Pergunta

Eu estava tentando fazer com que um jmenu se comportasse como um jbutton, mas estou tendo alguns problemas e espero que alguém aqui possa ajudar!

Eu adicionei um menulistener ao item Jmenu com isso, mas não consigo obter o menu/foco pop -up para deixar para me permitir clicar adequadamente nos tempos repetidos do JMENU para acionar essa função e eu esperava que alguém pudesse me dizer o que estou fazendo errado. Obrigado.

public void menuSelected(MenuEvent e)
        {
            ... // do stuff here code
            JMenu source = (JMenu)e.getSource();
            source.setSelected(false);
            source.setPopupMenuVisible(false);

        }
Foi útil?

Solução

Não tenho certeza completamente do que você está perguntando ...

Mas JMenuBar herda de Container - se você preferir adicionar um JButton para isso do que um JMenu você pode simplesmente ligar -

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

Outras dicas

Esta amostra de código é executada no Eclipse, novamente preocupada com a forma como você o está usando?

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

Eu sei que este é um tópico antigo, mas acho que posso ter uma solução. Eu tropecei em acumular esse problema em um dos meus aplicativos e encontrei uma solução alternativa. Tente usar um jmenuitem em vez de um jmenu. Ele terá o mesmo L&F que um jmenu quando você o anexar a um jmenubar. A única coisa que você precisa fazer é definir o tamanho do seu novo "botão", pois seu gerenciador de layout (mesmo que você não tenha definido um) redimensione esse componente com base em suas próprias regras:

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

A maneira de fazer isso é encontrada nesse link (se você se sentir desconfortável ao clicar no link, o Google para "SetSize não funciona" - será o dos dez melhores resultados). Se você não definir o tamanho corretamente, seu novo "botão" preencherá o espaço restante do seu jmenubar.

Experimente este código:

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

O método SetActionCommand () definirá um comando de ação, para que, quando você clicar no seu novo "Button", este será o comando de ação passado pelo argumento do evento de ação para o método executado pela ação, para que você possa identificá -lo facilmente:

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

Espero que isto ajude!

É muito difícil determinar o que você está tentando fazer aqui. Mas não acho que você esteja usando o JMENU corretamente.

Um jmenu é o objeto que representa um menu. É separado da barra de menus (jmenubar) e do item de menu (jmenuitem). Um jmenubar geralmente contém vários jmenus (arquivo, edição etc.), que por sua vez contêm vários jmenuitems (novo, aberto, fechado). Os jmenuitems são o que é clicado e "age como um botão" no menu.

Para obter um item de menu para agir como um botão, basta adicioná -lo ao menu. Por exemplo:

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

Se você está tentando criar um menu pop-up, precisará usar o JPOPUPMENU em vez do JMENU e não precisa de um jmenubar. Aqui estão os tutoriais de Java sobre menus: http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html

E aqui estão os documentos Java para Jmenubar, Jmenu, JPOPUPMENU, e Jmenuitem.

Se você editar sua pergunta e fornecer uma explicação mais detalhada do que você está fazendo, eu poderá dar uma ajuda mais específica.

Ok, decidi investigar um pouco mais e o seguinte é o Reslut e parece agir como um jbutton, mas parece um jmenu em um jmenubar. Código abaixo. (Observe apenas adicionar um Listener de ação a um jmenu não funcionou corretamente, qual é a razão do MouseListener. Você adiciona um Listener de ação ao Menubutton, como um botão normal e, desde que não adicione menuitems ao Menubutton (que tecnicamente você poderia) Ele aparecerá como um jmenu no jmenubar, mas se comportará como um botão.

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;
    }
}
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top