SWT Programm pausiert ungewollt

Mizar

Aktives Mitglied
Hallo,

ich bin gerade dabei mich mit SWT zu beschäftigen und bin dabei auf ein Verhalten gestoßen, das ich mir nicht so recht erklären kann. Und zwar hält mein Programm einfach ungewollt an wenn man eine gewisse Zeit lang nichts macht. Da dieses Verhalten in einem Programm auftritt, dessen Code mehrere hundert Zeilen lang ist und ich euch einen so langen Code nicht zumuten möchte, habe ich einen Code geschrieben der ähnlich aufgebaut ist, das gleiche Verhalten aufweist, aber deutlich kürzer und zudem kompilierbar ist. Und so schaut er aus:
Folgender Code startet schlichtweg die Anwendung:
Java:
import org.eclipse.swt.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class Main
{
	public void startGui()
	{
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		
		ClockWidget clock = new ClockWidget(shell, SWT.NO_BACKGROUND);
		clock.startClock();
		
		shell.pack();
		shell.open();
		while(!shell.isDisposed()) {
			if(!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}
	
	public static void main(String[] args)
	{
		new Main().startGui();
	}
}
Und das dazugehörige ClockWidget:
Java:
import java.util.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

public class ClockWidget extends Canvas implements Runnable
{
	private Composite parent;	
	private Calendar calendar;
	private boolean running;
	private String timeString;
	private Color circleColor;
	private Point circleSize;
	
	private static final Point MAX_CIRCLE_SIZE = new Point(100, 100);
	
	public ClockWidget(Composite parent)
	{
		this(parent, 0);
	}
	
	public ClockWidget(Composite parent, int style)
	{
		super(parent, style);
		this.parent = parent;
		this.calendar = new GregorianCalendar();
		this.running = false;
		this.timeString = "" + calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE) + ":" + calendar.get(Calendar.SECOND);
		this.circleColor = new Color(getDisplay(), 0, 0, 255);
		this.circleSize = new Point(0, 0);
		
		addDisposeListener(new DisposeListener()
		{
			@Override
			public void widgetDisposed(DisposeEvent e)
			{
				ClockWidget.this.widgetDisposed(e);
			}
		});
		addPaintListener(new PaintListener()
		{
			@Override
			public void paintControl(PaintEvent e)
			{
				ClockWidget.this.paintControl(e);
			}
		});
	}
	
	public void startClock()
	{
		if(!running) {
			running = true;
			Thread t = new Thread(this);
			t.start();
		}
	}
	
	@Override
	public void run()
	{
		long lastTime = System.nanoTime();
		long delta = 0;
		long framelimitTime = (long)1e9 / 60;
		long sleepTime = 0;
		
		while(running) {
			
			delta = System.nanoTime() - lastTime;
			sleepTime = framelimitTime - delta;
			lastTime = System.nanoTime();
			
			calendar.setTimeInMillis(System.currentTimeMillis());
			timeString = "" + calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE) + ":" + calendar.get(Calendar.SECOND);
			circleSize.x = MAX_CIRCLE_SIZE.x * calendar.get(Calendar.SECOND) / 60;
			circleSize.y = MAX_CIRCLE_SIZE.y * calendar.get(Calendar.SECOND) / 60;
			
			getDisplay().syncExec(new Runnable()
			{
				@Override
				public void run()
				{
					if(parent.isDisposed()) {
						running = false;
						return;
					}
					redraw();
				}
			});
			
			if(sleepTime > 0) {
				try {
					Thread.sleep(sleepTime / (long)1e6);
				} catch(InterruptedException e) {
					running = false;
				}
			} else {
				Thread.yield();
			}
		}
	}
	
	@Override
	public Point computeSize(int wHint, int hHint, boolean changed)
	{
		Image image = new Image(getDisplay(), 1, 1);
		GC gc = new GC(image);
		Point size = gc.stringExtent(timeString);
		gc.dispose();
		image.dispose();
		size.x += MAX_CIRCLE_SIZE.x;
		size.y += MAX_CIRCLE_SIZE.y;
		return new Point(wHint == SWT.DEFAULT ? size.x : wHint, hHint == SWT.DEFAULT ? size.y : hHint);
	}
	
	private void paintControl(PaintEvent e)
	{
		Image image = new Image(getDisplay(), getBounds());
		GC gc = new GC(image);
		
		gc.drawText(timeString, 0, 0);
		gc.setBackground(circleColor);
		gc.fillOval(gc.stringExtent(timeString).x, 0, circleSize.x, circleSize.y);
		
		e.gc.drawImage(image, 0, 0);
		
		gc.dispose();
		image.dispose();
	}
	
	private void widgetDisposed(DisposeEvent e)
	{
		running = false;
		circleColor.dispose();
	}
}
Ich konnte mit Hilfe von Debug-Ausgaben das Auftreten dieser plötzlichen Pausierung des Programmes auf Zeile 79 der ClockWidget-Klasse eingrenzen. Also sobald dort die syncExec-Methode aufgerufen wird, pausiert das Programm plötzlich wenn man längere Zeit nichts macht (also keine Tasten drückt, die Maus nicht bewegt, etc. während das Programm läuft). Es scheint so als würde das in der Main-Klasse erstellte Display-Objekt einfach "schlafen", da es durch das Nichtstun keine Events zum abarbeiten gibt und durch den synchronen Aufruf innerhalb der ClockWidget-Klasse wird damit eben auch mein Thread lahmgelegt.
Meine Frage: Kennt jemand evtl. einen Weg ein (vermutlich) eingeschlafenes Display mittels Code wieder aufzuwecken? Oder sollte man anders vorgehen als ich, wenn man von einem anderem Thread aus als dem UI-Thread ein Widget ständig aktualisieren muss?

