2014-07-07 2 views
19

두 개의 레이어 (= AnchorPanes) 중 하나를 다른 하나를 StackPane으로 쌓았습니다. 그래서 두 레이어가 전체 장면을 채 웁니다. 문제는 최상위 레이어 만 마우스 이벤트를 수신한다는 것입니다. 장면이 빌드가 얼마나기본 레이어에서 마우스 이벤트가 무시됩니다.

그게 전부 :

Layout of the Scene

만 버튼 B 이벤트하지만 버튼 A를하지 클릭 받는다. 내가 투명 마우스 (layerB.setMouseTransparent(true))에 레이어 B를 설정하면

Button A don't Receive Click Events

는 버튼 A는 마우스 이벤트를 수신합니다. 그러나 마우스 투명한 효과도 모든 자식에게 적용되므로 버튼 B는 더 이상 마우스 이벤트를받지 못합니다.

마우스 이벤트를 수신하기 위해 버튼 A와 버튼 B를 얻는 방법은 무엇입니까?

public class LayerTest extends Application { 
    @Override 
    public void start(final Stage primaryStage) throws Exception { 
     final Node layerA = createLayerA(); 
     final Node layerB = createLayerB(); 
     final Parent root = new StackPane(layerA, layerB); 
     final Scene scene = new Scene(root); 
     primaryStage.setScene(scene); 
     primaryStage.setWidth(250); 
     primaryStage.setHeight(200); 
     primaryStage.show(); 
    } 

    private Node createLayerA() { 
     final AnchorPane layerA = new AnchorPane(); 
     final Button buttonA = new Button("Button A"); 
     AnchorPane.setLeftAnchor(buttonA, 10d); 
     AnchorPane.setTopAnchor(buttonA, 10d); 
     buttonA.setOnMouseClicked(e -> System.out.println("Button A clicked")); 
     layerA.getChildren().setAll(buttonA); 
     return layerA; 
    } 

    private Node createLayerB() { 
     final AnchorPane layerB = new AnchorPane(); 
     final Button buttonB = new Button("Button B"); 
     AnchorPane.setRightAnchor(buttonB, 10d); 
     AnchorPane.setBottomAnchor(buttonB, 10d); 
     buttonB.setOnMouseClicked(e -> System.out.println("Button B clicked")); 
     layerB.getChildren().setAll(buttonB); 
     return layerB; 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+1

[JavaFX 2의 기본 노드로의 이벤트 발송] (http://stackoverflow.com/questions/15248716/javafx-2-event-dispatching-to-underlying-nodes) 및 [JavaFx, 이벤트 차단/소비] (힌트는 http://stackoverflow.com/questions/19498867/javafx-event-interception-consumption)을 참조하십시오. 그러나 레이아웃 계층을 변경하는 것이 더 적절할 것입니다. 다른 모든 해결 방법은 hackish처럼 보일 것이고 앞으로 머리 속에서 머리를 숙여 다룰 것입니다. –

+0

@UlukBiy가 정확하며 레이아웃의 계층 구조를 변경해야합니다. 두 개를 사용하는 대신 하나의 앵커 패널을 사용해 볼 수도 있습니다. 유사한 문제가 [여기에 설명되어 있습니다] (http://stackoverflow.com/questions/24510845/stackpane-mouseclick-to-be-listened-by-both-its-children) – ItachiUchiha

답변

22

솔루션

은 샘플 코드에 다음 줄을 추가

layerB.setPickOnBounds(false); 

이 마우스는 당신이 당신의 스택 요소의 레이어를 통해 볼 수있는 눈에 보이는 요소와 상호 작용할 수 있습니다.

맨 위 레이어의 요소가 맨 아래 레이어의 요소와 겹치면 맨 아래 레이어와 겹치는 부분을 클릭하면 맨 위 레이어가 마우스 이벤트를 사용하고 맨 아래 레이어는 해당 레이어를 수신하지 않습니다 (아마 당신이 원하는 것).

다른 해석

당신은 실제로 다음 Uluk의 의견에서 링크 된 질문 참조 차단하고 모든 레이어에 마우스 이벤트를 처리하고 싶다면 :

메서드 설명 기

setPickOnBounds 방법의 설명 :

MouseEvent 트리거 또는 함수 호출을 포함하는 경우 피킹 연산이이 노드에 대해 수행되는 방법을 정의한다. pickOnBounds이 참이면이 노드의 경계와 교차하여 피킹이 계산되고, 그렇지 않으면이 노드의 기하학적 모양과 교차하여 피킹이 계산됩니다.


창]는 기본적으로 눈에 보이는 배경을 가지고, 그래서 왜 마우스 이벤트를 소비해야합니까?

JavaFX 8과 함께 제공되는 기본 스타일 시트 인 modena.css의 경우, 기본적으로 페인은 매우 희미하게 음영 처리 된 배경을 가지고있어서 마우스 이벤트를 소비 할 수 있습니다. 이를 방지하려면 창의 배경색을 널로 설정하거나 창을 mouseTransparent으로 설정하십시오.

이 동작은 JavaFX 2와 JavaFX 8 사이에서 변경되었습니다. JavaFX 2는 Panes에 대한 배경을 설정하지 않은 caspian.css라는 기본 스타일 시트와 함께 제공됩니다.

+0

자세한 답변 주셔서 감사합니다, 잘 작동합니다 :) Java Doc가 Node에 대해 말했기 때문에, 기본값을 false로 설정 했으므로, 자기 자신을 위해 bound를 선택하려고하지 않았습니다. 그러나 Region의 소스 코드를 살펴보면 기본적으로 true로 설정되어있는 것으로 나타났습니다. 레이아웃의 기본 값, 즉 이자형. 창은 거짓이어야합니다. 창에는 기본적으로 보이는 배경이 없으므로 마우스 이벤트를 사용해야하는 이유는 무엇입니까? – Vertex

+0

감사. pane의 상단 창 배경색을 null로 설정하고'topPane.setPickOnBounds (false);'잘 동작합니다 – c0der

1

이벤트 렸기 때문에이 캔트 작업이 LayerB에 의해 사로 잡았된다

여기에 전체 작업 소스입니다. 당신은 LayerB이

layerB.setMouseTransparent(true) 

을 MouseTransparent하지만 버튼의 b는 mousetranparent도이 후에는 것을 확실하지 메신저 설정할 수 있습니다.

다른 레이아웃에 대해 생각해보십시오.

+1

감사합니다! 네, 맞습니다. 이벤트는 LayerB에 의해 소비됩니다. 그러나'layerB.setMouseTransparent (true)'는 작동하지 않습니다. JavaDoc에 따르면이 방법은 자체 노드뿐만 아니라 자식 노드에도 영향을 미친다. ButtonB는 LayerB의 자식이기 때문에 ButtonB는 마우스 이벤트를 얻지 못합니다. – Vertex

관련 문제