[Java/Swing] problemen met overriden van paint(Graphics g)

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een klein probleempje in een overriden paint methode van een JPanel...

We moeten voor een schoolopdracht een spelletje RushHour programmeren.
Alles werkt perfect, op 1 ding na, als hij de string tekent voor de score, dan blijft die op 0 staan, terwijl in het achterliggende level object de score wel toeneemt.


Java: LevelView.java
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
@Override
    public void paint(Graphics g) {
        // kleur instellen en tekenveld leegmaken
        g.setColor(Color.gray);
        g.clearRect(0, 0, viewSize.width, viewSize.height);
        // afbeelding tekenen
        g.drawImage(speelveld, 0, 0, null);
        // tekstkleur en font instellen
        g.setColor(Color.BLACK);
        g.setFont(levelNameFont);
        // metingen voor strings te tekenen
        FontMetrics fm = g.getFontMetrics();
        Rectangle2D stringSize = fm.getStringBounds(level.getNaam(), g);
        // teken levelnaam linksboven
        g.drawString(level.getNaam(), 20, 30);
        // andere font instellen
        g.setFont(stappenFont);
        // metingen voor string met aantal stappen
        stringSize = fm.getStringBounds("Aantal stappen: "+level.getAantalStappen(), g);
        // HIER GAAT HET FOUT - teken string met aantal stappen (score)
        g.drawString("Aantal stappen: "+level.getAantalStappen(), viewSize.width / 2 - (int) stringSize.getWidth(), viewSize.height - 50);

        // teken alle voertuigen
        if (voertuigLijst != null) {
            for (VoertuigView voertuigView : voertuigLijst) {
                Rectangle bnds = voertuigView.getBounds();
                bnds.x = transformeerPunt(voertuigView.getPositie()).x;
                bnds.y = transformeerPunt(voertuigView.getPositie()).y;
                voertuigView.setBounds(bnds);
                voertuigView.repaint();
            }
            // debug informatie
            System.out.println(level.toString());
        }
    }


Iemand enig idee wat ik verkeerd doe? Ik vermoed dat hij niet mooi zijn tekengebied leegmaakt op voorhand, maar zou niet weten hoe ik het anders moet doen :?

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Iets met relevante code tonen... wat zie je op het scherm? Is dit de "score" waar je het over hebt?
Java:
1
"Aantal stappen: "+level.getAantalStappen()


Dus er staat "Aantal stappen: 0" op je scherm? Dan klopt je code in level.getAantalStappen niet...

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Loop eens gewoon met een debugger door je code heen. Zet op regel 126 een breakpoint en kijk wat level.getAantalStappen() terug geeft.

“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.”


Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17:32

Robtimus

me Robtimus no like you

Begin eens met een super.paint(g); aan te roepen.

En override alsjeblieft liever de paintComponent method ipv paint.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Woy schreef op dinsdag 19 mei 2009 @ 09:47:
Loop eens gewoon met een debugger door je code heen. Zet op regel 126 een breakpoint en kijk wat level.getAantalStappen() terug geeft.
level.getAantalStappen() werkt perfect, ik heb al met een debugger er doorgelopen, het probleem ligt bij Swing of hoe ik Swing aanroep, niet in de modelklassen.
IceManX schreef op dinsdag 19 mei 2009 @ 09:48:
Begin eens met een super.paint(g); aan te roepen.

En override alsjeblieft liever de paintComponent method ipv paint.
als ik super.paint(g) eerst aanroep, maakt het geen verschil, maar ik ga wel eens proberen paintComponent te overschrijven ;)

update: ik het nu de paintComponent(Graphics g) methode overschreven, als ik nu zorg dat het venster onder mijn startmenu (van windows) zit en ik het startmenu open en sluit dan tekent hij wel de huidige waarde, maar anders nog niet. Het heeft dus blijkbaar iets te maken met het feit dat Swing maar gedeeltelijk zijn componenten hertekent.

[ Voor 18% gewijzigd door Verwijderd op 19-05-2009 10:30 . Reden: update ]


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Doe anders eens een Repaint op het moment dat je waardes veranderen!

“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.”


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Woy schreef op dinsdag 19 mei 2009 @ 11:01:
Doe anders eens een Repaint op het moment dat je waardes veranderen!
Inderdaad. Je moet zorgen dat je programma de paint(Component) methode opnieuw aan moet roepen. Normaal gebeurt dit alleen als je programma moet repainten (omdat het achter een ander scherm vandaan komt), of als je zelf een update forceert.

