How to prevent JFrame from closing
Asked Answered
S

3

8

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??

enter image description here

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();
        }
Supercilious answered 2/7, 2012 at 20:28 Comment(13)
but you don't have access to JFrame object? if yes you could just set the defaultCloseOperationPoston
@Spaeth I do not have access to defaultcloseOperation of invoked application as I mentionedSupercilious
how do you do to open the second window? you mentioned reflection, could you show exactly how you do to open the second window?Poston
@Spaeth Yes I am loading the compiled classes of the second application in question using 'customClassLoader' then by searching the main method of the application using reflection I am invoking the second applicationSupercilious
but in this case you have the second JFrame instantiated... even with reflection you can use it and set the defaultCloseOperation. Please attach the source code in order to provide more details...Poston
@Spaeth if the diagram can help you in understanding my problem please let me know else I would post the codes because they are really lengthySupercilious
@Spaeth ok I am posting the code :)Supercilious
Ok, now I got your problem, you invoke main right?Poston
@Spaeth Yes and now the problem rises when I close the target application my application also closes :(Supercilious
ok, check my answer... maybe you can follow that approach... please let me know your results ;)Poston
maybe you could first iterate over the windows in order to see how can you detect the one you need to change the defaultcloseoperation... can you debug it?Poston
@Spaeth target application is available as Jar and cannot do much about it I believe threads have something to do with this. Let me do a few hour work on it and then I hope I can come up with a solution. The target application is not always guaranteed to contain frames but whenever it does contain, I am facing this problem.Supercilious
I see, maybe you could get the windows before invoke the application, and then get windows again after invoke it, and check what is new on windows list, the new one you set the close operation.Poston
N
3

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.

Noranorah answered 3/7, 2012 at 7:21 Comment(0)
B
11

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.

Bumkin answered 2/7, 2012 at 20:31 Comment(3)
Yes your right all the windows are closing and your reason seems to be correct. However, I do not have access to the source code of invoked application hence cannot change its default close operationSupercilious
If you're invoking the application using reflection, then why can't you set the default close operation using reflection while you're at it?Anhwei
@RoddyoftheFrozenPeas I am not allowed to make changes to the application being invoked. All I can change is my codeSupercilious
P
6

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 ;)

Poston answered 2/7, 2012 at 20:29 Comment(1)
No this does not solve my problem The invoker application has its own JFrame that has to be prevented from closing on closing Jframe of invoked applicationSupercilious
N
3

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.

Noranorah answered 3/7, 2012 at 7:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.