2010-03-16 13 views
5

Stavo cercando di far funzionare un JMenu come un JButton ma ho qualche problema e spero che qualcuno qui possa aiutarti!Come fare un JMenu ha un comportamento Button in una JMenuBar

Ho aggiunto un MenuListener all'elemento JMenu con questo, ma non posso ottenere il menu popup/focus da lasciare per permettermi di fare correttamente clic sui tempi ripetuti di JMenu per attivare questa funzione e speravo che qualcuno potesse dirmi cosa sto sbagliando Grazie.

+0

io non sono sicuro di capire cosa si sta cercando di realizzare qui. Perché vuoi la JMenu di agire come un pulsante, invece di semplicemente usando JMenuItem? –

+0

Forse fornisci più del codice sorgente con cui stai lavorando, quindi possiamo vedere più in generale ciò che stai cercando di ottenere. –

risposta

8
Non

completamente sicuro di quello che stai chiedendo ...

Ma JMenuBar eredita da Container - se si preferisce aggiungere una JButton ad esso che un JMenu si può semplicemente chiamare -

JMenuBar menuBar = .... 
JButton myButton = .... 
menuBar.add(myButton); 
+0

Ahhhh non sapevo che potresti aggiungere un JButton a una JMenuBar ... Grazie mille – Kurru

+0

ma funziona su MAC OS X? – user584397

+3

il pulsante sembra diverso da un JMenu. –

1

Questo esempio di codice viene eseguito in eclissi, Ancora preoccupato di come lo si utilizza?

public class MyMenuFrame extends JFrame { 


    public MyMenuFrame() throws HeadlessException { 
     super("My Frame"); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setSize(400, 300); 
     Container pane = this.getContentPane(); 
     pane.setLayout(new BorderLayout()); 
     pane.add(new JLabel("Hi there"), BorderLayout.PAGE_START); 
     this.setVisible(true); 
     JMenuBar menubar = new JMenuBar(); 
     JMenu menu = new JMenu("File"); 

     menu.addMenuListener(new MenuListener() { 

      @Override 
      public void menuSelected(MenuEvent e) { 
       System.out.println("a"); 

      } 

      @Override 
      public void menuDeselected(MenuEvent e) { 
       System.out.println("a"); 

      } 

      @Override 
      public void menuCanceled(MenuEvent e) { 
       System.out.println("a"); 

      } 
     }); 
     menubar.add(menu); 
     this.setJMenuBar(menubar); 
    } 

    public static void main(String[] args) { 
     new MyMenuFrame(); 
    } 
} 
0

È molto difficile determinare cosa stai cercando di fare qui. Ma non penso che tu stia usando correttamente JMenu.

Un JMenu è l'oggetto che rappresenta un Menu. È separato dalla barra dei menu (JMenuBar) e dalla voce di menu (JMenuItem). Una JMenuBar di solito contiene più JMenus (File, Modifica, ecc.) Che a loro volta contengono più JMenuItems (Nuovo, Aperto, Chiudi). I JMenuItem sono ciò che viene cliccato e "agisce come un pulsante" nel menu.

Per ottenere una voce di menu che funzioni come un pulsante, è sufficiente aggiungerla al menu. Per esempio:

JMenu fileMenu = new JMenu("File"); 
JMenuItem newChoice = new JMenuItem("New"); 
newChoice.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     newHasBeenSelected(); 
    } 
}); 
fileMenu.add(newChoice); 

Se stai cercando di creare un menu pop-up, è necessario utilizzare JPopupMenu invece di JMenu, e non hai bisogno di un JMenuBar. Qui ci sono i tutorial Java sul menu: http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html

E qui sono la documentazione Java per JMenuBar, JMenu, JPopupMenu e JMenuItem.

Se si modifica la domanda e si fornisce una spiegazione più dettagliata di ciò che si sta facendo, potrei essere in grado di fornire un aiuto più specifico.

1

So che questo è un thread vecchio, ma penso che potrei avere una soluzione. Sono incappato in questo problema in una delle mie app e ho trovato una soluzione alternativa. Prova a utilizzare un oggetto JMenu invece di un JMenu. Avrà lo stesso L & F come JMenu quando lo si collega a una JMenuBar. L'unica cosa che dovete fare è impostare la dimensione del vostro nuovo "bottone", come gestore di layout (anche se non è stato impostato uno) si ridimensiona il componente in base alle proprie regole:

http://www.javaworld.com/javaworld/jw-09-2000/jw-0922-javatraps.html

Il modo per farlo si trova sotto quel link (se ti senti a disagio cliccando sul link, google per "setsize doesnt work" - sarà tra i primi dieci risultati). Se non si imposta correttamente la dimensione, il nuovo "pulsante" riempirà lo spazio rimanente della JMenuBar.

