1 /* 2 * Copyright (c) 2005, 2014, 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 @SuppressWarnings("serial") // JDK-implementation class 43 public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer 44 implements UIResource { 45 private boolean horizontalTextPositionSet; 46 private Icon sortArrow; 47 private EmptyIcon emptyIcon = new EmptyIcon(); 48 DefaultTableCellHeaderRenderer()49 public DefaultTableCellHeaderRenderer() { 50 setHorizontalAlignment(JLabel.CENTER); 51 } 52 setHorizontalTextPosition(int textPosition)53 public void setHorizontalTextPosition(int textPosition) { 54 horizontalTextPositionSet = true; 55 super.setHorizontalTextPosition(textPosition); 56 } 57 getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)58 public Component getTableCellRendererComponent(JTable table, Object value, 59 boolean isSelected, boolean hasFocus, int row, int column) { 60 Icon sortIcon = null; 61 62 boolean isPaintingForPrint = false; 63 64 if (table != null) { 65 JTableHeader header = table.getTableHeader(); 66 if (header != null) { 67 Color fgColor = null; 68 Color bgColor = null; 69 if (hasFocus) { 70 fgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellForeground"); 71 bgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellBackground"); 72 } 73 if (fgColor == null) { 74 fgColor = header.getForeground(); 75 } 76 if (bgColor == null) { 77 bgColor = header.getBackground(); 78 } 79 setForeground(fgColor); 80 setBackground(bgColor); 81 82 setFont(header.getFont()); 83 84 isPaintingForPrint = header.isPaintingForPrint(); 85 } 86 87 if (!isPaintingForPrint && table.getRowSorter() != null) { 88 if (!horizontalTextPositionSet) { 89 // There is a row sorter, and the developer hasn't 90 // set a text position, change to leading. 91 setHorizontalTextPosition(JLabel.LEADING); 92 } 93 SortOrder sortOrder = getColumnSortOrder(table, column); 94 if (sortOrder != null) { 95 switch(sortOrder) { 96 case ASCENDING: 97 sortIcon = DefaultLookup.getIcon( 98 this, ui, "Table.ascendingSortIcon"); 99 break; 100 case DESCENDING: 101 sortIcon = DefaultLookup.getIcon( 102 this, ui, "Table.descendingSortIcon"); 103 break; 104 case UNSORTED: 105 sortIcon = DefaultLookup.getIcon( 106 this, ui, "Table.naturalSortIcon"); 107 break; 108 } 109 } 110 } 111 } 112 113 setText(value == null ? "" : value.toString()); 114 setIcon(sortIcon); 115 sortArrow = sortIcon; 116 117 Border border = null; 118 if (hasFocus) { 119 border = DefaultLookup.getBorder(this, ui, "TableHeader.focusCellBorder"); 120 } 121 if (border == null) { 122 border = DefaultLookup.getBorder(this, ui, "TableHeader.cellBorder"); 123 } 124 setBorder(border); 125 126 return this; 127 } 128 getColumnSortOrder(JTable table, int column)129 public static SortOrder getColumnSortOrder(JTable table, int column) { 130 SortOrder rv = null; 131 if (table == null || table.getRowSorter() == null) { 132 return rv; 133 } 134 java.util.List<? extends RowSorter.SortKey> sortKeys = 135 table.getRowSorter().getSortKeys(); 136 if (sortKeys.size() > 0 && sortKeys.get(0).getColumn() == 137 table.convertColumnIndexToModel(column)) { 138 rv = sortKeys.get(0).getSortOrder(); 139 } 140 return rv; 141 } 142 143 @Override paintComponent(Graphics g)144 public void paintComponent(Graphics g) { 145 boolean b = DefaultLookup.getBoolean(this, ui, 146 "TableHeader.rightAlignSortArrow", false); 147 if (b && sortArrow != null) { 148 //emptyIcon is used so that if the text in the header is right 149 //aligned, or if the column is too narrow, then the text will 150 //be sized appropriately to make room for the icon that is about 151 //to be painted manually here. 152 emptyIcon.width = sortArrow.getIconWidth(); 153 emptyIcon.height = sortArrow.getIconHeight(); 154 setIcon(emptyIcon); 155 super.paintComponent(g); 156 Point position = computeIconPosition(g); 157 sortArrow.paintIcon(this, g, position.x, position.y); 158 } else { 159 super.paintComponent(g); 160 } 161 } 162 computeIconPosition(Graphics g)163 private Point computeIconPosition(Graphics g) { 164 FontMetrics fontMetrics = g.getFontMetrics(); 165 Rectangle viewR = new Rectangle(); 166 Rectangle textR = new Rectangle(); 167 Rectangle iconR = new Rectangle(); 168 Insets i = getInsets(); 169 viewR.x = i.left; 170 viewR.y = i.top; 171 viewR.width = getWidth() - (i.left + i.right); 172 viewR.height = getHeight() - (i.top + i.bottom); 173 SwingUtilities.layoutCompoundLabel( 174 this, 175 fontMetrics, 176 getText(), 177 sortArrow, 178 getVerticalAlignment(), 179 getHorizontalAlignment(), 180 getVerticalTextPosition(), 181 getHorizontalTextPosition(), 182 viewR, 183 iconR, 184 textR, 185 getIconTextGap()); 186 int x = getWidth() - i.right - sortArrow.getIconWidth(); 187 int y = iconR.y; 188 return new Point(x, y); 189 } 190 191 @SuppressWarnings("serial") // JDK-implementation class 192 private class EmptyIcon implements Icon, Serializable { 193 int width = 0; 194 int height = 0; paintIcon(Component c, Graphics g, int x, int y)195 public void paintIcon(Component c, Graphics g, int x, int y) {} getIconWidth()196 public int getIconWidth() { return width; } getIconHeight()197 public int getIconHeight() { return height; } 198 } 199 } 200