在JaxaFX 8中,我想对TableView的多个列进行排序,这可以通过按住shift键同时按下标题来实现。
但现在它应该在支持触控的设备上运行,我无法按下shift键。我尝试使用addEventHandler(..)捕获TableView上的事件,使用原始事件,按下修改器创建一个新事件并将其传递回Control。
我在扩展TableView的构造函数中的方法
final EventDispatcher orgDispatcher = getEventDispatcher();
setEventDispatcher((event, tail) -> {
if (event.getEventType() == MouseEvent.MOUSE_CLICKED) {
final MouseEvent mouseEvent = (MouseEvent) event;
final MouseEvent modifierEvent = new MouseEvent(MouseEvent.MOUSE_CLICKED, // type
mouseEvent.getX(), mouseEvent.getY(), mouseEvent.getScreenX(), mouseEvent.getScreenY(), // coords
MouseButton.SECONDARY, mouseEvent.getClickCount(), // clicks
true, true, true, true, // keyboard modifiers - shift-ctrl-alt-meta
false, false, false, // mouse modifiers
false, false, false, null);
mouseEvent.consume();
System.out.println("dispatched modified event" + mouseEvent.getButton() + modifierEvent.getButton());
return orgDispatcher.dispatchEvent(modifierEvent, tail);
}
return orgDispatcher.dispatchEvent(event, tail);
});
addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
System.out.println(event.getButton());
});
看起来这种方法的作用是点击带有主要打印辅助的TableView。但是排序没有按预期执行。似乎ColumnHeader在小部件的某个地方处理事件...
任何人都可以提供帮助 a)在正确的地方修改事件 或者b)为如何对列进行排序以及将这个漂亮的“箭头”图标添加到列中提供替代解决方案
功能显然已经存在我只是不知道如何解雇事件......
答案 0 :(得分:1)
显然我的问题的解决方案如下。
为了在多个列之后以编程方式设置排序,必须对ObservableList<TableColumn<E,?>> getSortOrder()
所持有的TableView
进行更改。可以简单地以正确的顺序添加TableColumn
。
由于通常通过shift-click导致这种情况的事件在JavaFX框架中某处(可能在某些Skin类或什么?)我无法通过EventFilter
捕获它。如果我在TableView
上应用过滤器已经发生了魔法......
因此,在我的自定义TableView中,我需要保留自己的sortOrder ObservableList
并在每个InputEvent
之后替换它。我没有在touchenabled设备上测试它,但是没有按Shift键我现在可以在多列之后进行排序。 (如果MouseEvent或TouchEvent没关系 - 关键是我没有键盘来按下修饰键)
addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
if (event.getTarget() instanceof TableColumnHeader) {
event.consume();
// Search for the clicked TableColumn:
TableColumn<E, ?> column = null;
final TableColumnHeader columHead = (TableColumnHeader) event.getTarget();
final String name = columHead.getTableColumn().getText();
for (final TableColumn<E, ?> col : getColumns()) {
if (col.getText().equals(name)) {
column = col;
}
}
// Now handle the sortOrder:
if (sortedColumns.containsKey(name)) {
if (sortedColumns.get(name) == TableColumn.SortType.ASCENDING) {
column.setSortType(TableColumn.SortType.DESCENDING);
sortedColumns.remove(name);
sortedColumns.put(name, TableColumn.SortType.DESCENDING);
} else {
sortedColumns.remove(name);
sortOrder.remove(column);
}
} else {
sortedColumns.put(name, TableColumn.SortType.ASCENDING);
sortOrder.add(column);
}
// Override the getSortOrder():
getSortOrder().clear();
getSortOrder().addAll(sortOrder);
}
});
带字段
private final ObservableMap<String, TableColumn.SortType> sortedColumns = FXCollections.observableHashMap();
private final ObservableList<TableColumn<E, ?>> sortOrder = FXCollections.observableArrayList();
答案 1 :(得分:0)
请注意,使用事件不会阻止调用EventHandler
上的其他TableView
(更不用说在列标题上注册的处理程序了)直接,在TableView的处理程序之前调用它们。它只会阻止调用TableView
父项上的事件处理程序。
您可能希望添加一个消耗该事件的事件过滤器(这会阻止调用任何处理程序)并触发已修改的事件。
addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
if(event.getButton() == MouseButton.PRIMARY) {
MouseEvent modifierEvent = new MouseEvent(MouseEvent.MOUSE_CLICKED, // type
event.getX(), event.getY(), event.getScreenX(), event.getScreenY(), // coords
MouseButton.SECONDARY, event.getClickCount(), // clicks
true, true, true, true, // keyboard modifiers - shift-ctrl-alt-meta
false, false, false, // mouse modifiers
false, false, false, null);
event.consume(); // prevents any left-click handlers from being invoked
Event.fireEvent(event.getTarget(), modifierEvent);
}
});
请注意,您无需替换事件调度程序来触发事件。有Event.fireEvent()静态方法可以做到这一点。