Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4352535

ToolTipManager still leaks in Metal L&F



    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 1.0.1, 1.3.0, 1.3.1
    • Fix Version/s: 1.3.1_03
    • Component/s: client-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
    • CPU:
      generic, x86, sparc
    • OS:
      generic, solaris_2.6, windows_nt



        Name: sl110371 Date: 07/12/2000

        java version "1.3.0"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
        Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

          Bug 4232051 is marked as closed, but this test program shows
          that it's still a problem. When I roll over a button it pops
          up a tool tip. This button won't get garbage collected until
          another button's tool tip is shown.
          Run this program. The "New Objects" button will place a new
          button in the main window, freeing the previous button for
          garbage collection. Pressing the "GC" button will collect
          the garbage, and print out the name of any button it cleans
          If you roll over a button to pop up its tool tip, then
          replace it with a new button, it won't get garbage collected
          until the new button's tool tip shows.
          This happens under Metal, but not under the Motif or Windows
          L&Fs. I haven't tried any others. I reproduced this under
          Windows. While I suspect it's cross platform, I didn't try
          it on any other platforms.
        import java.lang.ref.*;
        import javax.swing.*;
        import java.awt.*;
        import java.awt.event.*;
        import java.util.*;

        public class ToolTipLeak extends JPanel
          private static ReferenceQueue myQueue = new ReferenceQueue();
          private Thread myPoll = new Thread(new Poller());
          private HashSet myHash = new HashSet();
          private JComponent myPrevComp;

          public static void main(String[] args)
            JFrame mf = new JFrame("Memory Leak in Tool Tip");
            WindowListener wl = new WindowAdapter()
              public void windowClosing(WindowEvent evt) { System.exit(0); }
            mf.setBounds(10, 10, 400, 300);
            System.out.println("Java version " + System.getProperty("java.version"));
            mf.getContentPane().add(new ToolTipLeak(), BorderLayout.CENTER);
            super(new BorderLayout());
        // setLookAndFeel(); // put this line in to make bug go away.
            JPanel controlPanel = makeControlPanel();
            add(controlPanel, BorderLayout.SOUTH);
          private JPanel makeControlPanel()
            JPanel cPanel = new JPanel(new GridLayout(1, 0));
            JButton newBtn = new JButton("New Objects");
            JButton gcBtn = new JButton("GC");
            newBtn.addActionListener(new ActionListener()
              public void actionPerformed(ActionEvent evt)
            gcBtn.addActionListener(new ActionListener()
              public void actionPerformed(ActionEvent evt)
            return cPanel;
          private static int itr = 0;
          public void createNew()
            JButton b1 = makeBtn("Button " + itr);
            if (myPrevComp != null)
            myPrevComp = b1;
            add(b1, BorderLayout.CENTER);
          JButton makeBtn(String name)
            JButton btn = new TTButton(name);
            addWeakRef(btn, name);
            return btn;
          // So I can identify this class in optimizeIt
          private class TTButton extends JButton
            TTButton(String theName)
            // So I can identify this instance in OptimizeIt
            public String toString() { return getText() + ": " + super.toString(); }
          private void addWeakRef(Object thing, String theName)
            NamedWeakRef thisRef = new NamedWeakRef(thing, theName);
          private class NamedWeakRef extends WeakReference
            String myName;
            NamedWeakRef(Object thing, String theName)
              super(thing, myQueue);
              myName = theName;
          private class Poller implements Runnable
            public void run()
              NamedWeakRef myRef;
                  myRef = (NamedWeakRef)myQueue.remove();
                    System.out.println("GC cleaned up " + myRef.myName);
                catch(InterruptedException ie) { }

          private static void setLookAndFeel()
            catch (Exception lfex1)
              System.err.println("Error setting L&F");
        (Review ID: 107093)


            Issue Links



                svioletsunw Scott Violet (Inactive)
                duke J. Duke (Inactive)
                0 Vote for this issue
                0 Start watching this issue