添加FXML中定义的元素以循环列出 [英] adding elements defined in FXML to list with loop

查看:167
本文介绍了添加FXML中定义的元素以循环列出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多具有名称a1,a2,a3,...
的对象我需要将它们放入List中,因此使用它们更简单,我会以某种方式使用循环吗?

I have a lot of Objects with names a1, a2, a3, ... I need to put them into List, so that it was simplier to work with them, will I do it somehow with loop?

我的尝试是:

List<SomeObject> list = new LinkedList<SomeObject>();
for (int i=0; i<1000; i++){
    String varName = "a"+i;
    list.add((SomeObject) varName);
}

在这种情况下有人有建议吗?
在循环内创建变量不是解决方案,因为它们是.fxml文档的一部分。
或者给我一个如何使用循环创建的建议,因为它在.fxml中创建行并行添加循环新对象。

Does anyone have suggestions in this case? Create variables inside loop is not a solution, because they are a part of .fxml document. Or give me an advice how to create that with loop, for it create lines in .fxml parallel to adding in loop new objects.

更容易理解.fxml文件看起来像

To be more understandable .fxml file looks like

  <SomeObject fx:id="a1" *other props* />
  <SomeObject fx:id="a2" *other props* />
  <SomeObject fx:id="a3" *other props* />
  <SomeObject fx:id="a4" *other props* />

非常感谢您的建议!

推荐答案

如果您有这么多项目,最好使用Java初始化它们,而不是使用FXML。例如,而不是:

If you have that many items, it's probably best to initialize them using Java, rather than using FXML. For example, instead of:

<FlowPane fx:id="container" minWidth="..." minHeight="...">
    <Label fx:id="label1" text="Label 1"/>
    <Label fx:id="label2" text="Label 2"/>
    <Label fx:id="label3" text="Label 3"/>

    <!-- ... -->

    <Label fx:id="label1000" text="Label 1000"/>
</FlowPane>

和控制器

public class Controller {

    @FXML
    private FlowPane container ;
    @FXML
    private Label label1 ;
    @FXML
    private Label label2 ;
    // ...

    @FXML
    private Label label1000 ;

    // ...
}

我会做

<FlowPane fx:id="container" minWidth="..." minHeight="...">
</FlowPane>

public class Controller {

    @FXML
    private FlowPane container ;

    private List<Label> labels ;

    public void initialize() {
        labels = new ArrayList<>();
        for (int i = 1; i <= 1000; i++) {
            Label label = new Label("Label "+i);
            labels.add(label);
            container.getChildren().add(label);
        }
    }
}

作为这个想法的变种,考虑定义自定义组件:

As a variation on this idea, consider defining a custom component:

public class LabelFlow extends FlowPane {

    private List<Label> labels ;

    public LabelFlow(@NamedArg("numLabels") int numLabels) {
        labels = new ArrayList<>();
        for(int i = 1 ; i <= numLabels ; i++) {
            Label label = new Label("Label "+i);
            labels.add(label);
        }
        getChildren().addAll(labels);
    }

    public List<Label> getLabels() {
        return Collections.unmodifiableList(labels);
    }
}

现在使用FXML

<LabelFlow fx:id="labelFlow" numLabels="1000"/>

并在您的控制器中

public class Controller {
    @FXML
    private LabelFlow labelFlow ;

    public void initialize() {
        for (Label label : labelFlow.getLabels()) {
            // do whatever you need with label....
        }
    }
}

你需要跳过几个箍您想在Scene Builder中使用类似的自定义类。请参阅向SceneBuilder 2.0添加自定义组件

You need to jump through a couple of hoops if you want to use a custom class like that in Scene Builder. See Adding a custom component to SceneBuilder 2.0

如果确实想要在FXML中定义所有这些控件,这将是一个维护噩梦,你可以使用反射来访问变量。我不建议这样做,不仅因为它很难维护,而且因为它本质上的反射很容易出错(没有编译时检查)而且很复杂。

If you really want to define all those controls in FXML, which would be a maintenance nightmare imo, you can use reflection to access the variables. I don't recommend this, not just because it's hard to maintain, but also because reflection by its nature is error-prone (no compile-time checking) and complex.

但你可以做到

public class Controller {

    @FXML
    private FlowPane container ;
    @FXML
    private Label label1 ;
    @FXML
    private Label label2 ;
    // ...

    @FXML
    private Label label1000 ;

    private List<Label> labels ;

    public void initialize() throws Exception {
        labels = new ArrayList<>();
        for (int i = 1; i <= 1000; i++) {
            Field field = getClass().getDeclaredField("label"+i);
            boolean wasAccessible = field.isAccessible();
            field.setAccessible(true);
            Label label = (Label) field.get(this);
            field.setAccessible(wasAccessible);
            labels.add(label);
        }
    }
}

这篇关于添加FXML中定义的元素以循环列出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