通过 fxml 或 JavaFX 中的 Scene builder 在场景上动态添加小部件
Dynamically add widgets on a scene through fxml or Scene builder in JavaFX
我正在开发一个简单的 BeatBox,其中会根据选中的复选框播放不同的声音。
该程序应该有 256 个复选框,显示在 16x16 的网格上。因此,当我通过直接代码(即没有 fxml 或场景构建器)构建 GUI 时,我可以轻松地创建一个简单的循环来创建 256 个复选框,将它们添加到列表中以便我以后可以使用它们,并将它们添加到网格。
我正在尝试改变这种方法并使用场景构建器或直接在 fxml 文件上编码,但我想不出一种方法,我什至不知道那是不是可能的。试图弄清楚这一点,我遇到了这个疑问:
- 有没有办法通过 fxml 或场景构建器创建某种类型的小部件列表,其中填充了大量组件(对于我给定的示例,一个包含 256 个复选框的列表),然后在我的控制器上引用该列表class?
我真的不喜欢在场景生成器上拖放 256 个复选框,甚至在 fxml 上制作 256 个标签的想法。而且我认为该功能可能对许多其他情况有用。因此,如果可能的话,我很乐意提供帮助。
提前致谢!
FXML 格式不提供在循环中声明元素的方法。由于 Scene Builder 只是 FXML 文件的 WYSIWYG 编辑器,它也不提供此功能,也不提供声明和配置 256 个元素的快捷方式(例如通过对话框之类的)。这是在代码中添加节点是正确解决方案的情况之一。
为此,您需要将 FXML 文件 link 发送到控制器。从那里您可以在 initialize
方法中创建所有 256 个 CheckBox
es。此方法来自Initializable
interface, though since JavaFX 8 you no longer need to actually implement the interface. Instead, you just declare a no-arg method named initialize
(see ),如果非public
.
,则用@FXML
注释
这是一个小例子:
FXML 文件
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<!-- replace with your root -->
<HBox xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.example.Controller">
<GridPane fx:id="grid"/>
<!-- other elements... -->
</HBox>
控制器
package com.example;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.GridPane;
public class Controller {
@FXML private GridPane grid;
private CheckBox[][] boxes; // for access by grid coordinates
@FXML
private void initialize() {
boxes = new CheckBox[16][16];
for (int row = 0; row < boxes.length; row++) {
for (int col = 0; col < boxes[0].length; col++) {
CheckBox box = new CheckBox();
grid.add(box, col, row);
boxes[row][col] = box;
}
}
}
}
我正在开发一个简单的 BeatBox,其中会根据选中的复选框播放不同的声音。
该程序应该有 256 个复选框,显示在 16x16 的网格上。因此,当我通过直接代码(即没有 fxml 或场景构建器)构建 GUI 时,我可以轻松地创建一个简单的循环来创建 256 个复选框,将它们添加到列表中以便我以后可以使用它们,并将它们添加到网格。
我正在尝试改变这种方法并使用场景构建器或直接在 fxml 文件上编码,但我想不出一种方法,我什至不知道那是不是可能的。试图弄清楚这一点,我遇到了这个疑问: - 有没有办法通过 fxml 或场景构建器创建某种类型的小部件列表,其中填充了大量组件(对于我给定的示例,一个包含 256 个复选框的列表),然后在我的控制器上引用该列表class?
我真的不喜欢在场景生成器上拖放 256 个复选框,甚至在 fxml 上制作 256 个标签的想法。而且我认为该功能可能对许多其他情况有用。因此,如果可能的话,我很乐意提供帮助。
提前致谢!
FXML 格式不提供在循环中声明元素的方法。由于 Scene Builder 只是 FXML 文件的 WYSIWYG 编辑器,它也不提供此功能,也不提供声明和配置 256 个元素的快捷方式(例如通过对话框之类的)。这是在代码中添加节点是正确解决方案的情况之一。
为此,您需要将 FXML 文件 link 发送到控制器。从那里您可以在 initialize
方法中创建所有 256 个 CheckBox
es。此方法来自Initializable
interface, though since JavaFX 8 you no longer need to actually implement the interface. Instead, you just declare a no-arg method named initialize
(see public
.
@FXML
注释
这是一个小例子:
FXML 文件
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<!-- replace with your root -->
<HBox xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.example.Controller">
<GridPane fx:id="grid"/>
<!-- other elements... -->
</HBox>
控制器
package com.example;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.GridPane;
public class Controller {
@FXML private GridPane grid;
private CheckBox[][] boxes; // for access by grid coordinates
@FXML
private void initialize() {
boxes = new CheckBox[16][16];
for (int row = 0; row < boxes.length; row++) {
for (int col = 0; col < boxes[0].length; col++) {
CheckBox box = new CheckBox();
grid.add(box, col, row);
boxes[row][col] = box;
}
}
}
}