关于java:将FXML中定义的元素添加到循环列表中
adding elements defined in FXML to list with loop
我有很多名称为 a1、a2、a3、...的对象
我需要将它们放入列表中,以便使用它们更简单,我会以某种方式使用循环吗?
我的尝试是:
|
1
2 3 4 5 |
List<SomeObject> list = new LinkedList<SomeObject>();
for (int i=0; i<1000; i++){ String varName ="a"+i; list.add((SomeObject) varName); } |
在这种情况下,有人有什么建议吗?
在循环内创建变量不是解决方案,因为它们是 .fxml 文档的一部分。
或者给我一个建议,如何使用循环创建它,因为它在 .fxml 中创建与添加循环新对象平行的行。
为了更容易理解,.fxml 文件看起来像
|
1
2 3 4 |
<SomeObject fx:id="a1" *other props* />
<SomeObject fx:id="a2" *other props* /> <SomeObject fx:id="a3" *other props* /> <SomeObject fx:id="a4" *other props* /> |
非常感谢您的建议!
相关讨论
- 你为什么要创建很多对象 a1,a2,a3 而不是首先将它们放在列表中?
- 您真的在这样的 FXML 文件中定义了 1,000 个项目吗?当然,最好首先在 Java 中定义它们(即在您的控制器中),然后将它们添加到那里的 UI 中。
- 它只需要 10 次复制粘贴,2^10=1024 所以是的,我在 Scene builder=) James_D 中就是这样做的,你能举个例子来理解你的意思吗?
如果您有这么多项目,最好使用 Java 来初始化它们,而不是使用 FXML。例如,代替:
|
1
2 3 4 5 6 7 8 9 |
<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"/> |
和一个控制器
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Controller {
@FXML @FXML // ... |
我愿意
|
1
2 |
<FlowPane fx:id="container" minWidth="..." minHeight="...">
</FlowPane> |
和
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Controller {
@FXML private List<Label> labels ; public void initialize() { |
作为这个想法的变体,考虑定义一个自定义组件:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class LabelFlow extends FlowPane {
private List<Label> labels ; public LabelFlow(@NamedArg("numLabels") int numLabels) { public List<Label> getLabels() { |
现在在你的 FXML 中你做
|
1
|
<LabelFlow fx:id="labelFlow" numLabels="1000"/>
|
在你的控制器中
|
1
2 3 4 5 6 7 8 9 10 |
public class Controller {
@FXML private LabelFlow labelFlow ; public void initialize() { |
如果您想在 Scene Builder 中使用类似的自定义类,您需要跳过几个环节。请参阅将自定义组件添加到 SceneBuilder 2.0
如果您真的想在 FXML 中定义所有这些控件,这将是 imo 维护的噩梦,您可以使用反射来访问变量。我不推荐这个,不仅因为它难以维护,还因为反射本质上容易出错(没有编译时检查)和复杂。
但你可以做到
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class Controller {
@FXML @FXML private List<Label> labels ; public void initialize() throws Exception { |
相关讨论
- 非常感谢!它非常有用!
您可能更喜欢将对象直接放入 fxml 中的列表中:
|
1
2 3 4 5 6 7 8 |
<fx:define>
<FXCollections fx:id="theList" fx:factory="observableArrayList"> <SomeObject someProperty="SomeValue 1" /> <SomeObject someProperty="SomeValue 2" /> <SomeObject someProperty="SomeValue 3" /> <SomeObject someProperty="SomeValue 4" /> </FXCollections> </fx:define> |
并在控制器中访问它:
|
1
2 3 4 5 6 7 8 9 |
@FXML
private ObservableList<SomeObject> theList; @Override |
如果您不单独访问每个 SomeObject,您可以为它们删除 fx:id。有关 fxml 功能的更多信息,请参阅 FXML 简介。
相关讨论
- 谢谢,我今晚试试。想想,Dμhat 正是我要找的东西!
我个人更喜欢另一种可能性,但只是为了完整性:
你也可以在加载后通过fx:id属性访问由FXMLLoader创建的Object,使用FXMLLoader.getNamespace():
例子
命名空间.fxml
|
1
2 3 4 5 |
<AnchorPane xmlns:fx="http://javafx.com/fxml/1">
<children> <Text fx:id="node1" text="42"/> </children> </AnchorPane> |
正在加载
|
1
2 3 |
FXMLLoader loader = new FXMLLoader(getClass().getResource("namespace.fxml"));
loader.load(); System.out.println(((Text)loader.getNamespace().get("node1")).getText()); |
从 fxml 中的 Text 元素打印文本(即 42)。
当然,默认情况下,您无法访问控制器中的 FXMLLoader 实例,这意味着使用这种方法,您需要自己将信息传递给控制器??,如果那里需要的话。