在JavaFX中更改标签的文本

时间:2015-05-18 16:09:30

标签: javafx javafx-8 fxml fxmlloader

此问题已被问及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

但可以看到标签没有变化。我错过了一些重要的东西吗?

3 个答案:

答案 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);