2013-12-17 8 views
10

Sono novizio su javafx. Voglio mostrare il menu popup sul clic destro del mouse. Trovo un tutorial Here e Here ma non capisco. Voglio creare menu popup che mostrano in immagine su questo link.Come creare menu popup

In questo momento sto creando un palcoscenico ma non voglio lo stage. Ho bisogno di mostrare menu popup che mostrano con il tasto destro del mouse e chiudi quando clicco ovunque.

Ecco il mio codice in cui sto usando stage ma ho bisogno di ope menu popup come sopra link.

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(); 

    } 

Si prega di fornire qualsiasi link o riferimento.

risposta

20

Il contesto del codice non è molto chiaro: si tratta di un gestore di eventi? Se sì, per cosa è un gestore di eventi? In caso contrario, che cos'è event nell'istruzione if di apertura?

I due collegamenti forniti sono piuttosto complessi; in JavaFX (a differenza di Swing) si dovrebbe prendere in considerazione solo la sottoclasse delle classi di nodi esistenti per casi d'uso piuttosto avanzati. Non hai bisogno di questo livello di complessità solo per creare un menu popup.

Il modo più semplice per creare un menu popup è per un Control (o sottoclasse); hai solo bisogno di creare un ContextMenu, aggiungere MenuItem s ad esso, e impostarlo come contextMenu sul vostro controllo:

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); 

Se si desidera utilizzare un ContextMenu su un nodo che non è un Control (un Pane o un Shape, per esempio), non si dispone di un metodo setContextMenu(...), quindi basta un po 'di lavoro:

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()); 
     } 
    } 
}); 

Vedere la Javadocs per ContextMenu o tutorial per maggiori dettagli.

+0

ma voglio mostrarlo su treeview. Voglio mostrare popup su Treeview quando faccio clic destro su treeview –

+0

io uso questo codice ma il popup non mostra 'contextMenu.show (soariteTree, event.getScreenX(), event.getScreenY()); ' –

+0

Scusa .. sta funzionando ora .... ho messo il codice di dichiarazione al di fuori dell'evento poi funziona; grazie ... –

10

James_D ha già fornito un esempio di lavoro coerente con le esercitazioni, ma ho riscontrato dei problemi. James ha ragione nel dire che per qualsiasi Nodo di tipo Control il modo corretto per aprire il menu di scelta rapida è usare Control.setContextMenu(). Tuttavia in contrasto con il tutorial il modo corretto per registrare un menu di contesto sui non di controllo nodi è la seguente (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(); 
    }); 

Ciò è coerente con la cosa setContextMenu fa dietro le quinte. L'implementazione setContextMenu per Controls utilizza e consuma ContextMenuEvent ma lo non consuma l'evento del mouse. Ciò significa che se si registra un listener per MouseEvent su un riquadro e si utilizza setContextMenu su un controllo all'interno del riquadro, un clic con il pulsante destro del controllo aprirà effettivamente entrambi i menu di scelta rapida: il controllo attenderà e consumerà ContextMenuEvent mentre il pannello ascolta e consuma MouseEvent. Ho trovato nel mio codice con openjdk-8 che la registrazione di un listener ContextMenuEvent sul pannello ha risolto questo problema del menu contestuale duplicato.

Inoltre, ho riscontrato che un menu registrato su un riquadro non viene disattivato per impostazione predefinita quando l'utente fa clic altrove. Il listener MOUSE_PRESSED che non consuma il suo evento garantisce che il menu venga ignorato quando dovrebbe essere.

+0

cos'è il pannello in contextMenu.show (riquadro ....); –

+0

Questa è in realtà la soluzione corretta. Peccato che tu non sia più in alto .. –

+0

c'è anche un metodo setOnContextMenuRequested() nel nodo –