JavaFX WebView grow to fill entire area
One approach is to add the WebView
to a StackPane
, which "will attempt to resize each child to fill its content area." I've given the enclosing JFXPanel
to an arbitrary preferred size of 640 x 480
; resize the frame to see how the StackPane
reflows the WebView
content based on the default Pos.CENTER
.
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);
}
}
Actually, I think I got a solution based off 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);
}
}
I think the trick is to subclass Region, so that you can layout the WebView where you want it manually.