繁体   English   中英

当部署为Java Web Start时,SWT在Linux上挂起/冻结

[英]SWT hangs/freezes on Linux, when deployed as Java Web Start

我正在使用的Java WebStart应用程序将SWT用于GUI,最近我意识到了一个小而烦人的问题。 当我选择使用FileDialog即保存图像)时,对话框关闭后用户界面立即冻结。 该图像已保存,可以使用默认的图像查看器打开,没有任何问题,但是此后该应用程序无响应,因此我被迫终止了该应用程序。

我注意到,当尝试使用FileDialog打开文件时,结果是相同的,如果我改为通过使用jnlp文件将其作为参数发送来打开同一文件,则可以正常工作,因此我认为这不是问题与本地文件系统。

我试图在Windows上复制该问题,只是为了看到它在Win 7上能正常工作。作为第二次尝试进行故障排除,我试图从应用程序的本地版本(换句话说,非JWS)中保存图像,然后效果也很好...

我怀疑jnlp文件存在权限问题,但是所有权限都授予了该应用程序,并且签名也都正常(应用程序启动时指向该事实)。 此外,无论如何都要写入图像文件,因此它实际上不是允许的东西。

有任何想法吗?

更新:看来问题不仅仅取决于FileDialog,还取决于任何形式的图形用户交互。 无论何时部署了SWT窗口,程序都会冻结并显示灰屏。 我已在下面复制了一些代码,在此特定示例中,即使单击“取消”,应用程序也将变为灰屏无响应。 这是一些示例代码:

    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;
}

更新2:顺便说一句,我使用Sun JDK 1.6.0。 这是java -version命令的输出:

Java版本“ 1.6.0_22” Java SE运行时环境(内部版本1.6.0_22-b04)Java HotSpot(TM)64位服务器VM(内部版本17.1-b03,混合模式)

如果SaveFileAction.run()需要很长时间才能运行,则可以解释UI冻结的原因。

在SWT中,运行事件泵是您的责任。 通常情况如下:

while (!shell.isDisposed()) {
  if (!display.readAndDispatch()) {
    display.sleep();
  }
}

但是由于SWT也是单线程的,因此一次仅处理一个事件。 因此,如果事件侦听器花费很长时间运行,则UI将不可用,直到该侦听器完成并且控件返回到事件泵为止。

当需要长时间运行的操作时,在SWT中建议的做法是在工作线程中执行该操作,并根据需要向UI发送异步更新。

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);
      }
    } );
  }
} );

此项目在SWT FAQ解释更详细的线程模型。

SWT中存在一个导致此问题的错误: 这里

该错误最近已得到解决-有关更多信息,请参见该错误。

我只是有一个类似的问题。 我通过使用IcedTea Java 6 Webstart(OpenJDK的javaws )而不是Oracle的javaws启动jnlp文件解决了该问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM