001    /*
002     * ReduceGrayscaleDialog
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.Scrollbar;
021    import java.awt.Toolkit;
022    import java.awt.event.ActionEvent;
023    import java.awt.event.ActionListener;
024    import java.awt.event.AdjustmentEvent;
025    import java.awt.event.AdjustmentListener;
026    import net.sourceforge.jiu.apps.Strings;
027    
028    /**
029     * A dialog to enter the parameters for a grayscale reduction operation.
030     * @author Marco Schmidt
031     */
032    public class ReduceGrayscaleDialog extends Dialog implements ActionListener, AdjustmentListener
033    {
034            public static final int TYPE_DITHERING_NONE = 0;
035            public static final int TYPE_ORDERED_DITHERING = 1;
036            public static final int TYPE_FLOYD_STEINBERG_ERROR_DIFFUSION = 2;
037            public static final int TYPE_STUCKI_ERROR_DIFFUSION = 3;
038            public static final int TYPE_BURKES_ERROR_DIFFUSION = 4;
039            public static final int TYPE_SIERRA_ERROR_DIFFUSION = 5;
040            public static final int TYPE_JARVIS_JUDICE_NINKE_ERROR_DIFFUSION = 6;
041            public static final int TYPE_STEVENSON_ARCE_ERROR_DIFFUSION = 7;
042            public final int[][] DITHERING_METHODS =
043            {
044                    {
045                     TYPE_DITHERING_NONE,
046                     TYPE_ORDERED_DITHERING,
047                     TYPE_FLOYD_STEINBERG_ERROR_DIFFUSION,
048                     TYPE_STUCKI_ERROR_DIFFUSION,
049                     TYPE_BURKES_ERROR_DIFFUSION,
050                     TYPE_SIERRA_ERROR_DIFFUSION,
051                     TYPE_JARVIS_JUDICE_NINKE_ERROR_DIFFUSION,
052                     TYPE_STEVENSON_ARCE_ERROR_DIFFUSION
053                    },
054                    {
055                     Strings.DITHERING_NONE,
056                     Strings.ORDERED_DITHERING,
057                     Strings.FLOYD_STEINBERG_ERROR_DIFFUSION,
058                     Strings.STUCKI_ERROR_DIFFUSION,
059                     Strings.BURKES_ERROR_DIFFUSION,
060                     Strings.SIERRA_ERROR_DIFFUSION,
061                     Strings.JARVIS_JUDICE_NINKE_ERROR_DIFFUSION,
062                     Strings.STEVENSON_ARCE_ERROR_DIFFUSION
063                    }
064            };
065            private Strings strings;
066            private Button ok;
067            private Button cancel;
068            private Scrollbar scrollbar;
069            private Choice ditheringMethod;
070            private Label bitLabel;
071            private Label shadesLabel;
072            private boolean pressedOk;
073    
074            /**
075             * Creates a modal dialog to enter the parameters.
076             * @param owner the parent of this modal dialog
077             * @param strings an object to get String constants in the current language
078             * @param bits initial number of bits to be shown in the dialog
079             * @param maxBits maximum allowed number of bits
080             * @param ditheringMethodSelection initial selection of dithering method
081             */
082            public ReduceGrayscaleDialog(Frame owner, Strings strings, int bits, int  maxBits,
083                    int ditheringMethodSelection)
084            {
085                    super(owner, strings.get(Strings.REDUCE_NUMBER_OF_SHADES_OF_GRAY), true);
086                    pressedOk = false;
087                    this.strings = strings;
088                    Panel panel = new Panel();
089                    panel.setLayout(new GridLayout(0, 2));
090    
091                    bitLabel = new Label();
092                    panel.add(bitLabel);
093                    scrollbar = new Scrollbar(Scrollbar.HORIZONTAL, bits, 1, 1, maxBits + 1);
094                    scrollbar.addAdjustmentListener(this);
095                    panel.add(scrollbar);
096    
097                    panel.add(new Label(strings.get(Strings.NUMBER_OF_SHADES_OF_GRAY) + ": "));
098                    shadesLabel = new Label();
099                    panel.add(shadesLabel);
100    
101                    panel.add(new Label(strings.get(Strings.DITHERING_METHOD)));
102                    ditheringMethod = new Choice();
103                    for (int i = 0; i < DITHERING_METHODS[0].length; i++)
104                    {
105                            ditheringMethod.add(strings.get(DITHERING_METHODS[1][i]));
106                            if (ditheringMethodSelection == i)
107                            {
108                                    ditheringMethod.select(i);
109                            }
110                    }
111                    panel.add(ditheringMethod);
112    
113                    add(panel, BorderLayout.CENTER);
114    
115                    ok = new Button(strings.get(Strings.OK));
116                    ok.addActionListener(this);
117                    cancel = new Button(strings.get(Strings.CANCEL));
118                    cancel.addActionListener(this);
119    
120                    panel = new Panel();
121                    panel.add(ok);
122                    panel.add(cancel);
123                    add(panel, BorderLayout.SOUTH);
124    
125                    updateLabels();
126    
127                    pack();
128                    center();
129            }
130    
131            /**
132             * Hides (closes) this dialog if the OK button was source of the action event
133             * (e.g. if the button was pressed).
134             */
135            public void actionPerformed(ActionEvent e)
136            {
137                    if (e.getSource() == ok)
138                    {
139                            pressedOk = true;
140                            setVisible(false);
141                    }
142                    else
143                    if (e.getSource() == cancel)
144                    {
145                            setVisible(false);
146                    }
147            }
148    
149            public void adjustmentValueChanged(AdjustmentEvent e)
150            {
151                    updateLabels();
152            }
153    
154            /**
155             * Centers the dialog on screen.
156             */
157            public void center()
158            {
159                    Rectangle rect = getBounds();
160                    int width = rect.width;
161                    int height = rect.height;
162                    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
163                    setLocation((screenSize.width / 2) - (width / 2),
164                            (screenSize.height / 2) - (height / 2));
165            }
166    
167            public int getDitheringMethod()
168            {
169                    return DITHERING_METHODS[0][ditheringMethod.getSelectedIndex()];
170            }
171    
172            public int getNumBits()
173            {
174                    return scrollbar.getValue();
175            }
176    
177            public boolean hasPressedOk()
178            {
179                    return pressedOk;
180            }
181    
182            private void updateLabels()
183            {
184                    int numBits = getNumBits();
185                    bitLabel.setText(strings.get(Strings.NUMBER_OF_BITS) + ": " + numBits);
186                    shadesLabel.setText(Integer.toString(1 << numBits));
187            }
188    }