JMenuItem acelerador não funciona depois de mostrar dois JDialogs não-modais? (Somente Mac?)

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

Pergunta

Eu tenho o problema que os aceleradores de JMenuItems não estão mais funcionando depois de mostrar dois JDialogs diretamente após o outro.

Por favor, dê uma olhada neste pequeno exemplo que reproduz o 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);
            }
        }
    }
}

compilá-lo usando javac DialogBug.java e executá-lo em execução java DialogBug.

Você verá dois com "OK" -botões. Dispensar ambos os diálogos clicando neles. Agora pressione "Ctrl-O". Isso deve imprimir "Open executado" para o console, mas isso não vai acontecer. Agora clique no menu "File". Agora "Ctrl-O" funcionará como esperado.

Se você iniciar o aplicativo com qualquer argumento, por exemplo, java DialogBug x em seguida, apenas um diálogo será aberta e "Ctrl-O" irá funcionar imediatamente depois de dispensar a caixa de diálogo, como esperado.

O meu ambiente é o seguinte:

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)

Mas, tanto quanto eu sei que este aplicativo se comporta semelhante em outras VMs.

Por favor, ajuda-me!
Eu realmente não tem idéia do que pode dar errado aqui. Se este é um erro Java (e eu esperava que fosse um), então por favor deixe-me saber se você tem uma solução alternativa ...

Se você pode ou não pode reproduzir este em outros sistemas agradar me dizer isso nos comentários.
Muito obrigado!

Atualizar
Depois instalar Java 1.5 no Snow Leopard ( suspirar ) posso confirmar que isso acontece com 1.5.0_19, também, pelo menos no Snow Leopard.

Update 2
Funciona para mim no 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)

Update 3
Parece funcionar no Windows Vista, também. Isto torna este um Mac OS X 10.5 + 10.6 questão, AFAIK até agora.

Update 4
Este bug está arquivado sob Problema ID # 7240026 na Apple.

Foi útil?

Solução

Substitua o método actionPerformed da classe OkAction na classe MyDialog com o seguinte:

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

Por algum motivo (talvez porque os diálogos não são modal), OS X é não retornar o foco para o seu MyFrame. O foco retorna para MyFrame naturalmente se você descartar as caixas de diálogo, fechando-los, mas pode haver algo com simplesmente esconder as caixas de diálogo.

Outras dicas

bem para mim no XP usando Java (TM) SE Runtime Environment (construção 1.6.0_07-b06). Works

Por alguma razão eu parecem pensar que Ctrl + O é o acelerador para mudar a orientação componentes. Basta saber se isso acontece com todos os aceleradores ou única Ctrl + O?

Edit: você pode provavelmente esquecer esta sugestão. Eu não consigo encontrar / chamada onde eu pode ter pensado isso e e não pode verificar isso em qualquer um dos meus programas de teste.

Eu corri-lo sem problema no meu mac que tem OS X 10.4 e versão Java "1.5.0_19".

Eu estou querendo saber se depois de fechar as duas caixas de diálogo modais quadro principal tem o foco. Eu não usei aceleradores em um longo tempo, mas eu acho que talvez tenha havido alguma mudança recente sobre aceleradores registrados na barra de menus e aceleradores registrado no quadro (como atalhos).

Boa sorte com isso.

Eu tentei no Leopard / 10.5 eo programa não funciona com:

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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top