繁体   English   中英

如何在Java Swing工具栏中创建“下拉”菜单?

[英]How can I create a “Drop-Down” menu in a Java Swing toolbar?

我在Swing JToolBar上创建了一个下拉菜单。 但它并没有按照我想要的方式创造行为。 我的目标是像Firefox的“智能书签”按钮一样工作。

当用户选择菜单项时,它会消失:正确!

当用户按下ESC时,它会消失:CORRECT!

当用户点击菜单外的主框架中的某处时,它会消失:正确!

但是当用户第二次点击显示下拉菜单的按钮时,它不会消失:INCORRECT ... :-(

我的问题是如何添加这种行为,当点击第二次显示菜单的按钮时,它确实消失了。

这是我目前的代码,来自Mac上的Java 6:

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

public class ScratchSpace {

    public static void main(String[] arguments) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Toolbar with Popup Menu demo");

                final JToolBar toolBar = new JToolBar();
                toolBar.add(createMoreButton());

                final JPanel panel = new JPanel(new BorderLayout());
                panel.add(toolBar, BorderLayout.NORTH);
                panel.setPreferredSize(new Dimension(600, 400));
                frame.getContentPane().add(panel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private static AbstractButton createMoreButton() {
        final JToggleButton moreButton = new JToggleButton("More...");
        moreButton.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    createAndShowMenu((JComponent) e.getSource(), moreButton);
                }
            }
        });
        moreButton.setFocusable(false);
        moreButton.setHorizontalTextPosition(SwingConstants.LEADING);
        return moreButton;
    }

    private static void createAndShowMenu(final JComponent component, final AbstractButton moreButton) {
        JPopupMenu menu = new JPopupMenu();
        menu.add(new JMenuItem("Black"));
        menu.add(new JMenuItem("Red"));

        menu.addPopupMenuListener(new PopupMenuListener() {
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }

            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                moreButton.setSelected(false);
            }

            public void popupMenuCanceled(PopupMenuEvent e) {
                moreButton.setSelected(false);
            }
        });

        menu.show(component, 0, component.getHeight());
    }
}

嗯,这是一个潜在的解决方案,并非没有它的缺点。 只有您可以决定这是否适用于您的应用程序。 问题是弹出关闭发生在其他鼠标处理事件被触发之前,因此再次点击你的更多..按钮会导致弹出窗口隐藏,从而重置按钮状态以便在按钮被告知被按下之前取消选择。

简单的解决方法是在主程序中添加以下调用:

UIManager.put("PopupMenu.consumeEventOnClose", Boolean.TRUE);

结果是,每当弹出菜单因鼠标按下事件而关闭时,该菜单关闭时将消耗该鼠标事件,并且不会将鼠标事件传递给鼠标下的任何其他组件。 如果你能忍受限制,这是一个简单的解决方案。

发生的事情是,当您单击菜单时,它取消弹出菜单,因此您取消选择按钮,但下一个立即事件是单击按钮,现在取消选择它,以便再次显示菜单。

我还没有确切的解决方案,但请给我一点......

我不使用Firefox,因此我不知道智能书签按钮的样子,但可能使用JMenu作为“按钮”。 您可以尝试使用JButton的边框使其看起来更像一个按钮。

好吧,按钮上的监听器只有在按下它时才会作出反应,因为你只监听ItemEvent.SELECTED事件。 如何添加另一个if子句来监听ItemEvent.DESELECTED事件:

    moreButton.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                createAndShowMenu((JComponent) e.getSource(), moreButton);
            }
        }
    });

你既可以存储到一个参考menu的地方, 或者你可以让菜单本身添加其他监听器按钮。 后一种解决方案可能更简单,因为您似乎已经向菜单发送了一个按钮引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM