私の目標は、クラスのインスタンスのすべてのフィールドをtableViewに表示することです。クラスには、String型のフィールドを持つenum型のフィールドがあります。 列挙型は、文字列フィールド名としてComboBoxに表示されます。 もちろん編集可能でなければなりません。JavaFX表示列挙型の文字列(コンボボックスの文字列)(表形式)
今のところうまくいきません: EnumクラスのStringフィールドは、ComboBoxがクリックされた場合にのみ表示され、それ以外の場合は列挙定数の名前です。また、コンボボックスの別の列挙型が選択されている場合、編集のためにコミットすることはできません。 returnをクリックしても、commitEditのどちらのメソッドも呼び出されず、Comboboxの選択も解除されません。編集のために他の列が選択された場合、試行された編集は取り消されます。
私はこれを理解しようと努力しましたので、私はここで私を助けてくれるかもしれないと考えました。 元のタスクはエンタープライズソフトウェアのより大きなクラスであるため、私はこの質問をするために抽象化しました。
String型の列挙型を保持する列を作成し、MyEnum.values()およびMyEnum.valueOf()で機能させることができますが、元のクラスもパフォーマンスが悪いため、大きい。
ここで私のコードを例に挙げます。問題を理解できない場合は、コンボボックスを一度使用してみてください。
テーブルビューのタイプであるクラス:
public class MyClass {
private MyEnum myEnum;
private String string;
public MyClass(MyEnum myEnum, String string) {
this.myEnum = myEnum;
this.string = string;
}
public MyEnum getMyEnum() {
return myEnum;
}
public void setMyEnum(MyEnum myEnum) {
this.myEnum = myEnum;
}
public String getString() {
return string;
}
}
それは列挙型のフィールドです:
public enum MyEnum {
EnumOne("First Enum"),
EnumTwo("Second Enum");
private String name;
public String getName() {
return name;
}
private MyEnum(String name) {
this.name = name;
}
}
FXアプリケーション:
public class NewFXMain extends Application {
@Override
public void start(Stage primaryStage) {
ObservableList<MyClass> items = FXCollections.observableArrayList();
items.add(new MyClass(MyEnum.EnumOne, "String"));
TableView<MyClass> table = new TableView(items);
table.setEditable(true);
TableColumn<MyClass, MyEnum> myEnumColumn = new TableColumn();
TableColumn<MyClass, String> stringColumn = new TableColumn();
stringColumn.setCellFactory(TextFieldTableCell.forTableColumn());
stringColumn.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().getString()));
myEnumColumn.setCellFactory((param) -> new MyEnumComboBoxCell());
myEnumColumn.setCellValueFactory(data -> new ReadOnlyObjectWrapper(data.getValue().getMyEnum()));
myEnumColumn.setOnEditCommit(
event -> {
event.getRowValue().setMyEnum(event.getNewValue());
System.out.println(event.getRowValue().getMyEnum());
});
table.getColumns().addAll(myEnumColumn, stringColumn);
StackPane root = new StackPane();
root.getChildren().add(table);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
class MyEnumComboBoxCell extends ComboBoxTableCell<MyClass, MyEnum> {
private ComboBox<MyEnum> box;
public MyEnumComboBoxCell() {
box = new ComboBox<>(FXCollections.observableArrayList(MyEnum.values()));
box.setCellFactory(new Callback<ListView<MyEnum>, ListCell<MyEnum>>() {
@Override
public ListCell<MyEnum> call(ListView<MyEnum> param) {
return new ListCell<MyEnum>() {
@Override
protected void updateItem(MyEnum item, boolean empty) {
super.updateItem(item, empty);
if (item != null) setText(item.getName());
}
};
}
});
}
@Override
public void startEdit() {
super.startEdit();
setGraphic(box);
}
@Override
public void commitEdit(MyEnum newValue) {
super.commitEdit(newValue);
if (newValue != null) {
setText(newValue.getName());
getTableView().getSelectionModel().getSelectedItem().setMyEnum(newValue);
box.setValue(newValue);
}
}
@Override
public void updateItem(MyEnum item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(null);
setText(item.getName());
}
}
}
私はあなたのソリューションを実装しようとしましたが、少し違っていてもまだ機能していません。実際に私の例を書き直してもうまくいきましたか? 私はそれ以前に自分自身を試みたので、おそらくそうではないと思いますか? –
私はあなたのコード内の別の問題を発見したので、私はうん、あなたはバッキングモデルの値を設定するには、このソリューションを使用することができます – Sunflame