2012-08-25 10 views
7

La JMenuBar non inizia a mostrare JMenuItem s come selezionato o visualizza i popup di JMenu fino a quando non viene cliccato per la prima volta. Dopo aver fatto clic da qualche parte su JMenuBar, tutti questi elementi rispondono al passaggio del mouse.Attivare JMenuBar al passaggio del mouse sul numero di telefono

Vorrei escludere il clic iniziale richiesto e farlo attivare automaticamente al passaggio del mouse. C'è un modo per fare questo?

+3

Qualunque buona ragione per cui vuoi farlo? Tutte le barre dei menu di tutte le applicazioni si comportano allo stesso modo – Robin

+0

Bene, il mio menu ha un aspetto personalizzato e questo comportamento si adatta in modo più naturale. Inoltre, credo che questo comportamento sia molto più interattivo per l'utente. – springcorn

risposta

9

Il modo è aggiungere MouseListener su JMenu e ascoltare gli eventi mouseEntered. Nei gestori di eventi, è sufficiente fare clic su di esso utilizzando doClick. Ad esempio,

jMenuFile.addMouseListener(new MouseListener(){ 
    public void mouseEntered(MouseEvent e) { 
     jMenuFile.doClick(); 
    } 
    ... 
}); 

Una volta che si è fatto clic con il mouse sul clic del mouse, si apre automaticamente il menu a comparsa. Per attivare un intero JMenuBar, è necessario aggiungere un listener su ogni JMenu. A tale scopo, è preferibile creare un oggetto listener separatamente.

ho due voci di menu sulla barra, così ho fatto:

MouseListener ml = new MouseListener(){ 
    public void mouseClicked(MouseEvent e) {} 
    public void mousePressed(MouseEvent e) {} 
    public void mouseReleased(MouseEvent e) {} 
    public void mouseExited(MouseEvent e) {} 
    public void mouseEntered(MouseEvent e) { 
     ((JMenu)e.getSource()).doClick(); 
    } 
    }; 
    jMenuFile.addMouseListener(ml); 
    jMenuHelp.addMouseListener(ml); 

Se si dispone di tante voci di menu sulla barra, si può semplicemente scorrere esso:

for (Component c: jMenuBar1.getComponents()) { 
    if (c instanceof JMenu){ 
     c.addMouseListener(ml); 
    } 
} 
+0

Ho capito il listener di mouseEntered ma come si attiva l'intera JMenuBar dal mousentered? – springcorn

+0

appena modificato sopra –

+0

Grazie. Questo mi ha messo sulla strada giusta, ma credo che speravo che esistesse un modo più semplice per fare questo come jMenuBar.activate(), piuttosto che forzare il clic singolarmente. Per JMenuItem non è possibile chiamare doClick() invece credo che il modo migliore per generare questo comportamento sia setArmed (true) – springcorn

1

Roman C di La risposta iniziale e accettata non sarà AUTO. Chiudi il menu con MenuItem figlio come parte di JMenuBar.

Esecuzione di un ((JMenu) e.getSource()). DoClick(); sul mouseEntered simula il clic in uno dei genitori di JMenu ma non può essere semplicemente aggiunto al metodo mouseExited in quanto MouseListener deve essere collegato al menu Menu secondario e ai genitori di JMenu. (Che non fa nella normale assegnazione al MenuBar - si collega solo agli oggetti JMenu principali).

Inoltre, si verifica un problema a causa del tentativo di far sì che il listener di MouseExit attivi un metodo di "chiusura" SOLO quando il mouse ha abbandonato l'intera struttura del menu (ad esempio i menu a discesa Bambini).

Qui di seguito è una risposta completamente funzionante preso da mia app dal vivo:

Il modo in cui ho risolto il menu stretta su fuori del mouse è stato quello di eseguire una variabile booleana "isMouseOut" nella parte superiore del costruttore per tenere traccia e quindi allocare MouseListener in un modo più OO friendly per tenere traccia degli eventi MouseIn-MouseOut multipli mentre un utente interagisce con il menu. Che chiama un metodo menuClear separato che agisce sullo stato del booleano "isMouseOut". La classe implementa MouseListener. Questo è come è fatto.

Creare un ArrayList aggiungendo prima tutte le voci di menu a questo array.In questo modo:

Font menuFont = new Font("Arial", Font.PLAIN, 12); 
    JMenuBar menuBar = new JMenuBar(); 
    getContentPane().add(menuBar, BorderLayout.NORTH); 

// Array of MenuItems 
    ArrayList<JMenuItem> aMenuItms = new ArrayList<JMenuItem>(); 
    JMenuItem mntmRefresh = new JMenuItem("Refresh"); 
    JMenuItem mntmNew = new JMenuItem("New"); 
    JMenuItem mntmNormal = new JMenuItem("Normal"); 
    JMenuItem mntmMax = new JMenuItem("Max"); 
    JMenuItem mntmStatus = new JMenuItem("Status"); 
    JMenuItem mntmFeedback = new JMenuItem("Send Feedback"); 
    JMenuItem mntmEtsyTWebsite = new JMenuItem("EtsyT website"); 
    JMenuItem mntmAbout = new JMenuItem("About"); 

    aMenuItms.add(mntmRefresh); 
    aMenuItms.add(mntmNew); 
    aMenuItms.add(mntmNormal); 
    aMenuItms.add(mntmMax); 
    aMenuItms.add(mntmStatus); 
    aMenuItms.add(mntmFeedback); 
    aMenuItms.add(mntmEtsyTWebsite); 
    aMenuItms.add(mntmAbout); 

poi iterare ArrayList in questa fase l'aggiunta di un MouseListener utilizzando il for() ciclo:

for (Component c : aMenuItms) { 
     if (c instanceof JMenuItem) { 
      c.addMouseListener(ml); 
     } 
    } 

ora impostato genitori JMenu per il MenuBar:

// Now set JMenu parents on MenuBar 
    final JMenu mnFile = new JMenu("File"); 
    menuBar.add(mnFile).setFont(menuFont); 
    final JMenu mnView = new JMenu("View"); 
    menuBar.add(mnView).setFont(menuFont); 
    final JMenu mnHelp = new JMenu("Help"); 
    menuBar.add(mnHelp).setFont(menuFont); 

Quindi aggiungi il menu a discesaItems children ai genitori di JMenu:

// Now set menuItems as children of JMenu parents 
    mnFile.add(mntmRefresh).setFont(menuFont); 
    mnFile.add(mntmNew).setFont(menuFont); 
    mnView.add(mntmNormal).setFont(menuFont); 
    mnView.add(mntmMax).setFont(menuFont); 
    mnHelp.add(mntmStatus).setFont(menuFont); 
    mnHelp.add(mntmFeedback).setFont(menuFont); 
    mnHelp.add(mntmEtsyTWebsite).setFont(menuFont); 
    mnHelp.add(mntmAbout).setFont(menuFont); 

Aggiungere le mouseListeners ai genitori JMenu come una fase separata:

for (Component c : menuBar.getComponents()) { 
     if (c instanceof JMenu) { 
      c.addMouseListener(ml); 
     } 
    } 

Ora che il bambino MENUITEM elementi tutti hanno i propri ascoltatori che sono separati da elementi del genitore JMenu e la barra dei menu - E 'importante identificare il tipo di oggetto all'interno dell'istanza MouseListener() in modo da ottenere l'apertura automatica del menu al passaggio del mouse (in questo esempio i genitori 3x JMenu) MA ANCHE evita errori di eccezioni figlio e consente l'identificazione pulita di mouseOUT della struttura del menu senza cercare di monitorare dove la posizione del mouse è Il MouseListener è la seguente:

MouseListener ml = new MouseListener() { 
     public void mouseClicked(MouseEvent e) { 
     } 

     public void mousePressed(MouseEvent e) { 
     } 

     public void mouseReleased(MouseEvent e) { 
     } 

     public void mouseExited(MouseEvent e) { 
      isMouseOut = true; 
      timerMenuClear(); 
     } 

     public void mouseEntered(MouseEvent e) { 
      isMouseOut = false; 
      Object eSource = e.getSource(); 
      if(eSource == mnHelp || eSource == mnView || eSource == mnFile){ 
       ((JMenu) eSource).doClick(); 
      } 
     } 
    }; 

È possibile che simula solo clic del mouse nella JMenu 'genitori' (3x in questo esempio) in quanto sono i trigger per menu di scorrimento del menu bambino. Il metodo timerMenuClear() invita il MenuSelectionManager per svuotare qualsiasi punto SelectedPath era dal vivo al momento della vera mouseOut:

public void timerMenuClear(){ 
    ActionListener task = new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      if(isMouseOut == true){ 
       System.out.println("Timer"); 
      MenuSelectionManager.defaultManager().clearSelectedPath(); 
      } 
     } 
    };   
    //Delay timer half a second to ensure real mouseOUT 
    Timer timer = new Timer(1000, task); 
    timer.setInitialDelay(500);   
    timer.setRepeats(false); 
    timer.start(); 
} 

Mi c'è voluto un po 'di test, il monitoraggio quali valori ho potuto accedere all'interno della JVM durante il suo sviluppo - ma funziona a meraviglia! anche con i menu annidati :) Spero che molti trovino questo esempio completo molto utile.