Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX 2 BorderPane Use Full Space

I´m just facing a little issue that I can´t solve by myself. I try to place a vBox including a TextField and a HTML-Editor in my BorderPane, but the full space is not used. Another problem is that if I shrink the window, the html-editor overlaps with my left option window.

enter image description here

private void initEditor()
{
editor = new HTMLEditor();
editor.setId("editor");
editor.lookup(".top-toolbar").setDisable(true);
editor.lookup(".top-toolbar").setManaged(false);
((ToolBar) editor.lookup(".bottom-toolbar")).getItems().addAll(FXCollections.observableArrayList(((ToolBar)editor.lookup(".top-toolbar")).getItems()));

editorBox = new VBox();
TextField field = new TextField();
field.setPrefHeight(36);
field.setId("editor-title");
editorBox.setFillWidth(true);
editorBox.getChildren().addAll(field, editor);
    root.setCenter(editorBox);
}
like image 1000
Googles Avatar asked Jun 26 '12 17:06

Googles


People also ask

How does the BorderPane divide the pane window?

BorderPane lays out children in top, left, right, bottom, and center positions. The top and bottom children will be resized to their preferred heights and extend the width of the border pane. The left and right children will be resized to their preferred widths and extend the length between the top and bottom nodes.

Can you add multiple panes to a scene in JavaFX?

The Scene it self can only have one root Pane. So if you want 2 panes in the Scene you need 3.

What is the difference between HBox and VBox pane?

HBox is a subclass of Pane that lays out its children next to each other, in a horizontal row. VBox is a subclass of Pane that lays out its children in vertical column. An HBox might be used as the bottom component in a BorderPane, making it possible to line up several components along the bottom of the border pane.

What is computed size JavaFX?

For example, the computed size of a Button object is determined by the length of the text and the size of the font used for the label, plus the size of any image. Typically, the computed size is just big enough for the control and the label to be fully visible.


1 Answers

OK, so a few things going wrong here, I'll try to address them provide some advice and a sample solution.

I try to place a vBox including a TextField and a HTML-Editor in my BorderPane, but the full space is not used.

You need to use the VBox.setVgrow(editor, Priority.ALWAYS) method to get the HTMLEditor to take up any extra space in the VBox. Also, make sure that the HTMLeditor has an unbounded max height so that it can grow to fit the available area, for example editor.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE). Calling editorBox.setFillWidth(true) is redundant as the default value for the fillWidth property is true.

But even if you do all that, (as of 2.2b13) there is a bug in WebPane sizing which will cause you problems. Internally the WebPane is implemented as a GridPane containing the Toolbar and an editable WebView. By default, WebView has a preferred size of 800x600. The HtmlEditor control does not set the GridPane constraints for the WebView to allow it to be sized past it's preferred size.

To work around this, you can lookup the WebView via a css lookup after it has been added to an active Scene and adjust the GridPane constraints manually. Here is some code to do that:

stage.show();
...
WebView webview = (WebView) editor.lookup("WebView");
GridPane.setHgrow(webview, Priority.ALWAYS);
GridPane.setVgrow(webview, Priority.ALWAYS);

I shrink the window, the html-editor overlaps with my left option window.

Explicitly set the minimum width setting for the center pane in your BorderPane so that it won't overflow over the outer edge Panes.

editorBox.setMinSize(0, 0);

You need to do this because the BorderPane documentation states:

BorderPane does not clip its content by default, so it is possible that childrens' bounds may extend outside its own bounds if a child's min size prevents it from being fit within it space.


As an aside the lookup calls in your code are suspicious. Normally you can't lookup nodes by css ID until the node has been added to an active scene on a displayed stage and the JavaFX system has had a chance to run a CSS layout pass on the node - otherwise the lookup will just return null.


For debugging JavaFX layout issues, the ScenicView application is invaluable.


Here is a complete example to generate a layout similar to the image linked in your question, but without the issues you mention.

import com.javafx.experiments.scenicview.ScenicView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.web.*;
import javafx.stage.*;

public class HtmlEditorInBorderPane extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(final Stage stage) throws IOException {
    // option pane.
    VBox optionPane = new VBox(10);
    MenuBar menuBar = new MenuBar();
    menuBar.getMenus().addAll(new Menu("School"), new Menu("Social"), new Menu("Network"));
    TreeItem<String> root = new TreeItem<>("Private Notes");
    root.setExpanded(false);
    root.getChildren().addAll(new TreeItem<>("Layout"), new TreeItem<>("is not"), new TreeItem<>("easy"));
    TreeView<String> notes = new TreeView<>(root);
    optionPane.getChildren().addAll(menuBar, new Label("Kaiser Notes"), notes);
    optionPane.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");

    // editor pane.
    HTMLEditor editor = new HTMLEditor();
    VBox editorBox = new VBox(10);
    TextField textField = new TextField();
    editorBox.getChildren().addAll(textField, editor);
    editorBox.setStyle("-fx-background-color: mistyrose; -fx-padding: 10;");
    editor.setHtmlText(getSampleText());

    // option layout constraints
    VBox.setVgrow(notes, Priority.ALWAYS);

    // editor layout constraints
    textField.setMinHeight(Control.USE_PREF_SIZE); // stop the textfield from getting squashed when the scene is sized small.
    VBox.setVgrow(editor, Priority.ALWAYS);        // tells the editor to fill available vertical space.
    editorBox.setMinSize(0, 0);                    // stops the editor from overflowing it's bounds in a BorderPane.

    // layout the scene.
    BorderPane layout = new BorderPane();
    layout.setLeft(optionPane);
    layout.setCenter(editorBox);
    stage.setScene(new Scene(layout));
    stage.show();

    // addition of static layout grow constraints for the htmleditor embedded webview.
    WebView webview = (WebView) editor.lookup("WebView");
    GridPane.setHgrow(webview, Priority.ALWAYS);  // allow the webview to grow beyond it's preferred width of 800.
    GridPane.setVgrow(webview, Priority.ALWAYS);  // allow the webview to grow beyond it's preferred height of 600.
  }

  // get some dummy lorem ipsum sample text.
  private String getSampleText() throws IOException {
    StringBuilder builder = new StringBuilder();
    try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL("http://www.lorem-ipsum-text.com/").openStream()))) {
      String string;
      while ((string = in.readLine()) != null) {
        builder.append(string);
      }
    }
    return builder.toString();
  }
}
like image 57
jewelsea Avatar answered Sep 18 '22 18:09

jewelsea