使用JavaFX场景构建器使用数组

时间:2016-11-02 00:56:59

标签: javafx

我的应用程序中需要15个按钮,但我不想像

一样逐个声明它们
@FXML
private Button button1;
@FXML
private Button button2;
@FXML
private Button button3;
...
...
...
...

相反,我想这样做,创建一个按钮数组。

@FXML
private Button[][] button = new Button[5][3];

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

2 个答案:

答案 0 :(得分:3)

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

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

<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>

<强>辅助

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;
    }

}

控制器类

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));
    }

}

答案 1 :(得分:1)

我假设你只能通过播放fxml文件的代码来修改它。

对于简单的ArrayList,您可以执行以下操作(选中fx:definefx:reference):

第一种方式 - > 1

        <fx:define>
          <!-- create buttons and store them in a list -->
           <ArrayList fx:id="buttonsArray">
              <Button fx:id="firstButton" />
              <Button fx:id="secondButton" />
              <Button fx:id="thirdButton" />
           </ArrayList>
        </fx:define>


        <!-- add buttons in the list to scene graph -->
        <fx:reference source="firstButton"/>
        <fx:reference source="secondButton"/>
        <fx:reference source="thirdButton"/>

第二种方式 - &gt; 2

        <!-- add buttons in the list to scene graph -->
         <Button fx:id="firstButton" />
         <Button fx:id="secondButton" />
         <Button fx:id="thirdButton" />

       <fx:define>
          <!--store them into a list -->
           <ArrayList fx:id="buttonsArray">
               <fx:reference source="firstButton"/>
               <fx:reference source="secondButton"/>
               <fx:reference source="thirdButton"/>
           </ArrayList>
        </fx:define>

关于多维 ArrayList [3] [2]使用第一种方式 - > 1 它必须是这样的:

       <fx:define>
          <!-- create buttons and store them in a list -->
           <ArrayList fx:id="array">
              <Button fx:id="Button_0_0" /> //first row , first column
              <Button fx:id="Button_0_1" />
              <Button fx:id="Button_0_2" />
              <ArrayList fx:id="buttonsArray">
                  <Button fx:id="Button_1_0" /> //second row , first column
                  <Button fx:id="Button_1_1" />
                  <Button fx:id="Button_1_2" />
              </ArrayList>
           </ArrayList>
        </fx:define>


         <!-- add buttons in the list to scene graph -->
         <fx:reference source="Button_0_0" />
         <fx:reference source="Button_0_1" />
         <fx:reference source="Button_0_2" />
         <fx:reference source="Button_1_0" />
         <fx:reference source="Button_1_1" />
         <fx:reference source="Button_1_2" />

我建议你阅读上面给出的所有链接,并且:

1)create array of Label using FXML in JavaFX

2)Grouping together JavaFX FXML Objects