/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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.controlpanel;
import java.net.URL;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import de.muntjak.tinylookandfeel.*;
/**
* PSColorChooser
*
* @version 1.0
* @author Hans Bickel
*/
public class PSColorChooser extends JDialog {
private Color inColor, outColor;
private static PSColorChooser myInstance;
private ColorSelector colorSelector;
private HueSelector hueSelector;
private TwoColorField twoColorField;
private NumericTextField redField, greenField, blueField;
private NumericTextField satField, briField, hueField;
private JButton ok;
private boolean spinnerUpdate = false;
private static Cursor cs_cursor;
private static BufferedImage brightmask;
private static GraphicsConfiguration conf;
static {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
conf = ge.getDefaultScreenDevice().getDefaultConfiguration();
brightmask = loadBrightmask();
cs_cursor = loadCursor();
}
private static Cursor loadCursor() {
ImageIcon img = null;
Cursor c = null;
Dimension size = Toolkit.getDefaultToolkit().getBestCursorSize(16, 16);
if(size.width == 32) {
img = loadImageIcon("/de/muntjak/tinylookandfeel/icons/cs32.gif");
c = Toolkit.getDefaultToolkit().createCustomCursor(
img.getImage(), new Point(15, 15), "cs_cursor");
}
else if(size.width == 16) {
img = loadImageIcon("/de/muntjak/tinylookandfeel/icons/cs16.gif");
c = Toolkit.getDefaultToolkit().createCustomCursor(
img.getImage(), new Point(7, 7), "cs_cursor");
}
return c;
}
private static BufferedImage loadBrightmask() {
ImageIcon img = loadImageIcon("/de/muntjak/tinylookandfeel/icons/brightmask.png");
int w = img.getIconWidth();
int h = img.getIconHeight();
BufferedImage bimg = conf.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
Graphics g = bimg.getGraphics();
g.drawImage(img.getImage(), 0, 0, w, h, 0, 0, w, h, null);
return bimg;
}
protected static ImageIcon loadImageIcon(String fn) {
return new ImageIcon(PSColorChooser.class.getResource(fn));
// do the following without the leading slash
// return new ImageIcon(Thread.currentThread().getContextClassLoader().getResource(fn));
}
private PSColorChooser(Frame frame, Color inColor) {
super(frame, "PSColorChooser", true);
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
this.inColor = inColor;
outColor = inColor;
setupUI(frame, inColor);
}
public static Color showColorChooser(Frame frame, Color inColor) {
if(myInstance == null) {
myInstance = new PSColorChooser(frame, inColor);
}
myInstance.setColor(inColor);
myInstance.setVisible(true);
return myInstance.outColor;
}
public static void deleteInstance() {
myInstance = null;
}
public void setColor(Color c) {
spinnerUpdate = true;
inColor = c;
outColor = inColor;
int hue = ColorRoutines.getHue(c);
int sat = ColorRoutines.getSaturation(c);
int bri = ColorRoutines.getBrightness(c);
satField.setValue(sat);
briField.setValue(bri);
hueField.setValue(hue);
redField.setValue(c.getRed());
greenField.setValue(c.getGreen());
blueField.setValue(c.getBlue());
colorSelector.setColor(c);
hueSelector.setHue(hue);
twoColorField.setUpperColor(c);
twoColorField.setLowerColor(c);
spinnerUpdate = false;
}
private void colorChanged(Color c) {
spinnerUpdate = true;
int hue = ColorRoutines.getHue(c);
int sat = ColorRoutines.getSaturation(c);
int bri = ColorRoutines.getBrightness(c);
satField.setValue(sat);
briField.setValue(bri);
hueField.setValue(hue);
redField.setValue(c.getRed());
greenField.setValue(c.getGreen());
blueField.setValue(c.getBlue());
twoColorField.setUpperColor(c);
spinnerUpdate = false;
}
private void hueChanged(int hue) {
spinnerUpdate = true;
int sat = satField.getValue();
int bri = briField.getValue();
hueField.setValue(hue);
Color c = Color.getHSBColor(
(float)(hue / 360.0f), (float)(sat / 100.0f), (float)(bri / 100.0f));
redField.setValue(c.getRed());
greenField.setValue(c.getGreen());
blueField.setValue(c.getBlue());
twoColorField.setUpperColor(c);
colorSelector.setColor(c);
spinnerUpdate = false;
}
private void setupUI(Frame frame, Color inColor) {
JPanel p1 = new JPanel(new BorderLayout());
JPanel p2 = new JPanel(new BorderLayout());
// ColorSelector
JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 7));
int hue = ColorRoutines.getHue(inColor);
colorSelector = new ColorSelector(inColor);
p3.add(colorSelector);
p1.add(p3, BorderLayout.WEST);
// HueSelector
p3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 3));
hueSelector = new HueSelector(hue);
p3.add(hueSelector);
p1.add(p3, BorderLayout.CENTER);
p2.add(p1, BorderLayout.CENTER);
// TwoColorField
p1 = new JPanel(new BorderLayout());
p3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 7));
twoColorField = new TwoColorField(inColor);
p3.add(twoColorField);
p1.add(p3, BorderLayout.NORTH);
// Spinners
p3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 7));
p3.add(createNumericTextFields());
p1.add(p3, BorderLayout.CENTER);
p2.add(p1, BorderLayout.EAST);
getContentPane().add(p2, BorderLayout.NORTH);
// buttons
p3 = new JPanel(new FlowLayout(FlowLayout.RIGHT, 12, 4));
p3.setBorder(new EtchedBorder());
JButton b = new JButton("Cancel");
b.addActionListener(new CancelAction());
p3.add(b);
b = new JButton("OK");
b.addActionListener(new OKAction());
getRootPane().setDefaultButton(b);
p3.add(b);
getContentPane().add(p3, BorderLayout.SOUTH);
pack();
Dimension size = getSize();
setLocation(frame.getLocationOnScreen().x +
(frame.getWidth() - getSize().width) / 2,
frame.getLocationOnScreen().y +
(frame.getHeight() - getSize().height) / 2);
}
private JPanel createNumericTextFields() {
ActionListener rgbAction = new RGBAction();
ActionListener hsbAction = new HSBAction();
JPanel p2 = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.insets = new Insets(0, 0, 4, 2);
gc.anchor = GridBagConstraints.WEST;
gc.gridx = 0;
gc.gridy = 0;
p2.add(new JLabel("H:"), gc);
gc.gridx ++;
hueField = new NumericTextField(3, 0, 0, 360);
hueField.addActionListener(hsbAction);
p2.add(hueField, gc);
gc.gridx = 0;
gc.gridy ++;
p2.add(new JLabel("S:"), gc);
gc.gridx ++;
satField = new NumericTextField(3, 0, 0, 100);
satField.addActionListener(hsbAction);
p2.add(satField, gc);
gc.gridx = 0;
gc.gridy ++;
p2.add(new JLabel("B:"), gc);
gc.gridx ++;
briField = new NumericTextField(3, 0, 0, 100);
briField.addActionListener(hsbAction);
p2.add(briField, gc);
gc.insets = new Insets(8, 0, 4, 2);
gc.gridx = 0;
gc.gridy ++;
p2.add(new JLabel("R:"), gc);
gc.gridx ++;
redField = new NumericTextField(3, 0, 0, 255);
redField.addActionListener(rgbAction);
p2.add(redField, gc);
gc.gridx = 0;
gc.gridy ++;
gc.insets = new Insets(0, 0, 4, 2);
p2.add(new JLabel("G:"), gc);
gc.gridx ++;
greenField = new NumericTextField(3, 0, 0, 255);
greenField.addActionListener(rgbAction);
p2.add(greenField, gc);
gc.gridx = 0;
gc.gridy ++;
p2.add(new JLabel("B:"), gc);
gc.gridx ++;
blueField = new NumericTextField(3, 0, 0, 255);
blueField.addActionListener(rgbAction);
p2.add(blueField, gc);
return p2;
}
class ColorSelector extends JPanel {
private Dimension size = new Dimension(258, 258);
private float hue;
private int h, s, b;
private int circleX, circleY;
private Vector listeners;
private Color theColor;
private boolean mousePressed = false;
ColorSelector(Color c) {
h = ColorRoutines.getHue(c);
s = ColorRoutines.getSaturation(c) * 255 / 100;
b = ColorRoutines.getBrightness(c) * 255 / 100;
hue = (float)(h / 360.0);
theColor = c;
setBorder(new LineBorder(Color.BLACK, 1));
addMouseListener(new Mousey());
addMouseMotionListener(new MouseyDrag());
setCursor(cs_cursor);
}
void setColor(Color c) {
h = hueField.getValue();
s = satField.getValue() * 255 / 100;
b = briField.getValue() * 255 / 100;
hue = (float)(h / 360.0);
repaint(0);
}
public Dimension getPreferredSize() {
return size;
}
public void paint(Graphics g) {
super.paintBorder(g);
if(mousePressed) {
g.setClip(circleX, circleY, 11, 11);
}
Color c;
float sat;
for(int x = 0; x < 256; x++) {
sat = (float)(x / 255.0);
c = Color.getHSBColor(hue, sat, 1.0f);
g.setColor(c);
g.drawLine(x + 1, 1, x + 1, 256);
}
g.drawImage(brightmask, 1, 1, this);
circleX = s - 4; // 0 => 0, 100 => 255
circleY = 255 - b - 4; // 100 => 0, 0 => 255
if(mousePressed) {
g.setClip(circleX, circleY, 11, 11);
}
if(b < 160) {
g.setColor(Color.WHITE);
}
else {
g.setColor(Color.BLACK);
}
g.drawLine(circleX + 3, circleY, circleX + 7, circleY);
g.drawLine(circleX + 3, circleY + 10, circleX + 7, circleY + 10);
g.drawLine(circleX, circleY + 3, circleX, circleY + 7);
g.drawLine(circleX + 10, circleY + 3, circleX + 10, circleY + 7);
g.drawLine(circleX + 2, circleY + 1, circleX + 2, circleY + 1);
g.drawLine(circleX + 8, circleY + 1, circleX + 8, circleY + 1);
g.drawLine(circleX + 1, circleY + 2, circleX + 1, circleY + 2);
g.drawLine(circleX + 9, circleY + 2, circleX + 9, circleY + 2);
g.drawLine(circleX + 1, circleY + 8, circleX + 1, circleY + 8);
g.drawLine(circleX + 9, circleY + 8, circleX + 9, circleY + 8);
g.drawLine(circleX + 2, circleY + 9, circleX + 2, circleY + 9);
g.drawLine(circleX + 8, circleY + 9, circleX + 8, circleY + 9);
}
public void update(Graphics g) {
paint(g);
}
class Mousey extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if(e.getX() < 1 || e.getX() > 256) return;
if(e.getY() < 1 || e.getY() > 256) return;
s = e.getX() - 1;
if(s < 0) s = 0;
else if(s > 255) s = 255;
int y = e.getY() - 1;
if(y < 0) y = 0;
else if(y > 255) y = 255;
mousePressed = true;
b = 255 - y;
paint(ColorSelector.this.getGraphics());
theColor = Color.getHSBColor(hue, (float)(s / 255.0), (float)(b / 255.0));
colorChanged(theColor);
}
public void mouseReleased(MouseEvent e) {
mousePressed = false;
}
}
class MouseyDrag extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
s = e.getX() - 1;
if(s < 0) s = 0;
else if(s > 255) s = 255;
int y = e.getY() - 1;
if(y < 0) y = 0;
else if(y > 255) y = 255;
b = 255 - y;
paint(ColorSelector.this.getGraphics());
theColor = Color.getHSBColor(hue, (float)(s / 255.0), (float)(b / 255.0));
colorChanged(theColor);
}
}
}
class TwoColorField extends JPanel {
private Dimension size = new Dimension(60, 68);
private Color upperColor, lowerColor;
TwoColorField(Color c) {
setBorder(new LineBorder(Color.BLACK, 1));
upperColor = c;
lowerColor = c;
}
public Dimension getPreferredSize() {
return size;
}
void setUpperColor(Color c) {
upperColor = c;
outColor = c;
repaint(0);
}
void setLowerColor(Color c) {
lowerColor = c;
repaint(0);
}
public void paint(Graphics g) {
super.paintBorder(g);
g.setColor(upperColor);
g.fillRect(1, 1, 58, 33);
g.setColor(lowerColor);
g.fillRect(1, 34, 58, 33);
}
}
class HueSelector extends JPanel {
private Color darkColor = new Color(128, 128, 128);
private Dimension size = new Dimension(35, 266);
private float hue;
private int arrowY;
private Vector listeners;
HueSelector(int hue) {
this.hue = (float)(hue / 360.0);
addMouseListener(new Mousey());
addMouseMotionListener(new MouseyDrag());
}
void setHue(int hue) {
this.hue = (float)(hue / 360.0);
repaint(0);
}
public Dimension getPreferredSize() {
return size;
}
public void paint(Graphics g) {
g.setColor(Theme.backColor[Theme.style].getColor());
g.fillRect(0, 0, 35, 266);
drawArrows(g);
// border
g.setColor(darkColor);
g.drawLine(6, 3, 27, 3);
g.drawLine(6, 3, 6, 261);
g.setColor(Color.WHITE);
g.drawLine(6, 262, 28, 262);
g.drawLine(28, 3, 28, 261);
g.setColor(Color.BLACK);
g.drawRect(7, 4, 20, 257);
// gradients
int x1 = 8;
int x2 = 26;
int y1 = 5;
for(int y = 0; y < 256; y++) {
float h = (float)((255 - y) / 255.0);
g.setColor(Color.getHSBColor(h, 1.0f, 1.0f));
g.drawLine(x1, y + y1, x2, y + y1);
}
}
private void drawArrows(Graphics g) {
arrowY = 255 + 5 - (int)(hue * 255.0);
g.setColor(Color.BLACK);
g.drawLine(0, arrowY - 5, 0, arrowY + 5);
g.drawLine(1, arrowY - 4, 1, arrowY - 4);
g.drawLine(2, arrowY - 3, 2, arrowY - 3);
g.drawLine(3, arrowY - 2, 3, arrowY - 2);
g.drawLine(4, arrowY - 1, 4, arrowY - 1);
g.drawLine(5, arrowY, 5, arrowY);
g.drawLine(0, arrowY + 5, 0, arrowY + 5);
g.drawLine(1, arrowY + 4, 1, arrowY + 4);
g.drawLine(2, arrowY + 3, 2, arrowY + 3);
g.drawLine(3, arrowY + 2, 3, arrowY + 2);
g.drawLine(4, arrowY + 1, 4, arrowY + 1);
g.drawLine(34, arrowY - 5, 34, arrowY + 5);
g.drawLine(33, arrowY - 4, 33, arrowY - 4);
g.drawLine(32, arrowY - 3, 32, arrowY - 3);
g.drawLine(31, arrowY - 2, 31, arrowY - 2);
g.drawLine(30, arrowY - 1, 30, arrowY - 1);
g.drawLine(29, arrowY, 29, arrowY);
g.drawLine(34, arrowY + 5, 34, arrowY + 5);
g.drawLine(33, arrowY + 4, 33, arrowY + 4);
g.drawLine(32, arrowY + 3, 32, arrowY + 3);
g.drawLine(31, arrowY + 2, 31, arrowY + 2);
g.drawLine(30, arrowY + 1, 30, arrowY + 1);
}
class Mousey extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if(e.getY() < 5 || e.getY() > 260) return;
hue = (float)((255 - (e.getY() - 5)) / 255.0);
repaint();
hueChanged((int)(hue * 360.0));
}
}
class MouseyDrag extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
int y = e.getY() - 5;
if(y < 0) y = 0;
else if(y > 255) y = 255;
hue = (float)((255 - y) / 255.0);
repaint();
hueChanged((int)(hue * 360.0));
}
}
}
class RGBAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(spinnerUpdate) return;
int r = redField.getValue();
int g = greenField.getValue();
int b = blueField.getValue();
Color c = new Color(r, g, b);
twoColorField.setUpperColor(c);
spinnerUpdate = true;
int hue = ColorRoutines.getHue(c);
hueField.setValue(hue);
satField.setValue(ColorRoutines.getSaturation(c));
briField.setValue(ColorRoutines.getBrightness(c));
spinnerUpdate = false;
hueSelector.setHue(hue);
colorSelector.setColor(c);
}
}
class HSBAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(spinnerUpdate) return;
int h = hueField.getValue();
int s = satField.getValue();
int b = briField.getValue();
Color c = Color.getHSBColor(
(float)(h / 360.0f), (float)(s / 100.0f), (float)(b / 100.0f));
twoColorField.setUpperColor(c);
spinnerUpdate = true;
redField.setValue(c.getRed());
greenField.setValue(c.getGreen());
blueField.setValue(c.getBlue());
spinnerUpdate = false;
hueSelector.setHue(h);
colorSelector.setColor(c);
}
}
class OKAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
}
class CancelAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
outColor = null;
setVisible(false);
}
}
}