Javafx如何在Tab上模拟右键单击事件
Javafx how to simulate a right click event on Tab
我有一个 Tab
,我想以编程方式触发右键单击事件,弹出我的 ContextMenu
,在选项卡上设置
Tab tab = new Tab("Some tab that has no graphic and doesnt need graphic");
tab.setContextMenu(new ContextMenu(new MenuItem("go")));
//add it to a tabPane.
//now when i want to trigger a right click i do this
Event rightClick = new MouseEvent(MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, MouseButton.SECONDARY,
1, false, false, false, false, false, false, false, false, true, false, null);
MouseEvent.fireEvent(tab, rightClick);//but it doesnt work why??
我什至这样修改了代码
Event rightClick = new MouseEvent(MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, MouseButton.SECONDARY,
1, false, false, false, false, false, false, true, false, true, false, null); //still no
在任何普通节点上上面的代码都可以工作,只是 Tab
我需要一个 javafx 方式
它不起作用,因为Tab
不支持鼠标事件。 Tab
class 不是 Node
子 class,即它不代表您在 header 中看到的实际选项卡 UI选项卡窗格:它代表选项卡的模型。 (它封装了文本,是否被选中等)事件是支持的,如onCloseRequested
、onClosed
、onSelectionChanged
。参见 documentation.
要触发鼠标事件,您需要在选项卡代表的实际 UI 上触发它。您只能通过 CSS 查找来获得它,这有点麻烦,但它确实有效。
我实际上建议在上下文菜单上调用 show
,而不是触发事件,因为这在语义上更能代表您想要执行的操作。据我所知,您仍然需要查找该节点,因为您需要在屏幕上找到它的位置,但您可以直接 contextMenu.show(tab.getTabPane().getScene().getWindow());
并且上下文菜单会出现在 某处。但是最好能得到节点的引用:
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class ShowTabContextMenu extends Application {
@Override
public void start(Stage primaryStage) {
TabPane tabPane = new TabPane();
Tab tab = new Tab("Tab");
tab.setId("myTab");
tabPane.getTabs().add(tab);
ContextMenu contextMenu = new ContextMenu();
contextMenu.getItems().addAll(new MenuItem("Choice 1"), new MenuItem("Choice 2"));
tab.setContextMenu(contextMenu);
Scene scene = new Scene(tabPane, 400, 400);
PauseTransition pause = new PauseTransition(Duration.seconds(2));
pause.setOnFinished(e -> {
Node theTab = tabPane.lookup("#myTab");
contextMenu.show(theTab, Side.RIGHT, 0, 0);
});
primaryStage.setScene(scene);
primaryStage.show();
pause.play();
}
public static void main(String[] args) {
launch(args);
}
}
如果你真的想模拟一个事件,你应该模拟一个ContextMenuEvent
而不是鼠标事件:
pause.setOnFinished(e -> {
Node theTab = tabPane.lookup("#myTab");
// contextMenu.show(theTab, Side.RIGHT, 0, 0);
Bounds tabBounds = theTab.getBoundsInLocal();
double centerX = tabBounds.getMinX() + tabBounds.getWidth()/2;
double centerY = tabBounds.getMinY()+tabBounds.getHeight()/2;
Point2D location = theTab.localToScreen(centerX, centerY);
double x = location.getX();
double y = location.getY();
Event event = new ContextMenuEvent(ContextMenuEvent.CONTEXT_MENU_REQUESTED, centerX, centerY, x, y, false, new PickResult(theTab, x, y));
Event.fireEvent(theTab, event);
});
但这对我来说似乎是错误的:没有实际事件发生,您只是想要显示上下文菜单。
我有一个 Tab
,我想以编程方式触发右键单击事件,弹出我的 ContextMenu
,在选项卡上设置
Tab tab = new Tab("Some tab that has no graphic and doesnt need graphic");
tab.setContextMenu(new ContextMenu(new MenuItem("go")));
//add it to a tabPane.
//now when i want to trigger a right click i do this
Event rightClick = new MouseEvent(MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, MouseButton.SECONDARY,
1, false, false, false, false, false, false, false, false, true, false, null);
MouseEvent.fireEvent(tab, rightClick);//but it doesnt work why??
我什至这样修改了代码
Event rightClick = new MouseEvent(MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, MouseButton.SECONDARY,
1, false, false, false, false, false, false, true, false, true, false, null); //still no
在任何普通节点上上面的代码都可以工作,只是 Tab
我需要一个 javafx 方式
它不起作用,因为Tab
不支持鼠标事件。 Tab
class 不是 Node
子 class,即它不代表您在 header 中看到的实际选项卡 UI选项卡窗格:它代表选项卡的模型。 (它封装了文本,是否被选中等)事件是支持的,如onCloseRequested
、onClosed
、onSelectionChanged
。参见 documentation.
要触发鼠标事件,您需要在选项卡代表的实际 UI 上触发它。您只能通过 CSS 查找来获得它,这有点麻烦,但它确实有效。
我实际上建议在上下文菜单上调用 show
,而不是触发事件,因为这在语义上更能代表您想要执行的操作。据我所知,您仍然需要查找该节点,因为您需要在屏幕上找到它的位置,但您可以直接 contextMenu.show(tab.getTabPane().getScene().getWindow());
并且上下文菜单会出现在 某处。但是最好能得到节点的引用:
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class ShowTabContextMenu extends Application {
@Override
public void start(Stage primaryStage) {
TabPane tabPane = new TabPane();
Tab tab = new Tab("Tab");
tab.setId("myTab");
tabPane.getTabs().add(tab);
ContextMenu contextMenu = new ContextMenu();
contextMenu.getItems().addAll(new MenuItem("Choice 1"), new MenuItem("Choice 2"));
tab.setContextMenu(contextMenu);
Scene scene = new Scene(tabPane, 400, 400);
PauseTransition pause = new PauseTransition(Duration.seconds(2));
pause.setOnFinished(e -> {
Node theTab = tabPane.lookup("#myTab");
contextMenu.show(theTab, Side.RIGHT, 0, 0);
});
primaryStage.setScene(scene);
primaryStage.show();
pause.play();
}
public static void main(String[] args) {
launch(args);
}
}
如果你真的想模拟一个事件,你应该模拟一个ContextMenuEvent
而不是鼠标事件:
pause.setOnFinished(e -> {
Node theTab = tabPane.lookup("#myTab");
// contextMenu.show(theTab, Side.RIGHT, 0, 0);
Bounds tabBounds = theTab.getBoundsInLocal();
double centerX = tabBounds.getMinX() + tabBounds.getWidth()/2;
double centerY = tabBounds.getMinY()+tabBounds.getHeight()/2;
Point2D location = theTab.localToScreen(centerX, centerY);
double x = location.getX();
double y = location.getY();
Event event = new ContextMenuEvent(ContextMenuEvent.CONTEXT_MENU_REQUESTED, centerX, centerY, x, y, false, new PickResult(theTab, x, y));
Event.fireEvent(theTab, event);
});
但这对我来说似乎是错误的:没有实际事件发生,您只是想要显示上下文菜单。