tableview项不刷新,但在从不同的控制器添加它们之后已正确添加

rsl1atfo  于 2021-07-14  发布在  Java
关注(0)|答案(0)|浏览(184)

首先我想说的是,我已经检查了这个问题的各种类似的解决方案,但是发布这个问题的其他用户的代码设计与我的非常不同,我不知道如何使用发布的解决方案来解决相同的问题。
也就是说,我正在使用javafx和glion场景生成器来创建我的第一个应用程序。我会把代码贴在下面。这个(https://i.imgur.com/lo2mhzi.png)是应用程序目前的样子。“新建”按钮打开此窗口(https://i.imgur.com/kvz5tjt.png).
我有一个叫做weightapp的主类:

package application;

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

    public class WeightApp extends Application {

        @Override
        public void start(Stage primaryStage) throws Exception{
            Parent root = FXMLLoader.load(getClass().getResource("foodTab.fxml"));
            Scene main = new Scene(root);
            primaryStage.setScene(main);
            primaryStage.setTitle("App");
            primaryStage.setMinWidth(root.minWidth(-1));
            primaryStage.setMinHeight(root.minHeight(-1));
            primaryStage.show();
        }

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

一个foodtontroller类,它加载第一张图片中显示的内容,而不加载通过按new创建的窗口:

package application;

    import application.domain.Aliment;
    import javafx.collections.FXCollections;
    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.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.AnchorPane;
    import javafx.stage.Stage;
    import java.io.*;
    import java.util.Objects;

    public class FoodTabController {

        @FXML
        protected AnchorPane app, foodTab, foodButtonBar;

        @FXML
        protected TabPane mainWindow;

        @FXML
        protected Tab summaryTabLabel, foodTabLabel;

        @FXML
        protected Label alimentsLabel;

        @FXML
        protected Button deleteButton, refreshButton, newButton, newMealWindow;

        @FXML
        protected TableView<Aliment> alimentsTableView;

        @FXML
        protected TableColumn<Aliment, String> alimentsNameCol;

        @FXML
        protected TableColumn<Aliment, Double> alimentsKcalCol, alimentsFatCol, alimentsCarbsCol, alimentsProteinCol, alimentsFiberCol;

        protected ObservableList<Aliment> aliments = FXCollections.observableArrayList();

        public void initialize() {
            alimentsNameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
            alimentsKcalCol.setCellValueFactory(new PropertyValueFactory<>("calories"));
            alimentsFatCol.setCellValueFactory(new PropertyValueFactory<>("fat"));
            alimentsCarbsCol.setCellValueFactory(new PropertyValueFactory<>("carbohydrate"));
            alimentsProteinCol.setCellValueFactory(new PropertyValueFactory<>("protein"));
            alimentsFiberCol.setCellValueFactory(new PropertyValueFactory<>("fiber"));

            loadAliments();

            alimentsTableView.setItems(aliments);

        }

        // Aliments //

        public void newAlimentWindow() throws IOException {
            Parent newAlimentWindow = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("newAlimentWindow.fxml")));
            Stage stage = new Stage();
            stage.setScene(new Scene(newAlimentWindow));
            stage.show();
        }

        public void updateTableView() {
            aliments.clear();
            loadAliments();
        }

        public ObservableList<Aliment> alimentObservableList() {
            return aliments;
        }

        public void deleteAliment() {
            aliments.remove(alimentsTableView.getSelectionModel().getSelectedItem());
            saveAliments();
        }

        public void saveAliments() {
            String COMMA_DELIMITER = ",";
            String NEW_LINE_SEPARATOR = "\n";
            String FILE_HEADER = "aliment,calories,fat,carbs,protein,fiber";

            FileWriter fw = null;

            try {
                fw = new FileWriter("aliments.csv");

                fw.append(FILE_HEADER);
                fw.append(NEW_LINE_SEPARATOR);

                for (Aliment aliment : aliments) {
                    fw.append(String.valueOf(aliment.getName()));
                    fw.append(COMMA_DELIMITER);
                    fw.append(String.valueOf(aliment.getCalories()));
                    fw.append(COMMA_DELIMITER);
                    fw.append(String.valueOf(aliment.getFat()));
                    fw.append(COMMA_DELIMITER);
                    fw.append(String.valueOf(aliment.getCarbohydrate()));
                    fw.append(COMMA_DELIMITER);
                    fw.append(String.valueOf(aliment.getProtein()));
                    fw.append(COMMA_DELIMITER);
                    fw.append(String.valueOf(aliment.getFiber()));
                    fw.append(NEW_LINE_SEPARATOR);
                }
            } catch (Exception e) {
                System.out.println("Error writing to file");
                e.printStackTrace();
            } finally {
                try {
                    assert fw != null;
                    fw.flush();
                    fw.close();
                } catch (IOException e) {
                    System.out.println("Error while flushing/closing FileWriter.");
                    e.printStackTrace();
                }
            }
        }

        public void loadAliments()  {
            String COMMA_DELIMITER = ",";
            int ALIMENT_NAME = 0;
            int ALIMENT_CALORIES = 1;
            int ALIMENT_FAT = 2;
            int ALIMENT_CARBS = 3;
            int ALIMENT_PROTEIN = 4;
            int ALIMENT_FIBER = 5;

            BufferedReader fileReader = null;

            try {
                fileReader = new BufferedReader(new FileReader("aliments.csv"));
                fileReader.readLine();
                String line = "";

                while ((line = fileReader.readLine()) != null) {
                    String[] tokens = line.split(COMMA_DELIMITER);
                    aliments.add(new Aliment(String.valueOf(tokens[ALIMENT_NAME]), Double.parseDouble(tokens[ALIMENT_CALORIES]), Double.parseDouble(tokens[ALIMENT_FAT]), Double.parseDouble(tokens[ALIMENT_CARBS]), Double.parseDouble(tokens[ALIMENT_PROTEIN]), Double.parseDouble(tokens[ALIMENT_FIBER])));

                }
            } catch (Exception e) {
                System.out.println("Error reading aliments from CSV file");
                e.printStackTrace();
            } finally {
                try {
                    assert fileReader != null;
                    fileReader.close();
                } catch (IOException e) {
                    System.out.println("Error while trying to close FileReader");
                    e.printStackTrace();
                }
            }

        }
        // Aliments //
    }

