我遇到了一个模式对话框的错误我正在使用Java 8u151 / 8u152,这在8u112中不是问题,而且我不确定我是否在做一些固有的错误,或者这是否是一个JRE错误。这只影响Mac OS,据我所知(我正在运行OS 10.12.6),所以虽然我的问题不是特定于Mac的,如果你不是Mac,你将无法观察到这个bug用户。
我创建了一个模式对话框,主JFrame作为其父级。然后我创建一个新的模态对话框,我从对话框#1创建。将对话框#2的父级设置为主JFrame也是错误的吗?或者必须是对话#2?
问另一种方法:如果两个对话框共享同一个父对象(主JFrame),但最后创建了对话框#2,那么期望对话框#2应该位于顶部,还是未定义的行为是否合理?
使用8u112,对话框#2聚焦并位于顶部。对于8u151,对话框#2聚焦但落后。如果我点击任一对话框,对话框#2会抓住焦点并且似乎在大多数情况下表现得恰到好处。但是,有时对话框#2将保留在其他应用程序之上(我相信如果我点击主窗口,然后返回模态对话框就会发生这种情况......这部分肯定是个错误。)
注意:对于Java 8u121到(我认为)8u144,在8u152中应该修复的模态对话框存在其他问题(几个月前我记录了一个错误报告并检查了早期访问构建,事情确实如此然后修好了。
一些示例代码来说明我正在做的事情:
import javax.swing.*;
import java.awt.*;
public class Main extends JFrame {
MyPanel panel;
public Main() {
setTitle("This is a frame");
setSize(300, 200);
panel = new MyPanel(this);
add(panel);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
Main frame = new Main();
frame.pack();
frame.setVisible(true);
});
}
private static class MyPanel extends JPanel {
int dialogCounter = 1;
final JFrame theParent;
public MyPanel(JFrame parent) {
super();
theParent = parent;
setPreferredSize(new Dimension(300, 200));
JButton button = new JButton("Press the button");
button.addActionListener(e -> showDialog(theParent));
add(button);
}
private void showDialog(Frame parent) {
JDialog dialog = new JDialog(parent, "This is dialog " + dialogCounter, true);
setupDialog(dialog);
}
private void setupDialog(JDialog dialog) {
JPanel dialogPanel = new JPanel();
dialogPanel.setPreferredSize(new Dimension(300, 200));
dialogPanel.add(new JLabel("Current dialog count: " + dialogCounter++));
JButton button = new JButton("Open a new modal dialog");
button.addActionListener(e -> showDialog(theParent));
dialogPanel.add(button);
dialog.add(dialogPanel);
dialog.pack();
dialog.setVisible(true);
}
}
}
答案 0 :(得分:1)
这是8u151中引入的错误。它已经修复,应该向后移植到下一个OpenJDK 8更新版本。 以下是您可以使用的解决方法:
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
dialog.removeWindowListener(this);
dialog.toFront();
}
});