View Javadoc

1   /**
2    * Copyright 2009 Timothy Johnston Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3    * file except in compliance with the License. You may obtain a copy of the License at
4    * 
5    * http://www.apache.org/licenses/LICENSE-2.0
6    * 
7    * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8    * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9    * specific language governing permissions and limitations under the License.
10   */
11  package com.timjohnstondev.unitconverter.view;
12  
13  import java.awt.Color;
14  import java.awt.Component;
15  import java.awt.FlowLayout;
16  import java.awt.Font;
17  import java.awt.Graphics;
18  import java.awt.event.ActionEvent;
19  import java.awt.event.ActionListener;
20  import java.util.ResourceBundle;
21  import javax.swing.Icon;
22  import javax.swing.JButton;
23  import javax.swing.JColorChooser;
24  import javax.swing.JComboBox;
25  import javax.swing.JDialog;
26  import javax.swing.JLabel;
27  import javax.swing.JList;
28  import javax.swing.JPanel;
29  import javax.swing.ListCellRenderer;
30  import com.timjohnstondev.unitconverter.controller.LogicController;
31  import com.timjohnstondev.unitconverter.controller.ModelController;
32  
33  /**
34   * This panel contains all of the configuration options for the application. Background color, foreground color, and
35   * font size are adjustable.
36   */
37  public class ConfigurationPanel extends JPanel implements Configuration, ActionListener
38  {
39    private LogicController logicController;
40    private int iconWidthHeight;
41    private JButton backgroundColorButton;
42    private JButton foregroundColorButton;
43    private JButton defaultColorButton;
44    private Color chosen;
45    private JComboBox fontSizeList;
46    private JComboBox unitSeparatorList;
47    private UnitConverter mainPanel;
48    private ModelController modelController;
49    private ResourceBundle resources;
50  
51    /**
52     * Constructs a {@code ConfigurationPanel} with a {@link UnitConverter} to allow access back to the application's main
53     * panel for updating.
54     * 
55     * @param appPanel the {@code UnitConverter} to access to the main panel
56     * @param control the {@code Controller} to access to the model layer
57     */
58    public ConfigurationPanel(final UnitConverter appPanel, final ModelController control)
59    {
60      mainPanel = appPanel;
61      logicController = new LogicController();
62      modelController = control;
63      setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 5));
64  
65      resources = ResourceBundle.getBundle("com.timjohnstondev.unitconverter.view.View");
66      iconWidthHeight = Integer.parseInt(resources.getString("ConfigurationPanel.iconWidthHeight"));
67  
68      backgroundColorButton = new JButton(resources.getString("ConfigurationPanel.backgroundColorButtonText"));
69      foregroundColorButton = new JButton(resources.getString("ConfigurationPanel.foregroundColorButtonText"));
70      defaultColorButton = new JButton(resources.getString("ConfigurationPanel.defaultColorButtonText"));
71  
72      backgroundColorButton.setIcon(new ColorIcon(backgroundColorButton.getText()));
73      foregroundColorButton.setIcon(new ColorIcon(foregroundColorButton.getText()));
74  
75      final JLabel unitSeparatorLabel = new JLabel(resources.getString("ConfigurationPanel.unitSeparatorLabel"));
76      unitSeparatorList = new JComboBox(resources.getString("ConfigurationPanel.unitSeparatorList").split(","));
77      unitSeparatorList.setSelectedIndex(getSeparatorPreferenceIndex());
78      unitSeparatorList.setRenderer(new ComboBoxRenderer());
79  
80      final JLabel fontSizeLabel = new JLabel(resources.getString("ConfigurationPanel.defaultColorButtonText"));
81      fontSizeList = new JComboBox(resources.getString("ConfigurationPanel.fontSizes").split(","));
82      fontSizeList.setSelectedIndex(getFontPreferenceIndex());
83      fontSizeList.setRenderer(new ComboBoxRenderer());
84  
85      addActionListeners();
86  
87      add(backgroundColorButton);
88      add(foregroundColorButton);
89      add(defaultColorButton);
90      add(unitSeparatorLabel);
91      add(unitSeparatorList);
92      add(fontSizeLabel);
93      add(fontSizeList);
94    }
95  
96    private void addActionListeners()
97    {
98      backgroundColorButton.addActionListener(this);
99      foregroundColorButton.addActionListener(this);
100     defaultColorButton.addActionListener(this);
101     unitSeparatorList.addActionListener(this);
102     fontSizeList.addActionListener(this);
103   }
104 
105   private int getSeparatorPreferenceIndex()
106   {
107     final String unitSeparator = logicController.getUnitSeparatorPreference();
108     modelController.setUnitSeparator(unitSeparator.replaceAll("\"", ""));
109     return logicController.getPreferenceIndex(unitSeparatorList.getModel(), unitSeparator);
110   }
111 
112   private int getFontPreferenceIndex()
113   {
114     final int fontSize = logicController.getFontSizePreference(getFont().getSize());
115     return logicController.getPreferenceIndex(fontSizeList.getModel(), fontSize);
116   }
117 
118   private class ColorIcon implements Icon
119   {
120     private String property;
121 
122     public ColorIcon(final String prop)
123     {
124       property = prop;
125     }
126 
127     @Override
128     public int getIconHeight()
129     {
130       return iconWidthHeight;
131     }
132 
133     @Override
134     public int getIconWidth()
135     {
136       return iconWidthHeight;
137     }
138 
139     @Override
140     public void paintIcon(final Component component, final Graphics graphic, final int x, final int y)
141     {
142       graphic.setColor(Color.black);
143       graphic.fillRect(x, y, getIconWidth(), getIconHeight());
144       if (property.equals(backgroundColorButton.getText()))
145       {
146         graphic.setColor(mainPanel.getContentPane().getBackground());
147       }
148       else if (property.equals(foregroundColorButton.getText()))
149       {
150         graphic.setColor(mainPanel.getContentPane().getForeground());
151       }
152       graphic.fillRect(x + 1, y + 1, getIconWidth() - 2, getIconHeight() - 2);
153     }
154   }
155 
156   @Override
157   public final void setBackgroundColor(final Color color)
158   {
159     setBackground(color);
160     final Component[] children = getComponents();
161     for (Component child : children)
162     {
163       if (child instanceof JComboBox)
164       {
165         final JComboBox box = (JComboBox) child;
166         final Color buttonColor = box.getComponent(0).getBackground();
167         box.setBackground(color);
168         box.getComponent(0).setBackground(buttonColor);
169       }
170     }
171   }
172 
173   @Override
174   public final void setForegroundColor(final Color color)
175   {
176     setForeground(color);
177     final Component[] children = getComponents();
178     for (Component child : children)
179     {
180       if (child != defaultColorButton)
181       {
182         child.setForeground(color);
183       }
184     }
185   }
186 
187   @Override
188   public final void actionPerformed(final ActionEvent event)
189   {
190     if (event.getSource() == fontSizeList)
191     {
192       final JComboBox list = (JComboBox) event.getSource();
193       final String fontSize = (String) list.getSelectedItem();
194       mainPanel.setFontSize(Float.parseFloat(fontSize));
195     }
196     else if (event.getSource() == unitSeparatorList)
197     {
198       final JComboBox list = (JComboBox) event.getSource();
199       final String value = (String) list.getSelectedItem();
200       modelController.setUnitSeparator(value.replaceAll("\"", ""));
201       logicController.setUnitSeparatorPreference(value);
202     }
203     else if (event.getSource() == defaultColorButton)
204     {
205       resetColors();
206     }
207     else
208     {
209       Color current = mainPanel.getContentPane().getBackground();
210       if (event.getSource() == foregroundColorButton)
211       {
212         current = mainPanel.getContentPane().getForeground();
213       }
214 
215       final JColorChooser chooser = new JColorChooser(current != null ? current : Color.WHITE);
216       chooser.setDragEnabled(true);
217 
218       chosen = null;
219       final ActionListener okListener = new ActionListener()
220       {
221         public void actionPerformed(final ActionEvent ae)
222         {
223           chosen = chooser.getColor();
224         }
225       };
226 
227       final JDialog dialog = JColorChooser.createDialog(getParent(), resources
228           .getString("ConfigurationPanel.dialogTitle"), true, chooser, okListener, null);
229       dialog.setVisible(true);
230 
231       if (event.getSource() == backgroundColorButton && chosen != null)
232       {
233         mainPanel.setBackgroundColor(chosen);
234       }
235       else if (event.getSource() == foregroundColorButton && chosen != null)
236       {
237         mainPanel.setForegroundColor(chosen);
238       }
239     }
240   }
241 
242   private void resetColors()
243   {
244     mainPanel.setBackgroundColor(new Color(238, 238, 238));
245     mainPanel.setForegroundColor(new Color(51, 51, 51));
246   }
247 
248   @Override
249   public final void setFontSize(final float fontSize)
250   {
251     final Font font = getFont().deriveFont(fontSize);
252     setFont(font);
253     final Component[] children = getComponents();
254     for (Component child : children)
255     {
256       child.setFont(font);
257     }
258   }
259 
260   private class ComboBoxRenderer extends JLabel implements ListCellRenderer
261   {
262     public ComboBoxRenderer()
263     {
264       setOpaque(true);
265     }
266 
267     @Override
268     public Component getListCellRendererComponent(final JList list, final Object value, final int index,
269         final boolean isSelected, final boolean cellHasFocus)
270     {
271       setText(value.toString());
272 
273       if (isSelected)
274       {
275         setBackground(ConfigurationPanel.this.getBackground().brighter());
276       }
277       else
278       {
279         setBackground(ConfigurationPanel.this.getBackground());
280       }
281       return this;
282     }
283   }
284 }