KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > util > gui > resource > MenuFactory


1 /*
2
3    Copyright 2000-2001,2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.util.gui.resource;
19
20 import java.awt.Event JavaDoc;
21 import java.awt.event.KeyEvent JavaDoc;
22 import java.net.URL JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.MissingResourceException JavaDoc;
26 import java.util.ResourceBundle JavaDoc;
27
28 import javax.swing.AbstractButton JavaDoc;
29 import javax.swing.Action JavaDoc;
30 import javax.swing.ButtonGroup JavaDoc;
31 import javax.swing.ImageIcon JavaDoc;
32 import javax.swing.JCheckBoxMenuItem JavaDoc;
33 import javax.swing.JComponent JavaDoc;
34 import javax.swing.JMenu JavaDoc;
35 import javax.swing.JMenuBar JavaDoc;
36 import javax.swing.JMenuItem JavaDoc;
37 import javax.swing.JRadioButtonMenuItem JavaDoc;
38 import javax.swing.JSeparator JavaDoc;
39 import javax.swing.KeyStroke JavaDoc;
40
41 /**
42  * This class represents a menu factory which builds
43  * menubars and menus from the content of a resource file. <br>
44  *
45  * The resource entries format is (for a menubar named 'MenuBar'):<br>
46  * <pre>
47  * MenuBar = Menu1 Menu2 ...
48  *
49  * Menu1.type = RADIO | CHECK | MENU | ITEM
50  * Menu1 = Item1 Item2 - Item3 ...
51  * Menu1.text = text
52  * Menu1.icon = icon_name
53  * Menu1.mnemonic = mnemonic
54  * Menu1.accelerator = accelerator
55  * Menu1.action = action_name
56  * Menu1.selected = true | false
57  * Menu1.enabled = true | false
58  * ...
59  * mnemonic is a single character
60  * accelerator is of the form: mod+mod+...+X
61  * where mod is Shift, Meta, Alt or Ctrl
62  * '-' represents a separator
63  * </pre>
64  * All entries are optional except the '.type' entry
65  * Consecutive RADIO items are put in a ButtonGroup
66  *
67  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
68  * @version $Id: MenuFactory.java,v 1.8 2005/03/27 08:58:37 cam Exp $
69  */

70 public class MenuFactory extends ResourceManager {
71     // Constants
72
//
73
private final static String JavaDoc TYPE_MENU = "MENU";
74     private final static String JavaDoc TYPE_ITEM = "ITEM";
75     private final static String JavaDoc TYPE_RADIO = "RADIO";
76     private final static String JavaDoc TYPE_CHECK = "CHECK";
77     private final static String JavaDoc SEPARATOR = "-";
78
79     private final static String JavaDoc TYPE_SUFFIX = ".type";
80     private final static String JavaDoc TEXT_SUFFIX = ".text";
81     private final static String JavaDoc MNEMONIC_SUFFIX = ".mnemonic";
82     private final static String JavaDoc ACCELERATOR_SUFFIX = ".accelerator";
83     private final static String JavaDoc ACTION_SUFFIX = ".action";
84     private final static String JavaDoc SELECTED_SUFFIX = ".selected";
85     private final static String JavaDoc ENABLED_SUFFIX = ".enabled";
86     private final static String JavaDoc ICON_SUFFIX = ".icon";
87
88     /**
89      * The table which contains the actions
90      */

91     private ActionMap actions;
92
93     /**
94      * The current radio group
95      */

96     private ButtonGroup JavaDoc buttonGroup;
97
98     /**
99      * Creates a new menu factory
100      * @param rb the resource bundle that contains the menu bar
101      * description.
102      * @param am the actions to add to menu items
103      */

104     public MenuFactory(ResourceBundle JavaDoc rb, ActionMap am) {
105         super(rb);
106         actions = am;
107     buttonGroup = null;
108     }
109
110     /**
111      * Creates and returns a swing menu bar
112      * @param name the name of the menu bar in the resource bundle
113      * @throws MissingResourceException if one of the keys that compose the
114      * menu is missing.
115      * It is not thrown if the mnemonic, the accelerator and the
116      * action keys are missing
117      * @throws ResourceFormatException if the mnemonic is not a single
118      * character and if the accelerator is malformed
119      * @throws MissingListenerException if an item action is not found in the
120      * action map
121      */

122     public JMenuBar JavaDoc createJMenuBar(String JavaDoc name)
123     throws MissingResourceException JavaDoc,
124                ResourceFormatException,
125            MissingListenerException {
126         JMenuBar JavaDoc result = new JMenuBar JavaDoc();
127         List JavaDoc menus = getStringList(name);
128         Iterator JavaDoc it = menus.iterator();
129
130         while (it.hasNext()) {
131             result.add(createJMenuComponent((String JavaDoc)it.next()));
132         }
133         return result;
134     }
135
136     /**
137      * Creates and returns a menu item or a separator
138      * @param name the name of the menu item or "-" to create a separator
139      * @throws MissingResourceException if key is not the name of a menu item.
140      * It is not thrown if the mnemonic, the accelerator and the
141      * action keys are missing
142      * @throws ResourceFormatException in case of malformed entry
143      * @throws MissingListenerException if an item action is not found in the
144      * action map
145      */

146     protected JComponent JavaDoc createJMenuComponent(String JavaDoc name)
147     throws MissingResourceException JavaDoc,
148            ResourceFormatException,
149            MissingListenerException {
150     if (name.equals(SEPARATOR)) {
151         buttonGroup = null;
152         return new JSeparator JavaDoc();
153     }
154         String JavaDoc type = getString(name+TYPE_SUFFIX);
155         JComponent JavaDoc item = null;
156
157     if (type.equals(TYPE_RADIO)) {
158         if (buttonGroup == null) {
159         buttonGroup = new ButtonGroup JavaDoc();
160         }
161     } else {
162         buttonGroup = null;
163     }
164
165         if (type.equals(TYPE_MENU)) {
166             item = createJMenu(name);
167         } else if (type.equals(TYPE_ITEM)) {
168             item = createJMenuItem(name);
169         } else if (type.equals(TYPE_RADIO)) {
170             item = createJRadioButtonMenuItem(name);
171         buttonGroup.add((AbstractButton JavaDoc)item);
172         } else if (type.equals(TYPE_CHECK)) {
173             item = createJCheckBoxMenuItem(name);
174         } else {
175         throw new ResourceFormatException("Malformed resource",
176                           bundle.getClass().getName(),
177                           name+TYPE_SUFFIX);
178     }
179     
180         return item;
181     }
182
183     /**
184      * Creates and returns a new swing menu
185      * @param name the name of the menu bar in the resource bundle
186      * @throws MissingResourceException if one of the keys that compose the
187      * menu is missing.
188      * It is not thrown if the mnemonic, the accelerator and the
189      * action keys are missing
190      * @throws ResourceFormatException if the mnemonic is not a single
191      * character.
192      * @throws MissingListenerException if a item action is not found in the
193      * action map.
194      */

195     public JMenu JavaDoc createJMenu(String JavaDoc name)
196     throws MissingResourceException JavaDoc,
197            ResourceFormatException,
198            MissingListenerException {
199         JMenu JavaDoc result = new JMenu JavaDoc(getString(name+TEXT_SUFFIX));
200         initializeJMenuItem(result, name);
201
202         List JavaDoc items = getStringList(name);
203         Iterator JavaDoc it = items.iterator();
204
205         while (it.hasNext()) {
206             result.add(createJMenuComponent((String JavaDoc)it.next()));
207         }
208         return result;
209     }
210
211     /**
212      * Creates and returns a new swing menu item
213      * @param name the name of the menu item
214      * @throws MissingResourceException if one of the keys that compose the
215      * menu item is missing.
216      * It is not thrown if the mnemonic, the accelerator and the
217      * action keys are missing
218      * @throws ResourceFormatException if the mnemonic is not a single
219      * character.
220      * @throws MissingListenerException if then item action is not found in
221      * the action map.
222      */

223     public JMenuItem JavaDoc createJMenuItem(String JavaDoc name)
224     throws MissingResourceException JavaDoc,
225            ResourceFormatException,
226            MissingListenerException {
227         JMenuItem JavaDoc result = new JMenuItem JavaDoc(getString(name+TEXT_SUFFIX));
228         initializeJMenuItem(result, name);
229         return result;
230     }
231
232     /**
233      * Creates and returns a new swing radio button menu item
234      * @param name the name of the menu item
235      * @throws MissingResourceException if one of the keys that compose the
236      * menu item is missing.
237      * It is not thrown if the mnemonic, the accelerator and the
238      * action keys are missing
239      * @throws ResourceFormatException if the mnemonic is not a single
240      * character.
241      * @throws MissingListenerException if then item action is not found in
242      * the action map.
243      */

244     public JRadioButtonMenuItem JavaDoc createJRadioButtonMenuItem(String JavaDoc name)
245     throws MissingResourceException JavaDoc,
246            ResourceFormatException,
247            MissingListenerException {
248         JRadioButtonMenuItem JavaDoc result;
249     result = new JRadioButtonMenuItem JavaDoc(getString(name+TEXT_SUFFIX));
250         initializeJMenuItem(result, name);
251
252         // is the item selected?
253
try {
254         result.setSelected(getBoolean(name+SELECTED_SUFFIX));
255     } catch (MissingResourceException JavaDoc e) {
256     }
257     
258         return result;
259     }
260
261     /**
262      * Creates and returns a new swing check box menu item
263      * @param name the name of the menu item
264      * @throws MissingResourceException if one of the keys that compose the
265      * menu item is missing.
266      * It is not thrown if the mnemonic, the accelerator and the
267      * action keys are missing
268      * @throws ResourceFormatException if the mnemonic is not a single
269      * character.
270      * @throws MissingListenerException if then item action is not found in
271      * the action map.
272      */

273     public JCheckBoxMenuItem JavaDoc createJCheckBoxMenuItem(String JavaDoc name)
274     throws MissingResourceException JavaDoc,
275            ResourceFormatException,
276            MissingListenerException {
277         JCheckBoxMenuItem JavaDoc result;
278         result = new JCheckBoxMenuItem JavaDoc(getString(name+TEXT_SUFFIX));
279         initializeJMenuItem(result, name);
280
281         // is the item selected?
282
try {
283         result.setSelected(getBoolean(name+SELECTED_SUFFIX));
284     } catch (MissingResourceException JavaDoc e) {
285     }
286     
287         return result;
288     }
289
290     /**
291      * Initializes a swing menu item
292      * @param item the menu item to initialize
293      * @param name the name of the menu item
294      * @throws ResourceFormatException if the mnemonic is not a single
295      * character.
296      * @throws MissingListenerException if then item action is not found in
297      * the action map.
298      */

299     protected void initializeJMenuItem(JMenuItem JavaDoc item, String JavaDoc name)
300     throws ResourceFormatException,
301            MissingListenerException {
302         // Action
303
try {
304         Action JavaDoc a = actions.getAction(getString(name+ACTION_SUFFIX));
305         if (a == null) {
306         throw new MissingListenerException("", "Action",
307                                                    name+ACTION_SUFFIX);
308         }
309         item.setAction(a);
310             item.setText(getString(name+TEXT_SUFFIX));
311         if (a instanceof JComponentModifier) {
312         ((JComponentModifier)a).addJComponent(item);
313         }
314     } catch (MissingResourceException JavaDoc e) {
315     }
316
317     // Icon
318
try {
319         String JavaDoc s = getString(name+ICON_SUFFIX);
320         URL JavaDoc url = actions.getClass().getResource(s);
321         if (url != null) {
322         item.setIcon(new ImageIcon JavaDoc(url));
323         }
324     } catch (MissingResourceException JavaDoc e) {
325     }
326
327         // Mnemonic
328
try {
329         String JavaDoc str = getString(name+MNEMONIC_SUFFIX);
330         if (str.length() == 1) {
331         item.setMnemonic(str.charAt(0));
332         } else {
333         throw new ResourceFormatException("Malformed mnemonic",
334                           bundle.getClass().getName(),
335                           name+MNEMONIC_SUFFIX);
336         }
337     } catch (MissingResourceException JavaDoc e) {
338     }
339
340         // Accelerator
341
try {
342         if (!(item instanceof JMenu JavaDoc)) {
343         String JavaDoc str = getString(name+ACCELERATOR_SUFFIX);
344         KeyStroke JavaDoc ks = toKeyStroke(str);
345         if (ks != null) {
346             item.setAccelerator(ks);
347         } else {
348             throw new ResourceFormatException
349                         ("Malformed accelerator",
350                          bundle.getClass().getName(),
351                          name+ACCELERATOR_SUFFIX);
352         }
353         }
354     } catch (MissingResourceException JavaDoc e) {
355     }
356
357         // is the item enabled?
358
try {
359         item.setEnabled(getBoolean(name+ENABLED_SUFFIX));
360     } catch (MissingResourceException JavaDoc e) {
361     }
362     }
363
364     /**
365      * Translate a string into a key stroke.
366      * See the class comment for details
367      * @param str a string
368      */

369     protected KeyStroke JavaDoc toKeyStroke(String JavaDoc str) {
370         int state = 0;
371         int code = 0;
372         int modif = 0;
373         int i = 0;
374
375         while (state != 100 && i < str.length()) {
376             char curr = Character.toUpperCase(str.charAt(i));
377             
378             switch (state) {
379             case 0 :
380                 code = curr;
381                 switch (curr) {
382                 case 'C': state = 1; break;
383                 case 'A': state = 5; break;
384                 case 'M': state = 8; break;
385                 case 'S': state = 12; break;
386                 default:
387                     state = 100;
388                 }
389                 break;
390
391             case 1 : state = (curr == 'T') ? 2 : 100; break;
392             case 2 : state = (curr == 'R') ? 3 : 100; break;
393             case 3 : state = (curr == 'L') ? 4 : 100; break;
394             case 4 : state = (curr == '+') ? 0 : 100;
395                 if (state == 0) {
396                     modif |= Event.CTRL_MASK;
397                 }
398                 break;
399             case 5 : state = (curr == 'L') ? 6 : 100; break;
400             case 6 : state = (curr == 'T') ? 7 : 100; break;
401             case 7 : state = (curr == '+') ? 0 : 100;
402                 if (state == 0) {
403                     modif |= Event.ALT_MASK;
404                 }
405                 break;
406             case 8 : state = (curr == 'E') ? 9 : 100; break;
407             case 9 : state = (curr == 'T') ? 10: 100; break;
408             case 10: state = (curr == 'A') ? 11: 100; break;
409             case 11: state = (curr == '+') ? 0 : 100;
410                 if (state == 0) {
411                     modif |= Event.META_MASK;
412                 }
413                 break;
414             case 12: state = (curr == 'H') ? 13: 100; break;
415             case 13: state = (curr == 'I') ? 14: 100; break;
416             case 14: state = (curr == 'F') ? 15: 100; break;
417             case 15: state = (curr == 'T') ? 16: 100; break;
418             case 16: state = (curr == '+') ? 0 : 100;
419                 if (state == 0) {
420                     modif |= Event.SHIFT_MASK;
421                 }
422                 break;
423             }
424             i++;
425         }
426         if (code > 0 && modif > 0) {
427             if (i < str.length()) {
428                 char curr = Character.toUpperCase(str.charAt(i));
429                 switch (code) {
430                 case 'U':
431                     if (str.length() - i != 1 || curr != 'P') {
432                         break;
433                     }
434                     code = KeyEvent.VK_UP;
435                     break;
436                 case 'L':
437                     if (str.length() - i != 3 ||
438                         curr != 'E' ||
439                         Character.toUpperCase(str.charAt(i + 1)) != 'F' ||
440                         Character.toUpperCase(str.charAt(i + 2)) != 'T') {
441                         break;
442                     }
443                     code = KeyEvent.VK_LEFT;
444                     break;
445                 case 'D':
446                     if (str.length() - i != 3 ||
447                         curr != 'O' ||
448                         Character.toUpperCase(str.charAt(i + 1)) != 'W' ||
449                         Character.toUpperCase(str.charAt(i + 2)) != 'N') {
450                         break;
451                     }
452                     code = KeyEvent.VK_DOWN;
453                     break;
454                 case 'R':
455                     if (str.length() - i != 4 ||
456                         curr != 'I' ||
457                         Character.toUpperCase(str.charAt(i + 1)) != 'G' ||
458                         Character.toUpperCase(str.charAt(i + 2)) != 'H' ||
459                         Character.toUpperCase(str.charAt(i + 3)) != 'T') {
460                         break;
461                     }
462                     code = KeyEvent.VK_RIGHT;
463                 }
464             }
465             return KeyStroke.getKeyStroke(code, modif);
466         }
467         return null;
468     }
469 }
470
Popular Tags