有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JavaFX StackPane未从方法内部显示对象

好的,我用一个更简单的小例子重新编辑了这个问题

但我的问题是,我有一个StackPane,myStackPane,我正试图将标签加载到它上面。当程序首次运行时,StackPane为空。当我点击handleButtonAction按钮时,它会把我带到另一个阶段,这样我就可以在标签上输入我想要的文本。保存新文本后,它会将新设置传回主控制器,并更新标签的文本。然后将标签添加到StackPane

然而。。。。它不会在stackpane中显示新标签。我知道我正在进入这个方法,并且变量被正确地传递,因为我可以System.out.println所有的事情,并且它都是合适的。但为什么不将其添加到StackPane

谢谢大家

问题。爪哇

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Problems 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);
    }

}

FXMLDocumentController

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class FXMLDocumentController implements Initializable {

    @FXML
    private Button button;
    @FXML
    private StackPane myStackPane;

    private Label label = new Label("Text 1");

    @FXML
    private void handleButtonAction(ActionEvent event) {
        FXMLLoader secondLoader = new FXMLLoader();

        secondLoader.setLocation(getClass().getResource("FXMLSecond.fxml"));

        try {
            secondLoader.load();
        } catch (IOException e) {
        }

        FXMLSecondController secondController = secondLoader.getController();

        secondController.setFieldText(label.getText());

        Parent p = secondLoader.getRoot();
        Stage stage = new Stage();
        stage.setScene(new Scene(p));
        stage.showAndWait();
    }

    public void putLabelOnStackPane(String value) {
        label.setText(value);

        myStackPane.getChildren().add(label);
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

}

FXMLSecondController

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class FXMLSecondController implements Initializable {

    @FXML
    private Button saveText;
    @FXML
    private TextField textField;

    /**
     * Initializes the controller class.
     */


    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

    @FXML
    private void saveTextBtnPressed(ActionEvent event) {
        FXMLLoader firstLoader = new FXMLLoader();

        firstLoader.setLocation(getClass().getResource("FXMLDocument.fxml"));

        try {
            firstLoader.load();
        } catch (IOException e) {
        }

        FXMLDocumentController firstController = firstLoader.getController();

        firstController.putLabelOnStackPane(textField.getText());

        Stage stage = (Stage) saveText.getScene().getWindow();
        stage.close();
    }

    public void setFieldText(String value) {
        textField.setText(value);
    }

}

FXMLDocument

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="problems.FXMLDocumentController">
    <children>
        <Button fx:id="button" layoutX="128.0" layoutY="14.0" onAction="#handleButtonAction" text="Click Me!" />
      <StackPane fx:id="myStackPane" layoutX="61.0" layoutY="45.0" prefHeight="150.0" prefWidth="200.0" />
    </children>
</AnchorPane>

FXMLSecond

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/10.0.1" fx:controller="problems.FXMLSecondController">
   <children>
      <Button fx:id="saveText" layoutX="274.0" layoutY="106.0" mnemonicParsing="false" onAction="#saveTextBtnPressed" text="Button" />
      <TextField fx:id="textField" layoutX="226.0" layoutY="175.0" />
   </children>
</AnchorPane>

共 (1) 个答案

  1. # 1 楼答案

    主要问题是

    FXMLLoader firstLoader = new FXMLLoader();
    firstLoader.setLocation(getClass().getResource("FXMLDocument.fxml"));
    

    实际上,您构建了一个新的FXMLLoader,而不是获取对打开的FXMLLoader的引用
    例如,可以通过使用静态成员(参见here)获得对openFXMLLoader的引用,但最好使用稍微不同的方法:

    FXMLDocumentController。java

    public class FXMLDocumentController implements Initializable {
    
        @FXML
        private Button button;
        @FXML
        private StackPane myStackPane;
    
        private Label label = new Label("Text 1");
    
        @FXML
        private void handleButtonAction(ActionEvent event) {
    
            FXMLLoader secondLoader = new FXMLLoader();
            secondLoader.setLocation(getClass().getResource("FXMLSecond.fxml"));
    
            try {
                secondLoader.load();
            } catch (IOException e) {e.printStackTrace();  }
    
            FXMLSecondController secondController = secondLoader.getController();
            //secondController.setFieldText(label.getText());
            secondController.setTextProperty(label.textProperty());
    
            Parent p = secondLoader.getRoot();
            Stage stage = new Stage();
            stage.setScene(new Scene(p));
            stage.showAndWait();
            myStackPane.getChildren().add(label);
        }
    
        /*
        public void putLabelOnStackPane(String value) {
            label.setText(value);
    
            myStackPane.getChildren().add(label);
        }*/
    
        @Override
        public void initialize(URL url, ResourceBundle rb) { //no need to implement Initializable 
                                                             //if initialize not used 
        }    
    }
    

    FXMLSecondController。java

    public class FXMLSecondController implements Initializable {
    
        @FXML
        private Button saveText;
        @FXML
        private TextField textField;
    
        private StringProperty labelStringProperty;
    
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            textField.setEditable(true);
        }    
    
        @FXML
        private void saveTextBtnPressed(ActionEvent event) {
    
            /** By doing so you actually construct a new FXMLDocument
            FXMLLoader firstLoader = new FXMLLoader();
            firstLoader.setLocation(getClass().getResource("FXMLDocument.fxml"));
    
            try {
                firstLoader.load();
            } catch (IOException e) {
            }
    
            FXMLDocumentController firstController = firstLoader.getController();
            firstController.putLabelOnStackPane(textField.getText());
            */
            labelStringProperty.set(textField.getText());
            Stage stage = (Stage) saveText.getScene().getWindow();
            stage.close();
        }
    
        /*
        public void setFieldText(String value) {
            textField.setText(value);
        }*/
    
        public void setTextProperty(StringProperty labelStringProperty) {
            this.labelStringProperty = labelStringProperty;
            textField.setText(labelStringProperty.get());
        }
    }
    

    也考虑使用{a2}进行输入。

    编辑 要让FXMLSecondControllerFXMLDocoment更改FXMLDocumentController添加标签,以将所需的引用传递给FXMLSecondController

    public class FXMLDocumentController {
    
        @FXML
        private Button button;
        @FXML
        private StackPane myStackPane;
    
        private Label label = new Label("Text 1");
    
        @FXML
        private void handleButtonAction(ActionEvent event) {
    
            FXMLLoader secondLoader = new FXMLLoader();
            secondLoader.setLocation(getClass().getResource("FXMLSecond.fxml"));
    
            try {
                secondLoader.load();
            } catch (IOException e) {e.printStackTrace();  }
    
            FXMLSecondController secondController = secondLoader.getController();
            secondController.setRefrences(myStackPane.getChildren(), label);
    
            Parent p = secondLoader.getRoot();
            Stage stage = new Stage();
            stage.setScene(new Scene(p));
            stage.showAndWait();
        } 
    }
    

    并让FXMLSecondController使用这些参考资料:

    public class FXMLSecondController {
    
        @FXML
        private Button saveText;
        @FXML
        private TextField textField;
    
        private ObservableList<Node> children;
        private Label label;
    
        @FXML
        private void saveTextBtnPressed(ActionEvent event) {
    
            label.setText(textField.getText());
            children.add(label);
            Stage stage = (Stage) saveText.getScene().getWindow();
            stage.close();
        }
    
        public void setRefrences(ObservableList<Node> children, Label label) {      
            this.children = children;
            this.label = label;
            textField.setText(label.getText());
        }
    }