【问题标题】:(JavaFX WebEngine) JavaScript-to-Java Calls Work Inconsistently(JavaFX WebEngine) JavaScript 到 Java 调用工作不一致
【发布时间】:2017-11-19 22:39:57
【问题描述】:

早安,

我的应用程序的自定义最小化和关闭按钮工作不一致时遇到问题。我想在推进这个项目并使它变得更复杂之前解决这个问题。


背景

该应用程序是一个未经修饰的 JavaFX 阶段,其中包含一个 WebView,它加载由嵌入式 Tomcat 服务器托管的 JSP。 minimizeclose 按钮是 JSP 中的 HTML,并具有 onclick 侦听器,它们调用 Java 方法以通过 JavaScript-to-Java 接口类最小化和关闭应用程序, AppHandle 和一个委托类 AppUtility


问题

按钮工作,但工作不一致。此外,只要按钮确实随机失效,它们就会一起失效。

例如

  • 启动应用,按钮不起作用。
  • 启动应用程序,按钮工作。最小化应用程序,最大化应用程序 - 现在按钮不起作用。
  • 启动应用程序,按钮工作。将应用程序最小化和最大化一次,按钮仍然有效。再做一两次 - 现在按钮不起作用了。

代码

JavaFX 组件

Stage
|  
\-- StackPane
   |  
   \-- Browser (contains the WebView/WebEngine)

Browser 类扩展了Region 并包含WebView 及其WebEngine。这是 AppHandle 类绑定到 JSP 中的“app”标签的地方。

public Browser(String page, final AppUtility utility) {
  browser.setFontSmoothingType(FontSmoothingType.GRAY);
  browser.setContextMenuEnabled(false);

  webEngine.getLoadWorker().stateProperty()
    .addListener(
      new ChangeListener<State>() {
        @Override
        public void changed(ObservableValue<? extends State> ov, 
            State oldState, State newState) { 
          if (newState == State.SUCCEEDED) {
            JSObject win = (JSObject) webEngine.executeScript("window");
            win.setMember("app", new AppHandle(utility));
          }
        }
      }
    );
  webEngine.load(page);
  getChildren().add(browser);
}

这是 JSP 的相关部分,其中按钮调用 AppHandler 方法 onclick

<div class="container-app">
  <div class="text-title">myApp</div>

  <div class="icon utility minimize" onclick="app.hide()">
    <i class="fa fa-window-minimize" aria-hidden="true"></i>
  </div>

  <div class="icon utility close" onclick="app.exit()">
    <i class="fa fa-times" aria-hidden="true"></i>
  </div>
</div>

这是AppHandle 类,它的方法是从JSP 中的onclick 事件中调用的。如果我将print 语句放在exit()hide() 类中,当按钮失败时它们将不会执行。这让我相信JSObject 出现了问题。

public class AppHandle {
  private AppUtility utility;

  public AppHandle(AppUtility utility) {
    this.utility = utility;
  }

  public void exit() {
    utility.exit();
  }

  public void hide() {
    utility.hide();
  }
}

AppUtility 方法作用于 JavaFX Stage 以隐藏和关闭 JavaFX Application。我最初认为我的show/hide/inconified 逻辑可能有问题,但是当按钮失败时,这段代码甚至不会被执行。

public void exit() {
  if (SystemTray.isSupported())
    SystemTray.getSystemTray().remove(app.getTrayIcon());
  Platform.exit();
  System.exit(0);
}

public void hide() {        
  if (SystemTray.isSupported()) {
    try {
      SystemTray.getSystemTray().add(app.getTrayIcon());
      displayIconDialogue();
    } catch (AWTException e) {
      e.printStackTrace();
    }
  }
  app.getWindow().setIconified(true);
  app.getWindow().hide();
}

public void show() {
  if (SystemTray.isSupported())
    SystemTray.getSystemTray().remove(app.getTrayIcon());
  app.getWindow().setIconified(false);
  app.getWindow().show();
}

问题

  1. 如何在运行时评估我的 JSObject 的“健康状况”,看看它是否是罪魁祸首?

  2. 这里有什么东西会在启动时明确中断 JSP 和 AppHandle 之间的连接吗?在minimize?在show

如果它根本不起作用,这会更容易,我不确定不一致来自哪里。

任何帮助将不胜感激,

谢谢。

【问题讨论】:

    标签: javascript java jsp javafx jsobject


    【解决方案1】:

    呸,我解决了。让这成为我更好地寻找问题的一个教训。

    This question 让我知道了这个问题。

    我正在JSObject 中本地创建AppHandle。我想在某些时候本地 AppHandle 被取消引用,我的 JSP-to-Java 连接随之而来。

    我现在在AppClient 中创建AppHandle 并将其传递给Browser。这样,应用程序维护对句柄的引用。 Browser 构造函数更改为:

    public Browser(String page, AppHandle handle) {
      browser.setFontSmoothingType(FontSmoothingType.GRAY);
      browser.setContextMenuEnabled(false);
    
      webEngine.getLoadWorker().stateProperty()
        .addListener(
          new ChangeListener<State>() {
            @Override
            public void changed(ObservableValue<? extends State> ov, 
                State oldState, State newState) { 
              if (newState == State.SUCCEEDED) {
                JSObject win = (JSObject) webEngine.executeScript("window");
                win.setMember("app", handle);
              }
            }
          }
        );
      webEngine.load(page);
      getChildren().add(browser);
    }
    

    【讨论】:

    • 非常感谢。这也解决了我的问题。我想知道匿名声明时是否会收集垃圾或其他东西。官方文档提出了在本地创建它的讨厌的事情。 ?
    猜你喜欢
    • 2015-04-25
    • 1970-01-01
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2013-07-07
    相关资源
    最近更新 更多