001    /*
002     * OctreeDialog
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.Choice;
013    import java.awt.Dialog;
014    import java.awt.Dimension;
015    import java.awt.Frame;
016    import java.awt.GridLayout;
017    import java.awt.Label;
018    import java.awt.Panel;
019    import java.awt.Rectangle;
020    import java.awt.TextField;
021    import java.awt.Toolkit;
022    import java.awt.event.ActionEvent;
023    import java.awt.event.ActionListener;
024    import java.awt.event.KeyEvent;
025    import java.awt.event.KeyListener;
026    import net.sourceforge.jiu.apps.Strings;
027    import net.sourceforge.jiu.color.dithering.ErrorDiffusionDithering;
028    
029    /**
030     * A dialog to enter the parameters for an Octree color quantization operation.
031     * It also allows to enter the optional algorithms that can be applied in combination with Octree.
032     *
033     * @author Marco Schmidt
034     * @since 0.6.0
035     * @see MedianCutDialog
036     */
037    public class OctreeDialog extends Dialog implements 
038            ActionListener, KeyListener
039    {
040            public final int[] DITHERING_STRINGS =
041            {
042                    Strings.DITHERING_NONE,
043                    Strings.FLOYD_STEINBERG_ERROR_DIFFUSION,
044                    Strings.STUCKI_ERROR_DIFFUSION,
045                    Strings.BURKES_ERROR_DIFFUSION,
046                    Strings.SIERRA_ERROR_DIFFUSION,
047                    Strings.JARVIS_JUDICE_NINKE_ERROR_DIFFUSION,
048                    Strings.STEVENSON_ARCE_ERROR_DIFFUSION
049            };
050            public final int[] DITHERING_TYPES =
051            {
052                    0,
053                    ErrorDiffusionDithering.TYPE_FLOYD_STEINBERG,
054                    ErrorDiffusionDithering.TYPE_STUCKI,
055                    ErrorDiffusionDithering.TYPE_BURKES,
056                    ErrorDiffusionDithering.TYPE_SIERRA,
057                    ErrorDiffusionDithering.TYPE_JARVIS_JUDICE_NINKE,
058                    ErrorDiffusionDithering.TYPE_STEVENSON_ARCE
059            };
060            private Button ok;
061            private Button cancel;
062            private TextField numColorsField;
063            private Choice outputColorType;
064            private Choice dithering;
065            private boolean pressedOk;
066    
067            /**
068             * Creates a modal dialog to enter the parameter.
069             * @param owner the parent of this modal dialog
070             * @param strings an object to get String constants in the current language
071             * @param numColors the number of colors in the resulting image
072             * @param paletted if true, the output image will be paletted, otherwise truecolor
073             */
074            public OctreeDialog(Frame owner, Strings strings, int numColors, boolean paletted)
075            {
076                    super(owner, strings.get(Strings.OCTREE_COLOR_QUANTIZATION), true);
077                    pressedOk = false;
078    
079                    Panel panel = new Panel();
080                    panel.setLayout(new GridLayout(0, 2));
081    
082                    panel.add(new Label(strings.get(Strings.NUM_COLORS)));
083                    numColorsField = new TextField(Integer.toString(numColors), 6);
084                    numColorsField.addKeyListener(this);
085                    panel.add(numColorsField);
086    
087                    /*panel.add(new Label(strings.get(Strings.OUTPUT_COLOR_TYPE)));
088                    outputColorType = new Choice();
089                    outputColorType.add(strings.get(Strings.OUTPUT_COLOR_TYPE_PALETTED));
090                    outputColorType.add(strings.get(Strings.OUTPUT_COLOR_TYPE_RGB));
091                    outputColorType.select(paletted ? 0 : 1);
092                    panel.add(outputColorType);*/
093    
094                    panel.add(new Label(strings.get(Strings.DITHERING_METHOD)));
095                    dithering = new Choice();
096                    for (int i = 0; i < DITHERING_STRINGS.length; i++)
097                    {
098                            dithering.add(strings.get(DITHERING_STRINGS[i]));
099                    }
100                    dithering.select(1);
101                    panel.add(dithering);
102    
103                    add(panel, BorderLayout.CENTER);
104    
105                    ok = new Button(strings.get(Strings.OK));
106                    ok.addActionListener(this);
107                    cancel = new Button(strings.get(Strings.CANCEL));
108                    cancel.addActionListener(this);
109    
110                    panel = new Panel();
111                    panel.add(ok);
112                    panel.add(cancel);
113                    add(panel, BorderLayout.SOUTH);
114    
115                    pack();
116                    center();
117            }
118    
119            /**
120             * Hides (closes) this dialog if the OK button was source of the action event
121             * (e.g. if the button was pressed).
122             */
123            public void actionPerformed(ActionEvent e)
124            {
125                    if (e.getSource() == ok)
126                    {
127                            pressedOk = true;
128                            setVisible(false);
129                    }
130                    else
131                    if (e.getSource() == cancel)
132                    {
133                            setVisible(false);
134                    }
135            }
136    
137            /**
138             * Centers the dialog on screen.
139             */
140            public void center()
141            {
142                    Rectangle rect = getBounds();
143                    int width = rect.width;
144                    int height = rect.height;
145                    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
146                    setLocation((screenSize.width / 2) - (width / 2),
147                            (screenSize.height / 2) - (height / 2));
148            }
149    
150            public int getErrorDiffusion()
151            {
152                    int sel = dithering.getSelectedIndex();
153                    if (sel > 0)
154                    {
155                            return DITHERING_TYPES[sel];
156                    }
157                    else
158                    {
159                            return -1;
160                    }
161            }
162    
163            private int getIntValue(TextField textField)
164            {
165                    try
166                    {
167                            return Integer.parseInt(textField.getText());
168                    }
169                    catch (NumberFormatException nfe)
170                    {
171                            return -1;
172                    }
173            }       
174    
175            public int getNumColors()
176            {
177                    return getIntValue(numColorsField);
178            }
179    
180            public boolean hasPressedOk()
181            {
182                    return pressedOk;
183            }
184    
185            public boolean isOutputTypePaletted()
186            {
187                    return outputColorType.getSelectedIndex() == 0;
188            }
189    
190            public void keyPressed(KeyEvent e)
191            {
192                    updateOkButton();
193            }
194    
195            public void keyReleased(KeyEvent e)
196            {
197                    updateOkButton();
198            }
199    
200            public void keyTyped(KeyEvent e)
201            {
202                    updateOkButton();
203            }
204    
205            private void updateOkButton()
206            {
207                    int nc = getNumColors();
208                    boolean enabled = nc >= 1 && nc <= 256;
209                    ok.setEnabled(enabled);
210            }
211    
212            public boolean useErrorDiffusion()
213            {
214                    return dithering.getSelectedIndex() > 0;
215            }
216    
217            public boolean useNoDithering()
218            {
219                    return dithering.getSelectedIndex() == 0;
220            }
221    }