2013-12-17 88 views
10

我是javafx上的新手。我想在右鍵單擊上顯示彈出式菜單。我找到一個教程HereHere,但不明白。我想創建彈出式菜單,在這個鏈接上顯示圖像。如何創建彈出菜單

現在我正在創造舞臺,但我不想要舞臺。我需要顯示右鍵單擊時顯示的彈出菜單,當我點擊任何地方時關閉。

這是我在其中使用舞臺的代碼,但我需要打開像上面的鏈接彈出菜單。

public void MouseClickedOnTree(MouseEvent event) { 
if (event.isSecondaryButtonDown()) { 

     System.out.println("secondary press"); 
     final Stage optionstage = new Stage(); 

     VBox vBox = new VBox(5); 
     vBox.setMinHeight(50); 
     vBox.setMinWidth(50); 
     Button btnNewTestBed = new Button("New Testbed"); 
     btnNewTestBed.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       try { 
        optionstage.close(); 
        stage.show(); 
       } catch (IOException ex) { 
        Exceptions.printStackTrace(ex); 
       } 
      } 
     }); 
     Button btnOpenTestbed = new Button("Open Testbed"); 
     btnOpenTestbed.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       optionstage.close(); 

      } 
     }); 
     optionstage.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { 
      @Override 
      public void handle(KeyEvent t) { 
       if (t.getCode() == KeyCode.ESCAPE) { 
        System.out.println("click on escape"); 
        //Stage sb = (Stage) label.getScene().getWindow();//use any one object 
        if(optionstage.isShowing()) 
         optionstage.close(); 
       } 
      } 
     }); 

     vBox.getChildren().addAll(btnNewTestBed, btnOpenTestbed); 
     optionstage.setScene(new Scene(vBox, 100, 100)); 
     //stage.setScene(new Scene(new Group(new Text(50,50, "my second window")))); 
     optionstage.setX(event.getSceneX()); 
     optionstage.setY(event.getScreenY()); 
     optionstage.initStyle(StageStyle.UNDECORATED); 
     optionstage.show(); 

    } 

請給我提供任何鏈接或參考。

回答

20

你的代碼的上下文不是很清楚:這是在一個事件處理程序中嗎?如果是這樣,它是一個事件處理程序是什麼?如果不是,event在開頭if聲明中是什麼?

您提供的兩個鏈接非常複雜;在JavaFX中(與Swing不同),您應該只考慮對現有Node類進行子類化以獲得相當高級的用例。您只需創建一個彈出菜單就不需要這種複雜程度。

創建彈出式菜單的最簡單方法是使用Control(或其子類)。你只需要創建一個ContextMenu,加MenuItem s到它,並將它設置爲contextMenu在你的控制:

TextField textField = new TextField("Type Something"); // we will add a popup menu to this text field 
final ContextMenu contextMenu = new ContextMenu(); 
MenuItem cut = new MenuItem("Cut"); 
MenuItem copy = new MenuItem("Copy"); 
MenuItem paste = new MenuItem("Paste"); 
contextMenu.getItems().addAll(cut, copy, paste); 
cut.setOnAction(new EventHandler<ActionEvent>() { 
    @Override 
    public void handle(ActionEvent event) { 
     System.out.println("Cut..."); 
    } 
}); 
// ... 
textField.setContextMenu(contextMenu); 

如果你想在節點上,是不是一個Control(一Pane或使用ContextMenu一個Shape,例如),你沒有setContextMenu(...)方法,所以你只需要多一點的工作:

final AnchorPane pane = new AnchorPane(); 
// fill pane with nodes, etc 
// create context menu and menu items as above 
pane.setOnMousePressed(new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent event) { 
     if (event.isSecondaryButtonDown()) { 
      contextMenu.show(pane, event.getScreenX(), event.getScreenY()); 
     } 
    } 
}); 

JavadocsContextMenututorial瞭解更多詳情。

+0

但我想在treeview中顯示它。我想顯示樹形視圖彈出時,我右鍵點擊treeview –

+0

我使用此代碼,但彈出不顯示'contextMenu.show(soariteTree,事件。getScreenX(),event.getScreenY());' –

+0

對不起..它現在工作....我把事件的外部聲明代碼然後它的工作...謝謝.. –

10

James_D已經提供了一個與教程一致的工作示例,但我遇到了問題。 James對於任何類型的Node節點來說都是正確的,打開上下文菜單的正確方法是使用Control.setContextMenu()。然而出乎教程註冊在非控制節點的上下文菜單如下(Java的8)的正確方法:

pane.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event -> { 
     contextMenu.show(pane, event.getScreenX(), event.getScreenY()); 
     event.consume(); 
    }); 
    pane.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> { 
     contextMenu.hide(); 
    }); 

這是一致的setContextMenu做幕後的東西。控件的setContextMenu實現使用並消耗ContextMenuEvent,但而不是消耗鼠標事件。這意味着如果你在一個Pane上爲MouseEvent註冊一個監聽器,並在Pane上的一個Control上使用setContextMenu,那麼右鍵單擊該控件將實際上打開兩個上下文菜單:當Pane監聽時,Control將監聽並使用ContextMenuEvent並使用MouseEvent。我在openjdk-8的代碼中發現,在Pane上註冊ContextMenuEvent監聽器可以解決這個重複的上下文菜單問題。

我還發現,當用戶在其他地方點擊時,在窗格上註冊的菜單在默認情況下不會消失。不消耗事件的MOUSE_PRESSED監聽器確保菜單在應該時被解除。

+0

什麼是contextMenu.show中的窗格(窗格....); –

+0

這實際上是正確的解決方案。太糟糕了,你沒有更高.. –

+0

在Node中還有一個setOnContextMenuRequested()方法 –