Avatar billede trolle Nybegynder
26. april 2001 - 17:31 Der er 14 kommentarer og
2 løsninger

JLabel opdate for langsom

Der er en ting der har irriteret mig laenge!
Hvordan faar man en JLabel til at blive odateret foer et program gaar videre?
F.eks.

JLabel ting = new JLabel(\"ting);
<kode kode>...
public void startTing(){
  ting.setText(\"ting og sager\");
  metodeMedEnMasseLoekker();
  ting.setText(\"ting done\");
}

I ovenstaaende kode naar man aldrig at se ting blive til \"ting og sager\" formentlig fordi traaden har travlt inde i loekkerne...

Hvordan bliver label\'en opdateret foer traaden gaar videre? 
Og er det et meget generalt problem man skal passe paa?
Avatar billede disky Nybegynder
26. april 2001 - 17:39 #1
Sørg for at Paint() bliver kaldt.
Avatar billede trolle Nybegynder
26. april 2001 - 18:04 #2
Desvaerre...  den bliver stadig foerst opdateret efter
\"metodeMedEnMasseLoekker()\"
og med \"ting Done\"

kan man ikke bruge en delay() eller noget i den stil?
Avatar billede disky Nybegynder
26. april 2001 - 18:51 #3
mystisk
Avatar billede mpultz Nybegynder
26. april 2001 - 20:23 #4
Brug en SwingWorker. Den er ikke en del af JDK men kan downloades fra http://www.javasoft.com/ (se java tutorial). Kort fortalt så oprettes der en tråd hvor alle dine løkker løbes igennem. Når disse løkker er færdige kaldes finished() som så opdaterer gui. Generelt hvis du har nogle \"hårde\" beregninger så lav dem i en seperat tråd da det låser gui\'et.

Erstat

metodeMedEnMasseLoekker();
ting.setText(\"ting done\");

med

final SwingWorker worker = new SwingWorker()
{
  public Object construct()
  {
    metodeMedEnMasseLoekker(); 
  }

  // Runs in the event-dispatching thread.
  public void finished()
  {
    ting.setText(\"ting done\");
  }
};
worker.start();
Avatar billede disky Nybegynder
26. april 2001 - 20:27 #5
mpultz: generelt skal man køre GUI i en tråd og resten i andre tråde, netop for at undgå denne type lås der opstår.
Avatar billede trolle Nybegynder
26. april 2001 - 20:43 #6
jeg kan desvaerre ikke komme til at udvide JDK, da programmet ikke kommer til at koere paa min pc...
Ellers nogen forslag?
Avatar billede disky Nybegynder
26. april 2001 - 20:47 #7
Du behøves heller ikke at hente det.

Lav en tråd der styrer GUI, kan være den programmet kører i, i forvejen.

Og dine beregninger kører du i en seperart tråd. Som så afsluttes når beregningerne er udført.

Den første tråd står så og venter på at udregningerne er færdige.
Avatar billede trolle Nybegynder
26. april 2001 - 21:20 #8
Toevende:  okey......

Hvordan laver jeg saa saadan en ny traad?!?
og hvordan kan jeg lade traaden jeg kommer fra vente til den anden er faerdig?
Avatar billede disky Nybegynder
26. april 2001 - 21:34 #9
Class Ghost
{
    private Thread thread=null;
   
    public Ghost()
    {
        thread=new Thread(this);
    }
     
    public void start()
    {
        thread.start();
    }
   
    public void paint( Graphics g )
    {
    }
   
    public void run()
    {
        while(true) //kører altid, fjern hvis den skal stoppe
        {
            try
            {
                Thread.sleep(50);
            }
            catch( InterruptedException e )
            {
                e.printStackTrace(System.out);
            }
        }
    }   
}


Kaldes med:
Ghost ghost4=new Ghost();
ghost4.start();


(fra et pacman spil jeg engang rodede med)

Jeg kan ikke huske hvordan man ser om en tråd er stoppet. Men du kan f.eks. sætte et flag som din hovedtråd checker en gang imellem.

Avatar billede mpultz Nybegynder
26. april 2001 - 22:13 #10
disky: den lås som du refererer til er netop den du undgår ved at bruge en SwingWorker. Efter SwingWorker instansen er oprettet og startet fortsætter eksekvering (2 tråde nu). Når construct() metoden terminerer forespørger den systemet om at eksekvere finished() metoden i \"event dispatching\" tråden, den tråd alt GUI skal opdateres i.
Avatar billede disky Nybegynder
26. april 2001 - 22:14 #11
ja men som han skriver han kan ikke udvide sin JDK.

Men man kan godt få en event tilsendt når en tråd er færdig kan bare ikke huske hvordan
Avatar billede mpultz Nybegynder
26. april 2001 - 22:18 #12
trolle: Du behøver ikke \"udvide\" din JDK, det drejer sig om en klasse. Her er koden:

import javax.swing.SwingUtilities;

/**
* This is the 3rd version of SwingWorker (also known as
* SwingWorker 3), an abstract class that you subclass to
* perform GUI-related work in a dedicated thread.  For
* instructions on using this class, see:
*
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
*
* Note that the API changed slightly in the 3rd version:
* You must now invoke start() on the SwingWorker after
* creating it.
*/
public abstract class SwingWorker {
    private Object value;  // see getValue(), setValue()
    private Thread thread;
    private int priority;

    /**
    * Class to maintain reference to current worker thread
    * under separate synchronization control.
    */
    private static class ThreadVar {
        private Thread thread;
        ThreadVar(Thread t) { thread = t; }
        synchronized Thread get() { return thread; }
        synchronized void clear() { thread = null; }
    }

    private ThreadVar threadVar;

    /**
    * Get the value produced by the worker thread, or null if it
    * hasn\'t been constructed yet.
    */
    protected synchronized Object getValue() {
        return value;
    }

    /**
    * Set the value produced by worker thread
    */
    private synchronized void setValue(Object x) {
        value = x;
    }

    /**
    * Compute the value to be returned by the <code>get</code> method.
    */
    public abstract Object construct();

    /**
    * Called on the event dispatching thread (not on the worker thread)
    * after the <code>construct</code> method has returned.
    */
    public void finished() {
    }

    /**
    * A new method that interrupts the worker thread.  Call this method
    * to force the worker to stop what it\'s doing.
    */
    public void interrupt() {
        Thread t = threadVar.get();
        if (t != null) {
            t.interrupt();
        }
        threadVar.clear();
    }

    /**
    * Return the value created by the <code>construct</code> method.
    * Returns null if either the constructing thread or the current
    * thread was interrupted before a value was produced.
    *
    * @return the value created by the <code>construct</code> method
    */
    public Object get() {
        while (true) {
            Thread t = threadVar.get();
            if (t == null) {
                return getValue();
            }
            try {
                t.join();
            }
            catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // propagate
                return null;
            }
        }
    }

    public SwingWorker()
    {
      this(Thread.NORM_PRIORITY);
    }


    /**
    * Start a thread that will call the <code>construct</code> method
    * and then exit.
    */
    public SwingWorker(int _priority) {
        priority = _priority;
        final Runnable doFinished = new Runnable() {
          public void run() { finished(); }
        };

        Runnable doConstruct = new Runnable() {
            public void run() {
                try {
                    setValue(construct());
                }
                finally {
                    threadVar.clear();
                }

                SwingUtilities.invokeLater(doFinished);
            }
        };

        Thread t = new Thread(doConstruct);
        threadVar = new ThreadVar(t);
    }

    /**
    * Start the worker thread.
    */
    public void start() {
        Thread t = threadVar.get();
        if (t != null) {
            t.setPriority(priority);
            t.start();
        }
    }
}
Avatar billede mpultz Nybegynder
27. april 2001 - 13:40 #13
trolle: Følgende er \"næsten\" ækvivalent med at bruge en SwingWorker.

Thread t = new Thread(new Runnable() {
  public void run()
  {
    metodeMedEnMasseLoekker();
    SwingUtilities.invokeAndWait(new Runnable()
    {
      public void run()
      {
        ting.setText(\"ting done\");     
      }
    });
  }
});
t.start();
Avatar billede trolle Nybegynder
27. april 2001 - 17:02 #14
Selvfoelgelig var der en simpel loesning til problement!!!

Man kunne blot kalde  \"paint(getGraphics());\"  som dog tager lang tid, men loeser problemet!

De andre loesninger har desvaerre den bagdel, at foerst at fremmest de er besvaerlige i noget der skulle vaere et lille overskueligt program, og JLabel\'en gentegner hoejst oven i sig selv, hvilket giver noget hoejst uigennemskueligt text!

Men tak til jer begge!!!

Trolle
Avatar billede disky Nybegynder
27. april 2001 - 17:07 #15
fy slemme dreng, og du afviste det :-)

Men det vigtigste er du fandt en løsning
Avatar billede trolle Nybegynder
27. april 2001 - 19:02 #16
Jeg taenkte bare paa, at man kun kunne kalde paint ved, at kalde repaint();...
Og repaint() bliver aabenbart altid kaldt til sidst i en metode?!?  den der getGraphics() havde jeg ikke lige taenkt paa!

saa jeg er ked af alt jeres store arbejde, hvis det kunne have vaeret undgaaet!!!

Trolle
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester