java - 在 TableView 中拖动/重新排序列时水平滚动
问题描述
在 JavaFX 的TableView
(and TreeTableView
) 中,当水平滚动条存在时,使用拖放对列进行重新排序非常困难,因为当人们想要将列拖到当前不可见的位置时(离开滚动窗格视口),表格不会自动滚动.
我注意到已经有一个错误(增强)报告:
...但是由于它已经有一段时间没有得到解决了,我想知道是否有任何其他方法可以使用当前的 API 实现相同的行为。
有SSCCE:
public class TableViewColumnReorderDragSSCCE extends Application {
public static final int NUMBER_OF_COLUMNS = 30;
public static final int MAX_WINDOW_WIDTH = 480;
@Override
public void start(Stage stage) {
stage.setScene(new Scene(createTable()));
stage.show();
stage.setMaxWidth(MAX_WINDOW_WIDTH);
}
private TableView<List<String>> createTable() {
final TableView<List<String>> tableView = new TableView<>();
initColumns(tableView);
return tableView;
}
private void initColumns(TableView<List<String>> tableView) {
for (int i=0; i<NUMBER_OF_COLUMNS; i++) {
tableView.getColumns().add(new TableColumn<>("Column " + i));
}
tableView.getItems().add(Collections.emptyList());
}
}
重现步骤:
- 运行上面的SSCCE
- 尝试拖动
Column 0
后Column 29
我正在寻求一个功能齐全的解决方案(如果有的话)。
解决方案
由于没有提供完整的解决方案,我想出了自己的一个。我介绍了一个 ( ColumnsOrderingEnhancer
) 实现,它将通过自动滚动(在需要时)增强表视图列的重新排序。
用法(使用上述 SSCCE 中定义的表视图):
// Enhance table view columns reordering
final ColumnsOrderingEnhancer<List<String>> columnsOrderingEnhancer = new ColumnsOrderingEnhancer<>(tableView);
columnsOrderingEnhancer.init();
ColumnsOrderingEnhancer
执行:
public class ColumnsOrderingEnhancer<T> {
private final TableView<T> tableView;
public ColumnsOrderingEnhancer(TableView<T> tableView) {
this.tableView = tableView;
}
public void init() {
tableView.skinProperty().addListener((observable, oldSkin, newSkin) -> {
// This can be done only when skin is ready
final TableHeaderRow header = (TableHeaderRow) tableView.lookup("TableHeaderRow");
final MouseDraggingDirectionHelper mouseDraggingDirectionHelper = new MouseDraggingDirectionHelper(header);
final ScrollBar horizontalScrollBar = getTableViewHorizontalScrollbar();
// This is the most important part which is responsible for scrolling table during the column dragging out of the viewport.
header.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
final double totalHeaderWidth = header.getWidth();
final double xMousePosition = event.getX();
final MouseDraggingDirectionHelper.Direction direction = mouseDraggingDirectionHelper.getLastDirection();
maybeChangeScrollBarPosition(horizontalScrollBar, totalHeaderWidth, xMousePosition, direction);
});
});
}
private void maybeChangeScrollBarPosition(ScrollBar horizontalScrollBar, double totalHeaderWidth, double xMousePosition, MouseDraggingDirectionHelper.Direction direction) {
if (xMousePosition > totalHeaderWidth && direction == RIGHT) {
horizontalScrollBar.increment();
}
else if (xMousePosition < 0 && direction == LEFT) {
horizontalScrollBar.decrement();
}
}
private ScrollBar getTableViewHorizontalScrollbar() {
Set<Node> scrollBars = tableView.lookupAll(".scroll-bar");
final Optional<Node> horizontalScrollBar =
scrollBars.stream().filter(node -> ((ScrollBar) node).getOrientation().equals(Orientation.HORIZONTAL)).findAny();
try {
return (ScrollBar) horizontalScrollBar.get();
}
catch (NoSuchElementException e) {
return null;
}
}
/**
* A simple class responsible for determining horizontal direction of the mouse during dragging phase.
*/
static class MouseDraggingDirectionHelper {
private double xLastMousePosition = -1;
private Direction direction = null;
MouseDraggingDirectionHelper(Node node) {
// Event filters that are determining when scrollbar needs to be incremented/decremented
node.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> xLastMousePosition = event.getX());
node.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
direction = ((event.getX() - xLastMousePosition > 0) ? RIGHT : LEFT);
xLastMousePosition = event.getX();
});
}
enum Direction {
LEFT,
RIGHT
}
public Direction getLastDirection() {
return direction;
}
}
}
最终结果(效果出奇的好):
推荐阅读
- python - 将 Numpy 数组用于大型数据文件
- sql - 子查询作为 SQL Server UDF 的参数
- c# - 将文件解析为单独的字符串
- php - 带有帖子和自定义字段的 Wordpress 搜索
- javascript - 使用 JavaScript 通过 AJAX 将多个 Canvas 创建的图像保存到服务器
- material-ui - 材质用户界面 (MUI)。如何通过 props 将处理程序传递给 DataGrid 组件(用于在列类型 = 操作中使用它们)
- amazon-web-services - AWS EC2 不允许非常规端口访问网站
- java - com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'HTTP' HTTP ERROR 404 Not Found
- python - 将 pycairo svg 拆分为较小的页面
- macos - 在 Outlook for Mac 中使用 Applescript 复制条件格式