My favorites | Sign in
Project Logo
                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package com.explodingpixels.macwidgets.plaf;

import com.explodingpixels.data.Rating;
import com.explodingpixels.macwidgets.ITunesRatingTableCellRenderer;
import com.explodingpixels.macwidgets.ITunesTableHeaderRenderer;
import com.explodingpixels.macwidgets.MacFontUtils;
import com.explodingpixels.widgets.TableHeaderUtils;
import com.explodingpixels.widgets.TableUtils;
import com.explodingpixels.widgets.WindowUtils;

import javax.swing.BorderFactory;
import javax.swing.CellRendererPane;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.plaf.basic.BasicTableUI;
import javax.swing.table.TableCellEditor;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;

/**
* A UI delegate that renders an iTunes style table.
* <br/>
* <img src="../../../../../graphics/iTunesTable.png">
* <p/>
* Sorting indicators will be rendered if a
* {@link com.explodingpixels.widgets.TableUtils.SortDelegate} is installed on the associated
* {@link JTable} via the
* {@link TableUtils#makeSortable(javax.swing.JTable, com.explodingpixels.widgets.TableUtils.SortDelegate)}
* method.
*/
public class ITunesTableUI extends BasicTableUI {

private static final Color EVEN_ROW_COLOR = new Color(241, 245, 250);
private static final Color TABLE_GRID_COLOR = new Color(0xd9d9d9);
private static final Color SELECTION_ACTIVE_SELECTION_FOREGROUND_COLOR = Color.WHITE;
private static final Color SELECTION_ACTIVE_SELECTION_BACKGROUND_COLOR = new Color(0x3d80df);
private static final Color SELECTION_INACTIVE_SELECTION_FOREGROUND_COLOR = Color.BLACK;
private static final Color SELECTION_INACTIVE_SELECTION_BACKGROUND_COLOR = new Color(0xc0c0c0);
private static final Color SELECTION_ACTIVE_BOTTOM_BORDER_COLOR = new Color(125, 170, 234);
private static final Color SELECTION_INACTIVE_BOTTOM_BORDER_COLOR = new Color(224, 224, 224);
private static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);

@Override
public void installUI(JComponent c) {
super.installUI(c);

table.remove(rendererPane);
rendererPane = createCustomCellRendererPane();
table.add(rendererPane);

// TODO save defaults.

table.setOpaque(false);
table.setFont(MacFontUtils.ITUNES_FONT);
table.setGridColor(TABLE_GRID_COLOR);
table.setIntercellSpacing(new Dimension(0, 0));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

table.getTableHeader().setDefaultRenderer(new ITunesTableHeaderRenderer(table));

table.setShowHorizontalLines(false);
TableHeaderUtils.makeHeaderFillEmptySpace(table);
TableUtils.makeStriped(table, EVEN_ROW_COLOR);

table.setDefaultRenderer(Rating.class, new ITunesRatingTableCellRenderer());
table.setDefaultEditor(Object.class, createDefaultTableCellEditor());

makeTableActive();
WindowUtils.installWeakWindowFocusListener(table, createWindowFocusListener());
}

@Override
protected void installListeners() {
super.installListeners();
}

private void makeTableActive() {
table.setSelectionForeground(SELECTION_ACTIVE_SELECTION_FOREGROUND_COLOR);
table.setSelectionBackground(SELECTION_ACTIVE_SELECTION_BACKGROUND_COLOR);
}

private void makeTableInactive() {
table.setSelectionForeground(SELECTION_INACTIVE_SELECTION_FOREGROUND_COLOR);
table.setSelectionBackground(SELECTION_INACTIVE_SELECTION_BACKGROUND_COLOR);
}

private TableCellEditor createDefaultTableCellEditor() {
JTextField textField = new JTextField();
textField.setFont(MacFontUtils.ITUNES_FONT);
textField.setBorder(BorderFactory.createLineBorder(Color.BLACK));
return new DefaultCellEditor(textField);
}

private WindowFocusListener createWindowFocusListener() {
return new WindowFocusListener() {
public void windowGainedFocus(WindowEvent e) {
makeTableActive();
}

public void windowLostFocus(WindowEvent e) {
makeTableInactive();
}
};
}

private Border getRowBorder() {
return BorderFactory.createEmptyBorder(0, 5, 0, 5);
}

private Border getSelectedRowBorder() {
return BorderFactory.createCompoundBorder(
BorderFactory.createMatteBorder(0, 0, 1, 0, getSelectedRowBottomHighlight()),
BorderFactory.createEmptyBorder(1, 5, 0, 5));
}

private Color getSelectedRowBottomHighlight() {
return WindowUtils.isParentWindowFocused(table)
? SELECTION_ACTIVE_BOTTOM_BORDER_COLOR : SELECTION_INACTIVE_BOTTOM_BORDER_COLOR;
}

/**
* Creates a custom {@link CellRendererPane} that sets the renderer component to be non-opqaque
* if the associated row isn't selected. This custom {@code CellRendererPane} is needed because
* a table UI delegate has no prepare renderer like {@link JTable} has.
*/
private CellRendererPane createCustomCellRendererPane() {
return new CellRendererPane() {
@Override
public void paintComponent(Graphics graphics, Component component, Container container,
int x, int y, int w, int h, boolean shouldValidate) {

int rowAtPoint = table.rowAtPoint(new Point(x, y));
boolean isSelected = table.isRowSelected(rowAtPoint);
if (component instanceof JComponent) {
JComponent jComponent = (JComponent) component;
jComponent.setOpaque(isSelected);
jComponent.setBorder(isSelected ? getSelectedRowBorder() : getRowBorder());
jComponent.setBackground(isSelected ? jComponent.getBackground() : TRANSPARENT_COLOR);
}

super.paintComponent(graphics, component, container, x, y, w, h, shouldValidate);
}
};
}

}
Show details Hide details

Change log

r326 by kenneth.orr on Aug 24, 2009   Diff
Added HudSliderUI delegate.
Go to: 
Project members, sign in to write a code review

Older revisions

r323 by kenneth.orr on Aug 19, 2009   Diff
Fixed memory leak (part of  Issue 120 ).
r308 by kenneth.orr on Jul 15, 2009   Diff
Set CellRendererPane component
background color to transparent if the
component is not selected.
r305 by kenneth.orr on Jun 26, 2009   Diff
Added intermediate CellRendererPane to
act as UI delegates prepare renderer
method ( issue 100 ).
All revisions of this file

File info

Size: 6256 bytes, 155 lines
Hosted by Google Code