Toon posts:

[JAVA] Labels meegeven aan een thread

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo, ik ben sinds een lange tijd java weer op gaan pakken als programmeer taal, alleen nu zit ik met een thread probleem. Ik maak dus een thread aan (dit gaat denk ik allemaal goed) en aan die thread geef ik een labelobject mee. De thread moet deze dus verplaatsen. Het probleem is dus dat hij niets verplaatst. Mijn vraag is dus ook of dit wel kan, en als het niet kan, kan het dan met iets vergelijkbaars (bv een plaatje).
Mocht het gewoon kunnen, dan zal ik de code posten (als het een niet al te basic probleem is volgens jullie) want het kan natuurlijk dat ik wel een fout erin heb zitten....

BTW, heb op internet gekeken, hier gezocht en natuurlijk ook mijn boek erbij gepakt.

  • Dash2in1
  • Registratie: November 2001
  • Laatst online: 31-08 22:49
wat code zou mischien handig zijn ?!

Verwijderd

Topicstarter
De thread classe
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.awt.*;
import java.awt.event.*;

class Mannetje extends Thread {
    
    private Label mannetjeLBL;
    private int breedte = 200;
    private int hoogte = 20;
    private int beginX = 50;
    private int beginY = 80;
    private int eindX = 100;
    private int eindY = 150;
    
    public Mannetje(Label lbl) {
      mannetjeLBL = lbl;
    }
    
    public void run() {
      mannetjeLBL.setBounds(500,500,200,20);
      while ((beginX != eindX) && (beginY != eindY)) {
        if (beginX != eindX) {
            if (beginX < eindX) {
              beginX++;
            }
            else {
              beginX--;
            }
        }
        if (beginY != eindY) {
            if (beginY < eindY) {
              beginY++;
            }
            else {
              beginY--;
            }
        }
        mannetjeLBL.setBounds(beginX,beginY,breedte,hoogte);
      }
    }
    
}

De code in mn gui classe
code:
1
2
3
4
5
6
public void actionPerformed(ActionEvent event) {
      if (event.getSource() == start) {
        Mannetje man = new Mannetje(mannetjeLBL);
        man.start();
      }
    }

Neem aan dat dit genoeg is

  • Dash2in1
  • Registratie: November 2001
  • Laatst online: 31-08 22:49
wat me eigenlijk opvalt, is dat je hem eerst tekent op 500,500 en dat hij daarna verspringt naar een hele andere coordinaat. Weet alleen neit of het daar aan ligt, misschien dat er wat java-goden wat licht op kunnen schijnen :)

Verwijderd

Topicstarter
Op vrijdag 31 mei 2002 21:21 schreef Dash2in1 het volgende:
wat me eigenlijk opvalt, is dat je hem eerst tekent op 500,500 en dat hij daarna verspringt naar een hele andere coordinaat. Weet alleen neit of het daar aan ligt, misschien dat er wat java-goden wat licht op kunnen schijnen :)
Dat was om even te kijken of hij uberhaubt wel in de while-lus ging. Maar ook bij die regel doet hij nix

  • nxt
  • Registratie: November 2001
  • Laatst online: 26-08 13:51

nxt

dit is meestal mijn standaard skelet voor een thread class
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class IkDoeIets implements Runnable {
    private long delay=300;
    private Thread t;
    private boolean _isRunning=false;
    
    private synchronized boolean isRunning() {
         return _isRunning;
    }
    private synchronized void setRunning(boolean run) {
         _isRunning=run;
    }   

    public void start() {
        if (!isRunning()) {
            setRunning(true);
            t=new Thread(this);
            t.start();
        }
    }
    public void stop() {
        isRunning=false;
    }   
    public void run() {
        while (isRunning()) {
            
              try {
                Thread.sleep(delay);
               }catch(InterruptedException ex) { }
        }
    }
}

en als ik iets van
IkDoeIets blah=new IkDoeIets();
blah.start();
doe komt ie altijd in de run aan,
probeer het eens (dus met name de start method) en laat
me weten of het helpt


Wat het echter ook zou kunnen zijn is dat je per ongeluk een layoutmanager gebruikt in je applicatie ipv een null layout, waardoor setBounds geen effect heeft

edit: code aangepast n.a.v. .oisyn en mbravenboer

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

nxt: kleine opmerking
code:
1
Thread.currentThread().sleep(delay);

sleep is een static methode, die altijd de huidige thread laat slapen. Je moet m dus niet aanroepen op een instantie van een thread, maar op de klasse Thread zelf. Dus:
code:
1
Thread.sleep (delay);

Jouw aanroep doet in principe hetzelfde, maar vraagt ook nog eens de huidige thread op, want in principe vrij nutteloos is ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • nxt
  • Registratie: November 2001
  • Laatst online: 26-08 13:51