https://niels.nu


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hydra schreef op dinsdag 19 mei 2009 @ 11:05:
[...]


Inderdaad. Je moet zorgen dat je programma de paint(Component) methode opnieuw aan moet roepen. Normaal gebeurt dit alleen als je programma moet repainten (omdat het achter een ander scherm vandaan komt), of als je zelf een update forceert.
Maar het updaten gebeurt in paintComponent! Als ik daar nog is repaint aanroep dan zit de tekencode in een infinite loop!

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Verwijderd schreef op dinsdag 19 mei 2009 @ 11:27:
[...]

Maar het updaten gebeurt in paintComponent! Als ik daar nog is repaint aanroep dan zit de tekencode in een infinite loop!
Is het zinvol om een nieuwe score te berekenen als er niks aan de spelsituatie is veranderd, maar alleen aan het scherm? ;)

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Verwijderd schreef op dinsdag 19 mei 2009 @ 11:27:
Maar het updaten gebeurt in paintComponent! Als ik daar nog is repaint aanroep dan zit de tekencode in een infinite loop!
Ja, dat is ook nogal de verkeerde aanpak. Het updaten hoor je daarbuiten te doen. Hebben ze het bij jullie nog niet over het MVC model gehad?

Wikipedia: Model–view–controller

https://niels.nu


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hydra schreef op dinsdag 19 mei 2009 @ 11:33:
[...]


Ja, dat is ook nogal de verkeerde aanpak. Het updaten hoor je daarbuiten te doen. Hebben ze het bij jullie nog niet over het MVC model gehad?

Wikipedia: Model�view�controller
Maar het is niet updaten dat ik doe, het is het tekenen van al berekende informatie dat verkeerd gaat.
Ja we gebruiken MVC, als je echt het hele project wil zien kan je dat doen op op onze Google Code repository. Het model klopt perfect, als ik de informatie in het consolevenster weergeef, is er niks aan de hand, het is de manier waarop Swing tekent die hier voor hoofdpijn zorgt. Als ik naar de bewuste lijn ga met de debugger (Ik gebruik NetBeans) en dan Evaluate expression doe, komt de juiste string wel bovendrijven, dus het ligt niet aan het model.
CodeCaster schreef op dinsdag 19 mei 2009 @ 11:28:
[...]

Is het zinvol om een nieuwe score te berekenen als er niks aan de spelsituatie is veranderd, maar alleen aan het scherm? ;)
De score wordt niet berekend, gewoon uit het model gehaald om getekend te worden.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op dinsdag 19 mei 2009 @ 12:05:
[...]
De score wordt niet berekend, gewoon uit het model gehaald om getekend te worden.
En als het model ge-update word dan zul je dus een Repaint moeten doen.

Aan het feit dat het wel goed gaat als je wat anders in bijvoorbeeld je startmenu doet ( Wat ook een Repaint triggered ) blijkt dat het tekenen gewoon goed gaat, maar dat er niet ge-repaint word, dat gebeurd immers alleen als er aangegeven is dat dat nodig is.

“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.”


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Verwijderd schreef op dinsdag 19 mei 2009 @ 12:05:
Maar het is niet updaten dat ik doe, het is het tekenen van al berekende informatie dat verkeerd gaat.
Ja we gebruiken MVC, als je echt het hele project wil zien kan je dat doen op op onze Google Code repository. Het model klopt perfect, als ik de informatie in het consolevenster weergeef, is er niks aan de hand, het is de manier waarop Swing tekent die hier voor hoofdpijn zorgt. Als ik naar de bewuste lijn ga met de debugger (Ik gebruik NetBeans) en dan Evaluate expression doe, komt de juiste string wel bovendrijven, dus het ligt niet aan het model.
Als er iets in de state van het model veranderd, zou het model een event af moeten geven, en een repaint (repaint() functie) moeten forceren. En dat doe je kennelijk niet.

https://niels.nu


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hydra schreef op dinsdag 19 mei 2009 @ 12:24:
[...]


Als er iets in de state van het model veranderd, zou het model een event af moeten geven, en een repaint (repaint() functie) moeten forceren. En dat doe je kennelijk niet.
Dat het ik geprobeerd, maakt absoluut geen verschil, de code wordt wel degelijk aangeroepen, het is alsof Swing zelf de commando's gewoon negeerd.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Laat eens zien hoe en waar je de repaint aanroept? Je omschrijving roept aan alle kanten dat het een om een missende repaint gaat.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op dinsdag 19 mei 2009 @ 12:54:
Laat eens zien hoe en waar je de repaint aanroept? Je omschrijving roept aan alle kanten dat het een om een missende repaint gaat.
Het is geen missende repaint want al de rest tekent wel!

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op dinsdag 19 mei 2009 @ 14:28:
[...]

Het is geen missende repaint want al de rest tekent wel!
Om maar met one-liners te reageren.

Het is geen fout in swing, want bij de rest van de mensen werkt het wel!

Ik denk dat je toch nog wat meer zult moeten debuggen, want blijkbaar word de paint niet aangeroepen, of word niet de juiste parameters meegegeven aan g.drawString.

[ Voor 22% gewijzigd door Woy op 19-05-2009 14:31 ]

“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.”


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op dinsdag 19 mei 2009 @ 14:28:
[...]

Het is geen missende repaint want al de rest tekent wel!
Assumption is the mother of all fuckups. Er kunnen maar een paar redenen zijn waarom het niet werkt.
1: De aanroep op level levert telkens dezelfde waarde op (kan van alles zijn. Bijvoorbeeld dat je tegen een heel andere instantie van level aan het kletsen bent)
2: Het relevante deel van je scherm wordt niet geupdate (kan komen doordat je de repaint niet aanroept, of doordat je het paint gebeuren sowieso verkeerd geimplementeerd hebt)

Je geeft aan dat het wel werkt, wanneer je op een andere manier een redraw forceert (start menu er overheen laten gaan, maar zou je ook met een resize of minimaliseer/maximaliseer actie kunnen doen). Het lijkt mij dan helemaal geen vreemde aanname dat het toch wel eens 2 zou kunnen zijn.

Vind je het dan heel vreemd dat ik wat sceptisch bent wanneer je zegt dat de repaint echt wel goed aangeroepen wordt? Als de repaint echt wel goed aangeroepen werd zou je eigenlijk geen verschil moeten kunnen zien wanneer je op een andere manier een repaint forceert.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Bij sommige mensen krijg ik het idee dat ze niet geholpen willen worden...

https://niels.nu


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op dinsdag 19 mei 2009 @ 14:45:
[...]


Assumption is the mother of all fuckups. Er kunnen maar een paar redenen zijn waarom het niet werkt.
1: De aanroep op level levert telkens dezelfde waarde op (kan van alles zijn. Bijvoorbeeld dat je tegen een heel andere instantie van level aan het kletsen bent)
2: Het relevante deel van je scherm wordt niet geupdate (kan komen doordat je de repaint niet aanroept, of doordat je het paint gebeuren sowieso verkeerd geimplementeerd hebt)

Je geeft aan dat het wel werkt, wanneer je op een andere manier een redraw forceert (start menu er overheen laten gaan, maar zou je ook met een resize of minimaliseer/maximaliseer actie kunnen doen). Het lijkt mij dan helemaal geen vreemde aanname dat het toch wel eens 2 zou kunnen zijn.

Vind je het dan heel vreemd dat ik wat sceptisch bent wanneer je zegt dat de repaint echt wel goed aangeroepen wordt? Als de repaint echt wel goed aangeroepen werd zou je eigenlijk geen verschil moeten kunnen zien wanneer je op een andere manier een repaint forceert.
1: Dit het ik met de debugger al geverifiëerd en is niet het geval (zie boven)
2: Er is me nog iets komen dagen, ik werk met Windows 7 RC 1 (build 7100), misschien is het een glitch op het niveau van Windows? Ik zal dit straks verifiëren door het onder Ubuntu te draaien.

Extra informatie:
Ik heb eens geprobeerd om toch nog een extra repaint aan te roepen nadat er een stap werd gezet, dit had jammergenoeg geen resultaat :/

Update: Ik heb de repaint() overal nog is toegevoegt en nu werkt hij wel :? ik zie het verschil niet met wat ik deze ochtend probeerde, maar het werkt nu in elk geval wel...

[ Voor 5% gewijzigd door Verwijderd op 19-05-2009 18:14 . Reden: update ]


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

2: Er is me nog iets komen dagen, ik werk met Windows 7 RC 1 (build 7100), misschien is het een glitch op het niveau van Windows? Ik zal dit straks verifiëren door het onder Ubuntu te draaien.
Als je 100% zeker weet dat je code zou behoren te werken volgens het framework wat je gebruikt, mag je met deze beweringen aankomen.
Update: Ik heb de repaint() overal nog is toegevoegt en nu werkt hij wel :? ik zie het verschil niet met wat ik deze ochtend probeerde, maar het werkt nu in elk geval wel...
Overal toevoegen is niet de oplossing (ook al lijkt het te werken). Bekijk bijvoorbeeld eens de documentatie. Je hoeft alleen maar een repaint op een component aan te roepen op het moment dat het model wat dat component nodig heeft om te renderen, veranderd is. Dit zou je kunnen doen door met een Observer/Observable pattern te gaan werken.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • krvabo
  • Registratie: Januari 2003
  • Laatst online: 19-09 22:02

krvabo

MATERIALISE!

Nick_S schreef op dinsdag 19 mei 2009 @ 21:40:
Overal toevoegen is niet de oplossing (ook al lijkt het te werken). Bekijk bijvoorbeeld eens de documentatie. Je hoeft alleen maar een repaint op een component aan te roepen op het moment dat het model wat dat component nodig heeft om te renderen, veranderd is. Dit zou je kunnen doen door met een Observer/Observable pattern te gaan werken.
Als ik het me goed herinner is er in een correct MVC-model al een observer verwerkt, 'Model' update namelijk de 'View'.
Dat werd me overigens trouwens pas in mijn 4e jaar HBO duidelijk. Eerder was ons dat nooit verteld. Wat onderzoek doet wonderen :P

Maargoed dat leren ze vanzelf neem ik aan verder in hun opleiding. Dan krijgen ze vast wel design patterns. Ik denk dat het hele observer pattern hier nu in implementeren te omslachtig en uitgebreid voor ze zou zijn. Tenminste, ik neem aan dat de TS in z'n eerste of 2e jaar zit.
Het basisidee van het observer-pattern implementeren, Model->View update, is denk ik wel een goed idee.

Pong is probably the best designed shooter in the world.
It's the only one that is made so that if you camp, you die.


Acties:
  • 0 Henk 'm!

Verwijderd

Ik zou de TS willen aanraden om het boek "Killer Game Programming in Java" (http://oreilly.com/catalog/9780596007300/) te kopen. Ik heb het zelf ook op de plank staan. Alhoewel ik niks met spellen doe is het een van de betere Java2D boeken (Staat overigens ook een klein stuk over 3D in).

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Nick_S schreef op dinsdag 19 mei 2009 @ 21:40:
[...]

Overal toevoegen is niet de oplossing (ook al lijkt het te werken). Bekijk bijvoorbeeld eens de documentatie. Je hoeft alleen maar een repaint op een component aan te roepen op het moment dat het model wat dat component nodig heeft om te renderen, veranderd is. Dit zou je kunnen doen door met een Observer/Observable pattern te gaan werken.
Ik bedoelde "overal waar van toepassing" (lees: als er een geldige zet wordt geregistreerd).
krvabo schreef op dinsdag 19 mei 2009 @ 21:46:
[...]

Als ik het me goed herinner is er in een correct MVC-model al een observer verwerkt, 'Model' update namelijk de 'View'.
Dat werd me overigens trouwens pas in mijn 4e jaar HBO duidelijk. Eerder was ons dat nooit verteld. Wat onderzoek doet wonderen :P

Maargoed dat leren ze vanzelf neem ik aan verder in hun opleiding. Dan krijgen ze vast wel design patterns. Ik denk dat het hele observer pattern hier nu in implementeren te omslachtig en uitgebreid voor ze zou zijn. Tenminste, ik neem aan dat de TS in z'n eerste of 2e jaar zit.
Het basisidee van het observer-pattern implementeren, Model->View update, is denk ik wel een goed idee.
Mja, ik zit in mijn eerste jaar en Design Patterns komen pas in het 2e jaar aan bod, nu ken ik alleen maar Singletons (dank u Wikipedia _/-\o_ )

Er wordt van ons dan ook nog niet verwacht dat we een echt MVC model implementeren, gewoon dat we een duidelijke scheiding houden tussen model en view.
Pagina: 1