JDK-4192103 : Swing fails to generate exception with remove() from JDialog, JFrame, etc.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.6
  • CPU: sparc
  • Submitted: 1998-11-23
  • Updated: 2013-11-01
  • Resolved: 1999-01-12
Related Reports
Duplicate :  
Description
I'm filing this on behalf of a customer:

Swing fails to generate an exception when items are removed using
remove() or removeAll() from a JDialog, JFrame, JWindow, JApplet, or JInternalFrame.

If I create a JDialog / JFrame and try and add a child I get an error thrown at
runtime stating that I must use getContentPane().add instead of add(). However, the reverse is not true. I can do a remove() and not get an exception even though the remove() is incorrect. It should be getContentPane().remove().
The implication of this is severe memory leaks. I should be protected from doing
this.



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

public class Paul extends JFrame {
   JPanel topPanel = new JPanel();
   MyPanel centrePanel = new MyPanel();
   JButton pressButton = new JButton("Press Me");
   JButton exitButton = new JButton("Exit");
   JLabel label1 = new JLabel();

   public Paul() {
      this.getContentPane().setLayout(new BorderLayout());
      this.setSize(new Dimension(582, 431));
      this.setTitle("Memory Leak Bug");
      topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
      pressButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(ActionEvent e) {
          pressButton_actionPerformed(e);
      	}
      });

      exitButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(ActionEvent e) {
          System.exit(0);
      	}
      });

      this.getContentPane().add(topPanel, BorderLayout.NORTH);
      topPanel.add(exitButton);
      topPanel.add(pressButton);
      topPanel.add(label1);
      this.getContentPane().add(centrePanel, BorderLayout.CENTER);
      label1.setText("Free Memory: " + Runtime.getRuntime().freeMemory() );
      setVisible(true);
   }

   void pressButton_actionPerformed(ActionEvent e) {
      centrePanel.removeAll();
      this.remove(centrePanel);
      centrePanel = new MyPanel();
      this.getContentPane().add(centrePanel, BorderLayout.CENTER);
      System.gc();
      label1.setText("Free Memory: " + Runtime.getRuntime().freeMemory() );
   }

   public static void main(String[] args) {
      Paul f = new Paul();
   }
}

class MyPanel extends JPanel {
   TableModel dataModel = new AbstractTableModel() {
     public int getColumnCount() { return 10; }
     public int getRowCount() { return 30;}
     public Object getValueAt(int row, int col) { 
	return new Integer(row*col); 
     }
   };

   public MyPanel() {
      setLayout(new BorderLayout());
      add( new JScrollPane( new JTable(dataModel) ),  BorderLayout.CENTER);
   }
}