Ускоритель JMenuItem не работает после показа двух немодальных JDialogs? (Только Mac?) - PullRequest
0 голосов
/ 26 октября 2009

У меня проблема в том, что ускорители JMenuItems больше не работают после отображения двух JDialogs непосредственно друг за другом.

Пожалуйста, посмотрите на этот небольшой пример, который воспроизводит проблему:

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

Скомпилируйте его, используя javac DialogBug.java, и выполните его, запустив java DialogBug.

Вы увидите две кнопки "ОК". Отключите оба диалоговых окна, щелкая их. Теперь нажмите «Ctrl-O». Это должно вывести «Open execute» на консоль, но этого не произойдет. Теперь нажмите меню «Файл». Теперь «Ctrl-O» будет работать как положено.

Если вы запускаете приложение с любым аргументом, например, java DialogBug x тогда откроется только одно диалоговое окно, и "Ctrl-O" будет работать сразу после закрытия диалогового окна, как и ожидалось.

Моя среда выглядит следующим образом:

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)

Но насколько я знаю, это приложение ведет себя аналогично в других виртуальных машинах.

Пожалуйста, помогите мне!
Я действительно понятия не имею, что здесь может пойти не так. Если это ошибка Java (и я ожидаю, что она будет одной), пожалуйста, дайте мне знать, если у вас есть обходной путь ...

Если вы можете или не можете воспроизвести это на других системах, пожалуйста, сообщите мне об этом в комментариях.
Большое спасибо!

Обновление
После установки Java 1.5 на Snow Leopard ( sigh ) я могу подтвердить, что это также происходит с 1.5.0_19, по крайней мере на Snow Leopard.

Обновление 2
У меня работает на 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)

Обновление 3
Кажется, работает и в Windows Vista. Это делает эту проблему Mac OS X 10.5 + 10.6, пока что AFAIK.

Обновление 4
Эта ошибка хранится под идентификатором проблемы # 7240026 в Apple.

Ответы [ 4 ]

1 голос
/ 30 декабря 2009

Замените метод actionPerformed класса OkAction в классе MyDialog следующим:

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

По какой-то причине (возможно, потому что диалоги не модальные), OS X не возвращает фокус на ваш MyFrame. Фокус возвращается к MyFrame, естественно, если вы закрываете диалоги, закрывая их, но может быть что-то с простым скрытием диалогов.

0 голосов
/ 26 октября 2009

Я без проблем запустил его на своем Mac с OS X 10.4 и версией Java "1.5.0_19".

Мне интересно, если после закрытия двух модальных диалогов основное окно будет в фокусе. Я давно не использовал ускорители, но думаю, что, возможно, произошли некоторые недавние изменения в отношении ускорителей, зарегистрированных в строке меню, и ускорителей, зарегистрированных в кадре (например, ярлыки).

Удачи с этим.

0 голосов
/ 06 ноября 2009

Я пробовал на Leopard / 10.5, и программа не работает с:

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)
0 голосов
/ 26 октября 2009

Отлично работает для меня на XP с использованием Java (TM) SE Runtime Environment (сборка 1.6.0_07-b06).

Почему-то мне кажется, что Ctrl + O - это ускоритель для изменения ориентации компонентов. Просто интересно, происходит ли это со всеми ускорителями или только Ctrl + O?

Изменить: вы, вероятно, можете забыть это предложение. Кажется, я не могу найти / вспомнить, где я мог подумать, и не могу проверить это ни в одной из моих тестовых программ.

...