最后,我有一个newalimentwindowcontroller类,它是new按钮打开的窗口:

package application;

    import application.domain.Aliment;
    import javafx.fxml.FXML;
    import javafx.scene.control.Button;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.Pane;

    public class newAlimentWindowController extends FoodTabController {

        @FXML
        protected Pane newAlimentPane;

        @FXML
        protected TextField newAlimentSetName, newAlimentSetCal, newAlimentSetFat, newAlimentSetCarbs, newAlimentSetProtein, newAlimentSetFiber;

        @FXML
        protected Button addButton;

        public void initialize() {
            loadAliments();
        }

        public void addAliment() {
            aliments.add(new Aliment(newAlimentSetName.getText(), Double.parseDouble(newAlimentSetCal.getText()), Double.parseDouble(newAlimentSetFat.getText()), Double.parseDouble(newAlimentSetCarbs.getText()), Double.parseDouble(newAlimentSetProtein.getText()), Double.parseDouble(newAlimentSetFiber.getText())));
            saveAliments();
            updateTableView();
        }
    }

此外,食物对象:

package application.domain;

    import java.util.Objects;

    public class Aliment {

        private String name;
        private double weight;
        private double calories, fat, carbohydrate, protein, fiber;

        public Aliment(String name, double weight, double calories, double fat, double carbohydrate, double protein, double fiber) {
           this(name, calories, fat, carbohydrate, protein, fiber);
           this.weight = weight;
        }

        public Aliment(String name, double calories, double fat, double carbohydrate, double protein, double fiber) {
            this.name = name;
            this.weight = 100;
            this.calories = calories;
            this.fat = fat;
            this.carbohydrate = carbohydrate;
            this.protein = protein;
            this.fiber = fiber;
        }

一切正常,除了在新窗口中键入textfields并按下add按钮之后,addaliment方法中的updatetableview方法不会触发(aliment项添加正确,可观察列表不会在按下add按钮时刷新)。但是,如果我从链接到refresh按钮的foodtontroller类内部触发updatetableview方法,它就可以工作。
我不明白发生了什么:我可以从newalimentwindowcontroller与foodtontroller中的aliments observatable列表交互,因为aliments.add可以工作,同时savealiments方法也可以工作,但是updatetableview方法,也就是savealiments和aliments.add的方法,不工作。我很困惑。
我觉得我缺少了一些关于java编程的基本知识,因此我想了解正在发生的事情。任何帮助都将不胜感激,非常感谢!

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题