| /* |
| * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Sun designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Sun in the LICENSE file that accompanied this code. |
| * |
| * This code 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 |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| * CA 95054 USA or visit www.sun.com if you need additional information or |
| * have any questions. |
| */ |
| |
| package javax.swing.colorchooser; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.event.*; |
| import javax.swing.event.*; |
| import javax.swing.border.*; |
| import java.awt.image.*; |
| import java.util.Locale; |
| |
| /** |
| * Implements the default HSB Color chooser |
| * |
| * @author Tom Santos |
| * @author Steve Wilson |
| * @author Mark Davidson |
| * @author Shannon Hickey |
| */ |
| class DefaultHSBChooserPanel extends AbstractColorChooserPanel implements ChangeListener, HierarchyListener { |
| |
| private transient HSBImage palette; |
| private transient HSBImage sliderPalette; |
| |
| private transient Image paletteImage; |
| private transient Image sliderPaletteImage; |
| |
| private JSlider slider; |
| private JSpinner hField; |
| private JSpinner sField; |
| private JSpinner bField; |
| |
| private JTextField redField; |
| private JTextField greenField; |
| private JTextField blueField; |
| |
| private boolean isAdjusting = false; // Flag which indicates that values are set internally |
| private Point paletteSelection = new Point(); |
| private JLabel paletteLabel; |
| private JLabel sliderPaletteLabel; |
| |
| private JRadioButton hRadio; |
| private JRadioButton sRadio; |
| private JRadioButton bRadio; |
| |
| private static final int PALETTE_DIMENSION = 200; |
| private static final int MAX_HUE_VALUE = 359; |
| private static final int MAX_SATURATION_VALUE = 100; |
| private static final int MAX_BRIGHTNESS_VALUE = 100; |
| |
| private int currentMode = HUE_MODE; |
| |
| private static final int HUE_MODE = 0; |
| private static final int SATURATION_MODE = 1; |
| private static final int BRIGHTNESS_MODE = 2; |
| |
| public DefaultHSBChooserPanel() { |
| } |
| |
| private void addPaletteListeners() { |
| paletteLabel.addMouseListener(new MouseAdapter() { |
| public void mousePressed(MouseEvent e ) { |
| float[] hsb = new float[3]; |
| palette.getHSBForLocation( e.getX(), e.getY(), hsb ); |
| updateHSB( hsb[0], hsb[1], hsb[2] ); |
| } |
| }); |
| |
| paletteLabel.addMouseMotionListener(new MouseMotionAdapter() { |
| public void mouseDragged( MouseEvent e ){ |
| int labelWidth = paletteLabel.getWidth(); |
| |
| int labelHeight = paletteLabel.getHeight(); |
| int x = e.getX(); |
| int y = e.getY(); |
| |
| if ( x >= labelWidth ) { |
| x = labelWidth - 1; |
| } |
| |
| if ( y >= labelHeight ) { |
| y = labelHeight - 1; |
| } |
| |
| if ( x < 0 ) { |
| x = 0; |
| } |
| |
| if ( y < 0 ) { |
| y = 0; |
| } |
| |
| float[] hsb = new float[3]; |
| palette.getHSBForLocation( x, y, hsb ); |
| updateHSB( hsb[0], hsb[1], hsb[2] ); |
| } |
| }); |
| } |
| |
| private void updatePalette( float h, float s, float b ) { |
| int x = 0; |
| int y = 0; |
| |
| switch ( currentMode ) { |
| case HUE_MODE: |
| if ( h != palette.getHue() ) { |
| palette.setHue( h ); |
| palette.nextFrame(); |
| } |
| x = PALETTE_DIMENSION - (int)(s * PALETTE_DIMENSION); |
| y = PALETTE_DIMENSION - (int)(b * PALETTE_DIMENSION); |
| break; |
| case SATURATION_MODE: |
| if ( s != palette.getSaturation() ) { |
| palette.setSaturation( s ); |
| palette.nextFrame(); |
| } |
| x = (int)(h * PALETTE_DIMENSION); |
| y = PALETTE_DIMENSION - (int)(b * PALETTE_DIMENSION); |
| break; |
| case BRIGHTNESS_MODE: |
| if ( b != palette.getBrightness() ) { |
| palette.setBrightness( b ); |
| palette.nextFrame(); |
| } |
| x = (int)(h * PALETTE_DIMENSION); |
| y = PALETTE_DIMENSION - (int)(s * PALETTE_DIMENSION); |
| break; |
| } |
| |
| paletteSelection.setLocation( x, y ); |
| paletteLabel.repaint(); |
| } |
| |
| private void updateSlider( float h, float s, float b ) { |
| // Update the slider palette if necessary. |
| // When the slider is the hue slider or the hue hasn't changed, |
| // the hue of the palette will not need to be updated. |
| if (currentMode != HUE_MODE && h != sliderPalette.getHue() ) { |
| sliderPalette.setHue( h ); |
| sliderPalette.nextFrame(); |
| } |
| |
| float value = 0f; |
| |
| switch ( currentMode ) { |
| case HUE_MODE: |
| value = h; |
| break; |
| case SATURATION_MODE: |
| value = s; |
| break; |
| case BRIGHTNESS_MODE: |
| value = b; |
| break; |
| } |
| |
| slider.setValue( Math.round(value * (slider.getMaximum())) ); |
| } |
| |
| private void updateHSBTextFields( float hue, float saturation, float brightness ) { |
| int h = Math.round(hue * 359); |
| int s = Math.round(saturation * 100); |
| int b = Math.round(brightness * 100); |
| |
| if (((Integer)hField.getValue()).intValue() != h) { |
| hField.setValue(new Integer(h)); |
| } |
| if (((Integer)sField.getValue()).intValue() != s) { |
| sField.setValue(new Integer(s)); |
| } |
| if (((Integer)bField.getValue()).intValue() != b) { |
| bField.setValue(new Integer(b)); |
| } |
| } |
| |
| /** |
| * Updates the values of the RGB fields to reflect the new color change |
| */ |
| private void updateRGBTextFields( Color color ) { |
| redField.setText(String.valueOf(color.getRed())); |
| greenField.setText(String.valueOf(color.getGreen())); |
| blueField.setText(String.valueOf(color.getBlue())); |
| } |
| |
| /** |
| * Main internal method of updating the ui controls and the color model. |
| */ |
| private void updateHSB( float h, float s, float b ) { |
| if ( !isAdjusting ) { |
| isAdjusting = true; |
| |
| updatePalette( h, s, b ); |
| updateSlider( h, s, b ); |
| updateHSBTextFields( h, s, b ); |
| |
| Color color = Color.getHSBColor(h, s, b); |
| updateRGBTextFields( color ); |
| |
| getColorSelectionModel().setSelectedColor( color ); |
| |
| isAdjusting = false; |
| } |
| } |
| |
| /** |
| * Invoked automatically when the model's state changes. |
| * It is also called by <code>installChooserPanel</code> to allow |
| * you to set up the initial state of your chooser. |
| * Override this method to update your <code>ChooserPanel</code>. |
| */ |
| public void updateChooser() { |
| if ( !isAdjusting ) { |
| float[] hsb = getHSBColorFromModel(); |
| updateHSB( hsb[0], hsb[1], hsb[2] ); |
| } |
| } |
| |
| public void installChooserPanel(JColorChooser enclosingChooser) { |
| super.installChooserPanel(enclosingChooser); |
| setInheritsPopupMenu(true); |
| addHierarchyListener(this); |
| } |
| |
| /** |
| * Invoked when the panel is removed from the chooser. |
| */ |
| public void uninstallChooserPanel(JColorChooser enclosingChooser) { |
| super.uninstallChooserPanel(enclosingChooser); |
| cleanupPalettesIfNecessary(); |
| removeAll(); |
| removeHierarchyListener(this); |
| } |
| |
| /** |
| * Returns an float array containing the HSB values of the selected color from |
| * the ColorSelectionModel |
| */ |
| private float[] getHSBColorFromModel() { |
| Color color = getColorFromModel(); |
| float[] hsb = new float[3]; |
| Color.RGBtoHSB( color.getRed(), color.getGreen(), color.getBlue(), hsb ); |
| |
| return hsb; |
| } |
| |
| /** |
| * Builds a new chooser panel. |
| */ |
| protected void buildChooser() { |
| setLayout(new BorderLayout()); |
| JComponent spp = buildSliderPalettePanel(); |
| spp.setInheritsPopupMenu(true); |
| add(spp, BorderLayout.BEFORE_LINE_BEGINS); |
| |
| JPanel controlHolder = new JPanel(new SmartGridLayout(1,3)); |
| JComponent hsbControls = buildHSBControls(); |
| hsbControls.setInheritsPopupMenu(true); |
| controlHolder.add(hsbControls); |
| |
| controlHolder.add(new JLabel(" ")); // spacer |
| |
| JComponent rgbControls = buildRGBControls(); |
| rgbControls.setInheritsPopupMenu(true); |
| controlHolder.add(rgbControls); |
| controlHolder.setInheritsPopupMenu(true); |
| |
| controlHolder.setBorder(new EmptyBorder( 10, 5, 10, 5)); |
| add( controlHolder, BorderLayout.CENTER); |
| } |
| |
| /** |
| * Creates the panel with the uneditable RGB field |
| */ |
| private JComponent buildRGBControls() { |
| JPanel panel = new JPanel(new SmartGridLayout(2,3)); |
| panel.setInheritsPopupMenu(true); |
| |
| Color color = getColorFromModel(); |
| redField = new JTextField( String.valueOf(color.getRed()), 3 ); |
| redField.setEditable(false); |
| redField.setHorizontalAlignment( JTextField.RIGHT ); |
| redField.setInheritsPopupMenu(true); |
| |
| greenField = new JTextField(String.valueOf(color.getGreen()), 3 ); |
| greenField.setEditable(false); |
| greenField.setHorizontalAlignment( JTextField.RIGHT ); |
| greenField.setInheritsPopupMenu(true); |
| |
| blueField = new JTextField( String.valueOf(color.getBlue()), 3 ); |
| blueField.setEditable(false); |
| blueField.setHorizontalAlignment( JTextField.RIGHT ); |
| blueField.setInheritsPopupMenu(true); |
| |
| Locale locale = getLocale(); |
| String redString = UIManager.getString("ColorChooser.hsbRedText", locale); |
| String greenString = UIManager.getString("ColorChooser.hsbGreenText", locale); |
| String blueString = UIManager.getString("ColorChooser.hsbBlueText", locale); |
| |
| panel.add( new JLabel(redString) ); |
| panel.add( redField ); |
| panel.add( new JLabel(greenString) ); |
| panel.add( greenField ); |
| panel.add( new JLabel(blueString) ); |
| panel.add( blueField ); |
| |
| return panel; |
| } |
| |
| /** |
| * Creates the panel with the editable HSB fields and the radio buttons. |
| */ |
| private JComponent buildHSBControls() { |
| |
| Locale locale = getLocale(); |
| String hueString = UIManager.getString("ColorChooser.hsbHueText", locale); |
| String saturationString = UIManager.getString("ColorChooser.hsbSaturationText", locale); |
| String brightnessString = UIManager.getString("ColorChooser.hsbBrightnessText", locale); |
| |
| RadioButtonHandler handler = new RadioButtonHandler(); |
| |
| hRadio = new JRadioButton(hueString); |
| hRadio.addActionListener(handler); |
| hRadio.setSelected(true); |
| hRadio.setInheritsPopupMenu(true); |
| |
| sRadio = new JRadioButton(saturationString); |
| sRadio.addActionListener(handler); |
| sRadio.setInheritsPopupMenu(true); |
| |
| bRadio = new JRadioButton(brightnessString); |
| bRadio.addActionListener(handler); |
| bRadio.setInheritsPopupMenu(true); |
| |
| ButtonGroup group = new ButtonGroup(); |
| group.add(hRadio); |
| group.add(sRadio); |
| group.add(bRadio); |
| |
| float[] hsb = getHSBColorFromModel(); |
| |
| hField = new JSpinner(new SpinnerNumberModel((int)(hsb[0] * 359), 0, 359, 1)); |
| sField = new JSpinner(new SpinnerNumberModel((int)(hsb[1] * 100), 0, 100, 1)); |
| bField = new JSpinner(new SpinnerNumberModel((int)(hsb[2] * 100), 0, 100, 1)); |
| |
| hField.addChangeListener(this); |
| sField.addChangeListener(this); |
| bField.addChangeListener(this); |
| |
| hField.setInheritsPopupMenu(true); |
| sField.setInheritsPopupMenu(true); |
| bField.setInheritsPopupMenu(true); |
| |
| JPanel panel = new JPanel( new SmartGridLayout(2, 3) ); |
| |
| panel.add(hRadio); |
| panel.add(hField); |
| panel.add(sRadio); |
| panel.add(sField); |
| panel.add(bRadio); |
| panel.add(bField); |
| panel.setInheritsPopupMenu(true); |
| |
| return panel; |
| } |
| |
| /** |
| * Handler for the radio button classes. |
| */ |
| private class RadioButtonHandler implements ActionListener { |
| public void actionPerformed(ActionEvent evt) { |
| Object obj = evt.getSource(); |
| |
| if (obj instanceof JRadioButton) { |
| JRadioButton button = (JRadioButton)obj; |
| if (button == hRadio) { |
| setMode(HUE_MODE); |
| } else if (button == sRadio) { |
| setMode(SATURATION_MODE); |
| } else if (button == bRadio) { |
| setMode(BRIGHTNESS_MODE); |
| } |
| } |
| } |
| } |
| |
| private void setMode(int mode) { |
| if (currentMode == mode) { |
| return; |
| } |
| |
| isAdjusting = true; // Ensure no events propagate from changing slider value. |
| currentMode = mode; |
| |
| float[] hsb = getHSBColorFromModel(); |
| |
| switch (currentMode) { |
| case HUE_MODE: |
| slider.setInverted(true); |
| slider.setMaximum(MAX_HUE_VALUE); |
| palette.setValues(HSBImage.HSQUARE, hsb[0], 1.0f, 1.0f); |
| sliderPalette.setValues(HSBImage.HSLIDER, 0f, 1.0f, 1.0f); |
| break; |
| case SATURATION_MODE: |
| slider.setInverted(false); |
| slider.setMaximum(MAX_SATURATION_VALUE); |
| palette.setValues(HSBImage.SSQUARE, hsb[0], hsb[1], 1.0f); |
| sliderPalette.setValues(HSBImage.SSLIDER, hsb[0], 1.0f, 1.0f); |
| break; |
| case BRIGHTNESS_MODE: |
| slider.setInverted(false); |
| slider.setMaximum(MAX_BRIGHTNESS_VALUE); |
| palette.setValues(HSBImage.BSQUARE, hsb[0], 1.0f, hsb[2]); |
| sliderPalette.setValues(HSBImage.BSLIDER, hsb[0], 1.0f, 1.0f); |
| break; |
| } |
| |
| isAdjusting = false; |
| |
| palette.nextFrame(); |
| sliderPalette.nextFrame(); |
| |
| updateChooser(); |
| } |
| |
| protected JComponent buildSliderPalettePanel() { |
| |
| // This slider has to have a minimum of 0. A lot of math in this file is simplified due to this. |
| slider = new JSlider(JSlider.VERTICAL, 0, MAX_HUE_VALUE, 0); |
| slider.setInverted(true); |
| slider.setPaintTrack(false); |
| slider.setPreferredSize(new Dimension(slider.getPreferredSize().width, PALETTE_DIMENSION + 15)); |
| slider.addChangeListener(this); |
| slider.setInheritsPopupMenu(true); |
| // We're not painting ticks, but need to ask UI classes to |
| // paint arrow shape anyway, if possible. |
| slider.putClientProperty("Slider.paintThumbArrowShape", Boolean.TRUE); |
| paletteLabel = createPaletteLabel(); |
| addPaletteListeners(); |
| sliderPaletteLabel = new JLabel(); |
| |
| JPanel panel = new JPanel(); |
| panel.add( paletteLabel ); |
| panel.add( slider ); |
| panel.add( sliderPaletteLabel ); |
| |
| initializePalettesIfNecessary(); |
| |
| return panel; |
| } |
| |
| private void initializePalettesIfNecessary() { |
| if (palette != null) { |
| return; |
| } |
| |
| float[] hsb = getHSBColorFromModel(); |
| |
| switch(currentMode){ |
| case HUE_MODE: |
| palette = new HSBImage(HSBImage.HSQUARE, PALETTE_DIMENSION, PALETTE_DIMENSION, hsb[0], 1.0f, 1.0f); |
| sliderPalette = new HSBImage(HSBImage.HSLIDER, 16, PALETTE_DIMENSION, 0f, 1.0f, 1.0f); |
| break; |
| case SATURATION_MODE: |
| palette = new HSBImage(HSBImage.SSQUARE, PALETTE_DIMENSION, PALETTE_DIMENSION, 1.0f, hsb[1], 1.0f); |
| sliderPalette = new HSBImage(HSBImage.SSLIDER, 16, PALETTE_DIMENSION, 1.0f, 0f, 1.0f); |
| break; |
| case BRIGHTNESS_MODE: |
| palette = new HSBImage(HSBImage.BSQUARE, PALETTE_DIMENSION, PALETTE_DIMENSION, 1.0f, 1.0f, hsb[2]); |
| sliderPalette = new HSBImage(HSBImage.BSLIDER, 16, PALETTE_DIMENSION, 1.0f, 1.0f, 0f); |
| break; |
| } |
| paletteImage = Toolkit.getDefaultToolkit().createImage(palette); |
| sliderPaletteImage = Toolkit.getDefaultToolkit().createImage(sliderPalette); |
| |
| paletteLabel.setIcon(new ImageIcon(paletteImage)); |
| sliderPaletteLabel.setIcon(new ImageIcon(sliderPaletteImage)); |
| } |
| |
| private void cleanupPalettesIfNecessary() { |
| if (palette == null) { |
| return; |
| } |
| |
| palette.aborted = true; |
| sliderPalette.aborted = true; |
| |
| palette.nextFrame(); |
| sliderPalette.nextFrame(); |
| |
| palette = null; |
| sliderPalette = null; |
| |
| paletteImage = null; |
| sliderPaletteImage = null; |
| |
| paletteLabel.setIcon(null); |
| sliderPaletteLabel.setIcon(null); |
| } |
| |
| protected JLabel createPaletteLabel() { |
| return new JLabel() { |
| protected void paintComponent( Graphics g ) { |
| super.paintComponent( g ); |
| g.setColor( Color.white ); |
| g.drawOval( paletteSelection.x - 4, paletteSelection.y - 4, 8, 8 ); |
| } |
| }; |
| } |
| |
| public String getDisplayName() { |
| return UIManager.getString("ColorChooser.hsbNameText", getLocale()); |
| } |
| |
| /** |
| * Provides a hint to the look and feel as to the |
| * <code>KeyEvent.VK</code> constant that can be used as a mnemonic to |
| * access the panel. A return value <= 0 indicates there is no mnemonic. |
| * <p> |
| * The return value here is a hint, it is ultimately up to the look |
| * and feel to honor the return value in some meaningful way. |
| * <p> |
| * This implementation looks up the value from the default |
| * <code>ColorChooser.hsbMnemonic</code>, or if it |
| * isn't available (or not an <code>Integer</code>) returns -1. |
| * The lookup for the default is done through the <code>UIManager</code>: |
| * <code>UIManager.get("ColorChooser.rgbMnemonic");</code>. |
| * |
| * @return KeyEvent.VK constant identifying the mnemonic; <= 0 for no |
| * mnemonic |
| * @see #getDisplayedMnemonicIndex |
| * @since 1.4 |
| */ |
| public int getMnemonic() { |
| return getInt("ColorChooser.hsbMnemonic", -1); |
| } |
| |
| /** |
| * Provides a hint to the look and feel as to the index of the character in |
| * <code>getDisplayName</code> that should be visually identified as the |
| * mnemonic. The look and feel should only use this if |
| * <code>getMnemonic</code> returns a value > 0. |
| * <p> |
| * The return value here is a hint, it is ultimately up to the look |
| * and feel to honor the return value in some meaningful way. For example, |
| * a look and feel may wish to render each |
| * <code>AbstractColorChooserPanel</code> in a <code>JTabbedPane</code>, |
| * and further use this return value to underline a character in |
| * the <code>getDisplayName</code>. |
| * <p> |
| * This implementation looks up the value from the default |
| * <code>ColorChooser.rgbDisplayedMnemonicIndex</code>, or if it |
| * isn't available (or not an <code>Integer</code>) returns -1. |
| * The lookup for the default is done through the <code>UIManager</code>: |
| * <code>UIManager.get("ColorChooser.hsbDisplayedMnemonicIndex");</code>. |
| * |
| * @return Character index to render mnemonic for; -1 to provide no |
| * visual identifier for this panel. |
| * @see #getMnemonic |
| * @since 1.4 |
| */ |
| public int getDisplayedMnemonicIndex() { |
| return getInt("ColorChooser.hsbDisplayedMnemonicIndex", -1); |
| } |
| |
| public Icon getSmallDisplayIcon() { |
| return null; |
| } |
| |
| public Icon getLargeDisplayIcon() { |
| return null; |
| } |
| |
| /** |
| * Class for the slider and palette images. |
| */ |
| class HSBImage extends SyntheticImage { |
| protected float h = .0f; |
| protected float s = .0f; |
| protected float b = .0f; |
| protected float[] hsb = new float[3]; |
| |
| protected boolean isDirty = true; |
| protected int cachedY; |
| protected int cachedColor; |
| protected int type; |
| |
| private static final int HSQUARE = 0; |
| private static final int SSQUARE = 1; |
| private static final int BSQUARE = 2; |
| private static final int HSLIDER = 3; |
| private static final int SSLIDER = 4; |
| private static final int BSLIDER = 5; |
| |
| protected HSBImage(int type, int width, int height, float h, float s, float b) { |
| super(width, height); |
| setValues(type, h, s, b); |
| } |
| |
| public void setValues(int type, float h, float s, float b) { |
| this.type = type; |
| cachedY = -1; |
| cachedColor = 0; |
| setHue( h ); |
| setSaturation( s ); |
| setBrightness( b ); |
| } |
| |
| public final void setHue( float hue ) { |
| h = hue; |
| } |
| |
| public final void setSaturation( float saturation ) { |
| s = saturation; |
| } |
| |
| public final void setBrightness( float brightness ) { |
| b = brightness; |
| } |
| |
| public final float getHue() { |
| return h; |
| } |
| |
| public final float getSaturation() { |
| return s; |
| } |
| |
| public final float getBrightness() { |
| return b; |
| } |
| |
| protected boolean isStatic() { |
| return false; |
| } |
| |
| public synchronized void nextFrame() { |
| isDirty = true; |
| notifyAll(); |
| } |
| |
| public synchronized void addConsumer(ImageConsumer ic) { |
| isDirty = true; |
| super.addConsumer(ic); |
| } |
| |
| private int getRGBForLocation( int x, int y ) { |
| if (type >= HSLIDER && y == cachedY) { |
| return cachedColor; |
| } |
| |
| getHSBForLocation( x, y, hsb ); |
| cachedY = y; |
| cachedColor = Color.HSBtoRGB( hsb[0], hsb[1], hsb[2] ); |
| |
| return cachedColor; |
| } |
| |
| public void getHSBForLocation( int x, int y, float[] hsbArray ) { |
| switch (type) { |
| case HSQUARE: { |
| float saturationStep = ((float)x) / width; |
| float brightnessStep = ((float)y) / height; |
| hsbArray[0] = h; |
| hsbArray[1] = s - saturationStep; |
| hsbArray[2] = b - brightnessStep; |
| break; |
| } |
| case SSQUARE: { |
| float brightnessStep = ((float)y) / height; |
| float step = 1.0f / ((float)width); |
| hsbArray[0] = x * step; |
| hsbArray[1] = s; |
| hsbArray[2] = 1.0f - brightnessStep; |
| break; |
| } |
| case BSQUARE: { |
| float saturationStep = ((float)y) / height; |
| float step = 1.0f / ((float)width); |
| hsbArray[0] = x * step; |
| hsbArray[1] = 1.0f - saturationStep; |
| hsbArray[2] = b; |
| break; |
| } |
| case HSLIDER: { |
| float step = 1.0f / ((float)height); |
| hsbArray[0] = y * step; |
| hsbArray[1] = s; |
| hsbArray[2] = b; |
| break; |
| } |
| case SSLIDER: { |
| float saturationStep = ((float)y) / height; |
| hsbArray[0] = h; |
| hsbArray[1] = s - saturationStep; |
| hsbArray[2] = b; |
| break; |
| } |
| case BSLIDER: { |
| float brightnessStep = ((float)y) / height; |
| hsbArray[0] = h; |
| hsbArray[1] = s; |
| hsbArray[2] = b - brightnessStep; |
| break; |
| } |
| } |
| } |
| |
| /** |
| * Overriden method from SyntheticImage |
| */ |
| protected void computeRow( int y, int[] row ) { |
| if ( y == 0 ) { |
| synchronized ( this ) { |
| try { |
| while ( !isDirty ) { |
| wait(); |
| } |
| } catch (InterruptedException ie) { |
| } |
| isDirty = false; |
| } |
| } |
| |
| if (aborted) { |
| return; |
| } |
| |
| for ( int i = 0; i < row.length; ++i ) { |
| row[i] = getRGBForLocation( i, y ); |
| } |
| } |
| } |
| |
| public void stateChanged(ChangeEvent e) { |
| if (e.getSource() == slider) { |
| boolean modelIsAdjusting = slider.getModel().getValueIsAdjusting(); |
| |
| if (!modelIsAdjusting && !isAdjusting) { |
| int sliderValue = slider.getValue(); |
| int sliderRange = slider.getMaximum(); |
| float value = (float)sliderValue / (float)sliderRange; |
| |
| float[] hsb = getHSBColorFromModel(); |
| |
| switch ( currentMode ){ |
| case HUE_MODE: |
| updateHSB(value, hsb[1], hsb[2]); |
| break; |
| case SATURATION_MODE: |
| updateHSB(hsb[0], value, hsb[2]); |
| break; |
| case BRIGHTNESS_MODE: |
| updateHSB(hsb[0], hsb[1], value); |
| break; |
| } |
| } |
| } else if (e.getSource() instanceof JSpinner) { |
| float hue = ((Integer)hField.getValue()).floatValue() / 359f; |
| float saturation = ((Integer)sField.getValue()).floatValue() / 100f; |
| float brightness = ((Integer)bField.getValue()).floatValue() / 100f; |
| |
| updateHSB(hue, saturation, brightness); |
| } |
| } |
| |
| public void hierarchyChanged(HierarchyEvent he) { |
| if ((he.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { |
| if (isDisplayable()) { |
| initializePalettesIfNecessary(); |
| } else { |
| cleanupPalettesIfNecessary(); |
| } |
| } |
| } |
| |
| } |