I have a JavaFX dialog, and it seems the content of the grid don't span the entire width of the dialog. Right now it spans to a MAXIMUM of the the left side of the dialog, to the width of the OK button. I'd like to either remove the white space to the right of my input fields. Or span the entire width.
I've tried:
Setting the min-width of the gridpane
Setting the min-width of the textfields
Setting the width of the stage
I'm pretty much at a loss here.
Here's my code!
// Create the custom dialog.
Dialog dialog = new Dialog<>();
dialog.initOwner(mainStage);
// Set Custom Icon
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
stage.getIcons().add(new Image(Constants.kApplicationIcon));
dialog.getDialogPane().getStylesheets().add(Constants.kRootStylesheet);
dialog.getDialogPane().getStyleClass().add("accountDialog");
dialog.setTitle("New User Detected");
dialog.setHeaderText("Please complete user registration!");
// Set the button types.
ButtonType loginButtonType = new ButtonType("Create Account", ButtonBar.ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL);
// Create the username and password labels and fields.
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
grid.setAlignment(Pos.CENTER);
grid.setId("accountGrid");
TextField firstName = new TextField("First Name");
TextField lastName = new TextField("Last Name");
TextField email = new TextField("Email");
TextField gender = new TextField("Gender");
firstName.setId("textField");
lastName.setId("textField");
firstName.setPromptText("");
lastName.setPromptText("");
gender.setPromptText("");
email.setPromptText("");
email.setId("textField");
gender.setId("textField");
ToggleGroup studentRadioGroup = new ToggleGroup();
RadioButton mentorRadio = new RadioButton("Mentor");
RadioButton studentRadio = new RadioButton("Student");
studentRadio.fire();
mentorRadio.setToggleGroup(studentRadioGroup);
studentRadio.setToggleGroup(studentRadioGroup);
grid.add(new Label("First Name:"), 0, 0);
grid.add(firstName, 1, 0);
grid.add(new Label("Last Name:"), 0, 1);
grid.add(lastName, 1, 1);
grid.add(new Label("Email:"), 0, 2);
grid.add(email, 1, 2);
grid.add(new Label("Gender:"), 0, 3);
grid.add(gender, 1, 3);
GridPane.setHalignment(grid, HPos.CENTER);
GridPane.setHalignment(studentRadio, HPos.CENTER);
GridPane.setHalignment(studentRadio, HPos.CENTER);
grid.add(studentRadio, 0, 4);
grid.add(mentorRadio, 1, 4);
grid.setGridLinesVisible(true);
// Enable/Disable login button depending on whether a username was entered.
Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType);
loginButton.setDisable(true);
// Do some validation (using the Java 8 lambda syntax).
firstName.textProperty().addListener((observable, oldValue, newValue) -> {
loginButton.setDisable(newValue.trim().isEmpty());
});
dialog.getDialogPane().setContent(grid);
// Request focus on the firstname field by default.
Platform.runLater(firstName::requestFocus);
Optional<ButtonType> result = dialog.showAndWait();
ArrayList<String> data = new ArrayList<>();
System.out.println(result.get().toString());
if (result.get().getButtonData() == ButtonBar.ButtonData.OK_DONE) {
data.add("TRUE");
data.add(firstName.getText());
data.add(lastName.getText());
data.add(email.getText());
data.add(gender.getText());
data.add(mentorRadio.isSelected() ? "TRUE" : "FALSE");
} else {
data.add("FALSE");
}
return data;
Here's an image of the result. I want to again; either remove all the whitespace to the right of my grid, or span my grid to fit the whole width.
Image of Result
You are creating that extra space with grid.setPadding(new Insets(20, 150, 10, 10));. That 150 is the right padding. See the Insets documentation.
The GridPane is resized to it's preferred size. The padding on the right of 150 prevents the TextFields from growing larger in this direction.
grid.setPadding(new Insets(20, 150, 10, 10)); // sets right padding to 150
If you want to grow the TextFields to the maximum size the Labels/RadioButton to the left leaves, you should use ColumnConstraints to specify, that the second column should always grow:
ColumnConstraints constraints = new ColumnConstraints();
constraints.setHgrow(Priority.ALWAYS);
grid.getColumnConstraints().addAll(new ColumnConstraints(), constraints);
It's also possible to specify the preferred width of the second column via the ColumnConstraints object.
To test the behaviour when the window size changes, you could make the dialog resizeable:
dialog.setResizable(true);
To see the area the GridPane covers it could be helpful to assign a background:
grid.setStyle("-fx-background-color: red;");
Have you tried the setExpandableContent() method from the dialog's pane? You can pass in whatever node you like, and then it should be able to resize to fit the entire Alert.
An example of setting a GridPane as the Alert's content.
GridPane() grid = new GridPane();
Alert alert = new Alert(AlertType.INFORMATION);
alert.getDialogPane().setExpandableContent(grid);
Related
I'm trying to add a label beneath 3 labels I currently have on a different row, however it looks like the width of the fourth label that's below the top 3 is actually pushing away 2 labels on the row above, even though I have set this label to be on a different row.
mainGrid.add(scanLabel, 45, 25);
mainGrid.add(imageLabel, 75, 25);
mainGrid.add(patientLabel, 105, 25);
mainGrid.add(statusLabel, 45, 30);
Here's an image of the top 3 labels with the statusLabel commented out - https://puu.sh/FSdZd/a2b4585b69.png - and here is where I add my label back in and they get pushed out - https://puu.sh/FSesI/b0c524fedd.png
Rest of my code (left some out just so it's not so long):
public class ScanInterfaceStage {
Stage stage;
Scene scene;
BorderPane mainContent;
BorderPane buttonZone;
BorderPane topZone;
BorderPane leftZone;
BorderPane rightZone;
BorderPane bottomZone;
GridPane mainGrid;
GridPane voiceGrid;
Button backButton;
Button settingsButton;
Button exitButton;
Button voiceButton;
Button voiceConfirmButton;
Label statusLabel;
Label imageLabel;
Label patientLabel;
Label scanLabel;
Image exitImage;
Image backImage;
Image voiceImage;
Image settingsImage;
ImageView exitImageView;
ImageView backImageView;
ImageView voiceImageView;
ImageView settingsImageView;
Alert voicePopUp;
double offsetX;
double offsetY;
public ScanInterfaceStage (double sizeX, double sizeY, double positionX, double positionY) {
stage = new Stage();
// Instantiate panes
mainContent = new BorderPane();
buttonZone = new BorderPane();
leftZone = new BorderPane();
topZone = new BorderPane();
bottomZone = new BorderPane();
rightZone = new BorderPane();
voiceGrid = new GridPane();
mainGrid = new GridPane();
// Instantiate Labels
statusLabel = new Label("");
imageLabel = new Label("");
patientLabel = new Label("");
scanLabel = new Label("");
// Instantiate buttons
backButton = new Button("");
settingsButton = new Button("");
exitButton = new Button("");
voiceButton = new Button("");
voiceConfirmButton = new Button("Done\n\nClick to view");
// Set button sizes
exitButton.setMinWidth(103);
exitButton.setMaxWidth(103);
exitButton.setPrefWidth(103);
exitButton.setMinHeight(52);
exitButton.setMaxHeight(52);
exitButton.setPrefHeight(52);
voiceButton.setMinWidth(103);
voiceButton.setMaxWidth(103);
voiceButton.setPrefWidth(103);
voiceButton.setMinHeight(52);
voiceButton.setMaxHeight(52);
voiceButton.setPrefHeight(52);
backButton.setMinWidth(103);
backButton.setMaxWidth(103);
backButton.setPrefWidth(103);
backButton.setMinHeight(52);
backButton.setMaxHeight(52);
backButton.setPrefHeight(52);
settingsButton.setMinWidth(103);
settingsButton.setMaxWidth(103);
settingsButton.setPrefWidth(103);
settingsButton.setMinHeight(52);
settingsButton.setMaxHeight(52);
settingsButton.setPrefHeight(52);
// Set Label sizes
scanLabel.setMinWidth(250);
scanLabel.setMaxWidth(250);
scanLabel.setPrefWidth(250);
scanLabel.setMinHeight(400);
scanLabel.setMaxHeight(400);
scanLabel.setPrefHeight(400);
imageLabel.setMinWidth(500);
imageLabel.setMaxWidth(500);
imageLabel.setPrefWidth(500);
imageLabel.setMinHeight(350);
imageLabel.setMaxHeight(350);
imageLabel.setPrefHeight(350);
patientLabel.setMinWidth(250);
patientLabel.setMaxWidth(250);
patientLabel.setPrefWidth(250);
patientLabel.setMinHeight(400);
patientLabel.setMaxHeight(400);
patientLabel.setPrefHeight(400);
statusLabel.setMinWidth(800);
statusLabel.setMaxWidth(800);
statusLabel.setPrefWidth(800);
statusLabel.setMinHeight(150);
statusLabel.setMaxHeight(150);
statusLabel.setPrefHeight(150);
// Generate and apply drop shadow
DropShadow ds = new DropShadow();
ds.setOffsetY(3.0);
ds.setOffsetX(3.0);
ds.setColor(Color.GRAY);
exitButton.setEffect(ds);
settingsButton.setEffect(ds);
backButton.setEffect(ds);
voiceButton.setEffect(ds);
topZone.setEffect(ds);
scanLabel.setEffect(ds);
imageLabel.setEffect(ds);
patientLabel.setEffect(ds);
statusLabel.setEffect(ds);
// Define stage parameters
stage.setX(positionX);
stage.setY(positionY);
// Set the scene to display mainContent at passed size
scene = new Scene(mainContent, sizeX, sizeY);
// Setting up voice alert
voicePopUp = new Alert(AlertType.INFORMATION);
voicePopUp.initStyle(StageStyle.UNDECORATED);
voicePopUp.setGraphic(voiceImageView);
voicePopUp.setHeaderText("We are now listening!");
voicePopUp.setHeight(550);
voicePopUp.setWidth(550);
voicePopUp.setX(500);
voicePopUp.setY(500);
voicePopUp.getDialogPane().setStyle("-fx-background-color: c9f0ff; -fx-font: 25 Open_Sans;");
voicePopUp.setContentText("AMMS is now listening to your voice! Please clearly state what you would like us to help with!");
mainContent.setCenter(mainGrid);
mainContent.setTop(topZone);
mainContent.setLeft(leftZone);
mainContent.setRight(rightZone);
mainContent.setBottom(bottomZone);
mainGrid.setPadding(new Insets(10, 10, 10, 10));
mainGrid.setHgap(3);
mainGrid.setVgap(3);
Text menuText = new Text("AAMS - Scan Type: X-Ray");
menuText.setStyle("-fx-font: 25 Open_Sans-Semi-Bold");
topZone.setCenter(menuText);
mainGrid.add(scanLabel, 45, 25);
mainGrid.add(imageLabel, 75, 25);
mainGrid.add(patientLabel, 105, 25);
mainGrid.add(statusLabel, 45, 80);
A grid pane works by having indexed rows and columns which take up variable height and width, respectively. When you specify the column and row indexes in mainGrid.add(node, columnIndex, rowIndex), these are not pixel values, but indexes of the columns and rows respectively (which are zero-based).
So
mainGrid.add(scanLabel, 45, 25);
mainGrid.add(imageLabel, 75, 25);
mainGrid.add(patientLabel, 105, 25);
mainGrid.add(statusLabel, 45, 80);
results in a grid with 106 columns and 81 rows. Almost all of these are empty, so take up zero space. The exceptions are row 25, which contains three labels, and row 80, which contains 1 label, and columns 75 and 105, which contain one label each, and column 45, which contains two labels.
Since column 45 contains two labels, it will be sized so that it is wide enough to contain the widest of those labels. Columns 46-74, which are all empty and have zero width, all lie to the the right of that, the column 75 (wide enough to contain the imageLabel), followed by columns 76-104 (zero width) and finally column 105 (wide enough to contain the patient label).
The layout this creates is completely identical to
mainGrid.add(scanLabel, 0, 0);
mainGrid.add(imageLabel, 1, 0);
mainGrid.add(patientLabel, 2, 0);
mainGrid.add(statusLabel, 0, 1);
I think you are expecting the status label to span the full width of the grid; you can achieve this by setting its columnSpan. You probably need something like:
mainGrid.add(scanLabel, 0, 0);
mainGrid.add(imageLabel, 1, 0);
mainGrid.add(patientLabel, 2, 0);
mainGrid.add(statusLabel, 0, 1, 3, 1);
The last call uses the overloaded add() method, which specifies a column span and row span, in additional to the column and row indices.
I'm a bit of a javafx noob. I want to make it so this button updates the "GraphView" object called "viewGraph", but I don't know how to properly do this because I can't access outside variables in the setOnAction event. I would also want to make startVertice and endVertice outside of the event class as well but I don't know how to do that.
I would think the answer would be to somehow pass the variables in using parameters but I don't know how to do that.
I tried looking stuff up and trying random syntax stuff but I still dont know what to do. It seems simple though.
WeightedGraph<Campus> graph = new WeightedGraph<>(vertices, edges);
Label startCampus = new Label("Starting Campus: ");
Label endCampus = new Label(" Ending Campus: ");
TextField startText = new TextField();
TextField endText = new TextField();
Button displayShortestPathBtn = new Button("Display Shortest Path");
HBox input = new HBox();
input.getChildren().addAll(startCampus, startText, endCampus, endText, displayShortestPathBtn);
input.setPadding(new Insets(25, 0, 0, 0));
VBox vbox = new VBox();
GraphView viewGraph = new GraphView(graph);
vbox.getChildren().addAll(viewGraph, input);
vbox.setPadding(new Insets(50, 50, 25, 50));
displayShortestPathBtn.setOnAction((event) -> {
int startVertice = Integer.parseInt(startText.getText());
int endVertice = Integer.parseInt(endText.getText());
WeightedGraph<Campus>.ShortestPathTree shortestPathGraph = graph.getShortestPath(startVertice);
ArrayList<Integer> path = (ArrayList)shortestPathGraph.getPath(endVertice);
/*
What I want to do:
viewGraph = new GraphView(graph, path);
*/
});
primaryStage.setTitle("Final Exam");
primaryStage.setScene(new Scene(vbox));
primaryStage.show();
I just want to be able to access the outside variables but idk if that's possible or if I'm approaching the problem correctly in the first place.
Left side of picture: It is when it is run directly from intellij
Right side of picture: Created fat jar (which is created by the feature called "Jar with dependencies") is run as double click from mouse
As you can see, Checkboxes are not aligned .Every component is created by code not from fxml...What can be the cause of this?
Edit:
First of all, width and height are fixed. Thus they will never change. I disabled Them Below you can find the code.
HBox row1 = new HBox(10);
//row1.setPadding();
Label nameLbl = new Label("Login Email");
nameLbl.setPrefWidth(DefaultValues.LABEL_WIDTH);
nameLbl.setPadding(new Insets(4,0,0,0));
txtEmail = new TextField();
txtEmail.setPrefSize(DefaultValues.TEXTAREA_WIDTH,20);
txtEmail.focusedProperty().addListener((observable, oldValue, newValue) -> {
if(!newValue)
checkLicence();
});
row1.getChildren().addAll(nameLbl,txtEmail);
HBox row2 = new HBox(10);
Label passwordLbl = new Label("Password");
passwordLbl.setPrefWidth(DefaultValues.LABEL_WIDTH);
passwordLbl.setPadding(new Insets(4,0,0,0));
txtPassword = new PasswordField();
txtPassword.setPrefSize(DefaultValues.TEXTAREA_WIDTH,20);
row2.getChildren().add(passwordLbl);
row2.getChildren().add(txtPassword);
HBox row3 = new HBox(10);
//row1.setPadding();
Label refreshTime = new Label("Refresh Time");
refreshTime.setPrefWidth(DefaultValues.LABEL_WIDTH);
refreshTime.setPadding(new Insets(4,0,0,0));
txtRefreshTime = new TextField();
txtRefreshTime.setPrefSize(DefaultValues.TEXTAREA_WIDTH,20);
txtRefreshTime.setPromptText("Seconds");
txtRefreshTime.textProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue.matches("\\d*")) {
txtRefreshTime.setText(newValue.replaceAll("[^\\d]", ""));
}
});
row3.getChildren().add(refreshTime);
row3.getChildren().add(txtRefreshTime);
HBox row3_1 = new HBox(10);
//row1.setPadding();
Label userCountLbl = new Label("User Count(for point calc.)");
userCountLbl.setPrefWidth(DefaultValues.LABEL_WIDTH);
userCountLbl.setPadding(new Insets(4,0,0,0));
txtUserCountForPointCalc = new TextField();
txtUserCountForPointCalc.setPrefSize(DefaultValues.TEXTAREA_WIDTH,20);
txtUserCountForPointCalc.setPromptText("Not very important");
txtUserCountForPointCalc.textProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue.matches("\\d*")) {
txtUserCountForPointCalc.setText(newValue.replaceAll("[^\\d]", ""));
}
});
row3_1.getChildren().add(userCountLbl);
row3_1.getChildren().add(txtUserCountForPointCalc);
HBox row4 = new HBox(10);
//row1.setPadding();
Label showNotifications = new Label("Show Notifications");
showNotifications.setPrefWidth(DefaultValues.LABEL_WIDTH - 10);
showNotifications.setPadding(new Insets(4,0,0,0));
cbShowNotifications = new CheckBox();
cbShowNotifications.setPrefWidth(180);
Button btnClearNotificationCache = new Button("Clear Notification Cache");
btnClearNotificationCache.setOnAction(e -> {
notifiedAssignedToMeTickets.clear();
notifiedUnassignedTickets.clear();
});
row4.setAlignment(Pos.CENTER_LEFT);
row4.getChildren().addAll(showNotifications,cbShowNotifications,btnClearNotificationCache);
HBox row5 = new HBox(10);
//row1.setPadding();
Label autoReplyCompanies = new Label("Auto-Reply Companies");
autoReplyCompanies.setPrefWidth(DefaultValues.LABEL_WIDTH);
autoReplyCompanies.setPadding(new Insets(4,0,0,0));
txtAutoReplyCompanies = new TextField();
txtAutoReplyCompanies.setPrefSize(DefaultValues.TEXTAREA_WIDTH,20);
txtAutoReplyCompanies.setPromptText("(For Unassigned Tickets..)Seperate with ';' for multiple companies");
row5.getChildren().add(autoReplyCompanies);
row5.getChildren().add(txtAutoReplyCompanies);
//txtAutoReplyModules
HBox row5_2 = new HBox(10);
//row1.setPadding();
Label autoReplyModules = new Label("Auto-Reply Modules");
autoReplyModules.setPrefWidth(DefaultValues.LABEL_WIDTH);
autoReplyModules.setPadding(new Insets(4,0,0,0));
txtAutoReplyModules = new TextField();
txtAutoReplyModules.setPrefSize(DefaultValues.TEXTAREA_WIDTH,20);
txtAutoReplyModules.setPromptText("(For Unassigned Tickets..)Seperate with ';' for multiple modules");
row5_2.getChildren().add(autoReplyModules);
row5_2.getChildren().add(txtAutoReplyModules);
HBox row6 = new HBox(10);
//row1.setPadding();
Label autoReplyMessage = new Label("Auto-Reply Message");
autoReplyMessage.setPrefWidth(DefaultValues.LABEL_WIDTH);
autoReplyMessage.setPadding(new Insets(4,0,0,0));
txtAutoReplyMessage = new TextArea();
txtAutoReplyMessage.setPrefSize(DefaultValues.TEXTAREA_WIDTH,65);
row6.getChildren().add(autoReplyMessage);
row6.getChildren().add(txtAutoReplyMessage);
//cbStatistics
HBox row6_1 = new HBox(10);
Label searchStatistics = new Label("Process Statistics");
searchStatistics.setPrefWidth(DefaultValues.LABEL_WIDTH - 10);
searchStatistics.setPadding(new Insets(4,0,0,0));
cbStatistics = new CheckBox();
cbStatistics.setSelected(true);
cbStatistics.setPrefWidth(180);
row6_1.getChildren().addAll(searchStatistics,cbStatistics);
HBox row7 = new HBox(10);
//row1.setPadding();
Label searchUnassignedsLbl = new Label("Search Unassigned Tickets");
searchUnassignedsLbl.setPrefWidth(DefaultValues.LABEL_WIDTH - 10);
searchUnassignedsLbl.setPadding(new Insets(4,0,0,0));
cbSearchUnassigneds = new CheckBox();
cbSearchUnassigneds.setSelected(true);
cbSearchUnassigneds.setPrefWidth(180);
//row7.setAlignment(Pos.CENTER_LEFT);
row7.getChildren().addAll(searchUnassignedsLbl,cbSearchUnassigneds);
HBox row8 = new HBox(10);
//row1.setPadding();
Label searchAssignedToMe = new Label("Search Replied to u");
searchAssignedToMe.setPrefWidth(DefaultValues.LABEL_WIDTH);
searchAssignedToMe.setPadding(new Insets(4,0,0,0));
cbSearchAssignedToMeTickets = new CheckBox();
cbSearchAssignedToMeTickets.setSelected(true);
cbSearchAssignedToMeTickets.setPrefSize(DefaultValues.TEXTAREA_WIDTH,20);
row8.getChildren().add(searchAssignedToMe);
row8.getChildren().add(cbSearchAssignedToMeTickets);
HBox row9 = new HBox(10);
Label checkUpdateLbl = new Label("Check Updates");
checkUpdateLbl.setPrefWidth(DefaultValues.LABEL_WIDTH - 10);
checkUpdateLbl.setPadding(new Insets(4,0,0,0));
cbCheckUpdates = new CheckBox();
cbCheckUpdates.setSelected(checkUpdatesSetting);
cbCheckUpdates.setPrefWidth(180);
Button btnUpdateUpdater = new Button("Update Updater");
btnUpdateUpdater.setOnAction(event -> downloadUpdaterUpdate());
//btnUpdateUpdater.setPadding(new Insets(5));
row9.setAlignment(Pos.CENTER_LEFT);
row9.getChildren().addAll(checkUpdateLbl,cbCheckUpdates,btnUpdateUpdater);
HBox row10 = new HBox();
Label dummy = new Label("");
dummy.setPrefWidth(DefaultValues.LABEL_WIDTH);
Button btnSaveSettings = new Button("Save Settings");
btnSaveSettings.setOnAction(e -> {
if(txtEmail.getLength() == 0 || txtPassword.getLength() == 0 || txtRefreshTime.getLength() == 0)
showAlert(Alert.AlertType.ERROR,"","ilk 3 alan boş olamaz");
else{
Task<Void> task = new Task<Void>() {
#Override
protected Void call(){
shutDownCalled = true;
waitExecutorShutDown();
checkLicence();
Settings st = new Settings();
st.setEmail(txtEmail.getText().trim());
st.setPassword(txtPassword.getText().trim());
st.setRefreshTime(Integer.parseInt(txtRefreshTime.getText().trim()));
st.setUserCountForPointCalculation(txtUserCountForPointCalc.getLength() == 0 ? DefaultValues.userCountForPointCalculation : Integer.parseInt(txtUserCountForPointCalc.getText()));
st.setShowNotifications(cbShowNotifications.isSelected());
st.setAutoReplyCompanies(txtAutoReplyCompanies.getText().trim());
st.setAutoReplyModules(txtAutoReplyModules.getText().trim());
st.setAutoReplyMessage(txtAutoReplyMessage.getText().trim());
st.setSearchUnassignedTickets(cbSearchUnassigneds.isSelected());
st.setSearchAssignedToMeTickets(cbSearchAssignedToMeTickets.isSelected());
st.setCheckUpdates(cbCheckUpdates.isSelected());
st.setProcessStatistics(cbStatistics.isSelected());
Settings.saveNormalBotSettingsToFile(st);
settings = st;
needLogin = true;
initData(false);
return null;
}
};
new Thread(task).start();
mainTabs.getSelectionModel().select(0);
}
});
row10.getChildren().addAll(dummy,btnSaveSettings);
VBox vb = new VBox(9);
vb.setPadding(new Insets(10,10,0,10));
vb.getChildren().addAll(row1,row2,row3,row3_1,row5,row5_2,row6,row6_1,row4,row7,row8,row9,row10);
return vb;
An HBox makes no guarantee about the amount of space it actually assigns to any child node that is contained inside it. It merely guarantees to place them in order, with a minimum gap if you specify a spacing, and makes a best effort to size each child node to its preferred size. Many factors which are beyond your control will affect the actual size of each node, including font sizes (which depend on the available fonts), total size available to the HBox, etc etc. All these may change depending on the platform the application is running on, including depending on the JDK version.
So trying to line things up vertically by placing them in a collection of HBoxs and setting the preferred sizes of the child nodes is simply not a reliable way to approach this (and is not designed as such). The problem is there is no real way to connect the layout of one HBox to the layout of another HBox: they are all laid out independently. If you want to lay components out so they are aligned relative to each other both horizontally and vertically, you should use a GridPane, which is specifically designed for that purpose.
It is generally a very bad idea (not just in JavaFX; this applies to most UI toolkits) to hard-code sizes of anything, so anytime you are using this as a solution, there is almost certainly a better approach.
The basic idea behind using a GridPane would look like:
GridPane grid = new GridPane();
// padding around entire grid:
grid.setPadding(new Insets(4);
grid.setHgap(10);
grid.setVgap(9);
Label nameLbl = new Label("Login Email");
// column 0, row 0:
grid.add(nameLbl, 0, 0);
txtEmail = new TextField();
txtEmail.focusedProperty().addListener((observable, oldValue, newValue) -> {
if(!newValue)
checkLicence();
});
// column 1, row 0, span 2 columns:
grid.add(txtEmail, 1, 0, 2, 1);
// ...
Label searchAssignedToMe = new Label("Search Replied to u");
// column 0, row 7:
grid.add(searchAssignedToMe, 0, 7);
cbSearchAssignedToMeTickets = new CheckBox();
cbSearchAssignedToMeTickets.setSelected(true);
// column 1, row 7, span two columns:
grid.add(cbSearchAssignedToMeTickets, 1, 7, 2, 1);
Label checkUpdateLbl = new Label("Check Updates");
// column 0, row 8:
grid.add(checkUpdateLbl, 0, 8);
cbCheckUpdates = new CheckBox();
cbCheckUpdates.setSelected(checkUpdatesSetting);
// column 1, row 8:
grid.add(cbCheckUpdates, 1, 8);
Button btnUpdateUpdater = new Button("Update Updater");
btnUpdateUpdater.setOnAction(event -> downloadUpdaterUpdate());
// column 2, row 8:
grid.add(btnUpdateUpdater, 2, 8);
// ...
Button btnSaveSettings = new Button("Save Settings");
btnSaveSettings.setOnAction(...);
// center button horizontally in its cells (it spans the whole row):
GridPane.setHalignment(btnSaveSettings, HPos.CENTER);
// column 0, row 9, span 3 columns:
grid.add(btnSaveSettings, 0, 9, 3, 1);
You can completely configure how any potential extra space is allocated among the columns (using ColumnConstraints instances), among the rows (using RowConstraints instances), and how the controls are aligned within their individual cell(s). You can also specify these on a node-by-node basis if you need.
You probably want, for example, hgrow of the three columns to be SOMETIMES, SOMETIMES, and ALWAYS; you may need to set the fillWidth of the TextInputControls to true.
See the GridPane documentation, which explains this all completely.
I am trying to create a UI in JavaFX which should have two columns and one row. The row should span from top to bottom (100% height) and the columns should be 80% and 20% wide respectively. In the first column, I am creating a textarea, while the second one has a sidebar with multiple buttons.
The problem I am facing is that the textarea is not getting full height. I can change the height in px, but I want to change in percentage. I tried adding RowConstraint, but it does not works. Any idea how should I proceed?
public void start(Stage primaryStage)
{
primaryStage.setTitle("Particles");
primaryStage.setResizable(false);
GridPane grid = new GridPane();
grid.setVgap(10);
grid.setHgap(10);
RowConstraints row1 = new RowConstraints();
row1.setPercentHeight(100);
ColumnConstraints column1 = new ColumnConstraints();
column1.setPercentWidth(80);
ColumnConstraints column2 = new ColumnConstraints();
column2.setPercentWidth(20);
TextArea environment = new TextArea();
grid.add(environment, 0, 0);
Button start = new Button("START");
HBox hbBtn = new HBox(10);
hbBtn.setAlignment(Pos.CENTER);
hbBtn.getChildren().add(start);
grid.add(hbBtn, 1, 0);
Scene scene = new Scene(grid, 725, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
My Output:
You need to add the Vgrow Priority of the TextField as Always
GridPane.setVgrow(environment, Priority.ALWAYS);
In your code :
TextArea environment = new TextArea();
grid.add(environment, 0, 0);
GridPane.setVgrow(environment, Priority.ALWAYS);
Output:
I have created two Javafx Gridpanes and i want them to be in the same ligne, the second gridpane must be in the same ligne next to the first gridpane. Because i get one on the other when running.
This is my code:
Group root = new Group();
Scene scene = new Scene(root);
//creation du layout
layout = new GridPane();
layout.getColumnConstraints().add(new ColumnConstraints(350)); // column 1 is 350 wide
layout.getColumnConstraints().add(new ColumnConstraints(350));
layout.getColumnConstraints().add(new ColumnConstraints(350));
layout.setGridLinesVisible(true);
final Label source = new Label ("DRAG ");
layout.add(source, 0, 0);
final Label target = new Label ("DROP ");
layout.add(target, 1, 0);
layout2 = new GridPane();
layout2.getColumnConstraints().add(new ColumnConstraints(20)); // column 1 is 20 wide
layout2.setGridLinesVisible(true);
final Label source1 = new Label ("fire");
layout2.add(source1, 0, 4);
root.getChildren().addAll(layout,layout2);
If you want to add them next to each other, best choice would be to use HBox layout:
HBox hBox = new HBox();
//hBox.setSpacing(5.0);
//hBox.setPadding(new Insets(5,5,5,5));
hBox.getChildren().addAll(layout, layout2);