Javafx8 stackpane子项阻止鼠标事件

Javafx8 stackpane子项阻止鼠标事件,javafx,focus,mouseevent,Javafx,Focus,Mouseevent,我有一个带有复杂场景的javafx8应用程序。它由一个拆分窗格组成,在顶部部分,我有一个具有多个级别(子级)的堆栈窗格。最后面的是一个背景,在调整大小时只需要重新绘制,另一个是网格线,lat/long。另一个用于绘图,最后一个用于滑动复合控件。当复合材料(按钮、标签、组合框和文本字段,在stackframe的最后一个子项中,它正确地截取并处理鼠标和键盘事件。但是,当它位于顶部时,没有任何事件传播到下面的子窗格。我切换了顺序,现在按钮和轴控件工作,但现在没有任何内容传播到复合控件在它下面。按钮看不

我有一个带有复杂场景的javafx8应用程序。它由一个拆分窗格组成,在顶部部分,我有一个具有多个级别(子级)的堆栈窗格。最后面的是一个背景,在调整大小时只需要重新绘制,另一个是网格线,lat/long。另一个用于绘图,最后一个用于滑动复合控件。当复合材料(按钮、标签、组合框和文本字段,在stackframe的最后一个子项中,它正确地截取并处理鼠标和键盘事件。但是,当它位于顶部时,没有任何事件传播到下面的子窗格。我切换了顺序,现在按钮和轴控件工作,但现在没有任何内容传播到复合控件在它下面。按钮看不到鼠标的动作

这似乎类似于,但不清楚是否正确,也不清楚是否有正确的答案

我用一个非常简单的测试简化了我的场景,即source to follow。在这个测试中,我有一个StackPane,它有两个子项,都是VBox,一个if与左上对齐,另一个与右上对齐。只有右上角的第二个按钮响应被按下

为什么。我的应用程序有多个窗格的原因是性能。两种绘图操作都很昂贵且频繁,我不想不断地重新绘制静态或接近静态的布局

fxml

主要

在我的应用程序中,最后面的窗格是背景画布。它只需要绘制一次,然后在调整窗口大小时重新绘制

下一个是具有lat/long网格的画布。它只需要在窗口大小更改或垂直或水平比例更改时重新绘制

下一个是下图中的主绘图画布

<vbox>
<hbox>
   drawing canvas
   vertical scale
</hbox>
   horizontal scale
</vbox>

画布
垂直比例尺
水平比例尺
下一层带有一个或多个旗杆,其中垂直杆是一个类似于十字线的滑动尺。这些旗杆需要可拖动。如果该层位于顶部,则它可以完美滑动,但两个刻度无法聚焦。如果顶部的两个窗格颠倒,则刻度可以完美工作,但旗杆对象永远不会接收事件

两个按钮的示例非常简单地复制了我看到的内容

谢谢


在javafx的事件处理中,只有鼠标位置下最顶端的节点(在您的示例container2中)将被确定为鼠标单击事件的目标,这就是container1不接收事件的原因

目标节点是事件调度链中的结束节点。当您单击leftButton时,鼠标单击的事件将从场景图的根节点移动到目标节点(container2),如果没有被消耗,则返回。Container1不在调度链上,将不会接收事件:


您可以尝试使用
container.setPickOnBounds(false)

我添加了一个应用程序的屏幕截图。fxml应该是该屏幕截图的正确截图。如果不是,那就不是这个问题的重点。要部分重申这个问题,在Linux和Windows上,顶部窗格中的仅限控件都会显示接收事件。这两个按钮的应用程序是演示该问题的最小应用程序。鼠标右键工作,鼠标左键不工作。如果孩子们按其他顺序加载,左键可以工作,右键不能。虽然我愿意为你回答这个问题而表扬你。我不明白为什么。我找到了。这意味着这实际上是一个副本。在我拥有的书籍中,它们没有区分堆叠窗格与其他任何不同事实上,关于事件处理的书籍称事件遍历和消费事件,事件从上到下遍历子事件,直到到达消费().这实际上是在哪里解释的?谢谢!那为什么不只是文本字段的默认值呢?在合成场景中,总是会有用于布局的容器,即VBox中的HBox和其中的多个Whatever?正如我所说。我的实际场景非常复杂,为了简洁起见,我想提出一个最小的“for In”我试图一次一个地关闭setInBounds,看看是什么阻碍了事件的遍历。出于沮丧,我最终在所有地方都关闭了它。
package mouseeventdemo;
/**
 * Sample Skeleton for 'FXMLDocument.fxml' Controller Class
 */

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;

public class MouseEventDemoController {

    @FXML // ResourceBundle that was given to the FXMLLoader
    private ResourceBundle resources;

    @FXML // URL location of the FXML file that was given to the FXMLLoader
    private URL location;

    @FXML // fx:id="containerPane"
    private StackPane containerPane; // Value injected by FXMLLoader

    @FXML // fx:id="container1"
    private VBox container1; // Value injected by FXMLLoader

    @FXML // fx:id="leftButton"
    private Button leftButton; // Value injected by FXMLLoader

    @FXML // fx:id="container2"
    private VBox container2; // Value injected by FXMLLoader

    @FXML // fx:id="rightButton"
    private Button rightButton; // Value injected by FXMLLoader

    @FXML
    void leftButtonDown(ActionEvent event) {
        System.out.println("leftButtonPressed");
    }

    @FXML
    void rightButtonDown(ActionEvent event) {
        System.out.println("rightButtonPressed");
    }

    @FXML // This method is called by the FXMLLoader when initialization is complete
    void initialize() {
        assert containerPane != null : "fx:id=\"containerPane\" was not injected: check your FXML file 'FXMLDocument.fxml'.";
        assert container1 != null : "fx:id=\"container1\" was not injected: check your FXML file 'FXMLDocument.fxml'.";
        assert leftButton != null : "fx:id=\"leftButton\" was not injected: check your FXML file 'FXMLDocument.fxml'.";
        assert container2 != null : "fx:id=\"container2\" was not injected: check your FXML file 'FXMLDocument.fxml'.";
        assert rightButton != null : "fx:id=\"rightButton\" was not injected: check your FXML file 'FXMLDocument.fxml'.";

    }
}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mouseeventdemo;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 *
 * @author walt
 */
public class MouseEventDemo extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}
<vbox>
<hbox>
   drawing canvas
   vertical scale
</hbox>
   horizontal scale
</vbox>