Search code examples
javajavafxjavafx-webengine

JavaFX height resize issue


I am am trying to get both the Height and Width of a WebView in a tab to resize. The Width works the height doesn't. The System.out.println();'s show that the height is getting entered correctly, but you can only see a little bit at the top. How do I make it so the height will scale like the width does?

public class OuroborosViewer extends Application {

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage stage) {
    stage.setTitle("Ouroboros");
    Scene scene = new Scene(new VBox(), 1200, 800);
    scene.setFill(Color.OLDLACE);

    MenuBar menuBar = new MenuBar();
    Menu menuFile = new Menu("File");
    Menu menuEdit = new Menu("Edit");
    Menu menuView = new Menu("View");

    menuBar.getMenus().addAll(menuFile, menuEdit, menuView);
    ((VBox) scene.getRoot()).getChildren().addAll(menuBar);

    BorderPane borderPane = createTab(scene);
    ((VBox) scene.getRoot()).getChildren().add(borderPane);

    scene.widthProperty().addListener(new WidthListener());
    scene.heightProperty().addListener(new HeightListener());
    //  stage.getIcons().add(new Image("Ouroboros.svg"));
    stage.setScene(scene);
    stage.show();
}

private BorderPane createTab(Scene scene) {
    TabPane tabPane = new TabPane();
    BorderPane borderPane = new BorderPane();

    Tab tab = new Tab();
    tab.setText("Google");
    VBox hbox = new VBox();
    hbox.setAlignment(Pos.CENTER);
    tab.setContent(hbox);
    tabPane.getTabs().add(tab);

    tab.setContent(new OuroborosBrowser(scene));
    // bind to take available space

    borderPane.setCenter(tabPane);
    return borderPane;
}

private static class WidthListener implements ChangeListener<Number> {

    @Override
    public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
        String no = String.valueOf(newSceneWidth);
        double width = Double.parseDouble(no);
        System.out.println("Width : " + width);
        OuroborosBrowser.browsers[0].setPrefWidth(width);
    }
}

private static class HeightListener implements ChangeListener<Number> {

    @Override
    public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
        String no = String.valueOf(newSceneHeight);
        double height = Double.parseDouble(no);
        System.out.println("Height : " + height);
        OuroborosBrowser.browsers[0].setPrefHeight(height);
    }
}
}

class OuroborosBrowser extends Region {
public static int browserCounter = 0;
public static WebView[] browsers = new WebView[25];
private static WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
private static double browserWidth = 1200;
private static double browserHeight = 800;

public OuroborosBrowser(Scene scene) {
   // getStyleClass().add("browser");
    webEngine.load("http://www.google.com/index.html");
    browser.setPrefSize(scene.getWidth(), scene.getHeight());
    getChildren().add(browser);
    browsers[browserCounter] = browser;
    browserCounter++;
}
}

Solution

  • The width works because the Scene width is always equal to the Content width hence your problem, the height is different since you added the MenuBar(menuBar)

    so in your HeightListener do this

    System.out.println("Height : " + newSceneHeight);
    OuroborosBrowser.browsers[0].setPrefHeight(newSceneHeight.doubleValue() 
        - OuroborosBrowser.browsers[0].getScene().getRoot().getChildrenUnmodifiable()
               .get(0).prefHeight(-1));//all this nonsense to get the menuBar
    

    also these

        String no = String.valueOf(newSceneWidth); //no need
        double width = Double.parseDouble(no); // no need use newSceneHeight.doubleValue()
        System.out.println("Width : " + width); //why not use no rather ??, no need
        OuroborosBrowser.browsers[0].setPrefWidth(width);//use newSceneHeight.doubleValue()
    

    also change all these, its hard to understand, you can return only tab from here, BorderPane should be your root, where you can add the menuBar with setTop(node)

    TabPane tabPane = new TabPane();
    BorderPane borderPane = new BorderPane();
    
    Tab tab = new Tab();
    tab.setText("Google");
    VBox hbox = new VBox();//you are not using this
    hbox.setAlignment(Pos.CENTER);
    tab.setContent(hbox);//you replaced this
    tabPane.getTabs().add(tab);
    
    tab.setContent(new OuroborosBrowser(scene));//you see?
    // bind to take available space
    
    borderPane.setCenter(tabPane); // why this? its not needed
    return borderPane;