문제

스윙 jtoolbar에서 드롭 다운 메뉴를 만들었습니다. 그러나 그것은 내가 원하는 방식으로 행동하지 않습니다. 나는 그것이 Firefox의 "스마트 북마크"버튼처럼 작동하는 것을 목표로하고 있습니다.

사용자가 메뉴 항목을 선택하면 사라집니다.

사용자가 ESC를 누르면 사라집니다 : 맞습니다!

메뉴 외부의 메인 프레임 어딘가에 사용자가 클릭하면 사라집니다.

그러나 드롭 다운 메뉴를 표시하는 버튼에서 사용자가 두 번째로 클릭하면 사라지지 않습니다.

내 질문은이 동작을 추가 할 수있는 방법입니다. 메뉴를 두 번째로 표시하는 버튼을 클릭하면 사라집니다.

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를 사용하지 않으므로 Smart Bookmarks 버튼이 어떻게 보이는지 알지 못하지만 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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top