[java] label update probleem

Pagina: 1
Acties:

  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 22:13

Tjeerd

Be Original, Be Yourself.

Topicstarter
Ik heb een applet en daarbinnen is een een lus die kolommen afgaat en deze vervolgens controleert. Prima allemaal, maar nu wilde ik een soort van statusbar gebruiken die aangeeft welke kolom hij aan het controleren is (binnen de lus):

Java:
1
2
3
4
5
6
7
//pseudo-code:

 for (i=0; i<aantalkolommen; i++)
{
   doietsmetkolom();
    updatelabel("tekst");
}


Maar het label wordt pas bijgewerkt als heel de for-lus doorlopen is (dus aan alle kolommen zijn geweest). Ik heb al wat zitten rondspitten en blijkbaar wordt de GUI niet bijgewerkt. Ik heb al geprobeerd een Runnable te maken, van alles en nog wat zitten lezen over event dispatchers, invokeLater e.d. en paint() en validate()-methodes, maar niets lijkt te werken. Terwijl het enige dat ik wil is dat binnen de for-lus het label op de applet wordt bijgewerkt :(

Iemand suggesties en/of tips hoe het wel voor elkaar te krijgen?

[ Voor 7% gewijzigd door Tjeerd op 22-09-2004 14:31 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Eelke Spaak
  • Registratie: Juni 2001
  • Laatst online: 12-05 15:26

Eelke Spaak

- Vlad -

Hoe lang duurt het bijwerken van een kolom? Als je trouwens een Runnable gebruikt, moet je wel new Thread(Runnable).start() aanroepen (of iets wat op hetzelfde neerkomt natuurlijk) anders wordt het nog steeds vrolijk in de event thread uitgevoerd :) .

TheStreme - Share anything with anyone


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 22:13

Tjeerd

Be Original, Be Yourself.

Topicstarter
Het bijwerken van de kolom is een kwestie van gemiddeld 50 tot 250 rijen doorlopen en deze controleren. Duurt ongeveer 1/250e seconde denk ik.

Ik had al zoiets geprobeerd:

Java:
1
2
3
4
5
class Statusbar implements Runnable{
    void run(){
         labelStatus.setText("nieuwe status");
    }
}


Waarbij ik de thread (foutief?) start binnen de for-lus:

Java:
1
2
3
4
5
6
7
for (i=0; i<aantalkolommen; i++)
{
   doietsmetkolom(); 
   SwingUtilities.invokeLater(new Statusbar());
   //update statusbar?
}
 


Ik moet toegeven dat ik niet precies eruit kom welke volgorde ik een en ander nou moet aanroepen, ook de tutorials van Sun over Threads begreep ik niet goed.

[ Voor 24% gewijzigd door Tjeerd op 22-09-2004 14:43 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23:25

Janoz

Moderator Devschuur®

!litemod

Neem een paint op in de updatelabel methode en las een korte pauze in met Thread.sleep oid.

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


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 22:13

Tjeerd

Be Original, Be Yourself.

Topicstarter
Ik heb een Thread.sleep gedaan van 100 ms. en een repaint(), zie de code:

Java:
1
2
3
4
5
6
7
8
public void setStatus(String theStatus)
    {
                String stat = theStatus;
        
        labelStatus.setText( statusText + stat );               
        labelStatus.repaint();      
        try { Thread.sleep(10); } catch (InterruptedException e) {};
    }


Java:
1
2
3
4
5
for (i=0; i<aantalkolommen; i++)
{
   doietsmetkolom();    // controleren of rijen voldoen aan voorwaarde
   setstatus("Je bent nu bij kolom" + Integer.toString(i) );
}


Maar nog steeds niet willen updaten binnen de lus, pas als alle kolommen zijn geweest verschijnt er een tekst op het label.

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • bartkinbote
  • Registratie: November 2002
  • Laatst online: 21-05 08:44

bartkinbote

subterranean homesick alien

Probeer het eens met observables en met een aparte thread die de berekening doet. Zoiets:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.*;

class KolomUpdate extends Observable implements Runnable {
  public KolomUpdate(Observer o) {
    addObserver(o);
    start();
  }

  public void run() {
    for (i=0; i<aantalkolommen; i++)
    {
     doietsmetkolom();    // controleren of rijen voldoen aan voorwaarde
     setChanged();
     notifyObservers("Je bent nu bij kolom" + i);
    }
    setChanged();
    notifyObservers(null); //zeg dat de thread klaar is
  }
}


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class JeFrame implements Observer {
  KolomUpdate ku = null;

  public void update(Observable o, Object arg) {
    if (arg != null) {
      label.setText((String)arg);
      repaint();
    }
    ku = null;
  }

  public void updateKolommen() {
    if (ku==null) {
      ku = new KolomUpdate(this);
    }
  }
}


updateKolommen moet je aanroepen om het alles te starten.
Succes

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 20:53

Robtimus

me Robtimus no like you

Nestor schreef op 22 september 2004 @ 14:57:
Ik heb een Thread.sleep gedaan van 100 ms. en een repaint(), zie de code:

Java:
1
2
3
4
5
6
7
8
public void setStatus(String theStatus)
    {
                String stat = theStatus;
        
        labelStatus.setText( statusText + stat );               
        labelStatus.repaint();      
        try { Thread.sleep(10); } catch (InterruptedException e) {};
    }


Java:
1
2
3
4
5
for (i=0; i<aantalkolommen; i++)
{
   doietsmetkolom();    // controleren of rijen voldoen aan voorwaarde
   setstatus("Je bent nu bij kolom" + Integer.toString(i) );
}


Maar nog steeds niet willen updaten binnen de lus, pas als alle kolommen zijn geweest verschijnt er een tekst op het label.
Je gebruikt weer de event dispatcher thread, die ook je GUI repaint. Dat repainten doet ie nu dus pas weer nadat de method is afgelopen. Het duurt alleen wat langer.

Je hebt een aparte thread nodig die het echte werk doet, en aan de event dispatcher thread vertelt (dmv setText en repaint) dat er iets veranderd moet worden. Wat Eelke Spaak dus al zei.

Pseudo code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
handle event() {
    new Thread(new Executor()).start();
    // let the executor do the work
}

class Executor implements Runnable {
    public void run() {
        for (int i = 0; i < kolommen; i++) {
            // do iets
            update GUI;
        }
    }
}


De vuistregel: grote berekeningen doe je in een nieuwe thread, tenzij het niet erg is dat je GUI vastloopt.

[ Voor 5% gewijzigd door Robtimus op 22-09-2004 15:52 ]

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

Pagina: 1