Toon posts:

[Java/SWT] method aanspreken vanuit externe thread

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hello, ik ben momenteel bezig aan een project in Java (nl. het herschrijven van een Swing-app naar een SWT-app). Ik ben nog maar een 3-tal maanden bezig met java, dus is onderstaand probleem niet zo moeilijk voor java-experts...

Mijn probleem is het volgende...

Ik heb twee klassen:
De eerste (checkText) creert een thread die voordurend loopt naast de main-thread in de andere klasse (DrawText).
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
42
public class CheckText {
    
    private Display display;
    private DrawText dt;

    public CheckText(){
        
        Display dis = new Display();
        UpdateShell s = new UpdateShell(dis);
        s.start();  
        DrawText dt = new DrawText(dis);
        s.stop();
    }
    
        public class UpdateShell extends Thread
        {
            public UpdateShell(Display d){
                display = d;
            }
            
            public void run(){
                while (true) {
                    System.out.println("running...");   
                    display.syncExec(new Runnable() {
                    public void run() {
                        dt.Update();
                    }
                    });
                }
                
            }
            
        }
    
    
    
    public static void main(String[] args) {
        CheckText c = new CheckText();
    }
    
    
}

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
public class DrawText {
    
    private Display d;
    
    public DrawText(Display display){
        
        d = display;
        Shell s = new Shell(d);
        GridLayout l = new GridLayout();
        s.setLayout(l);
        Text t = new Text(s, SWT.BORDER|SWT.SINGLE);
        s.setSize(500,100);
        s.open();
        while(!s.isDisposed())  {
                    if(!d.readAndDispatch()){
                    d.sleep();}
                                }
        d.dispose();
        
    }
    
    public void Update(){
        System.out.println("Updating...");
    }

}

Indien we in bovenste code regels 24 tot en met 28 weglaten blijkt de code exact te werken. Ik zou nu graag een methode van de klasse DrawText aanspreken... Ik heb al vele mogelijke manieren uitgeprobeerd maar ik blijk er niet uit geraken. Zo had ik bij voorbeeld de Update-methode in de CheckText-class gezet, maar hierdoor werd mijn applicatie bijzonder traag... Hetzelfde effect kreeg ik toen ik een nieuwe klasse Update maakt...

Kan er iemand mij helpen plz... Hoe kan ik de de Update-method aanspreken vanuit de thread UpdateShell???

groeten, champ

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

Alarmnummer

-= Tja =-

Ik ben niet thuis in SWT maar bij dit stukje werd is wel een beetje angstig:

code:
1
2
3
4
5
6
7
8
9
10
11
public void run(){
                while (true) {
                    System.out.println("running...");    
                    display.syncExec(new Runnable() {
                    public void run() {
                        dt.Update();
                    }
                    });
                }
                
            }

Je loopt daar het continu een runnable te extecuten bij die display.syncExec. Ik neem aan dat dit voor een behoorlijke belasting gaat zorgen.

Verwijderd

Topicstarter
In SWT wordt er anders gewerkt dan in Swing/AWT...
Je hebt een main-thread die continu loopt en eigenlijk zoekt in de event-loop van de OS naar events die aan de app toebehoren.
Dit d.m.v. deze code:
code:
1
2
3
4
5
while(!shell.isDisposed())  {
                    if(!display.readAndDispatch()){
                    display.sleep();}
                                }
        display.dispose();

Het was nu de bedoeling om een parallelle thread te creëren die continu op een bepaalde statement gaat checken en indien deze waar is een dt.update gaat doen... Dit werkt allemaal goed, maar enkel de dt.update werkt niet ---- de vraag is dus eigenlijk waarom kan ik hier deze methode niet uitvoeren op dt???

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
public void run(){
                while (true) {
                    System.out.println("running...");  
              if (statement = true)  
                    display.syncExec(new Runnable() {
                    public void run() {
                        dt.Update();
                    }
                    });
              }
                }
                
            }

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

Alarmnummer

-= Tja =-

Verwijderd schreef op 16 december 2003 @ 12:10:
In SWT wordt er anders gewerkt dan in Swing/AWT...
Je hebt een main-thread die continu loopt en eigenlijk zoekt in de event-loop van de OS naar events die aan de app toebehoren.
Dit d.m.v. deze code:
code:
1
2
3
4
5
while(!shell.isDisposed())  {
                    if(!display.readAndDispatch()){
                    display.sleep();}
                                }
        display.dispose();

Het was nu de bedoeling om een parallelle thread te creëren die continu op een bepaalde statement gaat checken en indien deze waar is een dt.update gaat doen... Dit werkt allemaal goed, maar enkel de dt.update werkt niet
Je hebt in je 1e bericht vermeld dat je applicatie traag ging, dus vandaar. En verder heeft deze lus een sleep methode erin, dus krijg je geen 100% processor verbruik.

  • bille
  • Registratie: Mei 2000
  • Laatst online: 06-05 18:25

bille

Don't call me Buff

als ik me niet vergis moet je dT als final gedeclareerd hebben om het object aan te kunnen spreken vanuit een anonn. innerclass.

zoiets dus:
code:
1
private final DrawText dt


overgens: "method aanspreken vanuit externe thread" .. dat kan niet. Je kan alleen maar methoden aanspreken in de huidige thread. Je kan wel methoden aanspreken in een andere thread dan waar je nu inzit, maar dan moet je een referentie hebben naar die thread.

Overgens is het ook netjes om gebruik te maken van een threadpool. Je maakt nu iedere keer een nieuwe thread aan en dat vreet resources.

[ Voor 71% gewijzigd door bille op 16-12-2003 12:47 ]

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


Verwijderd

Topicstarter
Overgens is het ook netjes om gebruik te maken van een threadpool. Je maakt nu iedere keer een nieuwe thread aan en dat vreet resources.
Dat is inderdaad mss wel iets dat ik eens ga bekijken, bedankt voor de tip...
Maar gewoon als final declareren werkt blijkbaar toch niet...
Maar het leidt volgens mij wel tot de oplossing denk ik:

Als je zet:
code:
1
private final DrawText dt;

wordt er naar een instantiatie gevraagd, meestal wordt dit opgelost als volgt:
code:
1
2
3
private DrawText dt;
....
final DrawText dt = new DrawText(dis);

Als we nu kijken naar mijn code, zal de thread UpdateShell starten voordat de DrawText als final is gedeclareerd, waardoor ik waarschijnlijk de foutmelding krijg.
Dus als ik nu gewoon een nieuwe klasse aanmaak: UpdateShell als volgt lijkt het te werken...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class CheckText {
    
    private Display display;
    private DrawText dt;

    public CheckText(){
        
        Display dis = new Display();    
        DrawText dt = new DrawText(dis);
    
    }
    
    
    
    public static void main(String[] args) {
        CheckText c = new CheckText();
    }
    
    
}

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
public class DrawText {
    
    private Display d;
    private UpdateShell us;
    
    public DrawText(Display display){
        
            d = display;
            Shell s = new Shell(d);
            GridLayout l = new GridLayout();
            s.setLayout(l);
            Text t = new Text(s, SWT.BORDER|SWT.SINGLE);
            s.setSize(500,100);
            s.open();
            us = new UpdateShell(d, this);
            us.start();
            while(!s.isDisposed())    
                    {
                        if(!d.readAndDispatch())
                        {
                        d.sleep();
                        }
                    }
            d.dispose();
            us.stop();
        }
    
    public void Update(){
                System.out.println("Updating...");
            }
    
}

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class UpdateShell extends Thread {
    
                private Display display;
                private DrawText dt;
    
                public UpdateShell(Display d, DrawText drte){
                    display = d;
                    dt = drte;
                }
            
                public void run(){
                    while (true) {
                        System.out.println("running...");   
                        display.syncExec(new Runnable() {
                        public void run() {
                            dt.Update();
                        }
                        });
                    }
                
                }
            
            }
Pagina: 1