JavaFX 在 GridPane 中动态制作按钮
JavaFX making buttons in a GridPane dynamically
我正在尝试制作一个充满按钮的 JavaFX GridPane。我有一个包含对象的 ArrayList,对于这些对象中的每一个,都需要制作一个按钮。但是,ArrayList 的大小并不总是相同的。因此,到目前为止,我已经制作了这段代码:
JavaFX GridPane 部分:
<AnchorPane fx:id="gridAnchorPane" minHeight="120.0" minWidth="450.0" prefHeight="120.0" prefWidth="550.0">
<GridPane fx:id="peopleGridPane" hgap="5.0" layoutX="98.0" layoutY="43.0" translateX="1.0" translateY="1.0" translateZ="1.0" vgap="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
</GridPane>
</AnchorPane>
如您所见,我有零行和零列,因为我打算使它们成为动态数量和大小。
制作按钮的控制器部分:
int GRIDWIDTH = //how many buttons are to fit in one row
for (int i = 0; i < people.size(); i++){
peopleGridPane.add(personButton(people.get(i).getName()), i % GRIDWIDTH, i / GRIDWIDTH);
}
private Button personButton(String name) {
button.setPrefSize(
peopleGridPane.getWidth() / GRIDWIDTH,
peopleGridPane.getHeight() / (people.size() / GRIDWIDTH)
);
使用这种方法,我遇到了两个问题。
- 当我的网格少于三个时"people",我的网格看起来像这样
- 当我启动应用程序时,网格看起来像这样
一头雾水,欢迎大家指教
对于问题2,我做了一个简单的复习:
主要:
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
控制器:
private int GRIDWIDTH = 3;
@FXML
@Override
public void initialize(URL location, ResourceBundle resources) {
refresh();
}
private void refresh() {
for (int i = 0; i < people.size(); i++) {
Button button = new Button(people.get(i).getName());
button.setPrefSize(
grid.getWidth() / GRIDWIDTH,
grid.getHeight() / (people.size() / GRIDWIDTH)
);
button.setOnAction(event -> refresh());
grid.add(button, i % GRIDWIDTH, i / GRIDWIDTH);
}
}
public Controller() {
people = new ArrayList<>();
people.add(new Person("P1"));
people.add(new Person("P2"));
people.add(new Person("P3"));
people.add(new Person("P4"));
}
.fxml 文件:
<SplitPane dividerPositions="0.5" orientation="VERTICAL" prefHeight="201.0" prefWidth="240.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<items>
<Pane prefHeight="200.0" prefWidth="200.0" />
<GridPane fx:id="grid" alignment="center" hgap="10" vgap="10">
</GridPane>
</items>
</SplitPane>
点击按钮之前。
点击按钮后。
我已经发现了两个问题的解决方案。
裁剪到边框
按钮夹入按钮的原因是因为我将一个整数 a 除以一个整数 b,当 b > a 时,结果为 0,因为两者都是整数。当我将数字转换为双精度时,结果数字类似于 0.3333 或 0.66666,因此大于 0 并解决了问题。
按钮宽度为 0
这里的问题是,当我第一次调用refresh()
时,屏幕上的所有元素还没有"exist"。也就是说,它们确实存在,但是它们还没有被放到屏幕上,这使得它们的宽度和高度为 0.0 或 -1.0。但是,如果您指定特定的高度或宽度,例如指定的或最小的 width/height,如果 window 的高度或宽度 < 1,您可以调用这些属性。这样,当您调整 [=27= 的大小时,它看起来仍然不太好] 因为此时的宽度和高度只是一个静态双精度数,但至少它是可读的。
我正在尝试制作一个充满按钮的 JavaFX GridPane。我有一个包含对象的 ArrayList,对于这些对象中的每一个,都需要制作一个按钮。但是,ArrayList 的大小并不总是相同的。因此,到目前为止,我已经制作了这段代码:
JavaFX GridPane 部分:
<AnchorPane fx:id="gridAnchorPane" minHeight="120.0" minWidth="450.0" prefHeight="120.0" prefWidth="550.0">
<GridPane fx:id="peopleGridPane" hgap="5.0" layoutX="98.0" layoutY="43.0" translateX="1.0" translateY="1.0" translateZ="1.0" vgap="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
</GridPane>
</AnchorPane>
如您所见,我有零行和零列,因为我打算使它们成为动态数量和大小。
制作按钮的控制器部分:
int GRIDWIDTH = //how many buttons are to fit in one row
for (int i = 0; i < people.size(); i++){
peopleGridPane.add(personButton(people.get(i).getName()), i % GRIDWIDTH, i / GRIDWIDTH);
}
private Button personButton(String name) {
button.setPrefSize(
peopleGridPane.getWidth() / GRIDWIDTH,
peopleGridPane.getHeight() / (people.size() / GRIDWIDTH)
);
使用这种方法,我遇到了两个问题。
- 当我的网格少于三个时"people",我的网格看起来像这样
- 当我启动应用程序时,网格看起来像这样
一头雾水,欢迎大家指教
对于问题2,我做了一个简单的复习:
主要:
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
控制器:
private int GRIDWIDTH = 3;
@FXML
@Override
public void initialize(URL location, ResourceBundle resources) {
refresh();
}
private void refresh() {
for (int i = 0; i < people.size(); i++) {
Button button = new Button(people.get(i).getName());
button.setPrefSize(
grid.getWidth() / GRIDWIDTH,
grid.getHeight() / (people.size() / GRIDWIDTH)
);
button.setOnAction(event -> refresh());
grid.add(button, i % GRIDWIDTH, i / GRIDWIDTH);
}
}
public Controller() {
people = new ArrayList<>();
people.add(new Person("P1"));
people.add(new Person("P2"));
people.add(new Person("P3"));
people.add(new Person("P4"));
}
.fxml 文件:
<SplitPane dividerPositions="0.5" orientation="VERTICAL" prefHeight="201.0" prefWidth="240.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<items>
<Pane prefHeight="200.0" prefWidth="200.0" />
<GridPane fx:id="grid" alignment="center" hgap="10" vgap="10">
</GridPane>
</items>
</SplitPane>
点击按钮之前。
点击按钮后。
我已经发现了两个问题的解决方案。
裁剪到边框
按钮夹入按钮的原因是因为我将一个整数 a 除以一个整数 b,当 b > a 时,结果为 0,因为两者都是整数。当我将数字转换为双精度时,结果数字类似于 0.3333 或 0.66666,因此大于 0 并解决了问题。
按钮宽度为 0
这里的问题是,当我第一次调用refresh()
时,屏幕上的所有元素还没有"exist"。也就是说,它们确实存在,但是它们还没有被放到屏幕上,这使得它们的宽度和高度为 0.0 或 -1.0。但是,如果您指定特定的高度或宽度,例如指定的或最小的 width/height,如果 window 的高度或宽度 < 1,您可以调用这些属性。这样,当您调整 [=27= 的大小时,它看起来仍然不太好] 因为此时的宽度和高度只是一个静态双精度数,但至少它是可读的。