blob: 391f019ae6fad1c29f3dae7af04b8ffa6810e5c1 [file] [log] [blame]
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.java.swing.plaf.windows;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.table.*;
import static com.sun.java.swing.plaf.windows.TMSchema.*;
import static com.sun.java.swing.plaf.windows.XPStyle.*;
import sun.swing.table.*;
import sun.swing.SwingUtilities2;
public class WindowsTableHeaderUI extends BasicTableHeaderUI {
private TableCellRenderer originalHeaderRenderer;
public static ComponentUI createUI(JComponent h) {
return new WindowsTableHeaderUI();
}
public void installUI(JComponent c) {
super.installUI(c);
if (XPStyle.getXP() != null) {
originalHeaderRenderer = header.getDefaultRenderer();
if (originalHeaderRenderer instanceof UIResource) {
header.setDefaultRenderer(new XPDefaultRenderer());
}
}
}
public void uninstallUI(JComponent c) {
if (header.getDefaultRenderer() instanceof XPDefaultRenderer) {
header.setDefaultRenderer(originalHeaderRenderer);
}
super.uninstallUI(c);
}
@Override
protected void rolloverColumnUpdated(int oldColumn, int newColumn) {
if (XPStyle.getXP() != null) {
header.repaint(header.getHeaderRect(oldColumn));
header.repaint(header.getHeaderRect(newColumn));
}
}
private class XPDefaultRenderer extends DefaultTableCellHeaderRenderer {
Skin skin;
boolean isSelected, hasFocus, hasRollover;
int column;
XPDefaultRenderer() {
setHorizontalAlignment(LEADING);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
this.isSelected = isSelected;
this.hasFocus = hasFocus;
this.column = column;
this.hasRollover = (column == getRolloverColumn());
if (skin == null) {
skin = XPStyle.getXP().getSkin(header, Part.HP_HEADERITEM);
}
Insets margins = skin.getContentMargin();
Border border = null;
int contentTop = 0;
int contentLeft = 0;
int contentBottom = 0;
int contentRight = 0;
if (margins != null) {
contentTop = margins.top;
contentLeft = margins.left;
contentBottom = margins.bottom;
contentRight = margins.right;
}
/* idk:
* Both on Vista and XP there is some offset to the
* HP_HEADERITEM content. It does not seem to come from
* Prop.CONTENTMARGINS. Do not know where it is defined.
* using some hardcoded values.
*/
contentLeft += 5;
contentBottom += 4;
contentRight += 5;
/* On Vista sortIcon is painted above the header's text.
* We use border to paint it.
*/
Icon sortIcon;
if (WindowsLookAndFeel.isOnVista()
&& ((sortIcon = getIcon()) instanceof javax.swing.plaf.UIResource
|| sortIcon == null)) {
contentTop += 1;
setIcon(null);
sortIcon = null;
SortOrder sortOrder =
getColumnSortOrder(table, column);
if (sortOrder != null) {
switch (sortOrder) {
case ASCENDING:
sortIcon =
UIManager.getIcon("Table.ascendingSortIcon");
break;
case DESCENDING:
sortIcon =
UIManager.getIcon("Table.descendingSortIcon");
break;
}
}
if (sortIcon != null) {
contentBottom = sortIcon.getIconHeight();
border = new IconBorder(sortIcon, contentTop, contentLeft,
contentBottom, contentRight);
} else {
sortIcon =
UIManager.getIcon("Table.ascendingSortIcon");
int sortIconHeight =
(sortIcon != null) ? sortIcon.getIconHeight() : 0;
if (sortIconHeight != 0) {
contentBottom = sortIconHeight;
}
border =
new EmptyBorder(
sortIconHeight + contentTop, contentLeft,
contentBottom, contentRight);
}
} else {
contentTop += 3;
border = new EmptyBorder(contentTop, contentLeft,
contentBottom, contentRight);
}
setBorder(border);
return this;
}
public void paint(Graphics g) {
Dimension size = getSize();
State state = State.NORMAL;
TableColumn draggedColumn = header.getDraggedColumn();
if (draggedColumn != null &&
column == SwingUtilities2.convertColumnIndexToView(
header.getColumnModel(), draggedColumn.getModelIndex())) {
state = State.PRESSED;
} else if (isSelected || hasFocus || hasRollover) {
state = State.HOT;
}
/* on Vista there are more states for sorted columns */
if (WindowsLookAndFeel.isOnVista()) {
SortOrder sortOrder = getColumnSortOrder(header.getTable(), column);
if (sortOrder != null) {
switch(sortOrder) {
case ASCENDING:
/* falls through */
case DESCENDING:
switch (state) {
case NORMAL:
state = State.SORTEDNORMAL;
break;
case PRESSED:
state = State.SORTEDPRESSED;
break;
case HOT:
state = State.SORTEDHOT;
break;
default:
/* do nothing */
}
default :
/* do nothing */
}
}
}
skin.paintSkin(g, 0, 0, size.width-1, size.height-1, state);
super.paint(g);
}
}
/**
* A border with an Icon at the middle of the top side.
* Outer insets can be provided for this border.
*/
private static class IconBorder implements Border, UIResource{
private final Icon icon;
private final int top;
private final int left;
private final int bottom;
private final int right;
/**
* Creates this border;
* @param icon - icon to paint for this border
* @param top, left, bottom, right - outer insets for this border
*/
public IconBorder(Icon icon, int top, int left,
int bottom, int right) {
this.icon = icon;
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
public Insets getBorderInsets(Component c) {
return new Insets(icon.getIconHeight() + top, left, bottom, right);
}
public boolean isBorderOpaque() {
return false;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
icon.paintIcon(c, g,
x + left + (width - left - right - icon.getIconWidth()) / 2,
y + top);
}
}
}