/*
* org.openmicroscopy.shoola.util.ui.colourpicker.ColourSliderUI
*
*------------------------------------------------------------------------------
* Copyright (C) 2006 University of Dundee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.util.ui.colourpicker;
//Java imports
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
//Third-party libraries
//Application-internal dependencies
/**
* ColourSliderUI is the RGB Slider component, which allows the user to change
* the RGB values of the colour using the JSlider component. It also allows the
* user to change the text box associated with each slider to do the same.
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald
* <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
* @version 3.0
* <small>
* (<b>Internal version:</b> $$Revision: $$Date: $$)
* </small>
* @since OME2.2
*/
class RGBSliderUI
extends JPanel
{
/** The slider representing the red channel. */
private ColourSlider redSlider;
/** The slider representing the green channel. */
private ColourSlider greenSlider;
/** The slider representing the blue channel. */
private ColourSlider blueSlider;
/** The slider representing the alpha channel. */
private ColourSlider alphaSlider;
/** Change listener for red slider. */
private ChangeListener redChangeListener;
/** Change listener for green slider. */
private ChangeListener greenChangeListener;
/** Change listener for blue slider. */
private ChangeListener blueChangeListener;
/** Change listener for alpha slider. */
private ChangeListener alphaChangeListener;
/** Action listener for red text box. */
private ActionListener redTextboxActionListener;
/** Action listener for green text box. */
private ActionListener greenTextboxActionListener;
/** Action listener for Blue textbox. */
private ActionListener blueTextboxActionListener;
/** Action listener for alpha TextBox. */
private ActionListener alphaTextboxActionListener;
/**
* Boolean variable, true if the current component is active, this is
* controlled from the parent component. It tells the UI whether or not
* to ignore refresh events.
*/
private boolean active;
/**
* The textfield representing the colour red channel.
*/
private JTextField redTextbox;
/**
* The textfield representing the colour green channel.
*/
private JTextField greenTextbox;
/**
* The textfield representing the blue red channel.
*/
private JTextField blueTextbox;
/**
* The textfield representing the alpha red channel.
*/
private JTextField alphaTextbox;
/** The JLabel representing the colour red channel. */
private JLabel redLabel;
/** The JLabel representing the colour green channel. */
private JLabel greenLabel;
/** The JLabel representing the colour blue channel. */
private JLabel blueLabel;
/** The JLabel representing the colour alpha channel. */
private JLabel alphaLabel;
/** Current layout model, which is a gridbag controller. */
private GridBagLayout layout;
/** Model of the contoller. */
private RGBControl control;
/**
* Creates a new instance and keeps a reference to the control c.
*
* @param c Reference to the control. Mustn't be <code>null</code>.
*/
RGBSliderUI(RGBControl c)
{
if (c == null)
throw new NullPointerException("No control.");
control = c;
createUI();
active = false;
}
/**
* Sets the current component Active, called from parent control letting
* this component know it should listen to refresh events.
*
* @param act active or not.
*/
void setActive(boolean act) { active = act; }
/**
* Creates the Red slider, and changes listener, attaching the change
* listener to the slider.
*/
void createRedSlider()
{
Color s1,s;
Color e;
s1 = control.getColour();
s = new Color(0,s1.getGreen(), s1.getBlue(), 255);
e = new Color(255,s1.getGreen(), s1.getBlue(), 255);
redSlider = new ColourSlider(0, 255, s, e);
redSlider.setValue((int) (control.getRed()*255.0));
redChangeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent)
{
ColourSlider src = (ColourSlider) changeEvent.getSource();
control.setRed(src.getValue()/255.0f);
}
};
redSlider.addChangeListener(redChangeListener);
}
/**
* Creates the Green slider, and change listener, attaching the change
* listener to the slider.
*/
void createGreenSlider()
{
Color s1, s;
Color e1, e;
s1 = control.getColour();
s = new Color(s1.getRed(), 0, s1.getBlue(), 255);
e1 = control.getColour();
e = new Color(e1.getRed(), 255, s1.getBlue(), 255);
greenSlider = new ColourSlider(0, 255, s, e);
greenSlider.setValue((int) (control.getGreen()*255.0));
greenChangeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent)
{
ColourSlider src = (ColourSlider) changeEvent.getSource();
control.setGreen(src.getValue()/255.0f);
}
};
greenSlider.addChangeListener(greenChangeListener);
}
/**
* Creates the Blue slider, and changes listener, attaching the change
* listener to the slider.
*/
void createBlueSlider()
{
Color s1, s;
Color e1, e;
s1 = control.getColour();
s = new Color(s1.getRed(), s1.getGreen(), 0, 255);
e1 = control.getColour();
e = new Color(e1.getRed(), s1.getGreen(), 255, 255);
blueSlider = new ColourSlider(0, 255, s, e);
blueSlider.setValue((int) (control.getBlue()*255.0));
blueChangeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent)
{
ColourSlider src = (ColourSlider) changeEvent.getSource();
control.setBlue(src.getValue()/255.0f);
}
};
blueSlider.addChangeListener(blueChangeListener);
}
/**
* Creates the Alpha slider, and changes listener, attaching the change
* listener to the slider.
*/
void createAlphaSlider()
{
Color s1, s;
Color e1, e;
s1 = control.getColour();
s = new Color(s1.getRed(), s1.getGreen(), s1.getBlue(), 0);
e1 = control.getColour();
e = new Color(e1.getRed(), s1.getGreen(), s1.getBlue(), 255);
alphaSlider = new ColourSlider(0, 255, s, e);
alphaSlider.setValue((int) (control.getAlpha()*255.0));
alphaChangeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent)
{
ColourSlider src = (ColourSlider) changeEvent.getSource();
control.setAlpha(src.getValue()/255.0f);
}
};
alphaSlider.addChangeListener(alphaChangeListener);
}
/**
* Creates the Red textbox, and action listener, attaching the action
* listener to the textbox.
*/
void createRedTextbox()
{
redTextbox = new JTextField(""+(int) (control.getRed()*255));
redTextbox.setColumns(TabbedPaneUI.TEXTBOX_COLUMN);
redTextboxActionListener = new ActionListener(){
public void actionPerformed(ActionEvent actionEvent) {
JTextField src = (JTextField) actionEvent.getSource();
try {
int value = Integer.parseInt(src.getText());
if (value >=0 && value <= 255)
control.setRed(value/255.0f);
else {
ColourPicker.invalidColorValue();
redTextbox.setText(""+(int) (control.getRed()*255));
}
} catch(NumberFormatException e) {
ColourPicker.invalidColorValue();
redTextbox.setText(""+(int) (control.getRed()*255));
} //notify user and reset value
}
};
redTextbox.addActionListener(redTextboxActionListener);
}
/**
* Creates the Green textbox, and action listener, attaching the action
* listener to the textbox.
*/
void createGreenTextbox()
{
greenTextbox = new JTextField(""+(int) (control.getGreen()*255));
greenTextbox.setColumns(TabbedPaneUI.TEXTBOX_COLUMN);
greenTextboxActionListener = new ActionListener(){
public void actionPerformed(ActionEvent actionEvent) {
JTextField src = (JTextField) actionEvent.getSource();
try
{
int value = Integer.parseInt(src.getText());
if (value >= 0 && value <= 255)
control.setGreen(value/255.0f);
else {
ColourPicker.invalidColorValue();
greenTextbox.setText(""+(int) (control.getGreen()*255));
}
} catch(NumberFormatException e) {
ColourPicker.invalidColorValue();
greenTextbox.setText(""+(int) (control.getGreen()*255));
}
}
};
greenTextbox.addActionListener(greenTextboxActionListener);
}
/**
* Creates the Blue textbox, and action listener, attaching the action
* listener to the textbox.
*/
void createBlueTextbox()
{
blueTextbox = new JTextField(""+(int) (control.getBlue()*255));
blueTextbox.setColumns(TabbedPaneUI.TEXTBOX_COLUMN);
blueTextboxActionListener = new ActionListener(){
public void actionPerformed(ActionEvent actionEvent) {
JTextField src = (JTextField) actionEvent.getSource();
try {
int value = Integer.parseInt(src.getText());
if (value >=0 && value <=255)
control.setBlue(value/255.0f);
else {
ColourPicker.invalidColorValue();
blueTextbox.setText(""+(int) (control.getBlue()*255));
}
} catch(NumberFormatException e) {
ColourPicker.invalidColorValue();
blueTextbox.setText(""+(int) (control.getBlue()*255));
}
}
};
blueTextbox.addActionListener(blueTextboxActionListener);
}
/**
* Creates the Alpha textbox, and action listener, attaching the action
* listener to the textbox.
*/
void createAlphaTextbox()
{
alphaTextbox = new JTextField(""+(int) (control.getAlpha()*255));
alphaTextbox.setColumns(TabbedPaneUI.TEXTBOX_COLUMN);
alphaTextboxActionListener = new ActionListener(){
public void actionPerformed(ActionEvent actionEvent) {
JTextField src = (JTextField) actionEvent.getSource();
try {
int value = Integer.parseInt(src.getText());
if (value>=0 && value<=255)
control.setAlpha(value/255.0f);
else {
ColourPicker.invalidColorValue();
alphaTextbox.setText(""+(int) (control.getAlpha()*255));
}
} catch(NumberFormatException e) {
ColourPicker.invalidColorValue();
alphaTextbox.setText(""+(int) (control.getAlpha()*255));
}
}
};
alphaTextbox.addActionListener(alphaTextboxActionListener);
}
/** Creates labels, red, green, blue and alpha. */
void createLabels()
{
redLabel = new JLabel("Red");
greenLabel = new JLabel("Green");
blueLabel = new JLabel("Blue");
alphaLabel = new JLabel("Alpha");
}
/** Lays out the components previously created in createUI. */
void layoutComponents()
{
layout = new GridBagLayout();
this.setLayout(layout);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 80;
gbc.weighty = 5;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 5, 0, 5);
this.add(redLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
this.add(redSlider, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 20;
this.add(redTextbox,gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 80;
this.add(greenLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
this.add(greenSlider, gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.weightx = 20;
this.add(greenTextbox,gbc);
gbc.gridx = 0;
gbc.gridy = 4;
gbc.weightx = 80;
this.add(blueLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
this.add(blueSlider, gbc);
gbc.gridx = 1;
gbc.gridy = 5;
gbc.weightx = 20;
this.add(blueTextbox,gbc);
gbc.gridx = 0;
gbc.gridy = 6;
gbc.weightx = 80;
this.add(alphaLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 7;
this.add(alphaSlider, gbc);
gbc.gridx = 1;
gbc.gridy = 7;
gbc.weightx = 20;
this.add(alphaTextbox,gbc);
}
/**
* Creates slider UI, which consists of 4 JSliders, textfields and JLabels.
*/
void createUI()
{
createRedSlider();
createGreenSlider();
createBlueSlider();
createAlphaSlider();
createRedTextbox();
createGreenTextbox();
createBlueTextbox();
createAlphaTextbox();
createLabels();
layoutComponents();
}
/**
* Updates the red slider of the UI, including changing the colour gradient
* of the slider tracks.
*/
void updateRedSlider()
{
Color s, s1, e;
redSlider.setValue((int) (control.getRed()*255));
s1 = control.getColour();
s = new Color(0, s1.getGreen(), s1.getBlue(), 255);
e = new Color(255, s1.getGreen(), s1.getBlue(), 255);
redSlider.setRGBStart(s);
redSlider.setRGBEnd(e);
}
/**
* Updates the green slider of the UI, including changing the colour
* gradient of the slider tracks.
*/
void updateGreenSlider()
{
Color s, s1, e;
greenSlider.setValue((int) (control.getGreen()*255));
s1 = control.getColour();
s = new Color(s1.getRed(), 0, s1.getBlue(), 255);
e = new Color(s1.getRed(), 255, s1.getBlue(), 255);
greenSlider.setRGBStart(s);
greenSlider.setRGBEnd(e);
}
/**
* Updates the blue slider of the UI, including changing the colour gradient
* of the slider tracks.
*/
void updateBlueSlider()
{
Color s, s1, e;
blueSlider.setValue((int) (control.getBlue()*255));
s1 = control.getColour();
s = new Color(s1.getRed(), s1.getGreen(), 0, 255);
e = new Color(s1.getRed(), s1.getGreen(), 255, 255);
blueSlider.setRGBStart(s);
blueSlider.setRGBEnd(e);
}
/**
* Updates the alpha slider of the UI, including changing the colour
* gradient of the slider tracks.
*/
void updateAlphaSlider()
{
Color s, s1, e;
alphaSlider.setValue((int) (control.getAlpha()*255));
s1 = control.getColour();
s = new Color(s1.getRed(), s1.getGreen(), s1.getBlue(), 0);
e = new Color(s1.getRed(), s1.getGreen(), s1.getBlue(), 255);
alphaSlider.setRGBStart(s);
alphaSlider.setRGBEnd(e);
}
/**
* Updates the sliders of the UI, including changing the colour gradient
* of the different slider tracks.
*/
void updateSliders()
{
updateRedSlider();
updateBlueSlider();
updateGreenSlider();
updateAlphaSlider();
}
/** Updates the textboxes of the UI. */
void updateTextboxes()
{
redTextbox.setText(""+(int) (control.getRed()*255));
greenTextbox.setText(""+(int) (control.getGreen()*255));
blueTextbox.setText(""+(int) (control.getBlue()*255));
alphaTextbox.setText(""+(int) (control.getAlpha()*255));
}
/**
* Refresh method will be called by tabbedpanelUI when the model has
* changed.
*/
void refresh()
{
if (!(active)) return;
removeListeners();
updateSliders();
updateTextboxes();
addListeners();
repaint();
}
/**
* Adds change listeners to the components. Used in conjuntion with
* {@link #removeListeners()} to get round spurious event
* triggers when updating components.
*/
void addListeners()
{
redSlider.addChangeListener(redChangeListener);
greenSlider.addChangeListener(greenChangeListener);
blueSlider.addChangeListener(blueChangeListener);
alphaSlider.addChangeListener(alphaChangeListener);
redTextbox.addActionListener(redTextboxActionListener);
greenTextbox.addActionListener(greenTextboxActionListener);
blueTextbox.addActionListener(blueTextboxActionListener);
alphaTextbox.addActionListener(alphaTextboxActionListener);
}
/**
* Removes change listeners to the components. Used in conjuntion with
* {@link #addListeners()} to get round spurious event
* triggers when updating components.
*/
void removeListeners()
{
redSlider.removeChangeListener(redChangeListener);
greenSlider.removeChangeListener(greenChangeListener);
blueSlider.removeChangeListener(blueChangeListener);
alphaSlider.removeChangeListener(alphaChangeListener);
redTextbox.removeActionListener(redTextboxActionListener);
greenTextbox.removeActionListener(greenTextboxActionListener);
blueTextbox.removeActionListener(blueTextboxActionListener);
alphaTextbox.removeActionListener(alphaTextboxActionListener);
}
}