在TableView JavaFX中单击时更新当前行

Updating current row when clicked upon in TableView JavaFX

因此,如果用户选择的行与当前选择的行不同,则我有一段代码可以工作

1
2
3
4
5
6
7
8
9
table.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> {
                if (newValue == null) {
                    updateDetails(oldValue);
                    return;
                }
                updateDetails(newValue);
            });
}

但是,如果用户也单击相同的值,我希望此方法也能正常工作-基本上,代码的一部分会修改显示的图像,但是除非我单击另一个,否则该图像本身不会更新。行,然后返回到我之前所在的行。我希望能够通过单击它来更新我所在的行(这将称为updateDetails),但似乎无法弄清楚这一点...


创建自定义rowFactory并向其添加鼠标侦听器。
例子

这将显示最后单击的项的旧值属性,并单击新项作为Label的文本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
TableView<Item> tv = new TableView<>(FXCollections.observableArrayList(new Item("foo"), new Item("bar"), new Item("42")));

Label label = new Label();

TableColumn<Item, String> valueColumn = new TableColumn<>("value");
valueColumn.setCellValueFactory(d -> d.getValue().valueProperty());
tv.getColumns().add(valueColumn);

EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {

    private Item lastItem;

    @Override
    public void handle(MouseEvent event) {
        if (event.getButton() == MouseButton.PRIMARY) {
            TableRow<Item> source = (TableRow<Item>) event.getSource();
            if (!source.isEmpty()) {
                label.setText(MessageFormat.format("old: {0}; new: {1}", lastItem == null ? null : lastItem.getValue(), (lastItem = source.getItem()).getValue()));
            }
        }
    }
};

tv.setRowFactory(t -> {
    TableRow<Item> row = new TableRow();
    row.setOnMouseClicked(eventHandler);

    return row;
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Item {

    public Item() {
    }

    public Item(String value) {
        this.value.set(value);
    }

    private final StringProperty value = new SimpleStringProperty();

    public String getValue() {
        return value.get();
    }

    public void setValue(String val) {
        value.set(val);
    }

    public StringProperty valueProperty() {
        return value;
    }

}