javafx - 使用 JavaFX 场景构建器用数组中的按钮填充 fx id

标签 javafx

我的应用程序中需要 15 个按钮,但我不想一一声明它们

@FXML
private Button button1;
@FXML
private Button button2;
@FXML
private Button button3;
...
...
...
...

相反,我想创建一个按钮数组。
@FXML
private Button[][] button = new Button[5][3];

但是,在场景构建器中,我只能选择一个按钮,我认为它引用的是数组而不是单个按钮元素。
有什么方法可以让我轻松完成这项工作吗?

最佳答案

请注意,可以将数据存储在 ArrayList 中。正如 GoXR3Plus 在他的回答中所描述的那样。但是,您不能在 fxml 中创建数组。为此,您需要从 java 代码创建数组(例如,在 initialize 方法中)并将一些信息附加到 Node允许您检索索引信息。

这可以例如通过使用静态辅助方法将信息以及 css 类选择器附加到节点来完成,并将这些节点的共同祖先注入(inject) Controller :

<VBox fx:id="root" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml.arraystore.StoreController">
    <children>
        <Button text="1" Helper.indices="0 0"/>
        <Button text="2" Helper.indices="0 1"/>
        <Button text="3" Helper.indices="1 1"/>
        <Button text="4" Helper.indices="1 0"/>
        <Button text="5" Helper.indices="2 0"/>
        <Button text="6" Helper.indices="2 1"/>
    </children>
</VBox>

helper
public class Helper {

    private static final String MARK_CLASS = "array-store-mark";
    private static final String MARK_CLASS_SELECTOR = "." + MARK_CLASS;
    private static final String INDICES_KEY = "arrayStoreIndices";

    public static void setIndices(Node node, String indices) {
        if (node == null || indices == null) {
            throw new IllegalArgumentException();
        }
        String[] parts = indices.split("\\s+");
        int[] is = new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1])};

        // add css class
        node.getStyleClass().add(MARK_CLASS);

        // add index data
        node.getProperties().put(INDICES_KEY, is);
    }

    public static <T extends Node> T[][] getAsArray(Node parent, Class<T> nodeClass) {
        if (parent == null) {
            throw new IllegalArgumentException();
        }
        int max1 = 0;
        int max2 = 0;

        // find nodes by class
        Set<Node> marked = parent.lookupAll(MARK_CLASS_SELECTOR);

        // find array size
        for (Node n : marked) {
            n.getStyleClass().remove(MARK_CLASS);
            if (nodeClass.isAssignableFrom(n.getClass())) {
                int[] is = (int[]) n.getProperties().get(INDICES_KEY);
                if (max1 < is[0]) {
                    max1 = is[0];
                }
                if (max2 < is[1]) {
                    max2 = is[1];
                }
            }
        }

        T[][] result = (T[][]) Array.newInstance(nodeClass, max1+1, max2+1);

        // put data in array
        for (Node n : marked) {
            int[] is = (int[]) n.getProperties().remove(INDICES_KEY);

            if (nodeClass.isAssignableFrom(n.getClass())) {
                result[is[0]][is[1]] = (T) n;
            }
        }

        return result;
    }

}

Controller 类
public class StoreController {

    // common parent
    @FXML
    private Parent root;

    private Button[][] buttons;

    @FXML
    private void initialize() {
        buttons = Helper.getAsArray(root, Button.class);
        System.out.println(Arrays.deepToString(buttons));
    }

}

关于javafx - 使用 JavaFX 场景构建器用数组中的按钮填充 fx id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40370897/

相关文章:

Java - 从终端运行 jar 可以,但双击会破坏功能

JavaFX - 加载自定义控件的样式表

Java FX 文本区域对齐

css - JavaFX 和 CSS RadioButton 样式

javafx - 实现拖动多个选中的节点

Java/JavaFX,从项目内部读取文件和jar文件

user-interface - JavaFX - 拖动鼠标按钮后设置 slider 值

java - 单击按钮时不执行方法 [JavaFX]

gradle - FontAwesomeFX使用Gradle(IntelliJ)找不到de.jensd:fontawesomefx-fontawesome:4.7.0-11

java - 是否可以在 M1 Mac 上使用 Java 11 运行 JavaFX?