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

LightWeight JPopupMenu does not size correctly if a JTable is part of the popup

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 1.4.2
    • client-libs
    • Fix Understood
    • x86
    • windows_2000

      Name: gm110360 Date: 05/06/2004


      FULL PRODUCT VERSION :
      java version "1.4.2_03"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)
      Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows 2000 [Version 5.00.2195]

      A DESCRIPTION OF THE PROBLEM :
      When a JPopupMenu is created as light weight one and the popup menu has a JTable in it as a component the size if the popup menu is incorrect because the size of the header of the JTable is ignored.

      This is because the header view is installed in the addNotify method of the JTable which is called too late by JPopupMenu to make a difference in the size. As a result scrollbars appear in the popup instead of being sized correctly.

      (source attached)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      create a popup menu which contains a JTable in the popup make sure the popup is created as a light weight one.

      make sure you call:
      table.setPreferredScrollableViewportSize(table.getPreferredSize());
      to size the scrollpane to the size of the table
       
      Show the popup and you will see scrollbars.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      popup sized to fit the table without any scrollbars
      ACTUAL -
      popup size is smaller by the size of the table header and scrollbars show up

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.*;
      import javax.swing.table.*;
      import javax.swing.event.*;

      public class PopupBug extends JFrame
      {
        JButton m_bugButton = new JButton("Show the bug!");
        JButton m_hackButton = new JButton("Show the hack!");
        public PopupBug()
        {
          super("Popup Bug Example");
          
          m_bugButton.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent e)
            {showBuggyPopup();}
          });
          
          m_hackButton.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent e)
            {showPopup();}
          });
          
          JPanel temp = new JPanel();
          temp.setLayout(new FlowLayout());
          temp.add(m_bugButton);
          temp.add(m_hackButton);
          
          Container container = getContentPane();
          container.setLayout(new BorderLayout());
          container.add(temp, BorderLayout.NORTH);
          container.add(new JPanel(), BorderLayout.CENTER);
        }
        
        protected void showPopup()
        {
          JPopupMenu popup = new JPopupMenu();
          popup.setLayout(new BorderLayout());
          popup.add(new JLabel("This is the popup with the hack!"), BorderLayout.NORTH);
          popup.add(getScrollPane(), BorderLayout.CENTER);
          
          popup.addNotify(); //<--- Calling this will make the bug go away.
          popup.show(this, 130, 80);
        }
        
        protected void showBuggyPopup()
        {
          JPopupMenu popup = new JPopupMenu();
          popup.setLayout(new BorderLayout());
          popup.add(new JLabel("This is the popup with the bug!"), BorderLayout.NORTH);
          popup.add(getScrollPane(), BorderLayout.CENTER);
          
          popup.show(this, 10, 80);
        }
        
        protected JScrollPane getScrollPane()
        {
          TableModel dataModel = new AbstractTableModel()
          {
            public int getColumnCount() {return 3;}
            public int getRowCount() {return 3;}
            public Object getValueAt(int row, int col) {return new Integer(row*col);}
          };
          
          JTable table = new JTable(dataModel);
          JScrollPane scrollpane = new JScrollPane(table);
          table.setPreferredScrollableViewportSize(table.getPreferredSize());
          return scrollpane;
        }
        
        public static void main(String[] args)
        {
          PopupBug frame = new PopupBug();
          frame.addWindowListener(new WindowAdapter()
          {
            public void windowClosing(WindowEvent e)
            {
              System.exit(0);
            }
          });
          
          frame.pack();
          frame.setSize(400, 300);
          frame.show();
        }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Calling popup.addNotify(); before calling popup.show() forces the table to install the column headers before actual sizing takes place. But this is a costly workaround as it will be done again in the show() method.
      (Incident Review ID: 246916)
      ======================================================================

            peterz Peter Zhelezniakov
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: