图片的左侧:直接从intellij运行
图片的右侧:创建的胖jar(由名为" Jar with dependencies" 创建)从双击老鼠
如您所见,复选框未对齐。每个组件都是由代码而非fxml 创建的......可能是什么原因造成的?
修改
首先,宽度和高度是固定的。因此,他们永远不会改变。我禁用了它们下面你可以找到代码。
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;
答案 0 :(得分:1)
HBox
不保证它实际分配给其中包含的任何子节点的空间量。它只是保证按顺序放置它们,如果指定间距,则最小间隙,并尽最大努力将每个子节点的大小调整为其首选大小。您无法控制的许多因素都会影响每个节点的实际大小,包括字体大小(取决于可用字体),HBox
可用的总大小等等。所有这些因素可能会因平台而异应用程序正在运行,包括取决于JDK版本。
因此,尝试通过将它们放在HBox
的集合中来垂直排列并设置子节点的首选大小根本不是一种可靠的方法(并且不是这样设计的)。问题是没有真正的方法将一个HBox
的布局连接到另一个HBox
的布局:它们都是独立布局的。如果您想要放置组件以使它们在水平和垂直方向上相对于彼此对齐,则应使用专门为此目的设计的GridPane
。
通常一个非常糟糕的想法(不仅仅是在JavaFX中;这适用于大多数UI工具包)硬编码任何东西的大小,所以无论何时使用它作为解决方案,几乎肯定有更好的方法。< / p>
使用GridPane
背后的基本思路如下:
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);
您可以完全配置列之间(使用ColumnConstraints
实例)在行之间(使用RowConstraints
个实例)如何分配任何可能的额外空间,以及控件如何在其单个单元格中对齐(S)。如果需要,您还可以逐个节点指定这些内容。
您可能希望,例如,三列中的hgrow
为SOMETIMES
,SOMETIMES
和ALWAYS
;您可能需要将fillWidth
的{{1}}设置为TextInputControl
。
请参阅GridPane
documentation,它完全解释了这一点。