如何防止TableView在javaFX 8中执行TableColumn重新排序?

问题描述 投票:9回答:6

我读了这个https://bugs.openjdk.java.net/browse/JDK-8102128但是我没有在JavaFX 8的Api中找到一些东西。在TableView中没有任何阻止重新排序的方法吗?

tableview javafx-8
6个回答
14
投票

花了半天时间试图解决问题。也许我的调查可能对其他人有用。可以使用一些黑客禁用列重新排序。这是步骤:

  1. 获取表头。这可以按照这里描述的那样完成:https://stackoverflow.com/a/12465155
  2. 将change事件侦听器添加到reorderingProperty,它将重新排序设置为false。

完整代码在这里:

tableView.widthProperty().addListener(new ChangeListener<Number>()
{
    @Override
    public void changed(ObservableValue<? extends Number> source, Number oldWidth, Number newWidth)
    {
        TableHeaderRow header = (TableHeaderRow) tableView.lookup("TableHeaderRow");
        header.reorderingProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                header.setReordering(false);
            }
        });
    }
});

我不确定这个解决方案的副作用,但快速测试表明解决方案运行良好。


7
投票

我喜欢Alexander Chingarev的想法,但我认为代码会产生内存泄漏!每次width属性更改时,都会注册一个新的侦听器,而旧的侦听器永远不会被垃圾回收!因此,您可以存储对侦听器的引用,并确保在添加新侦听器之前将其从可观察值(在本例中为重新排序属性)中删除,或者确保仅将侦听器添加到重新排序属性中一次。

我使用了只改变一次的skin属性(如果我没有记错的话)来添加我的监听器:

tableView.skinProperty().addListener((obs, oldSkin, newSkin) -> {
    final TableHeaderRow header = (TableHeaderRow) lookup("TableHeaderRow");
    header.reorderingProperty().addListener((o, oldVal, newVal) -> header.setReordering(false));
});

6
投票

我知道问题标记java-8,但对于那些漫步的人,在Java 9所有上述代码将因为模块化而破坏,这使得.sun包无法访问和删除impl_。尽管有这些变化,它还引入了一些方便的公共方法,你可以使用它们:

  • setReorderable(boolean value)
  • getReorderable()

TableColumnBase这样的TableColumn用于设置可重新定位,


3
投票

Java 8 RT-24669中添加的API是column.impl_setReorderable(false);

您可以在impl_setReorderable源中看到TableColumnBase.java定义。

但是,此API仅供内部使用,标记为已弃用且不构成公共JavaFX API的一部分。

通常,JavaFX中的impl_方法将在以后的某个时间删除,如果您尝试使用它们,可能会破坏您的代码。

在查看表列上可重新排序属性实现的代码时,它会忽略指向表列标题的某些鼠标事件。在TableColumnHeader.java代码中搜索isReorderable以获取更多信息。

我不确定如何在不执行大量工作的情况下仅使用公共JavaFX API完成与impl_setReorderable API完全相同的行为。


3
投票

另一种解决方案,它不需要在Java 8中使用私有API。

public static <T> void preventColumnReordering(TableView<T> tableView) {
    Platform.runLater(() -> {
        for (Node header : tableView.lookupAll(".column-header")) {
            header.addEventFilter(MouseEvent.MOUSE_DRAGGED, Event::consume);
        }
    });
}

1
投票

谢谢!如果您要禁用多个表,它也适用于lambda。

private void yourTableListeners(){
    yourTableView.widthProperty()
            .addListener((observable, oldValue, newValue) -> yourReusableDisablingMethod(yourTableView));
    anotherTableView.widthProperty()
            .addListener((observable, oldValue, newValue) -> yourReusableDisablingMethod(anotherTableView));
}

@SuppressWarnings("restriction")
private void yourReusableDisablingMethod(TableView tableView) {
    TableHeaderRow header = (TableHeaderRow) tableView.lookup("TableHeaderRow");
    header.reorderingProperty().addListener(new ChangeListener<Boolean>() {
        public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
            header.setReordering(false);
        }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.