Schon einmal vielen Dank im voraus für jeden Tipp :)
 

Mizar

Aktives Mitglied
Ich habe mich weiter mit dem Problem beschäftigt, kam allerdings auf eine nicht ganz zufriedenstellende (vorläufige) Lösung. Also dann:
Was bisher geschah... :lol:
Ich entdeckte die wake()-Methode des Displays. Damit versuchte ich nun an mehreren Stellen des Codes das Display aufzuwecken. Hier mal ein Überblick darüber, wo ich die wake()-Methode überall versucht hatte aufzurufen:
Java:
getDisplay().wake();
getDisplay().syncExec(new Runnable()
{
	@Override
	public void run()
	{
		if(parent.isDisposed() || ClockWidget.this.isDisposed()) {
			running = false;
			return;
		}
		ClockWidget.this.getDisplay().wake();
		redraw();
	}
});
getDisplay().wake();
Natürlich hatte ich immer nur einen Aufruf der wake()-Methode im Code gehabt. Gebracht hatte es mir aber gar nichts. Das Programm hielt trotzdem nach kurzer Zeit der Inaktivität des Nutzers an.

Als nächstes stolperte ich in der SWT-API noch über eine Sache, von der ich glaubte das sie mir mehr bei diesem Problem helfen könnte. Und zwar heißt es bei der readAndDispatch()-Methode eines Displays unter anderem:
In addition to checking the system event queue, this method also checks if any inter-thread messages (created by syncExec() or asyncExec()) are waiting to be processed, and if so handles them before returning.
Das hörte sich doch schon ziemlich gut an. Nach etwas nachdenken hatte ich dann folgende Änderungen in der EventLoop der Main-Klasse vorgenommen:
Java:
while(!shell.isDisposed()) {
	if(!display.readAndDispatch()) {
		// display.sleep();
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {}
	}
}
Also, das Display schlief nicht mehr, sondern legte stattdessen nur noch kleine Pausen ein. Allerdings bin ich damit nicht wirklich zufrieden. Es scheint zwar mit diesen Änderungen erstmal zu funktionieren, aber ich denke nicht das dies wirklich eine saubere Lösung ist.

Darum nun erneut die Frage nach Tipps, Hilfestellungen und Vorschlägen zu diesem Problem. Denn ich bin mit meinem Latein so ziemlich am Ende und weiß nicht mehr so recht weiter. Oder soll diese vorläufige Lösung tatsächlich die Beste sein in SWT, um dieses Problem zu beheben? ???:L
 
