2016-04-21 241 views
0

在以下簡化的JavaFx程序中,它一直說應用程序不響應。當我註釋掉Platform.runLater(新的Runnable(){...}它不會崩潰。任何想法是錯誤的,我怎麼能解決這個問題?JavaFx Platform.runLater應用程序未響應

package apptest; 

import java.awt.BorderLayout; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Rectangle; 
import javafx.application.Platform; 
import javafx.embed.swing.JFXPanel; 
import javafx.scene.Scene; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.web.WebEngine; 
import javafx.scene.web.WebView; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 


public class apptest { 


    public static JFXPanel jfxPanel = new JFXPanel();   


    public static void main(String[] args){ 

     final JFrame frame = new JFrame(); 


     Platform.runLater(new Runnable() { 

     @Override 
     public void run() { 

     JPanel login = new JPanel(); 
     login.setLayout(new BorderLayout()); 
     login.setBounds(0, 0, 415, 180);  


     WebView webView = new WebView(); 
     WebEngine engine = webView.getEngine(); 
     engine.load("http://www.google.com"); 

     VBox root = new VBox(webView); 
     root.setStyle("-fx-focus-color: transparent;"); 
     Scene scene = new Scene(root,414,179);  

     ScrollPane scrollPane = new ScrollPane(); 
     scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); 
     scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); 
     scrollPane.setContent(webView);        

     root.getChildren().addAll(scrollPane); 
     jfxPanel.setScene(scene); 
     frame.add(login, BorderLayout.NORTH); 
     login.add(jfxPanel, BorderLayout.NORTH); 

     } 

     }); 


     frame.setLayout(null); 
     frame.setSize(415,180); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.setResizable(false); 
     frame.setAlwaysOnTop(true); 
     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     GraphicsDevice defaultScreen = ge.getDefaultScreenDevice(); 
     Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds(); 
     int x = 10; 
     int y = (int) rect.getMaxY() - (frame.getHeight() + 50);   
     frame.setLocation(x, y); 
     frame.setVisible(true); 


    } 

    } 

回答

0

答案之前,我想問你是否真的需要將JavaFX嵌入到Swing應用程序中這些是兩種不同的工具包,兩者一起使用會使事情變得非常困難,尤其是因爲你必須管理兩個不同的執行線程(AWT事件調度線程,所有Swing工作必須在所有的JavaFX工作必須進行的FX應用程序線程上執行)

假設您確實需要將JavaFX嵌入到Swing框架而不是JavaFX Stage中,則需要在其上創建Swing組件AWT ev ent調度線程,使用SwingUtilities.invokeLater(...)。需要使用Platform.runLater()在FX應用程序線程上創建JavaFX控件。在你的代碼中,你在主線程(不是AWT線程)上創建並配置JFrame,並在FX應用程序線程(不是AWT線程)上創建JPanel。我相信這會導致應用程序陷入僵局。

Javadocs for JFXPanel中顯示瞭如何正確線程的基本大綱。

另一個需要注意的是你的佈局結構是錯誤的。您添加webView直接向VBox

VBox root = new VBox(webView); 

但你置於同一webView一個ScrollPane

scrollPane.setContent(webView);        

這增加了相同的組件到場景圖的兩倍,這是不允許的(無論如何也沒有意義)。由於WebView實現了自己的滾動,因此您可以完全省略ScrollPane

您的應用程序代碼,再假設你需要混合的Swing和JavaFX,應該像

import java.awt.BorderLayout; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Rectangle; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

import javafx.application.Platform; 
import javafx.embed.swing.JFXPanel; 
import javafx.scene.Scene; 
import javafx.scene.layout.VBox; 
import javafx.scene.web.WebEngine; 
import javafx.scene.web.WebView; 

public class apptest { 


    public static void main(String[] args) { 

     // Create swing components on AWT thread: 

     SwingUtilities.invokeLater(() -> { 
      final JFrame frame = new JFrame(); 
      JPanel login = new JPanel(); 
      login.setLayout(new BorderLayout()); 
      login.setBounds(0, 0, 415, 180); 
      JFXPanel jfxPanel = new JFXPanel(); 
      frame.add(login, BorderLayout.NORTH); 
      login.add(jfxPanel, BorderLayout.NORTH); 

      // Create JavaFX content on FX Application Thread: 

      Platform.runLater(new Runnable() { 

       @Override 
       public void run() { 


        WebView webView = new WebView(); 
        WebEngine engine = webView.getEngine(); 
        engine.load("http://www.google.com"); 

        VBox root = new VBox(webView); 
        root.setStyle("-fx-focus-color: transparent;"); 
        Scene scene = new Scene(root, 414, 179); 

        jfxPanel.setScene(scene); 

       } 

      }); 

      frame.setLayout(null); 
      frame.setSize(415, 180); 
      frame.setLocationRelativeTo(null); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      frame.setResizable(false); 
      frame.setAlwaysOnTop(true); 
      GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
      GraphicsDevice defaultScreen = ge.getDefaultScreenDevice(); 
      Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds(); 
      int x = 10; 
      int y = (int) rect.getMaxY() - (frame.getHeight() + 50); 
      frame.setLocation(x, y); 
      frame.setVisible(true); 


     }); 

    } 


}