[java] repaint()

Pagina: 1
Acties:

  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
Hee mensen ik zit met een probleem,

ik heb een lift die omhoog moet gaan nadat ik op een knop geklikt heb.
Dus mijn GUI bevat het volgende stukje code:

Java:
1
2
3
4
5
6
7
8
9
10
    class ActionHandler implements ActionListener           // actie behandelaar neem alles van action luisteraar mee
    {
        public void actionPerformed(ActionEvent e)          // als actie uitgevoerd
        {
            String action = e.getActionCommand();           // maak string van actie
            if(action.equals("level 0")) lm.draairechts();      // vergelijk string en op basis daarvan actie in myCanvas doen
            else if(action.equals("level 1")) lm.draairechts();  //even allemaal de zelfde functie in verband met test fase
            else if(action.equals("level 2")) lm.draairechts();            
        }
    }


Dus als ik op een knop druk gaat in class liftMotor de methode draairechts() lopen deze moet vervolgens in myCanvas weer de methode rechts() aanroepen en in liftMotor staat dus mc.rechts();.

in princiepe werkt het allemaal, maar er gaat iets mis.
Hij moet namelijk 60 pixeljes omhoog dus ik doe

Java:
1
2
3
4
5
      mc.rechts();
       try{
            Thread.sleep(400);
            }
         catch(InterruptedException ie) {}


en in myCanvas staat dan :

Java:
1
2
3
4
5
    public void rechts()
    {
       yKooi = yKooi -1;
       repaint(); 
    }


nu verwacht ik dus dat als ik op de knop geklikt heb, dat de lift stapje voor
stapje omhoog gaat, nou niets is minder waar. Hij wacht dus gewoon
60x100ms en repaint dan pas.

hier nog even de paint methode:

Java:
1
2
3
4
5
6
7
8
9
    public void paint(Graphics g)
    {
        g.setColor(Color.ORANGE);
        g.fillRect(xBuild,yBuild,wBuild,hBuild);
        g.setColor(Color.BLUE);
        g.drawRect(xKooi,yKooi,wKooi,hKooi);
        g.setColor(Color.YELLOW);
        g.fillRect(xKooi,yKooi,wKooi,hKooi);
    }



snap jij het dan snap ik het .. maar ik snap het niet .. 8)7

[ Voor 4% gewijzigd door intrix op 09-12-2003 15:26 ]

welcome my son, welcome to the machine


Verwijderd

intrix schreef op 09 december 2003 @ 14:18:
Hij wacht dus gewoon
60x100ms en repaint dan pas.
dat is toch gewoon wat Thread.sleep(400); doet of zie ik het verkeert?

  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
nee hij moet na sleep(400) dus weer 1 omhoog

en dan na sleep(400) weer 1 px omhoog etc.

maar dat doet ie dus niet


hij wacht gewoon 60x sleep(400) en doet daarna pas PAINT()

welcome my son, welcome to the machine


Verwijderd

Als je nu repaint() aanroept, dan wordt eerst update() aangeroepen en vervolgens pas paint(). Dan zet je je sleep vervolgens in update(). Je hebt daarmee update overschreven.

Dan roep je dus repaint() aan, die roept eerst update() aan (dat heb je herschreven naar een sleep, en vervolgens roept ie paint() aan.

Dat een idee?

edit:normaal gesproken zorgt update er dus voor dat het scherm leeg wordt alvorens paint weer wordt uitgevoerd, maar je overschrijft de methode update dus.

[ Voor 21% gewijzigd door Verwijderd op 09-12-2003 15:30 ]


  • Harmsen
  • Registratie: November 2000
  • Laatst online: 11:11
Verwijderd schreef op 09 december 2003 @ 15:28:
Als je nu repaint() aanroept, dan wordt eerst update() aangeroepen en vervolgens pas paint(). Dan zet je je sleep vervolgens in update(). Je hebt daarmee update overschreven.

Dan roep je dus repaint() aan, die roept eerst update() aan (dat heb je herschreven naar een sleep, en vervolgens roept ie paint() aan.

Dat een idee?
Dit zal al genoeg helpen, maar wil je later nog meer animaties toevoegen dan is het misschien makkelijk en handig om doublebuffering te gebruiken.

Dan teken je alles offscreen op een BufferedImage, en dan zet je in de Paint() methode simpel G.drawImage(BufferedImage).

Dit voorkomt flikkeringen zodat je een mooie vloeinde animatie krijgt. Ander voordeel is dat je die bufferedImage aan een klasse mee kan geven en zo objecten zichzelf kan laten tekenen.

[ Voor 8% gewijzigd door Harmsen op 09-12-2003 15:36 ]

What a fine day for Science! | Specs


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
zou een idee kunnen zijn misschien als dat werkt .. maar eh :

This method is called in response to a call to repaint. The canvas is first cleared by filling it with the background color, and then completely redrawn by calling this canvas's paint method. Note: applications that override this method should either call super.update(g) or incorporate the functionality described above into their own code.

hoe los ik dit op dan?

welcome my son, welcome to the machine


Verwijderd

Nou, dat is toch precies wat hierboven ook al gezegd wordt :?

edit (nofi):
Ok, Hunter is zo vriendelijk om je meteen de oplossing te geven, maar dit kon je toch ook wel even zelf uitzoeken? Gewoon even lezen :)

[ Voor 56% gewijzigd door Verwijderd op 09-12-2003 15:43 ]


  • Harmsen
  • Registratie: November 2000
  • Laatst online: 11:11
intrix schreef op 09 december 2003 @ 15:34:
zou een idee kunnen zijn misschien als dat werkt .. maar eh :

This method is called in response to a call to repaint. The canvas is first cleared by filling it with the background color, and then completely redrawn by calling this canvas's paint method. Note: applications that override this method should either call super.update(g) or incorporate the functionality described above into their own code.

hoe los ik dit op dan?
De volgende Update methode gebruiken:

Java:
1
2
3
4
5
     public void Update(Graphics g) 
    { 
        Thread.sleep(400); 
        super.update(g);        
    }

What a fine day for Science! | Specs


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
Huntor schreef op 09 december 2003 @ 15:34:
[...]


Dit zal al genoeg helpen, maar wil je later nog meer animaties toevoegen dan is het misschien makkelijk en handig om doublebuffering te gebruiken.

Dan teken je alles offscreen op een BufferedImage, en dan zet je in de Paint() methode simpel G.drawImage(BufferedImage).

Dit voorkomt flikkeringen zodat je een mooie vloeinde animatie krijgt. Ander voordeel is dat je die bufferedImage aan een klasse mee kan geven en zo objecten zichzelf kan laten tekenen.
let's see als ik het goed begrijp krijg je dan een matrix van vakjes
die je met een kleur kan vullen. Maar dan moet je dus bijvoorbeeld voor een vierkant ieder pixeltje van dat vierkant vullen met een kleurtje dus van positie 1 tot en met 100 is dan groen en op het moment dat je omhoog gaat is 100 tot en met 200 groen ..

tenminste dat begrijp ik nu ik het zo eens lees ...

[ Voor 27% gewijzigd door intrix op 09-12-2003 16:01 ]

welcome my son, welcome to the machine


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
Huntor schreef op 09 december 2003 @ 15:39:
[...]


De volgende Update methode gebruiken:

Java:
1
2
3
4
5
     public void Update(Graphics g) 
    { 
        Thread.sleep(400); 
        super.update(g);        
    }
kijk soms ben ik een beetje traag van begrip zag het ook ineens beetje chaotisch typje af en toe :P

alleen moet je sleep altijd try{}catch(){} doen

[ Voor 7% gewijzigd door intrix op 09-12-2003 15:44 ]

welcome my son, welcome to the machine


Verwijderd

intrix schreef op 09 december 2003 @ 15:43:
[...]


kijk soms ben ik een beetje traag van begrip zag het ook ineens beetje chaotisch typje af en toe :P
Een van de eigenschappen van een goede programmeur :P
alleen moet je sleep altijd try{}catch(){} doen
Ja ;)
Omdat het een exception kan opgeven moet je hem afvangen

  • Harmsen
  • Registratie: November 2000
  • Laatst online: 11:11
intrix schreef op 09 december 2003 @ 15:42:
[...]


kijk dat is intressant .. eh .. BufferedImage

kan ik dat gewoon op java.sun.com/api/docu/1.4.1 ofzo ongeveer vinden hoe dat werkt .. volgens mij is dat de beste oplossing :)
Dat is wel te vinden in de help van de JDK. Anders moet je zoeken naar BufferedImage of animaties met Java. Ik heb al even gezocht naar het deining project waarin we dit voor school hebben gebruikt, maar helaas kan het niet vinden. Dat was een mooi voorbeeld geweest met betrekking tot BufferedImages en Graphics2D.
intrix schreef op 09 december 2003 @ 15:43:
[...]


kijk soms ben ik een beetje traag van begrip zag het ook ineens beetje chaotisch typje af en toe :P

alleen moet je sleep altijd try{}catch(){} doen
Sorry....

What a fine day for Science! | Specs


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
intrix schreef op 09 december 2003 @ 15:42:
[...]


let's see als ik het goed begrijp krijg je dan een matrix van vakjes
die je met een kleur kan vullen. Maar dan moet je dus bijvoorbeeld voor een vierkant ieder pixeltje van dat vierkant vullen met een kleurtje dus van positie 1 tot en met 100 is dan groen en op het moment dat je omhoog gaat is 100 tot en met 200 groen ..

tenminste dat begrijp ik nu ik het zo eens lees ...

