3

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

如何防止 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调用实例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().

我可以通过加载 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){


                      }
                      });

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

4

3 回答 3

2

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

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

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

更新示例

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

      JFrame aFrame = (JFrame)frame;

  }
}
于 2012-07-20T05:21:42.223 回答
1

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

这会引发端口号等问题,但您实际上可以通过组播来解决这个问题(基本上,“大家好,我在这里,来和我说话”),它可以用来确定谁可用或不可用 -以Broadcasting to Multiple Recipients为例。

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

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

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

现在,如果这还没有吓到您,请查看All About Sockets了解更多信息。

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

于 2012-07-20T05:49:16.043 回答
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);

                      }
                    }

    }

}
于 2012-07-20T10:00:05.513 回答