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

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

Removed some dead code.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
RevLine 
[4928]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 */
[5536]37package org.greenstone.gatherer;
38
[5597]39import java.awt.*;
[5296]40import java.io.*;
[4928]41import java.util.*;
42import javax.swing.*;
43import javax.swing.plaf.*;
44import javax.swing.text.*;
45import javax.swing.tree.*;
46import org.greenstone.gatherer.util.Utility;
[5536]47
[4928]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 */
[5862]69public class Dictionary
[4928]70 extends HashMap {
[5296]71
[4928]72 /** The font used when displaying various html text. */
[6855]73 static private FontUIResource font = null;
[4928]74 /** A reference to remind us of the current locale. */
[6855]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;
[5296]79
80
[6854]81 public Dictionary(Locale locale, FontUIResource font)
82 {
[4928]83 super();
[5296]84
[6854]85 // Initialize
[4928]86 this.font = font;
[6854]87 this.locale = ((locale == null) ? Locale.getDefault() : locale);
88 this.dictionary = ResourceBundle.getBundle(Utility.DICTIONARY, this.locale);
[4928]89 }
[5536]90
91
[6821]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 */
[6855]95 static public String getLanguage()
[6854]96 {
[6821]97 return locale.getLanguage();
[5296]98 }
99
[5529]100
[5593]101 static public String get(String key)
[5529]102 {
[6821]103 return get(key, (String[]) null);
[5529]104 }
105
106
[5593]107 static public String get(String key, String arg)
[5564]108 {
109 String[] args = new String[1];
110 args[0] = arg;
[6821]111 return get(key, args);
[5564]112 }
113
114
[4928]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>
[5536]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 */
[6821]121 static public String get(String key, String[] args)
122 {
[4928]123 try {
[6854]124 String initial_raw = dictionary.getString(key);
[6573]125
[6854]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
[5529]141 // If the string contains arguments we have to insert them.
[4928]142 String complete = "";
[6821]143
[5529]144 // While we still have initial string left.
[4928]145 while(initial.length() > 0 && initial.indexOf('{') != -1 && initial.indexOf('}') != -1) {
146 // Remove preamble
147 int opening = initial.indexOf('{');
148 int closing = initial.indexOf('}');
[5986]149 int comment_mark = initial.indexOf('-', opening); // May not exist
[6854]150 if (comment_mark > closing) { // May also be detecting a later comment
[5986]151 comment_mark = -1;
152 }
[4928]153 complete = complete + initial.substring(0, opening);
154 // Parse arg_num
[5986]155 String arg_str = null;
[6854]156 if (comment_mark != -1) {
[5986]157 arg_str = initial.substring(opening + 1, comment_mark);
158 }
159 else {
160 arg_str = initial.substring(opening + 1, closing);
161 }
[4928]162 int arg_num = Integer.parseInt(arg_str);
[6854]163 if (closing + 1 < initial.length()) {
[4928]164 initial = initial.substring(closing + 1);
165 }
166 else {
167 initial = "";
168 }
169 // Insert argument
[6854]170 if (args != null && 0 <= arg_num && arg_num < args.length) {
[4928]171 complete = complete + args[arg_num];
172 }
[6854]173 else if (arg_num >= 32) {
[4928]174 String f_subargs[] = new String[1];
[6854]175 if (font != null) {
[4928]176 f_subargs[0] = font.getFontName();
177 }
178 else {
179 f_subargs[0] = "Arial";
180 }
[6821]181 complete = complete + get("Farg" + arg_num, f_subargs);
[4928]182 }
183 }
[6573]184 complete = complete + initial;
185
[6854]186 return complete;
[4928]187 }
188 catch (Exception e) {
[5536]189 System.err.println("Missing value for key: " + key);
[8236]190 // DebugStream.printStackTrace(e);
[4928]191 return key;
192 }
193 }
[5529]194
195
[6821]196 static public void registerBoth(Component component, String text_key, String tooltip_key)
[5529]197 {
[5536]198 setText(component, text_key);
199 setTooltip(component, tooltip_key);
[5529]200 }
201
202
[6821]203 static public void registerText(Component component, String text_key)
[5529]204 {
[6821]205 setText(component, text_key);
[5529]206 }
207
208
[6821]209 static public void registerText(Component component, String text_key, String[] args)
[5529]210 {
[6821]211 setText(component, text_key, args);
[5529]212 }
213
214
[6821]215 static public void registerTooltip(Component component, String tooltip_key) {
216 setTooltip(component, tooltip_key);
[5529]217 }
218
219
[6821]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)
[5529]226 {
[6821]227 setText(component, text_key);
228 setTooltip(component, tooltip_key);
[5529]229 }
230
231
[6821]232 static public void setText(Component component, String text_key)
[5529]233 {
[6821]234 setText(component, text_key, null);
[5536]235 }
236
237
[6821]238 static public void setText(Component component, String text_key, String[] args)
[5536]239 {
[5529]240 if (component != null) {
241 // Update the component using the AWTEvent queue
[8591]242 SwingUtilities.invokeLater(new ComponentUpdateTask(component, get(text_key, args), null));
[5529]243 }
244 }
245
246
[6821]247 static public void setTooltip(Component component, String tooltip_key)
[5529]248 {
249 if (component != null) {
250 // Update the component using the AWTEvent queue
[8591]251 SwingUtilities.invokeLater(new ComponentUpdateTask(component, null, get(tooltip_key)));
[5529]252 }
253 }
254
[6821]255
256 static public void setTooltipText(Component component, String tooltip)
257 {
258 if (component != null) {
[8591]259 // Update the component using the AWTEvent queue
260 SwingUtilities.invokeLater(new ComponentUpdateTask(component, null, tooltip));
[6821]261 }
[6531]262 }
[5529]263
[6531]264
[5536]265 static private class ComponentUpdateTask
[5529]266 implements Runnable {
267
[8591]268 private Component component = null;
[5529]269 private String text = null;
270 private String tooltip = null;
271
[6821]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
[5529]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 }
[5597]288 else if (component instanceof Frame) {
289 ((Frame) component).setTitle(text);
290 }
[5529]291 else if (component instanceof JDialog) {
292 ((JDialog) component).setTitle(text);
293 }
294 else if (component instanceof JLabel) {
295 ((JLabel) component).setText(text);
296 }
[5571]297 else if (component instanceof JProgressBar) {
298 ((JProgressBar) component).setString(text);
299 }
[5529]300 else if (component instanceof JTextComponent) {
301 ((JTextComponent) component).setText(text);
[5536]302 ((JTextComponent) component).setCaretPosition(0);
[5529]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 /**
[5593]320 * Register a tab pane component. This will be deprecated eventually. */
[5536]321 static public void register(JTabbedPane component)
[5529]322 {
[5593]323 if (component != null) {
[6821]324 String[] args = new String[component.getTabCount()];
[5529]325
[6821]326 // Iterate through the tabbed panes tabs, updating values and recording the original key of each item in args.
[5593]327 for (int i = 0; i < args.length; i++) {
[6821]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 }
[4928]337 }
[5527]338
339
[5536]340 /** Updates a tabbed panes tab title and tooltip. */
341 static private class JTabbedPaneChangeTask
[6821]342 implements Runnable {
[5593]343
[6821]344 private JTabbedPane component;
345 private int index;
346 private String value;
347 private String tooltip;
[5527]348
[6821]349 public JTabbedPaneChangeTask(JTabbedPane component, int index, String value, String tooltip) {
[5536]350 this.component = component;
[6821]351 this.index = index;
352 this.value = value;
353 this.tooltip = tooltip;
354 }
[5593]355
[6821]356 public void run() {
357 component.setTitleAt(index, value);
358 component.setToolTipTextAt(index, tooltip);
359 }
[4928]360 }
361}
Note: See TracBrowser for help on using the repository browser.