L'accélérateur JMenuItem ne fonctionne pas après l'affichage de deux JDialogs non modaux? (Mac seulement?)

StackOverflow https://stackoverflow.com/questions/1622386

Question

J'ai le problème suivant: les accélérateurs de JMenuItems ne fonctionnent plus après l'affichage simultané de deux JDialogs.

Veuillez regarder ce petit exemple qui reproduit le problème:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class DialogBug
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new StartupRunnable(args.length == 0));
    }

    public static class StartupRunnable
        implements Runnable
    {
        private boolean both;

        public StartupRunnable(boolean both)
        {
            this.both=both;
        }

        public void run()
        {
            MyFrame myFrame=new MyFrame();
            myFrame.setVisible(true);
            myFrame.startUp(both);
        }
    }

    public static class MyFrame
        extends JFrame
    {
        private MyDialog dialog1;
        private MyDialog dialog2;

        public MyFrame()
        {
            super("MyFrame");
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            initUI();
        }

        private void initUI()
        {
            dialog1=new MyDialog(this);
            dialog2=new MyDialog(this);
            JMenuBar menuBar=new JMenuBar();
            JMenu fileMenu=new JMenu("File");
            menuBar.add(fileMenu);
            fileMenu.add(new JMenuItem(new OpenAction()));
            setJMenuBar(menuBar);
            setSize(200,200);
        }

        public void startUp(boolean both)
        {
            dialog1.setVisible(true);
            if(both)
            {
                dialog2.setVisible(true);
            }
        }

        private class OpenAction
            extends AbstractAction
        {
            public OpenAction()
            {
                super("Open");
                KeyStroke accelerator = KeyStroke.getKeyStroke("ctrl O");
                putValue(Action.ACCELERATOR_KEY, accelerator);
            }

            public void actionPerformed(ActionEvent e)
            {
                System.out.println("Open executed");
            }
        }

    }

    public static class MyDialog
        extends JDialog
    {
        public MyDialog(JFrame parent)
        {
            super(parent);
            setTitle("Dialog");
            setModal(false);
            add(new JButton(new OkAction()));
            pack();
        }

        private class OkAction
            extends AbstractAction
        {
            public OkAction()
            {
                super("Ok");
            }

            public void actionPerformed(ActionEvent e)
            {
                setVisible(false);
            }
        }
    }
}

Compilez-le avec javac DialogBug.java et exécutez-le en exécutant java DialogBug .

Vous en verrez deux avec les boutons "Ok". Fermez les deux boîtes de dialogue en cliquant dessus. Maintenant, appuyez sur "Ctrl-O". Cela devrait imprimer " Ouvert exécuté " à la console, mais cela n'arrivera pas. Cliquez maintenant sur le bouton "Fichier". menu. Maintenant " Ctrl-O " fonctionnera comme prévu.

Si vous démarrez l'application avec un argument, par exemple. java DialogBug x , une seule boîte de dialogue s’ouvrira et " Ctrl-O " fonctionnera immédiatement après avoir fermé la boîte de dialogue, comme prévu.

Mon environnement est le suivant:

java version "1.6.0_15"
Java(TM) SE Runtime Environment (build 1.6.0_15-b03-219)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02-90, mixed mode)

Mais pour autant que je sache, cette application se comporte de manière similaire sur d'autres machines virtuelles.

Aidez-moi s'il vous plaît!
Je n'ai vraiment aucune idée de ce qui pourrait mal se passer ici. S'il s'agit d'un bogue Java (et je m'attends à ce qu'il en soit un), merci de me prévenir si vous avez une solution de contournement ...

Si vous pouvez ou ne pouvez pas reproduire cela sur d'autres systèmes, merci de le signaler dans les commentaires.
Merci beaucoup!

Mettre à jour
Après installer Java 1.5 sur Snow Leopard ( sigh ) Je peux également confirmer que cela se produit avec 1.5.0_19, du moins sur Snow Leopard.

Mise à jour 2
Fonctionne pour moi sous Windows XP.

java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)

java version "1.5.0_13"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05)
Java HotSpot(TM) Client VM (build 1.5.0_13-b05, mixed mode)

Mise à jour 3
Semble fonctionner aussi sur Windows Vista. C’est donc un problème pour Mac OS X 10.5 + 10.6, autant que je sache.

Mise à jour 4
Ce bogue est classé sous le problème numéro 7240026 chez Apple.

Était-ce utile?

La solution

Remplacez la méthode actionPerformed de la classe OkAction dans la classe MyDialog par la suivante:

public void actionPerformed(ActionEvent e) {
            setVisible(false);
            MyDialog.this.getParent().requestFocus();
        }

Pour une raison quelconque (peut-être parce que les boîtes de dialogue ne sont pas modales), OS X ne renvoie pas le focus à votre MyFrame. Si vous fermez les boîtes de dialogue en fermant les boîtes de dialogue, le focus revient naturellement à MyFrame, mais il se peut que vous ayez simplement à les masquer.

Autres conseils

Fonctionne bien pour moi sous XP avec Java Runtime Environment (build 1.6.0_07-b06).

Pour une raison quelconque, il me semble que Ctrl + O est l’accélérateur permettant de modifier l’orientation des composants. Je me demandais simplement si cela se produisait avec tous les accélérateurs ou uniquement avec Ctrl + O?

Modifier: vous pouvez probablement oublier cette suggestion. Je n'arrive pas à trouver / à me souvenir des endroits où j'ai pu penser cela et je ne peux pas le vérifier dans aucun de mes programmes de test.

Je l'ai exécuté sans problème sur mon Mac doté de OS X 10.4 et de la version Java "1.5.0_19".

Je me demande si, après la fermeture des deux boîtes de dialogue modales, le cadre principal a le focus. Je n'ai pas utilisé d'accélérateurs depuis longtemps, mais je pense qu'il y a peut-être eu des changements récents concernant les accélérateurs enregistrés dans la barre de menus et les accélérateurs enregistrés dans le cadre (comme les raccourcis).

Bonne chance avec elle.

J'ai essayé Leopard / 10.5 et le programme ne fonctionne pas non plus avec:

Java 5 (JVM Apple)

java version "1.5.0_20"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_20-b02-315)
Java HotSpot(TM) Client VM (build 1.5.0_20-141, mixed mode, sharing)

Java 6 (port BSD SoyLatte / Open JDK)

java version "1.6.0_03-p3"
Java(TM) SE Runtime Environment (build 1.6.0_03-p3-landonf_19_aug_2008_14_55-b00)
Java HotSpot(TM) Server VM (build 1.6.0_03-p3-landonf_19_aug_2008_14_55-b00, mixed mode)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top