provare questo codice:

menuItem.setMinimumSize(someMenu.getSize()); 
menuItem.setPreferredSize(someMenu.getSize()); 
menuItem.setMaximumSize(someMenu.getSize()); 
menuItem.setActionCommand("ActionText"); 

setActionCommand() metodo imposterà un comando di azione, in modo che quando si fa clic con il nuovo "bottone" questo sarà il comando di azione approvato dal l'argomento evento azione per l'azione metodo eseguito, in modo da poter facilmente identificarlo:

public void actionPerformed(ActionEvent e) { 
    System.out.println(e.getActionCommand()); 
} 

Spero che questo aiuti!

0

Ok ho deciso di indagare un po 'di più e il seguente è il reslut e sembra agire proprio come un JButton ma appare come un jmenu su una jmenubar. Codice sotto. (si noti che l'aggiunta di un actionListener a un JMenu non ha funzionato correttamente quale è la ragione per il mouselistener. Si aggiunge un actionListener al menu stesso proprio come un normale pulsante e finché non si aggiunge alcun menu al menú (tecnicamente si potrebbe) apparirà come un JMenu sul JMenuBar ma comportarsi come un pulsante.

import java.awt.Component; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.lang.reflect.Method; 
import java.util.EventListener; 
import javax.swing.ImageIcon; 
import javax.swing.JMenu; 

public class MenuButton extends JMenu { 

private boolean startedIn = false; 
private ActionListener action; 

public MenuButton(String title) { 
    super(title); 
    removeListeners(this); 
    this.addMouseListener(new MenuButtonListener()); 

} 

public MenuButton(ImageIcon icon) { 
    super(); 
    removeListeners(this); 
    this.addMouseListener(new MenuButtonListener()); 
    this.setIcon(icon); 
} 

public void addActionListener(ActionListener a) { 
    action = a; 
} 
    //we need to remove all the listeners already associated with a JMenu. If we do 
//not do this, then it will not behave as expected because some mouseclicks are eaten 
//by these listeners. There is no easy way to do that, the following method is a 
//workaroundprovided in the java bug database. 
static private void removeListeners(Component comp) { 
    Method[] methods = comp.getClass().getMethods(); 
    for (int i = 0; i < methods.length; i++) { 
     Method method = methods[i]; 
     String name = method.getName(); 
     if (name.startsWith("remove") && name.endsWith("Listener")) { 

      Class[] params = method.getParameterTypes(); 
      if (params.length == 1) { 
       EventListener[] listeners = null; 
       try { 
        listeners = comp.getListeners(params[0]); 
       } catch (Exception e) { 
        // It is possible that someone could create a listener 
        // that doesn't extend from EventListener. If so, ignore 
        // it 
        System.out.println("Listener " + params[0] 
          + " does not extend EventListener"); 
        continue; 
       } 
       for (int j = 0; j < listeners.length; j++) { 
        try { 
         method.invoke(comp, new Object[] { listeners[j] }); 
         // System.out.println("removed Listener " + name + 
         // " for comp " + comp + "\n"); 
        } catch (Exception e) { 
         System.out 
           .println("Cannot invoke removeListener method " 
             + e); 
         // Continue on. The reason for removing all 
         // listeners is to 
         // make sure that we don't have a listener holding 
         // on to something 
         // which will keep it from being garbage collected. 
         // We want to 
         // continue freeing listeners to make sure we can 
         // free as much 
         // memory has possible 
        } 
       } 
      } else { 
       // The only Listener method that I know of that has more 
       // than 
       // one argument is removePropertyChangeListener. If it is 
       // something other than that, flag it and move on. 
       if (!name.equals("removePropertyChangeListener")) 
        System.out.println(" Wrong number of Args " + name); 
      } 
     } 
    } 
} 

public class MenuButtonListener extends MouseAdapter { 

    boolean within = false; 
    boolean pressed = false; 


    public void mousePressed(MouseEvent e) { 
     MenuButton.this.setSelected(true); 
     pressed = true; 
     //System.out.println("pressed"); 
    } 

    public void mouseReleased(MouseEvent e) { 
     //System.out.println("released"); 
     MenuButton.this.setSelected(false); 
     if (action != null && within && pressed) { 
      action.actionPerformed(new ActionEvent(this, 
        ActionEvent.ACTION_PERFORMED, null)); 
      MenuButton.this.setSelected(false); 
     } 
     pressed = false; 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
     within = true; 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
     within = false; 
    } 
} 
} 
Problemi correlati