Frage

Ich habe ein Dropdown-Menü in meinem Swing Jtoolbar erstellt. Aber es schafft nicht so, wie ich es will. Ich strebe darauf, dass es wie Firefoxs "Smart Lesezeichen" -Taste funktioniert.

Es verschwindet, wenn der Benutzer einen Menüelement auswählt: Richtig!

Es verschwindet, wenn der Benutzer ESC drückt: Richtig!

Es verschwindet, wenn der Benutzer irgendwo im Hauptrahmen außerhalb des Menüs klickt: Richtig!

Es verschwindet jedoch nicht, wenn der Benutzer ein zweites Mal auf der Schaltfläche klickt, die das Dropdown-Menü anzeigt: Falsch ... :-(

Meine Frage ist, wie ich dieses Verhalten hinzufügen kann, dass es verschwindet, wenn die Klicks auf die Schaltfläche ein zweites Mal angezeigt werden.

Hier ist mein aktueller Code von Java 6 auf dem Mac:

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());
    }
}
War es hilfreich?

Lösung

Nun, hier ist eine potenzielle Lösung, die nicht ohne Nachteile ist. Nur Sie können entscheiden, ob dies für Ihre Bewerbung akzeptabel ist. Das Problem ist, dass das Popup-Schließen auftritt, bevor andere Mausereignisse abgefeuert werden. Klicken Sie also auf Ihre Mehr. Die Taste führt dazu, dass das Popup sich ausschlägt, wodurch die Tasten auf Deaktiviert zurückgesetzt wird, bevor die Taste sogar gesagt wird, dass er gedrückt wurde.

Die einfache Problemumgehung besteht darin, den folgenden Anruf in Ihr Hauptprogramm hinzuzufügen:

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

Das Ergebnis ist, dass das Mausereignis zum Zeitpunkt des Schließens des Menüs verbraucht wird, wenn ein Popup-Menü aufgrund eines Maus-Ereignisses geschlossen wird und nicht an andere Komponenten unter der Maus weitergegeben wird. Wenn Sie mit Einschränkung leben können, ist dies eine einfache Lösung.

Andere Tipps

Was passiert, ist, dass beim Klicken auf das Menü das Popup -Menü abgebrochen wird, sodass Sie die Schaltfläche auswählen. Das nächste unmittelbare Ereignis ist jedoch auf die Schaltfläche, und jetzt wird das Menü erneut angezeigt.

Ich habe noch nicht die genaue Lösung, aber gib mir ein bisschen ...

Ich benutze Firefox nicht, daher weiß ich nicht, wie der intelligente Lesezeichen aussieht, aber vielleicht verwenden Sie einen JMenu als "Knopf". Sie könnten versuchen, den Rand eines Jbuttons zu verwenden, damit er eher wie ein Knopf aussieht.

Nun, der Hörer auf dem Knopf reagiert nur, wenn er nach unten gedrückt wird, weil Sie auf Hören ItemEvent.SELECTED Nur Ereignisse. Wie wäre es mit einer anderen IF -Klausel, auf die Sie zuhören sollen ItemEvent.DESELECTED Ereignisse hier:

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

Sie können entweder einen Verweis auf die speichern menu irgendwo, oder Sie können das Menü selbst dazu bringen, der Schaltfläche einen weiteren Hörer hinzuzufügen. Die letztere Lösung könnte einfacher sein, da Sie bereits einen Schaltflächenreferenz auf das Menü zu senden scheinen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top