9

I'm using JavaFX in a project instead of Swing because of the enhanced multimedia, webviewer and possibility to use visual effects. However, what I've learned from what I found on the web (http://docs.oracle.com/javafx/2/layout/jfxpub-layout.htm and others) is that JavaFX layout managers focus on scaling the size of the parent based on the size of the content, whereas Swing focusses on scaling the content according to the parent, at least based on the Layout being used.

Right now I'm using an Accordion with some TitledPane children. One of them contains a GridPane for the simple reason it is the best way I know to emulate a GridLayout (as I learned from my previous question here: JavaFX layout equivalent to GridLayout). I want to have the TitledPane's content split in 2 rows and 1 column, each row with a 50% height of the available space in the TitledPane (scaling with the Stage or Scene), equivalent to what a GridLayout(2,1) inside a BorderLayout.CENTER would accomplish. For this, I've added a GridPane with 2 RowConstraints using setPercentHeight(50) and 1 ColumnConstraint with setPercentWidth(100). However, I've noticed the contents are scaling with the grid properly, but the grid is not taking up all available space in the TitledPane (because apparently it doesn't act like a BorderPane's center). I've also tried with setMaxWidth to make the content scale with the parent, but it doesn't seem to work either (as said here: JavaFX: How to make my custom component use all available space from parent layout?). And even if it would, do I need to set the max width to EACH descendent in my UI elements tree to have all of them scale?

Either way, does anyone know how to make a TitledPane with 2 equal spaces in it underneath eachother that scale with the titledpane's size?

column width does not take up all available space

Community
  • 1
  • 1
RDM
  • 4,986
  • 4
  • 34
  • 43

1 Answers1

10

In fact, your gridpane is growing to fill all its parent. Consider the below code, I have added a background color (red) to the gridpane for debugging purposes.

Accordion accordion = new Accordion();
TitledPane titledPane = new TitledPane();
titledPane.setText("Title");
GridPane gridPane = new GridPane();
gridPane.setStyle("-fx-background-color:red");

gridPane.add(new TextArea("Hello"), 0, 0);
gridPane.add(new TextArea("World"), 0, 1);

titledPane.setContent(gridPane);
accordion.getPanes().add(titledPane);

If you execute this code, the gridpane will fill all its parent (check the red color spans all over the titledpane content).

However, the content of the gridpane will not fill all the column. If you try to resize the window, you will see that the textareas are not changing in width along with the gridpane. To fix that, you need to tell the first column of the gridpane to grow with the gridpane itself. The way to do that is to add the following constraint:

ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setFillWidth(true);
columnConstraints.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().add(columnConstraints);
Rasha
  • 565
  • 3
  • 7
  • Could you tell me what the difference is between setPercentWidth(100) and setFillWidth(true) + setHgrow(Priority.ALWAYS) ? – RDM Oct 04 '13 at 07:29
  • 1
    setPercentWidth would also work, instead of setHGrow(Priority.ALWAYS). They will both do the same thing in case you are using one column only. In case you have multiple columns, they would work differently. Because setHGrow will try to tell the layout which column of the gridpane needs to grow to fill the unclaimed available space. – Rasha Oct 04 '13 at 07:32
  • 1
    setFillWidth(true) is for the content of the column, not the column itself. The default is true I think. So you don't need to set it. What it means is whether the children of the column will be adjusted to fill all the width of the column. – Rasha Oct 04 '13 at 07:35
  • How deep does setFillWidth go? E.g. if I add a VBox with some Buttons in it to a column, I'm guessing the VBox will take up the space but the Buttons needs to be told to scale individually using setMaxWidth(Double.MAX_VALUE)? – RDM Oct 04 '13 at 07:45
  • I see where the confusion comes from. I think for you, you think that when you use setFillWidth(true), you expect the internal components to grow to fill the entire space. Unfortunately this is not the default behavior. setFillWidth(true) only says that the children can grow to fill the entire space available in the vbox, but I don't think it forces the children to do that. Try creating a Vbox with setFillWidth(true), add a button to it, the button will not grow. Add a textArea instead, the textarea will grow. – Rasha Oct 04 '13 at 07:52
  • 1
    If you're stuck , and want to force the contents to grow within its parent, consider wrapping those contents in an AnchorPane. – Rasha Oct 04 '13 at 07:53
  • Thanks for your help. I'll get it to work. It's just quite a different way of thinking when you're used to Swing... – RDM Oct 04 '13 at 08:02
  • no worries. A final note for reference: the documentation on VBox says the following about setFillWidth(true) "Whether or not resizable children will be resized to fill the full width of the vbox or be kept to their preferred width and aligned according to the alignment hpos value." http://docs.oracle.com/javafx/2/api/javafx/scene/layout/VBox.html#setFillWidth(boolean) . They keyword here is "resizable" children – Rasha Oct 04 '13 at 08:05