簡體   English   中英

嘗試在 TableView 中顯示對象列表時出現 javafx.fxml.LoadException JavaFX

[英]javafx.fxml.LoadException when trying to display a list of objects in a TableView JavaFX

我正在嘗試在 JavaFX 表中顯示對象列表,但是在循環遍歷要添加到表中的對象時,我一直遇到 JavaFX 異常,有人知道可能導致這種情況的原因嗎,我嘗試了幾種不同的 ObservableLists 實現但他們都看到產生相同的結果,我的結論是 class 或 .fxml 文件可能存在錯誤。 提前致謝。

JavaFX:

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

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="HomePageController">
   <left>
      <AnchorPane prefHeight="400.0" prefWidth="200.0" style="-fx-background-color: #c7a4ff;" BorderPane.alignment="CENTER">
         <children>
            <Label fx:id="userLabel" alignment="TOP_CENTER" contentDisplay="CENTER" text="Hello &lt;User&gt;" textAlignment="CENTER" textFill="WHITE">
               <font>
                  <Font name="Segoe UI Semilight" size="24.0" />
               </font>
               <padding>
                  <Insets bottom="10.0" left="25.0" right="25.0" top="10.0" />
               </padding>
            </Label>
               <padding>
                  <Insets bottom="10.0" left="25.0" right="25.0" top="10.0" />
               </padding>
            </Label>
            <Button layoutY="60.0" mnemonicParsing="false" onAction="#MenuSwitch" prefHeight="50.0" prefWidth="200.0" style="-fx-background-color: #aa80ff;" text="Home" textFill="WHITE">
               <font>
                  <Font size="14.0" />
               </font>
            </Button>
            <Button layoutY="120.0" mnemonicParsing="false" onAction="#MenuSwitch" prefHeight="50.0" prefWidth="200.0" style="-fx-background-color: #aa80ff;" text="Diet" textFill="WHITE">
               <font>
                  <Font size="14.0" />
               </font>
            </Button>
            <Button layoutY="180.0" mnemonicParsing="false" onAction="#MenuSwitch" prefHeight="50.0" prefWidth="200.0" style="-fx-background-color: #aa80ff;" text="Workout" textFill="WHITE">
               <font>
                  <Font size="14.0" />
               </font>
            </Button>
            <Button layoutY="240.0" mnemonicParsing="false" onAction="#MenuSwitch" prefHeight="50.0" prefWidth="200.0" style="-fx-background-color: #aa80ff;" text="Groups" textFill="WHITE">
               <font>
                  <Font size="14.0" />
               </font>
            </Button>
            <Button layoutY="300.0" mnemonicParsing="false" onAction="#MenuSwitch" prefHeight="50.0" prefWidth="200.0" style="-fx-background-color: #aa80ff;" text="User Information" textFill="WHITE">
               <font>
                  <Font size="14.0" />
               </font>
            </Button>
         </children>
      </AnchorPane>
   </left>
   <right>
      <AnchorPane prefHeight="400.0" prefWidth="394.0" BorderPane.alignment="CENTER">
         <children>
            <Label alignment="TOP_CENTER" contentDisplay="CENTER" layoutX="148.0" text="Home" textAlignment="CENTER" textFill="#aa80ff">
               <font>
                  <Font name="Segoe UI Semilight" size="24.0" />
               </font>
               <padding>
                  <Insets bottom="10.0" left="10.0" right="25.0" top="10.0" />
               </padding>
            </Label>
            <Label alignment="TOP_CENTER" contentDisplay="CENTER" layoutX="14.0" layoutY="55.0" text="My Goals" textAlignment="CENTER" textFill="#aa80ff">
               <font>
                  <Font name="Segoe UI Semilight" size="18.0" />
               </font>
               <padding>
                  <Insets bottom="10.0" left="10.0" right="25.0" top="10.0" />
               </padding>
            </Label>
            <TableView fx:id="tbData" layoutX="14.0" layoutY="102.0" prefHeight="200.0" prefWidth="360.0" style="-fx-background-color: #ffffff;">
              <columns>
                 <TableColumn fx:id="goalName" prefWidth="160.0" text="Name" />
                 <TableColumn fx:id="goalDate" prefWidth="50.0" text="Date" />
                 <TableColumn fx:id="goalStatus" prefWidth="75.0" text="Status" />
                 <TableColumn fx:id="goalGroups" prefWidth="10.0" text="Groups"/>
              </columns>
            </TableView>
         </children>
      </AnchorPane>
   </right>
   <bottom>
      <AnchorPane prefHeight="50.0" prefWidth="600.0" style="-fx-background-color: #c7a4ff;" BorderPane.alignment="CENTER">
         <children>
            <ImageView fitHeight="30.0" fitWidth="30.0" layoutX="380.0" layoutY="10.0" pickOnBounds="true" preserveRatio="true">
               <image>
                  <Image url="@img/add_box.png" />
               </image>
            </ImageView>
            <Button graphicTextGap="0.0" layoutX="380.0" layoutY="10.0" mnemonicParsing="false" onAction="#openSelectGoalTypePage" opacity="0.0" prefHeight="30.0" prefWidth="30.0" />
            <ImageView fitHeight="30.0" fitWidth="30.0" layoutX="300.0" layoutY="10.0" pickOnBounds="true" preserveRatio="true">
               <image>
                  <Image url="@img/mode_edit.png" />
               </image>
            </ImageView>
            <Button graphicTextGap="0.0" layoutX="300.0" layoutY="10.0" mnemonicParsing="false" onAction="#openEditGoalPage" opacity="0.0" prefHeight="30.0" prefWidth="30.0" />
            <ImageView fitHeight="30.0" fitWidth="30.0" layoutX="460.0" layoutY="10.0" pickOnBounds="true" preserveRatio="true">
               <image>
                  <Image url="@img/delete.png" />
               </image>
            </ImageView>
            <Button graphicTextGap="0.0" layoutX="460.0" layoutY="10.0" mnemonicParsing="false" onAction="#removeTableItem" opacity="0.0" prefHeight="30.0" prefWidth="30.0" />
         </children>
      </AnchorPane>
   </bottom>
