【问题标题】:JavaFX 2 refresh table cell to change styleJavaFX 2 刷新表格单元格以更改样式
【发布时间】:2012-09-24 07:49:14
【问题描述】:

我需要更改具有可变列数的 TableView 中任意单元格的样式。下面的代码显示了基本问题。

ExampleRow 类是来自电子表格的真实数据的代理,它的另一个功能是保存突出显示信息。因为我不知道会有多少列,所以我只保存一个应该突出显示的列列表(不支持列重新排列)。 ExampleTableCell 类只是设置单元格的文本并在需要时应用突出显示。

如果我在表格绘制之前设置了高亮显示 [cell (2,2)],那么当应用程序启动时,单元格会正确显示为红色文本。问题是单击按钮将单元格 (1,1) 设置为突出显示,但表格没有更改。如果我将应用程序窗口的大小调整为空,然后再次打开它,单元格 (1,1) 的突出显示将被正确绘制 - 大概是因为此过程强制完全重绘。

我想知道的是如何触发表格重新绘制新突出显示的单元格(或所有可见单元格),以便样式正确?

TIA

package example;

import java.util.HashSet;
import java.util.Set;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

public class CellHighlightExample extends Application {

    private final int columnCount = 4;
    private final int rowCount = 5;
    private TableView<ExampleRow> table = new TableView<>();

    @Override
    public void start(Stage stage) {
        BorderPane root = new BorderPane();
        Scene scene = new Scene(root);

        Callback<TableColumn.CellDataFeatures<ExampleRow, String>, ObservableValue<String>> cellValueFactory = new Callback<TableColumn.CellDataFeatures<ExampleRow, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ExampleRow, String> p) {
                int row = p.getValue().getRow();
                int col = p.getTableView().getColumns().indexOf(p.getTableColumn());
                return new SimpleObjectProperty<>("(" + row + ", " + col + ")");
            }
        };

        Callback<TableColumn<ExampleRow, String>, TableCell<ExampleRow, String>> cellFactory = new Callback<TableColumn<ExampleRow, String>, TableCell<ExampleRow, String>>() {
            @Override
            public TableCell<ExampleRow, String> call(TableColumn<ExampleRow, String> p) {
                return new ExampleTableCell<>();
            }
        };

        for (int i = 0, n = columnCount; i < n; i++) {
            TableColumn<ExampleRow, String> column = new TableColumn<>();
            column.setCellValueFactory(cellValueFactory);
            column.setCellFactory(cellFactory);
            table.getColumns().add(column);
        }

        ObservableList<ExampleRow> rows = FXCollections.observableArrayList();
        for (int i = 0, n = rowCount; i < n; i++) {
            ExampleRow row = new ExampleRow(i);
            //Force a cell to be highlighted to show that highlighting works.
            if (i == 2) { row.addHighlightedColumn(2); }
            rows.add(row);
        }
        table.setItems(rows);

        Button b = new Button("Click to Highlight");
        b.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                ExampleRow row = table.getItems().get(1);
                row.addHighlightedColumn(1);
                //How to trigger a redraw of the table or cell to reflect the new highlighting?
            }
        });

        root.setTop(b);
        root.setCenter(table);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private class ExampleTableCell<S extends ExampleRow, T extends String> extends TableCell<S, T> {

        @Override
        public void updateItem(T item, boolean empty) {
            super.updateItem(item, empty);

            if (item == null) {
                setText(null);
                setGraphic(null);
            } else {
                setText(item);
                int colIndex = getTableView().getColumns().indexOf(getTableColumn());
                ExampleRow row = getTableView().getItems().get(getIndex());
                if (row.isHighlighted(colIndex)) {
                    setTextFill(Color.RED);
                }
            }
        }
    }

    private class ExampleRow {

        private SimpleIntegerProperty row;
        private Set<Integer> highlightedColumns = new HashSet<>();

        public ExampleRow(int row) {
            this.row = new SimpleIntegerProperty(row);
        }

        public int getRow() { return row.get(); }
        public void setRow(int row) { this.row.set(row); }
        public SimpleIntegerProperty rowProperty() { return row; }

        public boolean isHighlighted(int col) {
            if (highlightedColumns.contains(col)) {
                return true;
            }
            return false;
        }

        public void addHighlightedColumn(int col) {
            highlightedColumns.add(col);
        }
    }
}

【问题讨论】:

    标签: javafx-2


    【解决方案1】:

    关于这个问题有很多讨论,即更改项目后刷新tableview。
    见
    JavaFX 2.1 TableView refresh items
    问题
    http://javafx-jira.kenai.com/browse/RT-21822
    http://javafx-jira.kenai.com/browse/RT-22463
    http://javafx-jira.kenai.com/browse/RT-22599

    解决方法是触发内部tableview更新方法。有些人建议删除 tableview 项目并再次添加它们,但最简单的解决方法似乎是:

    b.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent t) {
            ExampleRow row = table.getItems().get(1);
            row.addHighlightedColumn(1);
            //How to trigger a redraw of the table or cell to reflect the new highlighting?
            // Workaround
            table.getColumns().get(0).setVisible(false);
            table.getColumns().get(0).setVisible(true);
        }
    });
    

    在上面链接的问题 cmets 中找到。这是真正的解决方法还是错觉?你需要自己深入挖掘。

    【讨论】:

    • 感谢 Uluk,答案很明确。我也为您链接的错误投票。
    猜你喜欢
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2011-12-25
    相关资源
    最近更新 更多