메뉴 항목을 다루기 전에 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;
}
당신은 효과를 제거 할 경우 :
.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;
}
이 어떻게입니다 기본적으로 (
그래서 사용자 정의 컨텍스트 메뉴에있는 모든 항목의 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");
}
};
이전 답변을 편집했습니다. 다시 한번보십시오 –