[Java] spelbord update probleem

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • ingdas
  • Registratie: Mei 2007
  • Laatst online: 05-08-2013
Als beginnende java-programmeur ben ik aan het proberen om het spel "Khet" te programmeren (voor meer info erover verwijs ik naar Google).
Het is een bordspel voor 2 personen met 2 lasers. Na de beurt van 1 persoon wordt er een laser afgevuurd, dit wordt gevisualiseerd in mijn spel. De vakjes van mijn bord zijn JPanels met daarin 2 JLabels in een Overlay-layout. De laserstraal wordt geladen uit een gif-bestandje (die doorzichtig is buiten de laser) en dus boven mijn afbeelding geplaatst. Tot zover gaat het allemaal goed.
Om mijn spelbord te vernieuwen (mijn verplaatste stukken uit arrays zichtbaar te maken en eventuele resterende overlays te verwijderen) heb ik een functie update(). Deze werkt naar behoren voorzover ik kan zien, deze wordt ook aangeroepen vlak voor ik mijn laserstralen begin te tekenen. Maar nadat de laserstraal dus getekend is roep ik een timer op die een paar seconden later die functie nogmaals oproept, om het bord weer normaal zichtbaar te maken, zonder stralen, en als er een stuk geraakt is door de laserstraal moet deze ook verdwijnen, dat moet ook gebeuren door deze update().
Het probleem: heel mijn bordlayout is om zeep na die update() met vertraging, afbeeldingen worden maar half getekend of soms verkeerd geresized. Ik vroeg me af of het aan de functie lag of aan iets anders, en ik heb vervolgens een knop gemaakt om handmatig up te daten, als ik dat doe wordt de layout weer in orde.
Ik geraak er niet aan uit wat het probleem kan zijn. Hieronder nog eventjes de functie die met vertraging werkt, want daar zou het probleem moeten gecreëerd zijn voorzover ik kan zien.

Java:
1
2
3
4
5
6
7
8
9
10
11
     public void tekenBord() {
        TimerTask taak=new java.util.TimerTask(){

            @Override
            public void run() {
                update();
            }

        };
        timer.schedule(taak, 1000);
        }


mijn vraag: herkent iemand mijn probleem of weet iemand wat ik er aan kan doen?

Acties:
  • 0 Henk 'm!

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 08:16

BCC

Klinkt als een racing condition (dus dat update 2x tegelijk wordt aangeroepen oid).

[ Voor 20% gewijzigd door BCC op 27-12-2008 15:53 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


Acties:
  • 0 Henk 'm!

  • ingdas
  • Registratie: Mei 2007
  • Laatst online: 05-08-2013
Bedankt voor het snelle antwoord maar ik heb de indruk dat je vermoeden niet klopt. Ik heb nu mijn code die mijn klik op de updateknop verwerkt veranderd naar de vertraagde oproep, en de layout verandert ook in iets fout. Ik druk op die knop op een moment dat java enkel maar wacht op events, dus ik zie niet hoe update() 2 keer tegelijk kan opgeroepen worden.
Verder weet ik eigenlijk niet direct wat je kunt doen met console.log of hoe dat je iets doet.
Java:
1
2
3
if (clickedButton == updateknop){
                tekenBord();
            }

Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

De timer task wordt niet in de ui event thread uitgevoerd. Dat moet wel. Met bijv. SwingUtils kan je een runnable in die speciale thread uit laten voeren. Je code komt er dan ongeveer zo uit te zien:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
    public void tekenBord() { 
        TimerTask taak=new java.util.TimerTask(){ 
            public void run() { 
                SwingUtils.runInEventThread(new Runnable(){
                     public void run() { 
                        update(); 
                     }
                }
            } 
        }; 
        timer.schedule(taak, 1000); 
        }


Ik heb niet de javadoc bij de hand genomen, dus je zal even de exacte method name op moeten zoeken.

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • ingdas
  • Registratie: Mei 2007
  • Laatst online: 05-08-2013
Bedankt, het werkt inderdaad met de volgende code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void tekenBord() {

            TimerTask taak=new java.util.TimerTask(){
            @Override
            public void run() {
                SwingUtilities.invokeLater(new Runnable(){
                    @Override
                     public void run() {
                        update();
                     }
                });
            }
        };
        timer.schedule(taak, 3000);
        }

case solved _/-\o_

edit: ik ben blij dat het opgelost is maar nu bedenk ik dat ik eigenlijk nog altijd niet goed snap waarom het niet werkte en nu wel. Kan er iemand dat mij uitleggen. Er wordt nu in dezelfde thread gewerkt maar wat maakt dat uit voor de werking als er niets speciaals gedaan wordt in de event-thread?

[ Voor 22% gewijzigd door ingdas op 27-12-2008 16:31 ]


Acties:
  • 0 Henk 'm!

  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Ja, dat kan, maar je kan beter een javax.swing.Timer gebruiken (http://www.j2ee.me/docs/b...l/uiswing/misc/timer.html). Dan wordt je code een stuk simpeler.

Tevens moet je "repaint" gebruiken ipv update (zie javadoc voor JComponent). Update wordt normaal gesproken door Swing code aangeroepen en niet vanuit je eigen methodes.

Meer over de event dispatch thread: http://java.sun.com/docs/...concurrency/dispatch.html
De regel is dat UI updates binnen Swing altijd via de EDT moeten. Doe je dat niet dan is het resultaat onvoorspelbaar: het zou (soms) kunnen werken of niet. Als het werkt kan je het zien als toeval. Als het niet werkt ook :)

[ Voor 47% gewijzigd door grhmpf op 27-12-2008 16:47 ]


Acties:
  • 0 Henk 'm!

  • ingdas
  • Registratie: Mei 2007
  • Laatst online: 05-08-2013
- ik zal eens kijken voor de swing-timer, bedankt voor de tip
- update is een methode die ik zelf definieer, binnen update wordt er nog heel wat gedaan om te bepalen welke afbeelding nu overeenkomt met het stuk dat op die positie staat.
- bedankt voor de link over de dispatch thread
Pagina: 1