</BorderPane>

Controller:

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class HomePageController extends BaseController implements Initializable {

    @FXML
    private TableView<Goal> tbData = new TableView<>();

    @FXML
    public TableColumn<Goal, String> goalName;

    @FXML
    public TableColumn<Goal, String> goalDate;

    @FXML
    public TableColumn<Goal, String> goalStatus;

    @FXML
    public TableColumn<Goal, String> goalGroups;

    /*@FXML
    private Label userLabel;*/

    //allow user to select a table item/row and delete it using the delete button
    public void removeTableItem(){

    }

    public void openSelectGoalTypePage(javafx.event.ActionEvent actionEvent) throws IOException {
        root = FXMLLoader.load(getClass().getResource("SelectGoalType.fxml"));
        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
        scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public void openAddGoalPage(javafx.event.ActionEvent actionEvent) throws IOException {
        //if user selects weight goal then open AddWeightGoal page
        //else if user selects workout goal then open AddWorkoutGoal page
        root = FXMLLoader.load(getClass().getResource("AddWeightGoal.fxml"));
        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
        scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public void openEditGoalPage(javafx.event.ActionEvent actionEvent) throws IOException {
        root = FXMLLoader.load(getClass().getResource("EditGoal.fxml"));
        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
        scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {



        tbData = new TableView<>();
        TableColumn<Goal, String> goalName = new TableColumn<>("GoalName");
        goalName.setCellValueFactory(new PropertyValueFactory<>("goalName"));
        TableColumn<Goal, String> goalDate = new TableColumn<>("GoalDate");
        goalDate.setCellValueFactory(new PropertyValueFactory<>("goalDate"));
        TableColumn<Goal, String> goalStatus = new TableColumn<>("GoalStatus");
        goalDate.setCellValueFactory(new PropertyValueFactory<>("goalStatus"));
        TableColumn<Goal, String> goalGroups = new TableColumn<>("GoalGroups");
        goalGroups.setCellValueFactory(new PropertyValueFactory<>("goalGroups"));
        tbData.getColumns().add(goalName);
        tbData.getColumns().add(goalDate);
        tbData.getColumns().add(goalStatus);
        tbData.getColumns().add(goalGroups);

        tbData.setItems(getGoals());

    }


    private ObservableList<Goal> getGoals(){
        ObservableList<Goal> goals = FXCollections.observableArrayList();
        for(int i = 0; i < user.getGoals().size(); i++){
            goals.add(user.getGoals().get(i));
        }
        return goals;
    }
}

目標 Class:

import java.io.Serial;
import java.io.Serializable;

public class Goal implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    public String getGoalName() {
        return goalName;
    }

    public void setGoalName(String goalName) {
        this.goalName = goalName;
    }



    public String getGoalDate() {
        return goalDate;
    }

    public void setGoalDate(String goalDate) {
        this.goalDate = goalDate;
    }

    public String getGoalStatus() {
        return goalStatus;
    }

    public void setGoalStatus(String goalStatus) {
        this.goalStatus = goalStatus;
    }

    public String getGoalGroups() {
        return goalGroups;
    }

    public void setGoalGroups(String goalGroups) {
        this.goalGroups = goalGroups;
    }

    public Goal(String goalName, String goalDate, String goalStatus, String goalGroups) {
        this.goalName = goalName;
        this.goalDate = goalDate;
        this.goalStatus = goalStatus;
        this.goalGroups = goalGroups;
    }

    String goalName;
    String goalDate;
    String goalStatus;
    String goalGroups;
} 

編輯:

I've done some more debugging and it seems when I surround it with a try-catch block it's pointing to my user object from the base controller being null, even though I believe I pass it to the controller here's the base controller which holds the user object ,以及我用來傳遞用戶 object 的調用(在作為參數傳遞之前確認用戶很好)。 我似乎得到的唯一堆棧跟蹤是加載程序,這是來自嘗試捕獲: java.lang.NullPointerException: Cannot invoke "User.getGoals()" because "this.user" is null

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;

import java.io.IOException;

public class BaseController {

    User user;

    Parent root;
    Stage stage;
    Scene scene;
    @FXML
    Label userLabel;

    //default constructor
    public BaseController(){

    }

    void setUser(User user){
        this.user = user;
        userLabel.setText(user.getUsername());
    }

    //connect to current user once logged in
    /*
    public BaseController(User user){
        displayUsername(User);
    }*/

    //display current logged in user's first name
    /*
    private void displayUsername(User user){
        userLabel.setText(user.firstName);
    }*/

    /**
     * Menu Functions just in case
     */
//    public void openHomePage(javafx.event.ActionEvent actionEvent) throws IOException {
//        root = FXMLLoader.load(getClass().getResource("HomePage.fxml"));
//        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
//        scene = new Scene(root);
//        stage.setScene(scene);
//        stage.show();
//    }
//
//    public void openDietPage(javafx.event.ActionEvent actionEvent) throws IOException {
//        root = FXMLLoader.load(getClass().getResource("DietPage.fxml"));
//        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
//        scene = new Scene(root);
//        stage.setScene(scene);
//        stage.show();
//    }
//
//    public void openWorkoutPage(javafx.event.ActionEvent actionEvent) throws IOException {
//        root = FXMLLoader.load(getClass().getResource("WorkoutPage.fxml"));
//        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
//        scene = new Scene(root);
//        stage.setScene(scene);
//        stage.show();
//    }
//
//    public void openGroupsPage(javafx.event.ActionEvent actionEvent) throws IOException {
//        root = FXMLLoader.load(getClass().getResource("GroupsPage.fxml"));
//        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
//        scene = new Scene(root);
//        stage.setScene(scene);
//        stage.show();
//    }
//
//    public void openUserPage(javafx.event.ActionEvent actionEvent) throws IOException {
//        root = FXMLLoader.load(getClass().getResource("UserPage.fxml"));
//        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
//        scene = new Scene(root);
//        stage.setScene(scene);
//        stage.show();
//    }

    public void MenuSwitch(javafx.event.ActionEvent actionEvent) throws IOException{
        String text = ((Button)actionEvent.getSource()).getText();
        String filename="";
        switch(text){
            case "Home":
                filename="HomePage.fxml";break;
            case "Diet":
                filename="DietPage.fxml";break;
            case "Workout":
                filename="WorkoutPage.fxml";break;
            case "Groups":
                filename="GroupsPage.fxml";break;
            case "User Information":
                filename="UserPage.fxml";break;
            case "Edit group":
                filename="EditGroupPage.fxml"; break;
            case "Create group":
                filename="CreateGroupPage.fxml";break;
            case "Add Diet Item":
                filename="AddDietItemPage.fxml"; break;
            case "EditWorkoutPage":
                filename="EditWorkoutPage.fxml";break;
            case "AddWorkoutPage":
                filename="AddWorkoutPage.fxml";break;
            case "EditUserPage":
                filename="EditUserPage.fxml";break;
        }
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(filename));

        Parent root = (Parent) fxmlLoader.load();

        BaseController baseController = fxmlLoader.getController();

        System.out.println(user);

        baseController.setUser(user);

        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
        scene = new Scene(root);
        stage.setScene(scene);
        stage.show();

    }
}

從之前通過用戶object的controller:

FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("HomePage.fxml"));

                    Parent root = (Parent) fxmlLoader.load();

                    HomePageController controller = fxmlLoader.getController();

                    controller.setUser(newUser);

                    stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
                    scene = new Scene(root);
                    stage.setScene(scene);
                    stage.show();

