JAVA - how to modify SWT UI while looping in thread


JAVA - how to modify SWT UI while looping in thread



I'm trying to implement a Desktop app that loops trough a function and sets a textfield on the UI every 1 sec.



But I either get


org.eclipse.swt.SWTException: Invalid thread access



when I don't use the display



or the UI is really sluggish when I do


display.asyncExec(new Runnable() {



My code looks like this:


public void open() {
Display display = Display.getDefault();
shell = new Shell();
shell.setSize(486, 322);
shell.setText("SWT Application");

Button btnStartLoop = new Button(shell, SWT.NONE);
btnStartLoop.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() // updates displayArea
{
while (true) {
try {
text.setText("Text has been set");
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
});
btnStartLoop.setBounds(35, 30, 75, 25);
btnStartLoop.setText("Start Loop");

text = new Text(shell, SWT.BORDER);
text.setText("0");
text.setBounds(116, 32, 177, 21);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}



is there any way this can be overcome?




1 Answer
1



You must never sleep in the UI thread. You must use a new Thread for the background activity. You call Display.asyncExec from within the thread to run the UI update code in the UI thread.


Thread


Display.asyncExec


btnStartLoop.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(final MouseEvent e) {
final Thread background = new Thread(new Runnable() {
public void run()
{
while (true) {
try {
Display.getDefault().asyncExec(() -> text.setText("Text has been set"));
Thread.sleep(1000);
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
background.start();
}
});



Note: SwingUtilities is for Swing applications, do not use it in SWT apps.


SwingUtilities



You can also use the timerExec method of Display to run code after a specific delay which avoids the need for a background thread.


timerExec


Display


btnStartLoop.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(final MouseEvent e) {
final Runnable update = new Runnable() {
public void run()
{
text.setText("Text has been set");

Display.getDefault().timerExec(1000, this);
}
};
Display.getDefault().timerExec(0, update);
}
});





yep, that was it. thanks a lot @greg-449 !
– Daniel S
Jul 1 at 8:31






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

List of Kim Possible characters

Audio Livestreaming with Python & Flask

NSwag: Generate C# Client from multiple Versions of an API