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

Windows XP PLAF Table Header with TableSorter.setFont() = NullPointerException

XMLWordPrintable

      FULL PRODUCT VERSION :
        Bug exists on both

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

      and

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


      ADDITIONAL OS VERSION INFORMATION :
      Windows XP

      A DESCRIPTION OF THE PROBLEM :
      A nullpointer bug exists when trying to use the setFont function on a JTable that has been created using TableSorter and is viewed in Windows XP.

      It may be possible to argue that the bug exists in WindowsTableHeaderUI
      or in TableSorter.

      TableSorter is not by default included in any JDK release but it is written by sun and made available from
      http://java.sun.com/docs/books/tutorial/uiswing/components/table.html

      This bug is probably related to Bug ID 5049957 but it is not the same.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the attached code
      Click the Test Button

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Table font size should increase
      ACTUAL -
      NullPointerException thrown



      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.NullPointerException
      at com.sun.java.swing.plaf.windows.WindowsTableHeaderUI$XPDefaultRenderer.paint(WindowsTableHeaderUI.java:81)
      at javax.swing.CellRendererPane.paintComponent(CellRendererPane.java:134)
      at javax.swing.plaf.basic.BasicTableHeaderUI.paintCell(BasicTableHeaderUI.java:401)
      at javax.swing.plaf.basic.BasicTableHeaderUI.paint(BasicTableHeaderUI.java:341)
      at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142)
      at javax.swing.JComponent.paintComponent(JComponent.java:541)
      at javax.swing.JComponent.paint(JComponent.java:808)
      at javax.swing.JComponent.paintChildren(JComponent.java:647)
      at javax.swing.JComponent.paint(JComponent.java:817)
      at javax.swing.JViewport.paint(JViewport.java:722)
      at javax.swing.JComponent.paintChildren(JComponent.java:647)
      at javax.swing.JComponent.paint(JComponent.java:817)
      at javax.swing.JComponent.paintChildren(JComponent.java:647)
      at javax.swing.JComponent.paint(JComponent.java:817)
      at javax.swing.JComponent.paintChildren(JComponent.java:647)
      at javax.swing.JComponent.paint(JComponent.java:817)
      at javax.swing.JComponent.paintChildren(JComponent.java:647)
      at javax.swing.JComponent.paint(JComponent.java:817)
      at javax.swing.JLayeredPane.paint(JLayeredPane.java:557)
      at javax.swing.JComponent.paintChildren(JComponent.java:647)
      at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4802)
      at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4748)
      at javax.swing.JComponent.paint(JComponent.java:798)
      at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
      at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
      at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
      at java.awt.Container.paint(Container.java:1312)
      at javax.swing.JFrame.update(JFrame.java:392)
      at sun.awt.RepaintArea.paint(RepaintArea.java:169)
      at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:260)
      at java.awt.Component.dispatchEventImpl(Component.java:3678)
      at java.awt.Container.dispatchEventImpl(Container.java:1627)
      at java.awt.Window.dispatchEventImpl(Window.java:1606)
      at java.awt.Component.dispatchEvent(Component.java:3477)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
      at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import javax.swing.table.AbstractTableModel;

      import TableSorter;

      import java.awt.*;
      import java.awt.event.*;

      /*
       * Created on 24-Mar-2004
       *
       */

      /**
       * @author Rob Jones
       */
      public class TableFontSizeTest extends JFrame implements ActionListener
      {
          JLabel simple;
          JTable table;
      TableSorter sorter;

          public TableFontSizeTest()
          {
              //Must be run on WindowsXP for bug to show up.
              setLAF(UIManager.getSystemLookAndFeelClassName());
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              simple = new JLabel("Simple");
              
              MyTableModel tableModel = new MyTableModel();
              sorter = new TableSorter(tableModel);
              table = new JTable(sorter);
              sorter.setTableHeader(table.getTableHeader());
              
              JScrollPane tableScrollPanel = new JScrollPane();
              tableScrollPanel.add(table);
              tableScrollPanel.setViewportView(table);
              tableScrollPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
              tableScrollPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
              tableScrollPanel.setBorder(BorderFactory.createLoweredBevelBorder());
              
              JButton button = new JButton("Test");
              button.addActionListener(this);
              JPanel contents = new JPanel();
              contents.add(simple);
              contents.add(tableScrollPanel);
              contents.add(button);
              getContentPane().add(contents);
              pack();
          }

          public void actionPerformed(ActionEvent e)
          {
              table.setFont(new Font("Arial",Font.BOLD,14));
              table.getTableHeader().setFont(new Font("Arial",Font.BOLD,14));
              SwingUtilities.updateComponentTreeUI(this);
          }

          public static void main(String args[])
          {
              TableFontSizeTest test = new TableFontSizeTest();
              test.setVisible(true);
          }
          
          
          private static void setLAF(String lafName)
          {
              try
              {
                  UIManager.setLookAndFeel(lafName);
              }
              catch (ClassNotFoundException e)
              {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              catch (InstantiationException e)
              {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              catch (IllegalAccessException e)
              {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              catch (UnsupportedLookAndFeelException e)
              {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
          
          //This MyTableModel class taken from Swing Tutorial
         class MyTableModel extends AbstractTableModel
         {
              final String[] columnNames = {"First Name",
                                            "Last Name",
                                            "Sport",
                                            "# of Years",
                                            "Vegetarian"};
              final Object[][] data = {
                  {"Mary", "Campione",
                   "Snowboarding", new Integer(5), new Boolean(false)},
                  {"Alison", "Huml",
                   "Rowing", new Integer(3), new Boolean(true)},
                  {"Kathy", "Walrath",
                   "Chasing toddlers", new Integer(2), new Boolean(false)},
                  {"Mark", "Andrews",
                   "Speed reading", new Integer(20), new Boolean(true)},
                  {"Angela", "Lih",
                   "Teaching high school", new Integer(4), new Boolean(false)}
              };

              public int getColumnCount() {
                  return columnNames.length;
              }
              
              public int getRowCount() {
                  return data.length;
              }

              public String getColumnName(int col) {
                  return columnNames[col];
              }

              public Object getValueAt(int row, int col) {
                  return data[row][col];
              }

              /*
               * JTable uses this method to determine the default renderer/
               * editor for each cell. If we didn't implement this method,
               * then the last column would contain text ("true"/"false"),
               * rather than a check box.
               */
              public Class getColumnClass(int c) {
                  return getValueAt(0, c).getClass();
              }

              /*
               * Don't need to implement this method unless your table's
               * editable.
               */
              public boolean isCellEditable(int row, int col) {
                  //Note that the data/cell address is constant,
                  //no matter where the cell appears onscreen.
                  if (col < 2) {
                      return false;
                  } else {
                      return true;
                  }
              }

              /*
               * Don't need to implement this method unless your table's
               * data can change.
               */
              public void setValueAt(Object value, int row, int col) {
                  if (false) {
                      System.out.println("Setting value at " + row + "," + col
                                         + " to " + value
                                         + " (an instance of "
                                         + value.getClass() + ")");
                  }

                  if (data[0][col] instanceof Integer
                          && !(value instanceof Integer)) {
                      //With JFC/Swing 1.1 and JDK 1.2, we need to create
                      //an Integer from the value; otherwise, the column
                      //switches to contain Strings. Starting with v 1.3,
                      //the table automatically converts value to an Integer,
                      //so you only need the code in the 'else' part of this
                      //'if' block.
                      //XXX: See TableEditDemo.java for a better solution!!!
                      try {
                          data[row][col] = new Integer(value.toString());
                          fireTableCellUpdated(row, col);
                      } catch (NumberFormatException e) {
                          System.out.println("NFE");
                      }
                  } else {
                      data[row][col] = value;
                      fireTableCellUpdated(row, col);
                  }

              }
          }
          
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      A kinda of workaround exists by modifying TableSorter
      Commenting out two lines in setTableHeader in TableSorter as per below
      This stops the custom header which paints the arrow from being installed.

          public void setTableHeader(JTableHeader tableHeader) {
              if (this.tableHeader != null) {
                  this.tableHeader.removeMouseListener(mouseListener);
                  TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
                  if (defaultRenderer instanceof SortableHeaderRenderer) {
                      this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
                  }
              }
              this.tableHeader = tableHeader;
              if (this.tableHeader != null) {
                  this.tableHeader.addMouseListener(mouseListener);
      // this.tableHeader.setDefaultRenderer(
      // new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
              }
          }

            shickeysunw Shannon Hickey (Inactive)
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: