source: trunk/gli/src/org/greenstone/gatherer/Dictionary.java@ 8591

Last change on this file since 8591 was 8591, checked in by mdewsnip, 19 years ago

Removed some dead code.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer;
38
39import java.awt.*;
40import java.io.*;
41import java.util.*;
42import javax.swing.*;
43import javax.swing.plaf.*;
44import javax.swing.text.*;
45import javax.swing.tree.*;
46import org.greenstone.gatherer.util.Utility;
47
48/** Extends the ResourceBundle class to allow for the automatic insertion of arguments. Note that the key names beginning Farg are reserved for formatting. <BR>
49 * <BR>
50 * Property files usable by this class have the Backus-Naur form: <BR>
51 * <BR>
52 * FileLine ::= Comment | Mapping <BR>
53 * Comment ::= '#' SString <BR>
54 * Mapping ::= NZString ':' SString ( Argument SString )* <BR>
55 * NZString ::= ( Char | Int ) SString <BR>
56 * Argument ::= '{' Int '}' <BR>
57 * SString ::= String . ['"','#',...] -> ['\"','\#',...] <BR>
58 * <BR>
59 * In order to add a new dictionary Locale, simply copy the existing dictionary.properties files, replace the values (Strings after the ':') with the new language specific ones being careful to maintain formatting and Gatherer placed arguments, then save the new dictionary as: <br>
60 * <BR>
61 * dictionary_<I>locale</I>.properties<BR>
62 * <BR>
63 * where locale is made of two two-letter codes seperated by an underscore. The first code is in lower-case and defines the language. The second is in upper-case and defines the country. For example the default dictionary could also correctly be called:
64 * <BR>
65 * dictionary_en_NZ.properties<BR>
66 * @author John Thompson, Greenstone Digital Library, University of Waikato
67 * @version 2.3
68 */
69public class Dictionary
70 extends HashMap {
71
72 /** The font used when displaying various html text. */
73 static private FontUIResource font = null;
74 /** A reference to remind us of the current locale. */
75 static private Locale locale = null;
76 /** The ResourceBundle which contains the raw key-value mappings.
77 Loaded from a file named "dictionary<I>locale</I>.properties. */
78 static private ResourceBundle dictionary = null;
79
80
81 public Dictionary(Locale locale, FontUIResource font)
82 {
83 super();
84
85 // Initialize
86 this.font = font;
87 this.locale = ((locale == null) ? Locale.getDefault() : locale);
88 this.dictionary = ResourceBundle.getBundle(Utility.DICTIONARY, this.locale);
89 }
90
91
92 /** Retrieve the two letter code of the current language we are using, according to the stored locale.
93 * @return A <strong>String</strong> containing the two letter ISO639 language code.
94 */
95 static public String getLanguage()
96 {
97 return locale.getLanguage();
98 }
99
100
101 static public String get(String key)
102 {
103 return get(key, (String[]) null);
104 }
105
106
107 static public String get(String key, String arg)
108 {
109 String[] args = new String[1];
110 args[0] = arg;
111 return get(key, args);
112 }
113
114
115 /** Used to retrieve a property value from the Locale specific ResourceBundle, based upon the key and arguments supplied. If the key cannot be found or if some other part of the call fails a default (English) error message is returned. <BR>
116 * Here the get recieves a second argument which is an array of Strings used to populate argument fields, denoted {<I>n</I>}, within the value String returned. Note that argument numbers greater than or equal to 32 are automatically mapped to the formatting String named Farg<I>n</I>.
117 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle.
118 * @param args A <strong>String[]</strong> used to populate argument fields within the complete String.
119 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call.
120 */
121 static public String get(String key, String[] args)
122 {
123 try {
124 String initial_raw = dictionary.getString(key);
125
126 // Convert into Unicode
127 String initial = "";
128 try {
129 // This "ISO-8859-1" looks out of place, but it is very important.
130 // It is essential to call getBytes with an 8-bit encoding, otherwise
131 // Java kindly deems some characters "undisplayable", and replaces
132 // them with question marks. This is NOT good.
133 initial = new String(initial_raw.getBytes("ISO-8859-1"), "UTF-8");
134 }
135 catch (Exception ex) {
136 System.err.println("Exception: " + ex);
137 ex.printStackTrace();
138 return initial_raw;
139 }
140
141 // If the string contains arguments we have to insert them.
142 String complete = "";
143
144 // While we still have initial string left.
145 while(initial.length() > 0 && initial.indexOf('{') != -1 && initial.indexOf('}') != -1) {
146 // Remove preamble
147 int opening = initial.indexOf('{');
148 int closing = initial.indexOf('}');
149 int comment_mark = initial.indexOf('-', opening); // May not exist
150 if (comment_mark > closing) { // May also be detecting a later comment
151 comment_mark = -1;
152 }
153 complete = complete + initial.substring(0, opening);
154 // Parse arg_num
155 String arg_str = null;
156 if (comment_mark != -1) {
157 arg_str = initial.substring(opening + 1, comment_mark);
158 }
159 else {
160 arg_str = initial.substring(opening + 1, closing);
161 }
162 int arg_num = Integer.parseInt(arg_str);
163 if (closing + 1 < initial.length()) {
164 initial = initial.substring(closing + 1);
165 }
166 else {
167 initial = "";
168 }
169 // Insert argument
170 if (args != null && 0 <= arg_num && arg_num < args.length) {
171 complete = complete + args[arg_num];
172 }
173 else if (arg_num >= 32) {
174 String f_subargs[] = new String[1];
175 if (font != null) {
176 f_subargs[0] = font.getFontName();
177 }
178 else {
179 f_subargs[0] = "Arial";
180 }
181 complete = complete + get("Farg" + arg_num, f_subargs);
182 }
183 }
184 complete = complete + initial;
185
186 return complete;
187 }
188 catch (Exception e) {
189 System.err.println("Missing value for key: " + key);
190 // DebugStream.printStackTrace(e);
191 return key;
192 }
193 }
194
195
196 static public void registerBoth(Component component, String text_key, String tooltip_key)
197 {
198 setText(component, text_key);
199 setTooltip(component, tooltip_key);
200 }
201
202
203 static public void registerText(Component component, String text_key)
204 {
205 setText(component, text_key);
206 }
207
208
209 static public void registerText(Component component, String text_key, String[] args)
210 {
211 setText(component, text_key, args);
212 }
213
214
215 static public void registerTooltip(Component component, String tooltip_key) {
216 setTooltip(component, tooltip_key);
217 }
218
219
220 static public void registerTooltipText(Component component, String tooltip) {
221 setTooltipText(component, tooltip);
222 }
223
224
225 static public void setBoth(Component component, String text_key, String tooltip_key)
226 {
227 setText(component, text_key);
228 setTooltip(component, tooltip_key);
229 }
230
231
232 static public void setText(Component component, String text_key)
233 {
234 setText(component, text_key, null);
235 }
236
237
238 static public void setText(Component component, String text_key, String[] args)
239 {
240 if (component != null) {
241 // Update the component using the AWTEvent queue
242 SwingUtilities.invokeLater(new ComponentUpdateTask(component, get(text_key, args), null));
243 }
244 }
245
246
247 static public void setTooltip(Component component, String tooltip_key)
248 {
249 if (component != null) {
250 // Update the component using the AWTEvent queue
251 SwingUtilities.invokeLater(new ComponentUpdateTask(component, null, get(tooltip_key)));
252 }
253 }
254
255
256 static public void setTooltipText(Component component, String tooltip)
257 {
258 if (component != null) {
259 // Update the component using the AWTEvent queue
260 SwingUtilities.invokeLater(new ComponentUpdateTask(component, null, tooltip));
261 }
262 }
263
264
265 static private class ComponentUpdateTask
266 implements Runnable {
267
268 private Component component = null;
269 private String text = null;
270 private String tooltip = null;
271
272
273 public ComponentUpdateTask(Component component, String text, String tooltip)
274 {
275 this.component = component;
276 this.text = text;
277 this.tooltip = tooltip;
278 }
279
280
281 public void run()
282 {
283 // If the component has text
284 if (text != null) {
285 if (component instanceof AbstractButton) {
286 ((AbstractButton) component).setText(text);
287 }
288 else if (component instanceof Frame) {
289 ((Frame) component).setTitle(text);
290 }
291 else if (component instanceof JDialog) {
292 ((JDialog) component).setTitle(text);
293 }
294 else if (component instanceof JLabel) {
295 ((JLabel) component).setText(text);
296 }
297 else if (component instanceof JProgressBar) {
298 ((JProgressBar) component).setString(text);
299 }
300 else if (component instanceof JTextComponent) {
301 ((JTextComponent) component).setText(text);
302 ((JTextComponent) component).setCaretPosition(0);
303 }
304 else {
305 System.err.println("Unhandled component: " + component.getClass());
306 }
307 }
308
309 // If the component has a tooltip
310 if (tooltip != null) {
311 if (component instanceof JComponent) {
312 ((JComponent) component).setToolTipText(tooltip);
313 }
314 }
315 }
316 }
317
318
319 /**
320 * Register a tab pane component. This will be deprecated eventually. */
321 static public void register(JTabbedPane component)
322 {
323 if (component != null) {
324 String[] args = new String[component.getTabCount()];
325
326 // Iterate through the tabbed panes tabs, updating values and recording the original key of each item in args.
327 for (int i = 0; i < args.length; i++) {
328 if (args[i] == null) {
329 args[i] = component.getTitleAt(i);
330 }
331 String value = get(args[i], (String[]) null);
332 String tooltip = get(args[i] + "_Tooltip", (String[]) null);
333 JTabbedPaneChangeTask task = new JTabbedPaneChangeTask(component, i, value, tooltip);
334 SwingUtilities.invokeLater(task);
335 }
336 }
337 }
338
339
340 /** Updates a tabbed panes tab title and tooltip. */
341 static private class JTabbedPaneChangeTask
342 implements Runnable {
343
344 private JTabbedPane component;
345 private int index;
346 private String value;
347 private String tooltip;
348
349 public JTabbedPaneChangeTask(JTabbedPane component, int index, String value, String tooltip) {
350 this.component = component;
351 this.index = index;
352 this.value = value;
353 this.tooltip = tooltip;
354 }
355
356 public void run() {
357 component.setTitleAt(index, value);
358 component.setToolTipTextAt(index, tooltip);
359 }
360 }
361}
Note: See TracBrowser for help on using the repository browser.