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

时间:2012-07-20 05:13:30

标签: java reflection jvm jframe classloader

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

How to prevent JFrame from closing

所以我发布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调用Applic2的实例,该实例进一步调用NewFrame3的实例。就像我们可以看到我关闭'NewFrame3'的实例或Applic2的实例一样,整个程序关闭(由于EXIT_ON_CLOSE)语句。

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

我无法对APPlic2或NewFrame3进行任何更改。通过反思如果我们尝试将EXIT_ON_CLOSE转为DISPOSE_ON_CLOSE当我们没有扩展setDefaultCloseOperation()课程时,我们如何访问这些框架及其JFrames

在提到的另一个解决方案中,应该创建一个新的JVM实例,并且应该在这个新Applic2实例的新进程中执行JVM。但后来我遇到了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中实例化的帧。为什么会出现这种情况?

3 个答案:

答案 0 :(得分:2)

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

然后,你需要走过去,检查每一帧,看它是否符合你的要求。之后,您不需要反射,您可以直接访问框架

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

更新示例

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

      JFrame aFrame = (JFrame)frame;

  }
}

答案 1 :(得分:1)

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

这引发了端口号等问题,但你实际上可以做一个过去的事情(基本上,“干什么人,我在这里,来跟我说话”),这可以用来确定谁可用是否 - 请查看Broadcasting to Multiple Recipients作为示例。

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

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

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

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

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

答案 2 :(得分:1)

所以在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);

                      }
                    }

    }

}