1 /* 2 * Copyright (c) 1997, 2008, 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 26 package com.sun.java.swing.plaf.windows; 27 28 import java.awt.*; 29 import javax.swing.*; 30 import javax.swing.border.*; 31 import javax.swing.plaf.*; 32 import javax.swing.plaf.basic.*; 33 import javax.swing.table.*; 34 35 import static com.sun.java.swing.plaf.windows.TMSchema.*; 36 import static com.sun.java.swing.plaf.windows.XPStyle.*; 37 import sun.swing.table.*; 38 import sun.swing.SwingUtilities2; 39 40 41 public class WindowsTableHeaderUI extends BasicTableHeaderUI { 42 private TableCellRenderer originalHeaderRenderer; 43 44 public static ComponentUI createUI(JComponent h) { 45 return new WindowsTableHeaderUI(); 46 } 47 48 public void installUI(JComponent c) { 49 super.installUI(c); 50 51 if (XPStyle.getXP() != null) { 52 originalHeaderRenderer = header.getDefaultRenderer(); 53 if (originalHeaderRenderer instanceof UIResource) { 54 header.setDefaultRenderer(new XPDefaultRenderer()); 55 } 56 } 57 } 58 59 public void uninstallUI(JComponent c) { 60 if (header.getDefaultRenderer() instanceof XPDefaultRenderer) { 61 header.setDefaultRenderer(originalHeaderRenderer); 62 } 63 super.uninstallUI(c); 64 } 65 66 @Override 67 protected void rolloverColumnUpdated(int oldColumn, int newColumn) { 68 if (XPStyle.getXP() != null) { 69 header.repaint(header.getHeaderRect(oldColumn)); 70 header.repaint(header.getHeaderRect(newColumn)); 71 } 72 } 73 74 private class XPDefaultRenderer extends DefaultTableCellHeaderRenderer { 75 Skin skin; 76 boolean isSelected, hasFocus, hasRollover; 77 int column; 78 79 XPDefaultRenderer() { 80 setHorizontalAlignment(LEADING); 81 } 82 83 public Component getTableCellRendererComponent(JTable table, Object value, 84 boolean isSelected, boolean hasFocus, 85 int row, int column) { 86 super.getTableCellRendererComponent(table, value, isSelected, 87 hasFocus, row, column); 88 this.isSelected = isSelected; 89 this.hasFocus = hasFocus; 90 this.column = column; 91 this.hasRollover = (column == getRolloverColumn()); 92 if (skin == null) { 93 skin = XPStyle.getXP().getSkin(header, Part.HP_HEADERITEM); 94 } 95 Insets margins = skin.getContentMargin(); 96 Border border = null; 97 int contentTop = 0; 98 int contentLeft = 0; 99 int contentBottom = 0; 100 int contentRight = 0; 101 if (margins != null) { 102 contentTop = margins.top; 103 contentLeft = margins.left; 104 contentBottom = margins.bottom; 105 contentRight = margins.right; 106 } 107 /* idk: 108 * Both on Vista and XP there is some offset to the 109 * HP_HEADERITEM content. It does not seem to come from 110 * Prop.CONTENTMARGINS. Do not know where it is defined. 111 * using some hardcoded values. 112 */ 113 contentLeft += 5; 114 contentBottom += 4; 115 contentRight += 5; 116 117 /* On Vista sortIcon is painted above the header's text. 118 * We use border to paint it. 119 */ 120 Icon sortIcon; 121 if (WindowsLookAndFeel.isOnVista() 122 && ((sortIcon = getIcon()) instanceof javax.swing.plaf.UIResource 123 || sortIcon == null)) { 124 contentTop += 1; 125 setIcon(null); 126 sortIcon = null; 127 SortOrder sortOrder = 128 getColumnSortOrder(table, column); 129 if (sortOrder != null) { 130 switch (sortOrder) { 131 case ASCENDING: 132 sortIcon = 133 UIManager.getIcon("Table.ascendingSortIcon"); 134 break; 135 case DESCENDING: 136 sortIcon = 137 UIManager.getIcon("Table.descendingSortIcon"); 138 break; 139 } 140 } 141 if (sortIcon != null) { 142 contentBottom = sortIcon.getIconHeight(); 143 border = new IconBorder(sortIcon, contentTop, contentLeft, 144 contentBottom, contentRight); 145 } else { 146 sortIcon = 147 UIManager.getIcon("Table.ascendingSortIcon"); 148 int sortIconHeight = 149 (sortIcon != null) ? sortIcon.getIconHeight() : 0; 150 if (sortIconHeight != 0) { 151 contentBottom = sortIconHeight; 152 } 153 border = 154 new EmptyBorder( 155 sortIconHeight + contentTop, contentLeft, 156 contentBottom, contentRight); 157 } 158 } else { 159 contentTop += 3; 160 border = new EmptyBorder(contentTop, contentLeft, 161 contentBottom, contentRight); 162 } 163 setBorder(border); 164 return this; 165 } 166 167 public void paint(Graphics g) { 168 Dimension size = getSize(); 169 State state = State.NORMAL; 170 TableColumn draggedColumn = header.getDraggedColumn(); 171 if (draggedColumn != null && 172 column == SwingUtilities2.convertColumnIndexToView( 173 header.getColumnModel(), draggedColumn.getModelIndex())) { 174 state = State.PRESSED; 175 } else if (isSelected || hasFocus || hasRollover) { 176 state = State.HOT; 177 } 178 /* on Vista there are more states for sorted columns */ 179 if (WindowsLookAndFeel.isOnVista()) { 180 SortOrder sortOrder = getColumnSortOrder(header.getTable(), column); 181 if (sortOrder != null) { 182 switch(sortOrder) { 183 case ASCENDING: 184 /* falls through */ 185 case DESCENDING: 186 switch (state) { 187 case NORMAL: 188 state = State.SORTEDNORMAL; 189 break; 190 case PRESSED: 191 state = State.SORTEDPRESSED; 192 break; 193 case HOT: 194 state = State.SORTEDHOT; 195 break; 196 default: 197 /* do nothing */ 198 } 199 default : 200 /* do nothing */ 201 } 202 } 203 } 204 skin.paintSkin(g, 0, 0, size.width-1, size.height-1, state); 205 super.paint(g); 206 } 207 } 208 209 /** 210 * A border with an Icon at the middle of the top side. 211 * Outer insets can be provided for this border. 212 */ 213 private static class IconBorder implements Border, UIResource{ 214 private final Icon icon; 215 private final int top; 216 private final int left; 217 private final int bottom; 218 private final int right; 219 /** 220 * Creates this border; 221 * @param icon - icon to paint for this border 222 * @param top, left, bottom, right - outer insets for this border 223 */ 224 public IconBorder(Icon icon, int top, int left, 225 int bottom, int right) { 226 this.icon = icon; 227 this.top = top; 228 this.left = left; 229 this.bottom = bottom; 230 this.right = right; 231 } 232 public Insets getBorderInsets(Component c) { 233 return new Insets(icon.getIconHeight() + top, left, bottom, right); 234 } 235 public boolean isBorderOpaque() { 236 return false; 237 } 238 public void paintBorder(Component c, Graphics g, int x, int y, 239 int width, int height) { 240 icon.paintIcon(c, g, 241 x + left + (width - left - right - icon.getIconWidth()) / 2, 242 y + top); 243 } 244 } 245 }