首先我想说的是,我已经检查了这个问题的各种类似的解决方案,但是发布这个问题的其他用户的代码设计与我的非常不同,我不知道如何使用发布的解决方案来解决相同的问题。
也就是说,我正在使用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编程的基本知识,因此我想了解正在发生的事情。任何帮助都将不胜感激,非常感谢!
暂无答案!
目前还没有任何答案,快来回答吧!