2014-11-07 3 views
0

CustomMenuItem을 확장하는 클래스가 있습니다. 이 MenuItem은 ContextMenu에 추가됩니다. 이제 CustomMenuItem의 오른쪽에서 X 좌표를 가져와야합니다.JavaFX CustomMenuItem의 오른쪽 좌표

문제는 어떻게 좌표를 얻을 수 있는지 잘 모르는 것입니다. CustMenuItem에는 getX() 또는 getY()와 같은 좌표를 가져 오는 함수가 없습니다.

그럼이 문제를 어떻게 해결할 수 있습니까? 내가 좋아하는 것

이 일이 얻을 :

enter image description here

는 여기서 우리는 상황에 맞는 메뉴 (레드 라인)에 대한 샘플을 볼 수 있습니다. 컨텍스트 메뉴에는 많은 다른 CustomMenuItems가 구현되어 있습니다. 이제 CustomMenuItem의 오른쪽 상단 좌표를 가져오고 싶습니다.

아주 좋은 도움에 감사드립니다.

+0

이전 답변을 편집했습니다. 다시 한번보십시오 –

답변

1

메뉴 항목을 다루기 전에 ContextMenu이 팝업 창이므로 Window 속성이 있음을 알리기 시작합니다. 왼쪽, 위쪽 원점 및 (w, h)에 대해 (x, y)를 요구할 수 있습니다.

하지만 기본적으로 그림자가 포함되어 있기 때문에 효과를 고려해야합니다. 그리고 그럴 때 오른쪽과 아래쪽에 24x24 픽셀의 추가 공간이 추가됩니다.

X=t.getX()+cm.getWidth()-12-24; 
Y=t.getY()+cm.getHeight()-(12-8)-24; 
:
.context-menu { 
    -fx-effect: dropshadow(gaussian , rgba(0,0,0,0.2) , 12, 0.0 , 0 , 8); 
} 

이 기본의 DropShadow는 12 픽셀의 반경을 가지며, 8px의 하단 Y는 오프셋 때문에

는 오른쪽 및 24x24 영역을 포함하는 컨텍스트 메뉴의 하단 좌표는,,으로 주어진다

여기서 t은 장면과 관련하여 MouseEvent 일 수 있으며 값은 단순화를 위해 하드 코드됩니다.

예를 들어 보겠습니다. 당신이 당신의 사용자 정의 메뉴 항목을 구현하는 방법을 말을하지 않기 때문에, 난 그냥있는 간단한 메뉴 항목을 만듭니다 그래픽 및 텍스트 :

private final Label labX = new Label("X: "); 
private final Label labY = new Label("Y: "); 

@Override 
public void start(Stage primaryStage) { 
    final ContextMenu cm = new ContextMenu(); 
    MenuItem cmItem1 = createMenuItem("mNext", "Next Long Option",t->System.out.println("next")); 
    MenuItem cmItem2 = createMenuItem("mBack", "Go Back", t->System.out.println("back")); 

    SeparatorMenuItem sm = new SeparatorMenuItem(); 
    cm.getItems().addAll(cmItem1,cmItem2); 

    VBox root = new VBox(10,labX,labY); 
    Scene scene = new Scene(root, 300, 250); 
    scene.setOnMouseClicked(t->{ 
     if(t.getButton()==MouseButton.SECONDARY || t.isControlDown()){ 
      // t.getX,Y->scene based coordinates 
      cm.show(scene.getWindow(),t.getX()+scene.getWindow().getX()+scene.getX(), 
             t.getY()+scene.getWindow().getY()+scene.getY()); 
      labX.setText("Right X: "+(t.getX()+cm.getWidth()-12-24)); 
      labY.setText("Bottom Y: "+(t.getY()+cm.getHeight()-4-24)); 
     } 
    }); 
    scene.getStylesheets().add(getClass().getResource("root.css").toExternalForm()); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    primaryStage.setTitle("Scene: "+scene.getWidth()+"x"+scene.getHeight()); 
} 

private MenuItem createMenuItem(String symbol, String text, EventHandler<ActionEvent> t){ 
    MenuItem m=new MenuItem(text); 
    StackPane g=new StackPane(); 
    g.setPrefSize(24, 24); 
    g.setId(symbol); 
    m.setGraphic(g); 
    m.setOnAction(t); 
    return m; 
} 

