Java 在这种情况下,JVM或反射的新实例会有帮助吗
我以前发布过一个问题,但没有得到明确的解决方案 因此,我发布了一个SSCCE,这可能有助于更好地理解所面临的问题Java 在这种情况下,JVM或反射的新实例会有帮助吗,java,reflection,jvm,jframe,classloader,Java,Reflection,Jvm,Jframe,Classloader,我以前发布过一个问题,但没有得到明确的解决方案 因此,我发布了一个SSCCE,这可能有助于更好地理解所面临的问题 package myApp; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.swing.JFrame; import App2.Applic2; public class MYApp { @SuppressWarni
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
调用Applic2
的实例,后者进一步调用NewFrame3
的实例。我们可以看到,如果我关闭'NewFrame3'的实例或Applic2的实例,整个程序将关闭(由于EXIT\u ON\u close
)语句
我想要一个解决方案,其中MYAPP
不应在关闭Applic2
或NewFrame3
时关闭
我无法对APPlic2或NewFrame3进行任何更改。通过反射,如果我们试图将EXIT\u ON\u CLOSE
打开DISPOSE\u ON\u CLOSE
打开
在前面提到的另一个解决方案中,应该创建一个新的JVM
实例,并且应该在这个新的JVM
实例上的一个新进程中执行Applic2
。但后来我发现runtime.exec接受Java命令作为输入,而不是像method.invoke()
这样的Java语句
我可以通过加载Applic2的加载程序访问Applic2。我只能访问内存中Applic2的类文件,因此无法使用jar在runtime.exec()中运行。现在我该怎么解决呢
将这些语句添加到MYApp
类中可确保在单击帧的关闭按钮时不会发生任何事情,但情况似乎并非如此
Frame[] f2 = JFrame.getFrames();
for(Frame fx: f2){
System.out.println(fx.getTitle());
fx.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
}
});
这段代码需要添加到实例化的最后一个帧中,否则它会返回所有帧。i、 例如,如果将此帧添加到JFrame3类中,则返回所有实例化的帧,如果将其添加到MyApp中,则返回MyApp中的JFrame;如果添加了Applic2,则返回MyApp和Applic2中实例化的帧。为什么会出现这种行为???您可以使用JFrame.getFrames()
返回Frame
数组(您还可以getWindows()
查看在当前应用程序上下文中创建的那些窗口的较低级别列表)
然后,您需要遍历,检查每个帧,看看它是否满足您的要求。之后,你不需要反射,你可以直接进入画面
与其他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对象),查看更多信息
现在,如果这还没有吓跑你,请查看更多信息
最后,“如何”执行一个新JVM这个大问题,它实际上描述了一种执行新JVM的方法 在MadProgrammer和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);
}
}
}
}
+1对于你的答案,这个解决方案似乎很有帮助,让我来实施它,并将答案贴在这里给你。但是,您可以建议如何使用新的JVM实例以另一种方式实现它。您是指其他JVM吗?您想与它对话(跨进程通信)还是执行它?是的,完全正确!!跨进程通信。执行应用程序的新进程但是getFrames()返回awt帧,如何更改这些帧的DefaultCloseOperation(awt帧没有任何这样的方法)JFrame从java.awt.frame扩展而来,您应该检查该帧是否是JFrame的实例,然后将其强制转换