[英]Focus issues with java7 modal dialogs on mac osx
我一直在验证在mac osx的applet上运行的swing应用程序。
在此验证期间,我发现模式对话框存在以下问题:
所以我创建了一个小程序来显示问题。 你能帮我理解这里有什么问题吗?
package com.macosx.tests;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class DialogExample extends JApplet{
private static final long serialVersionUID = 1L;
private JPanel panel;
private JButton openDialogBtn;
private void doStart() {
panel = new JPanel();
panel.setPreferredSize(new Dimension(500,500));
openDialogBtn = new JButton("open dialog");
openDialogBtn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
ModalDialog dialog = new ModalDialog(panel, true);
dialog.setVisible(true);
}
});
panel.add(openDialogBtn);
setContentPane(panel);
}
class ModalDialog extends JDialog {
private static final long serialVersionUID = 1L;
public ModalDialog(Component parent, boolean modal) {
Dimension dimensionParentFrame = parent.getSize();
setSize(new Dimension((parent == null) ? 300 : dimensionParentFrame.width / 2, 75));
setModal(modal);
setModalityType(ModalityType.APPLICATION_MODAL);
JTextField txtField = new JTextField();
add(txtField, BorderLayout.CENTER);
}
}
@Override
public void start() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
doStart();
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
使用上面的方法创建.jar文件(test.jar)。 完成后,创建一个包含以下内容的html文件:
<html>
<head>
<title>Dialog test Applet</title>
</head>
<body>
<applet id="DialogTestApplet" height="800" width="600"
code="com.macosx.tests.DialogExample"
archive="test.jar">
</applet>
</div>
</body>
</html>
完成后,运行html文件。 你会看到一个灰色背景和一个按钮的小程序。 然后尝试:
那么,我在这里做错了什么? 有人用Mac电脑测试一下吗?
谢谢
眼镜:
java.vendor Oracle Corporation
java.version 1.7.0_07
os.name Mac OS X
os.version 10.7.4
browser firefox 15
注意:请注意,这仅在applet在浏览器上运行且仅在mac osx上运行时才会发生。
我发现了另一种解决方法。 打开窗口时,显示一个选项窗格几毫秒并关闭它。 它将焦点放在选项窗格上,然后返回到对话框,允许忽略该错误。
将此snipet代码添加到对话框构造函数中,它应该工作:
addWindowListener(new WindowAdapter(){
public void windowOpened(WindowEvent e){
JOptionPane pane = new JOptionPane();
final JDialog dialog = pane.createDialog("Please Wait");
Timer timer = new Timer(50, new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
timer.setRepeats(false);
timer.start();
dialog.setVisible(true);
}
您应该在ModalDialog上放置一个“所有者”窗口。 为此,您必须在ModalDialog构造函数中调用super(owner),并且可以使用SwingUtilities.getWindowAncestor(parent)
检索组件parent
的父窗口。
不是Mac / OSX用户,但这是关于Focus
和JDialog
常见问题,
在运行时创建JDialog
的情况下还有另一个问题,
Focus
是基于Native OS
属性而异步的
只创建一次JDialog
然后re_use
此container
进行另一个操作
JDialog#setVisible
应该包装到invokeLater()
可以通过JTextField#setText(JTextField#getText())
强制Focus
JTextField#setText(JTextField#getText())
包装到invokeLater()
Dialog Focus是@camickr的一个很好的解决方法
我确认,我在OS X上的JDK7中运行的旧applet也有同样的错误。正如海报所提到的,只有applet在浏览器中运行(ff)而不是appletviewer才能看到错误。
我可以验证这是Safari Mountain 6上的Java 1.7 Update 7+和Mountain Lion上运行的Firefox的问题。 奇怪的是,早期版本的Safari在Lion上运行并不是问题,但在旧操作系统的Firefox中存在问题。 由于许多applet用户都在Mac上,我非常渴望找到解决方法。 我找到的一种解决方法(通过任何方式都不够)是缩小窗口然后重新打开它。 textfields / textareas然后变得可编辑。 希望我们能找到更好的解决方案来解决这个烦人的需求。
我在Mac上使用Safari和Firefox的Java 7更新9遇到了同样的问题。 当我打开一个包含JTextField的JDialog时,JTextField无法访问。
我确实找到了解决方案。 我插入了一个延迟,从用户按下“显示对话框按钮”到执行显示按钮的代码。
例如:
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEvent ae){
TitleDialog dialog = new TitleDialog(main.findParentFrame()); // My JDialog which contains a JTextField.
dialog.setVisible(true);
}
};
javax.swing.Timer timer = new javax.swing.Timer(1000, al);
timer.setRepeats(false);
timer.start();
我经历过,如果延迟时间很短,解决方案将无效。
如果使用SwingUtilities.invokeLater
而不是javax.swing.Timer
它将无法正常工作。 也许SwingUtilities.invokeLater
的延迟太短了。
我找到了另外一个解决方法。 当从JavaScript调用JDialog时,它有一个焦点。
希望能帮助到你。 顺便说一下,来自Java教程的Web启动示例具有相同的问题http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html
我想使用上面的解决方法(从对话框打开对话框),但没有显示任何对话框。 这是一个不可见对话框的代码。
final JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setSize(0, 0);
dialog.setModal(true);
dialog.pack();
我找到了解决方案。
GetDirectory varGetDirectory = new GetDirectory(new JFrame(),true);
varGetDirectory.setVisible(true);
GetDirectory是包含JFileChooser的JDialog。
奇怪的是,所有JDialog对象都应该使用新的JFrame()作为父级调用,否则从一个父窗口单击将使顶级模式JDialog在zOrder中向后移动,并且不知何故它不能再设置在顶部。
我的问题和上面一样。 当我从另一个JDialog创建JDialog时,新对话框出现在另一个之后。
为了使它成为顶部我已经设置了如上所述的所有JDialog的父级,并且它根据预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.