Zuletzt bearbeitet:

Mizar

Aktives Mitglied
Okay, offenbar hat mein 2. Beitrag mehr verwirrt als geholfen. Darum noch eine kurze Erklärung um die Angelegenheit klarer zu machen.

Mit genau dem Code der sich in meinem 1. Beitrag befindet pausiert das Programm nach kurzer Zeit der Inaktivität des Nutzers. Also genau mit dieser Eventloop in der Main-Klasse:
Java:
while(!shell.isDisposed()) {
    if(!display.readAndDispatch()) {
        display.sleep();
    }
}
Und eben auch mit dieser üblichen SWT-Eventloop habe ich versucht das Problem mit dem Aufruf der wake()-Methode zu lösen, was aber, wie schon gesagt, nicht funktionierte.

Auf die folgende Eventloop kam ich dann nachdem ich in der SWT-API mehr über die readAndDispatch()-Methode erfahren hatte:
Java:
while(!shell.isDisposed()) {
    if(!display.readAndDispatch()) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {}
    }
}
Damit scheint das plötzliche Pausieren nicht mehr aufzutreten, aber ich denke eben nicht das dies eine saubere Lösung ist.
wie lange muss man denn da überhaupt warten? ich habs kurz mal probiert, aber bei mir hat nix pausiert :/
Wenn ich das Programm starte und danach absolut nichts mehr mache (keine Maus bewegen, keine Tasten drücken, etc.), dann pausiert das Programm oft schon innerhalb einer Minute (wohlgemerkt mit der "display.sleep()"-Loop). Manchmal kann es aber auch etwas länger dauern.

Ich hänge mal noch einen Screenshot an auf dem man sehen kann, dass das Programm, nach dem es ungewollt pausiert ist, partout nicht mehr von alleine weiterlaufen will. Auch, wie man sieht, nach dem man mehrere Minuten gewartet hat. Erst wenn man z. B. eine Taste drückt oder die Maus bewegt läuft es wieder ganz normal weiter.
 

