Java 如何防止JFrame关闭但仍不工作
我正在测试这个问题的解决方案 我遇到的问题是,如果我尝试调用一个应用程序,例如,该解决方案将不起作用。因此,在调用Java 如何防止JFrame关闭但仍不工作,java,swing,reflection,jframe,Java,Swing,Reflection,Jframe,我正在测试这个问题的解决方案 我遇到的问题是,如果我尝试调用一个应用程序,例如,该解决方案将不起作用。因此,在调用Applic2main之后,不只是添加以下代码 Frame[] f2 = JFrame.getFrames(); for(Frame fx: f2){ if (fx instanceof JFrame) { JFrame aFrame = (JFrame)fx;
Applic2
main之后,不只是添加以下代码
Frame[] f2 = JFrame.getFrames();
for(Frame fx: f2){
if (fx instanceof JFrame) {
JFrame aFrame = (JFrame)fx;
aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
我创建了一个异步线程,它不断地将JFrame.EXIT\u on\u操作更改为JFrame.DISPOSE\u on\u CLOSE,如下所示
import java.awt.Frame;
import javax.swing.JFrame;
public class FrameMonitor extends Thread{
@Override
public void run(){
while(true){
Frame[] f2 = JFrame.getFrames();
for(Frame fx : f2){
if(fx instanceof JFrame){
JFrame aframe =(JFrame)fx;
aframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
}
}
}
并通过MyApp类中的start方法调用该线程实例。但解决方案并不奏效。但我仍然面临着同样的问题,所有的帧都在一帧上关闭。为什么会发生这种情况?有什么建议以及如何克服这种情况
请检查以下问题:
让我更详细地介绍这个问题
将代码添加到工作区
将以下包添加到房地产代码中
package MyApplication;
import java.awt.Frame;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.JFrame;
import edu.ncsu.realestate.gui.Main;
public class MYApp {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String arg[]){
FrameMonitor monitor = new FrameMonitor();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(200,200);
f.setVisible(true);
Class cls = Main.class;
Object[] actuals = { new String[] {} };
// cls.
Method[] mts=cls.getMethods();
for(Method m : mts){
//System.out.println(m);
}
Method m = null;
try {
m=cls.getMethod("main", new Class[] { String[].class } );
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
m.invoke(null,actuals);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Frame[] f2 = JFrame.getFrames();
for(Frame fx: f2){
System.out.println(fx.getTitle());
// fx.setVisible(false);
if (fx instanceof JFrame) {
// System.out.println("M here");
// System.out.println(fx.getTitle());
System.out.println(fx.getName());
JFrame aFrame = (JFrame)fx;
aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
}
}
package MyApplication;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.Timer;
public class FrameMonitor{
public FrameMonitor(){
Timer timer = new Timer(10000, new FrameMonitor2());
timer.setCoalesce(true);
timer.setRepeats(true);
timer.start();
}
public static class FrameMonitor2 implements ActionListener {
@Override
public void actionPerformed(ActionEvent ae) {
Frame[] frames = Frame.getFrames();
for (Frame frame : frames) {
if (frame instanceof JFrame) {
JFrame change = (JFrame) frame;
System.out.println("Before = " + change.getTitle() + " = " + change.getDefaultCloseOperation());
((JFrame)frame).setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
System.out.println("After = " + change.getTitle() + " = " + change.getDefaultCloseOperation());
}
}
}
}
}
现在调用MyApplication包的主要部分,哪个inturn调用RealEstate游戏。这就是解决方案不起作用的地方,尝试关闭不同的不动产框架,然后看到整个应用程序关闭。因此,我已经做了一个快速测试,我可以让它正常工作 首先,我创建了三个JFrames(都是相同的,因为我很匆忙),其中默认的关闭值设置为
EXIT\u ON\u close
我验证了如果我关闭一个,它将关闭所有三个
然后我使用javax.swing.Timer
在可用帧列表中重复循环,并将默认关闭值设置为DISPOSE\u ON\u close
Timer timer = new Timer(1000, new UpdateTask());
timer.setCoalesce(true);
timer.setRepeats(true);
timer.start();
一旦执行,我就能够监视以下输出
Before = Frame 01 = 3
After = Frame 01 = 2
Before = Frame 02 = 3
After = Frame 02 = 2
Before = Frame 03 = 3
After = Frame 03 = 2
Before = Frame 01 = 2
After = Frame 01 = 2
Before = Frame 02 = 2
After = Frame 02 = 2
Before = Frame 03 = 2
After = Frame 03 = 2
如你所见。在第一次迭代中,帧从“3”变为“2”,并一直保持这种状态,直到我厌倦了输出并终止程序
我还检查了关闭一个或多个帧是否会退出程序
现在,有一个重要的提示。我相信这只适用于已经实现的帧(在屏幕上可见),但您可以测试这一点,看看您得到了什么;) 我快速检查了房地产游戏的代码,在
MainWindow.java中发现了您的问题:
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
如果您仍然希望窗口关闭,我不确定您可以从外部对此做些什么。一种方法(不一定是最好的)是实现自定义安全管理器
import java.awt.*;
import java.awt.event.*;
import java.security.Permission;
/** NoExit demonstrates how to prevent 'child'
applications from ending the VM with a call
to System.exit(0).
@author Andrew Thompson */
public class NoExit extends Frame implements ActionListener {
Button frameLaunch = new Button("Frame"),
exitLaunch = new Button("Exit");
/** Stores a reference to the original security manager. */
ExitManager sm;
public NoExit() {
super("Launcher Application");
sm = new ExitManager( System.getSecurityManager() );
System.setSecurityManager(sm);
setLayout(new GridLayout(0,1));
frameLaunch.addActionListener(this);
exitLaunch.addActionListener(this);
add( frameLaunch );
add( exitLaunch );
pack();
setSize( getPreferredSize() );
}
public void actionPerformed(ActionEvent ae) {
if ( ae.getSource()==frameLaunch ) {
TargetFrame tf = new TargetFrame();
} else {
// change back to the standard SM that allows exit.
System.setSecurityManager(
sm.getOriginalSecurityManager() );
// exit the VM when *we* want
System.exit(0);
}
}
public static void main(String[] args) {
NoExit ne = new NoExit();
ne.setVisible(true);
}
}
/** This example frame attempts to System.exit(0)
on closing, we must prevent it from doing so. */
class TargetFrame extends Frame {
static int x=0, y=0;
TargetFrame() {
super("Close Me!");
add(new Label("Hi!"));
addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.out.println("Bye!");
System.exit(0);
}
});
pack();
setSize( getPreferredSize() );
setLocation(++x*10,++y*10);
setVisible(true);
}
}
/** Our custom ExitManager does not allow the VM
to exit, but does allow itself to be replaced by
the original security manager.
@author Andrew Thompson */
class ExitManager extends SecurityManager {
SecurityManager original;
ExitManager(SecurityManager original) {
this.original = original;
}
/** Deny permission to exit the VM. */
public void checkExit(int status) {
throw( new SecurityException() );
}
/** Allow this security manager to be replaced,
if fact, allow pretty much everything. */
public void checkPermission(Permission perm) {
}
public SecurityManager getOriginalSecurityManager() {
return original;
}
}
请注意,不要从ETD以外的任何线程修改Swing组件,当我们考虑您的问题时,请阅读Swing中的并发性此解决方案不适用于房地产问题:(正如前面的链接中所提到的,为什么会发生这种情况?是因为房地产游戏的框架对象不可访问或无法锁定???+1以查找它:-)至于如何处理它:如果有对该窗口的引用,请删除侦听器(通过window.getWindowListener()循环)并删除同名上下文中的匿名,类似于MainWindow$
import java.awt.*;
import java.awt.event.*;
import java.security.Permission;
/** NoExit demonstrates how to prevent 'child'
applications from ending the VM with a call
to System.exit(0).
@author Andrew Thompson */
public class NoExit extends Frame implements ActionListener {
Button frameLaunch = new Button("Frame"),
exitLaunch = new Button("Exit");
/** Stores a reference to the original security manager. */
ExitManager sm;
public NoExit() {
super("Launcher Application");
sm = new ExitManager( System.getSecurityManager() );
System.setSecurityManager(sm);
setLayout(new GridLayout(0,1));
frameLaunch.addActionListener(this);
exitLaunch.addActionListener(this);
add( frameLaunch );
add( exitLaunch );
pack();
setSize( getPreferredSize() );
}
public void actionPerformed(ActionEvent ae) {
if ( ae.getSource()==frameLaunch ) {
TargetFrame tf = new TargetFrame();
} else {
// change back to the standard SM that allows exit.
System.setSecurityManager(
sm.getOriginalSecurityManager() );
// exit the VM when *we* want
System.exit(0);
}
}
public static void main(String[] args) {
NoExit ne = new NoExit();
ne.setVisible(true);
}
}
/** This example frame attempts to System.exit(0)
on closing, we must prevent it from doing so. */
class TargetFrame extends Frame {
static int x=0, y=0;
TargetFrame() {
super("Close Me!");
add(new Label("Hi!"));
addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.out.println("Bye!");
System.exit(0);
}
});
pack();
setSize( getPreferredSize() );
setLocation(++x*10,++y*10);
setVisible(true);
}
}
/** Our custom ExitManager does not allow the VM
to exit, but does allow itself to be replaced by
the original security manager.
@author Andrew Thompson */
class ExitManager extends SecurityManager {
SecurityManager original;
ExitManager(SecurityManager original) {
this.original = original;
}
/** Deny permission to exit the VM. */
public void checkExit(int status) {
throw( new SecurityException() );
}
/** Allow this security manager to be replaced,
if fact, allow pretty much everything. */
public void checkPermission(Permission perm) {
}
public SecurityManager getOriginalSecurityManager() {
return original;
}
}