2016-04-21 242 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); 


     }); 

    } 


}