gpt4 book ai didi

java - 让 LocalDate 显示在 Javafx 的 Tableview 中

转载 作者:行者123 更新时间:2023-11-30 10:15:59 24 4
gpt4 key购买 nike

我一直在开发我的应用程序的一部分,它允许用户输入他们学校放假的假期并将其保存到文件中。假期的名称和日期(存储为 LocalDate 对象)从文件中读取并存储在假期对象中,然后放入可观察的数组列表中。

这是主 Controller :

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<Job> 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<Holiday> tableView;

private HolidayData data;

public void initialize() throws IOException {
data = new HolidayData();
data.loadHolidays();
tableView.setItems(data.getHolidays());

}

这是假期类(class):

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<LocalDate> 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<LocalDate> dateProperty() {
return date;
}

这是 HolidayData 类,负责从文件读取数据和从文件读取数据并生成可观察的数组列表:

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<Holiday> holidays;

public HolidayData(){
formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
}

public static HolidayData getInstance() {
return instance;
}

public static String getFileName() {
return fileName;
}

public ObservableList<Holiday> 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<Holiday> 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 部分:

<TableView fx:id="tableView">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
</columnResizePolicy>
<columns>
<TableColumn text="Holiday Name">
<cellFactory>
<PropertyValueFactory property="name"/>
</cellFactory>
</TableColumn>
<TableColumn text="Date">
<cellFactory>
<PropertyValueFactory property="date" />
</cellFactory>
</TableColumn>
</columns>
</TableView>

我遇到的问题是 java.lang.ClassCastException 表示无法将表列转换为某个对象,我认为是 LocalDate 对象。我正在使用 SimpleObjectProperty 将它数据绑定(bind)到 FXML 文件,但我似乎无法让它工作。我唯一能想到做的就是将 Holiday 中的日期设为 SimpleStringProperty 并将其转换为所有其他部分中的 LocalDate在我的代码中,但这似乎是不必要的。我很感激任何人能给我的任何见解。

最佳答案

TL;DR 版本:你混淆了 cellValueFactorycellFactory .参见,例如,this tutorial为了很好地解释差异,下面针对这个特定示例进行了总结。

表列的 cellValueFactory是一个对象,它告诉列 哪些 值要显示在单元格中,或者更准确地说,如何从表示每一行的对象中获取这些值。这由 Callback<CellDataFeatures<Holiday, LocalDate>, ObservableProperty<LocalDate>> 表示,即映射 CellDataFeatures<Holiday, LocalDate> 的函数到 ObservableValue<LocalDate> .所以在 Java 代码中你会这样做

dateColumn.setCellValueFactory(holidayRowData -> holidayRowData.getValue().dateProperty());

或者,如果您更喜欢使用(有点传统)PropertyValueFactory类,你可以做

dateColumn.setCellValueFactory(new PropertyValueFactory<>("date"));

后一个版本具有(许多缺点,但只有一个)优点,即它也可以在 FXML 中完成。不过请注意,您需要 cellValueFactory , 而不是 cellFactory .所以你的 FXML 应该是

<TableView fx:id="tableView">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
</columnResizePolicy>
<columns>
<TableColumn text="Holiday Name">
<cellValueFactory>
<PropertyValueFactory property="name"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Date">
<cellValueFactory>
<PropertyValueFactory property="date" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>

cellFactory相比之下,是一个对象,它告诉列如何 显示数据。它由 Callback<TableColumn<Holiday, LocalDate>, TableCell<Holiday, LocalDate>> 表示,即映射 TableColumn<Holiday, LocalDate> 的函数到 TableCell<Holiday, LocalDate> . ClassCastException发生是因为您设置的电池工厂将被传递 TableColumn , 但期望收到 CellDataFeatures ,所以当它试图这样对待它时,转换失败。

除了单元格值工厂之外,您可能还需要一个单元格工厂,以便您可以控制日期的显示方式(例如控制用于它的格式)。如果您给日期列一个 fx:id ,说 <TableColumn fx:id="dateColumn"> , 并将其注入(inject)到 Controller 中

@FXML
private TableColumn<Holiday, LocalDate> dateColumn ;

然后在 Controller 的初始化方法中,你可以这样做:

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<Holiday, LocalDate>() {
@Override
protected void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
if (empty) {
setText("");
} else {
setText(formatter.format(date));
}
}
});
}

关于java - 让 LocalDate 显示在 Javafx 的 Tableview 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50224091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com