Хорошо, я нашел следующий (очень, очень грязный) обходной путь.Я никогда не пробовал этого раньше, потому что я предполагаю, что это предотвратит показ контекстного меню (как я отметил в моем исходном вопросе), но иногда просто используется событие мыши для каждого TableColumnHeader
, а контекстное меню по-прежнему отображается правильно (также работаетс TableColumns без контекстных меню).
Не уверен, что что-то внутреннее может пойти не так с этим, но, поскольку правый щелчок не дает ничего полезного по умолчанию, я надеюсь, что нет.
Конечно, lookupAll
необходимо вызывать после того, как оно было обработано.
Примечание 1: Если для TableMenuButtonVisible
установлено значение true, это необходимо делать каждый раз, когда для столбца установлено значение видимого.
Примечание 2: Становится все грязнее и грязнее.Простого повторного вызова после того, как для столбца установлено значение visible (см. Примечание 1), не всегда недостаточно (также не для вызова Platform.runLater
).Я предполагаю, что это потому, что заголовок столбца не был отображен в тот момент.Вам либо
- необходимо дождаться полного заполнения
Set<Node>
, т.е. его размер должен быть amountOfVisibleColumns + 1
.Если он равен количеству видимых столбцов, он не будет работать для вновь показанного столбца. - или вызовите
layout()
в TableView до lookupAll
- или если у вас естькласс, который расширяет
TableView
, переопределяет layoutChildren
и выполняет поиск, если количество видимых столбцов изменилось
Примечание 3 : необходимо отслеживать старый onMousePressed
и выполните ее, если кнопка не SECONDARY
, в противном случае изменение порядка столбцов не будет работать.
Пожалуйста, дайте мне знать, если вы можете придумать какой-нибудь более чистый способ.
![enter image description here](https://i.stack.imgur.com/qLLqr.gif)
import java.util.Set;
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.skin.TableColumnHeader;
import javafx.scene.input.MouseButton;
import javafx.stage.Stage;
public class Foo extends Application {
@Override
public void start(Stage stage) throws Exception {
TableView<Object> testView = new TableView<>();
testView.getColumns().addAll(createColumn("C1"), createColumn("C2"), createColumn("C3"));
stage.setOnShown(ev -> {
Set<Node> headers = testView.lookupAll("TableColumnHeader");
for (Node header : headers) {
if (header != null) {
((TableColumnHeader) header).setOnMousePressed(e -> {
if (e.getButton() == MouseButton.SECONDARY) {
e.consume();
}
});
}
}
});
stage.setScene(new Scene(testView));
stage.show();
}
private TableColumn<Object, Object> createColumn(String text) {
MenuItem item = new MenuItem("Context");
item.setOnAction(e -> {
System.out.println("Action");
});
ContextMenu contextMenu = new ContextMenu();
contextMenu.getItems().add(item);
TableColumn<Object, Object> column = new TableColumn<>(text);
column.setContextMenu(contextMenu);
return column;
}
public static void main(String[] args) {
launch(args);
}
}