Domanda

Ho creato un menu a discesa sul mio swing JToolBar. Ma non crea comportarsi nel modo desiderato. Sto puntando per farlo funzionare come il tasto "Smart Bookmarks" di Firefox.

E scompare quando l'utente seleziona una voce di menu:! CORRETTO

E scompare quando l'utente preme ESC: CORRETTO

E scompare quando l'utente fa clic da qualche parte nel telaio principale al di fuori del menu:! CORRETTO

Ma non scompare quando l'utente fa clic una seconda volta sul pulsante che mostra il menu a discesa: ERRATO ...: - (

La mia domanda è come posso aggiungere questo comportamento, che non scompare quando i clic sul pulsante che mostra il menu per la seconda volta.

Ecco il mio codice attuale, da Java 6 su 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());
    }
}
È stato utile?

Soluzione

Bene, ecco una soluzione potenziale che è non senza che sia svantaggi. Solo tu puoi decidere se questo è accettabile per l'applicazione. Il problema è che la chiusura popup si verifica prima di altri eventi del mouse di gestione vengono sparati quindi cliccando sul pulsante More .. provoca di nuovo la comparsa di nascondere, ritornando alla condizione pulsanti per deselezionato prima che il pulsante viene anche detto che è stato premuto.

La soluzione semplice è aggiungere la seguente chiamata all'interno del programma principale:

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

Il risultato di ciò è che ogni volta che un menu a comparsa viene chiuso a causa di un evento di mouse premuto, che evento del mouse sarà consumato al momento il menù è chiuso e non sarà trasmesso a tutti gli altri componenti sotto il mouse . Se si può vivere con limitazione, questa è una soluzione facile.

Altri suggerimenti

Quello che sta succedendo è che quando si fa clic dal menu, cancella il menu a comparsa, in modo da deselezionare il pulsante, ma il prossimo evento immediato è quello di cliccare il pulsante, e ora il suo deselezionata in modo che mostra di nuovo il menu.

Non ho la soluzione esatta ancora, ma mi danno un po '...

Non faccio uso di Firefox, quindi non so che cosa il tasto Smart Bookmarks assomiglia, ma forse usare un JMenu come il "pulsante". Si potrebbe provare a utilizzare il bordo di un JButton per farlo sembrare più simile a un pulsante.

Bene, l'ascoltatore sul pulsante reagisce solo quando è spinto verso il basso, perché si ascolta solo per eventi ItemEvent.SELECTED. Che ne dite di aggiungere un altro se la clausola di ascoltare per eventi ItemEvent.DESELECTED qui:

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

Si potrebbe o memorizzare un riferimento al menu da qualche parte, o si potrebbe creare il menu stesso aggiungere un altro ascoltatore al pulsante. Quest'ultima soluzione potrebbe essere più semplice, dal momento che già sembra di inviare un riferimento di pulsante per il menu.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top