【发布时间】:2016-12-30 05:36:02
【问题描述】:
我是 JavaFX 的新手,目前正在尝试为学校项目制作日历应用程序。我想知道是否有办法连接fx:id 这样的
@FXML
private Label Box01;
(In function)
String ExampleNum = "01";
(Box+ExampleNum).setText("Test");
【问题讨论】:
标签: javafx concatenation
我是 JavaFX 的新手,目前正在尝试为学校项目制作日历应用程序。我想知道是否有办法连接fx:id 这样的
@FXML
private Label Box01;
(In function)
String ExampleNum = "01";
(Box+ExampleNum).setText("Test");
【问题讨论】:
标签: javafx concatenation
除了@jewelsea 提到的方法,这里还有另外两种方法:
创建并注入一个Map,其中包含作为来自 fxml 的值的框:
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml.Controller">
<children>
<Label text="foo" fx:id="a"/>
<Label text="bar" fx:id="b"/>
<Spinner fx:id="number">
<valueFactory>
<SpinnerValueFactory.IntegerSpinnerValueFactory min="1" max="2"/>
</valueFactory>
</Spinner>
<Button text="modify" onAction="#modify"/>
<fx:define>
<HashMap fx:id="boxes">
<box1>
<fx:reference source="a"/>
</box1>
<box2>
<fx:reference source="b"/>
</box2>
</HashMap>
</fx:define>
</children>
</VBox>
控制器
public class Controller {
private Map<String, Label> boxes;
@FXML
private Spinner<Integer> number;
@FXML
private Label box1;
@FXML
private Label box2;
@FXML
private void modify(ActionEvent event) {
boxes.get("box"+number.getValue()).setText("42");
}
}
将FXMLLoader 的namespace 传递给控制器,这是一个Map<String, Object> 映射fx:ids 到关联的Objects,到控制器:
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml.Controller">
<children>
<Label text="foo" fx:id="box1"/>
<Label text="bar" fx:id="box2"/>
<Spinner fx:id="number">
<valueFactory>
<SpinnerValueFactory.IntegerSpinnerValueFactory min="1" max="2"/>
</valueFactory>
</Spinner>
<Button text="modify" onAction="#modify"/>
</children>
</VBox>
控制器
public class Controller implements NamespaceReceiver {
private Map<String, Object> namespace;
@FXML
private Spinner<Integer> number;
@FXML
private Label box1;
@FXML
private Label box2;
@FXML
private void modify(ActionEvent event) {
((Label)namespace.get("box" + number.getValue())).setText("42");
}
@Override
public void setNamespace(Map<String, Object> namespace) {
this.namespace = namespace;
}
}
public interface NamespaceReceiver {
public void setNamespace(Map<String, Object> namespace);
}
加载 fxml 的代码:
public static <T> T load(URL url) throws IOException {
FXMLLoader loader = new FXMLLoader(url);
T result = loader.load();
Object controller = loader.getController();
if (controller instanceof NamespaceReceiver) {
((NamespaceReceiver) controller).setNamespace(loader.getNamespace());
}
return result;
}
【讨论】:
各种可能的解决方案:
你可以使用reflection,但那样会很丑,我不建议这样做。
通常,如果您有很多东西,您会将它们放在一个集合中,例如列表或数组。标签将是某个布局窗格的子级,因此您可以获取窗格的子级并按索引查找项目,例如:
((Label) parent.getChildren().get(0)).setText("Text");
如果标签已被分配一个 css id,那么您可以将其用于lookup 标签。
例如,在您的 FXML 定义中:
<Label text="hello" fx:id="Box01" id="Box01"/>
然后您可以使用以下方法查找标签:
String boxNum = "01";
Label box = (Label) parent.lookup("#Box" + boxNum);
只需通过引用来引用该项目:
@FXML private Label box01;
box01.setText("Test");
旁白:请按照standard Java conventions使用驼峰式。
【讨论】:
fx:id,但没有指定id,则fx:id被用作id,这使得fxml代码中的id="Box01"变得多余...