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
|
package com.explodingpixels.macwidgets.plaf;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.plaf.basic.BasicCheckBoxUI;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import com.explodingpixels.macwidgets.MacFontUtils;
import com.explodingpixels.macwidgets.WidgetBaseColors;
/**
* Creates a Heads Up Display (HUD) style check box button, similar to that seen in various iApps
* (e.g. iPhoto).
* <br>
* <img src="../../../../../graphics/HUDCheckBoxUI.png">
*/
public class HudCheckBoxUI extends BasicCheckBoxUI {
private boolean isDarkColorScheme = true;
/**
* Creates a HUD style {@link javax.swing.plaf.CheckBoxUI}.
*/
public HudCheckBoxUI()
{
super();
}
/**
* Creates a HUD style {@link javax.swing.plaf.CheckBoxUI}.
*/
public HudCheckBoxUI(boolean isDarkColorScheme)
{
super();
this.isDarkColorScheme = isDarkColorScheme;
}
@Override
protected void installDefaults(final AbstractButton b) {
super.installDefaults(b);
HudPaintingUtils.initHudComponent(b, isDarkColorScheme);
b.setIconTextGap((int) (MacFontUtils.HUD_FONT_SIZE / 2));
icon = new CheckIcon(isDarkColorScheme);
}
@Override
public void paint(Graphics g, JComponent c) {
HudPaintingUtils.updateGraphicsToPaintDisabledControlIfNecessary((Graphics2D) g, c);
super.paint(g, c);
}
@Override
protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
MacFontUtils.enableAntialiasing((Graphics2D) g);
AbstractButton button = (AbstractButton) c;
FontMetrics fontMetrics = g.getFontMetrics(button.getFont());
int mnemonicIndex = button.getDisplayedMnemonicIndex();
g.setColor(button.getForeground());
BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemonicIndex,
textRect.x + getTextShiftOffset(),
textRect.y + fontMetrics.getAscent() + getTextShiftOffset());
}
// Check icon implementation. /////////////////////////////////////////////////////////////////
private class CheckIcon implements Icon {
private final int CHECK_BOX_SIZE = 12;
private boolean isDarkColorScheme = true;
private Color fontColor = WidgetBaseColors.DARK_FONT_COLOR;
public CheckIcon(boolean isDarkColorScheme)
{
this.isDarkColorScheme = isDarkColorScheme;
if (isDarkColorScheme)
fontColor = WidgetBaseColors.DARK_FONT_COLOR;
else
fontColor = WidgetBaseColors.LIGHT_FONT_COLOR;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
AbstractButton button = (AbstractButton) c;
Graphics2D graphics = (Graphics2D) g.create();
// translate the graphics context so that 0,0 is the top/left of the check box. this
// allows us to then delegate the painting to the HudPaintingUtils method, which assumes
// 0,0.
graphics.translate(x, y);
HudPaintingUtils.paintHudControlBackground(graphics, button, CHECK_BOX_SIZE,
CHECK_BOX_SIZE, HudPaintingUtils.Roundedness.CHECK_BOX, isDarkColorScheme);
drawCheckMarkIfNecessary(graphics, button.getModel());
graphics.dispose();
}
/**
* Draws the check mark if {@link ButtonModel#isSelected} returns true.
*/
private void drawCheckMarkIfNecessary(Graphics2D graphics, ButtonModel model) {
if (model.isSelected()) {
drawCheckMark(graphics, model);
}
}
/**
* Draws the check in the check box using the appropriate color based on the
* {@link ButtonModel#isPressed} state. Note that part of the check will be drawn outside
* it's bounds. Because this icon is actually being drawn inside a larger component (a
* {@link javax.swing.JCheckBox}), this shouldn't be an issue.
*/
private void drawCheckMark(Graphics2D graphics, ButtonModel model) {
int x1 = CHECK_BOX_SIZE / 4;
int y1 = CHECK_BOX_SIZE / 3;
int x2 = x1 + CHECK_BOX_SIZE / 6;
int y2 = y1 + CHECK_BOX_SIZE / 4;
int x3 = CHECK_BOX_SIZE - 2;
int y3 = -1;
Color color = model.isPressed() ?
HudPaintingUtils.PRESSED_MARK_COLOR : fontColor;
graphics.setStroke(new BasicStroke(1.65f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
graphics.setColor(color);
graphics.drawLine(x1, y1, x2, y2);
graphics.drawLine(x2, y2, x3, y3);
}
public int getIconWidth() {
return CHECK_BOX_SIZE;
}
public int getIconHeight() {
return CHECK_BOX_SIZE;
}
}
}
|