Having a GridPane with 2 rows and 2 columns, setting the row constraints to 50 percent height results in unwanted behaviour.
Code:
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="..." stylesheets="#general.css" prefWidth="800" prefHeight="600">
<top>
<VBox>
<!-- ... -->
</VBox>
</top>
<bottom>
<HBox>
<!-- ... -->
</HBox>
</bottom>
<center>
<GridPane >
<children>
<ScrollPane fx:id="tilePane" GridPane.columnIndex="0" GridPane.rowIndex="0">
<content>
</content>
<GridPane.margin>
<Insets bottom="2" left="2" right="2" top="2" />
</GridPane.margin>
</ScrollPane>
<TreeView fx:id="listPane" GridPane.columnIndex="0" GridPane.rowIndex="1">
<root>
<TreeItem value="Stages" />
</root>
<GridPane.margin>
<Insets bottom="2" left="2" right="2" top="2" />
</GridPane.margin>
</TreeView>
<ScrollPane fx:id="mapPane" GridPane.columnIndex="1" GridPane.rowIndex="0" GridPane.rowSpan="2">
<content>
</content>
<GridPane.margin>
<Insets bottom="2" left="2" right="2" top="2" />
</GridPane.margin>
</ScrollPane>
</children>
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" percentWidth="25"/>
<ColumnConstraints hgrow="ALWAYS" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="ALWAYS" percentHeight="50" />
<RowConstraints vgrow="ALWAYS" percentHeight="50" />
</rowConstraints>
</GridPane>
</center>
</BorderPane>
(mentioned attribute at the bottom)
I expected that the two rows would share their available height at a 50% rate. They do this, but they also consume a lot more space than needed.
Picture of the result with, and without percentHeight specified:
Do I understand percentHeight wrong, or is there another approach?
Related
I have an app with the following structure:
<GridPane>
<columnConstraints>
<ColumnConstraints fillWidth="true" hgrow="ALWAYS" />
</columnConstraints>
<rowConstraints>
<RowConstraints fillHeight="true" vgrow="ALWAYS" />
</rowConstraints>
<children>
<FlowPane fx:id="flwPictures" GridPane.columnIndex="0" GridPane.rowIndex="0"
GridPane.fillHeight="true" GridPane.fillWidth="true"
GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS" >
<padding>
<Insets top="2.0" bottom="2.0" left="2.0" right="2.0" />
</padding>
<children>
</children>
</FlowPane>
</children>
</GridPane>
I need the FlowPane to fill the size of its parent container of the GridPane. The Nodes are added dynamically based on user selection. So far what I observe is that flow pane is not filling.
Id like to place a label and a button (and a text field) in a horizontal layout. This works, but the baselines are unaligned. How to fix that?
The expected result is that the red lines (baselines of each control) are at the same height.
This is the FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<HBox prefHeight="100.0" prefWidth="400.0" spacing="10.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="Label" />
<Button mnemonicParsing="false" text="Button" />
<TextField text="Lorem Ipsum" />
</children>
</HBox>
Add an alignment attribute to the HBox with value "BASELINE_LEFT":
<HBox alignment="BASELINE_LEFT" prefHeight="100.0" prefWidth="400.0" spacing="10.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="Label" />
<Button mnemonicParsing="false" text="Button" />
<TextField text="Lorem Ipsum" />
</children>
</HBox>
I am developing a dialog box inside the scenebuilder and I can see there the size is 625x616 (I am using gridpane), however when I run the tool it looks much bigger (around 900x900).
This is the code I use to load the fxml file
private void DisplayDialog(String title, String fxmlPath) throws IOException {
final Stage dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(primaryStage);
dialog.setResizable(false);
dialog.setTitle(title);
dialog.getIcons().add(primaryStage.getIcons().get(0));
Parent root = FXMLLoader.load(getClass().getResource(fxmlPath));
Scene dialogScene = new Scene(root);
dialog.setScene(dialogScene);
dialog.show();
logger.exit();
}
and here it is my fxml file:
<GridPane hgap="5.0" vgap="10.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ca.mali.dialogs.chapter6.UpdateAttributeValuesServiceController">
<columnConstraints>
<ColumnConstraints hgrow="NEVER" maxWidth="300.0" minWidth="200.0" prefWidth="200.0" />
<ColumnConstraints hgrow="NEVER" prefWidth="400.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="-Infinity" vgrow="SOMETIMES" />
<RowConstraints vgrow="SOMETIMES" />
<RowConstraints maxHeight="-Infinity" vgrow="SOMETIMES" />
<RowConstraints maxHeight="-Infinity" vgrow="SOMETIMES" />
<RowConstraints maxHeight="-Infinity" vgrow="SOMETIMES" />
</rowConstraints>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<HBox alignment="CENTER_RIGHT" GridPane.columnIndex="1" GridPane.rowIndex="4">
<Button cancelButton="true" mnemonicParsing="false" onAction="#Cancel_click" text="Cancel">
<HBox.margin>
<Insets right="20.0" />
</HBox.margin>
</Button>
<Button fx:id="OkButton" defaultButton="true" disable="true" mnemonicParsing="false" onAction="#OK_click" text="OK" />
</HBox>
<Label text="Instance Name: " GridPane.halignment="RIGHT" />
<ComboBox fx:id="InstanceName" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" />
<TableView fx:id="AttributeValueTableView" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" GridPane.columnSpan="2" GridPane.rowIndex="1">
<columns>
<TableColumn fx:id="AttributeTableColumn" editable="false" maxWidth="1.7976931348623157E308" minWidth="50.0" prefWidth="200.0" text="Attribute" />
<TableColumn fx:id="ValueTableColumn" maxWidth="1.7976931348623157E308" minWidth="50.0" prefWidth="400.0" text="Value" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<Label text="User-supplied tag*:" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
<TextField fx:id="UserSuppliedTag" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="Logical Time:" GridPane.halignment="RIGHT" GridPane.rowIndex="3" />
<Spinner fx:id="LogicalTimeSpin" editable="true" GridPane.columnIndex="1" GridPane.rowIndex="3" />
</GridPane>
I also tried to replace Gridpane with VBox but I got the same results.
My first approach (which works fine)
I have two panes, gridPane (inner one) and borderPane (outer one). The grid pane is just a row of a few labels, so it is very low. It is designed with the Scene Builder. It gets loaded with the FXMLLoader and put into the center of the border pane which is created with the classical
BorderPane borderPane = new BorderPane();
The size of the window is as expected, nothing is too big or too small.
The second approach
I use Scene Builder to create the borderPane as well, but the grid pane does not get put into it right away in the Scene Builder.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/RootLayout.fxml"));
borderPane = (BorderPane) loader.load();
// ...
... and later on the gridPane:
borderPane.setCenter(gridPane);
When I run the app now, the window is wider and a lot higher.
Side note:
The borderPane's min/pref/max widths and heights all USE_COMPUTED_SIZE. The labels all use only USE_COMPUTED_SIZE. The ´gridPane` has 8 columns, each having min/pref width of 100. But the displayed window is > 1400 px wide and almost 800 px high. Like I said: it works fine if the border pane is created the classical way.
Here are the FXML files for both panes:
RootLayout.fxml (BorderPane, a.k.a. outer pane)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1">
</BorderPane>
PlacesOverview.fxml (GridPane, a.k.a. inner pane)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>
<GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<columnConstraints>
<ColumnConstraints minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" minWidth="100.0" prefWidth="100.0" />
<ColumnConstraints halignment="CENTER" minWidth="100.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<Label text="Name" GridPane.halignment="LEFT" />
<Label text="Montag" GridPane.columnIndex="1" GridPane.halignment="CENTER" />
<Label text="Dienstag" GridPane.columnIndex="2" GridPane.halignment="CENTER" />
<Label text="Mittwoch" GridPane.columnIndex="3" GridPane.halignment="CENTER" />
<Label text="Donnerstag" GridPane.columnIndex="4" GridPane.halignment="CENTER" />
<Label text="Freitag" GridPane.columnIndex="5" GridPane.halignment="CENTER" />
<Label text="Samstag" GridPane.columnIndex="6" GridPane.halignment="CENTER" />
<Label text="Sonntag" GridPane.columnIndex="7" GridPane.halignment="CENTER" />
</children>
</GridPane>
I am having one button. On click of that button. I am opening the stackpane which is right below it. For StackPane hard coded x layout values. So at first click the stackpane shows right below the button. The prob is when I maximize or resize the window it is not adjusting it's position(x).
FXML
<Button fx:id="searchCriteriaBtn" mnemonicParsing="false" onAction="#searchCriteriaAction" styleClass="redButton" text="Search Criteria">
<StackPane fx:id="searchCriteriaPane" alignment="TOP_RIGHT" prefHeight="150.0" prefWidth="200.0" styleClass="redBorder" translateX="239.0" translateY="-6.0" visible="false">
JAVA
#FXML
private void searchCriteriaAction(ActionEvent event){
searchCriteriaPane.visibleProperty().setValue(true);
searchCriteriaBtn.layoutXProperty().bind(searchCriteriaPane.layoutXProperty());
searchCriteriaBtn.layoutYProperty().bind(searchCriteriaPane.layoutYProperty());
}
I have found out the solution of overlay dropdown menu.
<MenuButton mnemonicParsing="false" nodeOrientation="LEFT_TO_RIGHT"
styleClass="redButton" text="Search Criteria" textFill="WHITE">
<items>
<MenuItem mnemonicParsing="false"
style="-fx-background-color: transparent; -fx-padding: 0; -fx-margin: 0;">
<AnchorPane minHeight="0.0" minWidth="0.0"
prefHeight="500.0" prefWidth="345.0" styleClass="noborder">
<children>
<HBox layoutY="156.0" minHeight="185.0" minWidth="345.0"
prefHeight="185.0" prefWidth="357.0" />
<HBox layoutX="5.0" layoutY="316.0" prefHeight="35.0"
prefWidth="348.0">
<children>
<Text layoutX="7.0" layoutY="335.0" strokeType="OUTSIDE"
strokeWidth="0.0" text="Template Name">
<HBox.margin>
<Insets right="5.0" top="9.0" />
</HBox.margin>
</Text>
<ComboBox fx:id="templateNameComboBox" layoutX="94.0"
layoutY="330.0" prefWidth="248.0" promptText="Select Template Name">
<HBox.margin>
<Insets left="7.0" />
</HBox.margin>
</ComboBox>
</children>
</HBox>
</children>
</AnchorPane>
</MenuItem>
</items>
<HBox.margin>
<Insets left="6.0" />
</HBox.margin>
<cursor>
<Cursor fx:constant="HAND" />
</cursor>
</MenuButton>