-
Kresleni v jave
Chtel bych se zeptat od ceho je potrebne dedit jake metody prekryt ci na co kreslit, aby se java sama starala o prekresleni jiz nakreslenych tvaru, ktere se smazali po tom kdyz pres vykres prejedu jinym oknem... Mam tridu Kresleni ktera dedi od canvas a kreslim na jPanel metodou paint(Graphic g), ktera je metodou tridy Kresleni. g je ziskako z panelu pomoci jPanel.getGraphics(); A zajimalo vy me jestli je nutne pro kresleni vyuzivat metodu paint(), jelikoz mam v tride 4 metody ktere kresli odlisne obrazce a chtel bych kresli volanim techto metod...
-
2 Příloh-a(y)
Re: Kresleni v jave
Teď to nějak nechápu. Máš třídu Kreslení, která je potomkem Canvas a v překryté metodě paint(Graphics g) kreslíš na Graphics, které je získáno z formuláře, na kterém je instance Kreslení?
Tedy nějak takto?
Kód:
class Kresleni extends Canvas
{
public void paint(Graphics g)
{
Graphics loG = jPanel.getGraphics();
// nyni kreslis na loG
}
}
V Heroutovi (Herout, Pavel: JAVA - grafické uživatelské prostředí a čeština. Kopp, České Budějovice, 2001.)
se píše, že pro kreslení se zásadně doporučuje v metodě paint(Graphics g), kterou JVM volá při potřebě překreslit okno, takže po odkrytí okna tuto metodu JVM automaticky zavolá.
http://java.sun.com/products/jfc/tsc...ing/index.html
Přidávám příklady. V prvním mám třídu zděděnou od Canvas, kterou dám na okno.
Ve druhé mám třídu zděděnou od Frame (AWT, Swing ještě neumím), které jsem překryl metodu paint(Graphics g) a všechno funguje jak má.
Když tak napiš podrobnosti o tvém programu, třeba budu moci nějak pomoct.
-
Re: Kresleni v jave
dejme to mu ze mam datovou strukturu treba frontu, ktera obsahuje prvky ktere se umeji vykreslit a maji jako atribut souradnice kam se vykresli. Takze vykreslim treba 5 prvku. po prejeti jinym oknem se vymazou. Takze me napadlo vytvorit metodu paint ktera pojede frontu a na kazdym prvku zavola jeho prekreasleni. Ale ted jsem narazil kam tu metodu paint mam dat...
mam
Kód:
public class Hlavni extends JApplet{
private static Hlavni applet = new Hlavni();
private Queue fronta;
private JPanel jPanelKresleni = new JPanel();
public void paint(){
Prvek pom=fronta.getZacatek();
while (pom != fronta.getKonec()){
pom.getObrazec().prekresli();
pom=pom.getDalsi();
};
}
}
Datovy prvek v sobe jeste obsahuje atribut obrazec ve kterem jsou ulozeny souradnice pro vykresleni. A obrazec obsahuje i Graphics g na ktere bude kreslit. Graphic g bylo obrazci predano konstruktorem pomoci jPanelKresleni.getGraphics();
snad jsem to napsal pochopitelne:)
jenze takhle me ta metoda paint nefunguje, co mam kam pridat aby see volala ta metoda paint();? ty tam mas toto
moFrame.add(moPlatno);
ja tam mam zas
frame.getContentPane().add(applet, BorderLayout.CENTER);
-
Re: Kresleni v jave
Takže předpokládám, že tam je konstruktor ve stylu
Kód:
class Prvek
{
private Graphics moG;
public Prvek(Graphics g) // samozrejme pripadne dalsi parametry
{
moG = g;
}
public void prekresli()
{
// kreslici kod pomoci moG
}
}
a prvky jsou následně tvořeny ve stylu:
Kód:
new Prvek(jPanelKresleni.getGraphics()); // plus pripadne dalsi parametry
Pokud to tak je, tak první věc, která mě napadá je, že já bych to spíš řešil takto:
Kód:
class Prvek
{
public void prekresli(Graphics poG)
{
// kreslici kod pomoci poG
}
}
public class Hlavni extends JApplet{
private static Hlavni applet = new Hlavni();
private Queue fronta;
private JPanel jPanelKresleni = new JPanel();
public void paint(Graphics g)
{
Prvek pom=fronta.getZacatek();
while (pom != fronta.getKonec()) {
pom.getObrazec().prekresli(g);
pom = pom.getDalsi();
}
}
}
Jde o to, že Graphics ziskaná z jPanelKresleni.getGraphics() může být jiná než ta předaná v parametru. Ale nechci Ti do toho kecat.:) Možná to ničemu nevadí, nevím.
ALE, hlavní chyba je ta, že máš metodu
public void paint()
kdeřto v rodičovské třídě je public void paint(Graphics g)
Takže JVM volá metodu paint(Graphics g) rodičovské třídy, ale tvojí paint() nevolá, protože to je jiná metoda. Změň to na public void paint(Graphics g) a začne to myslím fungovat.
Jenom mě napadá, že nevím jaktože se Ti něco vykreslí? Píšeš, že problém je v překreslení po překrytí jiným oknem, takže prvotní vykreslení asi proběne v pořádku. Kreslíš ještě jinde?
-
Re: Kresleni v jave
Parada, maka to:) Diky:)
Jsem to ten parametr chtel napsat ale rikal jsem si ze ho tam nebudu pouzivat, tak jsem ho vynechal:)
tak vysledna metoda vypada takto
Kód:
public void paint(Graphics g){
super.paint(g);
System.out.println("prekresleni");
Prvek pom=fronta.getZacatek();
while (pom != null){
pom.getObrazec().prekresli();
pom=pom.getDalsi();
};
}
jeste bylo potreba zavolat metodu predka aby se prekreslili ovladaci prvky(tlacitka, atd.)
jinak ta trida Prvek nema jen metodu prekresli. Ma treba prekresli(Color barva); nahoru(int posun) a ostatni metody pro posunuti obrazce vsemi smery... Tak jsem zvolil ten zpusob, ze dam g jako atribut objektu misto parametru metody, protoze se mi zdalo zbytecny pri volani metody objektu predavat jeste g pres parametr...
Jinak dik za pomoc:)
-
Re: Kresleni v jave
Tak jsem ten aplet dal do html stranky a vypada to ze budu muset pouzit double buffering. Jneze nevim jak ho mam rozhodit... Swing by mel podporovat double buffering automaticky, ale nejak jsem nepochopil jak to ma fungovat...
mam instanci applet ktera dedi po JApplet a kdyz dam
Kód:
System.out.println(RepaintManager.currentManager(applet).isDoubleBufferingEnabled());
System.out.println(applet.isDoubleBuffered());
tak to napise
ten double bufering ze swingu se vztahuje i na to co nakreslim ja?
Nakej navod jsem nasel tady http://www.realapplets.com/tutorial/...Buffering.html
Ale to je pro awt...
-
Re: Kresleni v jave
Aha, tak tam co jsem pochopil co je napsano v tomhto odkazu http://java.sun.com/products/jfc/tsc...dex.html#swing tak double buffering automaticky podporuji jen potomci tridy JComponent... Takze to asi budu muset udelat rucne
ale zasek jsem se uz tady
Kód:
bufferImage = createImage(100,100);
System.out.println(bufferImage);
pri vytvareni bufferImage nedojde k vytvoreni, v bufferImage je null...
Takto to ma v odkazu vyse a funguje to, ale me ne
-
Re: Kresleni v jave
Tak uz me double buffering skoro chodi. ma to jeden hacek.
takto mam metodu paint() v tride MujApplet ktera dedi po JApplet
Kód:
public void paint(Graphics g){
if (prekreslitPredka){
super.paint(this.getGraphics());
}
prekreslitPredka=true;
if (offScreen==null){
offScreen = createImage(500,500);
bufferGraphics = offScreen.getGraphics();
}
jPanelKresleni.getGraphics().drawImage(offScreen,0,90,this);
}
a takto je metoda co vola paint()
Kód:
public void dolu(int posun) {
for (int i = 0; i < posun; i++) {
bufferGraphics.clearRect(50,99+i,51,51);
bufferGraphics.drawRect(50,100+i,50,50);
prekreslitPredka=false;
paint(jPanelKresleni.getGraphics());
try {
Thread.sleep(10);
} catch (InterruptedException f) {
}
}
}
A problem je v tom, ze kdyz v metode paint volana metoda predka super.paint(this.getGraphics());
tak animace zacne problikavat. To jsem vyresil booleovskou promennou prekreslitPredka, kdyz je false tak se metoda predka paint() nezavola, ale to ma taky hacek. A to ten, ze se pri animaci neprekresli GUI kdyz pres nej pretanhu jine okno... Animace je kreslena na graficky kontech JPanelu...
EDIT: Ted jsem koukal ze kdyz se v metode paint vola super.paint(this.getGraphics); tak vyskoci vyuziti procesoru az na 60% pokud se metoda nevola tak je vyuziti temer nulove...