从另一个FXML/控制器更新TableView

问题描述 投票:0回答:1

我创建了一个 FXML 文件,允许用户查看患者是否进行了

TableView
中列出的手术,并且还能够添加新手术。要添加新手术,用户右键单击
TableView
,就会出现一个上下文菜单,其中包含菜单项“添加手术”。将出现一个新窗口,其中包含要添加到新手术中的文本字段。这是两个单独的 FXML 文件,每个文件都有自己的控制器文件。

理想的结果 - 当用户添加新手术时,我希望

TableView
刷新并添加新数据。

在 PatientModule 控制器中,我有以下内容:

@FXML
public TableView<ISurgeryModel> surgeryTableView;


ObservableList<ISurgeryModel> initialPTSurgData(){
    ISurgeryModel ptSur1 = new ISurgeryModel("10/20/2023", "Other", "L", "surgeon", "facility", "comments");
    return FXCollections.observableArrayList(ptSur1);
}


@Override
public void initialize(URL PatientModule, ResourceBundle resourceBundle) {
    surgeryDate.setCellValueFactory((new PropertyValueFactory<ISurgeryModel, String>("surgeryDate")));
    surgeryProcedure.setCellValueFactory((new PropertyValueFactory<ISurgeryModel, String>("surgeryProcedure")));
    surgerySide.setCellValueFactory((new PropertyValueFactory<ISurgeryModel, String>("surgerySide")));
    surgeryTableView.setItems(initialPTSurgData());
    ContextMenu surgContext = new ContextMenu();
    MenuItem addSurgery = new MenuItem("Add Surgery");
    MenuItem viewSurgDetails = new MenuItem("View Surgery Details");
    MenuItem deleteSurg = new MenuItem("Delete Surgery");
    surgContext.getItems().add(addSurgery);
    surgContext.getItems().add(viewSurgDetails);
    surgContext.getItems().add(deleteSurg);
    surgeryTableView.setContextMenu(surgContext);

    addSurgery.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            try {
                Parent popUp;
                popUp = FXMLLoader.load(Objects.requireNonNull(GaitApplication.class.getResource("Wizards/AddSurgery.fxml")));
                Stage stage1 = new Stage();
                stage1.setTitle("Add Surgery:   ");
                stage1.setScene(new Scene(popUp, 600, 480));
                stage1.show();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    });
}

AddSurgeryController
具有以下内容:

@FXML
private PatientModuleController patientModuleController;

@FXML
public void onSaveSurgery(ActionEvent event){
    ISurgeryModel newData = new ISurgeryModel(date.getText(), procedure.getText(), side.getText(), surgeon.getText(), facility.getText(), comments.getText());
    patientModuleController.surgeryTableView.getItems().add(newData);
    this.addSurgery.getScene().getWindow().hide();
}

当前,当点击“保存”按钮时,出现以下错误:

Cannot read field "surgeryTableView" because "this.patientModuleController" is null

我需要在

patientModuleController
中为
AddSurgeryController
创建一个构造函数吗?

javafx javafx-8 fxml
1个回答
0
投票

这是一个利用单独的对话框窗口和 FXML 对数据表执行创建、更新和删除操作的示例。

它使用了评论中讨论的一些概念。

创建一个模型,其中包含带有 提取器的可观察列表。

传递参数选项用于在调用窗口和对话框之间传递数据。它可以使用模型来实现此目的(例如,向模型添加可观察的 currentFriend 对象属性来表示当前正在编辑的好友,并将整个模型传递给新的对话框控制器),但这里没有必要。

在这个示例中,具有可观察列表的 Model 类并不是严格必需的。您可以仅依赖 TableView 中内置的列表,或者您创建并提供到支持 TableView 的控制器中的列表。不过,我提供了模型代码,以便您可以了解这样的设置如何工作以及该模型可用于其他任务。

可观察模型可用于的任务示例有:

  • 与应用程序的其他组件共享数据(例如数据库或持久层,或其他 GUI 控制器)
  • 将一些测试数据初始化到模型中(如本例所示)。

可观察模型可以扩展为以进一步可观察列表和属性的形式添加额外的应用程序数据和字段,但这对于这个简单的应用程序来说不是必需的。更大的应用程序可以有更大的可观察模型。如果使用依赖注入框架(例如 Spring),该模型可以表示为可注入 bean,框架将其注入到注入框架已知的任何组件中(例如,通过配置的 FXML 控制器工厂注入到 FXML 控制器中)。

该示例本可以使用内置的 JavaFX 对话框类,但改为使用为对话框手动创建的阶段。

添加功能

此代码演示了使用在新对话框窗口中创建的数据向表添加新行。

void addFriend() {
    int selectedIndex = friendsTable.getSelectionModel().getSelectedIndex();

    try {
        Friend newFriend = showFriendDialog(
                new Friend(null, null),
                "Add Friend"
        );

        if (newFriend != null) {
            friendsTable.getItems().add(
                    selectedIndex + 1,
                    newFriend
            );

            status.setText(
                    "Added " + newFriend.getFirstName() + " " + newFriend.getLastName()
            );
        }
    } catch (IOException e) {
        status.setText("Unable to add a friend.");
        e.printStackTrace();
    }
}

private Friend showFriendDialog(Friend friend, String title) throws IOException {
    FXMLLoader fxmlLoader = new FXMLLoader(
            FriendApplication.class.getResource(
                    "friend.fxml"
            )
    );
    Parent friendPane = fxmlLoader.load();
    FriendController addFriendController = fxmlLoader.getController();

    addFriendController.setFriend(friend);

    Stage addFriendStage = new Stage(StageStyle.UTILITY);
    addFriendStage.initModality(Modality.WINDOW_MODAL);
    addFriendStage.initOwner(getMyWindow());
    addFriendStage.setTitle(title);
    addFriendStage.setX(getMyWindow().getX() + getMyWindow().getWidth());
    addFriendStage.setY(getMyWindow().getY());
    addFriendStage.setScene(new Scene(friendPane));
    addFriendStage.showAndWait();

    return addFriendController.isSaved()
            ? friend
            : null;
}

示例代码

模块信息.java

module com.example.friends {
    requires javafx.controls;
    requires javafx.fxml;

    opens com.example.friends.controllers to javafx.fxml;
    exports com.example.friends;
}

private Friend showFriendDialog(Friend friend, String title) throws IOException {
    FXMLLoader fxmlLoader = new FXMLLoader(
            FriendApplication.class.getResource(
                    "friend.fxml"
            )
    );
    Parent friendPane = fxmlLoader.load();
    FriendController addFriendController = fxmlLoader.getController();

    addFriendController.setFriend(friend);

    Stage addFriendStage = new Stage(StageStyle.UTILITY);
    addFriendStage.initModality(Modality.WINDOW_MODAL);
    addFriendStage.initOwner(getMyWindow());
    addFriendStage.setTitle(title);
    addFriendStage.setX(getMyWindow().getX() + getMyWindow().getWidth());
    addFriendStage.setY(getMyWindow().getY());
    addFriendStage.setScene(new Scene(friendPane));
    addFriendStage.showAndWait();

    return addFriendController.isSaved()
            ? friend
            : null;
}

FriendApplication.java

package com.example.friends;

import com.example.friends.controllers.FriendsController;
import com.example.friends.model.Model;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class FriendApplication extends Application {
    private Model model;

    @Override
    public void start(Stage stage) throws IOException {
        model = new Model();

        FXMLLoader fxmlLoader = new FXMLLoader(
                FriendApplication.class.getResource(
                        "friends.fxml"
                )
        );
        Parent root = fxmlLoader.load();
        FriendsController controller = fxmlLoader.getController();
        controller.initModel(model);

        stage.setTitle("Friends");
        stage.setScene(new Scene(root));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

Friend.java

package com.example.friends.model;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Friend {
    private final StringProperty firstName;
    private final StringProperty lastName;

    public Friend(String firstName, String lastName) {
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
    }

    public String getFirstName() {
        return firstName.get();
    }

    public StringProperty firstNameProperty() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName.set(firstName);
    }

    public String getLastName() {
        return lastName.get();
    }

    public StringProperty lastNameProperty() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName.set(lastName);
    }

    @Override
    public String toString() {
        return "Friend{" +
                "firstName=" + getFirstName() +
                ", lastName=" + getLastName() +
                '}';
    }
}

模型.java

package com.example.friends.model;

import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class Model {
    private final ObservableList<Friend> friends = FXCollections.observableArrayList(friend ->
            new Observable[] {
                    friend.firstNameProperty(),
                    friend.lastNameProperty()
            }
    );

    public Model() {
        initTestData();
    }

    private void initTestData() {
        friends.setAll(
                new Friend("Sue", "Shallot"),
                new Friend("Perry", "Parsnip")
        );
    }

    public ObservableList<Friend> getFriends() {
        return friends;
    }
}

FriendsController.java

package com.example.friends.controllers;

import com.example.friends.FriendApplication;
import com.example.friends.model.Friend;
import com.example.friends.model.Model;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;

import java.io.IOException;

public class FriendsController {

    @FXML
    private TableView<Friend> friendsTable;

    @FXML
    private TableColumn<Friend, String> firstNameColumn;

    @FXML
    private TableColumn<Friend, String> lastNameColumn;

    @FXML
    private Button add;

    @FXML
    private Button edit;

    @FXML
    private Button remove;

    @FXML
    private Label status;