Java 2D API Graphics van Vincent J. Hardy is een aanrader !! (ISBN 0130142662)
die maar eens opzoeken in de tussentijd .. misschien is dat een idee :P

[ Voor 3% gewijzigd door intrix op 09-12-2003 16:21 ]

welcome my son, welcome to the machine


  • Harmsen
  • Registratie: November 2000
  • Laatst online: 11:11
intrix schreef op 09 december 2003 @ 15:42:
[...]


let's see als ik het goed begrijp krijg je dan een matrix van vakjes
die je met een kleur kan vullen. Maar dan moet je dus bijvoorbeeld voor een vierkant ieder pixeltje van dat vierkant vullen met een kleurtje dus van positie 1 tot en met 100 is dan groen en op het moment dat je omhoog gaat is 100 tot en met 200 groen ..

tenminste dat begrijp ik nu ik het zo eens lees ...
Nee, met een bufferedImage doe je dat niet. Met een BufferedImage kan je alles wat je met een Graphics2d ook kan. Dus draw, fill, polygon etc, etc. Maar het is niet onmiddelijk zichtbaar op het scherm. Pas wanneer je in de paint() methode zegt van g.drawimage(BufferedImage) wordt het hele gedoe pas op het scherm gezet. Dit voorkomt dat tijdens het opbouwen van het scherm het scherm gaat flikkeren door overlappingen.

Nog ff simpel gezegd:

Ik teken alles op een virtueel 2e beeldscherm genaamd bufferedImage, dit beeldscherm zie je niet(hij is virtueel). Als ik alles wat ik wil tekenen getekend heb op het bufferedImage, knip ik die image en kopieer ik hem in 1x op het echte beeldscherm wat je voor je ziet.

What a fine day for Science! | Specs


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
Huntor schreef op 09 december 2003 @ 16:34:
[...]


Nee, met een bufferedImage doe je dat niet. Met een BufferedImage kan je alles wat je met een Graphics2d ook kan. Dus draw, fill, polygon etc, etc. Maar het is niet onmiddelijk zichtbaar op het scherm. Pas wanneer je in de paint() methode zegt van g.drawimage(BufferedImage) wordt het hele gedoe pas op het scherm gezet. Dit voorkomt dat tijdens het opbouwen van het scherm het scherm gaat flikkeren door overlappingen.

Nog ff simpel gezegd:

Ik teken alles op een virtueel 2e beeldscherm genaamd bufferedImage, dit beeldscherm zie je niet(hij is virtueel). Als ik alles wat ik wil tekenen getekend heb op het bufferedImage, knip ik die image en kopieer ik hem in 1x op het echte beeldscherm wat je voor je ziet.
ok dat begrijp ik opzich wel
alleen niet hoe je die bufferedImage vult

zeg je dan ipv

g.drawOval soms

new bufferedImage bimg (zoiets)
bimg.drawOval(parameters);

welcome my son, welcome to the machine


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ja zo'n beetje wel.
het kan ongeveer op de volgende manier
Java:
1
2
3
BufferedImage image = new BufferedImage();
Graphics2D g2d = image.createGraphics() ;
g2d.drawOval( parameters );

Het verschil is dus dat je eerst even het Graphics object op moet vragen en niet meteen op het BufferedImage object de draw* methoden aanroept. Later kan je in je Paint methode dan gewoon
g.drawImage( BufferedImage, parameters );
doen

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
rwb schreef op 09 december 2003 @ 17:15:
Later kan je in je Paint methode dan gewoon
g.drawImage( BufferedImage, parameters );
doen
die drawImage die vraagt om een BufferedImageOp wat moet je daar mee doen dan snap niet helemaal wat daar nou het nut van is?

[ Voor 36% gewijzigd door intrix op 09-12-2003 18:33 ]

welcome my son, welcome to the machine


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
intrix schreef op 09 december 2003 @ 18:33:
[...]


die drawImage die vraagt om een BufferedImageOp wat moet je daar mee doen dan snap niet helemaal wat daar nou het nut van is?
Ik heb zelf nooit echt met Graphics2D gewerkt maar zo als ik het in de documentatie kan zien is dat om filters en dergelijke op de Image toe te passen. Als je dat niet hoeft kan je altijd gebruik maken van de methods van Graphics. Graphics2D erft namelijk van Graphics en de Graphics class heeft ook de methode

drawImage(Image img, int x, int y, ImageObserver observer) ;

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
Java 2D API Graphics van Vincent J. Hardy,
is alleen nog op bestelling te krijgen.
Ik heb dus in de tussentijd maar:
"java media api's cross-platform imaging, media and visualization"
gekocht in de hoop daar wat in te vinden!

[ Voor 15% gewijzigd door intrix op 11-12-2003 00:38 ]

welcome my son, welcome to the machine

Pagina: 1