在 JavaFX 中发现可能的故障

Possible Glitch found in JavaFX

抱歉,标题含糊不清,但我想我在 JavaFX BorderPane class 中发现了一个小故障,但我并不肯定。所以我正在做的是 运行 这个方法在 javaFx 并发任务 object 中,它在一个线程中。此方法一直有效,直到它命中打印语句。它打印出 1,然后不通过 root.setCenter 方法。如果我注释掉该代码,它会继续运行,否则它会卡在上面,就像它处于无限循环中一样。重要的是要注意根(一个 boderpane object)本地存储在 JavaFX 主线程中。感谢您的任何建议。

  // will be used to store all the sites we still need to visit so we can do
  // a breadth first graph traversal of the hostsite
  Queue<URL> unvistedURLs = new LinkedList<>();
  LinkedList<Text> currentLevelText = new LinkedList<>();
  Queue<URL> levelCheckpoints = new LinkedList<>();
  int currentLevelHieght = 0;

  // the origional host
  String hostName = origin.getHost();

  // temporary objects
  HTMLLinks endHTMLLinks = null;
  try
  {
     endHTMLLinks = new HTMLLinks(origin);
  }
  catch (IOException e1)
  {
     // TODO Auto-generated catch block
     e1.printStackTrace();
  }

  HostSiteInfo hostSiteInfo = new HostSiteInfo();
  URL currentURL;
  Group displayArea = new Group();

  System.out.println(1);
  root.setCenter(displayArea);
  System.out.println(2);
  // imediatley input the host as a site we need to visit
  unvistedURLs.add(origin);
  levelCheckpoints.offer(origin);


@Override
public void start(Stage primaryStage)
{
  try
  {
     final BorderPane root = new BorderPane();
     Scene scene = new Scene(root, 1600, 1000);

     @SuppressWarnings("rawtypes")
     Thread renderThread = new Thread(new Task(){

        @Override
        protected Object call() throws Exception
        {
           try
           {

              WebSpider.traverseURLs(root,
                    new URL("http://www.georgefox.edu/"),
                    new PrintStream(System.out));
           }
           catch (MalformedURLException e)
           {
              // TODO Auto-generated catch block
              e.printStackTrace();
           }

           return null;
        }});

     renderThread.setDaemon(true);
     renderThread.start();

JavaFx 应用程序的根在这个启动方法中被初始化。

假设 root.setCenterTask 中被调用(这在您的代码中并不清楚),您会收到异常,因为您正试图从 JavaFX 以外的线程修改场景图UI 线程。由于这是在 Task 内完成的,异常会被任务捕获,您最终看不到它。

要解决此问题,请将 root.setCenter(displayArea) 替换为

Platform.runLater(() -> root.cetCenter(displayArea)); 

参见Platform#runLater

为了能够发现此类问题,最好为您的 Task 设置一个 onFailed 处理程序:

Task<Void> myTask = new Task<>() {
    ...
}
myTask.setOnFailed(workerStateEvent -> {
     System.out.println("Something wrong happened...");
     myTask.getException().printStackTrace();
     // Or handle the problem however suits your application. 
});