/*******************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;
import de.muntjak.tinylookandfeel.Theme;
/**
* PSColorChooser
*
* @version 1.0
* @author Hans Bickel
*/
@SuppressWarnings (
{ "all" } )
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 );
}
}
}