我们有一个请求,根据某些控件,某些对话框应始终位于顶部。必须在每个对话框的基础上打开/关闭它。 在我看来,使用以下代码并执行以下步骤就像Java错误一样:
预期:dialog2保持在最顶层,dialog1不在
实际:没有任何对话框保留在最顶层。
这与对话框的所有者有一些联系。如果取消注释块注释,一切都按预期工作,但我认为这不是正常行为,因为Always on Top不应该连接到父级。这是正常的还是Swing的问题?不幸的是,为每个对话框设置新的所有者会引入其他问题。
public static void main(String[] args) {
final JFrame rahan = new JFrame("Rahan");
rahan.setSize(new Dimension(1000,1000));
rahan.setVisible(true);
JDialog d1 = getJDialog(/*new JFrame()*/);
JDialog d2 = getJDialog(/*new JFrame()*/);
}
private static JDialog getJDialog(/*JFrame owner*/) {
final JDialog jDialog = new JDialog(/*owner*/);
final JButton onTop = new JButton("OnTop");
onTop.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jDialog.setAlwaysOnTop(!jDialog.isAlwaysOnTop());
}
});
jDialog.add(onTop);
jDialog.setVisible(true);
jDialog.pack();
return jDialog;
}
答案 0 :(得分:1)
如果我像这样运行您的应用程序:
public static void main(String[] args) {
final JFrame rahan = new JFrame("Rahan");
rahan.setSize(new Dimension(1000,1000));
rahan.setVisible(true);
JDialog d1 = getJDialog(rahan);
JDialog d2 = getJDialog(rahan);
}
private static JDialog getJDialog(JFrame owner) {
final JDialog jDialog = new JDialog(owner);
final JButton onTop = new JButton("OnTop");
onTop.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
jDialog.setAlwaysOnTop(!jDialog.isAlwaysOnTop());
}
});
jDialog.add(onTop);
jDialog.setVisible(true);
jDialog.pack();
return jDialog;
}
}
完美无缺。这两个对话框始终位于顶部,并且它不是模态的,因此您可以单击该框架。
您可以尝试将对话框设置为模态,如下所示:
jDialog.setModal(true);
但这与你正在实现的目标背道而驰?
答案 1 :(得分:1)
查看setAlwaysOnTop
的代码,将这些代码直接发送到窗口对等体,因此这可能是依赖于操作系统的问题。
其次,您是否尝试在事件派发线程上进行所有创建?在此问题的前一篇文章中提出了这一点。
JDialog.setAlwaysOnTop(true) brings all dialogs to the front under Windows
答案 2 :(得分:1)
不确定此问题是否仍然相关,但我发现了该问题的潜在解决方法。如果您保留每次创建新窗口时所添加的所有可能“永远在线”的窗口的列表,您可以返回并关闭它们然后再打开以将它们放回原位。 / p>
ArrayList<Window> = new ArrayList<Window>();
.
.
.
void createWindow() {
Window w = new Window();
windowList.add(w);
}
然后,当其中一个窗口的“Always on Top”按钮关闭时,您将返回到windowList并切换所有设置为始终位于顶部的窗口。以下内容应该在动作监听器的actionPerformed函数中切换“Always on Top”:
if (!windowAlwaysOnTopButton.isSelected()) {
ArrayList<Window> turnedOff = new ArrayList<Window>();
for (Window w : windowList) {
if (w.isAlwaysOnTop()) {
w.setAlwaysOnTop(false);
turnedOff.add(w);
}
}
for (Window w : turnedOff) {
w.setAlwaysOnTop(true);
}
}
你需要两个for循环和turnOff列表,因为如果你在同一个循环中再关闭然后再打开,你会遇到原始问题,如果Windows A和B总是在顶部,那么Window A被关闭,Window B也将关闭。这就是为什么你需要将它们全部关闭,然后再次循环以重新打开它们。我意识到这可能是一个hackey解决方案,但如果它对我有用,它可能只对你有用。干杯!