nxt

hmmz goed punt.
we willen inderdaad liever geen overbodige dingen

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Het is op zich ook niet verkeerd om je isRunning variabele even te beschermen met een monitor ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 06-09 19:42
(Never mind)...

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik denk wel dat het strikt noodzakelijk is: er zouden nooit meerdere threads aan een variabele mogen zitten.

Het gaat inderdaad om de start, maar ook in je loop gebruik je direct de isRunning variabele. Dat kan misschien allemaal goed gaan, maar het is toch netter om hier even methoden voor te schrijven die gesynchronizeed zijn over this of een ander lock.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: (Never mind)...
Te laat :+ ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Martkrui
  • Registratie: Februari 2002
  • Laatst online: 29-08 14:35
code:
1
2
3
public Mannetje(Label lbl) {
      mannetjeLBL = lbl;
    }

't zal wel aan 't vroege uur liggen, maar ik heb toch het idee dat het label object hier ergens gecopierd wordt zodat je in een copie aan het rommelen bent..

zo en nu :Z

I haven't lost my mind! It's backed up on tape somewhere!


  • TheRebell
  • Registratie: Oktober 2000
  • Laatst online: 06:38
Op zaterdag 01 juni 2002 00:58 schreef Dr.DNA het volgende:
code:
1
2
3
public Mannetje(Label lbl) {
      mannetjeLBL = lbl;
    }

't zal wel aan 't vroege uur liggen, maar ik heb toch het idee dat het label object hier ergens gecopierd wordt zodat je in een copie aan het rommelen bent..

zo en nu :Z
Nee dit stukje klopt nog wel ('t is vroeg he ;) )

Hij geeft een label mee en die is daar bekend als "lbl", om er nu verder mee te willen werken moet ie hem ff een ander naam geven. Bv "mannetheLBL". Je kunt ook gewoon dezelfde naam gebruiken door
code:
1
this.lbl = lbl

te doen maargoed.... het is vroeg eej dus (en ga ook maar maffen.. :z )

  • TheOneLLama
  • Registratie: Oktober 2000
  • Laatst online: 20-01-2022

TheOneLLama

A llama like no llama before

Op vrijdag 31 mei 2002 21:11 schreef Grote Vos het volgende:
Hallo, ik ben sinds een lange tijd java weer op gaan pakken als programmeer taal, alleen nu zit ik met een thread probleem. Ik maak dus een thread aan (dit gaat denk ik allemaal goed) en aan die thread geef ik een labelobject mee. De thread moet deze dus verplaatsen. Het probleem is dus dat hij niets verplaatst. Mijn vraag is dus ook of dit wel kan, en als het niet kan, kan het dan met iets vergelijkbaars (bv een plaatje).
Je label wordt wel verplaats, maar hij wordt niet hertekent op het scherm, nl. omdat je scherm niet voor iedere keer dat er 1 labeltje verplaats wordt opnieuw getekend wordt (dan zal alles wel heel traag worden). Je zou het geloof ik met getGraphics() kunnen doen, maar dat is niet de meest nette manier.

Hertekenen gebeurt (als je het goed doet) vanuit de event thread. Het beste wat je kan doen is het daadwerkelijke veranderen van de positie van je label in de event thread te doen. Let wel op, het is niet de bedoeling dat je lang in de event thread blijft (zolang je met je eigen code in die event thread zit wordt er en kan er niks hertekent worden). Je moet dus code hebben die er maar een korte tijd in zit, waarna het scherm uitmatisch hertekent wordt. Zodra je dan weer iets wilt veranderen zorg je ervoor dat je code weer vanuit de event thread wordt gedraaid, waarna het scherm weer hertekend wordt, etc.

Er zijn verschillende manieren om te zorgen dat jou code vanuit de event thread wordt uitgevoerd, in Swing is 1 daarvan de Timer class geloof ik (werk niet zo vaak met Swing of AWT), die voor jou wel handig zou kunnen zijn hier.

Opera OpenOffice.org Jabber Psi jabber://llama@mordax.com


Verwijderd

Topicstarter
Bedankt voor alle replies, denk dat ik er wel wat aan heb, maar aangezien ik vandaag lange tijd in amsterdam heb rondgelopen, ga ik nu toch echt slapen, ik ga er morgen verder mee aan de slag, en laat eventuele problemen wel weten..

  • Hydra
  • Registratie: September 2000
  • Laatst online: 26-04 10:16
Op zaterdag 01 juni 2002 00:58 schreef Dr.DNA het volgende:
't zal wel aan 't vroege uur liggen, maar ik heb toch het idee dat het label object hier ergens gecopierd wordt zodat je in een copie aan het rommelen bent..
Java werkt vrijwel exclusief met references (in het geval van echte objecten), en dus wordt hier geen copie gemaakt.

https://niels.nu


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik denk dat het iets te maken heeft met je layout manager ofzo. Want als je bv een Flowlayout gebruikt zorgt de layoutmanager er zelf voor wat de locatie van het component is. Dan kan je veranderen wat je wilt maar dat helpt niet echt.

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


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Ik denk dat het ook aan de layoutmanager ligt (zie ook mijn post op javahova ;) )

Verwijderd

Topicstarter
De lay-out manager stond al op null. Dus daar kan het niet aan liggen. Hoe kan ik een thread bouwen die ervoor zorgt dat alles opnieuw getekend wordt?

Verwijderd

Topicstarter
Heb zelf wat geprobeerd, maar repaint() werkt iig niet. Zijn er nog andere manieren??

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op maandag 03 juni 2002 13:14 schreef Grote Vos het volgende:
Heb zelf wat geprobeerd, maar repaint() werkt iig niet. Zijn er nog andere manieren??
In principe moet repaint wel werken (wordt zelfs uitegevoerd op de Swing thread). Als ik nog een keer naar je code kijk dan zie ik ook dat jij een nogal drukke thread hebt. Jouw thread die blijft zonder delays draaien, dus miljoenen keren per seconde zijn jouw labels over het scherm aan het dansen en ik denk niet dat dat de bedoeling is. Probeer eens een Thread.sleep(200) in jouw while lus of kijk anders een naar de Timer class (die is hiervoor gemaakt).

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op vrijdag 31 mei 2002 22:42 schreef nxt het volgende:
dit is meestal mijn standaard skelet voor een thread class
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class IkDoeIets implements Runnable {
    private long delay=300;
    private Thread t;
    private boolean _isRunning=false;
    
    private synchronized boolean isRunning() {
         return _isRunning;
    }
    private synchronized void setRunning(boolean run) {
         _isRunning=run;
    }   

    public void start() {
        if (!isRunning()) {
            setRunning(true);
            t=new Thread(this);
            t.start();
        }
    }
    
    public void stop() {
        isRunning=false;    
    }   
    
    public void run() {
        while (isRunning()) {
            
              try {
                Thread.sleep(delay);
               }catch(InterruptedException ex) { }
        }
    }
}

en als ik iets van
IkDoeIets blah=new IkDoeIets();
blah.start();
doe komt ie altijd in de run aan,
probeer het eens (dus met name de start method) en laat
me weten of het helpt


Wat het echter ook zou kunnen zijn is dat je per ongeluk een layoutmanager gebruikt in je applicatie ipv een null layout, waardoor setBounds geen effect heeft

edit: code aangepast n.a.v. .oisyn en mbravenboer
Jouw 'ikDoeIets' is niet echt thread safe.

Als op tijdstip t1 thread 1 gaat starten, en hij roept start aan en heeft uitgelezen dat nog niet aan het draaien bent (if(!isRunning()), dan mag je dus het 1e statement van het if block gaan uitvoeren. Nu komt de sheduler eraan en geeft Thread2 de beurt en die komt nu ook aan bij de start methode en mag ook verder met de conditie. Dit houd dus in dat thread1 en thread2 allebei ikDoeIets mogen 'runnen'. Dit is dus een typisch geval van een race probleem.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class IkDoeIets implements Runnable{

    private boolean _canRun = true;
    private Thread _thread = null;

    public synchronized void start(){
        if(_thread != null && _thread.isAlive()){
            throw new RuntimeException("can start, already running");                       
        }
        _canRun = true;     
        _thread = new Thread(this);
        _thread.start();
    }
    
    public synchronized void stop(){
        if(_thread!=null && !_thread.isAlive()){
            throw new RuntimeException("can`t stop, no active thread");
        }       
        
        if(!_canRun){
            throw new RuntimeException("canRun already is false");
        }
        _canRun = false;
    }
    
    public void run(){
        while(_canRun){
            ...
        }
    }   
}

Verwijderd

Topicstarter
Helaas, repaint werkt niet, wat ik ook probeer.
Mijn paint methode ziet er alsvolgt uit:
code:
1
2
3
public void paint(Graphics g) {
      mannetjeLBL.setLocation(X,Y);
    }

en voordat ik repaint() doe, verander ik X en Y. Hij zou het label dan moeten verplaatsen toch??
Ik heb het label namelijk op een andere locatie geïnitialiseerd, en als ik het programma start, dan verplaatst hij het label wel. Daarna alleen niet meer. :?
Zelfs als ik het test met bv g.drawString, dan tekend ie nix opnieuw na repaint(); :?:?:?
Snap er echt niets meer van.....
Pagina: 1