謝謝!

編輯二:完整堆棧跟蹤:

java.lang.NullPointerException: Cannot invoke "User.getGoals()" because "this.user" is null
java.lang.NullPointerException: Cannot invoke "User.getGoals()" because "this.user" is null
    at HomePageController.initialize(HomePageController.java:75)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2655)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2517)
    at UserLoginController.login(UserLoginController.java:108)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1729)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8886)
    at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3856)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1851)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2584)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    at java.base/java.lang.Thread.run(Thread.java:832)
java.sql.SQLException: The prepared statement has been finalized

在執行FXMLLoader.load()期間會調用控制器的initialize()方法,因此在調用setUser(...)之前會調用initialize()getGoals() )。 因此,當您嘗試調用user.getGoals()時, user是 null 。

要在您設置的結構中解決此問題,您需要在setUser(...)時填充表列表。 您可以在子類中使用重寫的setUser(...)方法來做到這一點。

另請注意,初始化@FXML的字段始終是錯誤的(因為它們由FXMLLoader初始化為 FXML 文件中定義的元素)。 所以你的 controller 應該是這樣的:

public class HomePageController extends BaseController implements Initializable {

    @FXML
    private TableView<Goal> tbData ;

    @FXML
    public TableColumn<Goal, String> goalName;

    @FXML
    public TableColumn<Goal, String> goalDate;

