1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Oracle designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Oracle in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24 * or visit www.oracle.com if you need additional information or have any 25 * questions. 26 */ 27 package com.sun.javatest.tool; 28 29 import java.awt.Color; 30 import java.awt.Component; 31 import java.awt.Container; 32 import java.awt.Dimension; 33 import java.awt.Font; 34 import java.awt.GridBagConstraints; 35 import java.awt.GridBagLayout; 36 import java.awt.Image; 37 import java.awt.KeyboardFocusManager; 38 import java.awt.LayoutManager; 39 import java.awt.Toolkit; 40 import java.awt.Window; 41 import java.awt.event.ActionEvent; 42 import java.awt.event.ActionListener; 43 import java.awt.event.KeyEvent; 44 import java.net.URL; 45 import java.util.MissingResourceException; 46 47 import javax.accessibility.Accessible; 48 import javax.accessibility.AccessibleContext; 49 import javax.swing.AbstractButton; 50 import javax.swing.Action; 51 import javax.swing.BorderFactory; 52 import javax.swing.BoundedRangeModel; 53 import javax.swing.Box; 54 import javax.swing.ButtonGroup; 55 import javax.swing.DefaultListCellRenderer; 56 import javax.swing.Icon; 57 import javax.swing.ImageIcon; 58 import javax.swing.JButton; 59 import javax.swing.JCheckBox; 60 import javax.swing.JCheckBoxMenuItem; 61 import javax.swing.JComboBox; 62 import javax.swing.JComponent; 63 import javax.swing.JDialog; 64 import javax.swing.JFrame; 65 import javax.swing.JInternalFrame; 66 import javax.swing.JLabel; 67 import javax.swing.JList; 68 import javax.swing.JMenu; 69 import javax.swing.JMenuBar; 70 import javax.swing.JMenuItem; 71 import javax.swing.JOptionPane; 72 import javax.swing.JPanel; 73 import javax.swing.JPopupMenu; 74 import javax.swing.JProgressBar; 75 import javax.swing.JRadioButton; 76 import javax.swing.JRadioButtonMenuItem; 77 import javax.swing.JRootPane; 78 import javax.swing.JScrollPane; 79 import javax.swing.JSlider; 80 import javax.swing.JSplitPane; 81 //import javax.swing.JSpinner; 82 import javax.swing.JTabbedPane; 83 import javax.swing.JTable; 84 import javax.swing.JTextArea; 85 import javax.swing.JTextField; 86 import javax.swing.JToolBar; 87 import javax.swing.KeyStroke; 88 import javax.swing.ListModel; 89 //import javax.swing.SpinnerModel; 90 import javax.swing.SwingConstants; 91 import javax.swing.SwingUtilities; 92 import javax.swing.border.Border; 93 import javax.swing.border.TitledBorder; 94 import javax.swing.table.TableModel; 95 96 import com.sun.javatest.ProductInfo; 97 import com.sun.javatest.tool.jthelp.ContextHelpManager; 98 import com.sun.javatest.tool.jthelp.HelpBroker; 99 import com.sun.javatest.util.I18NResourceBundle; 100 import java.awt.Dialog; 101 import java.util.Enumeration; 102 import java.util.ResourceBundle; 103 import javax.swing.UIManager; 104 import javax.swing.plaf.metal.MetalLookAndFeel; 105 106 /** 107 * A factory for GUI components, providing support for 108 * internationalization, tool tips, context sensitive help, and on. 109 * UIFactory objects use a resource bundle specific to the client 110 * class to provide the internationalization support. 111 */ 112 public class UIFactory { 113 114 public static enum Colors { 115 /** 116 * Color used for highlighting incorrect input fields 117 */ 118 INPUT_INVALID(local_i18n.getString("colorprefs.colors.input.invalid.defvalue")), 119 /** 120 * Color used for highlighting correct input fields 121 */ 122 INPUT_VALID(local_i18n.getString("colorprefs.colors.input.valid.defvalue")), 123 /** 124 * Default background color for input fields 125 */ 126 INPUT_DEFAULT(local_i18n.getString("colorprefs.colors.input.default.defvalue")), 127 128 MENU_BACKGROUND(UIManager.getColor("Menu.background"), 255, false), 129 SEPARATOR_FOREGROUND(UIManager.getColor("Separator.foreground"), 255, false), 130 CONTROL_INFO(Color.RED, 255, false), 131 CONTROL_SHADOW(Color.RED, 255, false), 132 TEXT_HIGHLIGHT_COLOR(new JTextField().getSelectionColor(), 255, false), 133 TEXT_COLOR(new JLabel().getForeground(), 255, false), 134 TEXT_SELECTED_COLOR(new JTextField().getSelectedTextColor(), 255, false), 135 WINDOW_BACKGROUND(UIManager.getColor("Panel.background"), 255, false), 136 PRIMARY_CONTROL_HIGHLIGHT(Color.WHITE, 255, false), 137 PRIMARY_CONTROL_INFO(Color.BLACK, 255, false), 138 BUTTON_DISABLED_FOREGROUND(Color.WHITE, 255, false),//UIManager.getDefaults().getColor("Button.disabledForeground") 139 140 // these three are used for icon drawing only 141 PRIMARY_CONTROL_SHADOW(MetalLookAndFeel.getPrimaryControlShadow(), 255, false), 142 PRIMARY_CONTROL(MetalLookAndFeel.getPrimaryControl(), 255, false), 143 PRIMARY_CONTROL_DARK_SHADOW(MetalLookAndFeel.getPrimaryControlDarkShadow(), 255, false), 144 145 BLACK(Color.BLACK, 255, false), 146 TRANSPARENT(new Color(255, 255, 255, 0), false); 147 148 private final String defaultColor; 149 private Color color = null; 150 private boolean configurable; 151 152 Colors(Color defaultColor) { 153 this(defaultColor, true); 154 } 155 156 Colors(Color defaultColor, int alpha) { 157 this(new Color(defaultColor.getRed(), defaultColor.getGreen(), defaultColor.getBlue(), alpha), true); 158 } 159 160 Colors(Color defaultColor, int alpha, boolean configurable) { 161 this(new Color(defaultColor.getRed(), defaultColor.getGreen(), defaultColor.getBlue(), alpha), configurable); 162 } 163 164 Colors(Color defaultColor, boolean configurable) { 165 this.defaultColor = encodeARGB(defaultColor); 166 this.configurable = configurable; 167 } 168 169 Colors(String defaultColor) { 170 this.defaultColor = defaultColor; 171 this.configurable = true; 172 } 173 174 public boolean isConfigurable() { 175 return configurable; 176 } 177 178 /** 179 * Getter for default String-encoded color value. Is used for Color.decode() and 180 * should be formatted similarly 181 * 182 * @return Default String-encoded color value 183 */ 184 public String getDefaultValue() { 185 return defaultColor; 186 } 187 188 /** 189 * Getter for current color value. It is loaded from preferences if no color is set 190 * previously. 191 * 192 * @return Current color value 193 */ 194 public Color getValue() { 195 if(color == null) { 196 color = readColorFromPreferences(); 197 } 198 return color; 199 } 200 201 /** 202 * Setter for current color value. 203 * 204 * @return Old color value 205 */ 206 public Color setValue(Color c) { 207 Color t = color; 208 if (configurable) 209 color = c; 210 return t; 211 } 212 213 /** 214 * Get color name used in preferences file. It is formed from enum name. 215 * E.g. colors.input.invalid for INPUT_INVALID 216 * 217 * @return Color name used in preferences file 218 */ 219 public String getPreferencesName() { 220 return "colors." + this.name().toLowerCase().replaceAll("_", "."); 221 } 222 223 /** 224 * Read color value from preferences ignoring current color value that is 225 * returned by getValue(); 226 * 227 * @return Color value from preferences file 228 */ 229 public Color readColorFromPreferences() { 230 return decodeRGBA(Preferences.access().getPreference(this.getPreferencesName(), this.getDefaultValue())); 231 } 232 233 /** 234 * Find Colors by color preferences name. 235 * 236 * @param prefsName Color preferences name (e.g. "colors.input.default") 237 * @throws IllegalArgumentException in case there is no Colors with such 238 * name 239 * @return Colors associated with such preferences name 240 */ 241 public static Colors valueOfByPreferencesName(String prefsName) { 242 return Colors.valueOf(prefsName.replaceFirst("colors.", "").toUpperCase().replaceAll("\\.", "_")); 243 } 244 245 /** 246 * Get Color by colors preferences name. 247 * 248 * @param prefsName Color preferences name (e.g. "colors.input.default") 249 * @return Color if Preferences contain this color. Returns default value if exists<br> 250 * null otherwise 251 */ 252 public static Color getColorByPreferencesName(String prefsName) { 253 Preferences prefs = Preferences.access(); 254 try { 255 Colors c = valueOfByPreferencesName(prefsName); // IllegalArgumentException if such Colors doesn't exist 256 257 return c.getValue(); 258 } catch(IllegalArgumentException e) { 259 String color = prefs.getPreference(prefsName); // try to find color in preferences anyway 260 return color == null ? null : decodeRGBA(color); 261 } 262 } 263 264 /** 265 * Get array with all colors names used in preferences 266 * 267 * @return Names array 268 */ 269 public static String[] getColorsNames() { 270 Colors[] values = Colors.values(); 271 String temp[] = new String[values.length]; 272 for(int i = 0; i < values.length; i++) { 273 temp[i] = values[i].getPreferencesName(); 274 } 275 return temp; 276 } 277 278 public static Color decodeRGBA(String color) throws NumberFormatException { 279 try { 280 if (color.startsWith("0x") && color.length() == 10) { 281 Long colorCode = Long.decode(color); 282 int A = (int) (colorCode & 0xFF); 283 colorCode >>= 8; 284 int B = (int) (colorCode & 0xFF); 285 colorCode >>= 8; 286 int G = (int) (colorCode & 0xFF); 287 colorCode >>= 8; 288 int R = (int) (colorCode & 0xFF); 289 colorCode >>= 8; 290 return new Color(R, G, B, A); 291 } else { 292 return Color.decode(color); 293 } 294 } catch(Exception e) { 295 return Color.red; 296 } 297 } 298 299 public static String encodeARGB(Color color) { 300 if(color == null) 301 return ""; 302 return String.format("0x%02x%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 303 } 304 } 305 306 public static Font getBaseFont() { 307 return baseFont; 308 } 309 310 /** 311 * Get invalid input color (red by default) 312 * @return Color of invalid input 313 */ 314 public static Color getInvalidInputColor() { 315 return Colors.INPUT_INVALID.getValue(); 316 } 317 318 /** 319 * Set invalid input color 320 * @param newColor new invalid input color 321 */ 322 public static void setInvalidInputColor(Color newColor) { 323 Colors.INPUT_INVALID.setValue(newColor); 324 } 325 326 /** 327 * Get valid input color (green by default) 328 * @return Color of valid input 329 */ 330 public static Color getValidInputColor() { 331 return Colors.INPUT_VALID.getValue(); 332 } 333 334 /** 335 * Set valid input color 336 * @param newColor new valid input color 337 */ 338 public static void setValidInputColor(Color newColor) { 339 Colors.INPUT_VALID.setValue(newColor); 340 } 341 342 /** 343 * Get default input color (while by default) 344 * @return Color of default input 345 */ 346 public static Color getDefaultInputColor() { 347 return Colors.INPUT_DEFAULT.getValue(); 348 } 349 350 /** 351 * Set default input color 352 * @param newColor new default input color 353 */ 354 public static void setDefaultInputColor(Color newColor) { 355 Colors.INPUT_DEFAULT.setValue(newColor); 356 } 357 358 /** 359 * Set Color by preferences name 360 * @param name Color's preferences name 361 * @param c new Color to set 362 */ 363 public static void setColorByName(String name, Color c) { 364 Colors.valueOfByPreferencesName(name).setValue(c); 365 } 366 367 /** 368 * Set all colors to default values 369 */ 370 public static void setDefaultColors() { 371 Preferences pref = Preferences.access(); 372 Colors colors[] = Colors.values(); 373 for(Colors c: colors) { 374 pref.setPreference(c.getPreferencesName(), c.getDefaultValue()); 375 } 376 } 377 378 /** 379 * Add Preferences observer to color changes 380 * @param observer 381 */ 382 public static void addColorChangeObserver(Preferences.Observer observer) { 383 Preferences.access().addObserver(Colors.getColorsNames(), observer); 384 } 385 386 /** 387 * Creates a color-choosing button with background color set by preferences color name 388 * @param cs preferences color name. Used to set background color and is set as JButton.name 389 * @param label JLabel for button 390 * @param l ActionListener for button 391 * @return color-choosing button 392 */ 393 public JButton createColorChooseButton(String cs, JLabel label, ActionListener l) { 394 JButton b = new JButton(" "); 395 Color c = Colors.getColorByPreferencesName(cs); 396 b.setBackground(c); 397 b.setSize(14, 14); 398 b.setText(" "); 399 b.setName(cs); 400 if(l != null) 401 b.addActionListener(l); 402 if(label != null) 403 label.setLabelFor(b); 404 return b; 405 } 406 407 /** 408 * Create a UIFactory object for a specific class. 409 * The class is used to determine the resource bundle 410 * for i18n strings; the bundle is named i18n.properties 411 * in the same package as the specified class. 412 * @param c the class used to determine the i18n properties 413 * @param helpBroker the help broker to be used when creating help buttons 414 */ 415 public UIFactory(Class c, HelpBroker helpBroker) { 416 this(c, null, helpBroker); 417 } 418 419 /** 420 * Create a UIFactory object for a specific component. 421 * The component's class is used to determine the resource bundle 422 * for i18n strings; the bundle is named i18n.properties 423 * in the same package as the specified class. 424 * @param c the component used to determine the i18n properties 425 * @param helpBroker the help broker to be used when creating help buttons 426 */ 427 public UIFactory(Component c, HelpBroker helpBroker) { 428 this(c.getClass(), c, helpBroker); 429 } 430 431 /** 432 * Create a UIFactory object for a specific class. 433 * The class is used to determine the resource bundle 434 * for i18n strings; the bundle is named i18n.properties 435 * in the same package as the specified class. 436 * @param c the class used to determine the i18n properties 437 * @param p the parent component to be used for any dialogs that are created 438 * @param helpBroker the help broker to be used when creating help buttons 439 */ 440 public UIFactory(Class c, Component p, HelpBroker helpBroker) { 441 this.helpBroker = helpBroker; 442 clientClass = c; 443 parent = p; 444 i18n = I18NResourceBundle.getBundleForClass(c); 445 } 446 447 /** 448 * Set the parent component to be used for dialogs created by this factory. 449 * This setting cannot be changed after it is set. 450 * 451 * @param p The parent component, should not be null. 452 */ 453 public void setDialogParent(Component p) { 454 if (parent != null && parent != p) 455 throw new IllegalStateException(); 456 parent = p; 457 } 458 459 /** 460 * Get the screen resolution, in dots per inch, as provided 461 * by the default AWT toolkit. 462 * @return the screen resolution, in dots per inch 463 */ 464 public int getDotsPerInch() { 465 return DOTS_PER_INCH; 466 } 467 468 /** 469 * Get the help broker associated with this factory. 470 * @return the help broker associated with this factory 471 */ 472 public HelpBroker getHelpBroker() { 473 return helpBroker; 474 } 475 476 /** 477 * Get the resource bundle used to obtain the resources for the 478 * components create by this factory. 479 * @return the resource bundle used to obtain the resources for the 480 * components create by this factory 481 */ 482 public I18NResourceBundle getI18NResourceBundle() { 483 return i18n; 484 } 485 486 /** 487 * Get a keycode from the resource bundle. 488 * @param key the name of the resource to be returned 489 * @return the first character of the string that was found 490 */ 491 public int getI18NMnemonic(String key) { 492 String keyString = getI18NString(key); 493 KeyStroke keyStroke = KeyStroke.getKeyStroke(keyString); 494 if (keyStroke != null) 495 return keyStroke.getKeyCode(); 496 else 497 //System.err.println("WARNING: bad mnemonic keystroke for " + key + ": " + keyString); 498 return 0; 499 } 500 501 /** 502 * Get a color from the resource bundle. 503 * @param key the base name of the resource to be returned 504 * @return the color identified in the resource 505 */ 506 public Color getI18NColor(String key) { 507 String value = i18n.getString(key + ".clr"); 508 try { 509 if (value != null) 510 return Color.decode(value); 511 } 512 catch (Exception e) { 513 // ignore 514 } 515 return Color.BLACK; 516 } 517 518 /** 519 * Get a string from the resource bundle. 520 * @param key the name of the resource to be returned 521 * @return the string that was found 522 */ 523 public String getI18NString(String key) { 524 return i18n.getString(key); 525 } 526 527 /** 528 * Get a string from the resource bundle. 529 * @param key the name of the resource to be returned 530 * @param arg an argument to be formatted into the result using 531 * {@link java.text.MessageFormat#format} 532 * @return the formatted string 533 */ 534 public String getI18NString(String key, Object arg) { 535 return i18n.getString(key, arg); 536 } 537 538 /** 539 * Get a string from the resource bundle. 540 * @param key the name of the resource to be returned 541 * @param args an array of arguments to be formatted into the result using 542 * {@link java.text.MessageFormat#format} 543 * @return the formatted string 544 */ 545 public String getI18NString(String key, Object[] args) { 546 return i18n.getString(key, args); 547 } 548 549 /** 550 * Set the help ID for the context-sensitive help for a component. 551 * @param comp the component for which to set the help ID 552 * @param helpID the help ID identifying the context sensitive help for 553 * the component 554 */ 555 public void setHelp(final Component comp, final String helpID) { 556 if (helpID == null) 557 throw new NullPointerException(); 558 559 ContextHelpManager.setHelpIDString(comp, helpID); 560 561 if (comp instanceof JDialog) { 562 JDialog d = (JDialog) comp; 563 ContextHelpManager.setHelpIDString(d.getRootPane(), helpID); 564 Desktop.addHelpDebugListener(d); 565 566 final JComponent rootPane = d.getRootPane(); 567 KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0, false); 568 rootPane.registerKeyboardAction(new ActionListener(){ 569 @Override 570 public void actionPerformed(ActionEvent e) { 571 if (helpBroker != null){ 572 helpBroker.displayCurrentID(ContextHelpManager.getHelpIDString(rootPane)); 573 } 574 } 575 }, keystroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 576 577 } 578 else{ 579 if (comp instanceof JComponent){ 580 KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0, false); 581 ((JComponent)comp).registerKeyboardAction(new ActionListener(){ 582 583 @Override 584 public void actionPerformed(ActionEvent e) { 585 if (helpBroker != null){ 586 helpBroker.displayCurrentID(ContextHelpManager.getHelpIDString(comp)); 587 } 588 } 589 }, keystroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 590 } 591 592 } 593 594 } 595 596 /** 597 * Set a tool tip for a component from a resource in the factory's resource 598 * bundle. <br> 599 * By convention, tool tip resources end in ".tip". Most 600 * components created by this factory will already have a tool tip set, so 601 * this method need not be called for them. <br> 602 * Also, the component's accessible description text will automatically 603 * be set to the supplied tooltip text.<br> 604 * The resources used are: 605 * <table> 606 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the component 607 * </table> 608 * @param c the component for which to set the tool tip 609 * @param uiKey the base name of the resource to be used 610 */ 611 public void setToolTip(JComponent c, String uiKey) { 612 String text = getI18NString(uiKey + ".tip"); 613 c.setToolTipText(text); 614 615 // workaround - tooltip doesn't get copied from this component 616 // see JComponent.AccessibleJComponent.getToolTipText() 617 c.getAccessibleContext().setAccessibleDescription(text); 618 } 619 620 /** 621 * Sets only the accessible description for the given context, using the 622 * given key. 623 * <table> 624 * <tr><td><i>uiKey</i>.desc <td>accessible description 625 * </table> 626 * @param c the component to modify 627 * @param uiKey the base name of the resource to be used 628 * @see #setAccessibleDescription(AccessibleContext,String) 629 */ 630 public void setAccessibleDescription(Component c, String uiKey) { 631 setAccessibleDescription(c.getAccessibleContext(), uiKey); 632 } 633 634 /** 635 * Sets only the accessible description for the given context, using the 636 * given key. 637 * <table> 638 * <tr><td><i>uiKey</i>.desc <td>accessible description 639 * </table> 640 * @param c the context object to modify 641 * @param uiKey the base name of the resource to be used 642 */ 643 public void setAccessibleDescription(AccessibleContext c, String uiKey) { 644 String text = getI18NString(uiKey + ".desc"); 645 c.setAccessibleDescription(text); 646 } 647 648 /** 649 * Sets only the accessible name for the given context, using the 650 * given key. 651 * @param c the component object to modify 652 * @param uiKey the base name of the resource to be used 653 * @see #setAccessibleName(AccessibleContext,String) 654 */ 655 public void setAccessibleName(Component c, String uiKey) { 656 setAccessibleName(c.getAccessibleContext(), uiKey); 657 } 658 659 /** 660 * Sets only the accessible name for the given context, using the 661 * given key. 662 * <table> 663 * <tr><td><i>uiKey</i>.name <td>accessible name 664 * </table> 665 * @param c the context object to modify 666 * @param uiKey the base name of the resource to be used 667 */ 668 public void setAccessibleName(AccessibleContext c, String uiKey) { 669 String text = getI18NString(uiKey + ".name"); 670 c.setAccessibleName(text); 671 } 672 673 /** 674 * Sets the accessible name and description for the given 675 * component. 676 * @param c the component object to modify 677 * @param uiKey the base name of the resource to be used 678 * @see #setAccessibleInfo(AccessibleContext,String) 679 */ 680 public void setAccessibleInfo(Component c, String uiKey) { 681 setAccessibleInfo(c.getAccessibleContext(), uiKey); 682 } 683 684 /** 685 * Sets the accessibility name and description for the given context 686 * using the given key as the base. 687 * The resources used are: 688 * <table> 689 * <tr><td><i>uiKey</i>.name <td>accessible name 690 * <tr><td><i>uiKey</i>.desc <td>accessible description text 691 * </table> 692 * @param c the context object to modify 693 * @param uiKey the base name of the resource to be used 694 */ 695 public void setAccessibleInfo(AccessibleContext c, String uiKey) { 696 setAccessibleDescription(c, uiKey); 697 setAccessibleName(c, uiKey); 698 } 699 700 701 //---------------------------------------------------------------------------- 702 // 703 // borders 704 705 /** 706 * Create a titled border, using a resource to specify the title. <br> 707 * The resource used is: 708 * <table> 709 * <tr><td><i>uiKey</i>.bdr <td>the text for the title 710 * </table> 711 * @param uiKey the base name of the resource to be used 712 * @return the border that was created 713 */ 714 public Border createTitledBorder(String uiKey) { 715 return BorderFactory.createTitledBorder(null, getI18NString(uiKey + ".bdr"), TitledBorder.LEADING, TitledBorder.DEFAULT_JUSTIFICATION, getBaseFont(), Colors.TEXT_COLOR.getValue()); 716 } 717 718 //---------------------------------------------------------------------------- 719 // 720 // white space 721 722 /** 723 * Create a horizontal filler that expands to fill the available space. 724 * The name of the glue component will be set to <i>uikey</i>. No resource 725 * strings are required at this time. 726 * @param uiKey the base name of the resource to be used 727 * @return a filler component that expands to fill the available space 728 */ 729 public Component createHorizontalGlue(String uiKey) { 730 Component c = Box.createHorizontalGlue(); 731 c.setName(uiKey); 732 c.setFocusable(false); 733 return c; 734 } 735 736 /** 737 * Create a filler that expands to fill the available space. 738 * @param uiKey the base name of the resource to be used 739 * @return a filler component that expands to fill the available space 740 */ 741 public Component createGlue(String uiKey) { 742 Component c = Box.createGlue(); 743 c.setName(uiKey); 744 c.setFocusable(false); 745 return c; 746 } 747 748 749 /** 750 * Create a horizontal filler of a given width. 751 * @param width the desired width of the filler component 752 * @return a filler component of a given width 753 */ 754 public Component createHorizontalStrut(int width) { 755 Component c = Box.createHorizontalStrut(width); 756 c.setFocusable(false); 757 return c; 758 } 759 760 761 //---------------------------------------------------------------------------- 762 // 763 // buttons 764 765 /** 766 * Create a button, using resources to specify the name and the tool tip. <br> 767 * The resources used are: 768 * <table> 769 * <tr><td><i>uiKey</i>.btn <td>the name for the button 770 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 771 * </table> 772 * In addition, the name of the button and the action command 773 * for the button is set to <i>uiKey</i>. 774 * @param uiKey the base name of the resources to be used 775 * @return the button that was created 776 * @see #createHelpButton 777 * @see #createIconButton 778 */ 779 public JButton createButton(String uiKey) { 780 JButton b = new JButton(getI18NString(uiKey + ".btn")); 781 b.setActionCommand(uiKey); 782 b.setName(uiKey); 783 setMnemonic(b, uiKey); 784 setToolTip(b, uiKey); 785 return b; 786 } 787 788 /** 789 * Create a button based on the information in an Action. 790 * @param a the Action for which to define the button 791 * @return the button that was created 792 */ 793 public JButton createButton(Action a) { 794 JButton b = new JButton(a); 795 b.setName((String) (a.getValue(Action.NAME))); 796 return b; 797 } 798 799 /** 800 * Create a button containing an Icon. 801 * @param uiKey the base name of the resource to be used 802 * @param icon the icon to appear in the button 803 * @return the button that was created 804 */ 805 public JButton createButton(String uiKey, Icon icon) { 806 JButton b = new JButton(icon); 807 b.setName(uiKey); 808 setMnemonic(b, uiKey); 809 setToolTip(b, uiKey); 810 return b; 811 } 812 813 /** 814 * Create a button, using resources to specify the name and the tool tip, 815 * and with a specified ActionListener. <br> 816 * The resources used are: 817 * <table> 818 * <tr><td><i>uiKey</i>.btn <td>the name for the button 819 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 820 * </table> 821 * In addition, the name of the button and the action command 822 * for the button is set to <i>uiKey</i>. 823 * @param uiKey the base name of the resources to be used 824 * @param l the ActionListener to be add to the button 825 * @return the button that was created 826 */ 827 public JButton createButton(String uiKey, ActionListener l) { 828 JButton b = createButton(uiKey); 829 b.addActionListener(l); 830 return b; 831 } 832 833 /** 834 * Create a button, using resources to specify the name and the tool tip, 835 * and with a specified ActionListener and action command. <br> 836 * The resources used are: 837 * <table> 838 * <tr><td><i>uiKey</i>.btn <td>the name for the button 839 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 840 * </table> 841 * In addition, the name of the button is set to <i>uiKey</i>. 842 * @param uiKey the base name of the resources to be used 843 * @param l the ActionListener to be add to the button 844 * @param cmd the action command to be set for the button 845 * @return the button that was created 846 */ 847 public JButton createButton(String uiKey, ActionListener l, String cmd) { 848 JButton b = createButton(uiKey); 849 b.setActionCommand(cmd); 850 b.addActionListener(l); 851 return b; 852 } 853 854 /** 855 * Constant to identify the cancellation option. 856 */ 857 public static final String CANCEL = "cancel"; 858 859 /** 860 * Special method to create a cancel button. Differs from a 861 * standard button because it does not require a mnemonic, per 862 * the Java Look and Feel standard. 863 * @param uiKey key to use to get the tooltip with 864 * @return the button that was created 865 */ 866 public JButton createCancelButton(String uiKey) { 867 return createCancelButton(uiKey, closeListener); 868 } 869 870 /** 871 * Special method to create a cancel button. Differs from a 872 * standard button because it does not require a mnemonic, per 873 * the Java Look and Feel standard. 874 * @param uiKey key to use to get the tooltip with 875 * @param l listener to attach to the created button 876 * @return the button that was created 877 */ 878 public JButton createCancelButton(String uiKey, ActionListener l) { 879 JButton b; 880 881 I18NResourceBundle save_i18n = i18n; 882 try { 883 i18n = local_i18n; 884 b = new JButton(getI18NString("uif.cancel.btn")); 885 // no mnemonic for Cancel buttons 886 } 887 finally { 888 i18n = save_i18n; 889 } 890 891 b.setActionCommand(CANCEL); 892 b.addActionListener(l); 893 b.setName(uiKey); 894 setToolTip(b, uiKey); 895 return b; 896 } 897 898 /** 899 * Create a Close button, that will close the containing window when pressed, 900 * using a resource to specify the information for the button. <br> 901 * The resources used are: 902 * <table> 903 * <tr><td><i>uiKey</i>.btn <td>the name for the button 904 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the button 905 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 906 * </table> 907 * In addition, the name of the button is set to <i>uiKey</i>. 908 * @param uiKey the base name of the resources to be used 909 * @return the button that was created 910 * @see #createButton 911 */ 912 public JButton createCloseButton(String uiKey) { 913 return createCloseButton(uiKey, true); 914 } 915 916 /** 917 * Create a Close button, that will close the containing window when pressed, 918 * using a resource to specify the information for the button. <br> 919 * The resources used are: 920 * <table> 921 * <tr><td><i>uiKey</i>.btn <td>the name for the button 922 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the button, if required 923 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 924 * </table> 925 * In addition, the name of the button is set to <i>uiKey</i>. 926 * @param uiKey the base name of the resources to be used 927 * @param needMnemonic a boolean indicating whether or not a mnemonic should be 928 * set on the button. If the button is going to be the default button for a 929 * dialog, it does not need a mnemonic. 930 * @return the button that was created 931 * @see #createButton 932 */ 933 public JButton createCloseButton(String uiKey, boolean needMnemonic) { 934 JButton b = new JButton(getI18NString(uiKey + ".btn")); 935 b.setName(uiKey); 936 if (needMnemonic) 937 setMnemonic(b, uiKey); 938 setToolTip(b, uiKey); 939 b.addActionListener(closeListener); 940 return b; 941 } 942 943 /** 944 * Create a Help button, that will display a specific help topic when pressed, 945 * using a resource to specify the tool tip for the button. <br> 946 * The resource used is: 947 * <table> 948 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 949 * </table> 950 * In addition, the name of the button is set to <i>uiKey</i>. 951 * @param uiKey the base name of the resources to be used 952 * @param helpID the help ID for the help topic to be displayed when the 953 * button is pressed 954 * @return the button that was created 955 * @see #createButton 956 */ 957 public JButton createHelpButton(String uiKey, final String helpID) { 958 JButton hb = createButton(uiKey); 959 hb.addActionListener(new ActionListener() { 960 @Override 961 public void actionPerformed(ActionEvent e) { 962 if (helpBroker != null) { 963 helpBroker.displayCurrentID(helpID); 964 } 965 } 966 }); 967 968 return hb; 969 } 970 971 /** 972 * Create a button containing an icon, using resources to specify the 973 * icon image and the tool tip. <br> 974 * The resources used are: 975 * <table> 976 * <tr><td><i>uiKey</i>.icon <td>the name of the resource for the icon image 977 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 978 * </table> 979 * @param uiKey the base name of the resource to be used 980 * @return the button that was created 981 */ 982 public JButton createIconButton(String uiKey) { 983 JButton b = createButton(uiKey, createIcon(uiKey)); 984 b.setBorder(BorderFactory.createEmptyBorder()); 985 return b; 986 } 987 988 /** 989 * Create a button containing an icon, using resources to specify the 990 * icon image and the tool tip. <br> 991 * The resources used are: 992 * <table> 993 * <tr><td><i>uiKey</i>.icon <td>the name of the resource for the icon image 994 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 995 * </table> 996 * @param uiKey the base name of the resource to be used 997 * @param l the action listener to attach to the new button 998 * @return the button that was created 999 */ 1000 public JButton createIconButton(String uiKey, ActionListener l) { 1001 JButton b = createButton(uiKey, createIcon(uiKey)); 1002 b.addActionListener(l); 1003 return b; 1004 } 1005 1006 // note this uses local_i18n, not the client i18n 1007 private JButton createOptionButton(String uiKey) { 1008 I18NResourceBundle save_i18n = i18n; 1009 try { 1010 i18n = local_i18n; 1011 JButton b = createButton(uiKey, new ActionListener() { 1012 public void actionPerformed(ActionEvent e) { 1013 Component c = (Component) (e.getSource()); 1014 JOptionPane op = (JOptionPane) SwingUtilities.getAncestorOfClass(JOptionPane.class, c); 1015 op.setValue(c); // JOptionPane expects the value to be set to the selected button 1016 op.setVisible(false); 1017 } 1018 }); 1019 return b; 1020 } 1021 finally { 1022 i18n = save_i18n; 1023 } 1024 } 1025 1026 /** 1027 * Create a radio button, using resources to specify the name and tool tip. <br> 1028 * The button is initially set to <code>false</code>. 1029 * The resources used are: 1030 * <table> 1031 * <tr><td><i>uiKey</i>.rb <td>the label for the button 1032 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 1033 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the button 1034 * </table> 1035 * In addition, the name of the button is set to <i>uiKey</i>. 1036 * @param uiKey the base name of the resources to be used 1037 * @param group the group to which the check box will be added 1038 * @return the radio button that was created 1039 * @see #createButton 1040 * @see #createCheckBox 1041 */ 1042 public JRadioButton createRadioButton(String uiKey, ButtonGroup group) { 1043 String text = getI18NString(uiKey + ".rb"); 1044 JRadioButton btn = new JRadioButton(text, true); 1045 btn.setName(uiKey); 1046 btn.setSelected(false); // workaround Merlin bug 1047 setMnemonic(btn, uiKey); 1048 setToolTip(btn, uiKey); 1049 group.add(btn); 1050 return btn; 1051 } 1052 1053 /** 1054 * Set the mnemonic a button. 1055 * The resources used are: 1056 * <table> 1057 * <tr><td><i>uiKey</i>.mne <td>The keystroke to use 1058 * </table> 1059 * @param b the button to modify 1060 * @param uiKey the base name of the resources to be used 1061 * @see javax.swing.KeyStroke 1062 */ 1063 public void setMnemonic(AbstractButton b, String uiKey) { 1064 // NOTE: Swing is misleading; it uses an integer value for the mnemonic 1065 // but according to SwingUtilities.findDisplayedMnemonicIndex it is always 1066 // the literal character for the mnemonic, and not anything fancy like 1067 // an integer keycode 1068 int mne = getI18NMnemonic(uiKey + ".mne"); 1069 if (mne != 0) 1070 b.setMnemonic(mne); 1071 } 1072 1073 //---------------------------------------------------------------------------- 1074 // 1075 // check boxes 1076 1077 /** 1078 * Create a check box, using resources to specify the name and the tool tip. <br> 1079 * The resources used are: 1080 * <table> 1081 * <tr><td><i>uiKey</i>.ckb <td>the name for the check box 1082 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 1083 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the button 1084 * </table> 1085 * In addition, the name of the check box is set to <i>uiKey</i>. 1086 * @param uiKey the base name of the resources to be used 1087 * @return the check box that was created 1088 * @see #createCheckBoxMenuItem 1089 */ 1090 public JCheckBox createCheckBox(String uiKey) { 1091 return createCheckBox(uiKey, false, null); 1092 } 1093 1094 /** 1095 * Create a check box, using resources to specify the name and the tool tip. <br> 1096 * The resources used are: 1097 * <table> 1098 * <tr><td><i>uiKey</i>.ckb <td>the name for the check box 1099 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 1100 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the button 1101 * </table> 1102 * In addition, the name of the check box is set to <i>uiKey</i>. 1103 * @param uiKey the base name of the resources to be used 1104 * @param state the initial state of the check box 1105 * @return the check box that was created 1106 * @see #createCheckBoxMenuItem 1107 */ 1108 public JCheckBox createCheckBox(String uiKey, boolean state) { 1109 return createCheckBox(uiKey, state, null); 1110 } 1111 1112 /** 1113 * Create a check box, using resources to specify the name and the tool tip, 1114 * within a specified button group. <br> 1115 * The resources used are: 1116 * <table> 1117 * <tr><td><i>uiKey</i>.ckb <td>the name for the check box 1118 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the button 1119 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the button 1120 * </table> 1121 * In addition, the name of the check box is set to <i>uiKey</i>. 1122 * @param uiKey the base name of the resources to be used 1123 * @param state the initial state of the check box 1124 * @param group the group to which the check box will be added 1125 * @return the check box that was created 1126 */ 1127 public JCheckBox createCheckBox(String uiKey, boolean state, ButtonGroup group) { 1128 String ckbKey = uiKey + ".ckb"; 1129 JCheckBox b = new JCheckBox(getI18NString(ckbKey), state); 1130 b.setName(uiKey); 1131 if (group != null) 1132 group.add(b); 1133 setMnemonic(b, uiKey); 1134 setToolTip(b, uiKey); 1135 return b; 1136 } 1137 1138 1139 //---------------------------------------------------------------------------- 1140 // 1141 // choice lists 1142 1143 /** 1144 * Create a choice item, using resources to specify the choices and the 1145 * tool tip. <br> 1146 * The resources used are: 1147 * <table> 1148 * <tr><td><i>uiKey</i>.<i>choiceKeys<sub>i</sub></i>.chc <td>the choice to appear in the item, for 0 <= i < choiceKeys.length 1149 * <tr><td><i>uiKey</i>.name <td>the accessible name for the selector 1150 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the choice item 1151 * </table> 1152 * In addition, the name of the choice is set to <i>uiKey</i>. 1153 * Note: the choice item is created with the choices set to the names 1154 * of the resources used -- not the values. This means that the client can 1155 * examine and manipulate the choices, including the selected choice, 1156 * as location-independent resource names. A custom renderer is used to 1157 * ensure that the correctly localized value is displayed to the user. 1158 * @param uiKey the base name of the resources to be used for the menu 1159 * @param choiceKeys an array of strings used to construct the resource 1160 * names for the choices. 1161 * @return the choice item that was created 1162 * @see #createLiteralChoice 1163 */ 1164 public JComboBox createChoice(final String uiKey, final String[] choiceKeys) { 1165 return createChoice(uiKey, choiceKeys, false); 1166 } 1167 1168 /** 1169 * Same as the two parameter <code>createChoice</code>, except you can 1170 * make this an mutable choice component (freeform editing of the 1171 * response). If the component is to be editable, an additional 1172 * <i>uiKey</i>.ed resource is needed to set the component name of the 1173 * editable field which will be onscreen. 1174 * @param uiKey the base name of the resources to be used for the menu 1175 * @param choiceKeys an array of strings used to construct the resource 1176 * names for the choices. 1177 * @param editable True if the choice component should allow freeform 1178 * editing of the response. 1179 * @return a choice box with the attributes indicated by the parameters 1180 * @see #createChoice(String,String[]) 1181 */ 1182 public JComboBox createChoice(final String uiKey, final String[] choiceKeys, boolean editable) { 1183 // create a cache of the presentation string, for use when 1184 // rendering, but otherwise, let the JComboBox work in terms of the 1185 // choiceKeys 1186 final String[] choices = new String[choiceKeys.length]; 1187 for (int i = 0; i < choices.length; i++) 1188 choices[i] = getI18NString(uiKey + "." + choiceKeys[i] + ".chc"); 1189 1190 JComboBox choice = new JComboBox(choiceKeys); 1191 choice.setName(uiKey); 1192 setToolTip(choice, uiKey); 1193 setAccessibleName(choice, uiKey); 1194 1195 choice.setEditable(editable); 1196 if (editable) { 1197 Component editComp = choice.getEditor().getEditorComponent(); 1198 if (editComp instanceof Accessible) { 1199 if (editComp.getName() == null) 1200 editComp.setName(uiKey + ".ed"); 1201 AccessibleContext ac = choice.getAccessibleContext(); 1202 AccessibleContext ed_ac = editComp.getAccessibleContext(); 1203 ed_ac.setAccessibleName(ac.getAccessibleName()); 1204 ed_ac.setAccessibleDescription(ac.getAccessibleDescription()); 1205 } 1206 } 1207 1208 choice.setRenderer(new DefaultListCellRenderer() { 1209 public Component getListCellRendererComponent(JList list, Object o, int index, 1210 boolean isSelected, boolean cellHasFocus) { 1211 Object c = o; 1212 for (int i = 0; i < choiceKeys.length; i++) { 1213 if (choiceKeys[i] == o) { 1214 c = choices[i]; 1215 break; 1216 } 1217 } 1218 return super.getListCellRendererComponent(list, c, index, isSelected, cellHasFocus); 1219 } 1220 }); 1221 1222 return choice; 1223 } 1224 1225 /** 1226 * Create an empty choice item, using a resource to specify the tool tip. <br> 1227 * The resource used is: 1228 * <table> 1229 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the choice item 1230 * </table> 1231 * In addition, the name of the choice is set to <i>uiKey</i>. 1232 * @param uiKey the base name of the resources to be used for the menu 1233 * @return the choice component that was created 1234 */ 1235 public JComboBox createChoice(String uiKey) { 1236 return createChoice(uiKey, false); 1237 } 1238 1239 /** 1240 * Same as single parameter version, except you can select a 1241 * component that allows freeform editing of the user's response. 1242 * @param uiKey the base name of the resources to be used for the menu 1243 * @param editable True if the user should be allowed to edit the 1244 * response. 1245 * @return the choice component that was created 1246 * @see #createChoice(String) 1247 */ 1248 public JComboBox createChoice(String uiKey, boolean editable) { 1249 return createChoice(uiKey, editable, (JLabel) null); 1250 } 1251 1252 /** 1253 * Same as the one parameter version, except a label can be 1254 * associated with this component. This is to support accessibility. 1255 * @param uiKey the base name of the resources to be used for the menu 1256 * @param label Label to associate with this component 1257 * @return the choice component that was created 1258 * @see #createChoice(String) 1259 * @see javax.swing.JLabel#setLabelFor 1260 */ 1261 public JComboBox createChoice(String uiKey, JLabel label) { 1262 return createChoice(uiKey, false, label); 1263 } 1264 1265 /** 1266 * Combination of the two parameter methods, allowing you to select 1267 * a mutable response and associate a label. 1268 * @param uiKey the base name of the resources to be used for the menu 1269 * @param editable True if the user should be allowed to edit the 1270 * response. 1271 * @param label Label to associate with this component 1272 * @return a choice box with the attributes indicated by the parameters 1273 * @see #createChoice(String,JLabel) 1274 * @see #createChoice(String,boolean) 1275 * @see #createChoice(String) 1276 * @see javax.swing.JLabel#setLabelFor 1277 */ 1278 public JComboBox createChoice(String uiKey, boolean editable, JLabel label) { 1279 JComboBox choice = new JComboBox(); 1280 choice.setName(uiKey); 1281 setToolTip(choice, uiKey); 1282 1283 if (label != null) 1284 label.setLabelFor(choice); 1285 else 1286 setAccessibleName(choice, uiKey); 1287 1288 choice.setEditable(editable); 1289 if (editable) { 1290 Component editComp = choice.getEditor().getEditorComponent(); 1291 if (editComp instanceof Accessible) { 1292 if (editComp.getName() == null) 1293 editComp.setName(uiKey + ".ed"); 1294 AccessibleContext ac = choice.getAccessibleContext(); 1295 AccessibleContext ed_ac = editComp.getAccessibleContext(); 1296 ed_ac.setAccessibleName(ac.getAccessibleName()); 1297 ed_ac.setAccessibleDescription(ac.getAccessibleDescription()); 1298 } 1299 } 1300 1301 return choice; 1302 } 1303 1304 /** 1305 * Create an choice item containing literal choices, 1306 * and using a resource to specify the tool tip. 1307 * The choices appear as given: for example, this method might be used to 1308 * create a choice item containing a set of filenames from which to choose. <br> 1309 * Note that if the choices are strings, they should probably be localized, and 1310 * if they are otherwise should probably be shown to the user using a renderer 1311 * which produces localized output. 1312 * The resource used is: 1313 * <table> 1314 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the choice item 1315 * </table> 1316 * In addition, the name of the choice is set to <i>uiKey</i>. 1317 * @param uiKey the base name of the resources to be used for the menu 1318 * @param choices the choices to appear in the choice item 1319 * @return the choice item that was created 1320 * @see #createChoice 1321 */ 1322 public JComboBox createLiteralChoice(String uiKey, Object[] choices) { 1323 JComboBox choice = new JComboBox(choices); 1324 choice.setName(uiKey); 1325 setToolTip(choice, uiKey); 1326 return choice; 1327 } 1328 1329 //---------------------------------------------------------------------------- 1330 // 1331 // icons, images etc 1332 1333 /** 1334 * Create an icon, using a resource to specify the image. <br> 1335 * The resource used is: 1336 * <table> 1337 * <tr><td><i>uiKey</i>.icon <td>the name of a resource containing the image 1338 * </table> 1339 * @param uiKey the base name of the resource to be used 1340 * @return the icon that was created 1341 * @throws MissingResourceException if the image resource cannot be found 1342 * @see #createIconButton 1343 */ 1344 public Icon createIcon(String uiKey) { 1345 return new ImageIcon(getIconURL(uiKey)); 1346 } 1347 1348 /** 1349 * Get the resource URL for an icon specified in a resource bundle. <br> 1350 * The resource used is: 1351 * <table> 1352 * <tr><td><i>uiKey</i>.icon <td>the name of a resource containing the image 1353 * </table> 1354 * @param uiKey the base name of the resource to be used 1355 * @return the URL for the resource obtained from the resource bundle 1356 * @throws MissingResourceException if the image resource cannot be found 1357 */ 1358 public URL getIconURL(String uiKey) { 1359 String r = getI18NString(uiKey + ".icon"); 1360 URL url = clientClass.getResource(r); 1361 if (url == null) 1362 throw new MissingResourceException(r, clientClass.getName(), r); 1363 return url; 1364 } 1365 1366 /** 1367 * Create a label containing an icon, using a resource to specify the 1368 * icon image. <br> 1369 * The resource used is: 1370 * <table> 1371 * <tr><td><i>uiKey</i>.icon <td>the name of the resource for the icon image 1372 * </table> 1373 * @param uiKey the base name of the resource to be used 1374 * @return the image that was created 1375 * @throws MissingResourceException if the image resource cannot be found 1376 * @see #createLabel 1377 */ 1378 public JLabel createIconLabel(String uiKey) { 1379 return new JLabel(createIcon(uiKey)); 1380 } 1381 1382 /** 1383 * Create an image from a named resource. 1384 * @param r The resource containing the image data. 1385 * @return the image that was created 1386 * @throws MissingResourceException if the image resource cannot be found 1387 */ 1388 public Image createImage(String r) { 1389 URL url = getClass().getResource(r); 1390 if (url == null) 1391 throw new MissingResourceException(r, clientClass.getName(), r); 1392 return Toolkit.getDefaultToolkit().getImage(url); 1393 } 1394 1395 //---------------------------------------------------------------------------- 1396 // 1397 // labels 1398 1399 /** 1400 * Create a label, using a resource to specify the text. <br> 1401 * The resource used is: 1402 * <table> 1403 * <tr><td><i>uiKey</i>.lbl <td>the text for the label 1404 * </table> 1405 * @param uiKey the base name of the resource to be used 1406 * @return the label that was created 1407 * @see #createIconLabel 1408 */ 1409 public JLabel createLabel(String uiKey) { 1410 return createLabel(uiKey, false); 1411 } 1412 1413 /** 1414 * Create a label, using a resource to specify the text and an optional mnemonic.<br> 1415 * The resource used is: 1416 * <table> 1417 * <tr><td><i>uiKey</i>.lbl <td>the text for the label 1418 * <tr><td><i>uiKey</i>.tip <td>the tooltip text for the label 1419 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the label 1420 * </table> 1421 * @param uiKey the base name of the resource to be used 1422 * @param need508 whether or not a mnemonic and tooltip should be set for this label 1423 * @return the label that was created 1424 * @see #createIconLabel 1425 */ 1426 public JLabel createLabel(String uiKey, boolean need508) { 1427 JLabel l = new JLabel(getI18NString(uiKey + ".lbl")); 1428 l.setName(uiKey); 1429 if (need508) { 1430 setToolTip(l, uiKey); 1431 l.setDisplayedMnemonic(getI18NMnemonic(uiKey + ".mne")); 1432 } 1433 return l; 1434 } 1435 1436 1437 //---------------------------------------------------------------------------- 1438 // 1439 // lists 1440 1441 /** 1442 * Create an input text field, using a resource to specify the tool tip. <br> 1443 * The resource used is: 1444 * <table> 1445 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 1446 * </table> 1447 1448 1449 /** 1450 * Create an empty list component. <br> 1451 * Note: list components do not currently support tool tips. 1452 * When they do, this method will use a resource to specify the tool tip. 1453 * The resources used are: 1454 * <table> 1455 * <tr><td><i>uiKey</i>.name <td>the accessible name of the list 1456 * <tr><td><i>uiKey</i>.desc <td>the accessible description of the list 1457 * </table> 1458 * @param uiKey the base name of the resource to be used (currently ignored) 1459 * @return the list that was created 1460 */ 1461 public JList createList(String uiKey) { 1462 JList list = new JList(); 1463 list.setName(uiKey); 1464 setAccessibleInfo(list, uiKey); 1465 return list; 1466 } 1467 1468 /** 1469 * Create a list component with a given data model. <br> 1470 * Note: list components do not currently support tool tips. 1471 * When they do, this method will use a resource to specify the tool tip. 1472 * The resources used are: 1473 * <table> 1474 * <tr><td><i>uiKey</i>.name <td>the accessible name of the list 1475 * <tr><td><i>uiKey</i>.desc <td>the accessible description of the list 1476 * </table> 1477 * @param uiKey the base name of the resource to be used (currently ignored) 1478 * @param model the data model for this list 1479 * @return the list that was created 1480 */ 1481 public JList createList(String uiKey, ListModel model) { 1482 JList list = new JList(model); 1483 list.setName(uiKey); 1484 setAccessibleInfo(list, uiKey); 1485 return list; 1486 } 1487 1488 //---------------------------------------------------------------------------- 1489 // 1490 // menus 1491 1492 /** 1493 * Create an empty menu bar, using resources to specify the accessible info.<br> 1494 * The resources used are: 1495 * <table> 1496 * <tr><td><i>uiKey</i>.name <td>the accessible name text 1497 * <tr><td><i>uiKey</i>.desc <td>accessible description text 1498 * </table> 1499 * @param uiKey the base name of the resource to be used 1500 * @return the menu bar that was created 1501 */ 1502 public JMenuBar createMenuBar(String uiKey) { 1503 JMenuBar mb = new JMenuBar(); 1504 mb.setName(uiKey); 1505 setAccessibleInfo(mb, uiKey); 1506 return mb; 1507 } 1508 1509 /** 1510 * Create an empty menu, using resources to specify the name and mnemonic. <br> 1511 * The resources used are: 1512 * <table> 1513 * <tr><td><i>uiKey</i>.menu <td>the display name of the menu 1514 * <tr><td><i>uiKey</i>.mne <td>the single character mnemonic for the menu 1515 * <tr><td><i>uiKey</i>.desc <td>accessible description text 1516 * </table> 1517 * @param uiKey the base name of the resource to be used 1518 * @return the menu that was created 1519 * @see #createPopupMenu 1520 */ 1521 public JMenu createMenu(String uiKey) { 1522 JMenu m = new JMenu(); 1523 initMenu(m, uiKey); 1524 return m; 1525 } 1526 1527 /** 1528 * Initialize an empty menu, using resources to specify the name and mnemonic. <br> 1529 * The resources used are: 1530 * <table> 1531 * <tr><td><i>uiKey</i>.menu <td>the display name of the menu 1532 * <tr><td><i>uiKey</i>.mne <td>the single character mnemonic for the menu 1533 * <tr><td><i>uiKey</i>.desc <td>accessible description text 1534 * </table> 1535 * @param m the menu the be initialized 1536 * @param uiKey the base name of the resource to be used 1537 * @see #createPopupMenu 1538 */ 1539 public void initMenu(JMenu m, String uiKey) { 1540 m.setName(uiKey); 1541 m.setText(getI18NString(uiKey + ".menu")); 1542 setMnemonic(m, uiKey); 1543 setAccessibleDescription(m, uiKey); 1544 } 1545 1546 /** 1547 * Create a menu, using actions to specify the menu items, 1548 * and using resources to specify the name and mnemonic. <br> 1549 * The resources used are: 1550 * <table> 1551 * <tr><td><i>uiKey</i>.menu <td>the display name of the menu 1552 * <tr><td><i>uiKey</i>.mne <td>the single character mnemonic for the menu 1553 * </table> 1554 * @param uiKey the base name of the resources to be used 1555 * @param actions the actions from which to create the menu items; 1556 * use null in the array to indicate if and where a separator is required 1557 * @return the menu that was created 1558 * @see #createMenuItem(Action) 1559 */ 1560 public JMenu createMenu(String uiKey, Action[] actions) { 1561 JMenu m = createMenu(uiKey); 1562 for (int i = 0; i < actions.length; i++) { 1563 Action action = actions[i]; 1564 if (action == null) 1565 m.addSeparator(); 1566 else 1567 m.add(createMenuItem(action)); 1568 } 1569 return m; 1570 } 1571 1572 /** 1573 * Create a menu using resources and an action listener to specify 1574 * the menu items, and using resources to specify the name and mnemonic. <br> 1575 * The resources used are: 1576 * <table> 1577 * <tr><td><i>uiKey</i>.menu <td>the display name of the menu 1578 * <tr><td><i>uiKey</i>.mne <td>the single character mnemonic for the menu 1579 * <tr><td><i>uiKey</i>.<i>actions<sub>i</sub></i>.mit <td>the text for the menu item, for 0 <= i < choiceKeys.length 1580 * <tr><td><i>uiKey</i>.<i>actions<sub>i</sub></i>.mne <td>the single character mnemonic for the menu item, for 0 <= i < choiceKeys.length 1581 * </table> 1582 * @param uiKey the base name of the resources to be used 1583 * @param actions the qualifying names for the resources for the 1584 * individual menu items; use null in the array to indicate if 1585 * and where a separator is required 1586 * @param l the action listener to be used for each menu item 1587 * @return the menu that was created 1588 * @see #createMenuItem(String, String, ActionListener) 1589 */ 1590 public JMenu createMenu(String uiKey, String[] actions, ActionListener l) { 1591 JMenu m = new JMenu(); 1592 initMenu(m, uiKey, actions, l); 1593 return m; 1594 } 1595 1596 /** 1597 * Initialize a menu using resources and an action listener to specify 1598 * the menu items, and using resources to specify the name and mnemonic. <br> 1599 * The resources used are: 1600 * <table> 1601 * <tr><td><i>uiKey</i>.menu <td>the display name of the menu 1602 * <tr><td><i>uiKey</i>.mne <td>the single character mnemonic for the menu 1603 * <tr><td><i>uiKey</i>.<i>actions<sub>i</sub></i>.mit <td>the text for the menu item, for 0 <= i < choiceKeys.length 1604 * <tr><td><i>uiKey</i>.<i>actions<sub>i</sub></i>.mne <td>the single character mnemonic for the menu item, for 0 <= i < choiceKeys.length 1605 * </table> 1606 * @param m the menu the be initialized 1607 * @param uiKey the base name of the resources to be used 1608 * @param actions the qualifying names for the resources for the 1609 * individual menu items; use null in the array to indicate if 1610 * and where a separator is required 1611 * @param l the action listener to be used for each menu item 1612 * @see #createMenuItem(String, String, ActionListener) 1613 */ 1614 public void initMenu(JMenu m, String uiKey, String[] actions, ActionListener l) { 1615 initMenu(m, uiKey); 1616 for (int i = 0; i < actions.length; i++) { 1617 String action = actions[i]; 1618 if (action == null) 1619 m.addSeparator(); 1620 else 1621 m.add(createMenuItem(uiKey, action, l)); 1622 } 1623 } 1624 1625 /** 1626 * Create an empty popup menu. 1627 * @param uiKey the base name of the resource to be used (currently ignored) 1628 * @return the popup menu that was created 1629 * @see #createMenu 1630 */ 1631 public JPopupMenu createPopupMenu(String uiKey) { 1632 return new JPopupMenu(/*getI18NString(uiKey + ".pop")*/); 1633 } 1634 1635 /** 1636 * Create an popup menu. 1637 * @param uiKey the base name of the resource to be used 1638 * @param actions the qualifying names for the resources for the 1639 * individual menu items; use null in the array to indicate if 1640 * and where a separator is required 1641 * @param l the action listener to be used for each menu item 1642 * @return the popup menu that was created 1643 * @see #createMenu 1644 */ 1645 public JPopupMenu createPopupMenu(String uiKey, String[] actions, ActionListener l) { 1646 JPopupMenu m = createPopupMenu(uiKey); 1647 for (int i = 0; i < actions.length; i++) { 1648 String action = actions[i]; 1649 if (action == null) 1650 m.addSeparator(); 1651 else 1652 m.add(createMenuItem(uiKey, action, l)); 1653 } 1654 return m; 1655 } 1656 1657 //---------------------------------------------------------------------------- 1658 // 1659 // menu items 1660 1661 /** 1662 * Create a menu item for an action. 1663 * The name of the item is set to the action name. 1664 * @param action from which to create the menu item 1665 * @return the menu item that was created 1666 * @see #createMenu(String, Action[]) 1667 */ 1668 public JMenuItem createMenuItem(Action action) { 1669 JMenuItem item = new JMenuItem(action); 1670 item.setName((String)(action.getValue(Action.NAME))); 1671 // could (should?) ensure everything is set correctly 1672 return item; 1673 } 1674 1675 /** 1676 * Create a menu item, using resources to specify the text and mnemonic. <br> 1677 * The resources used are: 1678 * <table> 1679 * <tr><td><i>uiKey</i>.<i>action</i>.mit <td>the text for the menu item 1680 * <tr><td><i>uiKey</i>.<i>action</i>.mne <td>the single character mnemonic for the menu item 1681 * </table> 1682 * @param uiKey the base name of the resources to be used 1683 * @param action the qualifying name for the resources for the menu item 1684 * @param l the action listener for the menu item 1685 * @return the menu item that was created 1686 * @see #createMenu(String, String[], ActionListener) 1687 */ 1688 public JMenuItem createMenuItem(String uiKey, String action, ActionListener l) { 1689 JMenuItem item = new JMenuItem(getI18NString(uiKey + "." + action + ".mit")); 1690 item.setActionCommand(action); 1691 item.addActionListener(l); 1692 item.setName(action); 1693 setMnemonic(item, uiKey + "." + action); 1694 return item; 1695 } 1696 1697 /** 1698 * Create a check box menu item, using resources to specify the 1699 * name and the tool tip. <br> 1700 * The resources used are: 1701 * <table> 1702 * <tr><td><i>uiKey</i>.<i>name</i>.ckb <td>the name for the menu item 1703 * <tr><td><i>uiKey</i>.<i>name</i>.tip <td>the tool tip for the menu item 1704 * </table> 1705 * In addition, the name of the check box is set to <i>uiKey</i>. 1706 * @param uiKey the base name of the resources to be used 1707 * @param name a qualifying name for the resources used for this menu item 1708 * @param state the initial state of the check box 1709 * @return the check box that was created 1710 */ 1711 public JCheckBoxMenuItem createCheckBoxMenuItem(String uiKey, String name, boolean state) { 1712 String uiKey_name = uiKey + "." + name; 1713 String ckbKey = uiKey_name + ".ckb"; 1714 JCheckBoxMenuItem b = new JCheckBoxMenuItem(getI18NString(ckbKey), state); 1715 b.setName(uiKey_name); 1716 setMnemonic(b, uiKey_name); 1717 setToolTip(b, uiKey_name); 1718 return b; 1719 } 1720 1721 /** 1722 * Create a Help menu item, that will display a specific help topic when pressed, 1723 * using resources to specify the name and mnemonic for the item. <br> 1724 * The resource used is: 1725 * <table> 1726 * <tr><td><i>uiKey</i>.mit <td>the text for the menu item 1727 * <tr><td><i>uiKey</i>.mne <td>the mnemonic for the menu item 1728 * </table> 1729 * In addition, the name of the choice is set to <i>uiKey</i>. 1730 * @param uiKey the base name of the resources to be used 1731 * @param helpID the help ID for the help topic to be displayed when the 1732 * button is pressed 1733 * @return the button that was created 1734 * @see #createButton 1735 */ 1736 public JMenuItem createHelpMenuItem(String uiKey, final String helpID) { 1737 JMenuItem mi = new JMenuItem(getI18NString(uiKey + ".mit")); 1738 setMnemonic(mi, uiKey); 1739 mi.addActionListener(new ActionListener() { 1740 @Override 1741 public void actionPerformed(ActionEvent e) { 1742 if (helpBroker != null) { 1743 helpBroker.displayCurrentID(helpID); 1744 } 1745 } 1746 }); 1747 1748 return mi; 1749 } 1750 1751 /** 1752 * Create a menu item for a literal string and a specified listener. 1753 * No mnemonic key nor descriptive action is added. 1754 * @param literal the text for the menu item 1755 * @param l the action listener to add to the menu item 1756 * @return the menu item that was created 1757 */ 1758 public JMenuItem createLiteralMenuItem(String literal, ActionListener l) { 1759 JMenuItem item = new JMenuItem(literal); 1760 item.addActionListener(l); 1761 return item; 1762 } 1763 1764 /** 1765 * Create a check box menu item, using resources to specify the 1766 * name and the tool tip. <br> 1767 * The resources used are: 1768 * <table> 1769 * <tr><td><i>uiKey</i>.<i>name</i>.ckb <td>the name for the menu item 1770 * <tr><td><i>uiKey</i>.<i>name</i>.tip <td>the tool tip for the menu item 1771 * </table> 1772 * In addition, the name of the radio button is set to <i>uiKey</i>. 1773 * @param uiKey the base name of the resources to be used 1774 * @param name a qualifying name for the resources used for this menu item 1775 * @return the check box that was created 1776 */ 1777 public JRadioButtonMenuItem createRadioButtonMenuItem(String uiKey, String name) { 1778 String uiKey_name = uiKey + "." + name; 1779 String radKey = uiKey_name + ".rad"; 1780 JRadioButtonMenuItem b = new JRadioButtonMenuItem(getI18NString(radKey)); 1781 b.setName(uiKey_name); 1782 setMnemonic(b, uiKey_name); 1783 setToolTip(b, uiKey_name); 1784 return b; 1785 } 1786 1787 //---------------------------------------------------------------------------- 1788 // 1789 // scrollpane 1790 1791 /** 1792 * Surround a component in a scroll pane. 1793 * The name of the scroll pane component is set to <code>c.getName()</code> 1794 * plus the <i>.sp</i> suffix. 1795 * @param c The component to put into the scroll pane. 1796 * @return a scroll pane component with the given component inside 1797 */ 1798 public JScrollPane createScrollPane(JComponent c) { 1799 JScrollPane sp = new JScrollPane(c); 1800 sp.setName(c.getName() == null ? "sp" : c.getName() + ".sp"); 1801 sp.setFocusable(false); 1802 return sp; 1803 } 1804 1805 /** 1806 * Same as the single argument version, with options for altering 1807 * the scrollbar appearance policy. 1808 * @param c The component to put into the scroll pane. 1809 * @param vsp vertical scrollbar policy setting 1810 * @param hsp horizontal scrollbar policy setting 1811 * @return a scroll pane component with the given component inside 1812 * @see javax.swing.ScrollPaneConstants 1813 * @see javax.swing.JScrollPane 1814 */ 1815 public JScrollPane createScrollPane(JComponent c, int vsp, int hsp) { 1816 JScrollPane sp = new JScrollPane(c, vsp, hsp); 1817 sp.setName(c.getName() == null ? "sp" : c.getName() + ".sp"); 1818 sp.setFocusable(false); 1819 return sp; 1820 } 1821 1822 //---------------------------------------------------------------------------- 1823 // 1824 // slider 1825 1826 /** 1827 * Create a slider, using resources to specify the the tool tip. <br> 1828 * The resource used is: 1829 * <table> 1830 * <tr><td><i>uiKey</i>.<i>name</i>.tip <td>the tool tip for the menu item 1831 * </table> 1832 * @param uiKey the base name of the resources to be used 1833 * @param min the minimum value for the slider 1834 * @param max the maximum value for the slider 1835 * @param value the initial value for the slider 1836 * @return the slider that was created 1837 */ 1838 public JSlider createSlider(String uiKey, int min, int max, int value) { 1839 JSlider s = new JSlider(min, max, value); 1840 setToolTip(s, uiKey); 1841 return s; 1842 } 1843 1844 //---------------------------------------------------------------------------- 1845 // 1846 // split pane 1847 1848 /** 1849 * Create an empty split pane with the given orientation. 1850 * @param orient The split's orientation. 1851 * @return The empty split pane component. 1852 * @see javax.swing.JSplitPane#VERTICAL_SPLIT 1853 * @see javax.swing.JSplitPane#HORIZONTAL_SPLIT 1854 */ 1855 public JSplitPane createSplitPane(int orient) { 1856 JSplitPane sp = new JSplitPane(orient); 1857 sp.setName("split"); 1858 setSplitPaneInfo(sp); 1859 return sp; 1860 } 1861 1862 /** 1863 * Create an empty split pane with the given components inside. 1864 * @param orient The split's orientation. 1865 * @param c1 first component (left) 1866 * @param c2 first component (right) 1867 * @return The populated split pane component. 1868 * @see javax.swing.JSplitPane 1869 * @see javax.swing.JSplitPane#VERTICAL_SPLIT 1870 * @see javax.swing.JSplitPane#HORIZONTAL_SPLIT 1871 */ 1872 public JSplitPane createSplitPane(int orient, Component c1, Component c2) { 1873 JSplitPane sp = new JSplitPane(orient, c1, c2); 1874 sp.setName("split"); 1875 setSplitPaneInfo(sp); 1876 return sp; 1877 } 1878 1879 private void setSplitPaneInfo(JSplitPane sp) { 1880 // set a11y info manually using local bundle 1881 AccessibleContext ac = sp.getAccessibleContext(); 1882 if (sp.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { 1883 ac.setAccessibleName(local_i18n.getString("uif.sp.hor.name")); 1884 ac.setAccessibleDescription(local_i18n.getString("uif.sp.hor.desc")); 1885 } 1886 else { 1887 ac.setAccessibleName(local_i18n.getString("uif.sp.vert.name")); 1888 ac.setAccessibleDescription(local_i18n.getString("uif.sp.vert.desc")); 1889 } 1890 } 1891 1892 //---------------------------------------------------------------------------- 1893 // 1894 // spinners - not accessible as of JDK 1.5, so it's commented out here! 1895 1896 /** 1897 * Create a spinner. 1898 * @param uiKey the base name of the resources to be used 1899 * @return a spinner component 1900 * The resources used are: 1901 * <table> 1902 * <tr><td><i>uiKey</i>.<code>name</code><td> the accessible name for the tab pane. 1903 * Where <code>name</code> is the literal string "name". 1904 * <tr><td><i>uiKey</i>.<code>tip</code><td> the accessible name for the tab pane. 1905 * Where <code>tip</code> is the literal string "tip". 1906 * </table> 1907 * The tooltip will automatically be transferred to the pane's accessible 1908 * description. Use <code>setAccessibleDescription()</code> to set it 1909 * independently. 1910 public JSpinner createSpinner(String uiKey, SpinnerModel model) { 1911 JSpinner s = new JSpinner(model); 1912 s.setName(uiKey); 1913 setAccessibleName(s, uiKey); 1914 setToolTip(s, uiKey); 1915 return s; 1916 } 1917 */ 1918 1919 1920 //---------------------------------------------------------------------------- 1921 // 1922 // tabbed paned 1923 1924 /** 1925 * Create an empty tabbed pane. 1926 * @param uiKey the base name of the resources to be used 1927 * @return an empty (no tabs) tabbed pane 1928 * The resources used are: 1929 * <table> 1930 * <tr><td><i>uiKey</i>.<code>name</code><td> the accessible name for the tab pane. 1931 * Where <code>name</code> is the literal string "name". 1932 * <tr><td><i>uiKey</i>.<code>tip</code><td> the accessible name for the tab pane. 1933 * Where <code>tip</code> is the literal string "tip". 1934 * </table> 1935 * The tooltip will automatically be transferred to the pane's accessible 1936 * description. Use <code>setAccessibleDescription()</code> to set it 1937 * independently. 1938 */ 1939 public JTabbedPane createTabbedPane(String uiKey) { 1940 JTabbedPane p = new JTabbedPane(); 1941 p.setName(uiKey); 1942 setAccessibleName(p, uiKey); 1943 setToolTip(p, uiKey); 1944 return p; 1945 } 1946 1947 /** 1948 * Create a tabbed pane with a given set of component panes, 1949 * using resources to determine the name and tool tip for each tab. <br> 1950 * The resources used are: 1951 * <table> 1952 * <tr><td><i>uiKey</i>.<i>name<sub>i</sub></i>.tab <td>the display name for the tab, 1953 * where <i>name<sub>i</sub></i> is the component name for children[i] 1954 * <tr><td><i>uiKey</i>.<i>name<sub>i</sub></i>.tip <td>the tool tip for the tab, 1955 * where <i>name<sub>i</sub></i> is the component name for children[i] 1956 * <tr><td><i>uiKey</i>.<code>name</code><td> the accessible name for the tab pane. 1957 * Where <code>name</code> is the literal string "name". 1958 * <tr><td><i>uiKey</i>.<code>tip</code><td> the accessible name for the tab pane. 1959 * Where <code>tip</code> is the literal string "tip". 1960 * </table> 1961 * The tooltip will automatically be transferred to the pane's accessible 1962 * description. Use <code>setAccessibleDescription()</code> to set it 1963 * independently. 1964 * @param uiKey the base name of the resources to be used 1965 * @param children an array of components to be added into the tabbed pane 1966 * @return the tabbed pane that was created 1967 * @see #setAccessibleDescription(Component,String) 1968 * @see #setAccessibleName(Component,String) 1969 * @see #setToolTip(JComponent,String) 1970 */ 1971 public JTabbedPane createTabbedPane(String uiKey, JComponent[] children) { 1972 JTabbedPane p = new JTabbedPane(); 1973 p.setName(uiKey); 1974 setAccessibleName(p, uiKey); 1975 for (int i = 0; i < children.length; i++) { 1976 JComponent child = children[i]; 1977 addTab(p, uiKey + "." + child.getName(), child); 1978 } 1979 setToolTip(p, uiKey); 1980 return p; 1981 } 1982 1983 /** 1984 * Add a component to a tabbed pane, using resources to specify 1985 * the name and the tool tip for the tab. <br> 1986 * The resources used are: 1987 * <table> 1988 * <tr><td><i>uiKey</i>.tab <td>the name for the tab 1989 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the tab 1990 * </table> 1991 * @param tPane the tabbed pane to which to add the component 1992 * @param uiKey the base name of the resources to be used 1993 * @param comp the component to be added 1994 */ 1995 public void addTab(JTabbedPane tPane, String uiKey, JComponent comp) { 1996 String name = getI18NString(uiKey + ".tab"); 1997 String tip = getI18NString(uiKey + ".tip"); 1998 tPane.addTab(name, null, comp, tip); 1999 2000 } 2001 2002 //---------------------------------------------------------------------------- 2003 // 2004 // tables 2005 2006 /** 2007 * Create a table with a given data model. 2008 * Resources used: 2009 * <table> 2010 * <tr><td><i>uiKey</i>.<code>name</code><td> the accessible name for the tab pane. 2011 * Where <code>name</code> is the literal string "name". 2012 * <tr><td><i>uiKey</i>.<code>tip</code><td> the accessible name for the tab pane. 2013 * Where <code>tip</code> is the literal string "tip". 2014 * </table> 2015 * The tooltip will automatically be transferred to the pane's accessible 2016 * description. Use <code>setAccessibleDescription()</code> to set it 2017 * independently. 2018 * @param uiKey the base name of the resources to be used (currently ignored) 2019 * @param model the data model for the table 2020 * @return the table that was created 2021 * @see #setAccessibleDescription(Component,String) 2022 * @see #setAccessibleName(Component,String) 2023 * @see #setToolTip(JComponent,String) 2024 */ 2025 public JTable createTable(String uiKey, TableModel model) { 2026 JTable tbl = new JTable(model); 2027 setAccessibleName(tbl, uiKey); 2028 setToolTip(tbl, uiKey); 2029 return tbl; 2030 } 2031 2032 //---------------------------------------------------------------------------- 2033 // 2034 // text fields, text areas etc 2035 2036 /** 2037 * Create a text field for use as a heading, using a resource to specify 2038 * the heading. <br> 2039 * The resource used is: 2040 * <table> 2041 * <tr><td><i>uiKey</i>.txt <td>the text for the heading 2042 * </table> 2043 * In addition, the name of the output field is set to <i>uiKey</i>. 2044 * @param uiKey the base name of the resource to be used 2045 * @return the text field that was created 2046 */ 2047 public JTextField createHeading(String uiKey) { 2048 String value = getI18NString(uiKey + ".txt"); 2049 JTextField tf = new JTextField(value, value.length()); 2050 tf.setName(uiKey); 2051 tf.setEditable(false); 2052 tf.setFont(tf.getFont().deriveFont(Font.BOLD)); 2053 tf.setBorder(BorderFactory.createEmptyBorder()); 2054 tf.setBackground(Colors.TRANSPARENT.color); 2055 tf.setOpaque(false); 2056 setAccessibleDescription(tf, uiKey); 2057 setAccessibleName(tf, uiKey); 2058 return tf; 2059 } 2060 2061 /** 2062 * Create an input text field, using a resource to specify the tool tip. <br> 2063 * The resource used is: 2064 * <table> 2065 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2066 * </table> 2067 * In addition, the name of the input field is set to <i>uiKey</i>. 2068 * By default, the input field is 10 characters wide. 2069 * @param uiKey the base name of the resource to be used 2070 * @return the input field that was created 2071 */ 2072 public JTextField createInputField(String uiKey) { 2073 return createInputField(uiKey, null); 2074 } 2075 2076 /** 2077 * Create an input text field, using a resource to specify the tool tip. <br> 2078 * The resource used is: 2079 * <table> 2080 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2081 * </table> 2082 * In addition, the name of the input field is set to <i>uiKey</i>. 2083 * By default, the input field is 10 characters wide. 2084 * @param uiKey the base name of the resource to be used 2085 * @param label the label to associate with this component 2086 * @return the input field that was created 2087 */ 2088 public JTextField createInputField(String uiKey, JLabel label) { 2089 return createInputField(uiKey, 10, label); 2090 } 2091 2092 /** 2093 * Create an input text field with a specified number of columns, 2094 * using a resource to specify the tool tip. <br> 2095 * The resource used is: 2096 * <table> 2097 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2098 * </table> 2099 * In addition, the name of the input field is set to <i>uiKey</i>. 2100 * @param uiKey the base name of the resource to be used 2101 * @param cols the default width of the field, in characters 2102 * @return the input field that was created 2103 * @see #createOutputField 2104 */ 2105 public JTextField createInputField(String uiKey, int cols) { 2106 return createInputField(uiKey, cols, null); 2107 } 2108 2109 /** 2110 * Create an input text field with a specified number of columns, 2111 * using a resource to specify the tool tip. <br> 2112 * The resource used is: 2113 * <table> 2114 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2115 * </table> 2116 * In addition, the name of the input field is set to <i>uiKey</i>. 2117 * @param uiKey the base name of the resource to be used 2118 * @param cols the default width of the field, in characters 2119 * @param label the label to associate with this component 2120 * @return the input field that was created 2121 * @see #createOutputField 2122 */ 2123 public JTextField createInputField(String uiKey, int cols, JLabel label) { 2124 JTextField tf = new JTextField("", cols) { 2125 public Dimension getMinimumSize() { 2126 return getPreferredSize(); 2127 } 2128 }; 2129 2130 if (label != null) 2131 label.setLabelFor(tf); 2132 else { 2133 // this should be setAccessibleName(tf, uiKey); but that will break too much code 2134 tf.setName(uiKey); 2135 //setAccessibleName(tf, uiKey); 2136 } 2137 2138 setToolTip(tf, uiKey); 2139 return tf; 2140 } 2141 2142 /** 2143 * Create a message area, using a resource to specify the content. 2144 * The message area will be transparent, uneditable, and word-wrapped. <br> 2145 * The resource used is: 2146 * <table> 2147 * <tr><td><i>uiKey</i>.txt <td>the text for the message area 2148 * </table> 2149 * @param uiKey the name of the resource to be used 2150 * @return the message area that was created 2151 */ 2152 public JTextArea createMessageArea(String uiKey) { 2153 return createLocalizedMessageArea(uiKey, getI18NString(uiKey + ".txt"), true); 2154 } 2155 2156 /** 2157 * Create a message area, using a resource to specify the content. 2158 * The message area will be transparent, uneditable, and word-wrapped. <br> 2159 * The resource used is: 2160 * <table> 2161 * <tr><td><i>uiKey</i>.txt <td>the text for the message area 2162 * <tr><td><i>uiKey</i>.name <td>accessible name 2163 * <tr><td><i>uiKey</i>.desc <td>accessible description text 2164 * </table> 2165 * @param uiKey the name of the resource to be used 2166 * @param arg an argument to be formatted into the content using 2167 * {@link java.text.MessageFormat#format} 2168 * @return the message area that was created 2169 */ 2170 public JTextArea createMessageArea(String uiKey, Object arg) { 2171 return createLocalizedMessageArea(uiKey, getI18NString(uiKey + ".txt", arg), true); 2172 } 2173 2174 2175 /** 2176 * Create a message area, using a resource to specify the content. 2177 * The message area will be transparent, uneditable, and word-wrapped. <br> 2178 * The resource used is: 2179 * <table> 2180 * <tr><td><i>uiKey</i>.txt <td>the text for the message area 2181 * <tr><td><i>uiKey</i>.name <td>accessible name 2182 * <tr><td><i>uiKey</i>.desc <td>accessible description text 2183 * </table> 2184 * @param uiKey the name of the resource to be used 2185 * @param args an array of arguments to be formatted into the content using 2186 * {@link java.text.MessageFormat#format} 2187 * @return the message area that was created 2188 */ 2189 public JTextArea createMessageArea(String uiKey, Object[] args) { 2190 return createLocalizedMessageArea(uiKey, getI18NString(uiKey + ".txt", args), true); 2191 } 2192 2193 /** 2194 * Only use this method if the origin of the message text is not coming from 2195 * a bundle. 2196 */ 2197 private JTextArea createLiteralMessageArea(String msg) { 2198 JTextArea txt = new JTextArea(msg); 2199 txt.setName("literal"); 2200 txt.setOpaque(false); 2201 txt.setEditable(false); 2202 txt.setLineWrap(true); 2203 txt.setWrapStyleWord(true); 2204 // The height is effectively ignored in the next line (just don't use 0.) 2205 // The text will be laid out, wrapping lines, for the width, and the 2206 // preferred height will thereby be determined accordingly. 2207 txt.setSize(new Dimension(7 * DOTS_PER_INCH, Integer.MAX_VALUE)); 2208 // override JTextArea focus traversal keys, resetting them to 2209 // the Component default (i.e. the same as for the parent.) 2210 txt.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); 2211 txt.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); 2212 AccessibleContext ac = txt.getAccessibleContext(); 2213 ac.setAccessibleName(local_i18n.getString("uif.message.name")); 2214 ac.setAccessibleDescription(local_i18n.getString("uif.message.desc")); 2215 return txt; 2216 } 2217 2218 2219 /** 2220 * @param std True if this area should be made accessible. 2221 */ 2222 private JTextArea createLocalizedMessageArea(String uiKey, String msg, boolean std) { 2223 JTextArea txt = new JTextArea(msg); 2224 txt.setName(uiKey); 2225 txt.setOpaque(false); 2226 txt.setBackground(Colors.TRANSPARENT.getValue()); 2227 txt.setEditable(false); 2228 txt.setLineWrap(true); 2229 txt.setWrapStyleWord(true); 2230 // The height is effectively ignored in the next line (just don't use 0.) 2231 // The text will be laid out, wrapping lines, for the width, and the 2232 // preferred height will thereby be determined accordingly. 2233 txt.setSize(new Dimension(7 * DOTS_PER_INCH, Integer.MAX_VALUE)); 2234 // override JTextArea focus traversal keys, resetting them to 2235 // the Component default (i.e. the same as for the parent.) 2236 txt.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); 2237 txt.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); 2238 if (std) { 2239 AccessibleContext ac = txt.getAccessibleContext(); 2240 ac.setAccessibleName(local_i18n.getString("uif.message.name")); 2241 ac.setAccessibleDescription(local_i18n.getString("uif.message.desc")); 2242 } 2243 else 2244 setAccessibleInfo(txt, uiKey); 2245 return txt; 2246 } 2247 2248 /** 2249 * Create an output text field, using a resource to specify the tool tip. <br> 2250 * The resource used is: 2251 * <table> 2252 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2253 * <tr><td><i>uiKey</i>.name <td>accessible name 2254 * </table> 2255 * In addition, the name of the output field is set to <i>uiKey</i>. 2256 * By default, the output field is empty and is 10 characters wide. 2257 * @param uiKey the base name of the resource to be used 2258 * @return the empty output field that was created 2259 * @see #createInputField 2260 */ 2261 public JTextField createOutputField(String uiKey) { 2262 return createOutputField(uiKey, "", 10, null, false); 2263 } 2264 2265 /** 2266 * Same as the single parameter version, except a label, which labels 2267 * this new component, will be set. 2268 * The label's <code>setLabelFor()</code> will be set. 2269 * @param uiKey the base name of the resource to be used 2270 * @param label the label which is labeling this field 2271 * @return the output field that was created 2272 * @see #createInputField(String) 2273 */ 2274 public JTextField createOutputField(String uiKey, JLabel label) { 2275 return createOutputField(uiKey, "", 10, label, false); 2276 } 2277 2278 /** 2279 * Create an output text field with a specified number of columns, 2280 * using a resource to specify the tool tip, 2281 * which can automaticly select contained text.<br> 2282 * The label's <code>setLabelFor()</code> will be set. 2283 * @param uiKey the base name of the resource to be used 2284 * @param label the label which is labeling this field 2285 * @param autoSelect automaticly select text containing in the field on focus 2286 * @return the output field that was created 2287 * @see #createInputField(String) 2288 */ 2289 public JTextField createOutputField(String uiKey, JLabel label, boolean autoSelect) { 2290 return createOutputField(uiKey, "", 10, label, autoSelect); 2291 } 2292 2293 /** 2294 * Create an output text field with a specified number of columns, 2295 * and using a resource to specify the tool tip. <br> 2296 * The resource used is: 2297 * <table> 2298 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2299 * <tr><td><i>uiKey</i>.name <td>accessible name 2300 * </table> 2301 * In addition, the name of the output field is set to <i>uiKey</i>. 2302 * The output field is initially empty. 2303 * @param uiKey the base name of the resource to be used 2304 * @param cols the default width of the field, in characters 2305 * @return the empty output field that was created 2306 */ 2307 public JTextField createOutputField(String uiKey, int cols) { 2308 return createOutputField(uiKey, "", cols, null, false); 2309 } 2310 2311 /** 2312 * Create an output text field with a specified number of columns, 2313 * using a resource to specify the tool tip, with an attached label. <br> 2314 * The resource used is: 2315 * <table> 2316 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2317 * <tr><td><i>uiKey</i>.name <td>accessible name 2318 * </table> 2319 * In addition, the name of the output field is set to <i>uiKey</i>. 2320 * The output field is initially empty. 2321 * @param uiKey the base name of the resource to be used 2322 * @param cols the default width of the field, in characters 2323 * @param label the label which is labeling this field 2324 * @return the empty output field that was created 2325 */ 2326 public JTextField createOutputField(String uiKey, int cols, JLabel label) { 2327 return createOutputField(uiKey, "", cols, label, false); 2328 } 2329 2330 /** 2331 * Create an output text field with a specified number of columns, 2332 * using a resource to specify the tool tip, with an attached label, 2333 * which can automaticly select contained text.<br> 2334 * The resource used is: 2335 * <table> 2336 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2337 * <tr><td><i>uiKey</i>.name <td>accessible name 2338 * </table> 2339 * In addition, the name of the output field is set to <i>uiKey</i>. 2340 * The output field is initially empty. 2341 * @param uiKey the base name of the resource to be used 2342 * @param cols the default width of the field, in characters 2343 * @param label the label which is labeling this field 2344 * @param autoSelect automaticly select text containing in the field on focus 2345 * @return the empty output field that was created 2346 */ 2347 public JTextField createOutputField(String uiKey, int cols, JLabel label, boolean autoSelect) { 2348 return createOutputField(uiKey, "", cols, label, autoSelect); 2349 } 2350 2351 /** 2352 * Create an output text field containing a specified value, 2353 * and using a resource to specify the tool tip. <br> 2354 * The resource used is: 2355 * <table> 2356 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2357 * <tr><td><i>uiKey</i>.name <td>accessible name 2358 * </table> 2359 * In addition, the name of the output field is set to <i>uiKey</i>. 2360 * By default, the output field is 10 characters wide. 2361 * @param uiKey the base name of the resource to be used 2362 * @param value the initial text to appear in the output field 2363 * @return the output field that was created 2364 */ 2365 public JTextField createOutputField(String uiKey, String value) { 2366 return createOutputField(uiKey, value, 10, null, false); 2367 } 2368 2369 /** 2370 * Create an output text field containing a specified value, 2371 * using a resource to specify the tool tip, 2372 * with an attached label. <br> 2373 * The resource used is: 2374 * <table> 2375 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2376 * <tr><td><i>uiKey</i>.name <td>accessible name 2377 * </table> 2378 * In addition, the name of the output field is set to <i>uiKey</i>. 2379 * By default, the output field is 10 characters wide. 2380 * @param uiKey the base name of the resource to be used 2381 * @param value the text to appear in the output field 2382 * @param label the label which is labeling this field 2383 * @return the output field that was created 2384 */ 2385 public JTextField createOutputField(String uiKey, String value, JLabel label) { 2386 return createOutputField(uiKey, value, 10, label, false); 2387 } 2388 2389 /** 2390 * Create an output text field containing a specified value, 2391 * with a specified number of columns, 2392 * and using a resource to specify the tool tip. <br> 2393 * The resource used is: 2394 * <table> 2395 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2396 * <tr><td><i>uiKey</i>.name <td>accessible name 2397 * </table> 2398 * In addition, the name of the output field is set to <i>uiKey</i>. 2399 * @param uiKey the base name of the resource to be used 2400 * @param value the text to appear in the output field 2401 * @param cols the default width of the field, in characters 2402 * @return the output field that was created 2403 */ 2404 public JTextField createOutputField(String uiKey, String value, int cols) { 2405 return createOutputField(uiKey, value, cols, null, false); 2406 } 2407 2408 /** 2409 * Create an output text field containing a specified value, 2410 * with a specified number of columns, 2411 * using a resource to specify the tool tip, 2412 * with a label referencing this new field.<br> 2413 * The resource used is: 2414 * <table> 2415 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2416 * <tr><td><i>uiKey</i>.name <td>accessible name 2417 * </table> 2418 * In addition, the name of the output field is set to <i>uiKey</i>. 2419 * @param uiKey the base name of the resource to be used 2420 * @param value the text to appear in the output field 2421 * @param cols the default width of the field, in characters 2422 * @param label the label which is labeling this field 2423 * @return the output field that was created 2424 */ 2425 public JTextField createOutputField(String uiKey, String value, int cols, JLabel label) { 2426 return createOutputField(uiKey, value, cols, label, false); 2427 } 2428 2429 /** 2430 * Create an output text field containing a specified value, 2431 * with a specified number of columns, 2432 * using a resource to specify the tool tip, 2433 * with a label referencing this new field, 2434 * which can automaticly select contained text.<br> 2435 * The resource used is: 2436 * <table> 2437 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the field 2438 * <tr><td><i>uiKey</i>.name <td>accessible name 2439 * </table> 2440 * In addition, the name of the output field is set to <i>uiKey</i>. 2441 * @param uiKey the base name of the resource to be used 2442 * @param value the text to appear in the output field 2443 * @param cols the default width of the field, in characters 2444 * @param label the label which is labeling this field 2445 * @param autoSelect automaticly select text containing in the field on focus 2446 * @return the output field that was created 2447 */ 2448 public JTextField createOutputField(String uiKey, String value, int cols, JLabel label, boolean autoSelect) { 2449 final JTextField tf = new JTextField(value, cols); 2450 tf.setName(uiKey); 2451 tf.setEditable(false); 2452 tf.setBackground(Colors.TRANSPARENT.getValue()); 2453 tf.setOpaque(false); 2454 if(autoSelect) 2455 tf.addFocusListener(new java.awt.event.FocusListener() { 2456 public void focusGained(java.awt.event.FocusEvent e) { 2457 tf.setSelectionStart(0); 2458 tf.setSelectionEnd(tf.getText().length()); 2459 } 2460 2461 public void focusLost(java.awt.event.FocusEvent e) { 2462 tf.setSelectionStart(0); 2463 tf.setSelectionEnd(0); 2464 } 2465 }); 2466 2467 if (label != null) 2468 label.setLabelFor(tf); 2469 else 2470 setAccessibleName(tf, uiKey); 2471 2472 setToolTip(tf, uiKey); 2473 // override JTextField focus traversal keys, resetting them to 2474 // the Component default (i.e. the same as for the parent.) 2475 tf.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); 2476 tf.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); 2477 return tf; 2478 } 2479 2480 /** 2481 * Create a text area, using a resource to specify the tool tip. <br> 2482 * The resource used is: 2483 * <table> 2484 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the text area 2485 * </table> 2486 * In addition, the name of the text area is set to <i>uiKey</i>. 2487 * @param uiKey the base name of the resource to be used 2488 * @return the text area that was created 2489 */ 2490 public JTextArea createTextArea(String uiKey) { 2491 return createTextArea(uiKey, null); 2492 } 2493 2494 /** 2495 * Create a text area, using a resource to specify the tool tip. <br> 2496 * The resource used is: 2497 * <table> 2498 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the text area 2499 * </table> 2500 * In addition, the name of the text area is set to <i>uiKey</i>. 2501 * @param uiKey the base name of the resource to be used 2502 * @param label the label that labels this text area. May be null. 2503 * @return the text area that was created 2504 */ 2505 public JTextArea createTextArea(String uiKey, JLabel label) { 2506 JTextArea t = new JTextArea() { 2507 public Dimension getPreferredScrollableViewportSize() { 2508 return new Dimension(100, 100); 2509 } 2510 }; 2511 t.setName(uiKey); 2512 2513 if (label != null) 2514 label.setLabelFor(t); 2515 else 2516 setAccessibleName(t, uiKey); 2517 2518 setToolTip(t, uiKey); 2519 return t; 2520 } 2521 2522 //---------------------------------------------------------------------------- 2523 // 2524 // progress bars 2525 2526 /** 2527 * Create a basic progress bar. 2528 * The resource used is: 2529 * <table> 2530 * <tr><td><i>uiKey</i>.name <td>accessible name 2531 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the text area 2532 * </table> 2533 * 2534 * @param uiKey the base name of the resource to be used 2535 * @param orient Value from <code>JProgressBar</code> 2536 * @return Returns a progress bar component with the specified attributes. 2537 * @see javax.swing.JProgressBar#VERTICAL 2538 * @see javax.swing.JProgressBar#HORIZONTAL 2539 */ 2540 public JProgressBar createProgressBar(String uiKey, int orient) { 2541 JProgressBar pb = new JProgressBar(orient); 2542 setToolTip(pb, uiKey); 2543 setAccessibleName(pb, uiKey); 2544 2545 return pb; 2546 } 2547 2548 /** 2549 * Create a basic progress bar. 2550 * The resources used are: 2551 * <table> 2552 * <tr><td><i>uiKey</i>.name <td>accessible name 2553 * <tr><td><i>uiKey</i>.tip <td>the tool tip for the text area 2554 * </table> 2555 * 2556 * @param uiKey the base name of the resource to be used 2557 * @param orient Value from <code>JProgressBar</code> 2558 * @param model Model to use for the progress bar. 2559 * @return Returns a progress bar component with the specified attributes. 2560 * @see javax.swing.JProgressBar#VERTICAL 2561 * @see javax.swing.JProgressBar#HORIZONTAL 2562 */ 2563 public JProgressBar createProgressBar(String uiKey, int orient, 2564 BoundedRangeModel model) { 2565 JProgressBar pb = createProgressBar(uiKey, orient); 2566 pb.setModel(model); 2567 2568 return pb; 2569 } 2570 2571 //---------------------------------------------------------------------------- 2572 // 2573 // toolbar 2574 2575 /** 2576 * Create an empty toolbar. 2577 * The resources used are: 2578 * <table> 2579 * <tr><td><i>uiKey</i>.name <td>accessible name 2580 * <tr><td><i>uiKey</i>.desc <td>accessible description text 2581 * </table> 2582 * @param uiKey Used to obtain accessibility info and name the component 2583 * @return the tool bar that was created 2584 */ 2585 public JToolBar createToolBar(String uiKey) { 2586 JToolBar tb = new JToolBar(); 2587 tb.setName(uiKey); 2588 setAccessibleInfo(tb, uiKey); 2589 2590 return tb; 2591 } 2592 2593 /** 2594 * Create a toolbar, using actions to specify the buttons, 2595 * and using resources to specify the name and mnemonic. <br> 2596 * The components on the toolbar which are derived from the actions will 2597 * have their accessible description set to the short description of the 2598 * action. 2599 * The resources used are: 2600 * <table> 2601 * <tr><td><i>uiKey</i>.name <td>accessible name 2602 * <tr><td><i>uiKey</i>.desc <td>accessible description text 2603 * </table> 2604 * @param uiKey used to obtain accessibility info and name the component 2605 * @param actions the actions from which to create the buttons; 2606 * use null in the array to indicate if and where a separator is required 2607 * @return the tool bar that was created 2608 * @see javax.swing.Action#SHORT_DESCRIPTION 2609 */ 2610 public JToolBar createToolBar(String uiKey, Action[] actions) { 2611 JToolBar tb = new JToolBar(); 2612 tb.setName(uiKey); 2613 setAccessibleInfo(tb, uiKey); 2614 for (int i = 0; i < actions.length; i++) { 2615 Action action = actions[i]; 2616 if (action == null) 2617 tb.addSeparator(); 2618 else { 2619 JButton b = tb.add(action); 2620 b.setName((String) (action.getValue(Action.NAME))); 2621 b.getAccessibleContext().setAccessibleName(b.getName()); 2622 } 2623 } 2624 return tb; 2625 } 2626 2627 /** 2628 * Create a toolbar, using buttons. 2629 * The resources used are: 2630 * <table> 2631 * <tr><td><i>uiKey</i>.name <td>accessible name 2632 * <tr><td><i>uiKey</i>.desc <td>accessible description text 2633 * </table> 2634 * @param uiKey used to obtain accessibility info and name the component 2635 * @param buttons the buttons to be included in the bar.<br> 2636 * use null in the array to indicate if and where a separator is required 2637 * @return the tool bar that was created 2638 */ 2639 public JToolBar createToolBar(String uiKey, JButton[] buttons) { 2640 JToolBar tb = new JToolBar(); 2641 tb.setName(uiKey); 2642 setAccessibleInfo(tb, uiKey); 2643 for (int i = 0; i < buttons.length; i++) { 2644 JButton button = buttons[i]; 2645 if (button == null) 2646 tb.addSeparator(); 2647 else { 2648 tb.add(button); 2649 } 2650 } 2651 return tb; 2652 } 2653 2654 /** 2655 * Add a set of actions to an existing toolbar. 2656 * 2657 * @param tb The toolbar to modify, must not be null. 2658 * @param actions the actions from which to create the buttons; 2659 * use null in the array to indicate if and where a separator is required 2660 * @see javax.swing.Action#SHORT_DESCRIPTION 2661 */ 2662 public void addToolBarActions(JToolBar tb, Action[] actions) { 2663 for (int i = 0; i < actions.length; i++) { 2664 Action action = actions[i]; 2665 if (action == null) 2666 tb.addSeparator(); 2667 else { 2668 JButton b = tb.add(action); 2669 b.setName((String) (action.getValue(Action.NAME))); 2670 b.getAccessibleContext().setAccessibleName(b.getName()); 2671 } 2672 } 2673 } 2674 2675 //---------------------------------------------------------------------------- 2676 // 2677 // blocking confirmation and error dialogs 2678 2679 /** 2680 * Show an information dialog, using a resource to specify the error message. <br> 2681 * The resource used is: 2682 * <table> 2683 * <tr><td><i>uiKey</i>.err <td>the information message to be displayed 2684 * </table> 2685 * The method will block until the dialog is dismissed by the user. 2686 * @param uiKey the base name of the resource to be used 2687 */ 2688 public void showInformation(String uiKey) { 2689 showLocalizedInfo(uiKey, getI18NString(uiKey + ".inf")); 2690 } 2691 2692 /** 2693 * Show an error dialog, using a resource to specify the error message. <br> 2694 * The resource used is: 2695 * <table> 2696 * <tr><td><i>uiKey</i>.err <td>the error message to be displayed 2697 * </table> 2698 * The method will block until the dialog is dismissed by the user. 2699 * @param uiKey the base name of the resource to be used 2700 */ 2701 public void showError(String uiKey) { 2702 showLocalizedError(uiKey, getI18NString(uiKey + ".err")); 2703 } 2704 2705 /** 2706 * Show an error dialog, using a resource to specify the error message. <br> 2707 * The resource used is: 2708 * <table> 2709 * <tr><td><i>uiKey</i>.err <td>the error message to be displayed 2710 * </table> 2711 * @param uiKey the base name of the resource to be used 2712 * @param arg an argument to be formatted into the content using 2713 * {@link java.text.MessageFormat#format} 2714 * The method will block until the dialog is dismissed by the user. 2715 */ 2716 public void showError(String uiKey, Object arg) { 2717 showLocalizedError(uiKey, getI18NString(uiKey + ".err", arg)); 2718 } 2719 2720 /** 2721 * Show an error dialog, using a resource to specify the error message. <br> 2722 * The resource used is: 2723 * <table> 2724 * <tr><td><i>uiKey</i>.err <td>the error message to be displayed 2725 * </table> 2726 * @param uiKey the base name of the resource to be used 2727 * @param args an array of arguments to be formatted into the content using 2728 * {@link java.text.MessageFormat#format} 2729 * The method will block until the dialog is dismissed by the user. 2730 */ 2731 public void showError(String uiKey, Object[] args) { 2732 String msg = getI18NString(uiKey + ".err", args); 2733 String title = local_i18n.getString("uif.error", ProductInfo.getName()); 2734 JButton okBtn = createOptionButton("uif.ok"); 2735 JTextArea ta = createLocalizedMessageArea(uiKey, msg.trim(), true); 2736 Dimension d = ta.getMinimumSize(); 2737 Object content = ta; 2738 // need scrolling ? 2739 if (d.width > Math.round(6.f * DOTS_PER_INCH) || d.height > Math.round(2.f * DOTS_PER_INCH)) { 2740 JScrollPane sp = new JScrollPane(ta); 2741 sp.setPreferredSize(new Dimension(Math.round(6.f * DOTS_PER_INCH), 2742 Math.round(2.f * DOTS_PER_INCH))); 2743 content = sp; 2744 } 2745 2746 JOptionPane.showOptionDialog(parent, 2747 content, 2748 title, 2749 JOptionPane.DEFAULT_OPTION, 2750 JOptionPane.ERROR_MESSAGE, 2751 null, 2752 new Object[] { okBtn }, 2753 null); 2754 } 2755 2756 /** 2757 * Show an error dialog containing stack trace information, using a 2758 * resource to specify the error message. <br> 2759 * The resource used is: 2760 * <table> 2761 * <tr><td><i>uiKey</i>.err <td>the error message to be displayed 2762 * </table> 2763 * @param uiKey the base name of the resource to be used 2764 * @param args an array of arguments to be formatted into the content using 2765 * @param trace an array of arguments containing stack trace information 2766 * to be added to scrollable pane 2767 * The method will block until the dialog is dismissed by the user. 2768 */ 2769 public void showError(String uiKey, Object[] args, Object[] trace) { 2770 String title = local_i18n.getString("uif.error", ProductInfo.getName()); 2771 JButton okBtn = createOptionButton("uif.ok"); 2772 StringBuffer traceString = new StringBuffer(getI18NString(uiKey + ".err", args)); 2773 traceString.append(":\n"); 2774 for (int i = 0; i < trace.length; i++) { 2775 traceString.append(trace[i]); 2776 if (i != (trace.length -1)) 2777 traceString.append("\n\tat "); 2778 } 2779 JTextArea ta = createLocalizedMessageArea(uiKey, traceString.toString(), true); 2780 ta.setLineWrap(false); 2781 JScrollPane sp = new JScrollPane(ta); 2782 sp.setPreferredSize(new Dimension(Math.round(6.f * DOTS_PER_INCH), 2783 Math.round(2.f * DOTS_PER_INCH))); 2784 2785 JOptionPane.showOptionDialog(parent, 2786 sp, 2787 title, 2788 JOptionPane.DEFAULT_OPTION, 2789 JOptionPane.ERROR_MESSAGE, 2790 null, 2791 new Object[] { okBtn }, 2792 null); 2793 } 2794 2795 /** 2796 * Show a error dialog to the user, using previously localized (or 2797 * unlocalized) strings for the message and title. 2798 * @param title Title string for the dialog. If null, a generic title 2799 * will be used. 2800 * @param msg Message to show to the user. 2801 * @see #showError(String) 2802 * @see #showError(String,Object[]) 2803 * @see #showError(String,Object[],Object[]) 2804 */ 2805 public void showLiteralError(String title, String msg) { 2806 JButton okBtn = createOptionButton("uif.ok"); 2807 if (title == null) 2808 title = local_i18n.getString("uif.error", ProductInfo.getName()); 2809 2810 JOptionPane.showOptionDialog(parent, 2811 createLiteralMessageArea(msg), 2812 title, 2813 JOptionPane.DEFAULT_OPTION, 2814 JOptionPane.ERROR_MESSAGE, 2815 null, 2816 new Object[] { okBtn }, 2817 null); 2818 } 2819 2820 private void showLocalizedError(String uiKey, String text) { 2821 String title = local_i18n.getString("uif.error", ProductInfo.getName()); 2822 JButton okBtn = createOptionButton("uif.ok"); 2823 JOptionPane.showOptionDialog(parent, 2824 createLocalizedMessageArea(uiKey, text, true), 2825 title, 2826 JOptionPane.DEFAULT_OPTION, 2827 JOptionPane.ERROR_MESSAGE, 2828 null, 2829 new Object[] { okBtn }, 2830 null); 2831 } 2832 2833 2834 private void showLocalizedInfo(String uiKey, String text) { 2835 String title = i18n.getString(uiKey + ".title"); 2836 JButton okBtn = createOptionButton("uif.ok"); 2837 JOptionPane.showOptionDialog(parent, 2838 createLocalizedMessageArea(uiKey, text, true), 2839 title, 2840 JOptionPane.DEFAULT_OPTION, 2841 JOptionPane.INFORMATION_MESSAGE, 2842 null, 2843 new Object[] { okBtn }, 2844 null); 2845 } 2846 2847 /** 2848 * Show a confirmation dialog with OK and Cancel buttons, 2849 * using a resource to specify the message and title. <br> 2850 * The resources used are: 2851 * <table> 2852 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 2853 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 2854 * </table> 2855 * The method will block until the dialog is dismissed by the user. 2856 * @param uiKey the base name of the resource to be used 2857 * @return an integer signifying how the dialog was dismissed 2858 * @see JOptionPane#OK_OPTION 2859 * @see JOptionPane#CANCEL_OPTION 2860 */ 2861 public int showOKCancelDialog(String uiKey) { 2862 return showLocalizedOKCancelDialog(uiKey, getI18NString(uiKey + ".txt")); 2863 } 2864 2865 /** 2866 * Show a confirmation dialog with OK and Cancel buttons, 2867 * using a resource to specify the message and title. <br> 2868 * The resources used are: 2869 * <table> 2870 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 2871 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 2872 * </table> 2873 * The method will block until the dialog is dismissed by the user. 2874 * @param uiKey the base name of the resource to be used 2875 * @param arg an argument to be formatted into the content using 2876 * {@link java.text.MessageFormat#format} 2877 * @return an integer signifying how the dialog was dismissed 2878 * @see JOptionPane#OK_OPTION 2879 * @see JOptionPane#CANCEL_OPTION 2880 */ 2881 public int showOKCancelDialog(String uiKey, Object arg) { 2882 return showLocalizedOKCancelDialog(uiKey, getI18NString(uiKey + ".txt", arg)); 2883 } 2884 2885 /** 2886 * Show a confirmation dialog with OK and Cancel buttons, 2887 * using a resource to specify the message and title. <br> 2888 * The resources used are: 2889 * <table> 2890 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 2891 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 2892 * </table> 2893 * The method will block until the dialog is dismissed by the user. 2894 * @param uiKey the base name of the resource to be used 2895 * @return an integer signifying how the dialog was dismissed 2896 * @param args an array of arguments to be formatted into the content using 2897 * {@link java.text.MessageFormat#format} 2898 * @see JOptionPane#OK_OPTION 2899 * @see JOptionPane#CANCEL_OPTION 2900 */ 2901 public int showOKCancelDialog(String uiKey, Object[] args) { 2902 return showLocalizedOKCancelDialog(uiKey, getI18NString(uiKey + ".txt", args)); 2903 } 2904 2905 private int showLocalizedOKCancelDialog(String uiKey, String text) { 2906 JTextArea msg = createLocalizedMessageArea(uiKey, text, true); 2907 String title = getI18NString(uiKey + ".title"); 2908 JButton okBtn = createOptionButton("uif.ok"); 2909 JButton cancelBtn = createOptionButton("uif.cancel"); 2910 int rc = JOptionPane.showOptionDialog(parent, 2911 msg, 2912 title, 2913 JOptionPane.OK_CANCEL_OPTION, 2914 JOptionPane.QUESTION_MESSAGE, 2915 null, 2916 new Object[] { okBtn, cancelBtn }, 2917 null); 2918 return (rc == 0 ? JOptionPane.OK_OPTION /*0*/ 2919 : rc == 1 ? JOptionPane.CANCEL_OPTION /*2*/ 2920 : rc); 2921 } 2922 2923 /** 2924 * Show a confirmation dialog with Yes and No buttons, 2925 * using a resource to specify the message and title. <br> 2926 * The resources used are: 2927 * <table> 2928 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 2929 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 2930 * </table> 2931 * The method will block until the dialog is dismissed by the user. 2932 * @param uiKey the base name of the resource to be used 2933 * @return an integer signifying how the dialog was dismissed 2934 * @see JOptionPane#YES_OPTION 2935 * @see JOptionPane#NO_OPTION 2936 */ 2937 public int showYesNoDialog(String uiKey) { 2938 return showLocalizedYesNoDialog(uiKey, getI18NString(uiKey + ".txt")); 2939 } 2940 2941 /** 2942 * Show a confirmation dialog with Yes and No buttons, 2943 * using a resource to specify the message and title. <br> 2944 * The resources used are: 2945 * <table> 2946 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 2947 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 2948 * </table> 2949 * The method will block until the dialog is dismissed by the user. 2950 * @param uiKey the base name of the resource to be used 2951 * @param arg an argument to be formatted into the content using 2952 * {@link java.text.MessageFormat#format} 2953 * @return an integer signifying how the dialog was dismissed 2954 * @see JOptionPane#YES_OPTION 2955 * @see JOptionPane#NO_OPTION 2956 */ 2957 public int showYesNoDialog(String uiKey, Object arg) { 2958 return showLocalizedYesNoDialog(uiKey, getI18NString(uiKey + ".txt", arg)); 2959 } 2960 2961 /** 2962 * Show a confirmation dialog with Yes and No buttons, 2963 * using a resource to specify the title and component for the message.<br> 2964 * The resources used are: 2965 * <table> 2966 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 2967 * </table> 2968 * The method will block until the dialog is dismissed by the user. 2969 * @param uiKey the base name of the resource to be used 2970 * @param msg the GUI component to be used as the dialogs message payload 2971 * @return an integer signifying how the dialog was dismissed 2972 * @see JOptionPane#YES_OPTION 2973 * @see JOptionPane#NO_OPTION 2974 */ 2975 public int showCustomYesNoDialog(String uiKey, Component msg) { 2976 return showComponentYesNoDialog(uiKey, msg); 2977 } 2978 2979 /** 2980 * Show a confirmation dialog with Yes and No buttons, 2981 * using a resource to specify the message and title. <br> 2982 * The resources used are: 2983 * <table> 2984 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 2985 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 2986 * </table> 2987 * The method will block until the dialog is dismissed by the user. 2988 * @param uiKey the base name of the resource to be used 2989 * @return an integer signifying how the dialog was dismissed 2990 * @param args an array of arguments to be formatted into the content using 2991 * {@link java.text.MessageFormat#format} 2992 * @see JOptionPane#YES_OPTION 2993 * @see JOptionPane#NO_OPTION 2994 */ 2995 public int showYesNoDialog(String uiKey, Object[] args) { 2996 return showLocalizedYesNoDialog(uiKey, getI18NString(uiKey + ".txt", args)); 2997 } 2998 2999 private int showLocalizedYesNoDialog(String uiKey, String text) { 3000 JTextArea msg = createLocalizedMessageArea(uiKey, text, true); 3001 return showComponentYesNoDialog(uiKey, msg); 3002 } 3003 3004 /** 3005 * Show a Yes/No dialog with the given text and title. 3006 * Use this with care and only when really really needed. 3007 */ 3008 int showLiteralYesNoDialog(String title, String text) { 3009 // warning, this only works because createLocalizedMessageArea 3010 // does not use the uikey for anything except the component name 3011 JTextArea msg = createLocalizedMessageArea("literal", text, true); 3012 3013 // update showComponentYesNoDialog if you change this! 3014 JButton yesBtn = createOptionButton("uif.yes"); 3015 JButton noBtn = createOptionButton("uif.no"); 3016 return JOptionPane.showOptionDialog(parent, 3017 msg, 3018 title, 3019 JOptionPane.YES_NO_OPTION, 3020 JOptionPane.QUESTION_MESSAGE, 3021 null, 3022 new Object[] { yesBtn, noBtn }, 3023 null); 3024 } 3025 3026 private int showComponentYesNoDialog(String uiKey, Component msg) { 3027 // update showLiteralYesNoDialog if you change this! 3028 String title = getI18NString(uiKey + ".title"); 3029 JButton yesBtn = createOptionButton("uif.yes"); 3030 JButton noBtn = createOptionButton("uif.no"); 3031 return JOptionPane.showOptionDialog(parent, 3032 msg, 3033 title, 3034 JOptionPane.YES_NO_OPTION, 3035 JOptionPane.QUESTION_MESSAGE, 3036 null, 3037 new Object[] { yesBtn, noBtn }, 3038 null); 3039 } 3040 3041 /** 3042 * Show a confirmation dialog with Yes, No and Cancel buttons, 3043 * using a resource to specify the message and title. <br> 3044 * The resources used are: 3045 * <table> 3046 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 3047 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 3048 * </table> 3049 * The method will block until the dialog is dismissed by the user. 3050 * @param uiKey the base name of the resource to be used 3051 * @return an integer signifying how the dialog was dismissed 3052 * @see JOptionPane#YES_OPTION 3053 * @see JOptionPane#NO_OPTION 3054 * @see JOptionPane#CANCEL_OPTION 3055 */ 3056 public int showYesNoCancelDialog(String uiKey) { 3057 return showLocalizedYesNoCancelDialog(uiKey, getI18NString(uiKey + ".txt")); 3058 } 3059 3060 /** 3061 * Show a confirmation dialog with Yes and No buttons, 3062 * using a resource to specify the message and title. <br> 3063 * The resources used are: 3064 * <table> 3065 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 3066 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 3067 * </table> 3068 * The method will block until the dialog is dismissed by the user. 3069 * @param uiKey the base name of the resource to be used 3070 * @param arg an argument to be formatted into the content using 3071 * {@link java.text.MessageFormat#format} 3072 * @return an integer signifying how the dialog was dismissed 3073 * @see JOptionPane#YES_OPTION 3074 * @see JOptionPane#NO_OPTION 3075 * @see JOptionPane#CANCEL_OPTION 3076 */ 3077 public int showYesNoCancelDialog(String uiKey, Object arg) { 3078 return showLocalizedYesNoCancelDialog(uiKey, getI18NString(uiKey + ".txt", arg)); 3079 } 3080 3081 /** 3082 * Show a confirmation dialog with Yes and No buttons, 3083 * using a resource to specify the message and title. <br> 3084 * The resources used are: 3085 * <table> 3086 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 3087 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 3088 * </table> 3089 * The method will block until the dialog is dismissed by the user. 3090 * @param uiKey the base name of the resource to be used 3091 * @return an integer signifying how the dialog was dismissed 3092 * @param args an array of arguments to be formatted into the content using 3093 * {@link java.text.MessageFormat#format} 3094 * @see JOptionPane#YES_OPTION 3095 * @see JOptionPane#NO_OPTION 3096 * @see JOptionPane#CANCEL_OPTION 3097 */ 3098 public int showYesNoCancelDialog(String uiKey, Object[] args) { 3099 return showLocalizedYesNoCancelDialog(uiKey, getI18NString(uiKey + ".txt", args)); 3100 } 3101 3102 private int showLocalizedYesNoCancelDialog(String uiKey, String text) { 3103 JTextArea msg = createLocalizedMessageArea(uiKey, text, true); 3104 String title = getI18NString(uiKey + ".title"); 3105 JButton yesBtn = createOptionButton("uif.yes"); 3106 JButton noBtn = createOptionButton("uif.no"); 3107 JButton cancelBtn = createOptionButton("uif.cancel"); 3108 return JOptionPane.showOptionDialog(parent, 3109 msg, 3110 title, 3111 JOptionPane.YES_NO_CANCEL_OPTION, 3112 JOptionPane.QUESTION_MESSAGE, 3113 null, 3114 new Object[] { yesBtn, noBtn, cancelBtn }, 3115 null); 3116 } 3117 3118 /** 3119 * Show a message only dialog, no user feedback. 3120 * The resources used are: 3121 * <table> 3122 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 3123 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 3124 * </table> 3125 * @param uiKey the base name of the resource to be used 3126 * @param args any arguments to be used to create the message 3127 */ 3128 public void showInformationDialog(String uiKey, Object[] args) { 3129 showLocalizedInformationDialog(uiKey, 3130 getI18NString(uiKey + ".title"), 3131 getI18NString(uiKey + ".txt", args), parent); 3132 } 3133 3134 public void showInformationDialog(String uiKey, Object[] args, Component parent) { 3135 showLocalizedInformationDialog(uiKey, 3136 getI18NString(uiKey + ".title"), 3137 getI18NString(uiKey + ".txt", args), parent); 3138 } 3139 3140 3141 private void showLocalizedInformationDialog(String uiKey, String title, 3142 String text, Component localParent) { 3143 JTextArea msg = createLocalizedMessageArea(uiKey, text, true); 3144 Dimension d = msg.getMinimumSize(); 3145 Object content = msg; 3146 // need scrolling ? 3147 if (d.width > Math.round(6.f * DOTS_PER_INCH) || d.height > Math.round(2.f * DOTS_PER_INCH)) { 3148 JScrollPane sp = new JScrollPane(msg); 3149 sp.setPreferredSize(new Dimension(Math.round(6.f * DOTS_PER_INCH), 3150 Math.round(2.f * DOTS_PER_INCH))); 3151 content = sp; 3152 } 3153 3154 JOptionPane.showMessageDialog(localParent, 3155 content, 3156 title, 3157 JOptionPane.INFORMATION_MESSAGE, 3158 null); 3159 } 3160 3161 //---------------------------------------------------------------------------- 3162 // 3163 // don't show this again message box 3164 3165 /** 3166 * Show a dialog which provides the user with an informational message. 3167 * 3168 * The resources used are: 3169 * <table> 3170 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 3171 * </table> 3172 * @param uiKey the base name of the resource to be used 3173 * @param msg the body of the dialog, which should have already been localized 3174 */ 3175 public void showCustomInfoDialog(String uiKey, Object msg) { 3176 JOptionPane.showMessageDialog(parent, 3177 msg, 3178 getI18NString(uiKey + ".title"), 3179 JOptionPane.INFORMATION_MESSAGE, 3180 null); 3181 } 3182 3183 //---------------------------------------------------------------------------- 3184 // 3185 // panels 3186 3187 /** 3188 * Create a horizontal placeholder "box". <br> 3189 * The name of this new box component will be set to <i>uiKey</i>. 3190 * @param uiKey the base name of the resource to be used 3191 * @return A Box component 3192 * @see javax.swing.Box 3193 */ 3194 public Box createHorizontalBox(String uiKey) { 3195 Box box = Box.createHorizontalBox(); 3196 box.setName(uiKey); 3197 box.setFocusable(false); 3198 return box; 3199 } 3200 3201 /** 3202 * Create an empty panel. <br> 3203 * In the J2SE 1.4 and greater world, panels are focusable by default, 3204 * so this panel will be focusable. Because of this, accessibility 3205 * information must be set, therefore the following resources are 3206 * required from the resource bundle: 3207 * <table> 3208 * <tr><td><i>uiKey</i>.name <td>the accessible name of the panel 3209 * <tr><td><i>uiKey</i>.desc <td>accessible description text 3210 * </table> 3211 * The name of this new component will be set to <i>uiKey</i>. 3212 * @param uiKey the base name of the resource to be used 3213 * @return An empty panel component 3214 */ 3215 public JPanel createPanel(String uiKey) { 3216 return createPanel(uiKey, true); 3217 } 3218 3219 /** 3220 * Create an empty panel. <br> 3221 * In the J2SE 1.4 and greater world, panels are focusable by default, 3222 * so this panel will be focusable. Use this method to control 3223 * whether or not the panel remains focusable. If you choose 'true', 3224 * the following must be provided in the resource bundle: 3225 * <table> 3226 * <tr><td><i>uiKey</i>.name <td>the accessible name of the panel 3227 * <tr><td><i>uiKey</i>.desc <td>accessible description text 3228 * </table> 3229 * The name of this new component will be set to <i>uiKey</i>. 3230 * @param uiKey the base name of the resource to be used 3231 * @param focusable If true, the panel will accept focus in the GUI. 3232 * If false it will not. Note that if it is focusable, you need to 3233 * provide accessibility text. 3234 * @return An empty panel component 3235 */ 3236 public JPanel createPanel(String uiKey, boolean focusable) { 3237 JPanel p = new JPanel(); 3238 initPanel(p, uiKey, focusable); 3239 return p; 3240 } 3241 3242 /** 3243 * Create an empty panel with a specific layout manager. <br> 3244 * In the J2SE 1.4 and greater world, panels are focusable by default, 3245 * so this panel will be focusable. Because of this, accessibility 3246 * information must be set, therefore the following resources are 3247 * required from the resource bundle: 3248 * <table> 3249 * <tr><td><i>uiKey</i>.name <td>the accessible name of the panel 3250 * <tr><td><i>uiKey</i>.desc <td>accessible description text 3251 * </table> 3252 * The name of this new component will be set to <i>uiKey</i>. 3253 * @param uiKey the base name of the resource to be used 3254 * @param layout the layout manager instance to use in this panel 3255 * @return An empty panel component 3256 */ 3257 public JPanel createPanel(String uiKey, LayoutManager layout) { 3258 return createPanel(uiKey, layout, true); 3259 } 3260 3261 /** 3262 * Create an empty panel with a specific layout manager. <br> 3263 * In the J2SE 1.4 and greater world, panels are focusable by default, 3264 * so this panel will be focusable. Use this method to control 3265 * whether or not the panel remains focusable. If you choose 'true', 3266 * the following must be provided in the resource bundle: 3267 * <table> 3268 * <tr><td><i>uiKey</i>.name <td>the accessible name of the panel 3269 * <tr><td><i>uiKey</i>.desc <td>accessible description text 3270 * </table> 3271 * The name of this new component will be set to <i>uiKey</i>. 3272 * @param uiKey the base name of the resource to be used 3273 * @param layout the layout manager instance to use in this panel 3274 * @param focusable If true, the panel will accept focus in the GUI. 3275 * If false it will not. Note that if it is focusable, you need to 3276 * provide accessibility text. 3277 * @return An empty panel component 3278 */ 3279 public JPanel createPanel(String uiKey, LayoutManager layout, boolean focusable) { 3280 JPanel p = new JPanel(); 3281 initPanel(p, uiKey, layout, focusable); 3282 return p; 3283 } 3284 3285 /** 3286 * Set properties on an existing panel. 3287 * @param p the panel to modify 3288 * @param uiKey the base name of the resource to be used 3289 * @param focusable If true, the panel will accept focus in the GUI. 3290 * If false it will not. Note that if it is focusable, you need to 3291 * provide accessibility text. 3292 */ 3293 public void initPanel(JPanel p, String uiKey, boolean focusable) { 3294 p.setName(uiKey); 3295 if (focusable) 3296 setAccessibleInfo(p, uiKey); 3297 else 3298 p.setFocusable(false); 3299 } 3300 3301 /** 3302 * Set properties on an existing panel, including the layout manager. 3303 * @param p the panel to modify 3304 * @param uiKey the base name of the resource to be used 3305 * @param layout the layout manager instance that this panel should use 3306 * @param focusable If true, the panel will accept focus in the GUI. 3307 * If false it will not. Note that if it is focusable, you need to 3308 * provide accessibility text. 3309 */ 3310 public void initPanel(JPanel p, String uiKey, LayoutManager layout, boolean focusable) { 3311 initPanel(p, uiKey, focusable); 3312 p.setLayout(layout); 3313 3314 } 3315 3316 //---------------------------------------------------------------------------- 3317 // 3318 // dialogs 3319 3320 /** 3321 * Create an empty dialog. <br> 3322 * See <code>initDialog(JDialog,String)</code> for required resources. 3323 * @param uiKey the base name of the resource to be used 3324 * @param parent the parent component of this dialog 3325 * @return an empty dialog component 3326 * @see #initDialog 3327 */ 3328 public JDialog createDialog(String uiKey, Component parent) { 3329 JFrame owner = (JFrame) (SwingUtilities.getAncestorOfClass(JFrame.class, parent)); 3330 return createDialog(uiKey, owner); 3331 } 3332 3333 /** 3334 * Create an empty dialog. <br> 3335 * See <code>initDialog(JDialog,String)</code> for required resources. 3336 * @param uiKey the base name of the resource to be used 3337 * @param owner the parent frame of this dialog 3338 * @return an empty dialog component 3339 * @see #initDialog 3340 */ 3341 public JDialog createDialog(String uiKey, JFrame owner) { 3342 JDialog d = new JDialog(owner); 3343 initDialog(d, uiKey); 3344 return d; 3345 } 3346 3347 /** 3348 * Create an empty dialog. <br> 3349 * See <code>initDialog(JDialog,String)</code> for required resources. 3350 * @param uiKey the base name of the resource to be used 3351 * @param owner the parent frame of this dialog. If owner is null - icon is set to the dialog 3352 * @param title the localized title of this new dialog 3353 * @param content the content to go into the dialog 3354 * @return an dialog component with the given content component and title 3355 * @see #initDialog 3356 */ 3357 public JDialog createDialog(String uiKey, JFrame owner, String title, Container content) { 3358 return createDialog(uiKey, owner, title, content, Dialog.ModalityType.MODELESS); 3359 } 3360 3361 /** 3362 * Create an empty dialog. <br> 3363 * See <code>initDialog(JDialog,String)</code> for required resources. 3364 * @param uiKey the base name of the resource to be used 3365 * @param owner the parent frame of this dialog. If owner is null - icon is set to the dialog 3366 * @param title the localized title of this new dialog 3367 * @param content the content to go into the dialog 3368 * @param type specifies whether dialog blocks input to other windows when shown. 3369 * null value and unsupported modality types are equivalent to MODELESS 3370 * @return an dialog component with the given content component and title 3371 * @see #initDialog 3372 */ 3373 public JDialog createDialog(String uiKey, JFrame owner, String title, Container content, Dialog.ModalityType type) { 3374 // can't use constructor JDialog(Window, String, Dialog.ModalityType) - 3375 // it has different behavior from JDialog(Frame, String, boolean) 3376 JDialog d = new JDialog(owner, title, false); 3377 d.setModalityType(type); 3378 if (owner == null) { 3379 d.setIconImage(createImage("images/jticon.gif")); 3380 } 3381 initDialog(d, uiKey); 3382 d.setContentPane(content); 3383 return d; 3384 } 3385 3386 /** 3387 * Create an empty frame. Unlike to dialog <code>createDialog(String uiKey, 3388 * JFrame owner, String title, Container content)</code> it can't be modal, 3389 * it's always free-floating and it has minimize and maximize buttons <br/> 3390 * See <code>initFrame(JFrame,String)</code> for required resources. 3391 * @param uiKey the base name of the resource to be used 3392 * @param title the localized title of this new frame 3393 * @param content the content to go into the frame 3394 * @return a frame component with the given content component and title 3395 * @see #initFrame 3396 */ 3397 public JFrame createFrame(String uiKey, String title, Container content) { 3398 JFrame frame = new JFrame(title); 3399 initFrame(frame, uiKey); 3400 frame.setContentPane(content); 3401 return frame; 3402 } 3403 3404 /** 3405 * Create a dialog which will ask the user to wait. 3406 * The resources used are: 3407 * <table> 3408 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 3409 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 3410 * </table> 3411 * @param uiKey The prefix to retrieve strings to be displayed. 3412 * @param parent The parent component of this new dialog. 3413 * @return a dialog appropriate for asking the user to wait 3414 */ 3415 public JDialog createWaitDialog(String uiKey, Component parent) { 3416 JFrame owner = (JFrame) (SwingUtilities.getAncestorOfClass(JFrame.class, parent)); 3417 return createWaitDialog(uiKey, owner); 3418 } 3419 3420 /** 3421 * Create a dialog which will ask the user to wait. 3422 * The resources used are: 3423 * <table> 3424 * <tr><td><i>uiKey</i>.txt <td>the message to be displayed 3425 * <tr><td><i>uiKey</i>.title <td>the title for the dialog 3426 * <tr><td><i>uiKey</i>.desc <td>accessible description of the dialog 3427 * <tr><td><i>uiKey</i>.name <td>accessible name of the dialog 3428 * </table> 3429 * @param uiKey The prefix to retrieve strings to be displayed. 3430 * @param owner The frame which will own this new dialog. 3431 * @return a dialog appropriate for asking the user to wait 3432 */ 3433 public JDialog createWaitDialog(String uiKey, JFrame owner) { 3434 final int msgWidth = 50; 3435 JDialog d = new JDialog(owner); 3436 initDialog(d, uiKey); 3437 d.setTitle(getI18NString(uiKey + ".title")); 3438 3439 JProgressBar pb = new JProgressBar(SwingConstants.HORIZONTAL); 3440 pb.setName(uiKey); 3441 pb.setIndeterminate(true); 3442 pb.setBorderPainted(true); 3443 pb.setPreferredSize(new Dimension(Math.round(2.5f * DOTS_PER_INCH), 3444 15)); 3445 3446 JPanel body = createPanel(uiKey, new GridBagLayout(), false); 3447 GridBagConstraints gbc = new GridBagConstraints(); 3448 gbc.fill = GridBagConstraints.NONE; 3449 gbc.anchor = GridBagConstraints.CENTER; 3450 gbc.insets.left = 12; // JL&F spacing 3451 gbc.insets.right = 12; // JL&F spacing 3452 gbc.insets.top = 12; // JL&F spacing 3453 3454 gbc.gridy = 0; 3455 gbc.weightx = 0; 3456 3457 JTextArea msg = createLocalizedMessageArea(uiKey, 3458 getI18NString(uiKey + ".txt"), 3459 false); 3460 // uif sets the size, but too large for this dialog 3461 msg.setSize(new Dimension(Math.round(4.0f * DOTS_PER_INCH), 3462 Integer.MAX_VALUE)); 3463 body.add(msg, gbc); 3464 3465 // add progress bar 3466 gbc.gridy = 1; 3467 gbc.insets.top = 11; // JL&F spacing 3468 gbc.insets.bottom = 12; // JL&F spacing 3469 body.add(pb, gbc); 3470 3471 d.setContentPane(body); 3472 d.pack(); 3473 3474 d.setLocationRelativeTo(owner); 3475 return d; 3476 } 3477 3478 /** 3479 * Configure a dialog with accessibility information. 3480 * <table> 3481 * <tr><td><i>uiKey</i>.desc <td>accessible description of the dialog 3482 * <tr><td><i>uiKey</i>.name <td>accessible name of the dialog 3483 * <tr><td><i>uiKey</i>.root <td>component name for the root pane of the 3484 * dialog 3485 * </table> 3486 * @param d the dialog to upgrade 3487 * @param uiKey Key to retrieve the new properties with 3488 */ 3489 public void initDialog(JDialog d, String uiKey) { 3490 d.setName(uiKey); 3491 setAccessibleInfo(d, uiKey); 3492 d.setLocationRelativeTo(d.getParent()); 3493 3494 JRootPane root = d.getRootPane(); 3495 root.setName(uiKey + ".root"); 3496 AccessibleContext ac = d.getAccessibleContext(); 3497 AccessibleContext r_ac = root.getAccessibleContext(); 3498 r_ac.setAccessibleName(ac.getAccessibleName()); 3499 r_ac.setAccessibleDescription(ac.getAccessibleDescription()); 3500 } 3501 3502 /** 3503 * Configure a frame with accessibility information and an icon. 3504 * <table> 3505 * <tr><td><i>uiKey</i>.desc <td>accessible description of the frame 3506 * <tr><td><i>uiKey</i>.name <td>accessible name of the frame 3507 * <tr><td><i>uiKey</i>.root <td>component name for the root pane of the 3508 * frame 3509 * </table> 3510 * @param d the frame to upgrade 3511 * @param uiKey Key to retrieve the new properties with 3512 */ 3513 public void initFrame(JFrame d, String uiKey) { 3514 d.setName(uiKey); 3515 setAccessibleInfo(d, uiKey); 3516 d.setLocationRelativeTo(d.getParent()); 3517 3518 d.setIconImage(createImage("images/jticon.gif")); 3519 3520 JRootPane root = d.getRootPane(); 3521 root.setName(uiKey + ".root"); 3522 AccessibleContext ac = d.getAccessibleContext(); 3523 AccessibleContext r_ac = root.getAccessibleContext(); 3524 r_ac.setAccessibleName(ac.getAccessibleName()); 3525 r_ac.setAccessibleDescription(ac.getAccessibleDescription()); 3526 } 3527 3528 3529 //---------------------------------------------------------------------------- 3530 3531 /** 3532 * Dispose of any owned resources. 3533 */ 3534 public void dispose() { 3535 clientClass = null; 3536 parent = null; 3537 } 3538 3539 //---------------------------------------------------------------------------- 3540 3541 private static Font baseFont = new JLabel().getFont(); 3542 3543 private static final ActionListener closeListener = new ActionListener() { 3544 public void actionPerformed(ActionEvent e) { 3545 Component src = (Component) (e.getSource()); 3546 for (Container p = src.getParent(); p != null; p = p.getParent()) { 3547 if (p instanceof JInternalFrame || p instanceof Window) { 3548 p.setVisible(false); 3549 return; 3550 } 3551 } 3552 } 3553 }; 3554 3555 private Class clientClass; 3556 private Component parent; 3557 private I18NResourceBundle i18n; 3558 private HelpBroker helpBroker; 3559 3560 private static I18NResourceBundle local_i18n = I18NResourceBundle.getBundleForClass(UIFactory.class); 3561 private static final int DOTS_PER_INCH = Toolkit.getDefaultToolkit().getScreenResolution(); 3562 3563 /** 3564 * Extension to the UIFactory that allows to use more than one resource 3565 * bundle. All methods accessing the resource bundle are overridden to 3566 * search for a resource in the alternative bundle first, and, if not found, 3567 * look up it in the original one. 3568 * <b> 3569 * This class might be helpful, when a component extends another components 3570 * from a different package. 3571 */ 3572 public static class UIFactoryExt extends UIFactory { 3573 private I18NResourceBundle i18n_alt; 3574 private Class altClass; 3575 3576 public UIFactoryExt(UIFactory uif, Class altClass) { 3577 super(uif.clientClass, uif.parent, uif.helpBroker); 3578 i18n_alt = I18NResourceBundle.getBundleForClass(altClass); 3579 this.altClass = altClass; 3580 } 3581 3582 @Override 3583 public Color getI18NColor(String key) { 3584 if (!hasKey(i18n_alt,key)) { 3585 return super.getI18NColor(key); 3586 } 3587 String value = i18n_alt.getString(key + ".clr"); 3588 try { 3589 if (value != null) 3590 return Color.decode(value); 3591 } 3592 catch (Exception e) { 3593 // ignore 3594 } 3595 return Color.BLACK; 3596 3597 } 3598 3599 @Override 3600 public String getI18NString(String key) { 3601 if (hasKey(i18n_alt,key)) { 3602 return i18n_alt.getString(key); 3603 } else { 3604 return super.getI18NString(key); 3605 } 3606 } 3607 3608 @Override 3609 public String getI18NString(String key, Object arg) { 3610 if (hasKey(i18n_alt,key)) { 3611 return i18n_alt.getString(key, arg); 3612 } else { 3613 return super.getI18NString(key, arg); 3614 } 3615 } 3616 3617 @Override 3618 public String getI18NString(String key, Object[] args) { 3619 if (hasKey(i18n_alt,key)) { 3620 return i18n_alt.getString(key, args); 3621 } else { 3622 return super.getI18NString(key, args); 3623 } 3624 } 3625 3626 @Override 3627 public URL getIconURL(String uiKey) { 3628 String r = getI18NString(uiKey + ".icon"); 3629 3630 URL url = altClass.getResource(r); 3631 3632 if (url == null) 3633 url = super.getIconURL(uiKey); 3634 3635 return url; 3636 } 3637 3638 /** 3639 * It would be much better to use containsKey() instead, but 3640 * it's available since 1.6 3641 */ 3642 static boolean hasKey(ResourceBundle rb, String key) { 3643 Enumeration<String> keys = rb.getKeys(); 3644 if (keys == null || key == null) { 3645 return false; 3646 } 3647 while(keys.hasMoreElements()) { 3648 if (key.equals(keys.nextElement())) { 3649 return true; 3650 } 3651 } 3652 return false; 3653 } 3654 } 3655 }