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

时间:2014-03-05 15:59:53

标签: tableview javafx-8

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

7 个答案:

答案 0 :(得分:14)

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

  1. 获取表格标题。这可以按照此处所述完成:https://stackoverflow.com/a/12465155
  2. 将更改事件侦听器添加到reorderingProperty,它将重新排序设置为false。
  3. 完整代码在这里:

    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);
                }
            });
        }
    });
    

    我不确定此解决方案的副作用,但快速测试表明解决方案效果很好。

答案 1 :(得分: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));
});

答案 2 :(得分:6)

我知道标记为java-8的问题,但对于那些漫游的人来说,在Java 9中,由于模块化导致.sun包无法访问并删除impl_,所有上述代码都会中断}。尽管有这些变化,它还引入了一些方便的公共方法,你可以使用它们:

  • setReorderable(boolean value)
  • getReorderable()

用于TableColumnBase,例如TableColumn用于设置可重新排序,

答案 3 :(得分:3)

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

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

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

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

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

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

答案 4 :(得分: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);
        }
    });
}

答案 5 :(得分: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);
        }
    });
}

答案 6 :(得分:1)

在以前的贡献上进行扩展,我发现了

tableView.getColumns().forEach(e -> e.setReorderable(false));

在Java 13中非常有用。