/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Tiny Look and Feel *
* *
* (C) Copyright 2003 - 2007 Hans Bickel *
* *
* For licensing information and credits, please refer to the *
* comment in file de.muntjak.tinylookandfeel.TinyLookAndFeel *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package de.muntjak.tinylookandfeel.borders;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Window;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.border.AbstractBorder;
import javax.swing.plaf.UIResource;
import de.muntjak.tinylookandfeel.Theme;
import de.muntjak.tinylookandfeel.TinyLookAndFeel;
import de.muntjak.tinylookandfeel.controlpanel.ColorRoutines;
import de.muntjak.tinylookandfeel.controlpanel.SBChooser;
/**
* TinyFrameBorder
*
* @version 1.0
* @author Hans Bickel
*/
public class TinyFrameBorder extends AbstractBorder implements UIResource {
// cache for already painted captions
private static HashMap cache = new HashMap();
public static Color buttonUpperColor, buttonLowerColor;
private static TinyFrameBorder onlyInstance;
private static Robot robot;
private static boolean robotsSupported = true;
private Window window;
private int titleHeight;
private boolean isActive;
public static TinyFrameBorder getInstance() {
if(onlyInstance == null) {
onlyInstance = new TinyFrameBorder();
if(robot == null && robotsSupported) {
try {
robot = new Robot();
} catch(Exception ex) {
robotsSupported = false;
}
}
}
return onlyInstance;
}
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
window = SwingUtilities.getWindowAncestor(c);
isActive = window.isActive();
if(window instanceof JFrame) {
titleHeight = Theme.frameTitleHeight[Theme.derivedStyle[Theme.style]];
}
else {
titleHeight = Theme.frameInternalTitleHeight[Theme.derivedStyle[Theme.style]];
}
if(isActive) {
g.setColor(Theme.frameBorderColor[Theme.style].getColor());
}
else {
g.setColor(Theme.frameBorderDisabledColor[Theme.style].getColor());
}
switch(Theme.derivedStyle[Theme.style]) {
case Theme.TINY_STYLE:
drawTinyBorder(g, x, y, w, h);
break;
case Theme.W99_STYLE:
drawWinBorder(g, x, y, w, h);
break;
case Theme.YQ_STYLE:
drawXpBorder(g, x, y, w, h);
break;
}
Color col = null;
if(isActive) {
col = Theme.frameCaptionColor[Theme.style].getColor();
}
else {
col = Theme.frameCaptionDisabledColor[Theme.style].getColor();
}
g.setColor(col);
switch(Theme.derivedStyle[Theme.style]) {
case Theme.TINY_STYLE:
drawTinyCaption(g, x, y, w, h, col);
break;
case Theme.W99_STYLE:
drawWinCaption(g, x, y, w, h, col);
break;
case Theme.YQ_STYLE:
if(TinyLookAndFeel.controlPanelInstantiated) {
drawXpCaptionNoCache(g, x, y, w, h, col);
}
else {
drawXpCaption(g, x, y, w, h, col);
}
break;
}
}
private void drawTinyBorder(Graphics g, int x, int y, int w, int h) {
}
private void drawWinBorder(Graphics g, int x, int y, int w, int h) {
// Border color
g.drawLine(x, y, x + w - 2, y);
g.drawLine(x, y + 1, x, y + h - 2);
g.drawRect(x + 2, y + 2, w - 5, h - 5);
g.drawRect(x + 3, y + 3, w - 7, h - 7);
g.setColor(Color.WHITE);
g.drawLine(x + 1, y + 1, x + w - 3, y + 1);
g.drawLine(x + 1, y + 2, x + 1, y + h - 3);
g.setColor(Theme.frameDarkColor[Theme.style].getColor());
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
g.setColor(Theme.frameLightColor[Theme.style].getColor());
g.drawLine(x + 1, y + h - 2, x + w - 2, y + h - 2);
g.drawLine(w - 2, y + 1, x + w - 2, y + h - 2);
}
private void drawXpBorder(Graphics g, int x, int y, int w, int h) {
// left
g.drawLine(x, y + 6, x, y + h - 1);
g.drawLine(x + 2, y + titleHeight, x + 2, y + h - 3);
// right
g.drawLine(x + w - 1, y + 6, x + w - 1, y + h - 1);
g.drawLine(x + w - 3, y + titleHeight, x + w - 3, y + h - 3);
// bottom
g.drawLine(x + 2, y + h - 3, x + w - 3, y + h - 3);
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
if(robot != null) {
int wx = window.getLocationOnScreen().x - 4;
int wy = window.getLocationOnScreen().y;
Rectangle screenRect = new Rectangle(wx, wy, 4, 4);
g.drawImage(robot.createScreenCapture(screenRect), x, y, null);
wx = window.getLocationOnScreen().x + window.getWidth() + 1;
screenRect = new Rectangle(wx, wy, 4, 4);
g.drawImage(robot.createScreenCapture(screenRect), x + w - 4, y, null);
}
else {
g.setColor(Theme.backColor[Theme.style].getColor());
g.fillRect(0, 0, w, 3);
}
if(isActive) {
g.setColor(Theme.frameCaptionColor[Theme.style].getColor());
}
else {
g.setColor(Theme.frameCaptionDisabledColor[Theme.style].getColor());
}
// left
g.drawLine(x + 1, y + titleHeight, x + 1, y + h - 2);
// right
g.drawLine(x + w - 2, y + titleHeight, x + w - 2, y + h - 2);
// bottom
g.drawLine(x + 1, y + h - 2, x + w - 2, y + h - 2);
Color c = null;
if(isActive) {
c = Theme.frameBorderColor[Theme.style].getColor();
}
else {
c = Theme.frameBorderDisabledColor[Theme.style].getColor();
}
g.setColor(ColorRoutines.getAlphaColor(c, 82));
g.drawLine(x, y + 3, x, y + 3);
g.drawLine(x + w - 1, y + 3, x + w - 1, y + 3);
g.setColor(ColorRoutines.getAlphaColor(c, 156));
g.drawLine(x, y + 4, x, y + 4);
g.drawLine(x + w - 1, y + 4, x + w - 1, y + 4);
g.setColor(ColorRoutines.getAlphaColor(c, 215));
g.drawLine(x, y + 5, x, y + 5);
g.drawLine(x + w - 1, y + 5, x + w - 1, y + 5);
}
private void drawTinyCaption(Graphics g, int x, int y, int w, int h, Color c) {
}
private void drawWinCaption(Graphics g, int x, int y, int w, int h, Color c) {
int y2 = y + titleHeight - 2;
int tw = w - 8;
int maxSat = 56, maxBri = 78;
if(!isActive) {
maxSat = 0; maxBri = 50;
}
int sat = 0, bri = 0;
int memSat = 0, memBri = 0;
Color col = c;
for(int i = 0; i < tw; i++) { // horizontal
g.setColor(col);
g.drawLine(x + 4 + i, y + 4, x + 4 + i, y2);
sat = maxSat * i / tw;
bri = maxBri * i / tw;
if((sat != memSat) || (bri != memBri)) {
memSat = sat;
memBri = bri;
col = SBChooser.getAdjustedColor(c, sat, bri);
}
}
g.setColor(Theme.frameBorderColor[Theme.style].getColor());
g.drawLine(x + 4, y + titleHeight - 1,
x + w - 5, y + titleHeight - 1);
}
private void drawXpCaption(Graphics g, int x, int y, int w, int h, Color c) {
if(titleHeight == Theme.frameInternalTitleHeight[Theme.derivedStyle[Theme.style]]) {
drawXpInternalCaption(g, x, y, w, h, c);
return;
}
int spread1 = Theme.frameSpreadDarkDisabled[Theme.style];
int spread2 = Theme.frameSpreadLightDisabled[Theme.style];
int y2 = y;
Color borderColor = null;
if(isActive) {
borderColor = Theme.frameBorderColor[Theme.style].getColor();
spread1 = Theme.frameSpreadDark[Theme.style];
spread2 = Theme.frameSpreadLight[Theme.style];
}
else {
borderColor = Theme.frameBorderDisabledColor[Theme.style].getColor();
}
// always paint the semi-transparent parts
// 1
// blend
g.setColor(ColorRoutines.getAlphaColor(borderColor, 82));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 156));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 215));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
y2 ++;
// 2
Color c2 = ColorRoutines.darken(c, 4 * spread1);
g.setColor(c2);
g.drawLine(x + 3, y2, x + 5, y2); // left
g.drawLine(x + w - 6, y2, x + w - 4, y2); // right
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.getAlphaColor(c2, 23));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 3
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 4, y2, x + 5, y2); // left
g.drawLine(x + w - 6, y2, x + w - 5, y2); // right
// darker border
g.setColor(c);
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
c2 = ColorRoutines.darken(c, 6 * spread1);
g.setColor(c2);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 4
// darker border
g.setColor(c);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.lighten(c, 7 * spread2));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.lighten(c, 3 * spread2));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
g.setColor(c);
g.drawLine(x + 6, y2, x + 6, y2);
g.drawLine(x + w - 7, y2, x + w - 7, y2);
y2 ++;
// 5
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.drawLine(x + 5, y2, x + 6, y2); // left
g.drawLine(x + x + w - 7, y2, x + w - 6, y2); // right
// darker border
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.lighten(c, 5 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(c);
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
y2 ++;
// 6
// lighten little
g.setColor(ColorRoutines.darken(c, 4 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// now either paint from cache or create cached image
CaptionKey key = new CaptionKey(isActive, titleHeight);
Object value = cache.get(key);
if(value != null) {
// image is cached - paint and return
g.drawImage((Image)value,
x + 6, y, x + w - 6, y + 5,
0, 0, 1, 5,
window);
g.drawImage((Image)value,
x + 1, y + 5, x + w - 1, y + titleHeight,
0, 5, 1, titleHeight,
window);
// store button colors
buttonUpperColor = ColorRoutines.darken(c, 4 * spread1);
buttonLowerColor = ColorRoutines.lighten(c, 10 * spread2);
return;
}
Image img = new BufferedImage(1, titleHeight, BufferedImage.TYPE_INT_ARGB);
Graphics imgGraphics = img.getGraphics();
// 1
imgGraphics.setColor(borderColor);
imgGraphics.drawLine(0, 0, 1, 0);
// 2
imgGraphics.setColor(ColorRoutines.darken(c, 4 * spread1));
imgGraphics.drawLine(0, 1, 1, 1);
// 3
imgGraphics.setColor(ColorRoutines.lighten(c, 10 * spread2));
imgGraphics.drawLine(0, 2, 1, 2);
// 4
imgGraphics.setColor(c);
imgGraphics.drawLine(0, 3, 1, 3);
// 5
imgGraphics.setColor(ColorRoutines.darken(c, 2 * spread1));
imgGraphics.drawLine(0, 4, 1, 4);
// 6
buttonUpperColor = ColorRoutines.darken(c, 4 * spread1);
imgGraphics.setColor(buttonUpperColor);
imgGraphics.drawLine(0, 5, 1, 5);
// 7 - 8
imgGraphics.setColor(ColorRoutines.darken(c, 4 * spread1));
imgGraphics.drawLine(0, 6, 1, 6);
imgGraphics.drawLine(0, 7, 1, 7);
// 9 - 12
imgGraphics.setColor(ColorRoutines.darken(c, 3 * spread1));
imgGraphics.drawLine(0, 8, 1, 8);
imgGraphics.drawLine(0, 9, 1, 9);
imgGraphics.drawLine(0, 10, 1, 10);
imgGraphics.drawLine(0, 11, 1, 11);
// 13 - 15
imgGraphics.setColor(ColorRoutines.darken(c, 2 * spread1));
imgGraphics.drawLine(0, 12, 1, 12);
imgGraphics.drawLine(0, 13, 1, 13);
imgGraphics.drawLine(0, 14, 1, 14);
// 16 - 17
imgGraphics.setColor(ColorRoutines.darken(c, spread1));
imgGraphics.drawLine(0, 15, 1, 15);
imgGraphics.drawLine(0, 16, 1, 16);
// 18 - 19
imgGraphics.setColor(c);
imgGraphics.drawLine(0, 17, 1, 17);
imgGraphics.drawLine(0, 18, 1, 18);
// 20...
imgGraphics.setColor(ColorRoutines.lighten(c, 2 * spread2));
imgGraphics.drawLine(0, 19, 1, 19);
imgGraphics.setColor(ColorRoutines.lighten(c, 4 * spread2));
imgGraphics.drawLine(0, 20, 1, 20);
imgGraphics.setColor(ColorRoutines.lighten(c, 5 * spread2));
imgGraphics.drawLine(0, 21, 1, 21);
imgGraphics.setColor(ColorRoutines.lighten(c, 6 * spread2));
imgGraphics.drawLine(0, 22, 1, 22);
imgGraphics.setColor(ColorRoutines.lighten(c, 8 * spread2));
imgGraphics.drawLine(0, 23, 1, 23);
imgGraphics.setColor(ColorRoutines.lighten(c, 9 * spread2));
imgGraphics.drawLine(0, 24, 1, 24);
imgGraphics.setColor(ColorRoutines.lighten(c, 10 * spread2));
imgGraphics.drawLine(0, 25, 1, 25);
// 27
imgGraphics.setColor(ColorRoutines.lighten(c, 4 * spread2));
imgGraphics.drawLine(0, 26, 1, 26);
// 28
imgGraphics.setColor(ColorRoutines.darken(c, 2 * spread1));
imgGraphics.drawLine(0, 27, 1, 27);
// 29
if(isActive) {
imgGraphics.setColor(Theme.frameLightColor[Theme.style].getColor());
}
else {
imgGraphics.setColor(Theme.frameLightDisabledColor[Theme.style].getColor());
}
imgGraphics.drawLine(0, 28, 1, 28);
// dispose of image graphics
imgGraphics.dispose();
// paint image
g.drawImage(img,
x + 6, y, x + w - 6, y + 5,
0, 0, 1, 5,
window);
g.drawImage(img,
x + 1, y + 5, x + w - 1, y + titleHeight,
0, 5, 1, titleHeight,
window);
// add the image to the cache
cache.put(key, img);
}
private void drawXpCaptionNoCache(Graphics g, int x, int y, int w, int h, Color c) {
if(titleHeight == Theme.frameInternalTitleHeight[Theme.derivedStyle[Theme.style]]) {
drawXpInternalCaptionNoCache(g, x, y, w, h, c);
return;
}
int y2 = y;
int spread1 = Theme.frameSpreadDarkDisabled[Theme.style];
int spread2 = Theme.frameSpreadLightDisabled[Theme.style];
Color borderColor = null;
if(isActive) {
borderColor = Theme.frameBorderColor[Theme.style].getColor();
spread1 = Theme.frameSpreadDark[Theme.style];
spread2 = Theme.frameSpreadLight[Theme.style];
}
else {
borderColor = Theme.frameBorderDisabledColor[Theme.style].getColor();
}
// 1
g.setColor(borderColor);
g.drawLine(x + 6, y2, x + w - 7, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(borderColor, 82));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 156));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 215));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
y2 ++;
// 2
Color c2 = ColorRoutines.darken(c, 4 * spread1);
g.setColor(c2);
g.drawLine(x + 3, y2, x + w - 4, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.getAlphaColor(c2, 23));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 3
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 4, y2, x + w - 5, y2);
// darker border
g.setColor(c);
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
c2 = ColorRoutines.darken(c, 6 * spread1);
g.setColor(c2);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 4
g.setColor(c);
g.drawLine(x + 7, y2, x + w - 8, y2);
// darker border
g.setColor(c);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.lighten(c, 7 * spread2));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.lighten(c, 3 * spread2));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
g.setColor(c);
g.drawLine(x + 6, y2, x + 6, y2);
g.drawLine(x + w - 7, y2, x + w - 7, y2);
y2 ++;
// 5
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.drawLine(x + 5, y2, x + w - 6, y2);
// darker border
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.lighten(c, 5 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(c);
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
y2 ++;
// 6
buttonUpperColor = ColorRoutines.darken(c, 4 * spread1);
g.setColor(buttonUpperColor);
g.drawLine(x + 2, y2, x + w - 3, y2);
// lighten little
g.setColor(ColorRoutines.darken(c, 4 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 7 - 8
g.setColor(ColorRoutines.darken(c, 4 * spread1));
g.fillRect(x + 1, y2, w - 2, 2);
y2 += 2;
// 9 - 12
g.setColor(ColorRoutines.darken(c, 3 * spread1));
g.fillRect(x + 1, y2, w - 2, 4);
y2 += 4;
// 13 - 15
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.fillRect(x + 1, y2, w - 2, 3);
y2 += 3;
// 16 - 17
g.setColor(ColorRoutines.darken(c, 1 * spread1));
g.fillRect(x + 1, y2, w - 2, 2);
y2 += 2;
// 18 - 19
g.setColor(c);
g.fillRect(x + 1, y2, w - 2, 2);
y2 += 2;
// 20...
g.setColor(ColorRoutines.lighten(c, 2 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 4 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 5 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 6 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 8 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 9 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
buttonLowerColor = ColorRoutines.lighten(c, 10 * spread2);
g.setColor(buttonLowerColor);
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
// 27
g.setColor(ColorRoutines.lighten(c, 4 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
// 28
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
// 29
if(isActive) {
g.setColor(Theme.frameLightColor[Theme.style].getColor());
}
else {
g.setColor(Theme.frameLightDisabledColor[Theme.style].getColor());
}
g.drawLine(x + 1, y2, x + w - 2, y2);
}
private void drawXpInternalCaption(Graphics g, int x, int y, int w, int h, Color c) {
int spread1 = Theme.frameSpreadDarkDisabled[Theme.style];
int spread2 = Theme.frameSpreadLightDisabled[Theme.style];
int y2 = y;
Color borderColor = null;
if(isActive) {
borderColor = Theme.frameBorderColor[Theme.style].getColor();
spread1 = Theme.frameSpreadDark[Theme.style];
spread2 = Theme.frameSpreadLight[Theme.style];
}
else {
borderColor = Theme.frameBorderDisabledColor[Theme.style].getColor();
}
// always paint the semi-transparent parts
// 1
// blend
g.setColor(ColorRoutines.getAlphaColor(borderColor, 82));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 156));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 215));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
y2 ++;
// 2
Color c2 = ColorRoutines.darken(c, 4 * spread1);
g.setColor(c2);
g.drawLine(x + 3, y2, x + 5, y2); // left
g.drawLine(x + w - 6, y2, x + w - 4, y2); // right
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.getAlphaColor(c2, 23));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 3
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 4, y2, x + 5, y2); // left
g.drawLine(x + w - 6, y2, x + w - 5, y2); // right
// darker border
g.setColor(c);
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
c2 = ColorRoutines.darken(c, 6 * spread1);
g.setColor(c2);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 4
// darker border
g.setColor(c);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.lighten(c, 7 * spread2));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.lighten(c, 3 * spread2));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
g.setColor(c);
g.drawLine(x + 6, y2, x + 6, y2);
g.drawLine(x + w - 7, y2, x + w - 7, y2);
y2 ++;
// 5
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.drawLine(x + 5, y2, x + 6, y2); // left
g.drawLine(x + x + w - 7, y2, x + w - 6, y2); // right
// darker border
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.lighten(c, 5 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(c);
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
y2 ++;
// 6
// lighten little
g.setColor(ColorRoutines.darken(c, 4 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// now either paint from cache or create cached image
CaptionKey key = new CaptionKey(isActive, titleHeight);
Object value = cache.get(key);
if(value != null) {
// image is cached - paint and return
g.drawImage((Image)value,
x + 6, y, x + w - 6, y + 5,
0, 0, 1, 5,
window);
g.drawImage((Image)value,
x + 1, y + 5, x + w - 1, y + titleHeight,
0, 5, 1, titleHeight,
window);
// store button colors
buttonUpperColor = ColorRoutines.darken(c, 4 * spread1);
buttonLowerColor = ColorRoutines.lighten(c, 10 * spread2);
return;
}
Image img = new BufferedImage(1, titleHeight, BufferedImage.TYPE_INT_ARGB);
Graphics imgGraphics = img.getGraphics();
// 1
imgGraphics.setColor(borderColor);
imgGraphics.drawLine(0, 0, 1, 0);
// 2
imgGraphics.setColor(ColorRoutines.darken(c, 4 * spread1));
imgGraphics.drawLine(0, 1, 1, 1);
// 3
imgGraphics.setColor(ColorRoutines.lighten(c, 10 * spread2));
imgGraphics.drawLine(0, 2, 1, 2);
// 4
imgGraphics.setColor(c);
imgGraphics.drawLine(0, 3, 1, 3);
// 5
imgGraphics.setColor(ColorRoutines.darken(c, 2 * spread1));
imgGraphics.drawLine(0, 4, 1, 4);
// 6
imgGraphics.setColor(ColorRoutines.darken(c, 4 * spread1));
imgGraphics.drawLine(0, 5, 1, 5);
// 7
imgGraphics.setColor(ColorRoutines.darken(c, 4 * spread1));
imgGraphics.drawLine(0, 6, 1, 6);
// 8 - 10
imgGraphics.setColor(ColorRoutines.darken(c, 3 * spread1));
imgGraphics.drawLine(0, 7, 1, 7);
imgGraphics.drawLine(0, 8, 1, 8);
imgGraphics.drawLine(0, 9, 1, 9);
// 11 - 12
imgGraphics.setColor(ColorRoutines.darken(c, 2 * spread1));
imgGraphics.drawLine(0, 10, 1, 10);
imgGraphics.drawLine(0, 11, 1, 11);
// 13
imgGraphics.setColor(ColorRoutines.darken(c, spread1));
imgGraphics.drawLine(0, 12, 1, 12);
// 14 - 15
imgGraphics.setColor(c);
imgGraphics.drawLine(0, 13, 1, 13);
imgGraphics.drawLine(0, 14, 1, 14);
// 16...
imgGraphics.setColor(ColorRoutines.lighten(c, 2 * spread2));
imgGraphics.drawLine(0, 15, 1, 15);
imgGraphics.setColor(ColorRoutines.lighten(c, 4 * spread2));
imgGraphics.drawLine(0, 16, 1, 16);
imgGraphics.setColor(ColorRoutines.lighten(c, 5 * spread2));
imgGraphics.drawLine(0, 17, 1, 17);
imgGraphics.setColor(ColorRoutines.lighten(c, 6 * spread2));
imgGraphics.drawLine(0, 18, 1, 18);
imgGraphics.setColor(ColorRoutines.lighten(c, 8 * spread2));
imgGraphics.drawLine(0, 19, 1, 19);
imgGraphics.setColor(ColorRoutines.lighten(c, 9 * spread2));
imgGraphics.drawLine(0, 20, 1, 20);
imgGraphics.setColor(ColorRoutines.lighten(c, 10 * spread2));
imgGraphics.drawLine(0, 21, 1, 21);
// 23
imgGraphics.setColor(ColorRoutines.lighten(c, 4 * spread2));
imgGraphics.drawLine(0, 22, 1, 22);
// 24
imgGraphics.setColor(ColorRoutines.darken(c, 2 * spread1));
imgGraphics.drawLine(0, 23, 1, 23);
// 25
if(isActive) {
imgGraphics.setColor(Theme.frameLightColor[Theme.style].getColor());
}
else {
imgGraphics.setColor(Theme.frameLightDisabledColor[Theme.style].getColor());
}
imgGraphics.drawLine(0, 24, 1, 24);
// dispose of image graphics
imgGraphics.dispose();
// paint image
g.drawImage(img,
x + 6, y, x + w - 6, y + 5,
0, 0, 1, 5,
window);
g.drawImage(img,
x + 1, y + 5, x + w - 1, y + titleHeight,
0, 5, 1, titleHeight,
window);
// add the image to the cache
cache.put(key, img);
}
private void drawXpInternalCaptionNoCache(Graphics g, int x, int y, int w, int h, Color c) {
int y2 = y;
int spread1 = Theme.frameSpreadDarkDisabled[Theme.style];
int spread2 = Theme.frameSpreadLightDisabled[Theme.style];
Color borderColor = null;
if(isActive) {
borderColor = Theme.frameBorderColor[Theme.style].getColor();
spread1 = Theme.frameSpreadDark[Theme.style];
spread2 = Theme.frameSpreadLight[Theme.style];
}
else {
borderColor = Theme.frameBorderDisabledColor[Theme.style].getColor();
}
// 1
g.setColor(borderColor);
g.drawLine(x + 6, y2, x + w - 7, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(borderColor, 82));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 156));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.getAlphaColor(borderColor, 215));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
y2 ++;
// 2
Color c2 = ColorRoutines.darken(c, 4 * spread1);
g.setColor(c2);
g.drawLine(x + 3, y2, x + w - 4, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.getAlphaColor(c2, 23));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 3
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 4, y2, x + w - 5, y2);
// darker border
g.setColor(c);
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
c2 = ColorRoutines.darken(c, 6 * spread1);
g.setColor(c2);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
// blend
g.setColor(ColorRoutines.getAlphaColor(c2, 139));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 4
g.setColor(c);
g.drawLine(x + 7, y2, x + w - 8, y2);
// darker border
g.setColor(c);
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(ColorRoutines.lighten(c, 7 * spread2));
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
g.setColor(ColorRoutines.lighten(c, 3 * spread2));
g.drawLine(x + 5, y2, x + 5, y2);
g.drawLine(x + w - 6, y2, x + w - 6, y2);
g.setColor(c);
g.drawLine(x + 6, y2, x + 6, y2);
g.drawLine(x + w - 7, y2, x + w - 7, y2);
y2 ++;
// 5
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.drawLine(x + 5, y2, x + w - 6, y2);
// darker border
g.setColor(ColorRoutines.darken(c, 6 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
// blend from lightest color
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 2, y2, x + 2, y2);
g.drawLine(x + w - 3, y2, x + w - 3, y2);
g.setColor(ColorRoutines.lighten(c, 5 * spread2));
g.drawLine(x + 3, y2, x + 3, y2);
g.drawLine(x + w - 4, y2, x + w - 4, y2);
g.setColor(c);
g.drawLine(x + 4, y2, x + 4, y2);
g.drawLine(x + w - 5, y2, x + w - 5, y2);
y2 ++;
// 6
g.setColor(ColorRoutines.darken(c, 4 * spread1));
g.drawLine(x + 2, y2, x + w - 3, y2);
// lighten little
g.setColor(ColorRoutines.darken(c, 4 * spread1));
g.drawLine(x + 1, y2, x + 1, y2);
g.drawLine(x + w - 2, y2, x + w - 2, y2);
y2 ++;
// 7
g.setColor(ColorRoutines.darken(c, 4 * spread1));
g.fillRect(x + 1, y2, w - 2, 1);
y2 += 1;
// 8 - 10
g.setColor(ColorRoutines.darken(c, 3 * spread1));
g.fillRect(x + 1, y2, w - 2, 3);
y2 += 3;
// 11 - 12
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.fillRect(x + 1, y2, w - 2, 2);
y2 += 2;
// 13
g.setColor(ColorRoutines.darken(c, 1 * spread1));
g.fillRect(x + 1, y2, w - 2, 1);
y2 += 1;
// 14 - 15
g.setColor(c);
g.fillRect(x + 1, y2, w - 2, 2);
y2 += 2;
// 16...
g.setColor(ColorRoutines.lighten(c, 2 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 4 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 5 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 6 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 8 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 9 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
g.setColor(ColorRoutines.lighten(c, 10 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
// 23
g.setColor(ColorRoutines.lighten(c, 4 * spread2));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
// 24
g.setColor(ColorRoutines.darken(c, 2 * spread1));
g.drawLine(x + 1, y2, x + w - 2, y2);
y2 ++;
// 25
if(isActive) {
g.setColor(Theme.frameLightColor[Theme.style].getColor());
}
else {
g.setColor(Theme.frameLightDisabledColor[Theme.style].getColor());
}
g.drawLine(x + 1, y2, x + w - 2, y2);
}
/**
*
* @see javax.swing.border.Border#getBorderInsets(Component)
*/
public Insets getBorderInsets(Component c) {
Window w = SwingUtilities.getWindowAncestor(c);
if(w != null && (w instanceof Frame)) {
Frame f = (Frame)w;
// if the frame is maximized, the border should not be visible
if(f.getExtendedState() == (f.getExtendedState() | Frame.MAXIMIZED_BOTH)) {
return new Insets(0, 0, 0, 0);
}
}
return new Insets(0,
Theme.frameBorderWidth[Theme.derivedStyle[Theme.style]],
Theme.frameBorderWidth[Theme.derivedStyle[Theme.style]],
Theme.frameBorderWidth[Theme.derivedStyle[Theme.style]]);
}
/**
* CaptionKey is used as key in the cache HashMap.
* Overrides equals() and hashCode().
*/
static class CaptionKey {
private boolean isActive;
private int titleHeight;
CaptionKey(boolean isActive, int titleHeight) {
this.isActive = isActive;
this.titleHeight = titleHeight;
}
public boolean equals(Object o) {
if(o == null) return false;
if(!(o instanceof CaptionKey)) return false;
CaptionKey other = (CaptionKey)o;
return isActive == other.isActive &&
titleHeight == other.titleHeight;
}
public int hashCode() {
return (isActive ? 1 : 2) * titleHeight;
}
}
}