1 40 package org.jfree.util; 41 42 import java.awt.Image ; 43 import java.awt.Toolkit ; 44 import java.awt.event.InputEvent ; 45 import java.awt.event.KeyEvent ; 46 import java.awt.image.BufferedImage ; 47 import java.lang.reflect.Field ; 48 import java.net.URL ; 49 import java.text.MessageFormat ; 50 import java.util.Arrays ; 51 import java.util.Locale ; 52 import java.util.MissingResourceException ; 53 import java.util.ResourceBundle ; 54 import java.util.TreeMap ; 55 import java.util.TreeSet ; 56 import javax.swing.Icon ; 57 import javax.swing.ImageIcon ; 58 import javax.swing.JMenu ; 59 import javax.swing.KeyStroke ; 60 61 77 public class ResourceBundleSupport 78 { 79 82 private ResourceBundle resources; 83 84 88 private TreeMap cache; 89 93 private TreeSet lookupPath; 94 95 98 private String resourceBase; 99 100 103 private Locale locale; 104 105 111 public ResourceBundleSupport(final Locale locale, final String baseName) 112 { 113 this(locale, ResourceBundle.getBundle(baseName, locale), baseName); 114 } 115 116 125 protected ResourceBundleSupport(final Locale locale, 126 final ResourceBundle resourceBundle, 127 final String baseName) 128 { 129 if (locale == null) 130 { 131 throw new NullPointerException ("Locale must not be null"); 132 } 133 if (resourceBundle == null) 134 { 135 throw new NullPointerException ("Resources must not be null"); 136 } 137 if (baseName == null) 138 { 139 throw new NullPointerException ("BaseName must not be null"); 140 } 141 this.locale = locale; 142 this.resources = resourceBundle; 143 this.resourceBase = baseName; 144 this.cache = new TreeMap (); 145 this.lookupPath = new TreeSet (); 146 } 147 148 155 public ResourceBundleSupport(final Locale locale, 156 final ResourceBundle resourceBundle) 157 { 158 this(locale, resourceBundle, resourceBundle.toString()); 159 } 160 161 167 public ResourceBundleSupport(final String baseName) 168 { 169 this(Locale.getDefault(), ResourceBundle.getBundle(baseName), baseName); 170 } 171 172 179 protected ResourceBundleSupport(final ResourceBundle resourceBundle, 180 final String baseName) 181 { 182 this(Locale.getDefault(), resourceBundle, baseName); 183 } 184 185 190 public ResourceBundleSupport(final ResourceBundle resourceBundle) 191 { 192 this(Locale.getDefault(), resourceBundle, resourceBundle.toString()); 193 } 194 195 200 protected final String getResourceBase() 201 { 202 return this.resourceBase; 203 } 204 205 218 public synchronized String getString(final String key) 219 { 220 final String retval = (String ) this.cache.get(key); 221 if (retval != null) 222 { 223 return retval; 224 } 225 this.lookupPath.clear(); 226 return internalGetString(key); 227 } 228 229 236 protected String internalGetString(final String key) 237 { 238 if (this.lookupPath.contains(key)) 239 { 240 throw new MissingResourceException 241 ("InfiniteLoop in resource lookup", 242 getResourceBase(), this.lookupPath.toString()); 243 } 244 final String fromResBundle = this.resources.getString(key); 245 if (fromResBundle.startsWith("@@")) 246 { 247 final int idx = fromResBundle.indexOf('@', 2); 249 if (idx == -1) 250 { 251 throw new MissingResourceException 252 ("Invalid format for global lookup key.", getResourceBase(), key); 253 } 254 try 255 { 256 final ResourceBundle res = ResourceBundle.getBundle 257 (fromResBundle.substring(2, idx)); 258 return res.getString(fromResBundle.substring(idx + 1)); 259 } 260 catch (Exception e) 261 { 262 Log.error("Error during global lookup", e); 263 throw new MissingResourceException 264 ("Error during global lookup", getResourceBase(), key); 265 } 266 } 267 else if (fromResBundle.startsWith("@")) 268 { 269 final String newKey = fromResBundle.substring(1); 271 this.lookupPath.add(key); 272 final String retval = internalGetString(newKey); 273 274 this.cache.put(key, retval); 275 return retval; 276 } 277 else 278 { 279 this.cache.put(key, fromResBundle); 280 return fromResBundle; 281 } 282 } 283 284 292 public Icon getIcon(final String key, final boolean large) 293 { 294 final String name = getString(key); 295 return createIcon(name, true, large); 296 } 297 298 304 public Icon getIcon(final String key) 305 { 306 final String name = getString(key); 307 return createIcon(name, false, false); 308 } 309 310 325 public Integer getMnemonic(final String key) 326 { 327 final String name = getString(key); 328 return createMnemonic(name); 329 } 330 331 332 public Integer getOptionalMnemonic(final String key) 333 { 334 final String name = getString(key); 335 if (name != null && name.length() > 0) 336 { 337 return createMnemonic(name); 338 } 339 return null; 340 } 341 342 362 public KeyStroke getKeyStroke(final String key) 363 { 364 return getKeyStroke(key, getMenuKeyMask()); 365 } 366 367 public KeyStroke getOptionalKeyStroke(final String key) 368 { 369 return getOptionalKeyStroke(key, getMenuKeyMask()); 370 } 371 372 392 public KeyStroke getKeyStroke(final String key, final int mask) 393 { 394 final String name = getString(key); 395 return KeyStroke.getKeyStroke(createMnemonic(name).intValue(), mask); 396 } 397 398 public KeyStroke getOptionalKeyStroke(final String key, final int mask) 399 { 400 final String name = getString(key); 401 402 if (name != null && name.length() > 0) 403 { 404 return KeyStroke.getKeyStroke(createMnemonic(name).intValue(), mask); 405 } 406 return null; 407 } 408 409 428 public JMenu createMenu(final String keyPrefix) 429 { 430 final JMenu retval = new JMenu (); 431 retval.setText(getString(keyPrefix + ".name")); 432 retval.setMnemonic(getMnemonic(keyPrefix + ".mnemonic").intValue()); 433 return retval; 434 } 435 436 450 public URL getResourceURL(final String key) 451 { 452 final String name = getString(key); 453 final URL in = ObjectUtilities.getResource(name, ResourceBundleSupport.class); 454 if (in == null) 455 { 456 Log.warn("Unable to find file in the class path: " + name + "; key=" + key); 457 } 458 return in; 459 } 460 461 462 473 private ImageIcon createIcon(final String resourceName, final boolean scale, 474 final boolean large) 475 { 476 final URL in = ObjectUtilities.getResource(resourceName, ResourceBundleSupport.class); 477 ; 478 if (in == null) 479 { 480 Log.warn("Unable to find file in the class path: " + resourceName); 481 return new ImageIcon (createTransparentImage(1, 1)); 482 } 483 final Image img = Toolkit.getDefaultToolkit().createImage(in); 484 if (img == null) 485 { 486 Log.warn("Unable to instantiate the image: " + resourceName); 487 return new ImageIcon (createTransparentImage(1, 1)); 488 } 489 if (scale) 490 { 491 if (large) 492 { 493 return new ImageIcon (img.getScaledInstance(24, 24, Image.SCALE_SMOOTH)); 494 } 495 return new ImageIcon (img.getScaledInstance(16, 16, Image.SCALE_SMOOTH)); 496 } 497 return new ImageIcon (img); 498 } 499 500 507 private Integer createMnemonic(final String keyString) 508 { 509 if (keyString == null) 510 { 511 throw new NullPointerException ("Key is null."); 512 } 513 if (keyString.length() == 0) 514 { 515 throw new IllegalArgumentException ("Key is empty."); 516 } 517 int character = keyString.charAt(0); 518 if (keyString.startsWith("VK_")) 519 { 520 try 521 { 522 final Field f = KeyEvent .class.getField(keyString); 523 final Integer keyCode = (Integer ) f.get(null); 524 character = keyCode.intValue(); 525 } 526 catch (Exception nsfe) 527 { 528 } 530 } 531 return new Integer (character); 532 } 533 534 539 private int getMenuKeyMask() 540 { 541 try 542 { 543 return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); 544 } 545 catch (UnsupportedOperationException he) 546 { 547 return InputEvent.CTRL_MASK; 550 } 551 } 552 553 560 private BufferedImage createTransparentImage(final int width, 561 final int height) 562 { 563 final BufferedImage img = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB); 564 final int[] data = img.getRGB(0, 0, width, height, null, 0, width); 565 Arrays.fill(data, 0x00000000); 566 img.setRGB(0, 0, width, height, data, 0, width); 567 return img; 568 } 569 570 578 public Icon createTransparentIcon(final int width, final int height) 579 { 580 return new ImageIcon (createTransparentImage(width, height)); 581 } 582 583 591 public String formatMessage(final String key, final Object parameter) 592 { 593 return formatMessage(key, new Object []{parameter}); 594 } 595 596 605 public String formatMessage(final String key, 606 final Object par1, 607 final Object par2) 608 { 609 return formatMessage(key, new Object []{par1, par2}); 610 } 611 612 620 public String formatMessage(final String key, final Object [] parameters) 621 { 622 final MessageFormat format = new MessageFormat (getString(key)); 623 format.setLocale(getLocale()); 624 return format.format(parameters); 625 } 626 627 632 public Locale getLocale() 633 { 634 return locale; 635 } 636 } 637 | Popular Tags |