Custom context menu with effect

당신은 효과를 제거 할 경우 :

.context-menu { 
    -fx-effect: null; 
} 

는이 좌표는 다음과 같습니다 이제

X=t.getX()+cm.getWidth(); 
Y=t.getY()+cm.getHeight(); 

우리가 창을 가지고, 가자 항목에 넣습니다.

MenuItem 피부는 (그래픽)과 텍스트가 배치 된 Region 인 (개인) ContextMenuContent.MenuItemContainer 클래스에서 파생됩니다.

가 컨텍스트 메뉴를 빌드 할 때, 모든 항목이 VBox에 싸여 있으며, 당신이 항목에 대한 경계를 설정하면 당신이 볼 수있는 모두가 동등하게, 크기가 조정됩니다

.menu-item { 
    -fx-border-color: black; 
    -fx-border-width: 1; 
} 

이 어떻게입니다 기본적으로 (

Custom context menu with borde

그래서 사용자 정의 컨텍스트 메뉴에있는 모든 항목의 X 좌표는 부모로부터 같은 X입니다 (또는 효과없이, 위 참조)을 뺀 패딩의 1 개 픽셀 :처럼 보이는). 당신은 또한 항목에 대한 치수를 얻기 위해 개인 방법을 통해 갈 수

참고 : 개인 API는 향후 변경 수 있기 때문에이 비록

ContextMenuContent cmc= (ContextMenuContent)cm.getSkin().getNode(); 
System.out.println("cmc: "+cmc.getItemsContainer().getBoundsInParent()); 

하지 않는 것이 좋습니다. 요청에 의해

EDIT

이 람다 및 CSS 제거 동일한 코드이다.

private final Label labX = new Label("X: "); 
private final Label labY = new Label("Y: "); 

@Override 
public void start(Stage primaryStage) { 
    final ContextMenu cm = new ContextMenu(); 
    MenuItem cmItem1 = createMenuItem("mNext", "Next Long Option",action); 
    MenuItem cmItem2 = createMenuItem("mBack", "Go Back", action); 
    SeparatorMenuItem sm = new SeparatorMenuItem(); 
    cm.getItems().addAll(cmItem1,cmItem2); 

    VBox root = new VBox(10,labX,labY); 
    Scene scene = new Scene(root, 300, 250); 
    scene.setOnMouseClicked(new EventHandler<MouseEvent>() { 

     @Override 
     public void handle(MouseEvent t) { 
      if(t.getButton()==MouseButton.SECONDARY || t.isControlDown()){ 
       // t.getX,Y->scene based coordinates 
       cm.show(scene.getWindow(),t.getX()+scene.getWindow().getX()+scene.getX(), 
         t.getY()+scene.getWindow().getY()+scene.getY()); 
       labX.setText("Right X: "+(t.getX()+cm.getWidth()-12-24)); 
       labY.setText("Bottom Y: "+(t.getY()+cm.getHeight()-4-24)); 
      } 
     } 
    }); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    primaryStage.setTitle("Scene: "+scene.getWidth()+"x"+scene.getHeight()); 
} 

private MenuItem createMenuItem(String symbol, String text, EventHandler<ActionEvent> t){ 
    MenuItem m=new MenuItem(text); 
    StackPane g=new StackPane(); 
    g.setPrefSize(24, 24); 
    g.setId(symbol); 
    SVGPath svg = new SVGPath(); 
    svg.setContent("M0,5H2L4,8L8,0H10L5,10H3Z"); 
    m.setGraphic(svg); 
    m.setOnAction(t); 
    return m; 
} 

private final EventHandler<ActionEvent> action = new EventHandler<ActionEvent>() { 

    @Override 
    public void handle(ActionEvent event) { 
     System.out.println("action"); 
    } 
}; 
+0

@JosePerada 람다 식과 같은 CSS 및 Java 1.8 함수없이 예제를 구할 수 있습니까? –

+0

어떻게 Im을 다른 클래스에 넣을 수 있습니까? –

+0

마우스의 Y 위치는 어떻게 얻을 수 있습니까? –