File: MacBadgeRenderer.java

package info (click to toggle)
mac-widgets 0.10.0%2Bsvn416-dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,968 kB
  • ctags: 2,003
  • sloc: java: 9,909; makefile: 13; sh: 12
file content (141 lines) | stat: -rw-r--r-- 5,328 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
package com.explodingpixels.macwidgets;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;

import com.explodingpixels.widgets.WindowUtils;

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

    protected CustomJLabel fLabel = new CustomJLabel();

    protected boolean fSelected = false;

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

    protected final Color fSelectedColor;
    protected final Color fActiveUnselectedColor;
    protected final Color fInactiveUnselectedColor;
    protected final Color fTextColor;

    /**
     * Creates a badge renderer.
     */
    public MacBadgeRenderer(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) {
    	setState(String.valueOf(count), selected);
    }

    /**
     * Sets the state to use when drawing the badge.
     *
     * @param value    the text 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(String value, boolean selected) {
        fLabel.setText(value);
        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();
        }
    }

}