Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why is dispose() not working?

2,730 views
Skip to first unread message

Ross Mills

unread,
Dec 1, 2000, 7:24:09 PM12/1/00
to
Hi,

I have a simple JDialog with a single button. An ActionListener was added
to the button so that dispose() is called when the button is clicked. Also,
a WindowListener was added so that dispose() is called when then JDialog is
closed.

Here is my problem: When I close the JDialog by clicking on the X in the
upper right hand corner, the JDialog disappears and the garbage collector
reclaims the JDialog's resources. However, when I close the JDialog by
clicking on the button, the JDialog disappears but the JDialog's resources
are NOT reclaimed by the garbage collector. I continue to lose memory as I
repeatedly display and close the JDialog.

Below is a very short example in which this problem can be reproduced:

I know I could work-around this problem by reusing the JDialog, but I really
should not have to. How can I free the resources for this JDialog when I
click on the button?

Thanks,
Ross Mills


Here is the JDialog source code...

package TestDiag;

import com.sun.java.swing.*;
import java.awt.event.*;

public class Diag extends JDialog {
JButton closeBtn = new JButton("Close");

public Diag(JFrame parent) {
super(parent);
setModal(true);
closeBtn.addActionListener(new BtnListener());
addWindowListener(new WinListener());
getContentPane().add(closeBtn);
pack();
System.out.println("Built Diag");
}

protected void finalize() throws Throwable {
System.out.println("Cleaning up Diag");
}

class BtnListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
dispose();
}
}

class WinListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {
dispose();
}
}
}


and here is the JFrame from which I call the above JDialog...

package TestDiag;

import com.sun.java.swing.*;
import java.awt.event.*;

public class MainFrame extends JFrame {

JButton goBtn = new JButton("GO");

public MainFrame() {
goBtn.addActionListener(new BtnListener(this));
getContentPane().add(goBtn);
pack();
}

class BtnListener implements ActionListener {
MainFrame mFrame;

public BtnListener(MainFrame mFrame) {
this.mFrame = mFrame;
}

public void actionPerformed(ActionEvent e) {
Diag diag = new Diag(mFrame);
diag.setVisible(true);
System.gc();
}
}

static public void main(String args[]) {
(new MainFrame()).setVisible(true);
}
}


Karl Schmidt

unread,
Dec 2, 2000, 3:00:00 AM12/2/00
to
Ross Mills schrieb:

>
> Hi,
>
> I have a simple JDialog with a single button. An ActionListener was added
> to the button so that dispose() is called when the button is clicked. Also,
> a WindowListener was added so that dispose() is called when then JDialog is
> closed.
>
> Here is my problem: When I close the JDialog by clicking on the X in the
> upper right hand corner, the JDialog disappears and the garbage collector
> reclaims the JDialog's resources. However, when I close the JDialog by
> clicking on the button, the JDialog disappears but the JDialog's resources
> are NOT reclaimed by the garbage collector. I continue to lose memory as I
> repeatedly display and close the JDialog.
>
> Below is a very short example in which this problem can be reproduced:
>
> I know I could work-around this problem by reusing the JDialog, but I really
> should not have to. How can I free the resources for this JDialog when I
> click on the button?


I can't reproduce your problem. I tested your code: The first dialog
is finalized after the second is disposed. The reason is easy: When
you close and dispose the dialog, the event thread still has a reference
to it, so it can not be gc-ed. In your little example it is finalized
after disposing of the second dialog. In any larger application it will
be removed any time the gc does its work after you left the
actionPerformed() method of your BtnListener.

This doesn't seem to work all the time, though. I added a second button
to the main frame, which only calls the gc. Sometimes the dialog is
finalized, sometimes not. However, there are never more than two
objects of the dialog on the heap. I remember vaguely that some SUN
employee has been quoted in that way, that Swing does not have any
memory leaks, but some objects stay longer than you would expect. :-)

Here is my slightly changed test code:


import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

class Diag extends JDialog {


// some fields to identify the Diag objects
// increment for unique numbers
static int diagCounter = 0;

// count unfinalized objects
static int unfinalized = 0;

// the individual number of the Diag object
int diagNumber = 0;


JButton closeBtn = new JButton("Close");

public Diag(JFrame parent) {
super(parent);

// count the dialogs
diagNumber = ++diagCounter;

// one more unfinalized Diag
unfinalized++;

// name it, that looks nicer
setTitle("Dialog "+diagNumber);

// do the rest...


setModal(true);
closeBtn.addActionListener(new BtnListener());
addWindowListener(new WinListener());
getContentPane().add(closeBtn);
pack();

// add the number to the output
System.out.println("Built Diag "+diagNumber);
}


protected void finalize() throws Throwable {

// again the object counter is added to the output
System.out.println("Cleaning up Diag "+diagNumber);

// one unfinalized object less
System.out.println((--unfinalized) + " unfinalized diags left");
}


class BtnListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
dispose();
}
}

class WinListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {
dispose();
}
}
}

public class MainFrame extends JFrame {

JButton goBtn = new JButton("GO");

// a second button to trigger the gc
JButton finBtn = new JButton("GC");

public MainFrame() {
ActionListener bl = new BtnListener();
goBtn.addActionListener(bl);
finBtn.addActionListener(bl);

// we need another Layout since we have
// two buttons now
getContentPane().setLayout(new GridLayout(1,2));
getContentPane().add(goBtn);
getContentPane().add(finBtn);
pack();

// you forgot to listen for a graceful
// exit
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
dispose();
// just for fun
// watch any leftovers vanish
System.runFinalizersOnExit(true);
System.exit(0);
}
});
}

class BtnListener implements ActionListener {

public void actionPerformed(ActionEvent e) {
if (e.getSource() == goBtn) {

// the go button


Diag diag = new Diag(mFrame);
diag.setVisible(true);
System.gc();

} else {
// the gc button
System.gc();
}
}
}

static public void main(String args[]) {
(new MainFrame()).setVisible(true);
}
}


HTH


Karl Schmidt

jet

unread,
Dec 4, 2000, 3:00:00 AM12/4/00
to

before disposing try

closeBtn.removeActionListener(you'll need a handle to the listener here);

this will allow the garbage collector to work; why the X button seems to work
i don't know but i do know a simple dispose call doesn't; i've discovered that
quite often dialogs and internal frames won't get cleaned up unless you
specifically free some resources and listeners are often hangers on (not the
listeners
themselves but the listener lists that keep track of all the listeners)

Cameron Hayne

unread,
Dec 4, 2000, 3:00:00 AM12/4/00
to

Ross Mills wrote:

> public class Diag extends JDialog {
> JButton closeBtn = new JButton("Close");
>
> public Diag(JFrame parent) {
> super(parent);
> setModal(true);
> closeBtn.addActionListener(new BtnListener());
> addWindowListener(new WinListener());
> getContentPane().add(closeBtn);
> pack();
> System.out.println("Built Diag");
> }

[...]


>
> class BtnListener implements ActionListener {
> public void actionPerformed(ActionEvent e) {
> dispose();
> }
> }

The problem is that the 'dispose()' in the actionPerformed function
disposes of the BtnListener object. You need to call diag.dispose()
where 'diag' is a variable holding the Diag object.

But I think you don't actually have to call dispose() at all - just
hide the dialog when you are done with it and don't retain any
reference to it and it should automatically be garbage collected.

rathore...@gmail.com

unread,
Jun 11, 2015, 5:41:13 PM6/11/15
to
My Jdialog is not closing on a single click if i am cancelling the jdialog from the upper right portion of the dialog that cross sign.how can i close it on single click
0 new messages