简体   繁体   English

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

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

I've created a drop-down menu on my Swing JToolBar. 我在Swing JToolBar上创建了一个下拉菜单。 But it doesn't create behave the way I want. 但它并没有按照我想要的方式创造行为。 I'm aiming for it to work like Firefox's "Smart Bookmarks" button. 我的目标是像Firefox的“智能书签”按钮一样工作。

It disappears when the user selects a menu item: CORRECT! 当用户选择菜单项时,它会消失:正确!

It disappears when the user presses ESC: CORRECT! 当用户按下ESC时,它会消失:CORRECT!

It disappears when the user clicks somewhere in the main frame outside of the menu: CORRECT! 当用户点击菜单外的主框架中的某处时,它会消失:正确!

But it doesn't disappear when the user clicks a second time on the button that shows the drop-down menu: INCORRECT... :-( 但是当用户第二次点击显示下拉菜单的按钮时,它不会消失:INCORRECT ... :-(

My question is how can I add this behaviour, that it does disappear when the clicks on the button that shows the menu a second time. 我的问题是如何添加这种行为,当点击第二次显示菜单的按钮时,它确实消失了。

Here's my current code, from Java 6 on the Mac: 这是我目前的代码,来自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());
    }
}

Well, here is a potential solution that is not without it's drawbacks. 嗯,这是一个潜在的解决方案,并非没有它的缺点。 Only you can decide if this is acceptable for your application. 只有您可以决定这是否适用于您的应用程序。 The issue is that the popup closing occurs before other mouse-handling events are fired so clicking on your More.. button again causes the popup to hide, thus resetting the buttons state to deselected BEFORE the button even gets told it was pressed. 问题是弹出关闭发生在其他鼠标处理事件被触发之前,因此再次点击你的更多..按钮会导致弹出窗口隐藏,从而重置按钮状态以便在按钮被告知被按下之前取消选择。

The easy workaround is to add the following call within your main program: 简单的解决方法是在主程序中添加以下调用:

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

The result of this is that whenever a popup menu is closed because of a mouse-pressed event, that mouse event will be consumed at the time the menu is closed and won't be passed on to any other components under the mouse. 结果是,每当弹出菜单因鼠标按下事件而关闭时,该菜单关闭时将消耗该鼠标事件,并且不会将鼠标事件传递给鼠标下的任何其他组件。 If you can live with limitation, this is an easy solution. 如果你能忍受限制,这是一个简单的解决方案。

What's happening is that when you click off the menu, it cancels the popup menu, so you deselect the button, but the next immediate event is clicking the button, and now its deselected so it shows the menu again. 发生的事情是,当您单击菜单时,它取消弹出菜单,因此您取消选择按钮,但下一个立即事件是单击按钮,现在取消选择它,以便再次显示菜单。

I don't have the exact solution yet, but give me a little bit ... 我还没有确切的解决方案,但请给我一点......

I don't use Firefox so I don't know what the Smart Bookmarks button looks like, but maybe use a JMenu as the "button". 我不使用Firefox,因此我不知道智能书签按钮的样子,但可能使用JMenu作为“按钮”。 You could try using the Border of a JButton to make it look more like a button. 您可以尝试使用JButton的边框使其看起来更像一个按钮。

Well, the listener on the button reacts only when it is pushed down, because you listen for ItemEvent.SELECTED events only. 好吧,按钮上的监听器只有在按下它时才会作出反应,因为你只监听ItemEvent.SELECTED事件。 How about adding another if clause to listen for ItemEvent.DESELECTED events here: 如何添加另一个if子句来监听ItemEvent.DESELECTED事件:

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

You could either store a reference to the menu somewhere, or you could make the menu itself add another listener to the button. 你既可以存储到一个参考menu的地方, 或者你可以让菜单本身添加其他监听器按钮。 The latter solution could be more straightforward, since you already seem to send a button reference to the menu. 后一种解决方案可能更简单,因为您似乎已经向菜单发送了一个按钮引用。

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

相关问题 我如何在硒的帮助下单击此下拉菜单? - How can I click on this drop-down menu with help of selenium? 如何在多个项目选择的java swing中创建一个下拉列表? - How to create a drop-down list in java swing with multiple item selection? 如何使用具有下拉功能的SWT.RADIO样式创建eclipse工具栏项? - How do I create an eclipse toolbar item with SWT.RADIO style with drop-down capabilities? 创建按钮下拉菜单 - Create button drop-down menu 如何在JFrame中添加下拉菜单? - How to add a drop-down menu to a JFrame? 如何在不使用面板的情况下在Java中创建下拉列表? - How to create a drop down list in java without swing using panel? 如何在 Eclipse Kepler 工具栏中放置动态下拉列表? - How to put a dynamic drop-down list in Eclipse Kepler toolbar? 简单的Java GUI作为弹出窗口和下拉菜单 - Simple Java GUI as a popup window and drop-down menu 单击下拉弹出窗口外部时,如何使用 selenium 关闭下拉菜单 - How can I close the drop down using selenium when click on outside of drop-down popup 如何在包装在其中的下拉菜单中查找元素 <li> <a>和Sulnium Webdriver中使用Java的&gt; ul&gt;标签</a> - How to find elements in a drop-down menu wrapped inside <li>, <a> and >ul> tags in Selenium Webdriver using Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM