简体   繁体   English

根据内容更改TableRow颜色

[英]Change TableRow color based on content

I want to make a table that changes row color based on row's content. 我想制作一个根据行的内容更改行颜色的表。 Therefore I use the following code. 因此,我使用以下代码。 I did this by myself and that seems to be the cause of the problem ;) because the part where the row background is set seems not to work as intended: 我自己完成了此操作,这似乎是问题的原因;)因为设置row背景的那一部分似乎无法按预期工作:

Not the row with the GOODFRIENDS changes it's color but the one above. 带有GOODFRIENDSrow不会更改其颜色,而是上面的行。 As you see I placed a System.out.println(row.getItem()); 如您所见,我放置了System.out.println(row.getItem()); before the color is set to be sure that the row is the right 'row'. 在设置颜色之前,请确保该row是正确的“行”。 - And it is. -是的。 So at that point I have no idea why always the wrong row is colored while the row reference at runtime is another (the right one). 所以到那时我还不知道为什么总是在错误的row上涂上颜色,而在运行时row引用是另一行(正确的row )。

Any ideas? 有任何想法吗?

personTable.setRowFactory(new Callback<TableView<Person>, TableRow<Person>>() {

        Person person;
        int counter = 0;

        @Override
        public TableRow<Person> call(TableView<Person> tableView) {
            TableRow<Person> row = new TableRow<>();

            if (counter < tableView.getItems().size() && (person = tableView.getItems().get(counter)) != null) {
                row.setItem(person);
                counter++;
            }

            if (row.getItem() != null && row.getItem().getState() == State.GOODFRIEND) {
                System.out.println(row.getItem());
                row.setStyle("-fx-background-color: green;");
                //OR
                row.setBackground(new Background(
                        new BackgroundFill(Color.LIGHTGREEN, CornerRadii.EMPTY, new Insets(3, 0, 3, 0))));
            }

            row.setOnMouseClicked....

        return row;
    }

UPDATE: James_D solution works fine for coloring the rows, but the sedOnMouseClicked event doesn't work, because they are based on now empty row objects. 更新: James_D解决方案可以很好地为行着色,但是sedOnMouseClicked事件不起作用,因为它们基于现在为空的行对象。

    row.setOnMouseClicked(mouseEvent -> {
            if (!row.isEmpty()) {
                defriend_Button.setDisable(false);
                if (row.getItem().getState() == State.FRIEND) {
                    goodFriend_Button.setDisable(false);
                } else {
                    goodFriend_Button.setDisable(true);
                }
            } else if (row.isEmpty()) {
                personTable.getSelectionModel().select(null);
                defriend_Button.setDisable(true);
                goodfriend_Button.setDisable(true);
            }

            if (mouseEvent.getClickCount() == 2 && (!row.isEmpty())) {
                controller.showFriendDescriptionView(row.getItem());
            }
        });

You seem to be assuming that a single table row will be created for each item in the table, and in the order that the items exist. 您似乎假设将为表中的每个项目创建一个表格行,并以项目存在的顺序进行创建。 There is no such guarantee, and in fact in most cases this won't happen. 没有这样的保证,实际上在大多数情况下这是不会发生的。 TableRow s are essentially created for each visible row (whether or not they contain an item), and are reused to display different items as the user scrolls or the items displayed change for other reasons. TableRow本质上是为每个可见行创建的(无论它们是否包含一个项目),当用户滚动或显示的项目由于其他原因而改变时, TableRow可以重用于显示不同的项目。

So you need to override the updateItem(...) method and perform the logic there. 因此,您需要重写updateItem(...)方法并在那里执行逻辑。

personTable.setRowFactory(tv -> {
    TableRow<Person> row = new TableRow<Person>() {
        @Override
        public void updateItem(Person person, boolean empty) {
            super.updateItem(person, empty);
            if (person != null && person.getState() == State.GOODFRIEND) {
                setStyle("-fx-background-color: green;");
            } else {
                setStyle("");
            }
        }
    };
    row.setOnMouseClicked(...);
    return row ;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM