2012-07-02 275 views
7

我有一个Java GUI应用程序,使用反射和加载从中调用另一个Java GUI应用程序。它工作正常唯一的问题是,在关闭被调用的应用程序的JFrame时,Main GUI应用程序框架也关闭。我如何防止主应用程序(框架)关闭?如何防止JFrame关闭

我无法更改被调用应用程序的defaultCloseOperation,但是可以对主应用程序进行更改。它与线程有什么关系?

enter image description here

这是我的应用程序代码,执行目标应用

public class ClassExecutor{ 

    private ClassLoaderOfExtClass classLoader; 
    private byte[][] ArrayOfClasses; 
    private String[] ArrayOfBinaryNames; 
    @SuppressWarnings("rawtypes") 
    private ArrayList<Class> loadedClasses; 
    private ArrayList<String> loadedClasesNames; 
    private Object[] parameters; 


    @SuppressWarnings("rawtypes") 
    public ClassExecutor() { 
     classLoader = new ClassLoaderOfExtClass(); 
     new ArrayList<Class>(); 
     loadedClasses = new ArrayList<Class>(); 
     loadedClasesNames = new ArrayList<String>(); 
    } 

    @SuppressWarnings("unchecked") 
    public void execute(File[] file, String[] binaryPaths) { 
     Object[] actuals = { new String[] { "" } }; 
     Method m = null; 
     try { 
      Field classesx=ClassLoaderOfExtClass.class.getDeclaredField("classes"); 
      classesx.setAccessible(true); 
     } catch (SecurityException e1) { 
      e1.printStackTrace(); 
     } catch (NoSuchFieldException e1) { 
      e1.printStackTrace(); 
     } 


     /*for (int i = 0; i < file.length; i++) { 
      for (int j = 0; j < file.length; j++) { 

       try { 

        @SuppressWarnings("rawtypes") 
        Class c = classLoader.loadClassCustom(file[i], binaryPaths[i]); 
       //Fied classex=classLoader.getResource("classes"); 
       }catch(Exception e){ 

       } 

      } 
     } 
     Class<?>[]classesxx= getLoadedClasses(classLoader); 
     System.out.println("Loaded classes have size "+ classesxx.length);*/ 

     for (int i = 0; i < file.length; i++) { 
      try { 
       @SuppressWarnings("rawtypes") 
       Class c = classLoader.loadClassCustom(file[i], binaryPaths[i]); 

       try { 
        if (c.getMethod("main", new Class[] { String[].class }) != null) { 
         m = c.getMethod("main", new Class[] { String[].class }); 
        } else { 

         System.out.println("This class does not contain main"); 
         continue; 
        } 

       } catch (NoSuchMethodException e) { 
       // System.out.println("Main not found!!!"); 
        // System.out.println("M here"); 
        // e.printStackTrace(); // not printing stack trace 
       } catch (SecurityException e) { 
        e.printStackTrace(); 
       } 

      } catch (ClassNotFoundException e) { 
       System.out.println("No such class definition exist!!"); 
       // TODO Auto-generated catch block 
       // e.printStackTrace(); 
      } 

     } 

     try { 

      m.invoke(null, actuals); 

      // CallStack.print(); 
     } catch (IllegalArgumentException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InvocationTargetException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    @SuppressWarnings({ "unchecked", "rawtypes" }) 
    public void execute(ArrayList<byte[]> stuffedFiles, 
      ArrayList<String> binaryPaths) { 
     convertToArray(stuffedFiles, binaryPaths); 
     loadAllClasses(ArrayOfClasses, ArrayOfBinaryNames); 
     Object[] actuals = { new String[] { "" } }; 
     Method m = null; 

     /* 
     * Method[] m1= new Method[10]; for (Class c : loadedClasses) { 
     * m1=c.getMethods(); } for(Method m2: m1){ 
     * System.out.println(m2.getName()); } 
     */ 
     /* System.out.println(loadedClasses.size()); */ 
     for (Class c : loadedClasses) { 
      /* 
      * System.out.println(c.toString()); 
      * System.out.println(c.getConstructors()); 
      */ 
      // for (int i = 1; i < file.size(); i++) { 
      /* 
      * for(Method meth : c.getMethods()){ meth.setAccessible(true); 
      * 
      * } 
      */ 

      try { 
       if (c.getMethod("main", new Class[] { String[].class }) != null) { 
        m = c.getMethod("main", new Class[] { String[].class }); 
        break; 
       } else { 

       // System.out.println("This class does not contain main"); 
        continue; 
       } 

      } catch (NoSuchMethodException e) { 

       System.out.println("Program does not contain main"); 

      } catch (SecurityException e) { 
       e.printStackTrace(); 
      } 

     } 

     try { 

      if(parameters==null){ 

      m.invoke(null, actuals); 
      } 
      else{ 
       try { 

        System.out.println("It Fails Here"); 
        m.invoke(null, parameters); 
       } catch (Exception e) { 
        System.out.println("Illegal arguments"); 
       } 
      } 

      // CallStack.print(); 
     } catch (IllegalArgumentException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InvocationTargetException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
+0

但您无权访问JFrame对象?如果是的话,你可以只设置'defaultCloseOperation' –

+0

@Spaeth我没有访问被调用的应用程序的defaultcloseOperation,因为我提到 –

+0

你怎么做到打开第二个窗口?你提到了反思,你能否准确地展示你如何打开第二个窗口? –

回答

3

我不允许对正在调用的应用程序进行更改。

那是在回答@JeffLaJoie评论只是为了澄清,也不会要求任何变化对其他应用程序的代码,只是一个额外的方法调用或两个由您的应用程序。在运行时设置第三方帧的关闭操作。


做不到这一点,我能想到的最好的解决办法是在一个单独的Process启动一个新的JVM启动新框架,当用户关闭其他应用程序,它与第二个JVM将结束,同时离开原来的应用程序。在屏幕上。

6

你必须为defaultCloseOperation以下选项:

  • DO_NOTHING_ON_CLOSE - 关闭什么都不做的默认窗口操作;
  • HIDE_ON_CLOSE - 隐藏窗口默认窗口关闭操作;
  • DISPOSE_ON_CLOSE - 处置窗口默认窗口关闭操作。
  • EXIT_ON_CLOSE - 退出应用程序默认窗口关闭操作。尝试在Windows上设置此支持,例如JFrame,可能会根据SecurityManager引发SecurityException。建议你只在应用程序中使用它。

可以使用选项DISPOSE_ON_CLOSE以避免关闭所有窗口,只关闭所需窗口。

如果您没有直接访问JFrame对象的方法,那么您可以使用Window.getWindows()来接收所有的Windows实例(因为JFrame也是Window也会列出)。然后设置defaultCloseOperation

可能需要使用线程,因为需要在调用main方法之后设置defaultCloseOperation

理论上它的工作原理,所以我认为这是一个好球;)

+0

不,这不能解决我的问题调用者应用程序有其自己的JFrame,必须阻止关闭被调用的应用程序的Jframe –

+1

可能是一个注册的窗口监听器'System.exit'也... – dacwe

11

你想使用DISPOSE_ON_CLOSE操作,所以这将是setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)

EXIT_ON_CLOSE将是关闭的选项我相信所有的窗户都是你目前正在经历的。

+3

可能是一个注册的窗口侦听器,'System.exit'也... – dacwe

+0

是的,你的权利,所有的窗户正在关闭,你的理由似乎是正确的。但是,我无权访问调用的应用程序的源代码,因此无法更改其默认关闭操作。 –

+0

如果您使用反射调用应用程序,那么为什么不能在使用反射时设置默认关闭操作它? –