    @FXML
    public TableColumn<Goal, String> goalStatus;

    @FXML
    public TableColumn<Goal, String> goalGroups;

    /*@FXML
    private Label userLabel;*/

    //allow user to select a table item/row and delete it using the delete button
    public void removeTableItem(){

    }

    public void openSelectGoalTypePage(javafx.event.ActionEvent actionEvent) throws IOException {
        root = FXMLLoader.load(getClass().getResource("SelectGoalType.fxml"));
        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
        scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public void openAddGoalPage(javafx.event.ActionEvent actionEvent) throws IOException {
        //if user selects weight goal then open AddWeightGoal page
        //else if user selects workout goal then open AddWorkoutGoal page
        root = FXMLLoader.load(getClass().getResource("AddWeightGoal.fxml"));
        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
        scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public void openEditGoalPage(javafx.event.ActionEvent actionEvent) throws IOException {
        root = FXMLLoader.load(getClass().getResource("EditGoal.fxml"));
        stage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow();
        scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {



        goalName.setCellValueFactory(new PropertyValueFactory<>("goalName"));
        goalDate.setCellValueFactory(new PropertyValueFactory<>("goalDate"));
        goalDate.setCellValueFactory(new PropertyValueFactory<>("goalStatus"));
        goalGroups.setCellValueFactory(new PropertyValueFactory<>("goalGroups"));


    }

    @Override
    void setUser(User user){
        super.setUser(user);
        tbData.setItems(getGoals());
    }

    private ObservableList<Goal> getGoals(){
        return FXCollections.observableList(user.getGoals());
    }
}

更標准的方法是使用 MVC 類型的設計,其中用戶由ObjectProperty<User>表示,您可以觀察它的變化。 例如

public class BaseController {

    private final ObjectProperty<User> user;

    // ...

    //default constructor
    public BaseController(){
        user = new SimpleObjectProperty();
        user.addListener((obs, oldUser, newUser) ->
            userLabel.setText(newUser == null ? "" : newUser.getUsername()));
    }

    public ObjectProperty<User> userProperty() {
        return user ;
    }

    public final User getUser() {
        return userProperty().get();
    }

    public final void setUser(User user) {
        userProperty().set(user);
    }

    // ...
}

public class HomePageController extends BaseController implements Initializable {

    @FXML
    private TableView<Goal> tbData ;

    @FXML
    public TableColumn<Goal, String> goalName;

    @FXML
    public TableColumn<Goal, String> goalDate;

    @FXML
    public TableColumn<Goal, String> goalStatus;

    @FXML
    public TableColumn<Goal, String> goalGroups;

    public HomePageController() {
        userProperty().addListener((obs, oldUser, newUser) -> {
            if (newUser == null) {
                tbData.setItems(FXCollections.observableArrayList());
            } else {
                tbData.setItems(getGoals());
            }
        });
    }

    // ...

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        goalName.setCellValueFactory(new PropertyValueFactory<>("goalName"));
        goalDate.setCellValueFactory(new PropertyValueFactory<>("goalDate"));
        goalDate.setCellValueFactory(new PropertyValueFactory<>("goalStatus"));
        goalGroups.setCellValueFactory(new PropertyValueFactory<>("goalGroups"));


    }

    

    private ObservableList<Goal> getGoals(){
        return FXCollections.observableList(user.getGoals());
    }
}

通常在這里, user不是您需要觀察的唯一值,因此它將被分解到某處的 model 中。 例如,參見應用 MVC 與 JavaFx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM