Kreslení a překreslení – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Kreslení a překreslení – Java – Fórum – Programujte.comKreslení a překreslení – Java – Fórum – Programujte.com

 

Johnn195
~ Anonymní uživatel
15 příspěvků
28. 10. 2013   #1
-
0
-

Zdravím, mám opět jeden problém s Javou.

Potřebuji vykreslit obrázek, který mám zde

public void paint(Graphics2D g2d) {
	g2d.drawImage(img1, x, y, null);
}

A potřebuji s ním hýbat, to dělám tak, že měním souřadnice x a y. Ale vždy když zavolám tuto metodu, tak se obrázek vykreslí znovu, ale já potřebuji, aby se pouze překresloval. Také jsem zkoušel z místa volání metody volat i repaint(), ale to mi pak zmizelo úplně vše.

Grafice v Javě moc nerozumím, takže prosím o radu. Předem děkuji za odpověď

Nahlásit jako SPAM
IP: 195.26.25.–
z
~ Anonymní uživatel
268 příspěvků
28. 10. 2013   #2
-
0
-

Každá komponenta má metodu paint, která tu komponentu vykresluje. Volá se automaticky, když je to potřeba, nebo když to vynutíš.

Takže v paint musíš vykreslit všechno, co chceš zobrazit. Pokud ti po repaint všechno zmizí, tak nejspíš ten obsah vykresluješ někde jinde. Aby v paint nebyl složitý kód a mohl jsi kreslit odkudkoliv, tak se používá "trik", že si vytvoříš obrázek pro kompletní obsah a kreslíš si do něj jak chceš. V paint potom vykresluješ jen tento jeden obrázek.

http://programujte.com/forum/vlakno/20327-jak-je-to-s-tim-kreslenim-vlastne/#p153964

Ten tvůj obrázek se sám neposune. Musíš ten původní smazat a vykreslit ho znova na nové pozici, resp. všechno smazat a znova vykreslit.

Nahlásit jako SPAM
IP: 88.101.8.–
z
~ Anonymní uživatel
268 příspěvků
28. 10. 2013   #3
-
0
-

Pokud jen přepisuješ zděděnou metodu, aby se navíc vykresloval ten obrázek, tak stačí zavolat super.paint a pak vykreslit to, co tam chceš navíc.

Nahlásit jako SPAM
IP: 88.101.8.–
Johnn195
~ Anonymní uživatel
15 příspěvků
28. 10. 2013   #4
-
0
-

Díky za odpověď, ale stále tomu nerozumím. Když to teda nekreslím do paint, tak kam to tedy v tomto případě kreslím? A jak docílím toho, abych to tedy kreslil do paint? Aby mi to tedy nemizelo. Zkoušel jsem to upravit, ale stále žádný posun.

public class Grafika extends JPanel {
    Image img1 = Toolkit.getDefaultToolkit().getImage("src/img/test2.png");
    private int x = 0, y = 0;
    
    public void paint(Graphics2D g2d) {
        super.paint(g2d);
        g2d.drawImage(img1, x, y, null);
    }
    public void moveH() {
        x += 10;
    }
}

Když v této třídě kdekoliv zavolám repaint vůbec nic se nestane.

A jinak volám odsud

private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
        switch(evt.getExtendedKeyCode()) {
            case KeyEvent.VK_D:
                grafika.moveH();
                grafika.paint((Graphics2D)jPanel1.getGraphics());
                break;
        }
    }

Když volám repaint tady, tak všechno zmizí.

Zkoušel jsem se i dívat na různé tutoriály, ale žádná úprava mého kódu mi prostě nefungovala.

Nahlásit jako SPAM
IP: 195.26.25.–
sleepy
~ Anonymní uživatel
422 příspěvků
28. 10. 2013   #5
-
0
-

To co ty pouzivas je signatura nejakej uplne inej metody paint(Graphics2D g2d), v podstate tebou definovanej. Paint je v swingu a awt len paint(Graphics g). Skus si nad paint napisat @Override anotaciu a uvidis ze ti bude eclipse, alebo kompilator nadavat. Cize asi by si mohol pouzit skor nieco taketo:

public void paint(Graphics g) {
	g.drawImage(img, x,y,w,h,null);
}

Ak chces sila mocou Graphics2D (aj ked Shape nepouzivas v tvojom kode) tak potom niekde do kodu kde to planujes pouzit capni.

Graphics2D g2d = (Graphics2D) g;

