Reputation: 6562
The Java WebStart application I am working on uses SWT for GUI, and I have recently realized a small but annoying problem. When I choose an action that uses a FileDialog
i.e. save the image, the user interface freezes immediately after the dialog closes.
The image is saved, and can be opened with a default image viewer without any problem, but the application is non-responsive from then on, and I am forced to kill the application.
I noticed that the result is the same when try to open a file using a FileDialog
, if I instead open the same file by sending it as an argument by using the jnlp file, it works fine, so I don't think it's a problem with the local filesystem.
I have tried to replicate the problem on windows only to see that it works fine on Win 7. As a second attempt to troubleshoot, I tried to save an image from the local version of the application (in other words, non-JWS) and that works fine as well...
I was suspecting a permissions problem on the jnlp file, but all-permissions are given to the application, and signatures are all ok as well (the fact that the app starts points to that). Besides the image file is written anyways, so it can't really be a permission thing.
Any ideas?
UPDATE: It appears as there the problem doesn't only depend on FileDialog but any kind of graphical user interaction. Whenever SWT windows are deployed the program freezes with a gray screen, AFTER whatever action that was supposed to be done. I have copied some code below, in this particular example even if I click Cancel, the application becomes non-responsive with a gray screen. Here's some sample code:
public static boolean saveChangesBeforeDiscard(MyMain main)
{
if (main.isDirty())
{
MessageBox messageBox = new MessageBox(
main.getShell(),
SWT.ICON_WARNING | SWT.YES | SWT.NO | SWT.CANCEL);
messageBox.setMessage("Would you like to save the changes?");
messageBox.setText(MyMain.TOOL_NAME);
int answer = messageBox.open();
if (answer == SWT.YES)
{
SaveFileAction save = new SaveFileAction(main);
save.run();
return save.isSaved();
}
else if (answer == SWT.NO)
{
return true;
}
return false;
}
return true;
}
Update 2: Btw I use Sun JDK 1.6.0. Here's the output of the java -version command:
java version "1.6.0_22" Java(TM) SE Runtime Environment (build 1.6.0_22-b04) Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)
Upvotes: 2
Views: 1607
Reputation: 41
I just had a similar problem. I solved it by launching the jnlp
file with IcedTea Java 6 Webstart (OpenJDK's javaws
) instead of Oracle's javaws
.
Upvotes: 0
Reputation: 11
There is a bug in SWT that causes this: here
The bug has recently been resolved - see the bug for more info.
Upvotes: 1
Reputation: 6832
If SaveFileAction.run() takes a long time to run, that would explain the UI freezing.
In SWT, it is your responsibility to run the event pump. Typically it looks something like:
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
But because SWT is also single-threaded, only one event is processed at a time. So if an event listener takes a very long time to run, the UI will be unavailable until that listener finishes and control returns to the event pump.
When long-running operations are required, the recommended practice in SWT is to perform the operation in a worker thread, sending asynchronous updates to the UI as required.
executor.execute( new Runnable() {
public void run() {
showStatusMessage("Saving "+filename+"...");
SaveFileAction save = new SaveFileAction(main);
save.run();
showStatusMessage("File "+filename+" saved.")
}
private void showStatusMessage(final String message) {
Display.getDefault().asyncExec( new Runnable() {
public void run() {
statusLine.setMessage(message);
}
} );
}
} );
This entry on the SWT FAQ explains the threading model in more detail.
Upvotes: 3