KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > resource > FontRegistry


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.resource;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.Enumeration JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.MissingResourceException JavaDoc;
22 import java.util.ResourceBundle JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.eclipse.core.runtime.Assert;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.graphics.Font;
28 import org.eclipse.swt.graphics.FontData;
29 import org.eclipse.swt.widgets.Display;
30 import org.eclipse.swt.widgets.Shell;
31
32 /**
33  * A font registry maintains a mapping between symbolic font names
34  * and SWT fonts.
35  * <p>
36  * A font registry owns all of the font objects registered
37  * with it, and automatically disposes of them when the SWT Display
38  * that creates the fonts is disposed. Because of this, clients do
39  * not need to (indeed, must not attempt to) dispose of font
40  * objects themselves.
41  * </p>
42  * <p>
43  * A special constructor is provided for populating a font registry
44  * from a property files using the standard Java resource bundle mechanism.
45  * </p>
46  * <p>
47  * Methods are provided for registering listeners that will be kept
48  * apprised of changes to list of registed fonts.
49  * </p>
50  * <p>
51  * Clients may instantiate this class (it was not designed to be subclassed).
52  * </p>
53  *
54  * Since 3.0 this class extends ResourceRegistry.
55  */

56 public class FontRegistry extends ResourceRegistry {
57
58     /**
59      * FontRecord is a private helper class that holds onto a font
60      * and can be used to generate its bold and italic version.
61      */

62     private class FontRecord {
63
64         Font baseFont;
65
66         Font boldFont;
67
68         Font italicFont;
69
70         FontData[] baseData;
71
72         /**
73          * Create a new instance of the receiver based on the
74          * plain font and the data for it.
75          * @param plainFont The base looked up font.
76          * @param data The data used to look it up.
77          */

78         FontRecord(Font plainFont, FontData[] data) {
79             baseFont = plainFont;
80             baseData = data;
81         }
82
83         /**
84          * Dispose any of the fonts created for this record.
85          */

86         void dispose() {
87             baseFont.dispose();
88             if (boldFont != null) {
89                 boldFont.dispose();
90             }
91             if (italicFont != null) {
92                 italicFont.dispose();
93             }
94         }
95
96         /**
97          * Return the base Font.
98          * @return Font
99          */

100         public Font getBaseFont() {
101             return baseFont;
102         }
103
104         /**
105          * Return the bold Font. Create a bold version
106          * of the base font to get it.
107          * @return Font
108          */

109         public Font getBoldFont() {
110             if (boldFont != null) {
111                 return boldFont;
112             }
113
114             FontData[] boldData = getModifiedFontData(SWT.BOLD);
115             boldFont = new Font(Display.getCurrent(), boldData);
116             return boldFont;
117         }
118
119         /**
120          * Get a version of the base font data with the specified
121          * style.
122          * @param style the new style
123          * @return the font data with the style {@link FontData#FontData(String, int, int)}
124          * @see SWT#ITALIC
125          * @see SWT#NORMAL
126          * @see SWT#BOLD
127          * @todo Generated comment
128          */

129         private FontData[] getModifiedFontData(int style) {
130             FontData[] styleData = new FontData[baseData.length];
131             for (int i = 0; i < styleData.length; i++) {
132                 FontData base = baseData[i];
133                 styleData[i] = new FontData(base.getName(), base.getHeight(),
134                         base.getStyle() | style);
135             }
136
137             return styleData;
138         }
139
140         /**
141          * Return the italic Font. Create an italic version of the
142          * base font to get it.
143          * @return Font
144          */

145         public Font getItalicFont() {
146             if (italicFont != null) {
147                 return italicFont;
148             }
149
150             FontData[] italicData = getModifiedFontData(SWT.ITALIC);
151             italicFont = new Font(Display.getCurrent(), italicData);
152             return italicFont;
153         }
154
155         /**
156          * Add any fonts that were allocated for this record to the
157          * stale fonts. Anything that matches the default font will
158          * be skipped.
159          * @param defaultFont The system default.
160          */

161         void addAllocatedFontsToStale(Font defaultFont) {
162             //Return all of the fonts allocated by the receiver.
163
//if any of them are the defaultFont then don't bother.
164
if (defaultFont != baseFont && baseFont != null) {
165                 staleFonts.add(baseFont);
166             }
167             if (defaultFont != boldFont && boldFont != null) {
168                 staleFonts.add(boldFont);
169             }
170             if (defaultFont != italicFont && italicFont != null) {
171                 staleFonts.add(italicFont);
172             }
173         }
174     }
175
176     /**
177      * Table of known fonts, keyed by symbolic font name
178      * (key type: <code>String</code>,
179      * value type: <code>FontRecord</code>.
180      */

181     private Map JavaDoc stringToFontRecord = new HashMap JavaDoc(7);
182
183     /**
184      * Table of known font data, keyed by symbolic font name
185      * (key type: <code>String</code>,
186      * value type: <code>org.eclipse.swt.graphics.FontData[]</code>).
187      */

188     private Map JavaDoc stringToFontData = new HashMap JavaDoc(7);
189
190     /**
191      * Collection of Fonts that are now stale to be disposed
192      * when it is safe to do so (i.e. on shutdown).
193      * @see List
194      */

195     private List JavaDoc staleFonts = new ArrayList JavaDoc();
196
197     /**
198      * Runnable that cleans up the manager on disposal of the display.
199      */

200     protected Runnable JavaDoc displayRunnable = new Runnable JavaDoc() {
201         public void run() {
202             clearCaches();
203         }
204     };
205
206     /**
207      * Creates an empty font registry.
208      * <p>
209      * There must be an SWT Display created in the current
210      * thread before calling this method.
211      * </p>
212      */

213     public FontRegistry() {
214         this(Display.getCurrent(), true);
215     }
216
217     /**
218      * Creates a font registry and initializes its content from
219      * a property file.
220      * <p>
221      * There must be an SWT Display created in the current
222      * thread before calling this method.
223      * </p>
224      * <p>
225      * The OS name (retrieved using <code>System.getProperty("os.name")</code>)
226      * is converted to lowercase, purged of whitespace, and appended
227      * as suffix (separated by an underscore <code>'_'</code>) to the given
228      * location string to yield the base name of a resource bundle
229      * acceptable to <code>ResourceBundle.getBundle</code>.
230      * The standard Java resource bundle mechanism is then used to locate
231      * and open the appropriate properties file, taking into account
232      * locale specific variations.
233      * </p>
234      * <p>
235      * For example, on the Windows 2000 operating system the location string
236      * <code>"com.example.myapp.Fonts"</code> yields the base name
237      * <code>"com.example.myapp.Fonts_windows2000"</code>. For the US English locale,
238      * this further elaborates to the resource bundle name
239      * <code>"com.example.myapp.Fonts_windows2000_en_us"</code>.
240      * </p>
241      * <p>
242      * If no appropriate OS-specific resource bundle is found, the
243      * process is repeated using the location as the base bundle name.
244      * </p>
245      * <p>
246      * The property file contains entries that look like this:
247      * <pre>
248      * textfont.0=MS Sans Serif-regular-10
249      * textfont.1=Times New Roman-regular-10
250      *
251      * titlefont.0=MS Sans Serif-regular-12
252      * titlefont.1=Times New Roman-regular-12
253      * </pre>
254      * Each entry maps a symbolic font names (the font registry keys) with
255      * a "<code>.<it>n</it></code> suffix to standard font names
256      * on the right. The suffix indicated order of preference:
257      * "<code>.0</code>" indicates the first choice,
258      * "<code>.1</code>" indicates the second choice, and so on.
259      * </p>
260      * The following example shows how to use the font registry:
261      * <pre>
262      * FontRegistry registry = new FontRegistry("com.example.myapp.fonts");
263      * Font font = registry.get("textfont");
264      * control.setFont(font);
265      * ...
266      * </pre>
267      *
268      * @param location the name of the resource bundle
269      * @param loader the ClassLoader to use to find the resource bundle
270      * @exception MissingResourceException if the resource bundle cannot be found
271      * @since 2.1
272      */

273     public FontRegistry(String JavaDoc location, ClassLoader JavaDoc loader)
274             throws MissingResourceException JavaDoc {
275         Display display = Display.getCurrent();
276         Assert.isNotNull(display);
277         // FIXE: need to respect loader
278
//readResourceBundle(location, loader);
279
readResourceBundle(location);
280
281         hookDisplayDispose(display);
282     }
283
284     /**
285      * Load the FontRegistry using the ClassLoader from the PlatformUI
286      * plug-in
287      * @param location the location to read the resource bundle from
288      * @throws MissingResourceException Thrown if a resource is missing
289      */

290     public FontRegistry(String JavaDoc location) throws MissingResourceException JavaDoc {
291         // FIXE:
292
// this(location, WorkbenchPlugin.getDefault().getDescriptor().getPluginClassLoader());
293
this(location, null);
294     }
295
296     /**
297      * Read the resource bundle at location. Look for a file with the
298      * extension _os_ws first, then _os then just the name.
299      * @param location - String - the location of the file.
300      */

301
302     private void readResourceBundle(String JavaDoc location) {
303         String JavaDoc osname = System.getProperty("os.name").trim(); //$NON-NLS-1$
304
String JavaDoc wsname = SWT.getPlatform();
305         osname = StringConverter.removeWhiteSpaces(osname).toLowerCase();
306         wsname = StringConverter.removeWhiteSpaces(wsname).toLowerCase();
307         String JavaDoc OSLocation = location;
308         String JavaDoc WSLocation = location;
309         ResourceBundle JavaDoc bundle = null;
310         if (osname != null) {
311             OSLocation = location + "_" + osname; //$NON-NLS-1$
312
if (wsname != null) {
313                 WSLocation = OSLocation + "_" + wsname; //$NON-NLS-1$
314
}
315         }
316
317         try {
318             bundle = ResourceBundle.getBundle(WSLocation);
319             readResourceBundle(bundle, WSLocation);
320         } catch (MissingResourceException JavaDoc wsException) {
321             try {
322                 bundle = ResourceBundle.getBundle(OSLocation);
323                 readResourceBundle(bundle, WSLocation);
324             } catch (MissingResourceException JavaDoc osException) {
325                 if (location != OSLocation) {
326                     bundle = ResourceBundle.getBundle(location);
327                     readResourceBundle(bundle, WSLocation);
328                 } else {
329                     throw osException;
330                 }
331             }
332         }
333     }
334
335     /**
336      * Creates an empty font registry.
337      *
338      * @param display the Display
339      */

340     public FontRegistry(Display display) {
341         this(display, true);
342     }
343     
344     /**
345      * Creates an empty font registry.
346      *
347      * @param display
348      * the <code>Display</code>
349      * @param cleanOnDisplayDisposal
350      * whether all fonts allocated by this <code>FontRegistry</code>
351      * should be disposed when the display is disposed
352      * @since 3.1
353      */

354     public FontRegistry(Display display, boolean cleanOnDisplayDisposal) {
355         Assert.isNotNull(display);
356         if (cleanOnDisplayDisposal) {
357             hookDisplayDispose(display);
358         }
359     }
360
361     /**
362      * Find the first valid fontData in the provided list. If none are valid
363      * return the first one regardless. If the list is empty return null. Return
364      * <code>null</code> if one cannot be found.
365      *
366      * @param fonts the font list
367      * @param display the display used
368      * @return the font data of the like describe above
369      *
370      * @deprecated use bestDataArray in order to support Motif multiple entry
371      * fonts.
372      */

373     public FontData bestData(FontData[] fonts, Display display) {
374         for (int i = 0; i < fonts.length; i++) {
375             FontData fd = fonts[i];
376
377             if (fd == null) {
378                 break;
379             }
380
381             FontData[] fixedFonts = display.getFontList(fd.getName(), false);
382             if (isFixedFont(fixedFonts, fd)) {
383                 return fd;
384             }
385
386             FontData[] scalableFonts = display.getFontList(fd.getName(), true);
387             if (scalableFonts.length > 0) {
388                 return fd;
389             }
390         }
391
392         //None of the provided datas are valid. Return the
393
//first one as it is at least the first choice.
394
if (fonts.length > 0) {
395             return fonts[0];
396         }
397         
398         //Nothing specified
399
return null;
400     }
401
402     /**
403      * Find the first valid fontData in the provided list.
404      * If none are valid return the first one regardless.
405      * If the list is empty return <code>null</code>.
406      *
407      * @param fonts list of fonts
408      * @param display the display
409      * @return font data like described above
410      * @deprecated use filterData in order to preserve
411      * multiple entry fonts on Motif
412      */

413     public FontData[] bestDataArray(FontData[] fonts, Display display) {
414
415         FontData bestData = bestData(fonts, display);
416         if (bestData == null) {
417             return null;
418         }
419         
420         FontData[] datas = new FontData[1];
421         datas[0] = bestData;
422         return datas;
423     }
424     
425     /**
426      * Removes from the list all fonts that do not exist in this system.
427      * If none are valid, return the first irregardless. If the list is
428      * empty return <code>null</code>.
429      *
430      * @param fonts the fonts to check
431      * @param display the display to check against
432      * @return the list of fonts that have been found on this system
433      * @since 3.1
434      */

435     public FontData [] filterData(FontData [] fonts, Display display) {
436         ArrayList JavaDoc good = new ArrayList JavaDoc(fonts.length);
437         for (int i = 0; i < fonts.length; i++) {
438             FontData fd = fonts[i];
439
440             if (fd == null) {
441                 continue;
442             }
443
444             FontData[] fixedFonts = display.getFontList(fd.getName(), false);
445             if (isFixedFont(fixedFonts, fd)) {
446                 good.add(fd);
447             }
448
449             FontData[] scalableFonts = display.getFontList(fd.getName(), true);
450             if (scalableFonts.length > 0) {
451                 good.add(fd);
452             }
453         }
454
455         
456         //None of the provided datas are valid. Return the
457
//first one as it is at least the first choice.
458
if (good.isEmpty() && fonts.length > 0) {
459             good.add(fonts[0]);
460         }
461         else if (fonts.length == 0) {
462             return null;
463         }
464         
465         return (FontData[]) good.toArray(new FontData[good.size()]);
466     }
467     
468
469     /**
470      * Creates a new font with the given font datas or <code>null</code>
471      * if there is no data.
472      * @return FontRecord for the new Font or <code>null</code>.
473      */

474     private FontRecord createFont(String JavaDoc symbolicName, FontData[] fonts) {
475         Display display = Display.getCurrent();
476         if (display == null) {
477             return null;
478         }
479
480         FontData[] validData = filterData(fonts, display);
481         if (validData.length == 0) {
482             //Nothing specified
483
return null;
484         }
485
486         //Do not fire the update from creation as it is not a property change
487
put(symbolicName, validData, false);
488         Font newFont = new Font(display, validData);
489         return new FontRecord(newFont, validData);
490     }
491
492     /**
493      * Calculates the default font and returns the result.
494      * This method creates a font that must be disposed.
495      */

496     Font calculateDefaultFont() {
497         Display current = Display.getCurrent();
498         if (current == null) {
499             Shell shell = new Shell();
500             Font font = new Font(null, shell.getFont().getFontData());
501             shell.dispose();
502             return font;
503         }
504         return new Font(current, current.getSystemFont().getFontData());
505     }
506
507     /**
508      * Returns the default font data. Creates it if necessary.
509      * @return Font
510      */

511     public Font defaultFont() {
512         return defaultFontRecord().getBaseFont();
513     }
514
515     /**
516      * Returns the font descriptor for the font with the given symbolic
517      * font name. Returns the default font if there is no special value
518      * associated with that name
519      *
520      * @param symbolicName symbolic font name
521      * @return the font descriptor (never null)
522      *
523      * @since 3.3
524      */

525     public FontDescriptor getDescriptor(String JavaDoc symbolicName) {
526         Assert.isNotNull(symbolicName);
527         return FontDescriptor.createFrom(getFontData(symbolicName));
528     }
529     
530     
531     
532     /**
533      * Returns the default font record.
534      */

535     private FontRecord defaultFontRecord() {
536
537         FontRecord record = (FontRecord) stringToFontRecord
538                 .get(JFaceResources.DEFAULT_FONT);
539         if (record == null) {
540             Font defaultFont = calculateDefaultFont();
541             record = createFont(JFaceResources.DEFAULT_FONT, defaultFont
542                     .getFontData());
543             defaultFont.dispose();
544             stringToFontRecord.put(JFaceResources.DEFAULT_FONT, record);
545         }
546         return record;
547     }
548
549     /**
550      * Returns the default font data. Creates it if necessary.
551      */

552     private FontData[] defaultFontData() {
553         return defaultFontRecord().baseData;
554     }
555
556     /**
557      * Returns the font data associated with the given symbolic font name.
558      * Returns the default font data if there is no special value associated
559      * with that name.
560      *
561      * @param symbolicName symbolic font name
562      * @return the font
563      */

564     public FontData[] getFontData(String JavaDoc symbolicName) {
565
566         Assert.isNotNull(symbolicName);
567         Object JavaDoc result = stringToFontData.get(symbolicName);
568         if (result == null) {
569             return defaultFontData();
570         }
571
572         return (FontData[]) result;
573     }
574
575     /**
576      * Returns the font associated with the given symbolic font name.
577      * Returns the default font if there is no special value associated
578      * with that name.
579      *
580      * @param symbolicName symbolic font name
581      * @return the font
582      */

583     public Font get(String JavaDoc symbolicName) {
584
585         return getFontRecord(symbolicName).getBaseFont();
586     }
587
588     /**
589      * Returns the bold font associated with the given symbolic font name.
590      * Returns the bolded default font if there is no special value associated
591      * with that name.
592      *
593      * @param symbolicName symbolic font name
594      * @return the font
595      * @since 3.0
596      */

597     public Font getBold(String JavaDoc symbolicName) {
598
599         return getFontRecord(symbolicName).getBoldFont();
600     }
601
602     /**
603      * Returns the italic font associated with the given symbolic font name.
604      * Returns the italic default font if there is no special value associated
605      * with that name.
606      *
607      * @param symbolicName symbolic font name
608      * @return the font
609      * @since 3.0
610      */

611     public Font getItalic(String JavaDoc symbolicName) {
612
613         return getFontRecord(symbolicName).getItalicFont();
614     }
615
616     /**
617      * Return the font record for the key.
618      * @param symbolicName The key for the record.
619      * @return FontRecird
620      */

621     private FontRecord getFontRecord(String JavaDoc symbolicName) {
622         Assert.isNotNull(symbolicName);
623         Object JavaDoc result = stringToFontRecord.get(symbolicName);
624         if (result != null) {
625             return (FontRecord) result;
626         }
627
628         result = stringToFontData.get(symbolicName);
629
630         FontRecord fontRecord;
631
632         if (result == null) {
633             fontRecord = defaultFontRecord();
634         } else {
635             fontRecord = createFont(symbolicName, (FontData[]) result);
636         }
637
638         if (fontRecord == null) {
639             fontRecord = defaultFontRecord();
640         }
641
642         stringToFontRecord.put(symbolicName, fontRecord);
643         return fontRecord;
644
645     }
646
647     /* (non-Javadoc)
648      * @see org.eclipse.jface.resource.ResourceRegistry#getKeySet()
649      */

650     public Set JavaDoc getKeySet() {
651         return Collections.unmodifiableSet(stringToFontData.keySet());
652     }
653
654     /* (non-Javadoc)
655      * @see org.eclipse.jface.resource.ResourceRegistry#hasValueFor(java.lang.String)
656      */

657     public boolean hasValueFor(String JavaDoc fontKey) {
658         return stringToFontData.containsKey(fontKey);
659     }
660
661     /* (non-Javadoc)
662      * @see org.eclipse.jface.resource.ResourceRegistry#clearCaches()
663      */

664     protected void clearCaches() {
665
666         Iterator JavaDoc iterator = stringToFontRecord.values().iterator();
667         while (iterator.hasNext()) {
668             Object JavaDoc next = iterator.next();
669             ((FontRecord) next).dispose();
670         }
671
672         disposeFonts(staleFonts.iterator());
673         stringToFontRecord.clear();
674         staleFonts.clear();
675     }
676
677     /**
678      * Dispose of all of the fonts in this iterator.
679      * @param iterator over Collection of Font
680      */

681     private void disposeFonts(Iterator JavaDoc iterator) {
682         while (iterator.hasNext()) {
683             Object JavaDoc next = iterator.next();
684             ((Font) next).dispose();
685         }
686     }
687
688     /**
689      * Hook a dispose listener on the SWT display.
690      */

691     private void hookDisplayDispose(Display display) {
692         display.disposeExec(displayRunnable);
693     }
694
695     /**
696      * Checks whether the given font is in the list of fixed fonts.
697      */

698     private boolean isFixedFont(FontData[] fixedFonts, FontData fd) {
699         // Can't use FontData.equals() since some values aren't
700
// set if a fontdata isn't used.
701
int height = fd.getHeight();
702         String JavaDoc name = fd.getName();
703         for (int i = 0; i < fixedFonts.length; i++) {
704             FontData fixed = fixedFonts[i];
705             if (fixed.getHeight() == height && fixed.getName().equals(name)) {
706                 return true;
707             }
708         }
709         return false;
710     }
711
712     /**
713      * Converts a String into a FontData object.
714      */

715     private FontData makeFontData(String JavaDoc value) throws MissingResourceException JavaDoc {
716         try {
717             return StringConverter.asFontData(value.trim());
718         } catch (DataFormatException e) {
719             throw new MissingResourceException JavaDoc(
720                     "Wrong font data format. Value is: \"" + value + "\"", getClass().getName(), value); //$NON-NLS-2$//$NON-NLS-1$
721
}
722     }
723
724     /**
725      * Adds (or replaces) a font to this font registry under the given
726      * symbolic name.
727      * <p>
728      * A property change event is reported whenever the mapping from
729      * a symbolic name to a font changes. The source of the event is
730      * this registry; the property name is the symbolic font name.
731      * </p>
732      *
733      * @param symbolicName the symbolic font name
734      * @param fontData an Array of FontData
735      */

736     public void put(String JavaDoc symbolicName, FontData[] fontData) {
737         put(symbolicName, fontData, true);
738     }
739
740     /**
741      * Adds (or replaces) a font to this font registry under the given
742      * symbolic name.
743      * <p>
744      * A property change event is reported whenever the mapping from
745      * a symbolic name to a font changes. The source of the event is
746      * this registry; the property name is the symbolic font name.
747      * </p>
748      *
749      * @param symbolicName the symbolic font name
750      * @param fontData an Array of FontData
751      * @param update - fire a font mapping changed if true. False
752      * if this method is called from the get method as no setting
753      * has changed.
754      */

755     private void put(String JavaDoc symbolicName, FontData[] fontData, boolean update) {
756
757         Assert.isNotNull(symbolicName);
758         Assert.isNotNull(fontData);
759
760         FontData[] existing = (FontData[]) stringToFontData.get(symbolicName);
761         if (Arrays.equals(existing, fontData)) {
762             return;
763         }
764
765         FontRecord oldFont = (FontRecord) stringToFontRecord
766                 .remove(symbolicName);
767         stringToFontData.put(symbolicName, fontData);
768         if (update) {
769             fireMappingChanged(symbolicName, existing, fontData);
770         }
771
772         if (oldFont != null) {
773             oldFont.addAllocatedFontsToStale(defaultFontRecord().getBaseFont());
774         }
775     }
776
777     /**
778      * Reads the resource bundle. This puts FontData[] objects
779      * in the mapping table. These will lazily be turned into
780      * real Font objects when requested.
781      */

782     private void readResourceBundle(ResourceBundle JavaDoc bundle, String JavaDoc bundleName)
783             throws MissingResourceException JavaDoc {
784         Enumeration JavaDoc keys = bundle.getKeys();
785         while (keys.hasMoreElements()) {
786             String JavaDoc key = (String JavaDoc) keys.nextElement();
787             int pos = key.lastIndexOf('.');
788             if (pos == -1) {
789                 stringToFontData.put(key, new FontData[] { makeFontData(bundle
790                         .getString(key)) });
791             } else {
792                 String JavaDoc name = key.substring(0, pos);
793                 int i = 0;
794                 try {
795                     i = Integer.parseInt(key.substring(pos + 1));
796                 } catch (NumberFormatException JavaDoc e) {
797                     //Panic the file can not be parsed.
798
throw new MissingResourceException JavaDoc(
799                             "Wrong key format ", bundleName, key); //$NON-NLS-1$
800
}
801                 FontData[] elements = (FontData[]) stringToFontData.get(name);
802                 if (elements == null) {
803                     elements = new FontData[8];
804                     stringToFontData.put(name, elements);
805                 }
806                 if (i > elements.length) {
807                     FontData[] na = new FontData[i + 8];
808                     System.arraycopy(elements, 0, na, 0, elements.length);
809                     elements = na;
810                     stringToFontData.put(name, elements);
811                 }
812                 elements[i] = makeFontData(bundle.getString(key));
813             }
814         }
815     }
816
817     /**
818      * Returns the font descriptor for the JFace default font.
819      *
820      * @return the font descriptor for the JFace default font
821      * @since 3.3
822      */

823     public FontDescriptor defaultFontDescriptor() {
824         return FontDescriptor.createFrom(defaultFontData());
825     }
826 }
827
Popular Tags