【问题标题】:TableView individual cell listener JavaFXTableView 单个单元格侦听器 JavaFX
【发布时间】:2015-02-01 19:29:31
【问题描述】:

所以我正在开发一个“待办事项列表”应用程序,其中有一个包含要执行的任务的 TableView,并且在我的 TableView 中有一个“截止日期”列。我希望如果一项任务的截止日期已经过去,它会使特定的截止日期变成红色。

因此,如果用户在 2015 年 1 月 1 日打开应用,并且他的任务截止日期是 2014 年 12 月 31 日,则其对应的截止日期单元格的文本将显示为红色。

该表显然与具有 ObjectProperty“deadline”字段的“Task”对象的 ObservableList 相关联。

我该怎么做呢?

【问题讨论】:

    标签: java javafx listener tableview


    【解决方案1】:

    定义一个CSS PseudoClass 来表示一个过期项目。使用根据截止日期是否已过来设置伪类状态的单元工厂。您没有发布任何代码,但以下内容应该有所帮助:

    TableColumn<Task, LocalDate> deadlineColumn = new TableColumn<>("Deadline");
    deadlineColumn.setCellValueFactory( cellData -> cellData.getValue().deadlineProperty() ); // or similar...
    PseudoClass overdue = PseudoClass.getPseudoClass("overdue");
    deadlineColumn.setCellFactory(col -> new TableCell<Task, LocalDate>() {
        @Override
        public void updateItem(LocalDate deadline, boolean empty) {
            super.updateItem(deadline, empty) ;
            if (empty) {
                pseudoClassStateChanged(overdue, false);
                setText(null);
            } else {
                pseudoClassStateChanged(overdue, LocalDate.now().isAfter(deadline));
                setText(deadline.toString());
            }
        }
    });
    

    然后在一个外部的 css 文件中你可以这样做

    .table-cell:overdue {
        -fx-text-fill: red ;
    } 
    

    更新:这是一个完整的示例,上面显示的 CSS 在名为 overdue.css 的文件中:

    import java.time.LocalDate;
    import java.util.function.Function;
    
    import javafx.application.Application;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.beans.value.ObservableValue;
    import javafx.css.PseudoClass;
    import javafx.scene.Scene;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.layout.BorderPane;
    import javafx.stage.Stage;
    
    public class ToDoTable extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            TableView<ToDoItem> table = new TableView<>();
            table.getColumns().add(createColumn("Name", ToDoItem::nameProperty));
            TableColumn<ToDoItem, LocalDate> deadlineCol = createColumn("Deadline", ToDoItem::deadlineProperty);
            PseudoClass overdue = PseudoClass.getPseudoClass("overdue");
            deadlineCol.setCellFactory(col -> new TableCell<ToDoItem, LocalDate>() {
                @Override
                public void updateItem(LocalDate deadline, boolean empty) {
                    super.updateItem(deadline, empty);
                    if (empty) {
                        pseudoClassStateChanged(overdue, false);
                        setText(null);
                    } else {
                        pseudoClassStateChanged(overdue, LocalDate.now().isAfter(deadline));
                        setText(deadline.toString());
                    }
                }
            });
            table.getColumns().add(deadlineCol);
    
            for (int i=1; i <= 10; i++) {
                LocalDate deadline = LocalDate.now().plusDays(i - 5);
                ToDoItem item = new ToDoItem("Item "+i, deadline);
                table.getItems().add(item);
            }
    
            BorderPane root = new BorderPane(table);
            Scene scene = new Scene(root, 800, 600);
            scene.getStylesheets().add("overdue.css");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        private static <S,T> TableColumn<S,T> createColumn(String title, Function<S, ObservableValue<T>> property) {
            TableColumn<S,T> col = new TableColumn<>(title);
            col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
            return col ;
        }
    
    
        public static class ToDoItem {
            private final StringProperty name = new SimpleStringProperty();
            private final ObjectProperty<LocalDate> deadline = new SimpleObjectProperty<>();
    
            public ToDoItem(String name, LocalDate deadline) {
                this.name.set(name);
                this.deadline.set(deadline);
            }
    
            public final StringProperty nameProperty() {
                return this.name;
            }
    
            public final java.lang.String getName() {
                return this.nameProperty().get();
            }
    
            public final void setName(final java.lang.String name) {
                this.nameProperty().set(name);
            }
    
            public final ObjectProperty<LocalDate> deadlineProperty() {
                return this.deadline;
            }
    
            public final java.time.LocalDate getDeadline() {
                return this.deadlineProperty().get();
            }
    
            public final void setDeadline(final java.time.LocalDate deadline) {
                this.deadlineProperty().set(deadline);
            }
    
    
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

    • 我把它放进去,但用DeadlineColumn.setCellValueFactory(new PropertyValueFactory("deadline"));而不是deadlineColumn.setCellValueFactory( cellData -&gt; cellData.getValue().deadlineProperty() );,但它不起作用。它正在输入 else 语句,但它没有改变颜色。我在根目录中放了一个带有您提到的代码的“overdue.css”文件,如果找不到它会抛出非法ArgumentException 对吗?
    • 你是如何附加 CSS 的?到现场?还是给另一个家长?
    • 此外,您可以删除 css 文件,只是为了使用 if (LocalDate.now().isAfter(deadline)) { setStyle("-fx-text-fill: red;");} else { setStyle("");} 进行测试(而不是调用 psuedoClassStateChanged(...);)将其移至外部 CSS 文件更为可取。
    • 添加了一个完整的例子。
    • 非常感谢这个真正帮助我更好地理解它的例子。唯一不起作用的是scene.getStylesheets().add("overdue.css"); 给了我WARNING: com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged,通过用scene.getStylesheets().add(getClass().getResource("overdue.css").toExternalForm()); 替换它来修复它,但这可能是一个菜鸟解决方法。再次感谢!
    猜你喜欢
    • 2014-02-22
    • 2019-03-19
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 2014-07-22
    • 1970-01-01
    相关资源
    最近更新 更多