【问题标题】:JavaFX WebView grow to fill entire areaJavaFX WebView 增长到填满整个区域
【发布时间】:2017-01-30 05:00:38
【问题描述】:

我正在尝试制作一个扩展到周围 JPanel 的 javafx WebView。根据这个线程:http://www.coderanch.com/t/634791/JavaFX/java/Resizing-HTMLEditor-JavaFX,WebView 中有一个错误,您需要在 WebView 上调用GridPane.setHgrowGridPane.setVgrow。我已经在我的代码中添加了这些调用,但 WebView 仍然是 600x800px。

请注意,场景具有蓝色背景,因此您可以看到 javafx 的内容确实填满了整个 JPanel。但是 WebView 没有填充 javafx 组/场景。

import java.awt.BorderLayout;

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

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;


public class Main {

    private void initAndShowGUI() {
        // This method is invoked on the EDT thread
        JFrame frame = new JFrame("Swing and JavaFX");
        frame.setSize(1000, 1000);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        JPanel panel = new JPanel(new BorderLayout(0, 0));
        frame.getContentPane().add(panel, BorderLayout.CENTER);

        JButton button = new JButton("button");
        panel.add(button, BorderLayout.CENTER);

        final JFXPanel fxPanel = new JFXPanel();
        panel.add(fxPanel, BorderLayout.CENTER);


        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                initFX(fxPanel);
            }
       });
    }

    private WebView webView;

    private void initFX(JFXPanel fxPanel) {
        // This method is invoked on the JavaFX thread
        Scene scene = createScene();
        fxPanel.setScene(scene);

        GridPane.setHgrow(webView, Priority.ALWAYS);
        GridPane.setVgrow(webView, Priority.ALWAYS);
    }

    private Scene createScene() {
        Group root = new Group();
        Scene scene = new Scene(root, Color.ALICEBLUE);

        webView = new WebView();
        GridPane.setHgrow(webView, Priority.ALWAYS);
        GridPane.setVgrow(webView, Priority.ALWAYS);


        WebEngine webEngine = webView.getEngine();
        webEngine.load("http://www.google.com");
        root.getChildren().add(webView);

        GridPane.setHgrow(webView, Priority.ALWAYS);
        GridPane.setVgrow(webView, Priority.ALWAYS);

        return scene;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Main().initAndShowGUI();
            }
        });
    }
}

【问题讨论】:

标签: java swing javafx


【解决方案1】:

实际上,我想我得到了一个基于 http://docs.oracle.com/javafx/2/webview/WebViewSample.java.htm 的解决方案:

import java.awt.BorderLayout;

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

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;


public class WebViewSample {

    public static void main(String[] args) {

        JFrame frame = new JFrame("Swing and JavaFX");
        frame.setSize(1000, 1000);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel(new BorderLayout(0, 0));
        frame.getContentPane().add(panel, BorderLayout.CENTER);

        final JFXPanel jfxPanel = new JFXPanel();
        panel.add(jfxPanel);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                initFx(jfxPanel);
            }
       });
    }

    private static void initFx(JFXPanel fxPanel) {
        Stage stage = new Stage();
        stage.setTitle("Web View");
        Scene scene = new Scene(new Browser(), 1000, 1000, Color.web("#666970"));
        stage.setScene(scene);
        fxPanel.setScene(scene);
    }

}

class Browser extends Region {

    final WebView browser = new WebView();
    final WebEngine webEngine = browser.getEngine();

    public Browser() {
        // load the home page
        webEngine.load("http://www.google.com");

        //add components
        getChildren().add(browser);
    }

    @Override
    protected void layoutChildren() {
        double w = getWidth();
        double h = getHeight();
        layoutInArea(browser,0,0,w,h,0,HPos.CENTER,VPos.CENTER);
    }

}

我认为诀窍是对 Region 进行子类化,以便您可以手动将 WebView 布局到您想要的位置。

【讨论】:

    【解决方案2】:

    一种方法是将WebView 添加到StackPane,“将尝试调整每个孩子的大小以填充其内容区域”。我已将封闭的JFXPanel 赋予640 x 480 的任意preferred 大小;调整框架大小以查看StackPane 如何根据默认Pos.CENTER 重排WebView 内容。

    import java.awt.BorderLayout;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javafx.application.Platform;
    import javafx.embed.swing.JFXPanel;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.scene.web.WebEngine;
    import javafx.scene.web.WebView;
    
    /** @see https://stackoverflow.com/a/31576647/230513 */
    public class WebViewTest {
    
        private void initAndShowGUI() {
            // This method is invoked on the EDT thread
            JFrame frame = new JFrame("Swing and JavaFX");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            final JFXPanel fxPanel = new JFXPanel(){
    
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(640, 480);
                }
            };
            frame.add(fxPanel, BorderLayout.CENTER);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
            Platform.runLater(() -> {
                initFX(fxPanel);
            });
        }
    
        private void initFX(JFXPanel fxPanel) {
            // This method is invoked on the JavaFX thread
            Scene scene = createScene();
            fxPanel.setScene(scene);
        }
    
        private Scene createScene() {
            StackPane root = new StackPane();
            Scene scene = new Scene(root);
            WebView  webView = new WebView();
            WebEngine webEngine = webView.getEngine();
            webEngine.load("http://www.example.com");
            root.getChildren().add(webView);
            return scene;
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new WebViewTest()::initAndShowGUI);
        }
    }
    

    【讨论】:

    • 是的,这可行,并且不涉及像我需要的解决方案那样对 Region 进行子类化。我更喜欢这种方式。
    • 另见herehere显示的相关示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 2011-08-16
    相关资源
    最近更新 更多