A ak budes chciet nakoniec aj nieco skutocne riesit co sa ma prekreslovat, tak si precitaj nieco o doublebufferingu a volatileimage (ten je akcelerovany) + pohladat nieco po googli ja uz si toho vela nepamatam.

Nahlásit jako SPAM
IP: 147.175.177.–
Johnn195
~ Anonymní uživatel
15 příspěvků
28. 10. 2013   #6
-
0
-

#5 sleepy
Díky za odpověď. Tohle chápu a upravil jsem tu metodu paint podle toho jak jsi napsal. Ale stále bez výsledku, program se chová stejně, zkusil jsem i použít @Override anotaci a IDE (používám netbeans) mi to nepodtrhlo a šlo to i zkompilovat.

Nahlásit jako SPAM
IP: 195.26.25.–
sleepy
~ Anonymní uživatel
422 příspěvků
28. 10. 2013   #7
-
0
-

Tu je ukazka co som teraz urobil na rychlo urobil. Navrh je uplne zly ten nekopiruj, radsej si premisli ako by to bolo lepsie navrhnut. Ale mozno si v tom najdes svoju chybu:

// samotna animacia je to sice len stvorcek ale zamenou za image budes prekreslovat obrazok

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.Timer;

public class SimpleRepaint {
    public static void main(final String[] arg) throws InterruptedException {
	new SimpleRepaint();

    }

    JFrame frame;
    JCanvas canvas;
    Square sq;

    int timeSlice = 100;

    public SimpleRepaint() throws InterruptedException {
	this.frame = new JFrame("Simple repaint");
	this.frame.setSize(800, 600);
	this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	this.canvas = new JCanvas();
	this.sq = new Square(10, 10, 50);
	this.canvas.setDrawable(this.sq);
	this.frame.add(this.canvas);
	this.frame.setVisible(true);
	final Timer animationTimer = new Timer(this.timeSlice,
		new ActionListener() {
		    @Override
		    public void actionPerformed(final ActionEvent e) {
			SimpleRepaint.this.sq.moveLeft(5);
			SimpleRepaint.this.canvas.repaint();
		    }

		});
	animationTimer.start();
	Thread.sleep(10000);
	animationTimer.stop();
    }
}

// plocha kde sa kresli canvas
import java.awt.Graphics;

import javax.swing.JPanel;

public class JCanvas extends JPanel {

    /**
     * 
     */
    private static final long serialVersionUID = 3060757030831662850L;

    private Drawable drawable;

    @Override
    public void paint(final Graphics g) {
	super.paint(g);
	this.drawable.draw(g);
    }

    public void setDrawable(final Drawable d) {
	this.drawable = d;
    }
}

// interface toho co sa ma vykreslit

import java.awt.Graphics;

public interface Drawable {
    public void draw(Graphics g);
}

// objekt stvorca ktory sa da vykreslit

import java.awt.Color;
import java.awt.Graphics;

public class Square implements Drawable {

    public int width;
    public int x, y;

    public Square(final int initX, final int initY, final int width) {
	this.x = initX;
	this.y = initY;
	this.width = width;
    }

    @Override
    public void draw(final Graphics g) {
	// TODO Auto-generated method stub
	g.setColor(Color.red);
	g.drawRect(this.x, this.y, 50, 50);
    }

    public void moveBottom(final int step) {
	this.y += step;
    }

    public void moveLeft(final int step) {
	this.x += step;
    }

    public void moveRight(final int step) {
	this.x -= step;
    }

    public void moveTop(final int step) {
	this.y -= step;
    }

}

Nahlásit jako SPAM
IP: 147.175.177.–
sleepy
~ Anonymní uživatel
422 příspěvků
28. 10. 2013   #8
-
0
-

btw prehodil som omylom strany left a right.

Nahlásit jako SPAM
IP: 147.175.177.–
sleepy
~ Anonymní uživatel
422 příspěvků
28. 10. 2013   #9
-
0
-

Jaj pockaj ty mas problem s tym ze sa ti obrazok vykresli na novo ale neprekresli? Toto lepsie definuj co to znamena. Ze nezmizne ten povodny? (Staci zavolat flush). Tu je na co je ten override ktory som ti radil: http://docs.oracle.com/javase/7/docs/api/java/lang/Override.html. Ten mal pri paint(Graphics2D g2d) generovat chybove hlasky.

Nahlásit jako SPAM
IP: 147.175.177.–
Johnn195
~ Anonymní uživatel
15 příspěvků
28. 10. 2013   #10
-
0
-

#9 sleepy
Ano, to je můj problém. Vykresluji obrázek, kterým chci pohybovat, ale místo toho se vykresluje na novo. Předtím jsem omylem repaint volal někde jinde, proto vše zmizelo, ale teď, když volám repaint na správném místě, tak bez efektu obrázek je stejně vykreslen mnohokrát. Takže mi stačí akorát zavolat flush? A kde ho mám zavolat? Když jsem to zatím zkoušel v metodě paint, tak mi to IDE podtrhal.

A ano, anotace @Override mi při Graphics2D hází chybu, předtím neházel, protože už jsem tam měl pouze Graphics.

Nahlásit jako SPAM
IP: 195.26.25.–
goddard
~ Anonymní uživatel
41 příspěvků
29. 10. 2013   #11
-
0
-

v javafx by se ti tohle psalo jednoduseji

http://download.java.net/jdk8/jfxdocs/index.html

Nahlásit jako SPAM
IP: 94.112.88.–
sleepy
~ Anonymní uživatel
422 příspěvků
29. 10. 2013   #12
-
0
-

Pardon v componentoch nic ako flush neexistuje, ten sa nahcadza v image ...  to asi keby si pouzival doublebuffering (to ta teraz nemusi zauimat). Ale k veci, v tom painte volas v tvojom kode super.paint(Graphics g) teda tu pretazenu metodu? Lebo ta najskor vymaze cely obsah vykresli okno (komponentu, teda JPanel) a az za tym kreslis co chces ty. Presne ako to mam v kode co som ti poslal, konkretne class JCanvas. Za tym super.paint(g) ide hoc co co ches nakreslit. Tak este raz: 

import java.awt.Graphics;

import javax.swing.JPanel;

public class JCanvas extends JPanel {

    /**
     * 
     */
    private static final long serialVersionUID = 3060757030831662850L;

    private Drawable drawable;
    // rovnako mozes Overridnut paintComponent(Graphics g)
    
    @Override
    public void paint(final Graphics g) {
	super.paint(g); // treba volat aj toto super.paint(g)
	// tu napis co chces kreslit ja som
	// tu dal ze sa ma nakreslit object drawable
	this.drawable.draw(g);
    }
    
    // toto je mnou definovana metoda dolezite je len to co sadeje v paint(g)
    public void setDrawable(final Drawable d) {
	this.drawable = d;
    }
}

A tu je to s pohybujucim sa obrazkom:

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Square implements Drawable {

    public int width;
    public int x, y;
    private final BufferedImage img;

    public Square(final int initX, final int initY, final int width) {
	this.x = initX;
	this.y = initY;
	this.width = width;
	// tuto cast si nevsimaj len sa snazim nacpat vacsi obrazok do mensieho
	this.img = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB);
	try {
	    final BufferedImage im = ImageIO.read(new File(
		    "/cesta/k/obrazku/icons/page-add-icon.png"));
	    final Graphics g = this.img.getGraphics();
	    g.drawImage(im, 0, 0, this.img.getWidth(), this.img.getHeight(), 0,
		    0, im.getWidth(), im.getHeight(), null);
	    g.dispose();
	} catch (final IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }

    @Override
    public void draw(final Graphics g) {
	// TODO Auto-generated method stub
	g.drawImage(this.img, this.x, this.y, null);
    }

    public void moveBottom(final int step) {
	this.y += step;
    }

    public void moveLeft(final int step) {
	this.x += step;
    }

    public void moveRight(final int step) {
	this.x -= step;
    }

    public void moveTop(final int step) {
	this.y -= step;
    }

}
Nahlásit jako SPAM
IP: 147.175.177.–
sleepy
~ Anonymní uživatel
422 příspěvků
29. 10. 2013   #13
-
0
-

No a ten Override ma hadzat chybu, ak sa dana metoda (s rovankou signaturou) nenachadza nikde v jej nattriedach prip. interfacoch. No a v tomto pripade nic ako paint(Graphics2D g2d) neexistuje teda to hodilo chybu a to bolo pointou co som sa ti snazil povedat. No a s tym prekreslovanim to urob ako je to v tom priklade, skusal som to funguje to takze to musi fungovat aj tebe.

Nahlásit jako SPAM
IP: 147.175.177.–
Johnn195
~ Anonymní uživatel
15 příspěvků
30. 10. 2013   #14
-
0
-

#12 sleepy
Ok, moc díky. Nyní je mi to mnohem jasnější a už s tím dokáži o něco lépe pracovat. Díky! :)

Nahlásit jako SPAM
IP: 195.26.25.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 7 hostů

Podobná vlákna

Winapi překreslení — založil boom

WinApi - překreslení textu — založil General

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý