【发布时间】:2011-09-12 15:46:24
【问题描述】:
不幸的是,最近关闭的question 似乎没有得到很好的理解。这是典型的输出:
run:
Trying to Remove JDialog
Remove Cycle Done :-)
Checking if still exists any of TopLayoutContainers
JFrame
JDialog
Will Try Remove Dialog again, CycleNo. 1
-----------------------------------------------------------
Trying to Remove JDialog
Remove Cycle Done :-)
Checking if still exists any of TopLayoutContainers
JFrame
JDialog
Will Try Remove Dialog again, CycleNo. 2
-----------------------------------------------------------
Trying to Remove JDialog
Remove Cycle Done :-)
Checking if still exists any of TopLayoutContainers
JFrame
JDialog
Will Try Remove Dialog again, CycleNo. 3
-----------------------------------------------------------
Trying to Remove JDialog
Remove Cycle Done :-)
Checking if still exists any of TopLayoutContainers
JFrame
JDialog
*** End of Cycle Without Success, Exit App ***
BUILD SUCCESSFUL (total time: 13 seconds)
我会再次尝试问这个问题:我如何在 Runtime 上了解第一个打开的顶级 Container,并帮助我关闭 Swing NightMares 之一?
import java.awt.*;
import java.awt.event.WindowEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class RemoveDialogOnRuntime extends JFrame {
private static final long serialVersionUID = 1L;
private int contID = 1;
private boolean runProcess;
private int top = 20;
private int left = 20;
private int maxLoop = 0;
public RemoveDialogOnRuntime() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 300));
setTitle("Remove Dialog On Runtime");
setLocation(150, 150);
pack();
setVisible(true);
Point loc = this.getLocation();
top += loc.x;
left += loc.y;
AddNewDialog();
}
private void AddNewDialog() {
DialogRemove firstDialog = new DialogRemove();
remWins();
}
private void remWins() {
runProcess = true;
Thread th = new Thread(new RemTask());
th.setDaemon(false);
th.setPriority(Thread.MIN_PRIORITY);
th.start();
}
private class RemTask implements Runnable {
@Override
public void run() {
while (runProcess) {
Window[] wins = Window.getWindows();
for (int i = 0; i < wins.length; i++) {
if (wins[i] instanceof JDialog) {
System.out.println(" Trying to Remove JDialog");
wins[i].setVisible(false);
wins[i].dispose();
WindowEvent windowClosing = new WindowEvent(wins[i], WindowEvent.WINDOW_CLOSING);
wins[i].dispatchEvent(windowClosing);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowClosing);
Runtime runtime = Runtime.getRuntime();
runtime.gc();
runtime.runFinalization();
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(RemoveDialogOnRuntime.class.getName()).log(Level.SEVERE, null, ex);
}
}
wins = null;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println(" Remove Cycle Done :-)");
Runtime.getRuntime().runFinalization();
Runtime.getRuntime().gc();
runProcess = false;
}
});
}
pastRemWins();
}
}
private void pastRemWins() {
System.out.println(" Checking if still exists any of TopLayoutContainers");
Window[] wins = Window.getWindows();
for (int i = 0; i < wins.length; i++) {
if (wins[i] instanceof JFrame) {
System.out.println("JFrame");
wins[i].setVisible(true);
} else if (wins[i] instanceof JDialog) {
System.out.println("JDialog");
wins[i].setVisible(true);
}
}
if (wins.length > 1) {
wins = null;
maxLoop++;
if (maxLoop <= 3) {
System.out.println(" Will Try Remove Dialog again, CycleNo. " + maxLoop);
System.out.println(" -----------------------------------------------------------");
remWins();
} else {
System.out.println(" -----------------------------------------------------------");
System.out.println("*** End of Cycle Without Success, Exit App ***");
closeMe();
}
}
}
private void closeMe() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
System.exit(0);
}
});
}
private class DialogRemove extends JDialog {
private static final long serialVersionUID = 1L;
DialogRemove(final Frame parent) {
super(parent, "SecondDialog " + (contID++));
setLocation(top, left);
top += 20;
left += 20;
setPreferredSize(new Dimension(200, 200));
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModalityType(Dialog.ModalityType.MODELESS);
pack();
setVisible(true);
}
private DialogRemove() {
setTitle("SecondDialog " + (contID++));
setLocation(top, left);
top += 20;
left += 20;
setPreferredSize(new Dimension(200, 200));
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModalityType(Dialog.ModalityType.MODELESS);
pack();
setVisible(true);
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
RemoveDialogOnRuntime superConstructor = new RemoveDialogOnRuntime();
}
});
}
}
【问题讨论】:
-
@mKorbel,就像我之前所说的,将引用设置为
null,那么它将有资格进行垃圾收集。 -
@mre :-) 我非常感谢您在我之前的帖子中为删除对 Array 的引用所做的输入,并尝试通过 Object 从 Class(es) 中删除它,但仍然存在一个 JDialog 和一个 JWindow ... :-)
-
您的示例代码违反了“EDT 黄金法则”:永远不要从除 EDT 之外的其他线程调用 Swing 方法。当您调用 dispose() 时,您不在 EDT 中! pastRemWins() 中 setVisible() 的注释相同。
-
如果您可以通过“删除容器”来指定您的意思,例如,您的问题会更清楚。删除窗口的操作系统资源,隐藏窗口,收集窗口使用的 Java 对象使用的内存...
-
dispose()明确记录为释放窗口使用的所有操作系统资源,因此不是它的 java 部分! Javadoc 甚至提到调用pack()或setVisible(true)将重新创建新的操作系统资源以使窗口可显示。
标签: java swing runtime jdialog