JDK-6403371 : REGRESSION: JTable header renderer only paints as component orientation as left
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-03-24
  • Updated: 2010-04-03
  • Resolved: 2006-04-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b80Fixed
Related Reports
Relates :  
Description
A DESCRIPTION OF THE REGRESSION :
The JTable header no longer supports ComponentOrientation.RIGHT_TO_LEFT.   For some applications it is preferred to have the column header icon to appear on the right of the header text.   This is done creating a proxy cell renderer that installs a custom icon and force the component orientation of cell renderer component.

REPRODUCIBLE TESTCASE OR STEPS TO REPRODUCE:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class IconTest implements Runnable {
  
  public void run() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTable table = new JTable(new NumberModel());
    table.getTableHeader().setDefaultRenderer(
            new HeaderRenderer(table.getTableHeader().getDefaultRenderer()));
    frame.getContentPane().add(new JScrollPane(table));
    frame.setSize(640, 480);
    frame.validate();
    frame.setVisible(true);
  }
  
  private static class HeaderRenderer implements TableCellRenderer, Icon {
    private final TableCellRenderer defaultRenderer;
    
    private HeaderRenderer(TableCellRenderer d) {
      assert d != null;
      this.defaultRenderer = d;
    }
    
    public Component getTableCellRendererComponent(JTable table, Object value,
                          boolean isSelected, boolean hasFocus, int row, int column) {
      JLabel comp = (JLabel)defaultRenderer.
              getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
      final JTableHeader header = table.getTableHeader();
      if(header != null) {
        comp.setForeground(header.getForeground());
        comp.setBackground(header.getBackground());
        comp.setFont(header.getFont());
      }
      else {
        comp.setText("Null header");
      }
      comp.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
      comp.setHorizontalAlignment(SwingConstants.CENTER);
      
      
      comp.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
      comp.setIcon(this);
      return comp;
    }
    
     public int getIconWidth() {return 7;}
     public int getIconHeight() {return 7;}

     /**
      * Paints a triangle on the table header.
      * @param comp the component.
      * @param g the graphics used to paint.
      * @param x the origin x
      * @param y the origin y
      */
     public void paintIcon(Component comp, Graphics g, int x, int y) {
       final int height = getIconHeight();
       final int width = getIconWidth();
       final Color c = comp.getBackground();

       Color brighter = c.brighter();
       Color darker = c.darker();

       g.setColor(darker);
       g.drawLine(x, y, x + width / 2, y + height); //left side
       g.setColor(brighter);
       g.drawLine(x, y, x + width, y); //top
       g.drawLine(x + width, y, x + width / 2, y + height); //right side
       g.setColor(c);
     }
  }
  
  private static class NumberModel extends AbstractTableModel {
    public int getRowCount() {return 7;}
    public int getColumnCount() {return 7;}
    public Object getValueAt(int row, int col) {
      return Integer.valueOf(row * this.getColumnCount() + col);
    }
  }
  
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new IconTest());
  }
}

RELEASE LAST WORKED:
5.0 Update 6

RELEASE TEST FAILS:
mustang-b70

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The icon for each column header should appear on the right side of the text.
ACTUAL -
The icon always appears on left of the header text.

OBSERVED APPLICATION IMPACT:
Icon is on the wrong side.

Comments
EVALUATION The fix will be to only change the orientation if a rowsorter has been specified, and the developer hasn't explicitly set an orientation.
30-03-2006

EVALUATION Shannon is indeed right, the horizontal text position was made leading. This was done so that the sort icon appears after the text. Unfortunately it appears folks are depending upon the alignment being trailing.
24-03-2006

EVALUATION Likely relates to recent work done to table header for sorting rendering.
24-03-2006