JavaFx Platform.runLater应用程序无响应

时间:2016-04-21 10:14:52

标签: java javafx webview

在下面简化的JavaFx程序中,它一直说Application Not Responsive。当我注释掉Platform.runLater(新的Runnable(){...}时,它不会崩溃。任何想法有什么问题以及如何解决它?

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


    }

    }

1 个答案:

答案 0 :(得分:0)

在回答之前,我想问一下你是否真的需要在Swing应用程序中嵌入JavaFX。这是两个不同的工具包,并且两者结合使用会使事情变得非常困难,特别是因为您必须管理两个不同的执行线程(AWT事件调度线程,必须在其上进行所有Swing工作)和FX Application Thread,必须进行JavaFX工作。)

假设您确实需要在Swing框架而不是JavaFX Stage中嵌入JavaFX,则需要使用SwingUtilities.invokeLater(...)在AWT事件分派线程上创建Swing组件。需要使用Platform.runLater()在FX Application线程上创建JavaFX控件。在您的代码中,您在主线程(而不是AWT线程)上创建和配置JFrame并在FX应用程序线程上创建JPanel(再次,而不是AWT线程)。我相信这会导致应用程序陷入僵局。

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


        });

    }


}
相关问题