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.
Qualunque buona ragione per cui vuoi farlo? Tutte le barre dei menu di tutte le applicazioni si comportano allo stesso modo – Robin
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