0

2 つの JDialog を次々に表示した後、JMenuItems のアクセラレータが機能しなくなるという問題があります。

問題を再現するこの小さな例を見てください。

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、running で実行しますjava DialogBug

「OK」ボタンが 2 つ表示されます。両方のダイアログをクリックして閉じます。ここで「Ctrl-O」を押します。これにより、コンソールに「オープンが実行されました」と出力されるはずですが、これは起こりません。「ファイル」メニューをクリックします。これで、「Ctrl-O」が期待どおりに機能するようになりました。

たとえば、任意の引数を指定してアプリを起動すると、java DialogBug xダイアログが 1 つだけ開き、期待どおり、ダイアログを閉じた直後に「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)

しかし、私が知る限り、このアプリは他の VM でも同様に動作します。

私を助けてください!
ここで何がうまくいかないのか、私にはまったくわかりません。これが Java のバグである場合 (そして私はそれがバグであると予想しています)、回避策があれば教えてください...

他のシステムでこれを再現できる、または再現できない場合は、コメントで教えてください。
どうもありがとう!

Update Java 1.5 を Snow Leopard にインストールした
後(ため息)、これが 1.5.0_19 でも発生することを確認できます。少なくとも Snow Leopard ではそうです。

Update 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)

Update 3
Windows Vista でも動作するようです。これにより、これは Mac OS X 10.5+10.6 の問題になります。

Update 4
このバグは、Apple で問題 ID #7240026 として登録されています。

4

4 に答える 4

1

MyDialog クラスの OkAction クラスの actionPerformed メソッドを次のように置き換えます。

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

何らかの理由で (おそらくダイアログがモーダルではないため)、OS X が MyFrame にフォーカスを戻していません。ダイアログを閉じて消せば自然に MyFrame にフォーカスが戻りますが、単純にダイアログを非表示にすると何かあるかもしれません。

于 2009-12-30T16:37:13.190 に答える
0

Java(TM)SEランタイム環境(ビルド1.6.0_07-b06)を使用するXPでは問題なく動作します。

どういうわけか、Ctrl+Oはコンポーネントの向きを変更するためのアクセラレータだと思います。これがすべてのアクセラレータで発生するのか、Ctrl + Oのみで発生するのか疑問に思っていますか?

編集:あなたはおそらくこの提案を忘れることができます。私はこれを考えたかもしれない場所を見つけたり思い出したりすることができず、私のテストプログラムのいずれかでこれを確認することができません。

于 2009-10-26T00:23:47.890 に答える
0

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/オープン JDK BSD ポート)

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)
于 2009-11-05T22:35:52.950 に答える
0

OS X 10.4とJavaバージョン「1.5.0_19」を搭載したMacで問題なく実行しました。

2 つのモーダル ダイアログを閉じた後、メイン フレームにフォーカスがあるかどうか疑問に思っています。久しくアクセラレータを使っていなかったのですが、メニューバーに登録するアクセラレータ、フレームに登録するアクセラレータ(ショートカットなど)が最近変わったのではないかと思います。

頑張ってください。

于 2009-10-26T06:40:29.180 に答える