我遇到的问题是,在直接显示两个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
对其进行编译,然后执行java DialogBug
。
你会看到两个“Ok”-Buttons。关闭两个单击它们的对话框。 现在按“Ctrl-O”。这应该打印“打开执行”到控制台,但这不会发生。 现在单击“文件”菜单。现在“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错误(我希望它是一个),那么如果你有一个解决方法,请告诉我......
如果您能够或不能在其他系统上重现这一点,请在评论中告诉我 非常感谢!
更新
在installing Java 1.5 on Snow Leopard(叹息)之后,我可以确认这种情况发生在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
此错误在Apple的问题ID#7240026下提交。
答案 0 :(得分:1)
使用以下内容替换MyDialog类中OkAction类的actionPerformed方法:
public void actionPerformed(ActionEvent e) {
setVisible(false);
MyDialog.this.getParent().requestFocus();
}
出于某种原因(可能因为对话框不是模态的),OS X不会将焦点返回到MyFrame。如果您通过关闭对话框来关闭对话框,焦点会自然返回到MyFrame,但可能只是隐藏对话框。
答案 1 :(得分:0)
使用Java(TM)SE运行时环境(版本1.6.0_07-b06)在XP上运行正常。
出于某种原因,我似乎认为Ctrl + O是用于更改组件方向的加速器。只是想知道这是否适用于所有加速器或只有Ctrl + O?
编辑:你可能会忘记这个建议。我似乎无法找到/回想起我曾经想过的地方,也无法在我的任何测试程序中验证这一点。
答案 2 :(得分:0)
我在运行OS X 10.4和Java版本“1.5.0_19”的Mac上运行它没问题。
我想知道在关闭两个模态对话框后,主框架是否具有焦点。 我很久没有使用过加速器了,但我想最近在菜单栏中注册的加速器以及框架中注册的加速器(如快捷方式)可能会有一些变化。
祝你好运。
答案 3 :(得分: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 / Open 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)