/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.libraries.designtime.swing.colorchooser;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import org.pentaho.reporting.libraries.designtime.swing.VerticalLayout;
import org.pentaho.reporting.libraries.designtime.swing.event.DocumentChangeHandler;
public class CombinedColorChooser extends AbstractColorChooserPanel
{
private class ChooseRGBComponentActionHandler implements ActionListener
{
private RGBColorSelectorPanel.ColorComponents component;
private ChooseRGBComponentActionHandler(final RGBColorSelectorPanel.ColorComponents component)
{
this.component = component;
}
public void actionPerformed(final ActionEvent e)
{
rgbColorSelectorPanel.setComponent(component);
colorSelectorLayout.last(colorSelectorPanel);
reconfigureSlider(component);
}
}
private class ChooseHSBComponentActionHandler implements ActionListener
{
private HSBColorSelectorPanel.ColorComponents component;
private ChooseHSBComponentActionHandler(final HSBColorSelectorPanel.ColorComponents component)
{
this.component = component;
}
public void actionPerformed(final ActionEvent e)
{
hsbColorSelectorPanel.setComponent(component);
colorSelectorLayout.first(colorSelectorPanel);
reconfigureSlider(component);
}
}
private class ColorSelectionHandler implements ChangeListener
{
private ColorSelectionHandler()
{
}
public void stateChanged(final ChangeEvent e)
{
final Color color = getColorFromModel();
colorModel.setSelectedColor(color);
}
}
private class ExtColorHandler implements ChangeListener
{
private ExtColorHandler()
{
}
private String colorToHex(final Color c)
{
final String color = Integer.toHexString(c.getRGB() & 0x00ffffff);
final StringBuffer retval = new StringBuffer(6);
final int fillUp = 6 - color.length();
for (int i = 0; i < fillUp; i++)
{
retval.append('0');
}
retval.append(color);
return retval.toString().toUpperCase();
}
public void stateChanged(final ChangeEvent e)
{
if (processExternalEvent)
{
return;
}
try
{
processExternalEvent = true;
final Color color = colorModel.getSelectedColor();
getColorSelectionModel().copyInto(colorModel);
red.setValue(colorModel.getRed());
green.setValue(colorModel.getGreen());
blue.setValue(colorModel.getBlue());
hue.setValue(colorModel.getHue());
saturation.setValue(colorModel.getSaturation());
value.setValue(colorModel.getValue());
colorCode.setText(colorToHex(color));
previewPanel.setCurrent(color);
}
finally
{
processExternalEvent = false;
}
}
}
private class HSBKeyboardInputHandler implements ChangeListener
{
public void stateChanged(final ChangeEvent e)
{
if (processExternalEvent)
{
return;
}
colorModel.setHSB((Integer) hue.getValue(), (Integer) saturation.getValue(), (Integer) value.getValue());
}
}
private class RGBKeyboardInputHandler implements ChangeListener
{
public void stateChanged(final ChangeEvent e)
{
if (processExternalEvent)
{
return;
}
colorModel.setRGB((Integer) red.getValue(), (Integer) green.getValue(), (Integer) blue.getValue());
}
}
private class ColorCodeInputHandler extends DocumentChangeHandler
{
private ColorCodeInputHandler()
{
}
protected void handleChange(final DocumentEvent e)
{
if (processExternalEvent)
{
return;
}
final String text = colorCode.getText();
try
{
final int value = Integer.parseInt(text, 16);
colorModel.setSelectedColor(new Color(value));
}
catch (Exception ex)
{
// ignore ..
}
}
}
private class SliderChangeHandler implements ChangeListener
{
private SliderChangeHandler()
{
}
public void stateChanged(final ChangeEvent e)
{
if (sliderSelector == null)
{
return;
}
final Object component = sliderSelector;
if (HSBColorSelectorPanel.ColorComponents.BRIGHTNESS.equals(component))
{
colorModel.setHSB(colorModel.getHue(), colorModel.getSaturation(), selectedValueSlider.getValue());
}
if (HSBColorSelectorPanel.ColorComponents.SATURATION.equals(component))
{
colorModel.setHSB(colorModel.getHue(), selectedValueSlider.getValue(), colorModel.getValue());
}
if (HSBColorSelectorPanel.ColorComponents.HUE.equals(component))
{
colorModel.setHSB(selectedValueSlider.getValue(), colorModel.getSaturation(), colorModel.getValue());
}
if (RGBColorSelectorPanel.ColorComponents.RED.equals(component))
{
colorModel.setRGB(selectedValueSlider.getValue(), colorModel.getGreen(), colorModel.getBlue());
}
if (RGBColorSelectorPanel.ColorComponents.GREEN.equals(component))
{
colorModel.setRGB(colorModel.getRed(), selectedValueSlider.getValue(), colorModel.getBlue());
}
if (RGBColorSelectorPanel.ColorComponents.BLUE.equals(component))
{
colorModel.setRGB(colorModel.getRed(), colorModel.getGreen(), selectedValueSlider.getValue());
}
}
}
private ExtendedColorModel colorModel;
private ColorSelectionHandler selectionHandler;
private JRadioButton hueSelector;
private JRadioButton saturationSelector;
private JRadioButton valueSelector;
private ColorPreviewPanel previewPanel;
private JRadioButton redSelector;
private JRadioButton greenSelector;
private JRadioButton blueSelector;
private JSpinner hue;
private JSpinner saturation;
private JSpinner value;
private JSpinner red;
private JSpinner green;
private JSpinner blue;
private JTextField colorCode;
private JPanel colorSelectorPanel;
private CardLayout colorSelectorLayout;
private HSBColorSelectorPanel hsbColorSelectorPanel;
private RGBColorSelectorPanel rgbColorSelectorPanel;
private boolean processExternalEvent;
private JSlider selectedValueSlider;
private Object sliderSelector;
public CombinedColorChooser()
{
previewPanel = new ColorPreviewPanel();
colorModel = new ExtendedColorModel();
colorModel.addChangeListener(new ExtColorHandler());
selectionHandler = new ColorSelectionHandler();
selectedValueSlider = new JSlider();
selectedValueSlider.setOrientation(JSlider.VERTICAL);
selectedValueSlider.addChangeListener(new SliderChangeHandler());
final ColorChooserMessages messages = ColorChooserMessages.getInstance();
hueSelector = new JRadioButton(messages.getString("Hue"));
hueSelector.setSelected(true);
hueSelector.addActionListener(new ChooseHSBComponentActionHandler(HSBColorSelectorPanel.ColorComponents.HUE));
saturationSelector = new JRadioButton(messages.getString("Saturation"));
saturationSelector.addActionListener(new ChooseHSBComponentActionHandler(HSBColorSelectorPanel.ColorComponents.SATURATION));
valueSelector = new JRadioButton(messages.getString("Brightness"));
valueSelector.addActionListener(new ChooseHSBComponentActionHandler(HSBColorSelectorPanel.ColorComponents.BRIGHTNESS));
redSelector = new JRadioButton(messages.getString("Red"));
redSelector.addActionListener(new ChooseRGBComponentActionHandler(RGBColorSelectorPanel.ColorComponents.RED));
greenSelector = new JRadioButton(messages.getString("Green"));
greenSelector.addActionListener(new ChooseRGBComponentActionHandler(RGBColorSelectorPanel.ColorComponents.GREEN));
blueSelector = new JRadioButton(messages.getString("Blue"));
blueSelector.addActionListener(new ChooseRGBComponentActionHandler(RGBColorSelectorPanel.ColorComponents.BLUE));
final ButtonGroup bg = new ButtonGroup();
bg.add(hueSelector);
bg.add(saturationSelector);
bg.add(valueSelector);
bg.add(redSelector);
bg.add(greenSelector);
bg.add(blueSelector);
hue = new JSpinner(new SpinnerNumberModel(0, 0, 359, 1));
hue.addChangeListener(new HSBKeyboardInputHandler());
saturation = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1));
saturation.addChangeListener(new HSBKeyboardInputHandler());
value = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1));
value.addChangeListener(new HSBKeyboardInputHandler());
red = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
red.addChangeListener(new RGBKeyboardInputHandler());
green = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
green.addChangeListener(new RGBKeyboardInputHandler());
blue = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
blue.addChangeListener(new RGBKeyboardInputHandler());
colorCode = new JTextField();
colorCode.setColumns(6);
colorCode.getDocument().addDocumentListener(new ColorCodeInputHandler());
hsbColorSelectorPanel = new HSBColorSelectorPanel();
rgbColorSelectorPanel = new RGBColorSelectorPanel();
colorSelectorLayout = new CardLayout();
colorSelectorPanel = new JPanel();
colorSelectorPanel.setLayout(colorSelectorLayout);
colorSelectorPanel.add("HSB", hsbColorSelectorPanel); // NON-NLS
colorSelectorPanel.add("RGB", rgbColorSelectorPanel); // NON-NLS
colorSelectorLayout.first(colorSelectorPanel);
buildChooser();
reconfigureSlider(HSBColorSelectorPanel.ColorComponents.HUE);
}
private JPanel createValueInputPanel()
{
final JPanel leftPanel = new JPanel();
leftPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.gridheight = 1;
leftPanel.add(hueSelector, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(hue, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 3;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(new JLabel("\u00b0"), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.gridheight = 1;
leftPanel.add(saturationSelector, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(saturation, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 3;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(new JLabel("%"), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 2;
gbc.gridheight = 1;
leftPanel.add(valueSelector, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(value, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 3;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(new JLabel("%"), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 3;
gbc.gridwidth = 3;
gbc.gridheight = 1;
leftPanel.add(Box.createRigidArea(new Dimension(20, 20)), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 4;
gbc.gridwidth = 2;
gbc.gridheight = 1;
leftPanel.add(redSelector, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 4;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(red, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 5;
gbc.gridwidth = 2;
gbc.gridheight = 1;
leftPanel.add(greenSelector, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 5;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(green, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 6;
gbc.gridwidth = 2;
gbc.gridheight = 1;
leftPanel.add(blueSelector, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 6;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(blue, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 7;
gbc.gridwidth = 3;
gbc.gridheight = 1;
leftPanel.add(Box.createRigidArea(new Dimension(20, 20)), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 8;
gbc.gridwidth = 1;
gbc.gridheight = 1;
leftPanel.add(new JLabel("#"), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 8;
gbc.gridwidth = 3;
gbc.gridheight = 1;
leftPanel.add(colorCode, gbc);
return leftPanel;
}
protected void buildChooser()
{
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 3;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(colorSelectorPanel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 3;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(selectedValueSlider, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
add(createPreviewPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
add(createValueInputPanel(), gbc);
}
private JComponent createPreviewPanel()
{
final ColorChooserMessages messages = ColorChooserMessages.getInstance();
final JPanel p = new JPanel();
p.setLayout(new VerticalLayout());
p.add(new JLabel(messages.getString("New")));
p.add(previewPanel);
p.add(new JLabel(messages.getString("Old")));
return p;
}
public String getDisplayName()
{
final ColorChooserMessages messages = ColorChooserMessages.getInstance();
return messages.getString("CombinedTitle");
}
public Icon getSmallDisplayIcon()
{
return null;
}
public void installChooserPanel(final ExtendedColorModel enclosingChooser)
{
super.installChooserPanel(enclosingChooser);
rgbColorSelectorPanel.setColorSelectionModel(colorModel);
hsbColorSelectorPanel.setColorSelectionModel(colorModel);
final ExtendedColorModel colorSelectionModel = getColorSelectionModel();
if (colorSelectionModel != null)
{
colorSelectionModel.addChangeListener(selectionHandler);
selectionHandler.stateChanged(null);
previewPanel.setPrevious(colorSelectionModel.getSelectedColor());
}
}
public void uninstallChooserPanel()
{
final ExtendedColorModel colorSelectionModel = getColorSelectionModel();
if (colorSelectionModel != null)
{
colorSelectionModel.removeChangeListener(selectionHandler);
}
super.uninstallChooserPanel();
rgbColorSelectorPanel.setColorSelectionModel(null);
hsbColorSelectorPanel.setColorSelectionModel(null);
}
private void reconfigureSlider(final Object component)
{
sliderSelector = null;
if (HSBColorSelectorPanel.ColorComponents.BRIGHTNESS.equals(component))
{
selectedValueSlider.setMinimum(0);
selectedValueSlider.setMaximum(100);
selectedValueSlider.setValue(colorModel.getValue());
}
if (HSBColorSelectorPanel.ColorComponents.SATURATION.equals(component))
{
selectedValueSlider.setMinimum(0);
selectedValueSlider.setMaximum(100);
selectedValueSlider.setValue(colorModel.getSaturation());
}
if (HSBColorSelectorPanel.ColorComponents.HUE.equals(component))
{
selectedValueSlider.setMinimum(0);
selectedValueSlider.setMaximum(359);
selectedValueSlider.setValue(colorModel.getHue());
}
if (RGBColorSelectorPanel.ColorComponents.RED.equals(component))
{
selectedValueSlider.setMinimum(0);
selectedValueSlider.setMaximum(255);
selectedValueSlider.setValue(colorModel.getRed());
}
if (RGBColorSelectorPanel.ColorComponents.GREEN.equals(component))
{
selectedValueSlider.setMinimum(0);
selectedValueSlider.setMaximum(255);
selectedValueSlider.setValue(colorModel.getGreen());
}
if (RGBColorSelectorPanel.ColorComponents.BLUE.equals(component))
{
selectedValueSlider.setMinimum(0);
selectedValueSlider.setMaximum(255);
selectedValueSlider.setValue(colorModel.getBlue());
}
sliderSelector = component;
}
}