Javafx如何在Tab上模拟右键单击事件

时间:2016-06-08 19:18:43

标签: java javafx javafx-2 javafx-8

我有一个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方式

1 个答案:

答案 0 :(得分:3)

它不起作用,因为Tab不支持鼠标事件。 Tab类不是Node子类,即它不代表您在选项卡窗格标题中看到的实际选项卡UI:它表示选项卡的模型。 (它封装了文本,是否被选中等。)事件是支持,如onCloseRequestedonClosedonSelectionChanged。请参阅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);
    });

但这对我来说似乎不对:没有发生实际事件,你只想显示上下文菜单。