作者:En199010221 | 来源:互联网 | 2023-09-01 18:01
我一直在处理我的应用程序的一部分,该应用程序允许用户输入他们学校起飞的假期并将其保存到文件中.从文件中读取假日的名称和日期(存储为LocalDate对象)并存储在假日对象中并放入可观察的arra
我一直在处理我的应用程序的一部分,该应用程序允许用户输入他们学校起飞的假期并将其保存到文件中.从文件中读取假日的名称和日期(存储为LocalDate对象)并存储在假日对象中并放入可观察的arraylist中.
这是主控制器:
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Optional;
public class Controller {
@FXML
private BorderPane mainGridPane;
private ArrayList jobs = new ArrayList<>();
private static XSSFRow row;
private boolean fileClosed = false;
@FXML
private DatePicker employeeStartDate;
@FXML
private Label evaluation40;
@FXML
private Label evaluation80;
@FXML
private Label evaluation120;
@FXML
private DatePicker summerStart;
@FXML
private DatePicker summerEnd;
@FXML
private DatePicker fallStart;
@FXML
private DatePicker fallEnd;
@FXML
private TableView tableView;
private HolidayData data;
public void initialize() throws IOException {
data = new HolidayData();
data.loadHolidays();
tableView.setItems(data.getHolidays());
}
这是假期课程:
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import java.time.LocalDate;
public class Holiday {
private SimpleStringProperty name = new SimpleStringProperty();
private ObjectProperty date;
public Holiday(String name, LocalDate date) {
this.name.set(name);
this.date = new SimpleObjectProperty<>(date);
}
public String getName() {
return name.get();
}
public SimpleStringProperty nameProperty() {
return name;
}
public LocalDate getDate() {
return date.get();
}
public ObjectProperty dateProperty() {
return date;
}
这是HolidayData类,负责从文件和生成以及可观察的arraylist读取数据:
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
public class HolidayData {
private static HolidayData instance = new HolidayData();
private static String fileName = "schoolHolidays.txt";
private DateTimeFormatter formatter;
private ObservableList holidays;
public HolidayData(){
formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
}
public static HolidayData getInstance() {
return instance;
}
public static String getFileName() {
return fileName;
}
public ObservableList getHolidays(){
return holidays;
}
public void addHoliday(Holiday holiday){
holidays.add(holiday);
}
public void loadHolidays() throws IOException {
holidays = FXCollections.observableArrayList();
Path path = Paths.get(fileName);
BufferedReader br = Files.newBufferedReader(path);
String input;
try{
while((input = br.readLine()) != null){String[] holidayPieces = input.split("\t");String name = holidayPieces[0];String dateString = holidayPieces[1];LocalDate date = LocalDate.parse(dateString, formatter);Holiday holiday = new Holiday(name, date);holidays.add(holiday);
}
}catch(IOException e) {
e.printStackTrace();
} finally{
if(br != null){br.close();
}
}
}
public void storeHolidays()throws IOException{
Path path = Paths.get(fileName);
BufferedWriter bw = Files.newBufferedWriter(path);
try {
Iterator iter = holidays.iterator();
while(iter.hasNext()){Holiday holiday = iter.next();bw.write(String.format("%s\t%s", holiday.getName(), holiday.getDate().format(formatter)));bw.newLine();
}
}finally {
if (bw != null){bw.close();
}
}
}
public void deleteHoliday(Holiday holiday){
holidays.remove(holiday);
}
}
这是FXML文件的tableView部分:
我遇到的问题是java.lang.ClassCastException,表示无法将表列强制转换为某个对象,我认为该对象是LocalDate对象.我使用SimpleObjectProperty将它数据绑定到FXML文件,但我似乎无法让它工作.我能想到的另一件事就是在Holiday中将日期设为SimpleStringProperty并将其转换为我代码中所有其他部分的LocalDate,但这似乎是不必要的.我很感激任何人都能给我的见解.
解决方法:
TL; DR版:您将cellValueFactory与cellFactory混淆.例如,参见this tutorial,以获得对差异的一个很好的解释,这对于下面这个特定的例子进行了总结.
表列的cellValueFactory是一个对象,它告诉列要在单元格中显示哪些值,或者更准确地说是如何从表示每行的对象中获取这些值.这由Callback,ObservableProperty>表示,即映射CellDataFeatures的功能.到ObservableValue.所以在Java代码中你会这样做
dateColumn.setCellValueFactory(holidayRowData -> holidayRowData.getValue().dateProperty());
或者,如果您更喜欢使用(有些遗留的)PropertyValueFactory类,您可以这样做
dateColumn.setCellValueFactory(new PropertyValueFactory<>("date"));
后一版本具有(许多缺点,但一个)优点,它也可以在FXML中完成.但请注意,您需要cellValueFactory,而不是cellFactory.所以你的FXML应该是
相反,cellFactory是一个告诉列如何显示数据的对象.它由Callback,TableCell>表示,即映射TableColumn的功能.到TableCell.发生ClassCastException是因为您设置的单元格工厂将要传递TableColumn,但是期望接收CellDataFeatures,因此当它尝试对其进行处理时,转换将失败.
除了单元格值工厂之外,您可能还需要一个单元工厂,以便您可以控制日期的显示方式(例如,控制用于它的格式).如果您为日期列指定一个fx:id,请说,然后将其注入控制器
@FXML
private TableColumn dateColumn ;
然后在控制器的initialize方法中,你可以这样做:
public void initialize() throws IOException {
data = new HolidayData();
data.loadHolidays();
tableView.setItems(data.getHolidays());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
dateColumn.setCellFactory(column -> new TableCell() {
@Override
protected void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
if (empty) {setText("");
} else {setText(formatter.format(date));
}
}
});
}