2

I would like some clarity on what is exactly happening here. Say I have these three methods and I continually hit the button again and again. Is this causing some kind of memory leak or chain of pointers that I am unaware of? My understand is that when a method ends any variables local to that method are cleaned up. This would include that "pointer" to the new JFrame then correct?

Again assume the user is clicking the button on each frame.

    public class driver {


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        parentFrame pF = new parentFrame();
    }
}

-

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class parentFrame extends JFrame {

    private JFrame frame; 
    private JButton button;

    public parentFrame() {
        frame = new JFrame("Parent Frame");
        frame.setSize(400, 400);
        button = new JButton();
        frame.add(button);
        button.addActionListener(new buttonPress());
        frame.setVisible(true);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void createChild() {
        @SuppressWarnings("unused")
        childFrame cF = new childFrame(); //The default constructor will display the frame
        frame.dispose(); //How?
    }

    class buttonPress implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            createChild();
        }
    }

}

-

    import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class childFrame extends JFrame {

    private JFrame frame; 
    private JButton button;

    public childFrame() {
        frame = new JFrame("Child Frame");
        frame.setSize(400, 400);
        button = new JButton();
        frame.add(button);
        button.addActionListener(new buttonPress());
        frame.setVisible(true);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void createParent() {
        parentFrame pF = new parentFrame(); //The default constructor will display the frame
        frame.dispose(); //How?
    }

    class buttonPress implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            createParent();
        }
    }

}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Warsum
  • 29
  • 1
  • 2
  • 3
    Note: your `ParentFrame` class extends from `JFrame` but you use a class variable named `frame` to display the frame and don't dispose any of `ParentFrame`s instances. That's probably causing the memory leak (not fully tested though). I'd just remove the `extends JFrame` from the class header and use local variables instead. Also: [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice) – dic19 Jan 21 '15 at 15:18
  • I use frame so I do not have to call super() and I have access to the frame variable. Is this poor programming and logically wrong? Keeps me from using 'this' which I find makes code sometimes confusing. – Warsum Jan 21 '15 at 15:19
  • 3
    The 'other frames' should be dialogs.. If you'd followed the link added by @dic19, you'd find that discussed. – Andrew Thompson Jan 21 '15 at 15:32

2 Answers2

1

I'm not sure what you mean by "I don't have to call super()", but if you want to avoid confusion, then either extend JFrame or use a variable in your class of type JFrame. You have both, and create the variable reference in the constructor, so that when JFrame frame = new parentFrame(); is executed, two JFrames are created: the one on which you have the new operator, and the one in the constructor of that object.

As for cleanup, when you execute setVisible(true); on a JFrame, it seems obvious to me that the JFrame reference gets put into the Swing system, and so the variable in your method (whether local or instance (or static)) is no longer the only reference. I think of dispose() as an instruction to the Swing framework that the code is done with this variable, clean up after it and remove all references to it. If you don't do that before you lose your own reference to the variable (e.g., if it were a local variable and you didn't do that before you exited the method), then you would lose your chance to call dispose. I suppose you could still get a reference from Swing somehow, and then call dispose on it.

You don't say whether you have evidence of a memory leak or or just trying to understand this code.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • Just trying to understand the code. So I should extend JFrame but not use my own local variables? – Warsum Jan 21 '15 at 15:39
  • 3
    No, you shouldn't extend from JFrame if you won't add any Swing related feature. Composition is highly preferred over inheritance. Just use local variables. @Dominick – dic19 Jan 21 '15 at 15:45
  • Okay if I remove my local variable and extend JFrame I still have the same question. How can I create a new Frame in the parentFrame and then dispose of that frame but the child frame remains alive. Is control passed to the child frame? – Warsum Jan 21 '15 at 16:22
  • Extending JFrame is fine -- whether it is better to use variables or extend the class depends on how you're going to use it. I haven't done this; I suspect that, if you call setVisible on the child, then dispose of the parent, then reverse this sequence on a child button-push, then you'll get what you want. If you don't, debug it, and post a specific question about whatever puzzles you about it. – arcy Jan 22 '15 at 02:05
0

I have read your question, the answers and the comments. I advice you to review OOP basics to link your objects better. About the comment:

How can I create a new Frame in the parentFrame and then dispose of that frame but the child frame remains alive. Is control passed to the child frame?

Each JFrame is an independent instance of the JFrame object. You don't need to manually pass control. What you should do is define closing behaviour for each JFrame: A main frame on close will close the whole program (EXIT_ON_CLOSE), secondary frames can have other behaviour (HIDE_ON_CLOSE or DISPOSE_ON_CLOSE). You define this with:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

I should advice you to go through the java tutorials and make sure you understand well about classes and instances before diving into swing. Start manually will help you understand better (I saw they told you this already but I agree on it). Keep on!

corlaez
  • 1,352
  • 1
  • 15
  • 30