JavaFx:我有一个带有Button的HBox,在一个Group中,我想为每个节点管理不同的“MousePressed”事件。 目前,如果我为所有节点处理相同的事件,它总是由父节点(组)捕获。
有办法吗? 例如,有没有办法确定鼠标坐标是否在节点的子节点上(在我的例子中是HBox)?
这是我需要的一个例子:
如果我点击Group我想要隐藏HBox如果鼠标的坐标不与HBox碰撞,如果我点击HBox,Hbox不需要隐藏,如果我点击按钮(实现)作为一个ImageView)我需要执行代码而不隐藏HBox。
所以我想做的就是这样:
@FXML
Group group;
” 其中group在使用sceneBuilder设计的AncorPane中 “
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-sources/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
感谢您的帮助。
答案 0 :(得分:2)
你的问题不清楚,但是,如果它对你有所帮助:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
// the magic: use setPickOnBounds(false);
public class LayersWithMouseEvents extends Application {
@Override
public void start(Stage primaryStage) {
// root
StackPane root = new StackPane();
// layers
Pane bottomLayer = new Pane();
Pane topLayer = new Pane();
// bottom: layer1, top: layer2
root.getChildren().addAll(bottomLayer, topLayer);
// layer 1 objects
Rectangle rectangle = new Rectangle( 100,100,100,100);
rectangle.setFill(Color.GREEN);
rectangle.setOnMousePressed(e -> System.out.println("Rectangle 0: " + e));
bottomLayer.getChildren().add(rectangle);
// layer 2 objects
rectangle = new Rectangle( 50,50,50,50);
rectangle.setFill(Color.RED);
rectangle.setOnMousePressed(e -> System.out.println("Rectangle 1: " + e));
topLayer.getChildren().add(rectangle);
rectangle = new Rectangle( 125,125,50,50);
rectangle.setFill(Color.RED);
rectangle.setOnMousePressed(e -> System.out.println("Rectangle 2: " + e));
topLayer.getChildren().add(rectangle);
rectangle = new Rectangle( 200,200,50,50);
rectangle.setFill(Color.RED);
rectangle.setOnMousePressed(e -> System.out.println("Rectangle 3: " + e));
topLayer.getChildren().add(rectangle);
// layer 1 event handler
bottomLayer.setOnMousePressed(e -> System.out.println("Layer 1: " + e));
// layer 2 event handler
topLayer.setOnMousePressed(e -> System.out.println("Layer 2: " + e));
// this is the magic that allows you to click on the layer1 object event though layer 2 is on top of layer 1
// but ONLY(!) as long as the layer is transparent. if you add e. g. this it won't work anymore to click through to layer 1:
// layer2.setStyle( "-fx-background-color:yellow");
topLayer.setPickOnBounds(false);
primaryStage.setScene(new Scene(root, 800, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
另一个例子是将监听器添加到父级,e。 G。场景并像这样检查事件的目标:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class LayersWithMouseEvents2 extends Application {
@Override
public void start(Stage primaryStage) {
Rectangle rectangle = new Rectangle( 100,100,100,100);
rectangle.setFill(Color.GREEN);
HBox hBox = new HBox();
hBox.setPrefSize(200, 200);
hBox.setStyle("-fx-background-color:yellow");
hBox.getChildren().add( rectangle);
Group root = new Group();
root.getChildren().add(hBox);
primaryStage.setScene(new Scene(root, 800, 600));
primaryStage.show();
primaryStage.getScene().setOnMousePressed(e -> System.out.println("Scene: " + e));
}
public static void main(String[] args) {
launch(args);
}
}
取决于您点击的位置:
Scene: MouseEvent [source = javafx.scene.Scene@2c69fd61, target = javafx.scene.Scene@2c69fd61, eventType = MOUSE_PRESSED, consumed = false, x = 295.0, y = 134.0, z = 0.0, button = PRIMARY, primaryButtonDown, pickResult = PickResult [node = null, point = Point3D [x = 295.0, y = 134.0, z = 0.0], distance = 1119.6152422706632]
Scene: MouseEvent [source = javafx.scene.Scene@2c69fd61, target = HBox@5a40dda8, eventType = MOUSE_PRESSED, consumed = false, x = 148.0, y = 134.0, z = 0.0, button = PRIMARY, primaryButtonDown, pickResult = PickResult [node = HBox@5a40dda8, point = Point3D [x = 148.0, y = 134.0, z = 0.0], distance = 1119.6152422706632]
Scene: MouseEvent [source = javafx.scene.Scene@2c69fd61, target = Rectangle[x=100.0, y=100.0, width=100.0, height=100.0, fill=0x008000ff], eventType = MOUSE_PRESSED, consumed = false, x = 52.0, y = 54.0, z = 0.0, button = PRIMARY, primaryButtonDown, pickResult = PickResult [node = Rectangle[x=100.0, y=100.0, width=100.0, height=100.0, fill=0x008000ff], point = Point3D [x = 152.0, y = 154.0, z = 0.0], distance = 1119.6152422706632]
随着可见性的切换,它可能是这样的:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class LayersWithMouseEvents2 extends Application {
boolean hBoxVisible = true;
@Override
public void start(Stage primaryStage) {
Rectangle rectangle = new Rectangle( 100,100,100,100);
rectangle.setFill(Color.GREEN);
HBox hBox = new HBox();
hBox.setPrefSize(200, 200);
hBox.setStyle("-fx-background-color:yellow");
hBox.getChildren().add( rectangle);
Group root = new Group();
root.getChildren().add(hBox);
Scene scene = new Scene(root, 800, 600);
scene.setOnMousePressed(e -> {
System.out.println("Scene: " + e);
if( e.getTarget() == hBox) {
System.out.println( "HBox clicked");
}
if( e.getTarget() == rectangle) {
System.out.println( "Rectangle clicked");
}
if( e.getTarget() == scene) {
System.out.println( "Scene clicked");
hBoxVisible = !hBoxVisible;
hBox.setVisible(hBoxVisible);}
});
primaryStage.setScene( scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}