簡體   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