001    /*
002     * HueSaturationValueDialog
003     * 
004     * Copyright (c) 2001, 2002, 2003 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.gui.awt.dialogs;
009    
010    import java.awt.BorderLayout;
011    import java.awt.Button;
012    import java.awt.Checkbox;
013    import java.awt.Color;
014    import java.awt.Dialog;
015    import java.awt.Frame;
016    import java.awt.GridLayout;
017    import java.awt.Label;
018    import java.awt.Panel;
019    import java.awt.TextComponent;
020    import java.awt.TextField;
021    import java.awt.event.ActionEvent;
022    import java.awt.event.ActionListener;
023    import java.awt.event.KeyEvent;
024    import java.awt.event.KeyListener;
025    import java.awt.event.ItemEvent;
026    import java.awt.event.ItemListener;
027    import net.sourceforge.jiu.apps.Strings;
028    
029    /**
030     * A dialog to enter the parameters for an hue/saturation/value adjustment operation.
031     * Saturation and value are specified as percentage values between -100 and 100,
032     * where 0 means no change.
033     * Hue can be specified optionally (a Choice component must be checked so
034     * that the hue value will be used); it is a value between 0 and 359.
035     *
036     * @since 0.5.0
037     * @author Marco Schmidt
038     * @see net.sourceforge.jiu.color.adjustment.HueSaturationValue
039     */
040    public class HueSaturationValueDialog extends Dialog implements
041            ActionListener, ItemListener, KeyListener
042    {
043            private Button ok;
044            private Button cancel;
045            private Panel colorPanel;
046            private TextField hue;
047            private TextField saturation;
048            private TextField value;
049            private Checkbox setHue;
050            private boolean pressedOk;
051    
052            /**
053             * @param owner the Frame this dialog will belong to
054             */
055            public HueSaturationValueDialog(Frame owner, Strings strings, boolean initialSetHue, int h, int s, int v)
056            {
057                    super(owner, strings.get(Strings.ADJUST_HUE_SATURATION_AND_VALUE), true);
058                    pressedOk = false;
059                    Panel panel = new Panel();
060                    panel.setLayout(new GridLayout(0, 2));
061    
062                    setHue = new Checkbox(strings.get(Strings.SET_HUE), initialSetHue);
063                    setHue.addItemListener(this);
064                    panel.add(setHue);
065                    colorPanel = new Panel();
066                    panel.add(colorPanel);
067    
068                    panel.add(new Label(strings.get(Strings.HUE)));
069                    hue = new TextField(Integer.toString(h));
070                    hue.addKeyListener(this);
071                    panel.add(hue);
072    
073                    panel.add(new Label(strings.get(Strings.SATURATION)));
074                    saturation = new TextField(Integer.toString(s));
075                    saturation.addKeyListener(this);
076                    panel.add(saturation);
077    
078                    panel.add(new Label(strings.get(Strings.VALUE)));
079                    value = new TextField(Integer.toString(v));
080                    value.addKeyListener(this);
081                    panel.add(value);
082    
083                    add(panel, BorderLayout.CENTER);
084    
085                    ok = new Button(strings.get(Strings.OK));
086                    ok.addActionListener(this);
087                    cancel = new Button(strings.get(Strings.CANCEL));
088                    cancel.addActionListener(this);
089    
090                    panel = new Panel();
091                    panel.add(ok);
092                    panel.add(cancel);
093                    add(panel, BorderLayout.SOUTH);
094    
095                    updateTextFields();
096    
097                    pack();
098                    Dialogs.center(this);
099            }
100    
101            /**
102             * Hides (closes) this dialog if the OK button was source of the action event
103             * (e.g. if the button was pressed).
104             */
105            public void actionPerformed(ActionEvent e)
106            {
107                    if (e.getSource() == ok)
108                    {
109                            pressedOk = true;
110                            setVisible(false);
111                    }
112                    else
113                    if (e.getSource() == cancel)
114                    {
115                            setVisible(false);
116                    }
117            }
118    
119            public int getHue()
120            {
121                    return getValue(hue);
122            }
123    
124            public int getSaturation()
125            {
126                    return getValue(saturation);
127            }
128    
129            public int getValue()
130            {
131                    return getValue(value);
132            }
133    
134            /**
135             * Attempts to convert the content of the argument text component
136             * to an <code>int</code>; if successful, returns that int, otherwise
137             * -1000 is returned.
138             * @param textField the text component that is supposed to hold an int value
139             * @return int representation of the text component's data
140             */
141            private int getValue(TextComponent textField)
142            {
143                    try
144                    {
145                            return Integer.parseInt(textField.getText());
146                    }
147                    catch (NumberFormatException nfe)
148                    {
149                            return -1000;
150                    }
151            }       
152    
153            public boolean hasPressedOk()
154            {
155                    return pressedOk;
156            }
157    
158            public void itemStateChanged(ItemEvent e)
159            {
160                    updateTextFields();
161            }
162    
163            public boolean isHueSet()
164            {
165                    return setHue.getState();
166            }
167    
168            /**
169             * Computes width and height of new image and updates the
170             * corresponding labels.
171             * The labels will either display width and height or a single
172             * dash if the data in the text fields is invalid.
173             */
174            private void updateTextFields()
175            {
176                    hue.setEnabled(setHue.getState());
177                    int h = getValue(hue);
178                    int s = getValue(saturation);
179                    int v = getValue(value);
180                    boolean enabled = s >= -100 && s <= 100 && v >= -100 && v <= 100;
181                    if (setHue.getState())
182                    {
183                            enabled = enabled && h >= 0 && h <= 359;
184                    }
185                    ok.setEnabled(enabled);
186                    Color color = new Color(Color.HSBtoRGB(h / 360f, 1.0f, 1.0f));
187                    colorPanel.setBackground(color);
188            }
189    
190            public void keyPressed(KeyEvent e)
191            {
192                    updateTextFields();
193            }
194    
195            public void keyReleased(KeyEvent e)
196            {
197                    updateTextFields();
198            }
199    
200            public void keyTyped(KeyEvent e)
201            {
202                    updateTextFields();
203            }
204    }