7

我试图让 JMenu 表现得像 JButton 但我遇到了一些问题,希望这里有人可以提供帮助!

我已经向 JMenu 项目添加了一个 MenuListener ,但我无法让弹出菜单/焦点离开以使我能够正确单击 JMenu 重复多次以触发此功能,我希望有人能告诉我我在做什么错误的。谢谢。

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

        }
4

5 回答 5

10

不完全确定你在问什么......

但是JMenuBar继承自Container- 如果你宁愿添加 aJButton而不是 aJMenu你可以简单地调用 -

JMenuBar menuBar = ....
JButton myButton = ....
menuBar.add(myButton);
于 2010-03-16T17:26:16.713 回答
1

此代码示例在eclipse中运行,再次关心你是如何使用它的?

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();
    }
}
于 2010-03-16T17:24:09.197 回答
1

我知道这是一个旧线程,但我想我可能有一个解决方案。我在我的一个应用程序中偶然发现了这个问题,并找到了解决方法。尝试使用 JMenuItem 而不是 JMenu。当您将它附加到 JMenuBar 时,它将具有与 JMenu 相同的 L&F。您唯一需要做的就是设置新“按钮”的大小,因为您的布局管理器(即使您没有设置)将根据自己的规则调整此组件的大小:

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

可以在该链接下找到执行此操作的方法(如果单击该链接感到不舒服,请在 Google 上搜索“setsize doesn't work” - 这将是前十名的结果)。如果您没有正确设置大小,您的新“按钮”将填满 JMenuBar 的剩余空间。

试试这个代码:

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

setActionCommand() 方法将设置一个动作命令,这样当您单击新的“按钮”时,这将是动作事件参数传递给动作执行方法的动作命令,以便您可以轻松识别它:

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

希望这可以帮助!

于 2010-09-16T11:25:29.563 回答
0

很难确定您要在这里做什么。但我认为您没有正确使用 JMenu。

JMenu 是表示菜单的对象。它独立于菜单栏 (JMenuBar) 和菜单项 (JMenuItem)。一个 JMenuBar 通常包含多个 JMenu(文件、编辑等),这些 JMenuItem 又包含多个 JMenuItem(新建、打开、关闭)。JMenuItems 是在菜单中单击并“充当按钮”的内容。

要使菜单项像按钮一样,只需将其添加到菜单中即可。例如:

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

如果您尝试创建弹出菜单,则需要使用 JPopupMenu 而不是 JMenu,并且不需要 JMenuBar。以下是有关菜单的 Java 教程:http: //java.sun.com/docs/books/tutorial/uiswing/components/menu.html

这里是JMenuBarJMenuJPopupMenuJMenuItem的 Java 文档。

如果您编辑您的问题并更详细地解释您在做什么,我可能会提供更具体的帮助。

于 2010-03-16T17:27:00.440 回答
0

好的,我决定对此进行更多调查,以下是结果,看起来就像 JButton,但看起来像 jmenubar 上的 jmenu。代码如下。(请注意,只是将 actionListener 添加到 JMenu 不起作用,这就是 mouselistener 的原因。您将 actionListener 添加到 menubutton 就像普通按钮一样,只要您不向 menubutton 添加任何菜单项(从技术上讲,您可以)它将在 JMenuBar 上显示为 JMenu,但其行为类似于按钮。

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;
    }
}
}
于 2012-06-20T15:10:42.477 回答