001    /*
002     * MapToArbitraryPaletteDialog
003     * 
004     * Copyright (c) 2001, 2002 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.CheckboxGroup;
014    import java.awt.Choice;
015    import java.awt.Dialog;
016    import java.awt.Frame;
017    import java.awt.GridLayout;
018    import java.awt.Label;
019    import java.awt.Panel;
020    import java.awt.event.ActionEvent;
021    import java.awt.event.ActionListener;
022    import net.sourceforge.jiu.apps.Strings;
023    import net.sourceforge.jiu.color.dithering.ErrorDiffusionDithering;
024    
025    /**
026     * A dialog to enter the parameters for an operation to map an RGB truecolor
027     * image to any given palette.
028     *
029     * @since 0.5.0
030     * @author Marco Schmidt
031     * @see net.sourceforge.jiu.color.quantization.ArbitraryPaletteQuantizer
032     */
033    public class MapToArbitraryPaletteDialog extends Dialog implements
034            ActionListener
035    {
036            public static final int PALETTE_FILE = 0;
037            public static final int PALETTE_WEBSAFE = 1;
038            public static final int PALETTE_PALM_256_COLORS = 2;
039            public static final int PALETTE_PALM_16_COLORS = 3;
040            public static final int PALETTE_PALM_16_GRAY = 4;
041            public static final int PALETTE_PALM_4_GRAY = 5;
042            public static final int NUM_PALETTE_TYPES = 6;
043            private static final int[] PALETTE_STRING_CONSTANTS =
044            {
045                    Strings.PALETTE_FROM_FILE,
046                    Strings.WEBSAFE_PALETTE,
047                    Strings.PALETTE_PALM_256_COLORS,
048                    Strings.PALETTE_PALM_16_COLORS,
049                    Strings.PALETTE_PALM_16_GRAY,
050                    Strings.PALETTE_PALM_4_GRAY,
051            };
052    
053            private static final int[] DITHERING_STRING_CONSTANTS =
054            {
055                    Strings.DITHERING_NONE,
056                    Strings.FLOYD_STEINBERG_ERROR_DIFFUSION,
057                    Strings.STUCKI_ERROR_DIFFUSION,
058                    Strings.BURKES_ERROR_DIFFUSION,
059                    Strings.SIERRA_ERROR_DIFFUSION,
060                    Strings.JARVIS_JUDICE_NINKE_ERROR_DIFFUSION,
061                    Strings.STEVENSON_ARCE_ERROR_DIFFUSION
062            };
063            private static final int[] ERROR_DIFFUSION_TYPES =
064            {
065                    ErrorDiffusionDithering.TYPE_FLOYD_STEINBERG,
066                    ErrorDiffusionDithering.TYPE_STUCKI,
067                    ErrorDiffusionDithering.TYPE_BURKES,
068                    ErrorDiffusionDithering.TYPE_SIERRA,
069                    ErrorDiffusionDithering.TYPE_JARVIS_JUDICE_NINKE,
070                    ErrorDiffusionDithering.TYPE_STEVENSON_ARCE
071            };
072            private Button ok;
073            private Button cancel;
074    
075            private Checkbox[] checkboxes;
076    
077            private CheckboxGroup paletteType;
078    
079            private Choice dithering;
080            private boolean pressedOk;
081    
082            /**
083             * @param owner the Frame this dialog will belong to
084             */
085            public MapToArbitraryPaletteDialog(Frame owner, Strings strings)
086            {
087                    super(owner, strings.get(Strings.MAP_TO_ARBITRARY_PALETTE), true);
088                    pressedOk = false;
089    
090                    // 1 (CENTER) main panel with components for the various options
091                    Panel mainPanel = new Panel(new GridLayout(0, 1));
092    
093                    // 1.1 Label with message text
094                    Panel panel = new Panel(new GridLayout(0, 1));
095                    panel.add(new Label(strings.get(Strings.CHOOSE_PALETTE_TYPE)));
096                    mainPanel.add(panel);
097    
098                    // 1.2 radio buttons (CheckboxGroup) with palette type
099                    panel = new Panel(new GridLayout(0, 1));
100                    paletteType = new CheckboxGroup();
101                    checkboxes = new Checkbox[PALETTE_STRING_CONSTANTS.length];
102                    boolean selected = true;
103                    for (int i = 0; i < NUM_PALETTE_TYPES; i++)
104                    {
105                            checkboxes[i] = new Checkbox(strings.get(PALETTE_STRING_CONSTANTS[i]), paletteType, selected);
106                            selected = false;
107                            panel.add(checkboxes[i]);
108                    }
109                    mainPanel.add(panel);
110    
111                    // 1.3 Choice with dithering types
112                    panel = new Panel();
113                    panel.add(new Label(strings.get(Strings.DITHERING_METHOD)));
114                    dithering = new Choice();
115                    for (int i = 0; i < DITHERING_STRING_CONSTANTS.length; i++)
116                    {
117                            dithering.add(strings.get(DITHERING_STRING_CONSTANTS[i]));
118                    }
119                    dithering.select(1);
120                    panel.add(dithering);
121                    mainPanel.add(panel);
122    
123                    add(mainPanel, BorderLayout.CENTER);
124    
125                    // 2 (SOUTH) buttons OK and Cancel
126                    panel = new Panel();
127    
128                    // 2.1 OK button
129                    ok = new Button(strings.get(Strings.OK));
130                    ok.addActionListener(this);
131                    panel.add(ok);
132                    // 2.2 Cancel button
133                    cancel = new Button(strings.get(Strings.CANCEL));
134                    cancel.addActionListener(this);
135                    panel.add(cancel);
136    
137                    add(panel, BorderLayout.SOUTH);
138    
139                    pack();
140                    Dialogs.center(this);
141            }
142    
143            /**
144             * Hides (closes) this dialog if the OK button was source of the action event
145             * (e.g. if the button was pressed).
146             */
147            public void actionPerformed(ActionEvent e)
148            {
149                    if (e.getSource() == ok)
150                    {
151                            pressedOk = true;
152                            setVisible(false);
153                    }
154                    else
155                    if (e.getSource() == cancel)
156                    {
157                            setVisible(false);
158                    }
159            }
160    
161            /**
162             * If the use of error diffusion was selected, this method
163             * returns on of the ErrorDiffusionDithering TYPE constants
164             */
165            public int getErrorDiffusionType()
166            {
167                    int sel = dithering.getSelectedIndex();
168                    if (sel > 0 && sel <= ERROR_DIFFUSION_TYPES.length)
169                    {
170                            return ERROR_DIFFUSION_TYPES[sel - 1];
171                    }
172                    else
173                    {
174                            return -1;
175                    }
176            }
177    
178            /**
179             * Return the palette type (one of the PALETTE_xyz constants of this class)
180             * that is currently selected in the dialog.
181             */
182            public int getPaletteType()
183            {
184                    for (int i = 0; i < checkboxes.length; i++)
185                    {
186                            if (checkboxes[i].getState())
187                            {
188                                    return i;
189                            }
190                    }
191                    return -1;
192            }
193    
194            /**
195             * Returns true if the OK button was pressed, false if 
196             * it was the Cancel button.
197             */
198            public boolean hasPressedOk()
199            {
200                    return pressedOk;
201            }
202    
203            /**
204             * Returns whether the use of one of the error diffusion 
205             * algorithms is selected in the dialog.
206             */
207            public boolean useErrorDiffusion()
208            {
209                    return dithering.getSelectedIndex() > 0;
210            }
211    }