I have a Java GUI application from which another java GUI application is invoked using reflection and loading. It works fine the only problem faced is, on closing the JFrame
of invoked application the Main GUI
application frame also closes. How can I prevent the main application (frame) from closing??
I cannot change the defaultCloseOperation
of the invoked application, However a change to the main application can be made. Does it have any thing to do with threads??
This is my applications code that executes a target application
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();
}
You'll want to use the DISPOSE_ON_CLOSE operation, so it would be setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
EXIT_ON_CLOSE would be the option that closes all windows which I believe is what you are currently experiencing.
You have the following options for the defaultCloseOperation
:
DO_NOTHING_ON_CLOSE
- The do-nothing default window close operation;HIDE_ON_CLOSE
- The hide-window default window close operation;DISPOSE_ON_CLOSE
- The dispose-window default window close operation.EXIT_ON_CLOSE
- The exit application default window close operation. Attempting to set this on Windows that support this, such as JFrame, may throw a SecurityException based on the SecurityManager. It is recommended you only use this in an application.The Option DISPOSE_ON_CLOSE
could be used in order to avoid to close all windows, closing just the one you want.
If you don't have direct access to JFrame object as you have with the last posted code, you could use Window.getWindows() in order to receive all windows instance (as JFrame
is a Window
too it will be listed too). And then set the defaultCloseOperation
on that.
Possibly you will need to use threads because the defaultCloseOperation
needs to be set after invoke main method.
Theoretically it works, so I think this is a good shot ;)
I am not allowed to make changes to the application being invoked.
That was a comment in reply to @JeffLaJoie just to clarify, it would not require any changes to the code of the other app., just an extra method call or two by your app. at run-time to set the close operation of the 3rd party frame.
Failing that, the best solution I can think of is to start the new frame in a separate Process
that starts a new JVM, when the user closes the other app., it and the 2nd JVM will end, while leaving the original app. on-screen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With