此问题已被问及here,但无法找到任何答案。我已经复制了类似的情况,我想使用控制器从另一个类改变标签的文本
FXMLDocumentController.java
public class FXMLDocumentController implements Initializable {
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Connector.Connecting();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setLabelText(String text)
{
System.out.println("FXMLDocumentController.setLabelText(): Called");
label.setText(text);
}
}
FXMLDocument.fxml
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="demo5.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Demo5.java
public class Demo5 extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Connector.java
public class Connector {
public static void Connecting() {
try {
System.out.println("Connector.Connecting(): Called");
FXMLLoader loader = new FXMLLoader(FXMLDocumentController.class.getResource("FXMLDocument.fxml"));
loader.load();
FXMLDocumentController controller = (FXMLDocumentController) loader.getController();
controller.setLabelText("Bye World");
} catch (IOException ex) {
Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
在控制台输出
Connector.Connecting(): Called
FXMLDocumentController.setLabelText(): Called
但可以看到标签没有变化。我错过了一些重要的东西吗?
答案 0 :(得分:5)
您可以更改Connector类以接收Controller实例:
public class Connector {
public static void Connecting(FXMLDocumentController controller) {
try {
System.out.println("Connector.Connecting(): Called");
controller.setLabelText("Bye World");
} catch (IOException ex) {
Logger.getLogger(Connector.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class FXMLDocumentController implements Initializable {
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Connector.Connecting(this);
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setLabelText(String text)
{
System.out.println("FXMLDocumentController.setLabelText(): Called");
label.setText(text);
}
}
注意:强>
如果您的连接器需要更长的时间来执行它所需的任何内容,您可能希望使用任务,因此您不会冻结您的UI。要更新Label,您必须绑定text属性,然后使用updateMessage()
方法更新Text值。
public class FXMLDocumentController implements Initializable {
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("FXMLDocumentController.#handleButtonAction");
label.setText("Hello World!");
Task<Boolean> connectorTask = new ConnectorTask();
label.textProperty().bind(connectorTask.messageProperty());
connectorTask.setOnSucceeded(e -> {
// this is going to be called if the task ends up without error
label.textProperty().unbind();
});
new Thread(connectorTask).start();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
//public void setLabelText(String text)
//{
// System.out.println("FXMLDocumentController.setLabelText(): Called");
// label.setText(text);
//}
public class ConnectorTask extends Task<Boolean> {
@Override
protected Boolean call() throws Exception {
// ... do whatever you need here
// then you call this method to update the TextProperty from the Label that was bound.
updateMessage("Bye World");
return Boolean.TRUE;
}
}
}
答案 1 :(得分:1)
您的Demo5类和Connector类都通过调用FXMLLoader.load()
创建FXMLDocumentController的唯一实例。 Demo5类中的实例将放置在场景图中并变为可见。连接器中的实例未显示。当你调用setLabelText()时,它正在改变一个看不见的标签的文本。你可能想要做的是在Demo5中获取FXMLDocumentController实例,并通过构造函数或setter方法将它提供给Connector类。您可能需要根据Connector类的用途更改一些内容。或者,您可以使用连接器类加载FXML根和控制器并提供访问它们的方法,然后在Demo5中使用这些方法使场景可见。
答案 2 :(得分:1)
我通过在FXMLDocumentController.java中将Label定义为静态来以简单的方式实现它:
@FXML GridPane myGridPane;
public static Label totLabel = new Label("Total");
并在FXMLDocumentController类的initialize方法中将其添加到myGridPane:
@Override
public void initialize(URL url, ResourceBundle rb) {
myGridPane.add(totLabel, 0, 3);
}
在任何其他类中,您可以像这样调用此标签的setText():
String message = "this message will appear in the total label";//your string
FXMLDocumentController.totLabel.setText(message);