    private Model model;

    @FXML
    void addFriend() {
        int selectedIndex = friendsTable.getSelectionModel().getSelectedIndex();

        try {
            Friend newFriend = showFriendDialog(
                    new Friend(null, null),
                    "Add Friend"
            );

            if (newFriend != null) {
                friendsTable.getItems().add(
                        selectedIndex + 1,
                        newFriend
                );

                status.setText(
                        "Added " + newFriend.getFirstName() + " " + newFriend.getLastName()
                );
            }
        } catch (IOException e) {
            status.setText("Unable to add a friend.");
            e.printStackTrace();
        }
    }

    @FXML
    void editFriend() {
        Friend selectedFriend = friendsTable.getSelectionModel().getSelectedItem();
        if (selectedFriend == null) {
            return;
        }

        try {
            Friend editedFriend = showFriendDialog(
                    selectedFriend,
                    "Edit Friend"
            );

            if (editedFriend != null) {
                status.setText(
                        "Edited " + editedFriend.getFirstName() + " " + editedFriend.getLastName()
                );
            }
        } catch (IOException e) {
            status.setText("Unable to add a friend.");
            e.printStackTrace();
        }
    }

    @FXML
    void removeFriend() {
        ObservableList<Friend> friendsToRemove =
                friendsTable.getSelectionModel().getSelectedItems();

        if (friendsToRemove.isEmpty()) {
            return;
        }

        friendsTable.getItems().removeAll(
                friendsTable.getSelectionModel().getSelectedItems()
        );

        status.setText(
                "Removed " + friendsToRemove.size() + " friend(s)."
        );
    }

    @FXML
    private void initialize() {
        edit.disableProperty().bind(
                friendsTable.getSelectionModel().selectedItemProperty().isNull()
        );
        remove.disableProperty().bind(
                friendsTable.getSelectionModel().selectedItemProperty().isNull()
        );

        friendsTable.getSelectionModel().setSelectionMode(
                SelectionMode.MULTIPLE
        );

        firstNameColumn.setCellValueFactory(param ->
                param.getValue().firstNameProperty()
        );
        lastNameColumn.setCellValueFactory(param ->
                param.getValue().lastNameProperty()
        );
    }

    private Friend showFriendDialog(Friend friend, String title) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(
                FriendApplication.class.getResource(
                        "friend.fxml"
                )
        );
        Parent friendPane = fxmlLoader.load();
        FriendController addFriendController = fxmlLoader.getController();

        addFriendController.setFriend(friend);

        Stage addFriendStage = new Stage(StageStyle.UTILITY);
        addFriendStage.initModality(Modality.WINDOW_MODAL);
        addFriendStage.initOwner(getMyWindow());
        addFriendStage.setTitle(title);
        addFriendStage.setX(getMyWindow().getX() + getMyWindow().getWidth());
        addFriendStage.setY(getMyWindow().getY());
        addFriendStage.setScene(new Scene(friendPane));
        addFriendStage.showAndWait();

        return addFriendController.isSaved()
                ? friend
                : null;
    }

    private Window getMyWindow() {
        return friendsTable.getScene().getWindow();
    }

    public void initModel(Model model) {
        friendsTable.setItems(model.getFriends());

        this.model = model;
    }
}

FriendController.java

package com.example.friends.controllers;

import com.example.friends.model.Friend;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class FriendController {
    @FXML
    private TextField firstName;

    @FXML
    private TextField lastName;

    @FXML
    private Button save;

    @FXML
    private Button cancel;

    private Friend friend;
    private boolean saved;

    @FXML
    private void initialize() {
        ButtonBar.setButtonData(
                save,
                ButtonBar.ButtonData.APPLY
        );
        ButtonBar.setButtonData(
                cancel,
                ButtonBar.ButtonData.CANCEL_CLOSE
        );

        save.setDefaultButton(true);
        cancel.setCancelButton(true);

        save.disableProperty().bind(
                firstName.textProperty().isEmpty()
                        .or(
                                lastName.textProperty().isEmpty()
                        )
        );
    }

    public void setFriend(Friend friend) {
        this.friend = friend;

        firstName.setText(friend.getFirstName());
        lastName.setText(friend.getLastName());
    }

    @FXML
    void onSave() {
        // if required, you could do some validation on the data before saving here.

        friend.setFirstName(firstName.getText());
        friend.setLastName(lastName.getText());

        saved = true;

        getMyStage().close();
    }

    @FXML
    void onCancel() {
        getMyStage().close();
    }

    public boolean isSaved() {
        return saved;
    }

    private Stage getMyStage() {
        return (Stage) save.getScene().getWindow();
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>friends</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>friends</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <javafx.version>21.0.1</javafx.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
© www.soinside.com 2019 - 2024. All rights reserved.