在javafx tableview中添加工具提示并更改tablecells的颜色

时间:2016-10-28 09:17:02

标签: java javafx tableview

我想在tablview中显示db-result。因此我有一个动态创建的tableview:

  public void createTableView() throws Exception {
    List<String> columnNames = new ArrayList<>();
    columnNames = test.getColumnNames();

    for (int i = 0; i < test.getColumnCount(); i++) {
        TableColumn<ObservableList<String>,String> column = new TableColumn<>(columnNames.get(i));
        final int j = i;

        column.setCellValueFactory(new Callback<CellDataFeatures<ObservableList<String>, String>, ObservableValue<String>>(){                   
            public ObservableValue<String> call(CellDataFeatures<ObservableList<String>, String> param) {                                                                                             
            return new SimpleStringProperty(param.getValue().get(j).toString());                       
            }
        });
        tableView.getColumns().add(column); 
    } 

添加db-result:

public void initializeTableView(List<List<String>> result) throws Exception {
    ObservableList<ObservableList<String>> data = FXCollections.observableArrayList();      
    if (tableView.getColumns().size() == 0) {
       createTableView();
    }
    for (int i = 0; i < result.size(); i++) {
        ObservableList<String> row = FXCollections.observableArrayList();
        row.addAll(result.get(i));
        data.add(row);      
    }   
    tableView.setItems(data);

现在我得到第二个db-result,我在同一个tableview中显示。现在我想比较第一个结果列表和第二个结果列表,如果值不相等,我想在工具提示中显示第一个结果并将cellcolor更改为红色。

1 个答案:

答案 0 :(得分:0)

您可以使用比较数据的自定义TableCell。当然,最好不要将整个数据存储两次。如果更改是稀疏的,使用Map来存储原始值会更有效,但是设置单元格样式的想法是一样的。

示例:

@Override
public void start(Stage primaryStage) {
    // create sample data
    List<List<String>> result = Arrays.asList(
            Arrays.asList("a", "b"),
            Arrays.asList("c", "d"),
            Arrays.asList("e", "f"),
            Arrays.asList("g", "h"),
            Arrays.asList("i", "j")
    );

    TableView<ObservableList<String>> tableView = new TableView<>();
    List<String> columnNames = Arrays.asList("column1", "column2");

    for (int i = 0; i < columnNames.size(); i++) {
        TableColumn<ObservableList<String>, String> column = new TableColumn<>(columnNames.get(i));
        final int j = i;

        column.setCellValueFactory((CellDataFeatures<ObservableList<String>, String> param) -> Bindings.stringValueAt(param.getValue(), j));

        // use custom cells
        column.setCellFactory(tc -> new TableCell<ObservableList<String>, String>() {

            private final Tooltip tooltip = new Tooltip();

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);

                if (empty) {
                    // clear the cell
                    setStyle(null);
                    setText(null);
                    setTooltip(null);
                } else {
                    setText(item);
                    String original = result.get(getIndex()).get(j);
                    if (Objects.equals(original, item)) {
                        // same value as original -> no tooltip, no background
                        setStyle(null);
                        setTooltip(null);
                    } else {
                        // different -> red background + tooltip
                        setStyle("-fx-background-color: red;");
                        setTooltip(tooltip);
                        tooltip.setText(original);
                    }
                }
            }

        });
        tableView.getColumns().add(column);
    }

    ObservableList<ObservableList<String>> data = FXCollections.observableArrayList();

    for (int i = 0; i < result.size(); i++) {
        ObservableList<String> row = FXCollections.observableArrayList();
        row.addAll(result.get(i));
        data.add(row);
    }
    tableView.setItems(data);

    // do some modifications
    data.get(0).set(1, "1");
    data.get(3).set(0, "3");

    Scene scene = new Scene(tableView);

    primaryStage.setScene(scene);
    primaryStage.show();
}