9

Swing JToolBar にドロップダウン メニューを作成しました。しかし、それは私が望むように振る舞うことはありません。Firefoxの「スマートブックマーク」ボタンのように機能することを目指しています。

ユーザーがメニュー項目を選択すると消えます: 正しい!

ユーザーが ESC を押すと消えます: 正しい!

ユーザーがメニューの外側のメインフレームのどこかをクリックすると消えます: 正しい!

しかし、ユーザーがドロップダウンメニューを表示するボタンをもう一度クリックしても消えません: INCORRECT... :-(

私の質問は、メニューを表示するボタンを2回クリックすると消えるというこの動作をどのように追加できるかです。

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

4 に答える 4

5

さて、ここに欠点がないわけではない潜在的な解決策があります。これがアプリケーションに受け入れられるかどうかを判断できるのはあなただけです。問題は、他のマウス処理イベントが発生する前にポップアップが閉じるため、[その他]ボタンをもう一度クリックするとポップアップが非表示になり、ボタンが押されたと通知される前にボタンの状態が選択解除にリセットされることです。

簡単な回避策は、メインプログラム内に次の呼び出しを追加することです。

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

この結果、マウスが押されたイベントのためにポップアップメニューが閉じられると、そのマウスイベントはメニューが閉じられたときに消費され、マウスの下の他のコンポーネントに渡されません。あなたが制限を持って生きることができるなら、これは簡単な解決策です。

于 2009-12-17T17:05:59.767 に答える
0

私は Firefox を使用していないので、スマート ブックマーク ボタンがどのように見えるかはわかりませんが、「ボタン」として JMenu を使用している可能性があります。JButton の Border を使用して、ボタンのように見せることができます。

于 2009-12-14T16:05:19.373 に答える
-1

ItemEvent.SELECTEDボタンのリスナーは、イベントのみをリッスンするため、ボタンが押されたときにのみ反応します。ItemEvent.DESELECTEDここでイベントをリッスンするために別のif句を追加するのはどうですか?

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

menuどこかに参照を保存するか、メニュー自体にボタンに別のリスナーを追加させることができます。後者の解決策は、すでにメニューへのボタン参照を送信しているように見えるため、より簡単な場合があります。

于 2009-12-14T11:21:21.220 に答える