File: ITunesTableUI.java

package info (click to toggle)
mac-widgets 0.10.0%2Bsvn416-dfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,968 kB
  • sloc: java: 9,909; makefile: 13; sh: 12
file content (166 lines) | stat: -rw-r--r-- 5,753 bytes parent folder | download | duplicates (4)
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
156
157
158
159
160
161
162
163
164
165
166
package com.explodingpixels.macwidgets.plaf;

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;

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 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;

/**
 * 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 {

	protected static final Color EVEN_ROW_COLOR = new Color(241, 245, 250);
	protected static final Color TABLE_GRID_COLOR = new Color(0xd9d9d9);
	protected static final Color SELECTION_ACTIVE_SELECTION_FOREGROUND_COLOR = Color.WHITE;
	protected static final Color SELECTION_ACTIVE_SELECTION_BACKGROUND_COLOR = new Color(
			0x3d80df);
	protected static final Color SELECTION_INACTIVE_SELECTION_FOREGROUND_COLOR = Color.BLACK;
	protected static final Color SELECTION_INACTIVE_SELECTION_BACKGROUND_COLOR = new Color(
			0xc0c0c0);
	protected static final Color SELECTION_ACTIVE_BOTTOM_BORDER_COLOR = new Color(
			125, 170, 234);
	protected static final Color SELECTION_INACTIVE_BOTTOM_BORDER_COLOR = new Color(
			224, 224, 224);
	protected 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();
			}
		};
	}

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

	public 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.
	 */
	protected 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 ? table
							.getSelectionBackground() : TRANSPARENT_COLOR);
				}
				super.paintComponent(graphics, component, container, x, y, w,
						h, shouldValidate);
			}
		};
	}
}