2012-07-02 48 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

如果您使用反射調用應用程序,那麼爲什麼不能在使用反射時設置默認關閉操作它? –