File: SourceListCountBadgeRenderer.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 (122 lines) | stat: -rw-r--r-- 4,755 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
package com.explodingpixels.macwidgets;

import com.explodingpixels.widgets.WindowUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;

/**
 * Renders a rounded rectangle (i.e. a badge) with a given number in the center of the rectangle.
 */
public class SourceListCountBadgeRenderer {

    private CustomJLabel fLabel = new CustomJLabel();

    private boolean fSelected = false;

    private static Font BADGE_FONT = new Font("Helvetica", Font.BOLD, 11);

    private final Color fSelectedColor;
    private final Color fActiveUnselectedColor;
    private final Color fInactiveUnselectedColor;
    private final Color fTextColor;

    /**
     * Creates a badge renderer.
     */
    public SourceListCountBadgeRenderer(Color selectedColor, Color activeUnselectedColor,
                                        Color inactiveUnselectedColor, Color textColor) {
        fLabel.setFont(BADGE_FONT);
        fLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6));

        fSelectedColor = selectedColor;
        fActiveUnselectedColor = activeUnselectedColor;
        fInactiveUnselectedColor = inactiveUnselectedColor;
        fTextColor = textColor;
    }

    /**
     * Sets the state to use when drawing the badge.
     *
     * @param count    the count value to draw in the center of the badge.
     * @param selected {@code} true if the badge should be rendered in a selected state.
     */
    public void setState(int count, boolean selected) {
        fLabel.setText(String.valueOf(count));
        fSelected = selected;
    }

    /**
     * Gets the user interface component to representing this {@code SourceListCountBadgeRenderer}.
     * The returned {@link JComponent} should be added to a container that will be displayed.
     *
     * @return the user interface component representing this {@code SourceListCountBadgeRenderer}.
     */
    public JComponent getComponent() {
        return fLabel;
    }

    // Custom JLabel implementation. //////////////////////////////////////////////////////////////

    private class CustomJLabel extends JLabel {

        private Color getSelectedBadgeColor() {
            return fSelectedColor;
        }

        private Color getUnselectedBadgeColor(boolean parentWindowHasFocus) {
            return parentWindowHasFocus ? fActiveUnselectedColor : fInactiveUnselectedColor;
        }

        @Override
        protected void paintComponent(Graphics g) {
            // create a buffered image to draw the component into. this lets us
            // draw "out" an area, making it transparent.
            BufferedImage image = new BufferedImage(getWidth(), getHeight(),
                    BufferedImage.TYPE_INT_ARGB);

            // create the graphics and set its initial state.
            Graphics2D g2d = image.createGraphics();
            g2d.setFont(getFont());
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(fSelected
                    ? getSelectedBadgeColor()
                    : getUnselectedBadgeColor(WindowUtils.isParentWindowFocused(this)));

            // draw the badge.
            g2d.fillRoundRect(0, 0, getWidth(), getHeight(), getHeight(), getHeight());

            // set the color to use for the text - note this color is always
            // the same, though it won't always show because of the composite
            // set below.
            g2d.setColor(fTextColor);
            // if the badge is selected, punch out the text so that the
            //    underlying color shows through as the font color.
            // else use use a standard alpha composite to simply draw on top of
            //    whatever is currently there.
            g2d.setComposite(fSelected
                    ? AlphaComposite.DstOut : AlphaComposite.SrcOver);
            // calculate the bottom left point to draw the text at.
            Font font = g2d.getFont();
            FontRenderContext renderContext = g2d.getFontRenderContext();
            GlyphVector glyphVector = font.createGlyphVector(renderContext, getText());
            Rectangle visualBounds = glyphVector.getVisualBounds().getBounds();
            int x = getWidth() / 2 - g2d.getFontMetrics().stringWidth(getText()) / 2;
            int y = getHeight() / 2 - visualBounds.height / 2 - visualBounds.y;

            // draw the badge text.
            g2d.drawString(getText(), x, y);

            // draw the image into this component.
            g.drawImage(image, 0, 0, null);

            // dispose of the buffered image graphics.
            g2d.dispose();
        }
    }

}