在这种情况下,JVM或reflection的新实例是否有用

我之前发过一个问题,但没有明确的解决方案

如何防止JFrame关闭 。

所以我发布的SSCCE可能有助于更好地理解所面临的问题

package myApp; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.swing.JFrame; import App2.Applic2; public class MYApp { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String arg[]){ JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setTitle("Application frame 1"); f.setSize(200,200); f.setVisible(true); Class cls = Applic2.class; Object[] actuals = { new String[] { "" } }; 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(); } } } 

第二个包

 package App2; import javax.swing.JFrame; public class Applic2 { @SuppressWarnings("unused") public static void main(String args[]){ JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(200,200); f.setVisible(true); f.setTitle("This needs not to be changed"); NewFrame3 Frame3 = new NewFrame3(); } } 

第二类App2包。

 package App2; import javax.swing.JFrame; public class NewFrame3 { public NewFrame3(){ JFrame f = new JFrame(); f.setTitle("f3"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(200,200); f.setLocation(200, 200); f.setVisible(true); } } 

MYAPP调用MYAPP实例,该实例进一步调用NewFrame3实例。 就像我们可以看到我关闭’NewFrame3’的实例或Applic2的实例Applic2 ,整个程序关闭(由于EXIT_ON_CLOSE )语句。

我想要一个解决方案, MYAPP不应该在关闭Applic2NewFrame3时关闭。

我无法对APPlic2或NewFrame3进行任何更改。 通过reflection如果我们试图将EXIT_ON_CLOSE转为DISPOSE_ON_CLOSE当我们没有扩展JFrames类时,我们如何访问这些帧及其setDefaultCloseOperation()

在提到的另一个解决方案中,应该创建一个新的JVM实例, Applic2应该在这个新的JVM实例上的新进程中执行Applic2 。 但后来我遇到了runtime.exec将Java命令作为输入而不是像method.invoke()这样的Java语句。

我可以通过加载了Applic2的加载器访问Applic2我只能在内存中访问Applic2的类文件,所以我无法使用jar在runtime.exec()中运行。 现在我该如何解决?

将这些语句添加到MYApp classensures,单击关闭框架的关闭按钮没有任何反应,但这似乎不是这样的

 Frame[] f2 = JFrame.getFrames(); for(Frame fx: f2){ System.out.println(fx.getTitle()); fx.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent we){ } }); 

并且此代码需要添加到实例化的最后一帧,否则它会返回所有帧。 即,如果将此帧添加到JFrame3类,则返回所有实例化帧,如果添加到MyApp中,则返回MyApp中的JFrame,如果添加了Applic2,则返回在MYApp和Applic2中实例化的帧。 为什么这个行为?

您可以使用JFrame.getFrames()返回一个Frame数组(您也可以使用getWindows()获取当前应用程序上下文中创建的那些窗口的低级别列表)。

然后,您需要完成检查,检查每个框架是否符合您的要求。 之后,您不需要reflection,您可以直接访问帧

与其他JVM通信的唯一方法是通过套接字通信(例如RMI)。

更新示例

 Frame[] listOfFrames = JFrame.getFrames(); for (Frame : listOfFrames) { if (frame instanceof JFrame) { JFrame aFrame = (JFrame)frame; } } 

跨进程通信并不是一件简单的事情。 基本上,您要与之通信的每个进程都需要具有ServerSocket ,以便接收传入的请求。 如果要执行双向通信,每个进程都需要拥有自己的ServerSocket ,这将允许任何进程启动通信。

这引发了端口号等问题,但你实际上可以做一个过去的事情(基本上,“干什么人,我在这里,来跟我说话”),这可以用来确定谁可用 – 看一下广播到多个收件人的例子。

所以。 准备就绪后,您将在其端口上打开与相关进程(localhost / 127.0.0.1)的套接字连接并开始聊天。

现在。 我看到你所描述的问题是,为了让它运行,你将需要某种启动器,它可以创建服务器套接字,然后执行现有程序(就像你一样)已经描述过),这提出了为什么? 如果您的唯一目标是让这些框架停止关闭您的应用程序,只需在新的JVM中启动该程序即可实现该目标。 显然,如果你仍然需要更多来自他们的信息,那么这是所有努力工作的合理借口。

现在,好消息是,您可以跨套接字序列化对象(也就是说,您可以通过套接字连接发送Java对象),查看发现Java序列化API的秘密以获取更多信息。

现在,如果这还没有吓到你,请查看All About Sockets以获取更多信息。

最后,关于“如何”执行新JVM的重大问题,请查看Java ProcessBuilder ,它实际上描述了一种可以执行新JVM的方法!

所以在MadProgrammer amd mKorbel提供的帮助下完成了解决方案,这里是更新的MYApp课程

 package myApp; import java.awt.Frame; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.swing.JFrame; import App2.Applic2; public class MYApp { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String arg[]){ JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setTitle("Application frame 1"); f.setSize(200,200); f.setVisible(true); Class cls = Applic2.class; Object[] actuals = { new String[] { "" } }; Method m = null; try { m=cls.getMethod("main", new Class[] { String[].class } ); Method[] m1 =Frame.class.getDeclaredMethods(); } 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(); // Window[] f23= JFrame.getFrames(); for(Frame fx: f2){ System.out.println(fx.getTitle()); // fx.setVisible(false); if (fx instanceof JFrame) { JFrame aFrame = (JFrame)fx; aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } } } }