我读了这个https://bugs.openjdk.java.net/browse/JDK-8102128但是我没有在JavaFX 8的Api中找到一些东西。在TableView中没有任何阻止重新排序的方法吗?
花了半天时间试图解决问题。也许我的调查可能对其他人有用。可以使用一些黑客禁用列重新排序。这是步骤:
完整代码在这里:
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);
}
});
}
});
我不确定这个解决方案的副作用,但快速测试表明解决方案运行良好。
我喜欢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));
});
我知道问题标记java-8
,但对于那些漫步的人,在Java 9
所有上述代码将因为模块化而破坏,这使得.sun
包无法访问和删除impl_
。尽管有这些变化,它还引入了一些方便的公共方法,你可以使用它们:
setReorderable(boolean value)
getReorderable()
对TableColumnBase
这样的TableColumn
用于设置可重新定位,
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完全相同的行为。
另一种解决方案,它不需要在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);
}
});
}
谢谢!如果您要禁用多个表,它也适用于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);
}
});
}