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.
Related
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);
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 have an HBox with two GridPanels, a bigger one in the left and a smaller one in the right (starting at the end of the right side the scene) however I cannot manage to get them in the positions I want to. This is how it looks right now. As you can see, the red GridPane is on top of the other one. The red panel should go all the wait to the right.
Moreover, I would like them to stay in the same position even if some buttons or text are added to either one of the GridPanes.
Here is my code:
//TEST BUTTONS PANEL
testButtonPane = new GridPane();
testButtonPane.setHgap(10);
testButtonPane.setVgap(9);
testButtonPane.setPadding(new Insets(140, 100, 0, 100));
questionLabel = new Label("Question:");
questionLabel.setPrefWidth(500.0);
questionLabel.setPrefHeight(50.0);
questionLabel.setStyle("-fx-font: 30 timesnewroman; -fx-base: #AE3522");
testButtonPane.add(questionLabel,1,1);
testButtonPane.add(backButton,1,10);
backButton = new Button("BACK");
backButton.setOnAction(e -> primaryStage.setScene(sceneCreateTest));
backButton.setPrefWidth(140.0);
backButton.setPrefHeight(50.0);
backButton.setStyle("-fx-font: 30 timesnewroman; -fx-base: #AE3522");
testButtonPane.add(backButton,1,10);
//SCORE PANEL
scoreButtonPane = new GridPane();
scoreButtonPane.setHgap(10);
scoreButtonPane.setVgap(9);
scoreButtonPane.setPadding(new Insets(10, 10, 0, 10));
scoreButtonPane.setStyle("-fx-background-color: #AE3522;-fx-border-color: black");
statusTitleLabel = new Label("STATUS");
statusTitleLabel.setPrefWidth(160.0);
statusTitleLabel.setPrefHeight(50.0);
statusTitleLabel.setStyle("-fx-font: 30 timesnewroman; -fx-text-fill:black ;");
scoreButtonPane.add(statusTitleLabel,1,1,2,1);
scoreLabel = new Label("Score: ");
scoreLabel.setPrefWidth(130.0);
scoreLabel.setPrefHeight(50.0);
scoreLabel.setStyle("-fx-font: 20 timesnewroman; -fx-text-fill:black ;");
scoreButtonPane.add(scoreLabel,1,2);
timerLabel = new Label("Time: ");
timerLabel.setPrefWidth(130.0);
timerLabel.setPrefHeight(50.0);
timerLabel.setStyle("-fx-font: 20 timesnewroman; -fx-text-fill:black ;");
scoreButtonPane.add(timerLabel,1,3);
QInLabel = new Label("Question: ");
QInLabel.setPrefWidth(130.0);
QInLabel.setPrefHeight(50.0);
QInLabel.setStyle("-fx-font: 20 timesnewroman; -fx-text-fill:black ;");
scoreButtonPane.add(QInLabel,1,4);
//Makes possible to have two panes in the same scene/layout
HBox hBoxTest = new HBox();
hBoxTest.setSpacing(10.0);
hBoxTest.setPadding(new Insets(140,10,50,10));
hBoxTest.getChildren().addAll(testButtonPane, scoreButtonPane);
The test buttons panel should go in the left and the score panel is the red one and should go in the right. I hope you can help me. Thank you so much in advance. =)
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:
Hi I want to create a billing page as part of my Mini-project as in image project billing. I tried to create it using setBounds. But i didn't get the desired page. Can anyone help me to do this?
package start;
void makeandshowGUI()
{
billno=new JTextField(15);
dd=new JTextField(2);
mm=new JTextField(2);
yy=new JTextField(2);
itemcode=new JTextField(5);
itemname=new JTextField(50);
qty=new JTextField(3);
cname=new JTextField(50);
wlcm=new JLabel("Product Billing # BillDesk");
ptotal=new JLabel("");
billn=new JLabel("Bill No.:");
billdate=new JLabel("Bill Date");
cusname=new JLabel("Customer Name");
pid=new JLabel("Product ID:");
slash1=new JLabel("/");
slash2=new JLabel("/");
pname=new JLabel("Product Name:");
pqty=new JLabel("Qty:");
total=new JLabel("Total:");
billd=new JLabel("Billing Details");
purchased=new JLabel("Purchase Details");
ftotal=new JLabel("Total:");
disc=new JLabel("Discount:");
gtotal=new JLabel("Grand Total:");
save=new JButton("Save Bill & Print");
view=new JButton("View Bill");
list=new JButton("..");
String[] columnNames = {"Sl. No.",
"Product ID",
"Product Name",
"Qty",
"Rate","Price"};
JFrame bill=new JFrame("Product Billing || BillDesk");
bill.setSize(1000,5000);
bill.setBackground(Color.white);
bill.setVisible(true);
bill.setResizable(false);
bill.setMinimumSize(new Dimension(1000, 1000));
DefaultTableModel model = new DefaultTableModel(columnNames,10);
JTable billTable=new JTable(model)
{#Override
public boolean isCellEditable(int arg0, int arg1) {
return false;
}};
JScrollPane pane = new JScrollPane(billTable);
Container c=bill.getContentPane();
bill.setLayout(null);
wlcm.setBounds(500, 0, 200, 20);
billn.setBounds(0, 100, 100, 25);
billno.setBounds(52,100,100,25);
billdate.setBounds(700, 100, 100, 25);
dd.setBounds(751, 100,20, 25);
slash1.setBounds(772,100,5,25);
mm.setBounds(777, 100,20, 25);
slash2.setBounds(810,100,5,25);
yy.setBounds(813, 100,20, 25);
cusname.setBounds(0, 130, 50, 25);
cname.setBounds(55, 130, 50, 25);
pid.setBounds(0, 200, 50, 25);
itemcode.setBounds(55, 200, 30, 25);
pname.setBounds(100, 200, 50,25);
itemname.setBounds(125, 200, 50,25);
list.setBounds(206, 200, 5, 25);
pqty.setBounds(215, 200, 25, 25);
qty.setBounds(145, 200, 25, 25);
total.setBounds(175, 200, 25, 25);
ptotal.setBounds(205, 200, 50, 50);
c.add(wlcm,FlowLayout.LEADING);
c.add(billn);
c.add(billdate);
c.add(cusname);
c.add(pid);
c.add(pname);
c.add(pqty);
c.add(slash1);
c.add(slash2);
c.add(ptotal);
c.add(billno);
c.add(dd);
c.add(mm);
c.add(yy);
c.add(cname);
c.add(cusname);
c.add(itemcode);
c.add(itemname);
c.add(list);
c.add(qty);
c.add(total);
c.add(ptotal);
}
`
Why are you manually trying to arrange everything ? You should consider using a LayoutManager which will handle the task for you.
JComponents with their ability to nest are really powerful and allow you to create really neat UIs without having to worry about manually positioning them. Each one of the nested JComponent, say a JPanel can have a different LayoutManager associated with them.
Also, the 4 parameters in setBounds() are:
x - the new x-coordinate of this component
y - the new y-coordinate of this component
width - the new width of this component
height - the new height of this component
The problem is the width and height. Manually assigning them will give an inconsistent look-and-feel to your application across screens of different resolutions. A LayoutManager will handle all that for you.