2016-01-17 115 views
0

JavaFx:我在組中有一個帶有Button的HBox,並且我想爲每個節點管理「MousePressed」事件。 目前,如果我處理所有節點的相同事件,它總是會被父節點(組)捕獲。JavaFx:檢查鼠標是否在節點的子節點上

有沒有辦法做到這一點? 例如,有沒有一種方法可以確定鼠標座標是否在節點的子節點(在我的例子中是HBox)?

這是什麼,我需要一個例子:

enter image description here

如果我點擊組我想隱藏HBox中,如果鼠標的座標不與HBox中發生碰撞,如果我點擊HBox中,Hbox不需要隱藏,如果我點擊按鈕(作爲ImageView實現),我需要執行代碼而不隱藏HBox。

因此,例如,我希望做的是這樣的事情:

' 
Group group= new Group(); 
HBox hBox = new HBox(); 
ImageView image= new ImageView(); 
hBox.getChildren().add(image); 
hBox.toFront(); 
group.getChildren().add(hBox); 
image.setImage(ImageUtil.getImage("img.png")); 
group.setOnMousePressed(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent mouseEvent) { 
         <if not collide with HBOX hide HBOX.> 

        } 
       }); 
box.setOnMousePressed(new EventHandler<MouseEvent>() { 
        @Override 
        public void handle(MouseEvent mouseEvent) { 
         <do other things without hidding HBOX.> 

        } 
       }); 



image.onMouseClickedProperty().set(new EventHandler<MouseEvent>() { 
           @Override 
           public void handle(MouseEvent mouseEvent) { 
     <do something> 
            } 

          }); 

' 其中組設計有sceneBuilder 的AncorPane內'

@FXML 
Group group; 

'

感謝您的幫助。

+0

剛向每個子節點註冊不同的處理程序。也許這將有助於發佈一些代碼。 –

+0

我已經爲父母(組)和一個爲孩子(HBox)註冊了兩個處理程序,問題是所有東西都被第一個(一個鏈接到組)所捕獲...... – navy1978

+0

發佈[MCVE]。沒有代碼示例就很難(也許不可能)知道發生了什麼問題。 –

回答

2

你的問題還不清楚,但nontheless,如果它可以幫助你:

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 = [email protected], target = [email protected], 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 = [email protected], target = [email protected], eventType = MOUSE_PRESSED, consumed = false, x = 148.0, y = 134.0, z = 0.0, button = PRIMARY, primaryButtonDown, pickResult = PickResult [node = [email protected], point = Point3D [x = 148.0, y = 134.0, z = 0.0], distance = 1119.6152422706632] 
Scene: MouseEvent [source = [email protected], 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); 
    } 
} 
+0

謝謝你的回答但是這不是我所需要的我已經更新了我的問題並添加了我需要的示例.. – navy1978

+0

我更新了答案。 – Roland

+0

@ navy1978這就是爲什麼需要SSCCE的原因:沒有,這是一個猜測你想要達到什麼的程度,以及你的代碼出錯的程度。請注意,它**總是**可能提供這樣一個例子,剝離到最低限度,這表明一個問題! – kleopatra