无法弄清楚如何使用ComboBox将枚举列表添加到表中。现在,该代码无法编译,它在StringConverter的grade.toString()中失败。以下是我正在使用的基本示例。最终,我希望能够做三件事:
显示具有所有可用枚举的组合框
[如果当前存在,则用当前等级预先填充。
能够更改所选内容并使用新选择内容更新学生的对象。
任何人都可以帮忙吗?
public class App extends Application {
@Override
public void start(Stage stage) throws Exception {
try {
StackPane root = new StackPane();
TableView<Student> tbl = new TableView<>();
TableColumn<Student, Grade> col = new TableColumn<>("Grade");
ObservableList<Grade> grades = FXCollections.observableArrayList(Grade.values());
col.setCellFactory(ComboBoxTableCell.forTableColumn(new StringConverter<Grade>() {
@Override
public String toString(Grade grade) {
return grade.toString();
}
@Override
public Grade fromString(String s) {
return Grade.valueOf(s);
}
}, grades));
tbl.getColumns().add(col);
Student a = new Student();
a.grade = Grade.A;
a.name = "Mark";
tbl.setItems(FXCollections.observableArrayList(a));
root.getChildren().add(tbl);
Scene scene = new Scene(root, 800, 600);
stage.setScene(scene);
stage.show();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
枚举
public enum Grade {
A (5),
B (4),
C (3),
D (2),
F (1);
int gradePoints;
Grade(int gradePoints) {
this.gradePoints = gradePoints;
}
public int getGradePoints() {
return gradePoints;
}
}
和学生班:
public class Student {
String name; // name has the default value null
int age; // age has the default value 0
boolean isScienceMajor; // isScienceMajor has default value false
char gender; // gender has default value '\u0000'
Grade grade;
}
您没有告诉系统如何找出单元格的值。
您需要在列上设置单元格值工厂。最简单的方法是让Student类使用并公开JavaFX属性,然后使用将单元格值工厂设置为propertyValueFactory来命名与给定列关联的属性。
如果要使表或特定的列可编辑,则需要指定它(并在定义项类型的类中公开适当的setter或属性方法)。
[开始编辑单元格,用户需要双击该单元格以将其从显示模式转换为编辑模式(然后将显示组合框,但没有下拉菜单)。然后单击组合框以将其下拉,然后从下拉菜单中选择适当的等级,之后将保存该值并将单元格切换回读取模式。系统将知道。从属性值定义中,调用适当的设置器将新选择的成绩保存回基础项目的成绩属性。
App.java
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
StackPane root = new StackPane();
TableView<Student> tbl = new TableView<>();
tbl.setEditable(true);
TableColumn<Student, String> nameCol = new TableColumn<>("Name");
nameCol.setEditable(false);
nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<Student, Grade> gradeCol = new TableColumn<>("Grade");
gradeCol.setEditable(true);
ObservableList<Grade> grades = FXCollections.observableArrayList(Grade.values());
gradeCol.setCellFactory(
ComboBoxTableCell.forTableColumn(
new StringConverter<>() {
@Override
public String toString(Grade grade) {
return grade != null ? grade.toString() : null;
}
@Override
public Grade fromString(String s) {
return s != null ? Grade.valueOf(s) : null;
}
},
grades
)
);
gradeCol.setCellValueFactory(new PropertyValueFactory<>("grade"));
tbl.getColumns().addAll(nameCol, gradeCol);
Student aStudent = new Student(
"Mark", Grade.A
);
tbl.setItems(FXCollections.observableArrayList(aStudent));
root.getChildren().add(tbl);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
Student.java
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleObjectProperty;
public class Student {
private ReadOnlyStringWrapper name;
private ObjectProperty<Grade> grade;
public Student(String name, Grade grade) {
this.name = new ReadOnlyStringWrapper(name);
this.grade = new SimpleObjectProperty<>(grade);
}
public String getName() {
return name.get();
}
public ReadOnlyStringProperty nameProperty() {
return name.getReadOnlyProperty();
}
public Grade getGrade() {
return grade.get();
}
public ObjectProperty<Grade> gradeProperty() {
return grade;
}
public void setGrade(Grade grade) {
this.grade.set(grade);
}
}
等级等级与您问题中的定义保持一致。