DefaultHSBChooserPanel.java [plain text]
package javax.swing.colorchooser;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.MemoryImageSource;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
class DefaultHSBChooserPanel extends AbstractColorChooserPanel
{
private transient Image gradientImage;
private transient JPanel gradientPanel;
private transient Image trackImage;
private transient JPanel trackPanel;
private transient JSlider slider;
private transient JRadioButton hRadio;
private transient JRadioButton sRadio;
private transient JRadioButton bRadio;
private transient JSpinner hSpinner;
private transient JSpinner sSpinner;
private transient JSpinner bSpinner;
private static final int imgWidth = 200;
private static final int imgHeight = 200;
private static final int trackWidth = 30;
private static final JLabel R = new JLabel("R");
private static final JLabel G = new JLabel("G");
private static final JLabel B = new JLabel("B");
private transient JLabel rFull;
private transient JLabel gFull;
private transient JLabel bFull;
private transient Point gradientPoint = new Point();
private transient boolean internalChange = false;
private transient boolean spinnerTrigger = false;
private transient int locked = -1;
static final int HLOCKED = 0;
static final int SLOCKED = 1;
static final int BLOCKED = 2;
private transient boolean handlingMouse;
class MainGradientMouseListener extends MouseAdapter
implements MouseMotionListener
{
public void mousePressed(MouseEvent e)
{
gradientPoint = e.getPoint();
update(e.getPoint());
}
public void mouseDragged(MouseEvent e)
{
Point p = e.getPoint();
if (p.x < 0 || p.y < 0 || p.y > imgHeight || p.x > imgWidth)
return;
gradientPoint = p;
update(p);
}
public void mouseMoved(MouseEvent e)
{
}
private void update(Point p)
{
handlingMouse = true;
if (hSpinner.isEnabled())
updateH(p);
else if (sSpinner.isEnabled())
updateS(p);
else
updateB(p);
handlingMouse = false;
}
private void updateH(Point p)
{
float s = (imgWidth - p.x * 1f) / imgWidth;
float b = (imgHeight - p.y * 1f) / imgHeight;
internalChange = true;
sSpinner.setValue(new Integer((int) (s * 100)));
internalChange = false;
bSpinner.setValue(new Integer((int) (b * 100)));
revalidate();
}
private void updateS(Point p)
{
float h = p.x * 1f / imgWidth;
float b = (imgHeight - p.y * 1f) / imgHeight;
internalChange = true;
hSpinner.setValue(new Integer((int) (h * 365)));
internalChange = false;
bSpinner.setValue(new Integer((int) (b * 100)));
revalidate();
}
private void updateB(Point p)
{
float h = p.x * 1f / imgWidth;
float s = (imgHeight - p.y * 1f) / imgHeight;
internalChange = true;
hSpinner.setValue(new Integer((int) (h * 365)));
internalChange = false;
sSpinner.setValue(new Integer((int) (s * 100)));
revalidate();
}
}
class SliderChangeListener implements ChangeListener
{
public void stateChanged(ChangeEvent e)
{
if (internalChange)
return;
Integer value = new Integer(slider.getValue());
switch (locked)
{
case HLOCKED:
hSpinner.setValue(value);
break;
case SLOCKED:
sSpinner.setValue(value);
break;
case BLOCKED:
bSpinner.setValue(value);
break;
}
}
}
class RadioStateListener implements ChangeListener
{
public void stateChanged(ChangeEvent e)
{
JSpinner change;
if (e.getSource() == hRadio)
{
locked = HLOCKED;
change = hSpinner;
}
else if (e.getSource() == sRadio)
{
locked = SLOCKED;
change = sSpinner;
}
else
{
locked = BLOCKED;
change = bSpinner;
}
change.setEnabled(((AbstractButton) e.getSource()).isSelected());
updateSlider();
updateTrack();
updateImage();
repaint();
}
}
class ImageScrollListener implements ChangeListener
{
public void stateChanged(ChangeEvent e)
{
if (internalChange)
return;
float h = ((Number) hSpinner.getValue()).intValue() / 360f;
float s = ((Number) sSpinner.getValue()).intValue() / 100f;
float b = ((Number) bSpinner.getValue()).intValue() / 100f;
spinnerTrigger = true;
getColorSelectionModel().setSelectedColor(new Color(Color.HSBtoRGB(h, s,
b)));
spinnerTrigger = false;
if (! handlingMouse && slider != null && ! slider.getValueIsAdjusting())
{
updateImage();
updateTrack();
}
repaint();
}
}
DefaultHSBChooserPanel()
{
super();
}
public String getDisplayName()
{
return "HSB";
}
public void updateChooser()
{
Color c = getColorSelectionModel().getSelectedColor();
float[] hsbVals = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(),
null);
internalChange = true;
if (! spinnerTrigger)
{
hSpinner.setValue(new Integer((int) (hsbVals[0] * 360)));
sSpinner.setValue(new Integer((int) (hsbVals[1] * 100)));
bSpinner.setValue(new Integer((int) (hsbVals[2] * 100)));
}
switch (locked)
{
case HLOCKED:
if (slider != null)
slider.setValue(((Number) hSpinner.getValue()).intValue());
if (! handlingMouse)
{
gradientPoint.x = (int) ((1
- ((Number) sSpinner.getValue()).intValue() / 100f) * imgWidth);
gradientPoint.y = (int) ((1
- ((Number) bSpinner.getValue()).intValue() / 100f) * imgHeight);
}
break;
case SLOCKED:
if (slider != null)
slider.setValue(((Number) sSpinner.getValue()).intValue());
if (! handlingMouse)
{
gradientPoint.x = (int) (((Number) hSpinner.getValue()).intValue() / 360f * imgWidth);
gradientPoint.y = (int) ((1
- ((Number) bSpinner.getValue()).intValue() / 100f) * imgHeight);
}
break;
case BLOCKED:
if (slider != null)
slider.setValue(((Number) bSpinner.getValue()).intValue());
if (! handlingMouse)
{
gradientPoint.x = (int) (((Number) hSpinner.getValue()).intValue() / 360f * imgWidth);
gradientPoint.y = (int) ((1
- ((Number) sSpinner.getValue()).intValue() / 100f) * imgHeight);
}
break;
}
internalChange = false;
if (! handlingMouse && slider != null && ! slider.getValueIsAdjusting())
updateImage();
if (! handlingMouse || locked != HLOCKED)
updateTrack();
updateTextFields();
}
protected void buildChooser()
{
setLayout(new BorderLayout());
add(buildRightPanel(), BorderLayout.EAST);
JPanel container = new JPanel();
container.setLayout(new BorderLayout());
gradientPanel = new JPanel()
{
public Dimension getPreferredSize()
{
return new Dimension(imgWidth, imgHeight);
}
public void paint(Graphics g)
{
if (gradientImage != null)
g.drawImage(gradientImage, 0, 0, this);
Color saved = g.getColor();
g.setColor(Color.WHITE);
g.drawOval(gradientPoint.x - 3, gradientPoint.y - 3, 6, 6);
g.setColor(saved);
}
};
MouseAdapter ml = new MainGradientMouseListener();
gradientPanel.addMouseListener(ml);
gradientPanel.addMouseMotionListener((MouseMotionListener) ml);
trackPanel = new JPanel()
{
public Dimension getPreferredSize()
{
return new Dimension(trackWidth, imgHeight);
}
public void paint(Graphics g)
{
if (trackImage != null)
g.drawImage(trackImage, 0, 0, this);
}
};
slider = new JSlider();
slider.setPaintTrack(false);
slider.setPaintTicks(false);
slider.setOrientation(SwingConstants.VERTICAL);
updateSlider();
container.add(gradientPanel, BorderLayout.WEST);
container.add(slider, BorderLayout.CENTER);
container.add(trackPanel, BorderLayout.EAST);
add(container, BorderLayout.WEST);
slider.addChangeListener(new SliderChangeListener());
repaint();
}
public void uninstallChooserPanel(JColorChooser chooser)
{
trackImage = null;
gradientImage = null;
gradientPanel = null;
slider = null;
hSpinner = null;
sSpinner = null;
bSpinner = null;
hRadio = null;
sRadio = null;
bRadio = null;
removeAll();
super.uninstallChooserPanel(chooser);
}
private Container buildRightPanel()
{
JPanel container = new JPanel();
container.setLayout(new GridLayout(6, 2));
hRadio = new JRadioButton("H");
sRadio = new JRadioButton("S");
bRadio = new JRadioButton("B");
ButtonGroup group = new ButtonGroup();
group.add(hRadio);
group.add(sRadio);
group.add(bRadio);
hSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 359, 1));
sSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1));
bSpinner = new JSpinner(new SpinnerNumberModel(100, 0, 100, 1));
hSpinner.setEnabled(false);
sSpinner.setEnabled(false);
bSpinner.setEnabled(false);
ChangeListener cl = new RadioStateListener();
ChangeListener scroll = new ImageScrollListener();
hRadio.addChangeListener(cl);
sRadio.addChangeListener(cl);
bRadio.addChangeListener(cl);
hSpinner.addChangeListener(scroll);
sSpinner.addChangeListener(scroll);
bSpinner.addChangeListener(scroll);
hRadio.setSelected(true);
container.add(hRadio);
container.add(hSpinner);
container.add(sRadio);
container.add(sSpinner);
container.add(bRadio);
container.add(bSpinner);
rFull = new JLabel("red full");
gFull = new JLabel("green full");
bFull = new JLabel("blue full");
container.add(R);
container.add(rFull);
container.add(G);
container.add(gFull);
container.add(B);
container.add(bFull);
return container;
}
public Icon getSmallDisplayIcon()
{
return null;
}
public Icon getLargeDisplayIcon()
{
return null;
}
public void paint(Graphics g)
{
super.paint(g);
}
private void updateHLockImage()
{
int index = 0;
int[] pix = new int[imgWidth * imgHeight];
float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < imgWidth; i++)
pix[index++] = Color.HSBtoRGB(hValue, (imgWidth - i * 1f) / imgWidth,
(imgHeight - j * 1f) / imgHeight)
| (255 << 24);
gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
pix, 0, imgWidth));
}
private void updateBLockImage()
{
int[] pix = new int[imgWidth * imgHeight];
float bValue = ((Number) bSpinner.getValue()).intValue() / 100f;
int index = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < imgWidth; i++)
pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth,
(imgHeight - j * 1f) / imgHeight, bValue)
| (255 << 24);
gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
pix, 0, imgWidth));
}
private void updateSLockImage()
{
int[] pix = new int[imgWidth * imgHeight];
float sValue = ((Number) sSpinner.getValue()).intValue() / 100f;
int index = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < imgWidth; i++)
pix[index++] = Color.HSBtoRGB(i * 1f / imgWidth, sValue,
(imgHeight - j * 1f) / imgHeight)
| (255 << 24);
gradientImage = createImage(new MemoryImageSource(imgWidth, imgHeight,
pix, 0, imgWidth));
}
private void updateImage()
{
switch (locked)
{
case HLOCKED:
updateHLockImage();
break;
case SLOCKED:
updateSLockImage();
break;
case BLOCKED:
updateBLockImage();
break;
}
}
private void updateTextFields()
{
int c = getColorSelectionModel().getSelectedColor().getRGB();
rFull.setText("" + (c >> 16 & 0xff));
gFull.setText("" + (c >> 8 & 0xff));
bFull.setText("" + (c & 0xff));
repaint();
}
private void updateSlider()
{
if (slider == null)
return;
slider.setMinimum(0);
if (locked == HLOCKED)
{
slider.setMaximum(359);
;
slider.setValue(((Number) hSpinner.getValue()).intValue());
slider.setInverted(true);
}
else
{
slider.setMaximum(100);
slider.setInverted(false);
if (sRadio.isSelected())
slider.setValue(((Number) sSpinner.getValue()).intValue());
else
slider.setValue(((Number) bSpinner.getValue()).intValue());
}
repaint();
}
private void updateTrack()
{
switch (locked)
{
case HLOCKED:
updateHTrack();
break;
case SLOCKED:
updateSTrack();
break;
case BLOCKED:
updateBTrack();
break;
}
}
private void updateHTrack()
{
int trackIndex = 0;
int[] trackPix = new int[trackWidth * imgHeight];
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < trackWidth; i++)
trackPix[trackIndex++] = Color.HSBtoRGB(j * 1f / imgHeight, 1f, 1f)
| (255 << 24);
trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
trackPix, 0, trackWidth));
}
private void updateSTrack()
{
int[] trackPix = new int[trackWidth * imgHeight];
float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
float bValue = ((Number) bSpinner.getValue()).intValue() / 100f;
int trackIndex = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < trackWidth; i++)
trackPix[trackIndex++] = Color.HSBtoRGB(hValue,
(imgHeight - j * 1f) / imgHeight,
bValue) | (255 << 24);
trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
trackPix, 0, trackWidth));
}
private void updateBTrack()
{
int[] trackPix = new int[trackWidth * imgHeight];
float hValue = ((Number) hSpinner.getValue()).intValue() / 360f;
float sValue = ((Number) sSpinner.getValue()).intValue() / 100f;
int trackIndex = 0;
for (int j = 0; j < imgHeight; j++)
for (int i = 0; i < trackWidth; i++)
trackPix[trackIndex++] = Color.HSBtoRGB(hValue, sValue,
(imgHeight - j * 1f) / imgHeight)
| (255 << 24);
trackImage = createImage(new MemoryImageSource(trackWidth, imgHeight,
trackPix, 0, trackWidth));
}
private float[] getHSBValues()
{
Color c = getColorFromModel();
float[] f = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
return f;
}
}