如何有条件地格式化 JavaFX ComboBoxTableCell 标签
How to conditionally format JavaFX ComboBoxTableCell label
我认为可以根据以下 JavaFX 11 文档项目有条件地格式化 JavaFX ComboBoxTableCell
标签:
- ComboBoxTableCell class 描述:
By default, the ComboBoxTableCell
is rendered as a Label
when not being edited [...].
- Labeledclass
setTextFill
方法说明:
Sets the value of the property textFill
.
如果我的假设是正确的,我想知道如何修改以下 SSCCE,以便将任何 ComboBoxTableCell
标签 textFill
属性 设置为以下 Paint
值.谢谢!
Color.Red
如果其值无效
Color.Blue
如果它的值是为不同的行设置的。
public class PersonInRoom extends Application
{
private final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("Jacob" , "Kitchen"),
new Person("Isabella", "Bedroom"),
new Person("Ethan" , "Attic"));
TableView<Person> table ;
public static void main(String[] args) {launch(args);}
@Override
public void start(Stage stage)
{
TableColumn nameCol = new TableColumn("Name");
nameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
TableColumn roomCol = new TableColumn("Room");
roomCol.setCellValueFactory(new PropertyValueFactory<Person, String>("room"));
roomCol.setCellFactory(ComboBoxTableCell.forTableColumn("Bathroom", "Bedroom", "Kitchen"));
roomCol.setOnEditCommit((EventHandler<CellEditEvent<Person, String>>) t -> t.getTableView().getItems().get(t.getTablePosition().getRow()).setRoom(t.getNewValue()));
table = new TableView<>();
table.setEditable(true);
table.setItems(data);
table.getColumns().addAll(nameCol, roomCol);
VBox vbox = new VBox();
vbox.getChildren().addAll(table);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person
{
private final SimpleStringProperty name;
private final SimpleStringProperty room;
private Person(String name, String room)
{
this.name = new SimpleStringProperty(name);
this.room = new SimpleStringProperty(room);
}
public String getName() {return name.get();}
public String getRoom() {return room.get();}
public void setRoom(String r) {room.set(r);}
}
}
根据 kleopatra 在 2020-09-28 中的建议 03:30:59Z 评论此问题顶部提出的问题页数:
You need a custom cell and override updateItem to set the color
depending on context.
...我创建了一个自定义单元格(准确地说是 ComboBoxTableCell
)并覆盖了它的 updateItem
方法。
随意 re-use 它(见下面的源代码)但请注意 kleopatra 在 2020 上针对此答案发表的评论-09-2803:30:59Z:
You are probably aware that the logic itself doesn't belong into the
view (aka: cell) - it should be handled "near" the model, including a
notification path (vs. hacking around by calling refresh).
public class PersonInRoom extends Application
{
private final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("Jacob", "Kitchen"),
new Person("Isabella", "Bedroom"),
new Person("Ethan", "Attic"));
TableView<Person> table;
public static void main(String[] args) {launch(args);}
@Override
public void start(Stage stage)
{
TableColumn nameCol = new TableColumn("Name");
nameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
TableColumn roomCol = new TableColumn("Room");
roomCol.setCellValueFactory(new PropertyValueFactory<Person, String>("room"));
roomCol.setCellFactory(new Callback<TableColumn<Person, String>, ComboBoxTableCell<Person, String>>()
{
@Override
public ComboBoxTableCell<Person, String> call(TableColumn<Person, String> personStringTableColumn)
{
String rooms[] = {"Bathroom", "Bedroom", "Kitchen"};
return new ComboBoxTableCell<>(rooms)
{
@Override
public void updateItem(String item, boolean empty)
{
super.updateItem(item, empty);
if (!empty) {
setText(item);
boolean found = false;
for (int i = 0; i < rooms.length; i++) {
if (rooms[i].equals(item)) {
found = true;
break;
}
}
if (!found) {
setTextFill(Color.RED);
return;
}
int count = 0;
for (int i = 0; i < data.size(); i++) {
if (data.get(i).getRoom().equals(item)) {
if (++count > 1) {
setTextFill(Color.BLUE);
return;
}
}
}
setTextFill(Color.BLACK);
}
}
};
}
});
roomCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>()
{
@Override
public void handle(CellEditEvent<Person, String> cellEditEvent)
{
cellEditEvent.getTableView().getItems().get(cellEditEvent.getTablePosition().getRow()).setRoom(cellEditEvent.getNewValue());
table.refresh();
}
});
table = new TableView<>();
table.setEditable(true);
table.setItems(data);
table.getColumns().addAll(nameCol, roomCol);
VBox vbox = new VBox();
vbox.getChildren().addAll(table);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person
{
private final SimpleStringProperty name;
private final SimpleStringProperty room;
private Person(String name, String room)
{
this.name = new SimpleStringProperty(name);
this.room = new SimpleStringProperty(room);
}
public String getName() {return name.get();}
public String getRoom() {return room.get();}
public void setRoom(String r) {room.set(r);}
}
}
我认为可以根据以下 JavaFX 11 文档项目有条件地格式化 JavaFX ComboBoxTableCell
标签:
- ComboBoxTableCell class 描述:
By default, the
ComboBoxTableCell
is rendered as aLabel
when not being edited [...].
- Labeledclass
setTextFill
方法说明:
Sets the value of the property
textFill
.
如果我的假设是正确的,我想知道如何修改以下 SSCCE,以便将任何 ComboBoxTableCell
标签 textFill
属性 设置为以下 Paint
值.谢谢!
Color.Red
如果其值无效
Color.Blue
如果它的值是为不同的行设置的。
public class PersonInRoom extends Application
{
private final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("Jacob" , "Kitchen"),
new Person("Isabella", "Bedroom"),
new Person("Ethan" , "Attic"));
TableView<Person> table ;
public static void main(String[] args) {launch(args);}
@Override
public void start(Stage stage)
{
TableColumn nameCol = new TableColumn("Name");
nameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
TableColumn roomCol = new TableColumn("Room");
roomCol.setCellValueFactory(new PropertyValueFactory<Person, String>("room"));
roomCol.setCellFactory(ComboBoxTableCell.forTableColumn("Bathroom", "Bedroom", "Kitchen"));
roomCol.setOnEditCommit((EventHandler<CellEditEvent<Person, String>>) t -> t.getTableView().getItems().get(t.getTablePosition().getRow()).setRoom(t.getNewValue()));
table = new TableView<>();
table.setEditable(true);
table.setItems(data);
table.getColumns().addAll(nameCol, roomCol);
VBox vbox = new VBox();
vbox.getChildren().addAll(table);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person
{
private final SimpleStringProperty name;
private final SimpleStringProperty room;
private Person(String name, String room)
{
this.name = new SimpleStringProperty(name);
this.room = new SimpleStringProperty(room);
}
public String getName() {return name.get();}
public String getRoom() {return room.get();}
public void setRoom(String r) {room.set(r);}
}
}
根据 kleopatra 在 2020-09-28 中的建议 03:30:59Z 评论此问题顶部提出的问题页数:
You need a custom cell and override updateItem to set the color depending on context.
...我创建了一个自定义单元格(准确地说是 ComboBoxTableCell
)并覆盖了它的 updateItem
方法。
随意 re-use 它(见下面的源代码)但请注意 kleopatra 在 2020 上针对此答案发表的评论-09-2803:30:59Z:
You are probably aware that the logic itself doesn't belong into the view (aka: cell) - it should be handled "near" the model, including a notification path (vs. hacking around by calling refresh).
public class PersonInRoom extends Application
{
private final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("Jacob", "Kitchen"),
new Person("Isabella", "Bedroom"),
new Person("Ethan", "Attic"));
TableView<Person> table;
public static void main(String[] args) {launch(args);}
@Override
public void start(Stage stage)
{
TableColumn nameCol = new TableColumn("Name");
nameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
TableColumn roomCol = new TableColumn("Room");
roomCol.setCellValueFactory(new PropertyValueFactory<Person, String>("room"));
roomCol.setCellFactory(new Callback<TableColumn<Person, String>, ComboBoxTableCell<Person, String>>()
{
@Override
public ComboBoxTableCell<Person, String> call(TableColumn<Person, String> personStringTableColumn)
{
String rooms[] = {"Bathroom", "Bedroom", "Kitchen"};
return new ComboBoxTableCell<>(rooms)
{
@Override
public void updateItem(String item, boolean empty)
{
super.updateItem(item, empty);
if (!empty) {
setText(item);
boolean found = false;
for (int i = 0; i < rooms.length; i++) {
if (rooms[i].equals(item)) {
found = true;
break;
}
}
if (!found) {
setTextFill(Color.RED);
return;
}
int count = 0;
for (int i = 0; i < data.size(); i++) {
if (data.get(i).getRoom().equals(item)) {
if (++count > 1) {
setTextFill(Color.BLUE);
return;
}
}
}
setTextFill(Color.BLACK);
}
}
};
}
});
roomCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>()
{
@Override
public void handle(CellEditEvent<Person, String> cellEditEvent)
{
cellEditEvent.getTableView().getItems().get(cellEditEvent.getTablePosition().getRow()).setRoom(cellEditEvent.getNewValue());
table.refresh();
}
});
table = new TableView<>();
table.setEditable(true);
table.setItems(data);
table.getColumns().addAll(nameCol, roomCol);
VBox vbox = new VBox();
vbox.getChildren().addAll(table);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person
{
private final SimpleStringProperty name;
private final SimpleStringProperty room;
private Person(String name, String room)
{
this.name = new SimpleStringProperty(name);
this.room = new SimpleStringProperty(room);
}
public String getName() {return name.get();}
public String getRoom() {return room.get();}
public void setRoom(String r) {room.set(r);}
}
}