File: ITunesTableUI.java

package info (click to toggle)
mac-widgets 0.9.5%2Bsvn369-dfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,920 kB
  • sloc: java: 8,318; makefile: 13; sh: 12
file content (155 lines) | stat: -rw-r--r-- 6,256 bytes parent folder | download
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);
            }
        };
    }

}