View Javadoc

1   /*
2    * Copyright 2006-2016 The JGUIraffe Team.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License")
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sf.jguiraffe.gui.platform.swing.builder.components;
17  
18  import java.util.Enumeration;
19  
20  import javax.swing.AbstractButton;
21  import javax.swing.ButtonGroup;
22  
23  import net.sf.jguiraffe.gui.builder.components.Color;
24  import net.sf.jguiraffe.gui.builder.components.WidgetHandler;
25  
26  import org.apache.commons.lang.ObjectUtils;
27  
28  /**
29   * <p>
30   * A specialized {@link WidgetHandler} implementation for Swing radio groups.
31   * </p>
32   * <p>
33   * A radio group in Swing is somewhat special. It is not a graphical component
34   * on its own, but it merely refers to the actual radio button components.
35   * However, in the <em>JGUIraffe</em> library radio groups are more or less
36   * treated like regular components, and their properties can be accessed through
37   * the {@link WidgetHandler} interface.
38   * </p>
39   * <p>
40   * Because of this a special implementation is needed for radio buttons. This
41   * implementations acts like a typical composite. Set operations are delegated
42   * to all components in the group. For get operations there are some
43   * limitations: Unless noted otherwise for a specific operation, the group widget
44   * handler expects that all radio buttons in the group share the same properties
45   * (e.g. colors or visible state). Therefore it simply returns the corresponding
46   * property of the first button in the group.
47   * </p>
48   * <p>
49   * Implementation notes: This class is not thread-safe. It should be accessed
50   * from the <em>event dispatch thread</em> only. The {@code ButtonGroup} must
51   * not be changed after it was passed to the constructor.
52   * </p>
53   *
54   * @author Oliver Heger
55   * @version $Id: SwingRadioGroupWidgetHandler.java 205 2012-01-29 18:29:57Z oheger $
56   */
57  class SwingRadioGroupWidgetHandler implements WidgetHandler
58  {
59      /** Constant for the tool tip separator. */
60      private static final String TIP_SEPARATOR = "\n";
61  
62      /** Stores the underlying button group. */
63      private final ButtonGroup buttonGroup;
64  
65      /** An array for easy access to the buttons in the group. */
66      private final AbstractButton[] buttons;
67  
68      /** An array with the original tool tips of the radio buttons. */
69      private final String[] buttonTips;
70  
71      /** The tool tip of the whole radio group. */
72      private String groupTip;
73  
74      /**
75       * Creates a new instance of {@code SwingRadioGroupWidgetHandler} and
76       * initializes it with the underlying {@code ButtonGroup}.
77       *
78       * @param group the {@code ButtonGroup}
79       */
80      public SwingRadioGroupWidgetHandler(ButtonGroup group)
81      {
82          assert group != null : "Null ButtonGroup passed in!";
83          buttonGroup = group;
84  
85          buttons = new AbstractButton[group.getButtonCount()];
86          int idx = 0;
87          for (Enumeration<AbstractButton> en = group.getElements(); en
88                  .hasMoreElements();)
89          {
90              buttons[idx++] = en.nextElement();
91          }
92          assert buttons.length > 0 : "Group is empty!";
93  
94          buttonTips = new String[buttons.length];
95      }
96  
97      /**
98       * Returns a reference to the underlying {@code ButtonGroup} object.
99       *
100      * @return the {@code ButtonGroup}
101      */
102     public ButtonGroup getButtonGroup()
103     {
104         return buttonGroup;
105     }
106 
107     /**
108      * Returns the background color of this radio button group. This
109      * implementation assumes that all radio buttons in the group have the same
110      * color. So it returns the color of the first radio button.
111      *
112      * @return the background color of this radio button group
113      */
114     public Color getBackgroundColor()
115     {
116         return SwingComponentUtils.getBackgroundColor(buttons[0]);
117     }
118 
119     /**
120      * Returns the foreground color of this radio button group. This
121      * implementation assumes that all radio buttons in the group have the same
122      * color. So it returns the color of the first radio button.
123      *
124      * @return the foreground color of this radio button group
125      */
126     public Color getForegroundColor()
127     {
128         return SwingComponentUtils.getForegroundColor(buttons[0]);
129     }
130 
131     /**
132      * Returns the tool tip of this radio group. The tool tip for the whole
133      * group is independent of the tips of single radio buttons. So this
134      * implementation just returns the string that was set using
135      * {@link #setToolTip(String)}.
136      *
137      * @return the tool tip of this radio group
138      */
139     public String getToolTip()
140     {
141         return groupTip;
142     }
143 
144     /**
145      * Returns the widget wrapped by this handler. This implementation returns
146      * the underlying {@code ButtonGroup} object, which is not a real graphical
147      * widget.
148      *
149      * @return the wrapped widget
150      */
151     public Object getWidget()
152     {
153         return getButtonGroup();
154     }
155 
156     /**
157      * Returns the visible state of this radio group. This implementation
158      * expects that all buttons in the group have the same visible state. So
159      * only the first button is checked.
160      *
161      * @return the visible state of this group
162      */
163     public boolean isVisible()
164     {
165         return buttons[0].isVisible();
166     }
167 
168     /**
169      * Sets the background color of this radio button group. This implementation
170      * passes the color to all radio buttons in the group. If the color is
171      * <b>null</b>, this method has no effect.
172      *
173      * @param c the new background color
174      */
175     public void setBackgroundColor(Color c)
176     {
177         if (c != null)
178         {
179             for (AbstractButton b : buttons)
180             {
181                 SwingComponentUtils.setBackgroundColor(b, c);
182             }
183         }
184     }
185 
186     /**
187      * Sets the foreground color of this radio button group. This implementation
188      * passes the color to all radio buttons in the group. If the color is
189      * <b>null</b>, this method has no effect.
190      *
191      * @param c the new foreground color
192      */
193     public void setForegroundColor(Color c)
194     {
195         if (c != null)
196         {
197             for (AbstractButton b : buttons)
198             {
199                 SwingComponentUtils.setForegroundColor(b, c);
200             }
201         }
202     }
203 
204     /**
205      * Sets the tool tip of this radio group. This implementation sets the
206      * overall tool tip, and it changes the tool tips of the radio buttons that
207      * belong to this group. The tool tips of the radio buttons are generated by
208      * their original tool tip, a separator, plus the group's tool tip.
209      *
210      * @param tip the new tool tip for the whole group
211      */
212     public void setToolTip(String tip)
213     {
214         for (int i = 0; i < buttons.length; i++)
215         {
216             String expectedTip = SwingComponentUtils.combineToolTips(
217                     buttonTips[i], groupTip, TIP_SEPARATOR);
218             String currentTip = SwingComponentUtils.getToolTip(buttons[i]);
219             if (!ObjectUtils.equals(expectedTip, currentTip))
220             {
221                 // the tip of the button has changed in the mean time
222                 buttonTips[i] = currentTip;
223             }
224 
225             SwingComponentUtils.setToolTip(buttons[i], buttonTips[i], tip,
226                     TIP_SEPARATOR);
227         }
228 
229         groupTip = tip;
230     }
231 
232     /**
233      * Sets the visible state of this radio group. This implementation sets the
234      * visible state for all radio buttons in the group.
235      *
236      * @param f the new visible state
237      */
238     public void setVisible(boolean f)
239     {
240         for (AbstractButton b : buttons)
241         {
242             b.setVisible(f);
243         }
244     }
245 
246     /**
247      * Returns the font of this radio group. This implementation returns the
248      * font of the first button.
249      *
250      * @return the font of this widget
251      */
252     public Object getFont()
253     {
254         return SwingComponentUtils.getFont(buttons[0]);
255     }
256 
257     /**
258      * Sets the font for this radio group. This implementation sets the font for
259      * all buttons in the group.
260      *
261      * @param font the font to be set
262      */
263     public void setFont(Object font)
264     {
265         for (AbstractButton b : buttons)
266         {
267             SwingComponentUtils.setFont(b, font);
268         }
269     }
270 }