【问题标题】:How to conditionally format JavaFX ComboBoxTableCell label如何有条件地格式化 JavaFX ComboBoxTableCell 标签
【发布时间】:2020-10-03 16:15:59
【问题描述】:

我认为可以根据以下 JavaFX 11 文档项有条件地格式化 JavaFX ComboBoxTableCell 标签

默认情况下,ComboBoxTableCell 在未被编辑时呈现为Label [...]。

  • LabeledsetTextFill方法说明:

设置属性textFill的值。

如果我的假设是正确的,我想知道如何修改以下 SSCCE,以便将任何 ComboBoxTableCell 标签 textFill 属性设置为以下 Paint 值。谢谢!

  1. Color.Red 如果其值无效

  1. 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);}
    }
}

【问题讨论】:

  • 您需要一个自定义单元格并覆盖 updateItem 以根据上下文设置颜色
  • @kleopatra,非常感谢您的评论。我已经在我自己的问题的答案中包含了根据您的指导更新的 SSCCE 代码 sn-p。

标签: javafx combobox format label


【解决方案1】:

正如 kleopatra2020-09-28 03:30:59Z 中对本页顶部提出的问题的评论:

您需要一个自定义单元格并覆盖 updateItem 来设置颜色 取决于上下文。

...我创建了一个自定义单元格(准确地说是ComboBoxTableCell)并覆盖了它的updateItem 方法。

随意重复使用它(参见下面的源代码),但请注意 kleopatra2020-09-28 03:30:59Z 对此答案发表的评论

你可能知道逻辑本身不属于 视图(又名:单元格) - 应该在模型“附近”处理,包括 通知路径(而不是通过调用刷新来破解)。

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);}
    }
}

【讨论】:

  • good starter :) 您可能知道逻辑本身不属于视图(又名:单元格) - 它应该在模型“附近”处理,包括通知路径(与通过调用刷新来破解)。
  • @kleopatra,非常感谢您的鼓励和补充评论。我在答案的正文中引用了您的评论,以确保我的代码 sn-p 的潜在用户能够很好地理解它。
猜你喜欢
  • 2021-09-26
  • 1970-01-01
  • 2016-07-27
  • 2021-11-05
  • 1970-01-01
  • 2019-07-28
  • 2018-11-18
  • 2012-03-09
  • 1970-01-01
相关资源
最近更新 更多