1 /* 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package sun.swing.table; 26 27 import sun.swing.DefaultLookup; 28 29 import java.awt.Component; 30 import java.awt.Color; 31 import java.awt.FontMetrics; 32 import java.awt.Graphics; 33 import java.awt.Insets; 34 import java.awt.Point; 35 import java.awt.Rectangle; 36 import java.io.Serializable; 37 import javax.swing.*; 38 import javax.swing.plaf.UIResource; 39 import javax.swing.border.Border; 40 import javax.swing.table.*; 41 42 public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer 43 implements UIResource { 44 private boolean horizontalTextPositionSet; 45 private Icon sortArrow; 46 private EmptyIcon emptyIcon = new EmptyIcon(); 47 48 public DefaultTableCellHeaderRenderer() { 49 setHorizontalAlignment(JLabel.CENTER); 50 } 51 52 public void setHorizontalTextPosition(int textPosition) { 53 horizontalTextPositionSet = true; 54 super.setHorizontalTextPosition(textPosition); 55 } 56 57 public Component getTableCellRendererComponent(JTable table, Object value, 58 boolean isSelected, boolean hasFocus, int row, int column) { 59 Icon sortIcon = null; 60 61 boolean isPaintingForPrint = false; 62 63 if (table != null) { 64 JTableHeader header = table.getTableHeader(); 65 if (header != null) { 66 Color fgColor = null; 67 Color bgColor = null; 68 if (hasFocus) { 69 fgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellForeground"); 70 bgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellBackground"); 71 } 72 if (fgColor == null) { 73 fgColor = header.getForeground(); 74 } 75 if (bgColor == null) { 76 bgColor = header.getBackground(); 77 } 78 setForeground(fgColor); 79 setBackground(bgColor); 80 81 setFont(header.getFont()); 82 83 isPaintingForPrint = header.isPaintingForPrint(); 84 } 85 86 if (!isPaintingForPrint && table.getRowSorter() != null) { 87 if (!horizontalTextPositionSet) { 88 // There is a row sorter, and the developer hasn't 89 // set a text position, change to leading. 90 setHorizontalTextPosition(JLabel.LEADING); 91 } 92 SortOrder sortOrder = getColumnSortOrder(table, column); 93 if (sortOrder != null) { 94 switch(sortOrder) { 95 case ASCENDING: 96 sortIcon = DefaultLookup.getIcon( 97 this, ui, "Table.ascendingSortIcon"); 98 break; 99 case DESCENDING: 100 sortIcon = DefaultLookup.getIcon( 101 this, ui, "Table.descendingSortIcon"); 102 break; 103 case UNSORTED: 104 sortIcon = DefaultLookup.getIcon( 105 this, ui, "Table.naturalSortIcon"); 106 break; 107 } 108 } 109 } 110 } 111 112 setText(value == null ? "" : value.toString()); 113 setIcon(sortIcon); 114 sortArrow = sortIcon; 115 116 Border border = null; 117 if (hasFocus) { 118 border = DefaultLookup.getBorder(this, ui, "TableHeader.focusCellBorder"); 119 } 120 if (border == null) { 121 border = DefaultLookup.getBorder(this, ui, "TableHeader.cellBorder"); 122 } 123 setBorder(border); 124 125 return this; 126 } 127 128 public static SortOrder getColumnSortOrder(JTable table, int column) { 129 SortOrder rv = null; 130 if (table == null || table.getRowSorter() == null) { 131 return rv; 132 } 133 java.util.List<? extends RowSorter.SortKey> sortKeys = 134 table.getRowSorter().getSortKeys(); 135 if (sortKeys.size() > 0 && sortKeys.get(0).getColumn() == 136 table.convertColumnIndexToModel(column)) { 137 rv = sortKeys.get(0).getSortOrder(); 138 } 139 return rv; 140 } 141 142 @Override 143 public void paintComponent(Graphics g) { 144 boolean b = DefaultLookup.getBoolean(this, ui, 145 "TableHeader.rightAlignSortArrow", false); 146 if (b && sortArrow != null) { 147 //emptyIcon is used so that if the text in the header is right 148 //aligned, or if the column is too narrow, then the text will 149 //be sized appropriately to make room for the icon that is about 150 //to be painted manually here. 151 emptyIcon.width = sortArrow.getIconWidth(); 152 emptyIcon.height = sortArrow.getIconHeight(); 153 setIcon(emptyIcon); 154 super.paintComponent(g); 155 Point position = computeIconPosition(g); 156 sortArrow.paintIcon(this, g, position.x, position.y); 157 } else { 158 super.paintComponent(g); 159 } 160 } 161 162 private Point computeIconPosition(Graphics g) { 163 FontMetrics fontMetrics = g.getFontMetrics(); 164 Rectangle viewR = new Rectangle(); 165 Rectangle textR = new Rectangle(); 166 Rectangle iconR = new Rectangle(); 167 Insets i = getInsets(); 168 viewR.x = i.left; 169 viewR.y = i.top; 170 viewR.width = getWidth() - (i.left + i.right); 171 viewR.height = getHeight() - (i.top + i.bottom); 172 SwingUtilities.layoutCompoundLabel( 173 this, 174 fontMetrics, 175 getText(), 176 sortArrow, 177 getVerticalAlignment(), 178 getHorizontalAlignment(), 179 getVerticalTextPosition(), 180 getHorizontalTextPosition(), 181 viewR, 182 iconR, 183 textR, 184 getIconTextGap()); 185 int x = getWidth() - i.right - sortArrow.getIconWidth(); 186 int y = iconR.y; 187 return new Point(x, y); 188 } 189 190 private class EmptyIcon implements Icon, Serializable { 191 int width = 0; 192 int height = 0; 193 public void paintIcon(Component c, Graphics g, int x, int y) {} 194 public int getIconWidth() { return width; } 195 public int getIconHeight() { return height; } 196 } 197 }