Anhänge

  • angehalten.jpg
    angehalten.jpg
    6,5 KB · Aufrufe: 22
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
Juelin starten maven javafx programm ohne netbeans AWT, Swing, JavaFX & SWT 38
P AWT Programm funktioniert nicht richtig AWT, Swing, JavaFX & SWT 35
G CAD Programm AWT, Swing, JavaFX & SWT 4
thor_norsk E - Mail Programm AWT, Swing, JavaFX & SWT 2
_user_q Über installDist exportiertes Programm wirft "Unsupported JavaFX configuration" AWT, Swing, JavaFX & SWT 0
CodingBerlin JavaFX Programm läuft nur unter Eclipse AWT, Swing, JavaFX & SWT 1
J Programm findet Resource nicht. AWT, Swing, JavaFX & SWT 6
N Programm Läuft nicht auf anderen Pcs AWT, Swing, JavaFX & SWT 9
imawake Java Paket-Tracking Programm 📦 AWT, Swing, JavaFX & SWT 7
S Lustiges programm schnell coden? AWT, Swing, JavaFX & SWT 2
O Ein Java-Programm mit Swing steuern AWT, Swing, JavaFX & SWT 1
P Swing Programm hängt sich bei Buttondruck auf? (GUI für "Chatbot" erstellen) AWT, Swing, JavaFX & SWT 15
M DragAndDrop - aus Browser ins Programm AWT, Swing, JavaFX & SWT 6
T Java GUI - Würfel Programm AWT, Swing, JavaFX & SWT 6
JojoSand Java Programm wird nicht gestartet - keinen Fehlerhinweis AWT, Swing, JavaFX & SWT 9
SvenPittelkow Programm soll auf JButton warten bis der geklickt wurde AWT, Swing, JavaFX & SWT 1
I Gui in bestehendes Java-Programm AWT, Swing, JavaFX & SWT 11
L JavaFX IntelliJ Standalone Programm exportieren AWT, Swing, JavaFX & SWT 9
Bluedaishi JavaFX Programm start mit zwei scenen bzw Fenster AWT, Swing, JavaFX & SWT 1
M AWT Programm in den Tray minimieren AWT, Swing, JavaFX & SWT 2
steven789hjk543 Swing Weiß jemand, warum dieses Programm nicht funktioniert? AWT, Swing, JavaFX & SWT 7
A Java Programm gestalten AWT, Swing, JavaFX & SWT 4
P Swing Warum startet das Programm nicht? AWT, Swing, JavaFX & SWT 3
J JavaFX Kamera im Programm öffnen AWT, Swing, JavaFX & SWT 6
H Hintergrundbild in einem Programm AWT, Swing, JavaFX & SWT 4
MR._FIRE_Flower progressBar in ein bestehendes Programm einbauen AWT, Swing, JavaFX & SWT 3
J Verbesserungsvorschläge?! Kleines AWT Programm AWT, Swing, JavaFX & SWT 4
A Programm nun in ein Frame basteln AWT, Swing, JavaFX & SWT 1
A Swing Programm funktioniert aber zwei Buttons werden angezeigt AWT, Swing, JavaFX & SWT 3
G Zeichnen Programm AWT, Swing, JavaFX & SWT 1
R Swing Programm läuft nur beim Debuggen korrekt ab AWT, Swing, JavaFX & SWT 4
Arif Swing Programm friert ein... AWT, Swing, JavaFX & SWT 2
apple_pie1998 Programm gibt plötzlich exceptions aus. AWT, Swing, JavaFX & SWT 4
N Swing Wie Programm strukturieren? (Dynamisch Komponenten hinzufügen) AWT, Swing, JavaFX & SWT 1
N JLabel ändern während Programm ausgeführt wird AWT, Swing, JavaFX & SWT 4
X JMenu Menu-Bar ausrichtung ändern im Programm AWT, Swing, JavaFX & SWT 0
T Swing Programm hängt sich auf! AWT, Swing, JavaFX & SWT 23
L Probleme mit Programm AWT, Swing, JavaFX & SWT 13
S Grafik: Programm kommt nicht zur paint()-Methode AWT, Swing, JavaFX & SWT 6
P Programm durch Dateiaufruf starten und Datei öffnen AWT, Swing, JavaFX & SWT 2
S Action durchführen beim Programm beenden AWT, Swing, JavaFX & SWT 3
N Programm mit Swing und Thread, Figur bewegen sich nicht AWT, Swing, JavaFX & SWT 6
G Programm GUI erstellen AWT, Swing, JavaFX & SWT 5
L JButton flackern - Programm hängt sich auf AWT, Swing, JavaFX & SWT 3
T Programm im METRO Design? AWT, Swing, JavaFX & SWT 1
J Programm hängt sich bei Log In auf AWT, Swing, JavaFX & SWT 1
C Programm mit Passwort schließen AWT, Swing, JavaFX & SWT 5
D Robot Programm mit Escape abbrechen (aus Eclipse heraus) AWT, Swing, JavaFX & SWT 2
N Programm läuft perfekt in Eclipse aber nicht in .JAR AWT, Swing, JavaFX & SWT 3
S JScrollPane --> Programm hängt sich beim scrollen auf AWT, Swing, JavaFX & SWT 2
J Programm im GUI ausführen AWT, Swing, JavaFX & SWT 4
A Probleme mit 2 JFrames in einem Programm AWT, Swing, JavaFX & SWT 7
S Event Handling konsole Programm mit Tastendruck beenden AWT, Swing, JavaFX & SWT 5
G JTextArea on the fly aus anderem Programm befüllen AWT, Swing, JavaFX & SWT 4
K Swing Konsolen Programm in GUI - Suche Hilfe bei Konsolenausgabe AWT, Swing, JavaFX & SWT 2
W Windows Fenster in einem Programm AWT, Swing, JavaFX & SWT 2
F Mal Programm AWT, Swing, JavaFX & SWT 13
C In Hauptfenster Programm-Klassen implementieren AWT, Swing, JavaFX & SWT 9
A KeyListener Button wechseln & Programm beenden AWT, Swing, JavaFX & SWT 4
C Swing Wie kann ich im Programm das Menü schließen AWT, Swing, JavaFX & SWT 2
J SWING - Programm ohne Eclipse etc. starten AWT, Swing, JavaFX & SWT 7
J Button soll nach Klick Text ändern und Programm in 3 Sekunden beenden AWT, Swing, JavaFX & SWT 6
M Programm hängt sich auf nachdem repaint() benutzt wurde AWT, Swing, JavaFX & SWT 2
M Programm in Jframe "einbinden" AWT, Swing, JavaFX & SWT 7
S Programm auf aktuellen Stand bringen AWT, Swing, JavaFX & SWT 2
Spin Tool: Popup -Programm AWT, Swing, JavaFX & SWT 3
GUI-Programmer Swing JWindow - Programm wird ohne Grund beendet AWT, Swing, JavaFX & SWT 3
E Kreis-Mal-Programm AWT, Swing, JavaFX & SWT 7
P Programm aktuallisiert sich nur beim Rüberzeigen AWT, Swing, JavaFX & SWT 6
T Java-Anwendung arbeitet Programm in seltsamer Reihenfolge ab AWT, Swing, JavaFX & SWT 3
C Programm für 5 sekunden anhalten und actionevent abfangen AWT, Swing, JavaFX & SWT 18
J Programm schließen AWT, Swing, JavaFX & SWT 4
J Programm nur einmal öffnen AWT, Swing, JavaFX & SWT 3
E Windows Kontext Menü - Laufendes Programm AWT, Swing, JavaFX & SWT 3
T Programm vom Desktop starten! AWT, Swing, JavaFX & SWT 2
S Programm pausieren während JDialog offen ist AWT, Swing, JavaFX & SWT 2
M Browser in Programm einbinden AWT, Swing, JavaFX & SWT 4
R Durch Listener lässt sich Programm nicht mehr ausführen AWT, Swing, JavaFX & SWT 4
H Userinput in GUI an externes Programm AWT, Swing, JavaFX & SWT 8
D Firefox aus Programm starten AWT, Swing, JavaFX & SWT 4
S LayoutManager Einfaches Programm mit VE und Eclipse3.6 realisieren AWT, Swing, JavaFX & SWT 2
J SWT 32 bit Programm für 64 bit Jave AWT, Swing, JavaFX & SWT 10
R GUI hängt während Programm läuft AWT, Swing, JavaFX & SWT 7
S AWT Fenster schließen und Programm beenden AWT, Swing, JavaFX & SWT 10
H Infofenster vor dem eigentlichen Java Programm AWT, Swing, JavaFX & SWT 3
B Uberschrift in Swing-Programm zur Laufzeit aendern... AWT, Swing, JavaFX & SWT 4
C Swing Kleines Programm mit SWING unter Verwendung von MVC AWT, Swing, JavaFX & SWT 5
capgeti Wie Programm in JPanel (o.ä.) starten? AWT, Swing, JavaFX & SWT 3
B Externes Programm mit Robot Steuern AWT, Swing, JavaFX & SWT 3
G Programm läuft nur auf manchen Rechnern AWT, Swing, JavaFX & SWT 10
K Website in Java Programm einbinden AWT, Swing, JavaFX & SWT 3
B komplettes programm in einem fenster AWT, Swing, JavaFX & SWT 5
L Frage bei Programm mit Zufallskreisen AWT, Swing, JavaFX & SWT 9
L Programm terminated (zu frueh) AWT, Swing, JavaFX & SWT 3
T SplashScreen im laufenden Programm AWT, Swing, JavaFX & SWT 2
M Panelinhalt im Programm verändern AWT, Swing, JavaFX & SWT 12
R Programm nicht mehr in der Taskleiste AWT, Swing, JavaFX & SWT 2
3TageBart Ebenen in Zeichen-Programm implementieren AWT, Swing, JavaFX & SWT 9
H Swing HUD in externes Programm einblenden AWT, Swing, JavaFX & SWT 7
R Japaner koennen mein Programm nicht nutzen..? AWT, Swing, JavaFX & SWT 11

Ähnliche Java Themen

Neue Themen


Oben