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

ToolTipManager still leaks in Metal L&F

    XMLWordPrintable

    Details

    • 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:
      03
    • CPU:
      generic, x86, sparc
    • OS:
      generic, solaris_2.6, windows_nt

      Backports

        Description



        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
          up.
          
          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.addWindowListener(wl);
            mf.setBounds(10, 10, 400, 300);
            System.out.println("Java version " + System.getProperty("java.version"));
            mf.getContentPane().add(new ToolTipLeak(), BorderLayout.CENTER);
            mf.show();
          }
          
          ToolTipLeak()
          {
            super(new BorderLayout());
        // setLookAndFeel(); // put this line in to make bug go away.
            JPanel controlPanel = makeControlPanel();
            add(controlPanel, BorderLayout.SOUTH);
            myPoll.start();
          }
          
          private JPanel makeControlPanel()
          {
            JPanel cPanel = new JPanel(new GridLayout(1, 0));
            JButton newBtn = new JButton("New Objects");
            JButton gcBtn = new JButton("GC");
            cPanel.add(newBtn);
            cPanel.add(gcBtn);
            newBtn.addActionListener(new ActionListener()
            {
              public void actionPerformed(ActionEvent evt)
              {
                createNew();
              }
            });
            gcBtn.addActionListener(new ActionListener()
            {
              public void actionPerformed(ActionEvent evt)
              {
                System.gc();
              }
            });
            return cPanel;
          }
          
          private static int itr = 0;
          public void createNew()
          {
            JButton b1 = makeBtn("Button " + itr);
            b1.setToolTipText(b1.getText());
            if (myPrevComp != null)
              remove(myPrevComp);
            myPrevComp = b1;
            add(b1, BorderLayout.CENTER);
            revalidate();
            itr++;
          }
          
          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)
            {
              super(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);
            myHash.add(thisRef);
          }
          
          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;
              while(true)
              {
                try
                {
                  myRef = (NamedWeakRef)myQueue.remove();
                  synchronized(System.out)
                  {
                    System.out.println("GC cleaned up " + myRef.myName);
                    myHash.remove(myRef);
                  }
                }
                catch(InterruptedException ie) { }
              }
            }
          }

          private static void setLookAndFeel()
          {
            try
            {
              UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        //
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
            }
            catch (Exception lfex1)
            {
              System.err.println("Error setting L&F");
              lfex1.printStackTrace();
            }
          }
        }
        (Review ID: 107093)
        ======================================================================

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                svioletsunw Scott Violet (Inactive)
                Reporter:
                duke J. Duke (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: