Domanda

Ho il problema che gli acceleratori di JMenuItems non funzionano più dopo aver mostrato due dialoghi J direttamente uno dopo l'altro.

Dai un'occhiata a questo piccolo esempio che riproduce il problema:

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

Compilalo usando javac DialogBug.java ed eseguilo eseguendo java DialogBug .

Ne vedrai due con i pulsanti "Ok". Chiudi entrambe le finestre di dialogo facendo clic su di esse. Ora premi " Ctrl-O " ;. Questo dovrebbe stampare " Apri eseguito " alla console ma questo non accadrà. Ora fai clic su " File " menu. Ora " Ctrl-O " funzionerà come previsto.

Se avvii l'app con qualsiasi argomento, ad es. java DialogBug x quindi si aprirà solo una finestra di dialogo e " Ctrl-O " funzionerà immediatamente dopo aver chiuso la finestra di dialogo, come previsto.

Il mio ambiente è il seguente:

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)

Ma per quanto ne so questa app si comporta in modo simile in altre VM.

Per favore, aiutami!
Davvero non ho idea di cosa potrebbe andare storto qui. Se si tratta di un bug Java (e mi aspetto che sia uno), per favore fatemi sapere se avete una soluzione alternativa ...

Se puoi o non puoi riprodurlo su altri sistemi, per favore dimmelo nei commenti.
Grazie mille!

Aggiorna
Dopo l'installazione di Java 1.5 su Snow Leopard ( sigh ) Posso confermare che ciò accade anche con 1.5.0_19, almeno su Snow Leopard.

Aggiornamento 2
Funziona per me su 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)

Aggiornamento 3
Sembra funzionare anche su Windows Vista. Questo rende questo un problema con Mac OS X 10.5 + 10.6, AFAIK finora.

Aggiornamento 4
Questo errore è archiviato con ID problema # 7240026 su Apple.

È stato utile?

Soluzione

Sostituisci il metodo actionPerformed della classe OkAction nella classe MyDialog con il seguente:

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

Per qualche motivo (forse perché le finestre di dialogo non sono modali), OS X non sta riportando lo stato attivo su MyFrame. L'attenzione ritorna su MyFrame naturalmente se chiudi i dialoghi chiudendoli, ma potrebbe esserci qualcosa con il semplice nascondere i dialoghi.

Altri suggerimenti

Funziona bene per me su XP utilizzando Java (TM) SE Runtime Environment (build 1.6.0_07-b06).

Per qualche motivo mi sembra di pensare che Ctrl + O sia l'acceleratore per cambiare l'orientamento di un componente. Mi chiedo solo se questo accada con tutti gli acceleratori o solo Ctrl + O?

Modifica: probabilmente puoi dimenticare questo suggerimento. Non riesco a trovare / ricordare dove avrei potuto pensarlo e non posso verificarlo in nessuno dei miei programmi di test.

L'ho eseguito senza problemi sul mio Mac con OS X 10.4 e versione Java "1.5.0_19".

Mi chiedo se dopo aver chiuso i due dialoghi modali il frame principale abbia il focus. Non uso gli acceleratori da molto tempo, ma penso che forse ci siano stati alcuni cambiamenti recenti relativi agli acceleratori registrati nella barra dei menu e agli acceleratori registrati nel frame (come le scorciatoie).

Buona fortuna.

Ho provato su Leopard / 10.5 e il programma non funziona con nessuno dei due:

Java 5 (Apple JVM)

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 (SoyLatte / Open JDK BSD Port)

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top