JavaFx 8 MouseEvents触发不一致

时间:2014-12-03 23:16:53

标签: java mouseevent javafx-8

编辑:问题似乎来自使用SplitPane。我删除了它,但现在我遇到了MouseTransparent问题,cf评论

我在StackPane上遇到问题,其中Controller类应该通过鼠标拖动来管理节点转换:

出于某种原因,只要鼠标进入StackPane,就会正确触发.setOnMouseEntered事件。但是,setOnMousePressed(在单击StackPane中的节点时)根本不会触发,除非在StackPane中心的标签上。当我删除标签时,没有任何东西发射。 StackPane本身由SplitPane组成,它由几个其他节点组成。

其中一些节点(那些应该被拖动的节点)也有一些setOnMousePressed等事件管理,它们被正确触发了!

更多地了解背景:我正在进行海军对战游戏实施。我目前正在尝试通过控制器类来管理船只放置(这样我就可以确认船不会被放置在界外或在另一条船上)。控制器类(BoatMoveManager)在实例化时,在最高的StackPane上创建所有这些mouseEvent处理程序(GameBoard扩展StackPane)。

public class BoatMoveManager {
    GameBoard gB;

    public BoatMoveManager(GameBoard g){
        gB = g;

        //the following mouseEventHandler fires correctly whenever the mouse enters the GameBoard (StackPane)
        gB.setOnMouseEntered(event -> {
            System.out.println("GameBoard OnMouseEntered");

        //the following mouseEventHandler doesn't fire, except on a label in the middle of the GameBoard
        gB.setOnMousePressed(event -> {
            System.out.println("GameBoard OnMousePressed");
        });

我不明白为什么事件会与标签一起触发,而不是GameBoard中的其他节点......(可能是标签是直接"内部&#34 ; GameBoard,而其他节点位于水平分割器的顶部?)

例如,这是GameBoard的构造函数:

public class GameBoard extends StackPane {
    private SplitPane splitter;
    private TilePane gameZone;
    private TabZone tabs;
    private Grid playerGrid, opponentGrid, playerHarbor, opponentHarbor;
    private FlowPane playerGrids, opponentGrids, playerZone, opponentZone;
    private Score playerScore, opponentScore;
    private Label popup;

    private static HBox playerHBox, opponentHBox;
    private static VBox playerVBox, opponentVBox;

    private static BoatMoveManager bMM;

    private List<Boat> playerBoatsList = new ArrayList<Boat>(), opponentBoatsList = new ArrayList<Boat>() ;

    public GameBoard(){
        super();

        playerGrid = new Grid('G','H');
        opponentGrid = new Grid('G','H');
        playerHarbor = new Grid('H','H');
        opponentHarbor = new Grid('H','H');

        bMM = new BoatMoveManager(this);

        for(int i = 1 ; i < 5 ; ++i){
            playerBoatsList.add(new Boat(i, playerGrid, playerHarbor));
            opponentBoatsList.add(new Boat(i, opponentHarbor, opponentGrid));
        }

        playerGrid.drawBoat(playerBoatsList.get(0), 3, 4);
        playerGrid.drawBoat(playerBoatsList.get(1), 3, 5);
        playerGrid.drawBoat(playerBoatsList.get(2), 3, 6);
        playerGrid.drawBoat(playerBoatsList.get(3), 3, 7);

        playerScore = new Score();
        opponentScore = new Score();

        gameZone = new TilePane(Orientation.HORIZONTAL);
        gameZone.setStyle("-fx-background-color: lightgray");

        playerHBox = new HBox();
        playerHBox.getChildren().addAll(playerHarbor, playerGrid);

        playerHBox.setSpacing(Grid.getUnit());

        playerVBox = new VBox();
        playerVBox.getChildren().addAll(playerScore,playerHBox);
        playerVBox.maxWidthProperty().bind(gameZone.widthProperty().divide(2));
        playerScore.setAlignment(Pos.CENTER);

        opponentHBox = new HBox();
        opponentHBox.getChildren().addAll(opponentGrid, opponentHarbor);
        opponentHBox.setSpacing(Grid.getUnit());

        opponentVBox = new VBox();
        opponentVBox.getChildren().addAll(opponentScore,opponentHBox);
        opponentScore.setAlignment(Pos.CENTER);

        gameZone.getChildren().addAll(playerVBox, opponentVBox);
        gameZone.setHgap(Grid.getUnit()*3);
        gameZone.setAlignment(Pos.CENTER);

        gameZone.setSnapToPixel(false);
        tabs = new TabZone();

        splitter = new SplitPane();
        splitter.setOrientation(Orientation.VERTICAL);
        splitter.setDividerPositions(0.75f,0.25f);
        splitter.getItems().addAll(gameZone,tabs);

        splitter.setOnDragEntered(event ->{
            BoatMoveManager.setTarget(splitter);
        });

        popup = new Label("uninitialized");

        this.getChildren().addAll(splitter,popup);

        this.setOnDragEntered(event -> {
            BoatMoveManager.setTarget(this);
        });
    }

我正在谈论的标签是&#34; popup&#34;,它在构造函数的最后添加了&#34; splitter&#34;在

this.getChildren().addAll(splitter,popup);

但考虑到这样一个事实,即使我没有添加它,像MousePressed这样的事件也不会通过GameBoard激发......

这里是GameBoard的布局,以清理事物(网格和船只布局是不言自明的): GameBoard layout (在新标签页中打开此图片,以全尺寸查看) 我希望这并不是太混乱,无法理解我想要做的事情。为什么它不起作用。

2 个答案:

答案 0 :(得分:0)

我现在还不确定。我几乎必须在我的计算机上测试代码才能确定,但​​请尝试

this.setMouseTransparency(true);

这将使其无法单击堆栈窗口。同样为了将来参考,您可以在GameBoard的调用开始时删除“this”。如果你的类扩展了StackPane,那么调用getChildren()。add(node)是完全合法的。

答案 1 :(得分:0)

遇到同样的问题(再次)..

我相信StackPane是你的问题。他们不喜欢明显地传递事件.. 在我的情况下,设置: stackPane .setPickOnBounds(假);

是我的修复。

我希望这能为您解决问题......也许是一个错误?