/*
* $Id$
*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javatest.tool;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.KeyboardFocusManager;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.MissingResourceException;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.BoundedRangeModel;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
//import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
//import javax.swing.SpinnerModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.table.TableModel;
import com.sun.javatest.ProductInfo;
import com.sun.javatest.tool.jthelp.ContextHelpManager;
import com.sun.javatest.tool.jthelp.HelpBroker;
import com.sun.javatest.util.I18NResourceBundle;
import java.awt.Dialog;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalLookAndFeel;
/**
* A factory for GUI components, providing support for
* internationalization, tool tips, context sensitive help, and on.
* UIFactory objects use a resource bundle specific to the client
* class to provide the internationalization support.
*/
public class UIFactory {
public static enum Colors {
/**
* Color used for highlighting incorrect input fields
*/
INPUT_INVALID(local_i18n.getString("colorprefs.colors.input.invalid.defvalue")),
/**
* Color used for highlighting correct input fields
*/
INPUT_VALID(local_i18n.getString("colorprefs.colors.input.valid.defvalue")),
/**
* Default background color for input fields
*/
INPUT_DEFAULT(local_i18n.getString("colorprefs.colors.input.default.defvalue")),
MENU_BACKGROUND(UIManager.getColor("Menu.background"), 255, false),
SEPARATOR_FOREGROUND(UIManager.getColor("Separator.foreground"), 255, false),
CONTROL_INFO(Color.RED, 255, false),
CONTROL_SHADOW(Color.RED, 255, false),
TEXT_HIGHLIGHT_COLOR(new JTextField().getSelectionColor(), 255, false),
TEXT_COLOR(new JLabel().getForeground(), 255, false),
TEXT_SELECTED_COLOR(new JTextField().getSelectedTextColor(), 255, false),
WINDOW_BACKGROUND(UIManager.getColor("Panel.background"), 255, false),
PRIMARY_CONTROL_HIGHLIGHT(Color.WHITE, 255, false),
PRIMARY_CONTROL_INFO(Color.BLACK, 255, false),
BUTTON_DISABLED_FOREGROUND(Color.WHITE, 255, false),//UIManager.getDefaults().getColor("Button.disabledForeground")
// these three are used for icon drawing only
PRIMARY_CONTROL_SHADOW(MetalLookAndFeel.getPrimaryControlShadow(), 255, false),
PRIMARY_CONTROL(MetalLookAndFeel.getPrimaryControl(), 255, false),
PRIMARY_CONTROL_DARK_SHADOW(MetalLookAndFeel.getPrimaryControlDarkShadow(), 255, false),
BLACK(Color.BLACK, 255, false),
TRANSPARENT(new Color(255, 255, 255, 0), false);
private final String defaultColor;
private Color color = null;
private boolean configurable;
Colors(Color defaultColor) {
this(defaultColor, true);
}
Colors(Color defaultColor, int alpha) {
this(new Color(defaultColor.getRed(), defaultColor.getGreen(), defaultColor.getBlue(), alpha), true);
}
Colors(Color defaultColor, int alpha, boolean configurable) {
this(new Color(defaultColor.getRed(), defaultColor.getGreen(), defaultColor.getBlue(), alpha), configurable);
}
Colors(Color defaultColor, boolean configurable) {
this.defaultColor = encodeARGB(defaultColor);
this.configurable = configurable;
}
Colors(String defaultColor) {
this.defaultColor = defaultColor;
this.configurable = true;
}
public boolean isConfigurable() {
return configurable;
}
/**
* Getter for default String-encoded color value. Is used for Color.decode() and
* should be formatted similarly
*
* @return Default String-encoded color value
*/
public String getDefaultValue() {
return defaultColor;
}
/**
* Getter for current color value. It is loaded from preferences if no color is set
* previously.
*
* @return Current color value
*/
public Color getValue() {
if(color == null) {
color = readColorFromPreferences();
}
return color;
}
/**
* Setter for current color value.
*
* @return Old color value
*/
public Color setValue(Color c) {
Color t = color;
if (configurable)
color = c;
return t;
}
/**
* Get color name used in preferences file. It is formed from enum name.
* E.g. colors.input.invalid for INPUT_INVALID
*
* @return Color name used in preferences file
*/
public String getPreferencesName() {
return "colors." + this.name().toLowerCase().replaceAll("_", ".");
}
/**
* Read color value from preferences ignoring current color value that is
* returned by getValue();
*
* @return Color value from preferences file
*/
public Color readColorFromPreferences() {
return decodeRGBA(Preferences.access().getPreference(this.getPreferencesName(), this.getDefaultValue()));
}
/**
* Find Colors by color preferences name.
*
* @param prefsName Color preferences name (e.g. "colors.input.default")
* @throws IllegalArgumentException in case there is no Colors with such
* name
* @return Colors associated with such preferences name
*/
public static Colors valueOfByPreferencesName(String prefsName) {
return Colors.valueOf(prefsName.replaceFirst("colors.", "").toUpperCase().replaceAll("\\.", "_"));
}
/**
* Get Color by colors preferences name.
*
* @param prefsName Color preferences name (e.g. "colors.input.default")
* @return Color if Preferences contain this color. Returns default value if exists
* null otherwise
*/
public static Color getColorByPreferencesName(String prefsName) {
Preferences prefs = Preferences.access();
try {
Colors c = valueOfByPreferencesName(prefsName); // IllegalArgumentException if such Colors doesn't exist
return c.getValue();
} catch(IllegalArgumentException e) {
String color = prefs.getPreference(prefsName); // try to find color in preferences anyway
return color == null ? null : decodeRGBA(color);
}
}
/**
* Get array with all colors names used in preferences
*
* @return Names array
*/
public static String[] getColorsNames() {
Colors[] values = Colors.values();
String temp[] = new String[values.length];
for(int i = 0; i < values.length; i++) {
temp[i] = values[i].getPreferencesName();
}
return temp;
}
public static Color decodeRGBA(String color) throws NumberFormatException {
try {
if (color.startsWith("0x") && color.length() == 10) {
Long colorCode = Long.decode(color);
int A = (int) (colorCode & 0xFF);
colorCode >>= 8;
int B = (int) (colorCode & 0xFF);
colorCode >>= 8;
int G = (int) (colorCode & 0xFF);
colorCode >>= 8;
int R = (int) (colorCode & 0xFF);
colorCode >>= 8;
return new Color(R, G, B, A);
} else {
return Color.decode(color);
}
} catch(Exception e) {
return Color.red;
}
}
public static String encodeARGB(Color color) {
if(color == null)
return "";
return String.format("0x%02x%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
}
}
public static Font getBaseFont() {
return baseFont;
}
/**
* Get invalid input color (red by default)
* @return Color of invalid input
*/
public static Color getInvalidInputColor() {
return Colors.INPUT_INVALID.getValue();
}
/**
* Set invalid input color
* @param newColor new invalid input color
*/
public static void setInvalidInputColor(Color newColor) {
Colors.INPUT_INVALID.setValue(newColor);
}
/**
* Get valid input color (green by default)
* @return Color of valid input
*/
public static Color getValidInputColor() {
return Colors.INPUT_VALID.getValue();
}
/**
* Set valid input color
* @param newColor new valid input color
*/
public static void setValidInputColor(Color newColor) {
Colors.INPUT_VALID.setValue(newColor);
}
/**
* Get default input color (while by default)
* @return Color of default input
*/
public static Color getDefaultInputColor() {
return Colors.INPUT_DEFAULT.getValue();
}
/**
* Set default input color
* @param newColor new default input color
*/
public static void setDefaultInputColor(Color newColor) {
Colors.INPUT_DEFAULT.setValue(newColor);
}
/**
* Set Color by preferences name
* @param name Color's preferences name
* @param c new Color to set
*/
public static void setColorByName(String name, Color c) {
Colors.valueOfByPreferencesName(name).setValue(c);
}
/**
* Set all colors to default values
*/
public static void setDefaultColors() {
Preferences pref = Preferences.access();
Colors colors[] = Colors.values();
for(Colors c: colors) {
pref.setPreference(c.getPreferencesName(), c.getDefaultValue());
}
}
/**
* Add Preferences observer to color changes
* @param observer
*/
public static void addColorChangeObserver(Preferences.Observer observer) {
Preferences.access().addObserver(Colors.getColorsNames(), observer);
}
/**
* Creates a color-choosing button with background color set by preferences color name
* @param cs preferences color name. Used to set background color and is set as JButton.name
* @param label JLabel for button
* @param l ActionListener for button
* @return color-choosing button
*/
public JButton createColorChooseButton(String cs, JLabel label, ActionListener l) {
JButton b = new JButton(" ");
Color c = Colors.getColorByPreferencesName(cs);
b.setBackground(c);
b.setSize(14, 14);
b.setText(" ");
b.setName(cs);
if(l != null)
b.addActionListener(l);
if(label != null)
label.setLabelFor(b);
return b;
}
/**
* Create a UIFactory object for a specific class.
* The class is used to determine the resource bundle
* for i18n strings; the bundle is named i18n.properties
* in the same package as the specified class.
* @param c the class used to determine the i18n properties
* @param helpBroker the help broker to be used when creating help buttons
*/
public UIFactory(Class c, HelpBroker helpBroker) {
this(c, null, helpBroker);
}
/**
* Create a UIFactory object for a specific component.
* The component's class is used to determine the resource bundle
* for i18n strings; the bundle is named i18n.properties
* in the same package as the specified class.
* @param c the component used to determine the i18n properties
* @param helpBroker the help broker to be used when creating help buttons
*/
public UIFactory(Component c, HelpBroker helpBroker) {
this(c.getClass(), c, helpBroker);
}
/**
* Create a UIFactory object for a specific class.
* The class is used to determine the resource bundle
* for i18n strings; the bundle is named i18n.properties
* in the same package as the specified class.
* @param c the class used to determine the i18n properties
* @param p the parent component to be used for any dialogs that are created
* @param helpBroker the help broker to be used when creating help buttons
*/
public UIFactory(Class c, Component p, HelpBroker helpBroker) {
this.helpBroker = helpBroker;
clientClass = c;
parent = p;
i18n = I18NResourceBundle.getBundleForClass(c);
}
/**
* Set the parent component to be used for dialogs created by this factory.
* This setting cannot be changed after it is set.
*
* @param p The parent component, should not be null.
*/
public void setDialogParent(Component p) {
if (parent != null && parent != p)
throw new IllegalStateException();
parent = p;
}
/**
* Get the screen resolution, in dots per inch, as provided
* by the default AWT toolkit.
* @return the screen resolution, in dots per inch
*/
public int getDotsPerInch() {
return DOTS_PER_INCH;
}
/**
* Get the help broker associated with this factory.
* @return the help broker associated with this factory
*/
public HelpBroker getHelpBroker() {
return helpBroker;
}
/**
* Get the resource bundle used to obtain the resources for the
* components create by this factory.
* @return the resource bundle used to obtain the resources for the
* components create by this factory
*/
public I18NResourceBundle getI18NResourceBundle() {
return i18n;
}
/**
* Get a keycode from the resource bundle.
* @param key the name of the resource to be returned
* @return the first character of the string that was found
*/
public int getI18NMnemonic(String key) {
String keyString = getI18NString(key);
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyString);
if (keyStroke != null)
return keyStroke.getKeyCode();
else
//System.err.println("WARNING: bad mnemonic keystroke for " + key + ": " + keyString);
return 0;
}
/**
* Get a color from the resource bundle.
* @param key the base name of the resource to be returned
* @return the color identified in the resource
*/
public Color getI18NColor(String key) {
String value = i18n.getString(key + ".clr");
try {
if (value != null)
return Color.decode(value);
}
catch (Exception e) {
// ignore
}
return Color.BLACK;
}
/**
* Get a string from the resource bundle.
* @param key the name of the resource to be returned
* @return the string that was found
*/
public String getI18NString(String key) {
return i18n.getString(key);
}
/**
* Get a string from the resource bundle.
* @param key the name of the resource to be returned
* @param arg an argument to be formatted into the result using
* {@link java.text.MessageFormat#format}
* @return the formatted string
*/
public String getI18NString(String key, Object arg) {
return i18n.getString(key, arg);
}
/**
* Get a string from the resource bundle.
* @param key the name of the resource to be returned
* @param args an array of arguments to be formatted into the result using
* {@link java.text.MessageFormat#format}
* @return the formatted string
*/
public String getI18NString(String key, Object[] args) {
return i18n.getString(key, args);
}
/**
* Set the help ID for the context-sensitive help for a component.
* @param comp the component for which to set the help ID
* @param helpID the help ID identifying the context sensitive help for
* the component
*/
public void setHelp(final Component comp, final String helpID) {
if (helpID == null)
throw new NullPointerException();
ContextHelpManager.setHelpIDString(comp, helpID);
if (comp instanceof JDialog) {
JDialog d = (JDialog) comp;
ContextHelpManager.setHelpIDString(d.getRootPane(), helpID);
Desktop.addHelpDebugListener(d);
final JComponent rootPane = d.getRootPane();
KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0, false);
rootPane.registerKeyboardAction(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if (helpBroker != null){
helpBroker.displayCurrentID(ContextHelpManager.getHelpIDString(rootPane));
}
}
}, keystroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
}
else{
if (comp instanceof JComponent){
KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0, false);
((JComponent)comp).registerKeyboardAction(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if (helpBroker != null){
helpBroker.displayCurrentID(ContextHelpManager.getHelpIDString(comp));
}
}
}, keystroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
}
}
}
/**
* Set a tool tip for a component from a resource in the factory's resource
* bundle.
* By convention, tool tip resources end in ".tip". Most
* components created by this factory will already have a tool tip set, so
* this method need not be called for them.
* Also, the component's accessible description text will automatically
* be set to the supplied tooltip text.
* The resources used are:
*
* uiKey.tip | the tool tip for the component
* |
* @param c the component for which to set the tool tip
* @param uiKey the base name of the resource to be used
*/
public void setToolTip(JComponent c, String uiKey) {
String text = getI18NString(uiKey + ".tip");
c.setToolTipText(text);
// workaround - tooltip doesn't get copied from this component
// see JComponent.AccessibleJComponent.getToolTipText()
c.getAccessibleContext().setAccessibleDescription(text);
}
/**
* Sets only the accessible description for the given context, using the
* given key.
*
* uiKey.desc | accessible description
* |
* @param c the component to modify
* @param uiKey the base name of the resource to be used
* @see #setAccessibleDescription(AccessibleContext,String)
*/
public void setAccessibleDescription(Component c, String uiKey) {
setAccessibleDescription(c.getAccessibleContext(), uiKey);
}
/**
* Sets only the accessible description for the given context, using the
* given key.
*
* uiKey.desc | accessible description
* |
* @param c the context object to modify
* @param uiKey the base name of the resource to be used
*/
public void setAccessibleDescription(AccessibleContext c, String uiKey) {
String text = getI18NString(uiKey + ".desc");
c.setAccessibleDescription(text);
}
/**
* Sets only the accessible name for the given context, using the
* given key.
* @param c the component object to modify
* @param uiKey the base name of the resource to be used
* @see #setAccessibleName(AccessibleContext,String)
*/
public void setAccessibleName(Component c, String uiKey) {
setAccessibleName(c.getAccessibleContext(), uiKey);
}
/**
* Sets only the accessible name for the given context, using the
* given key.
*
* uiKey.name | accessible name
* |
* @param c the context object to modify
* @param uiKey the base name of the resource to be used
*/
public void setAccessibleName(AccessibleContext c, String uiKey) {
String text = getI18NString(uiKey + ".name");
c.setAccessibleName(text);
}
/**
* Sets the accessible name and description for the given
* component.
* @param c the component object to modify
* @param uiKey the base name of the resource to be used
* @see #setAccessibleInfo(AccessibleContext,String)
*/
public void setAccessibleInfo(Component c, String uiKey) {
setAccessibleInfo(c.getAccessibleContext(), uiKey);
}
/**
* Sets the accessibility name and description for the given context
* using the given key as the base.
* The resources used are:
*
* uiKey.name | accessible name
* |
uiKey.desc | accessible description text
* |
* @param c the context object to modify
* @param uiKey the base name of the resource to be used
*/
public void setAccessibleInfo(AccessibleContext c, String uiKey) {
setAccessibleDescription(c, uiKey);
setAccessibleName(c, uiKey);
}
//----------------------------------------------------------------------------
//
// borders
/**
* Create a titled border, using a resource to specify the title.
* The resource used is:
*
* uiKey.bdr | the text for the title
* |
* @param uiKey the base name of the resource to be used
* @return the border that was created
*/
public Border createTitledBorder(String uiKey) {
return BorderFactory.createTitledBorder(null, getI18NString(uiKey + ".bdr"), TitledBorder.LEADING, TitledBorder.DEFAULT_JUSTIFICATION, getBaseFont(), Colors.TEXT_COLOR.getValue());
}
//----------------------------------------------------------------------------
//
// white space
/**
* Create a horizontal filler that expands to fill the available space.
* The name of the glue component will be set to uikey. No resource
* strings are required at this time.
* @param uiKey the base name of the resource to be used
* @return a filler component that expands to fill the available space
*/
public Component createHorizontalGlue(String uiKey) {
Component c = Box.createHorizontalGlue();
c.setName(uiKey);
c.setFocusable(false);
return c;
}
/**
* Create a filler that expands to fill the available space.
* @param uiKey the base name of the resource to be used
* @return a filler component that expands to fill the available space
*/
public Component createGlue(String uiKey) {
Component c = Box.createGlue();
c.setName(uiKey);
c.setFocusable(false);
return c;
}
/**
* Create a horizontal filler of a given width.
* @param width the desired width of the filler component
* @return a filler component of a given width
*/
public Component createHorizontalStrut(int width) {
Component c = Box.createHorizontalStrut(width);
c.setFocusable(false);
return c;
}
//----------------------------------------------------------------------------
//
// buttons
/**
* Create a button, using resources to specify the name and the tool tip.
* The resources used are:
*
* uiKey.btn | the name for the button
* |
uiKey.tip | the tool tip for the button
* |
* In addition, the name of the button and the action command
* for the button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @return the button that was created
* @see #createHelpButton
* @see #createIconButton
*/
public JButton createButton(String uiKey) {
JButton b = new JButton(getI18NString(uiKey + ".btn"));
b.setActionCommand(uiKey);
b.setName(uiKey);
setMnemonic(b, uiKey);
setToolTip(b, uiKey);
return b;
}
/**
* Create a button based on the information in an Action.
* @param a the Action for which to define the button
* @return the button that was created
*/
public JButton createButton(Action a) {
JButton b = new JButton(a);
b.setName((String) (a.getValue(Action.NAME)));
return b;
}
/**
* Create a button containing an Icon.
* @param uiKey the base name of the resource to be used
* @param icon the icon to appear in the button
* @return the button that was created
*/
public JButton createButton(String uiKey, Icon icon) {
JButton b = new JButton(icon);
b.setName(uiKey);
setMnemonic(b, uiKey);
setToolTip(b, uiKey);
return b;
}
/**
* Create a button, using resources to specify the name and the tool tip,
* and with a specified ActionListener.
* The resources used are:
*
* uiKey.btn | the name for the button
* |
uiKey.tip | the tool tip for the button
* |
* In addition, the name of the button and the action command
* for the button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param l the ActionListener to be add to the button
* @return the button that was created
*/
public JButton createButton(String uiKey, ActionListener l) {
JButton b = createButton(uiKey);
b.addActionListener(l);
return b;
}
/**
* Create a button, using resources to specify the name and the tool tip,
* and with a specified ActionListener and action command.
* The resources used are:
*
* uiKey.btn | the name for the button
* |
uiKey.tip | the tool tip for the button
* |
* In addition, the name of the button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param l the ActionListener to be add to the button
* @param cmd the action command to be set for the button
* @return the button that was created
*/
public JButton createButton(String uiKey, ActionListener l, String cmd) {
JButton b = createButton(uiKey);
b.setActionCommand(cmd);
b.addActionListener(l);
return b;
}
/**
* Constant to identify the cancellation option.
*/
public static final String CANCEL = "cancel";
/**
* Special method to create a cancel button. Differs from a
* standard button because it does not require a mnemonic, per
* the Java Look and Feel standard.
* @param uiKey key to use to get the tooltip with
* @return the button that was created
*/
public JButton createCancelButton(String uiKey) {
return createCancelButton(uiKey, closeListener);
}
/**
* Special method to create a cancel button. Differs from a
* standard button because it does not require a mnemonic, per
* the Java Look and Feel standard.
* @param uiKey key to use to get the tooltip with
* @param l listener to attach to the created button
* @return the button that was created
*/
public JButton createCancelButton(String uiKey, ActionListener l) {
JButton b;
I18NResourceBundle save_i18n = i18n;
try {
i18n = local_i18n;
b = new JButton(getI18NString("uif.cancel.btn"));
// no mnemonic for Cancel buttons
}
finally {
i18n = save_i18n;
}
b.setActionCommand(CANCEL);
b.addActionListener(l);
b.setName(uiKey);
setToolTip(b, uiKey);
return b;
}
/**
* Create a Close button, that will close the containing window when pressed,
* using a resource to specify the information for the button.
* The resources used are:
*
* uiKey.btn | the name for the button
* |
uiKey.mne | the mnemonic for the button
* |
uiKey.tip | the tool tip for the button
* |
* In addition, the name of the button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @return the button that was created
* @see #createButton
*/
public JButton createCloseButton(String uiKey) {
return createCloseButton(uiKey, true);
}
/**
* Create a Close button, that will close the containing window when pressed,
* using a resource to specify the information for the button.
* The resources used are:
*
* uiKey.btn | the name for the button
* |
uiKey.mne | the mnemonic for the button, if required
* |
uiKey.tip | the tool tip for the button
* |
* In addition, the name of the button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param needMnemonic a boolean indicating whether or not a mnemonic should be
* set on the button. If the button is going to be the default button for a
* dialog, it does not need a mnemonic.
* @return the button that was created
* @see #createButton
*/
public JButton createCloseButton(String uiKey, boolean needMnemonic) {
JButton b = new JButton(getI18NString(uiKey + ".btn"));
b.setName(uiKey);
if (needMnemonic)
setMnemonic(b, uiKey);
setToolTip(b, uiKey);
b.addActionListener(closeListener);
return b;
}
/**
* Create a Help button, that will display a specific help topic when pressed,
* using a resource to specify the tool tip for the button.
* The resource used is:
*
* uiKey.tip | the tool tip for the button
* |
* In addition, the name of the button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param helpID the help ID for the help topic to be displayed when the
* button is pressed
* @return the button that was created
* @see #createButton
*/
public JButton createHelpButton(String uiKey, final String helpID) {
JButton hb = createButton(uiKey);
hb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (helpBroker != null) {
helpBroker.displayCurrentID(helpID);
}
}
});
return hb;
}
/**
* Create a button containing an icon, using resources to specify the
* icon image and the tool tip.
* The resources used are:
*
* uiKey.icon | the name of the resource for the icon image
* |
uiKey.tip | the tool tip for the button
* |
* @param uiKey the base name of the resource to be used
* @return the button that was created
*/
public JButton createIconButton(String uiKey) {
JButton b = createButton(uiKey, createIcon(uiKey));
b.setBorder(BorderFactory.createEmptyBorder());
return b;
}
/**
* Create a button containing an icon, using resources to specify the
* icon image and the tool tip.
* The resources used are:
*
* uiKey.icon | the name of the resource for the icon image
* |
uiKey.tip | the tool tip for the button
* |
* @param uiKey the base name of the resource to be used
* @param l the action listener to attach to the new button
* @return the button that was created
*/
public JButton createIconButton(String uiKey, ActionListener l) {
JButton b = createButton(uiKey, createIcon(uiKey));
b.addActionListener(l);
return b;
}
// note this uses local_i18n, not the client i18n
private JButton createOptionButton(String uiKey) {
I18NResourceBundle save_i18n = i18n;
try {
i18n = local_i18n;
JButton b = createButton(uiKey, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Component c = (Component) (e.getSource());
JOptionPane op = (JOptionPane) SwingUtilities.getAncestorOfClass(JOptionPane.class, c);
op.setValue(c); // JOptionPane expects the value to be set to the selected button
op.setVisible(false);
}
});
return b;
}
finally {
i18n = save_i18n;
}
}
/**
* Create a radio button, using resources to specify the name and tool tip.
* The button is initially set to false
.
* The resources used are:
*
* uiKey.rb | the label for the button
* |
uiKey.tip | the tool tip for the button
* |
uiKey.mne | the mnemonic for the button
* |
* In addition, the name of the button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param group the group to which the check box will be added
* @return the radio button that was created
* @see #createButton
* @see #createCheckBox
*/
public JRadioButton createRadioButton(String uiKey, ButtonGroup group) {
String text = getI18NString(uiKey + ".rb");
JRadioButton btn = new JRadioButton(text, true);
btn.setName(uiKey);
btn.setSelected(false); // workaround Merlin bug
setMnemonic(btn, uiKey);
setToolTip(btn, uiKey);
group.add(btn);
return btn;
}
/**
* Set the mnemonic a button.
* The resources used are:
*
* uiKey.mne | The keystroke to use
* |
* @param b the button to modify
* @param uiKey the base name of the resources to be used
* @see javax.swing.KeyStroke
*/
public void setMnemonic(AbstractButton b, String uiKey) {
// NOTE: Swing is misleading; it uses an integer value for the mnemonic
// but according to SwingUtilities.findDisplayedMnemonicIndex it is always
// the literal character for the mnemonic, and not anything fancy like
// an integer keycode
int mne = getI18NMnemonic(uiKey + ".mne");
if (mne != 0)
b.setMnemonic(mne);
}
//----------------------------------------------------------------------------
//
// check boxes
/**
* Create a check box, using resources to specify the name and the tool tip.
* The resources used are:
*
* uiKey.ckb | the name for the check box
* |
uiKey.tip | the tool tip for the button
* |
uiKey.mne | the mnemonic for the button
* |
* In addition, the name of the check box is set to uiKey.
* @param uiKey the base name of the resources to be used
* @return the check box that was created
* @see #createCheckBoxMenuItem
*/
public JCheckBox createCheckBox(String uiKey) {
return createCheckBox(uiKey, false, null);
}
/**
* Create a check box, using resources to specify the name and the tool tip.
* The resources used are:
*
* uiKey.ckb | the name for the check box
* |
uiKey.tip | the tool tip for the button
* |
uiKey.mne | the mnemonic for the button
* |
* In addition, the name of the check box is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param state the initial state of the check box
* @return the check box that was created
* @see #createCheckBoxMenuItem
*/
public JCheckBox createCheckBox(String uiKey, boolean state) {
return createCheckBox(uiKey, state, null);
}
/**
* Create a check box, using resources to specify the name and the tool tip,
* within a specified button group.
* The resources used are:
*
* uiKey.ckb | the name for the check box
* |
uiKey.tip | the tool tip for the button
* |
uiKey.mne | the mnemonic for the button
* |
* In addition, the name of the check box is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param state the initial state of the check box
* @param group the group to which the check box will be added
* @return the check box that was created
*/
public JCheckBox createCheckBox(String uiKey, boolean state, ButtonGroup group) {
String ckbKey = uiKey + ".ckb";
JCheckBox b = new JCheckBox(getI18NString(ckbKey), state);
b.setName(uiKey);
if (group != null)
group.add(b);
setMnemonic(b, uiKey);
setToolTip(b, uiKey);
return b;
}
//----------------------------------------------------------------------------
//
// choice lists
/**
* Create a choice item, using resources to specify the choices and the
* tool tip.
* The resources used are:
*
* uiKey.choiceKeysi.chc | the choice to appear in the item, for 0 <= i < choiceKeys.length
* |
uiKey.name | the accessible name for the selector
* |
uiKey.tip | the tool tip for the choice item
* |
* In addition, the name of the choice is set to uiKey.
* Note: the choice item is created with the choices set to the names
* of the resources used -- not the values. This means that the client can
* examine and manipulate the choices, including the selected choice,
* as location-independent resource names. A custom renderer is used to
* ensure that the correctly localized value is displayed to the user.
* @param uiKey the base name of the resources to be used for the menu
* @param choiceKeys an array of strings used to construct the resource
* names for the choices.
* @return the choice item that was created
* @see #createLiteralChoice
*/
public JComboBox createChoice(final String uiKey, final String[] choiceKeys) {
return createChoice(uiKey, choiceKeys, false);
}
/**
* Same as the two parameter createChoice
, except you can
* make this an mutable choice component (freeform editing of the
* response). If the component is to be editable, an additional
* uiKey.ed resource is needed to set the component name of the
* editable field which will be onscreen.
* @param uiKey the base name of the resources to be used for the menu
* @param choiceKeys an array of strings used to construct the resource
* names for the choices.
* @param editable True if the choice component should allow freeform
* editing of the response.
* @return a choice box with the attributes indicated by the parameters
* @see #createChoice(String,String[])
*/
public JComboBox createChoice(final String uiKey, final String[] choiceKeys, boolean editable) {
// create a cache of the presentation string, for use when
// rendering, but otherwise, let the JComboBox work in terms of the
// choiceKeys
final String[] choices = new String[choiceKeys.length];
for (int i = 0; i < choices.length; i++)
choices[i] = getI18NString(uiKey + "." + choiceKeys[i] + ".chc");
JComboBox choice = new JComboBox(choiceKeys);
choice.setName(uiKey);
setToolTip(choice, uiKey);
setAccessibleName(choice, uiKey);
choice.setEditable(editable);
if (editable) {
Component editComp = choice.getEditor().getEditorComponent();
if (editComp instanceof Accessible) {
if (editComp.getName() == null)
editComp.setName(uiKey + ".ed");
AccessibleContext ac = choice.getAccessibleContext();
AccessibleContext ed_ac = editComp.getAccessibleContext();
ed_ac.setAccessibleName(ac.getAccessibleName());
ed_ac.setAccessibleDescription(ac.getAccessibleDescription());
}
}
choice.setRenderer(new DefaultListCellRenderer() {
public Component getListCellRendererComponent(JList list, Object o, int index,
boolean isSelected, boolean cellHasFocus) {
Object c = o;
for (int i = 0; i < choiceKeys.length; i++) {
if (choiceKeys[i] == o) {
c = choices[i];
break;
}
}
return super.getListCellRendererComponent(list, c, index, isSelected, cellHasFocus);
}
});
return choice;
}
/**
* Create an empty choice item, using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the choice item
* |
* In addition, the name of the choice is set to uiKey.
* @param uiKey the base name of the resources to be used for the menu
* @return the choice component that was created
*/
public JComboBox createChoice(String uiKey) {
return createChoice(uiKey, false);
}
/**
* Same as single parameter version, except you can select a
* component that allows freeform editing of the user's response.
* @param uiKey the base name of the resources to be used for the menu
* @param editable True if the user should be allowed to edit the
* response.
* @return the choice component that was created
* @see #createChoice(String)
*/
public JComboBox createChoice(String uiKey, boolean editable) {
return createChoice(uiKey, editable, (JLabel) null);
}
/**
* Same as the one parameter version, except a label can be
* associated with this component. This is to support accessibility.
* @param uiKey the base name of the resources to be used for the menu
* @param label Label to associate with this component
* @return the choice component that was created
* @see #createChoice(String)
* @see javax.swing.JLabel#setLabelFor
*/
public JComboBox createChoice(String uiKey, JLabel label) {
return createChoice(uiKey, false, label);
}
/**
* Combination of the two parameter methods, allowing you to select
* a mutable response and associate a label.
* @param uiKey the base name of the resources to be used for the menu
* @param editable True if the user should be allowed to edit the
* response.
* @param label Label to associate with this component
* @return a choice box with the attributes indicated by the parameters
* @see #createChoice(String,JLabel)
* @see #createChoice(String,boolean)
* @see #createChoice(String)
* @see javax.swing.JLabel#setLabelFor
*/
public JComboBox createChoice(String uiKey, boolean editable, JLabel label) {
JComboBox choice = new JComboBox();
choice.setName(uiKey);
setToolTip(choice, uiKey);
if (label != null)
label.setLabelFor(choice);
else
setAccessibleName(choice, uiKey);
choice.setEditable(editable);
if (editable) {
Component editComp = choice.getEditor().getEditorComponent();
if (editComp instanceof Accessible) {
if (editComp.getName() == null)
editComp.setName(uiKey + ".ed");
AccessibleContext ac = choice.getAccessibleContext();
AccessibleContext ed_ac = editComp.getAccessibleContext();
ed_ac.setAccessibleName(ac.getAccessibleName());
ed_ac.setAccessibleDescription(ac.getAccessibleDescription());
}
}
return choice;
}
/**
* Create an choice item containing literal choices,
* and using a resource to specify the tool tip.
* The choices appear as given: for example, this method might be used to
* create a choice item containing a set of filenames from which to choose.
* Note that if the choices are strings, they should probably be localized, and
* if they are otherwise should probably be shown to the user using a renderer
* which produces localized output.
* The resource used is:
*
* uiKey.tip | the tool tip for the choice item
* |
* In addition, the name of the choice is set to uiKey.
* @param uiKey the base name of the resources to be used for the menu
* @param choices the choices to appear in the choice item
* @return the choice item that was created
* @see #createChoice
*/
public JComboBox createLiteralChoice(String uiKey, E[] choices) {
JComboBox choice = new JComboBox<>(choices);
choice.setName(uiKey);
setToolTip(choice, uiKey);
return choice;
}
//----------------------------------------------------------------------------
//
// icons, images etc
/**
* Create an icon, using a resource to specify the image.
* The resource used is:
*
* uiKey.icon | the name of a resource containing the image
* |
* @param uiKey the base name of the resource to be used
* @return the icon that was created
* @throws MissingResourceException if the image resource cannot be found
* @see #createIconButton
*/
public Icon createIcon(String uiKey) {
return new ImageIcon(getIconURL(uiKey));
}
/**
* Get the resource URL for an icon specified in a resource bundle.
* The resource used is:
*
* uiKey.icon | the name of a resource containing the image
* |
* @param uiKey the base name of the resource to be used
* @return the URL for the resource obtained from the resource bundle
* @throws MissingResourceException if the image resource cannot be found
*/
public URL getIconURL(String uiKey) {
String r = getI18NString(uiKey + ".icon");
URL url = clientClass.getResource(r);
if (url == null)
throw new MissingResourceException(r, clientClass.getName(), r);
return url;
}
/**
* Create a label containing an icon, using a resource to specify the
* icon image.
* The resource used is:
*
* uiKey.icon | the name of the resource for the icon image
* |
* @param uiKey the base name of the resource to be used
* @return the image that was created
* @throws MissingResourceException if the image resource cannot be found
* @see #createLabel
*/
public JLabel createIconLabel(String uiKey) {
return new JLabel(createIcon(uiKey));
}
/**
* Create an image from a named resource.
* @param r The resource containing the image data.
* @return the image that was created
* @throws MissingResourceException if the image resource cannot be found
*/
public Image createImage(String r) {
URL url = getClass().getResource(r);
if (url == null)
throw new MissingResourceException(r, clientClass.getName(), r);
return Toolkit.getDefaultToolkit().getImage(url);
}
//----------------------------------------------------------------------------
//
// labels
/**
* Create a label, using a resource to specify the text.
* The resource used is:
*
* uiKey.lbl | the text for the label
* |
* @param uiKey the base name of the resource to be used
* @return the label that was created
* @see #createIconLabel
*/
public JLabel createLabel(String uiKey) {
return createLabel(uiKey, false);
}
/**
* Create a label, using a resource to specify the text and an optional mnemonic.
* The resource used is:
*
* uiKey.lbl | the text for the label
* |
uiKey.tip | the tooltip text for the label
* |
uiKey.mne | the mnemonic for the label
* |
* @param uiKey the base name of the resource to be used
* @param need508 whether or not a mnemonic and tooltip should be set for this label
* @return the label that was created
* @see #createIconLabel
*/
public JLabel createLabel(String uiKey, boolean need508) {
JLabel l = new JLabel(getI18NString(uiKey + ".lbl"));
l.setName(uiKey);
if (need508) {
setToolTip(l, uiKey);
l.setDisplayedMnemonic(getI18NMnemonic(uiKey + ".mne"));
}
return l;
}
//----------------------------------------------------------------------------
//
// lists
/**
* Create an input text field, using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
/**
* Create an empty list component.
* Note: list components do not currently support tool tips.
* When they do, this method will use a resource to specify the tool tip.
* The resources used are:
*
* uiKey.name | the accessible name of the list
* |
uiKey.desc | the accessible description of the list
* |
* @param uiKey the base name of the resource to be used (currently ignored)
* @return the list that was created
*/
public JList createList(String uiKey) {
JList list = new JList<>();
list.setName(uiKey);
setAccessibleInfo(list, uiKey);
return list;
}
/**
* Create a list component with a given data model.
* Note: list components do not currently support tool tips.
* When they do, this method will use a resource to specify the tool tip.
* The resources used are:
*
* uiKey.name | the accessible name of the list
* |
uiKey.desc | the accessible description of the list
* |
* @param uiKey the base name of the resource to be used (currently ignored)
* @param model the data model for this list
* @return the list that was created
*/
public JList createList(String uiKey, ListModel model) {
JList list = new JList<>(model);
list.setName(uiKey);
setAccessibleInfo(list, uiKey);
return list;
}
//----------------------------------------------------------------------------
//
// menus
/**
* Create an empty menu bar, using resources to specify the accessible info.
* The resources used are:
*
* uiKey.name | the accessible name text
* |
uiKey.desc | accessible description text
* |
* @param uiKey the base name of the resource to be used
* @return the menu bar that was created
*/
public JMenuBar createMenuBar(String uiKey) {
JMenuBar mb = new JMenuBar();
mb.setName(uiKey);
setAccessibleInfo(mb, uiKey);
return mb;
}
/**
* Create an empty menu, using resources to specify the name and mnemonic.
* The resources used are:
*
* uiKey.menu | the display name of the menu
* |
uiKey.mne | the single character mnemonic for the menu
* |
uiKey.desc | accessible description text
* |
* @param uiKey the base name of the resource to be used
* @return the menu that was created
* @see #createPopupMenu
*/
public JMenu createMenu(String uiKey) {
JMenu m = new JMenu();
initMenu(m, uiKey);
return m;
}
/**
* Initialize an empty menu, using resources to specify the name and mnemonic.
* The resources used are:
*
* uiKey.menu | the display name of the menu
* |
uiKey.mne | the single character mnemonic for the menu
* |
uiKey.desc | accessible description text
* |
* @param m the menu the be initialized
* @param uiKey the base name of the resource to be used
* @see #createPopupMenu
*/
public void initMenu(JMenu m, String uiKey) {
m.setName(uiKey);
m.setText(getI18NString(uiKey + ".menu"));
setMnemonic(m, uiKey);
setAccessibleDescription(m, uiKey);
}
/**
* Create a menu, using actions to specify the menu items,
* and using resources to specify the name and mnemonic.
* The resources used are:
*
* uiKey.menu | the display name of the menu
* |
uiKey.mne | the single character mnemonic for the menu
* |
* @param uiKey the base name of the resources to be used
* @param actions the actions from which to create the menu items;
* use null in the array to indicate if and where a separator is required
* @return the menu that was created
* @see #createMenuItem(Action)
*/
public JMenu createMenu(String uiKey, Action[] actions) {
JMenu m = createMenu(uiKey);
for (int i = 0; i < actions.length; i++) {
Action action = actions[i];
if (action == null)
m.addSeparator();
else
m.add(createMenuItem(action));
}
return m;
}
/**
* Create a menu using resources and an action listener to specify
* the menu items, and using resources to specify the name and mnemonic.
* The resources used are:
*
* uiKey.menu | the display name of the menu
* |
uiKey.mne | the single character mnemonic for the menu
* |
uiKey.actionsi.mit | the text for the menu item, for 0 <= i < choiceKeys.length
* |
uiKey.actionsi.mne | the single character mnemonic for the menu item, for 0 <= i < choiceKeys.length
* |
* @param uiKey the base name of the resources to be used
* @param actions the qualifying names for the resources for the
* individual menu items; use null in the array to indicate if
* and where a separator is required
* @param l the action listener to be used for each menu item
* @return the menu that was created
* @see #createMenuItem(String, String, ActionListener)
*/
public JMenu createMenu(String uiKey, String[] actions, ActionListener l) {
JMenu m = new JMenu();
initMenu(m, uiKey, actions, l);
return m;
}
/**
* Initialize a menu using resources and an action listener to specify
* the menu items, and using resources to specify the name and mnemonic.
* The resources used are:
*
* uiKey.menu | the display name of the menu
* |
uiKey.mne | the single character mnemonic for the menu
* |
uiKey.actionsi.mit | the text for the menu item, for 0 <= i < choiceKeys.length
* |
uiKey.actionsi.mne | the single character mnemonic for the menu item, for 0 <= i < choiceKeys.length
* |
* @param m the menu the be initialized
* @param uiKey the base name of the resources to be used
* @param actions the qualifying names for the resources for the
* individual menu items; use null in the array to indicate if
* and where a separator is required
* @param l the action listener to be used for each menu item
* @see #createMenuItem(String, String, ActionListener)
*/
public void initMenu(JMenu m, String uiKey, String[] actions, ActionListener l) {
initMenu(m, uiKey);
for (int i = 0; i < actions.length; i++) {
String action = actions[i];
if (action == null)
m.addSeparator();
else
m.add(createMenuItem(uiKey, action, l));
}
}
/**
* Create an empty popup menu.
* @param uiKey the base name of the resource to be used (currently ignored)
* @return the popup menu that was created
* @see #createMenu
*/
public JPopupMenu createPopupMenu(String uiKey) {
return new JPopupMenu(/*getI18NString(uiKey + ".pop")*/);
}
/**
* Create an popup menu.
* @param uiKey the base name of the resource to be used
* @param actions the qualifying names for the resources for the
* individual menu items; use null in the array to indicate if
* and where a separator is required
* @param l the action listener to be used for each menu item
* @return the popup menu that was created
* @see #createMenu
*/
public JPopupMenu createPopupMenu(String uiKey, String[] actions, ActionListener l) {
JPopupMenu m = createPopupMenu(uiKey);
for (int i = 0; i < actions.length; i++) {
String action = actions[i];
if (action == null)
m.addSeparator();
else
m.add(createMenuItem(uiKey, action, l));
}
return m;
}
//----------------------------------------------------------------------------
//
// menu items
/**
* Create a menu item for an action.
* The name of the item is set to the action name.
* @param action from which to create the menu item
* @return the menu item that was created
* @see #createMenu(String, Action[])
*/
public JMenuItem createMenuItem(Action action) {
JMenuItem item = new JMenuItem(action);
item.setName((String)(action.getValue(Action.NAME)));
// could (should?) ensure everything is set correctly
return item;
}
/**
* Create a menu item, using resources to specify the text and mnemonic.
* The resources used are:
*
* uiKey.action.mit | the text for the menu item
* |
uiKey.action.mne | the single character mnemonic for the menu item
* |
* @param uiKey the base name of the resources to be used
* @param action the qualifying name for the resources for the menu item
* @param l the action listener for the menu item
* @return the menu item that was created
* @see #createMenu(String, String[], ActionListener)
*/
public JMenuItem createMenuItem(String uiKey, String action, ActionListener l) {
JMenuItem item = new JMenuItem(getI18NString(uiKey + "." + action + ".mit"));
item.setActionCommand(action);
item.addActionListener(l);
item.setName(action);
setMnemonic(item, uiKey + "." + action);
return item;
}
/**
* Create a check box menu item, using resources to specify the
* name and the tool tip.
* The resources used are:
*
* uiKey.name.ckb | the name for the menu item
* |
uiKey.name.tip | the tool tip for the menu item
* |
* In addition, the name of the check box is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param name a qualifying name for the resources used for this menu item
* @param state the initial state of the check box
* @return the check box that was created
*/
public JCheckBoxMenuItem createCheckBoxMenuItem(String uiKey, String name, boolean state) {
String uiKey_name = uiKey + "." + name;
String ckbKey = uiKey_name + ".ckb";
JCheckBoxMenuItem b = new JCheckBoxMenuItem(getI18NString(ckbKey), state);
b.setName(uiKey_name);
setMnemonic(b, uiKey_name);
setToolTip(b, uiKey_name);
return b;
}
/**
* Create a Help menu item, that will display a specific help topic when pressed,
* using resources to specify the name and mnemonic for the item.
* The resource used is:
*
* uiKey.mit | the text for the menu item
* |
uiKey.mne | the mnemonic for the menu item
* |
* In addition, the name of the choice is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param helpID the help ID for the help topic to be displayed when the
* button is pressed
* @return the button that was created
* @see #createButton
*/
public JMenuItem createHelpMenuItem(String uiKey, final String helpID) {
JMenuItem mi = new JMenuItem(getI18NString(uiKey + ".mit"));
setMnemonic(mi, uiKey);
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (helpBroker != null) {
helpBroker.displayCurrentID(helpID);
}
}
});
return mi;
}
/**
* Create a menu item for a literal string and a specified listener.
* No mnemonic key nor descriptive action is added.
* @param literal the text for the menu item
* @param l the action listener to add to the menu item
* @return the menu item that was created
*/
public JMenuItem createLiteralMenuItem(String literal, ActionListener l) {
JMenuItem item = new JMenuItem(literal);
item.addActionListener(l);
return item;
}
/**
* Create a check box menu item, using resources to specify the
* name and the tool tip.
* The resources used are:
*
* uiKey.name.ckb | the name for the menu item
* |
uiKey.name.tip | the tool tip for the menu item
* |
* In addition, the name of the radio button is set to uiKey.
* @param uiKey the base name of the resources to be used
* @param name a qualifying name for the resources used for this menu item
* @return the check box that was created
*/
public JRadioButtonMenuItem createRadioButtonMenuItem(String uiKey, String name) {
String uiKey_name = uiKey + "." + name;
String radKey = uiKey_name + ".rad";
JRadioButtonMenuItem b = new JRadioButtonMenuItem(getI18NString(radKey));
b.setName(uiKey_name);
setMnemonic(b, uiKey_name);
setToolTip(b, uiKey_name);
return b;
}
//----------------------------------------------------------------------------
//
// scrollpane
/**
* Surround a component in a scroll pane.
* The name of the scroll pane component is set to c.getName()
* plus the .sp suffix.
* @param c The component to put into the scroll pane.
* @return a scroll pane component with the given component inside
*/
public JScrollPane createScrollPane(JComponent c) {
JScrollPane sp = new JScrollPane(c);
sp.setName(c.getName() == null ? "sp" : c.getName() + ".sp");
sp.setFocusable(false);
return sp;
}
/**
* Same as the single argument version, with options for altering
* the scrollbar appearance policy.
* @param c The component to put into the scroll pane.
* @param vsp vertical scrollbar policy setting
* @param hsp horizontal scrollbar policy setting
* @return a scroll pane component with the given component inside
* @see javax.swing.ScrollPaneConstants
* @see javax.swing.JScrollPane
*/
public JScrollPane createScrollPane(JComponent c, int vsp, int hsp) {
JScrollPane sp = new JScrollPane(c, vsp, hsp);
sp.setName(c.getName() == null ? "sp" : c.getName() + ".sp");
sp.setFocusable(false);
return sp;
}
//----------------------------------------------------------------------------
//
// slider
/**
* Create a slider, using resources to specify the the tool tip.
* The resource used is:
*
* uiKey.name.tip | the tool tip for the menu item
* |
* @param uiKey the base name of the resources to be used
* @param min the minimum value for the slider
* @param max the maximum value for the slider
* @param value the initial value for the slider
* @return the slider that was created
*/
public JSlider createSlider(String uiKey, int min, int max, int value) {
JSlider s = new JSlider(min, max, value);
setToolTip(s, uiKey);
return s;
}
//----------------------------------------------------------------------------
//
// split pane
/**
* Create an empty split pane with the given orientation.
* @param orient The split's orientation.
* @return The empty split pane component.
* @see javax.swing.JSplitPane#VERTICAL_SPLIT
* @see javax.swing.JSplitPane#HORIZONTAL_SPLIT
*/
public JSplitPane createSplitPane(int orient) {
JSplitPane sp = new JSplitPane(orient);
sp.setName("split");
setSplitPaneInfo(sp);
return sp;
}
/**
* Create an empty split pane with the given components inside.
* @param orient The split's orientation.
* @param c1 first component (left)
* @param c2 first component (right)
* @return The populated split pane component.
* @see javax.swing.JSplitPane
* @see javax.swing.JSplitPane#VERTICAL_SPLIT
* @see javax.swing.JSplitPane#HORIZONTAL_SPLIT
*/
public JSplitPane createSplitPane(int orient, Component c1, Component c2) {
JSplitPane sp = new JSplitPane(orient, c1, c2);
sp.setName("split");
setSplitPaneInfo(sp);
return sp;
}
private void setSplitPaneInfo(JSplitPane sp) {
// set a11y info manually using local bundle
AccessibleContext ac = sp.getAccessibleContext();
if (sp.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
ac.setAccessibleName(local_i18n.getString("uif.sp.hor.name"));
ac.setAccessibleDescription(local_i18n.getString("uif.sp.hor.desc"));
}
else {
ac.setAccessibleName(local_i18n.getString("uif.sp.vert.name"));
ac.setAccessibleDescription(local_i18n.getString("uif.sp.vert.desc"));
}
}
//----------------------------------------------------------------------------
//
// spinners - not accessible as of JDK 1.5, so it's commented out here!
/**
* Create a spinner.
* @param uiKey the base name of the resources to be used
* @return a spinner component
* The resources used are:
*
* uiKey.name | the accessible name for the tab pane.
* Where name is the literal string "name".
* |
uiKey.tip | the accessible name for the tab pane.
* Where tip is the literal string "tip".
* |
* The tooltip will automatically be transferred to the pane's accessible
* description. Use setAccessibleDescription()
to set it
* independently.
public JSpinner createSpinner(String uiKey, SpinnerModel model) {
JSpinner s = new JSpinner(model);
s.setName(uiKey);
setAccessibleName(s, uiKey);
setToolTip(s, uiKey);
return s;
}
*/
//----------------------------------------------------------------------------
//
// tabbed paned
/**
* Create an empty tabbed pane.
* @param uiKey the base name of the resources to be used
* @return an empty (no tabs) tabbed pane
* The resources used are:
*
* uiKey.name | the accessible name for the tab pane.
* Where name is the literal string "name".
* |
uiKey.tip | the accessible name for the tab pane.
* Where tip is the literal string "tip".
* |
* The tooltip will automatically be transferred to the pane's accessible
* description. Use setAccessibleDescription()
to set it
* independently.
*/
public JTabbedPane createTabbedPane(String uiKey) {
JTabbedPane p = new JTabbedPane();
p.setName(uiKey);
setAccessibleName(p, uiKey);
setToolTip(p, uiKey);
return p;
}
/**
* Create a tabbed pane with a given set of component panes,
* using resources to determine the name and tool tip for each tab.
* The resources used are:
*
* uiKey.namei.tab | the display name for the tab,
* where namei is the component name for children[i]
* |
uiKey.namei.tip | the tool tip for the tab,
* where namei is the component name for children[i]
* |
uiKey.name | the accessible name for the tab pane.
* Where name is the literal string "name".
* |
uiKey.tip | the accessible name for the tab pane.
* Where tip is the literal string "tip".
* |
* The tooltip will automatically be transferred to the pane's accessible
* description. Use setAccessibleDescription()
to set it
* independently.
* @param uiKey the base name of the resources to be used
* @param children an array of components to be added into the tabbed pane
* @return the tabbed pane that was created
* @see #setAccessibleDescription(Component,String)
* @see #setAccessibleName(Component,String)
* @see #setToolTip(JComponent,String)
*/
public JTabbedPane createTabbedPane(String uiKey, JComponent[] children) {
JTabbedPane p = new JTabbedPane();
p.setName(uiKey);
setAccessibleName(p, uiKey);
for (int i = 0; i < children.length; i++) {
JComponent child = children[i];
addTab(p, uiKey + "." + child.getName(), child);
}
setToolTip(p, uiKey);
return p;
}
/**
* Add a component to a tabbed pane, using resources to specify
* the name and the tool tip for the tab.
* The resources used are:
*
* uiKey.tab | the name for the tab
* |
uiKey.tip | the tool tip for the tab
* |
* @param tPane the tabbed pane to which to add the component
* @param uiKey the base name of the resources to be used
* @param comp the component to be added
*/
public void addTab(JTabbedPane tPane, String uiKey, JComponent comp) {
String name = getI18NString(uiKey + ".tab");
String tip = getI18NString(uiKey + ".tip");
tPane.addTab(name, null, comp, tip);
}
//----------------------------------------------------------------------------
//
// tables
/**
* Create a table with a given data model.
* Resources used:
*
* uiKey.name | the accessible name for the tab pane.
* Where name is the literal string "name".
* |
uiKey.tip | the accessible name for the tab pane.
* Where tip is the literal string "tip".
* |
* The tooltip will automatically be transferred to the pane's accessible
* description. Use setAccessibleDescription()
to set it
* independently.
* @param uiKey the base name of the resources to be used (currently ignored)
* @param model the data model for the table
* @return the table that was created
* @see #setAccessibleDescription(Component,String)
* @see #setAccessibleName(Component,String)
* @see #setToolTip(JComponent,String)
*/
public JTable createTable(String uiKey, TableModel model) {
JTable tbl = new JTable(model);
setAccessibleName(tbl, uiKey);
setToolTip(tbl, uiKey);
return tbl;
}
//----------------------------------------------------------------------------
//
// text fields, text areas etc
/**
* Create a text field for use as a heading, using a resource to specify
* the heading.
* The resource used is:
*
* uiKey.txt | the text for the heading
* |
* In addition, the name of the output field is set to uiKey.
* @param uiKey the base name of the resource to be used
* @return the text field that was created
*/
public JTextField createHeading(String uiKey) {
String value = getI18NString(uiKey + ".txt");
JTextField tf = new JTextField(value, value.length());
tf.setName(uiKey);
tf.setEditable(false);
tf.setFont(tf.getFont().deriveFont(Font.BOLD));
tf.setBorder(BorderFactory.createEmptyBorder());
tf.setBackground(Colors.TRANSPARENT.color);
tf.setOpaque(false);
setAccessibleDescription(tf, uiKey);
setAccessibleName(tf, uiKey);
return tf;
}
/**
* Create an input text field, using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
* In addition, the name of the input field is set to uiKey.
* By default, the input field is 10 characters wide.
* @param uiKey the base name of the resource to be used
* @return the input field that was created
*/
public JTextField createInputField(String uiKey) {
return createInputField(uiKey, null);
}
/**
* Create an input text field, using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
* In addition, the name of the input field is set to uiKey.
* By default, the input field is 10 characters wide.
* @param uiKey the base name of the resource to be used
* @param label the label to associate with this component
* @return the input field that was created
*/
public JTextField createInputField(String uiKey, JLabel label) {
return createInputField(uiKey, 10, label);
}
/**
* Create an input text field with a specified number of columns,
* using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
* In addition, the name of the input field is set to uiKey.
* @param uiKey the base name of the resource to be used
* @param cols the default width of the field, in characters
* @return the input field that was created
* @see #createOutputField
*/
public JTextField createInputField(String uiKey, int cols) {
return createInputField(uiKey, cols, null);
}
/**
* Create an input text field with a specified number of columns,
* using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
* In addition, the name of the input field is set to uiKey.
* @param uiKey the base name of the resource to be used
* @param cols the default width of the field, in characters
* @param label the label to associate with this component
* @return the input field that was created
* @see #createOutputField
*/
public JTextField createInputField(String uiKey, int cols, JLabel label) {
JTextField tf = new JTextField("", cols) {
public Dimension getMinimumSize() {
return getPreferredSize();
}
};
if (label != null)
label.setLabelFor(tf);
else {
// this should be setAccessibleName(tf, uiKey); but that will break too much code
tf.setName(uiKey);
//setAccessibleName(tf, uiKey);
}
setToolTip(tf, uiKey);
return tf;
}
/**
* Create a message area, using a resource to specify the content.
* The message area will be transparent, uneditable, and word-wrapped.
* The resource used is:
*
* uiKey.txt | the text for the message area
* |
* @param uiKey the name of the resource to be used
* @return the message area that was created
*/
public JTextArea createMessageArea(String uiKey) {
return createLocalizedMessageArea(uiKey, getI18NString(uiKey + ".txt"), true);
}
/**
* Create a message area, using a resource to specify the content.
* The message area will be transparent, uneditable, and word-wrapped.
* The resource used is:
*
* uiKey.txt | the text for the message area
* |
uiKey.name | accessible name
* |
uiKey.desc | accessible description text
* |
* @param uiKey the name of the resource to be used
* @param arg an argument to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @return the message area that was created
*/
public JTextArea createMessageArea(String uiKey, Object arg) {
return createLocalizedMessageArea(uiKey, getI18NString(uiKey + ".txt", arg), true);
}
/**
* Create a message area, using a resource to specify the content.
* The message area will be transparent, uneditable, and word-wrapped.
* The resource used is:
*
* uiKey.txt | the text for the message area
* |
uiKey.name | accessible name
* |
uiKey.desc | accessible description text
* |
* @param uiKey the name of the resource to be used
* @param args an array of arguments to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @return the message area that was created
*/
public JTextArea createMessageArea(String uiKey, Object[] args) {
return createLocalizedMessageArea(uiKey, getI18NString(uiKey + ".txt", args), true);
}
/**
* Only use this method if the origin of the message text is not coming from
* a bundle.
*/
private JTextArea createLiteralMessageArea(String msg) {
JTextArea txt = new JTextArea(msg);
txt.setName("literal");
txt.setOpaque(false);
txt.setEditable(false);
txt.setLineWrap(true);
txt.setWrapStyleWord(true);
// The height is effectively ignored in the next line (just don't use 0.)
// The text will be laid out, wrapping lines, for the width, and the
// preferred height will thereby be determined accordingly.
txt.setSize(new Dimension(7 * DOTS_PER_INCH, Integer.MAX_VALUE));
// override JTextArea focus traversal keys, resetting them to
// the Component default (i.e. the same as for the parent.)
txt.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
txt.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
AccessibleContext ac = txt.getAccessibleContext();
ac.setAccessibleName(local_i18n.getString("uif.message.name"));
ac.setAccessibleDescription(local_i18n.getString("uif.message.desc"));
return txt;
}
/**
* @param std True if this area should be made accessible.
*/
private JTextArea createLocalizedMessageArea(String uiKey, String msg, boolean std) {
JTextArea txt = new JTextArea(msg);
txt.setName(uiKey);
txt.setOpaque(false);
txt.setBackground(Colors.TRANSPARENT.getValue());
txt.setEditable(false);
txt.setLineWrap(true);
txt.setWrapStyleWord(true);
// The height is effectively ignored in the next line (just don't use 0.)
// The text will be laid out, wrapping lines, for the width, and the
// preferred height will thereby be determined accordingly.
txt.setSize(new Dimension(7 * DOTS_PER_INCH, Integer.MAX_VALUE));
// override JTextArea focus traversal keys, resetting them to
// the Component default (i.e. the same as for the parent.)
txt.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
txt.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
if (std) {
AccessibleContext ac = txt.getAccessibleContext();
ac.setAccessibleName(local_i18n.getString("uif.message.name"));
ac.setAccessibleDescription(local_i18n.getString("uif.message.desc"));
}
else
setAccessibleInfo(txt, uiKey);
return txt;
}
/**
* Create an output text field, using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* By default, the output field is empty and is 10 characters wide.
* @param uiKey the base name of the resource to be used
* @return the empty output field that was created
* @see #createInputField
*/
public JTextField createOutputField(String uiKey) {
return createOutputField(uiKey, "", 10, null, false);
}
/**
* Same as the single parameter version, except a label, which labels
* this new component, will be set.
* The label's setLabelFor()
will be set.
* @param uiKey the base name of the resource to be used
* @param label the label which is labeling this field
* @return the output field that was created
* @see #createInputField(String)
*/
public JTextField createOutputField(String uiKey, JLabel label) {
return createOutputField(uiKey, "", 10, label, false);
}
/**
* Create an output text field with a specified number of columns,
* using a resource to specify the tool tip,
* which can automaticly select contained text.
* The label's setLabelFor()
will be set.
* @param uiKey the base name of the resource to be used
* @param label the label which is labeling this field
* @param autoSelect automaticly select text containing in the field on focus
* @return the output field that was created
* @see #createInputField(String)
*/
public JTextField createOutputField(String uiKey, JLabel label, boolean autoSelect) {
return createOutputField(uiKey, "", 10, label, autoSelect);
}
/**
* Create an output text field with a specified number of columns,
* and using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* The output field is initially empty.
* @param uiKey the base name of the resource to be used
* @param cols the default width of the field, in characters
* @return the empty output field that was created
*/
public JTextField createOutputField(String uiKey, int cols) {
return createOutputField(uiKey, "", cols, null, false);
}
/**
* Create an output text field with a specified number of columns,
* using a resource to specify the tool tip, with an attached label.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* The output field is initially empty.
* @param uiKey the base name of the resource to be used
* @param cols the default width of the field, in characters
* @param label the label which is labeling this field
* @return the empty output field that was created
*/
public JTextField createOutputField(String uiKey, int cols, JLabel label) {
return createOutputField(uiKey, "", cols, label, false);
}
/**
* Create an output text field with a specified number of columns,
* using a resource to specify the tool tip, with an attached label,
* which can automaticly select contained text.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* The output field is initially empty.
* @param uiKey the base name of the resource to be used
* @param cols the default width of the field, in characters
* @param label the label which is labeling this field
* @param autoSelect automaticly select text containing in the field on focus
* @return the empty output field that was created
*/
public JTextField createOutputField(String uiKey, int cols, JLabel label, boolean autoSelect) {
return createOutputField(uiKey, "", cols, label, autoSelect);
}
/**
* Create an output text field containing a specified value,
* and using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* By default, the output field is 10 characters wide.
* @param uiKey the base name of the resource to be used
* @param value the initial text to appear in the output field
* @return the output field that was created
*/
public JTextField createOutputField(String uiKey, String value) {
return createOutputField(uiKey, value, 10, null, false);
}
/**
* Create an output text field containing a specified value,
* using a resource to specify the tool tip,
* with an attached label.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* By default, the output field is 10 characters wide.
* @param uiKey the base name of the resource to be used
* @param value the text to appear in the output field
* @param label the label which is labeling this field
* @return the output field that was created
*/
public JTextField createOutputField(String uiKey, String value, JLabel label) {
return createOutputField(uiKey, value, 10, label, false);
}
/**
* Create an output text field containing a specified value,
* with a specified number of columns,
* and using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* @param uiKey the base name of the resource to be used
* @param value the text to appear in the output field
* @param cols the default width of the field, in characters
* @return the output field that was created
*/
public JTextField createOutputField(String uiKey, String value, int cols) {
return createOutputField(uiKey, value, cols, null, false);
}
/**
* Create an output text field containing a specified value,
* with a specified number of columns,
* using a resource to specify the tool tip,
* with a label referencing this new field.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* @param uiKey the base name of the resource to be used
* @param value the text to appear in the output field
* @param cols the default width of the field, in characters
* @param label the label which is labeling this field
* @return the output field that was created
*/
public JTextField createOutputField(String uiKey, String value, int cols, JLabel label) {
return createOutputField(uiKey, value, cols, label, false);
}
/**
* Create an output text field containing a specified value,
* with a specified number of columns,
* using a resource to specify the tool tip,
* with a label referencing this new field,
* which can automaticly select contained text.
* The resource used is:
*
* uiKey.tip | the tool tip for the field
* |
uiKey.name | accessible name
* |
* In addition, the name of the output field is set to uiKey.
* @param uiKey the base name of the resource to be used
* @param value the text to appear in the output field
* @param cols the default width of the field, in characters
* @param label the label which is labeling this field
* @param autoSelect automaticly select text containing in the field on focus
* @return the output field that was created
*/
public JTextField createOutputField(String uiKey, String value, int cols, JLabel label, boolean autoSelect) {
final JTextField tf = new JTextField(value, cols);
tf.setName(uiKey);
tf.setEditable(false);
tf.setBackground(Colors.TRANSPARENT.getValue());
tf.setOpaque(false);
if(autoSelect)
tf.addFocusListener(new java.awt.event.FocusListener() {
public void focusGained(java.awt.event.FocusEvent e) {
tf.setSelectionStart(0);
tf.setSelectionEnd(tf.getText().length());
}
public void focusLost(java.awt.event.FocusEvent e) {
tf.setSelectionStart(0);
tf.setSelectionEnd(0);
}
});
if (label != null)
label.setLabelFor(tf);
else
setAccessibleName(tf, uiKey);
setToolTip(tf, uiKey);
// override JTextField focus traversal keys, resetting them to
// the Component default (i.e. the same as for the parent.)
tf.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
tf.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
return tf;
}
/**
* Create a text area, using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the text area
* |
* In addition, the name of the text area is set to uiKey.
* @param uiKey the base name of the resource to be used
* @return the text area that was created
*/
public JTextArea createTextArea(String uiKey) {
return createTextArea(uiKey, null);
}
/**
* Create a text area, using a resource to specify the tool tip.
* The resource used is:
*
* uiKey.tip | the tool tip for the text area
* |
* In addition, the name of the text area is set to uiKey.
* @param uiKey the base name of the resource to be used
* @param label the label that labels this text area. May be null.
* @return the text area that was created
*/
public JTextArea createTextArea(String uiKey, JLabel label) {
JTextArea t = new JTextArea() {
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(100, 100);
}
};
t.setName(uiKey);
if (label != null)
label.setLabelFor(t);
else
setAccessibleName(t, uiKey);
setToolTip(t, uiKey);
return t;
}
//----------------------------------------------------------------------------
//
// progress bars
/**
* Create a basic progress bar.
* The resource used is:
*
* uiKey.name | accessible name
* |
uiKey.tip | the tool tip for the text area
* |
*
* @param uiKey the base name of the resource to be used
* @param orient Value from JProgressBar
* @return Returns a progress bar component with the specified attributes.
* @see javax.swing.JProgressBar#VERTICAL
* @see javax.swing.JProgressBar#HORIZONTAL
*/
public JProgressBar createProgressBar(String uiKey, int orient) {
JProgressBar pb = new JProgressBar(orient);
setToolTip(pb, uiKey);
setAccessibleName(pb, uiKey);
return pb;
}
/**
* Create a basic progress bar.
* The resources used are:
*
* uiKey.name | accessible name
* |
uiKey.tip | the tool tip for the text area
* |
*
* @param uiKey the base name of the resource to be used
* @param orient Value from JProgressBar
* @param model Model to use for the progress bar.
* @return Returns a progress bar component with the specified attributes.
* @see javax.swing.JProgressBar#VERTICAL
* @see javax.swing.JProgressBar#HORIZONTAL
*/
public JProgressBar createProgressBar(String uiKey, int orient,
BoundedRangeModel model) {
JProgressBar pb = createProgressBar(uiKey, orient);
pb.setModel(model);
return pb;
}
//----------------------------------------------------------------------------
//
// toolbar
/**
* Create an empty toolbar.
* The resources used are:
*
* uiKey.name | accessible name
* |
uiKey.desc | accessible description text
* |
* @param uiKey Used to obtain accessibility info and name the component
* @return the tool bar that was created
*/
public JToolBar createToolBar(String uiKey) {
JToolBar tb = new JToolBar();
tb.setName(uiKey);
setAccessibleInfo(tb, uiKey);
return tb;
}
/**
* Create a toolbar, using actions to specify the buttons,
* and using resources to specify the name and mnemonic.
* The components on the toolbar which are derived from the actions will
* have their accessible description set to the short description of the
* action.
* The resources used are:
*
* uiKey.name | accessible name
* |
uiKey.desc | accessible description text
* |
* @param uiKey used to obtain accessibility info and name the component
* @param actions the actions from which to create the buttons;
* use null in the array to indicate if and where a separator is required
* @return the tool bar that was created
* @see javax.swing.Action#SHORT_DESCRIPTION
*/
public JToolBar createToolBar(String uiKey, Action[] actions) {
JToolBar tb = new JToolBar();
tb.setName(uiKey);
setAccessibleInfo(tb, uiKey);
for (int i = 0; i < actions.length; i++) {
Action action = actions[i];
if (action == null)
tb.addSeparator();
else {
JButton b = tb.add(action);
b.setName((String) (action.getValue(Action.NAME)));
b.getAccessibleContext().setAccessibleName(b.getName());
}
}
return tb;
}
/**
* Create a toolbar, using buttons.
* The resources used are:
*
* uiKey.name | accessible name
* |
uiKey.desc | accessible description text
* |
* @param uiKey used to obtain accessibility info and name the component
* @param buttons the buttons to be included in the bar.
* use null in the array to indicate if and where a separator is required
* @return the tool bar that was created
*/
public JToolBar createToolBar(String uiKey, JButton[] buttons) {
JToolBar tb = new JToolBar();
tb.setName(uiKey);
setAccessibleInfo(tb, uiKey);
for (int i = 0; i < buttons.length; i++) {
JButton button = buttons[i];
if (button == null)
tb.addSeparator();
else {
tb.add(button);
}
}
return tb;
}
/**
* Add a set of actions to an existing toolbar.
*
* @param tb The toolbar to modify, must not be null.
* @param actions the actions from which to create the buttons;
* use null in the array to indicate if and where a separator is required
* @see javax.swing.Action#SHORT_DESCRIPTION
*/
public void addToolBarActions(JToolBar tb, Action[] actions) {
for (int i = 0; i < actions.length; i++) {
Action action = actions[i];
if (action == null)
tb.addSeparator();
else {
JButton b = tb.add(action);
b.setName((String) (action.getValue(Action.NAME)));
b.getAccessibleContext().setAccessibleName(b.getName());
}
}
}
//----------------------------------------------------------------------------
//
// blocking confirmation and error dialogs
/**
* Show an information dialog, using a resource to specify the error message.
* The resource used is:
*
* uiKey.err | the information message to be displayed
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
*/
public void showInformation(String uiKey) {
showLocalizedInfo(uiKey, getI18NString(uiKey + ".inf"));
}
/**
* Show an error dialog, using a resource to specify the error message.
* The resource used is:
*
* uiKey.err | the error message to be displayed
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
*/
public void showError(String uiKey) {
showLocalizedError(uiKey, getI18NString(uiKey + ".err"));
}
/**
* Show an error dialog, using a resource to specify the error message.
* The resource used is:
*
* uiKey.err | the error message to be displayed
* |
* @param uiKey the base name of the resource to be used
* @param arg an argument to be formatted into the content using
* {@link java.text.MessageFormat#format}
* The method will block until the dialog is dismissed by the user.
*/
public void showError(String uiKey, Object arg) {
showLocalizedError(uiKey, getI18NString(uiKey + ".err", arg));
}
/**
* Show an error dialog, using a resource to specify the error message.
* The resource used is:
*
* uiKey.err | the error message to be displayed
* |
* @param uiKey the base name of the resource to be used
* @param args an array of arguments to be formatted into the content using
* {@link java.text.MessageFormat#format}
* The method will block until the dialog is dismissed by the user.
*/
public void showError(String uiKey, Object[] args) {
String msg = getI18NString(uiKey + ".err", args);
String title = local_i18n.getString("uif.error", ProductInfo.getName());
JButton okBtn = createOptionButton("uif.ok");
JTextArea ta = createLocalizedMessageArea(uiKey, msg.trim(), true);
Dimension d = ta.getMinimumSize();
Object content = ta;
// need scrolling ?
if (d.width > Math.round(6.f * DOTS_PER_INCH) || d.height > Math.round(2.f * DOTS_PER_INCH)) {
JScrollPane sp = new JScrollPane(ta);
sp.setPreferredSize(new Dimension(Math.round(6.f * DOTS_PER_INCH),
Math.round(2.f * DOTS_PER_INCH)));
content = sp;
}
JOptionPane.showOptionDialog(parent,
content,
title,
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE,
null,
new Object[] { okBtn },
null);
}
/**
* Show an error dialog containing stack trace information, using a
* resource to specify the error message.
* The resource used is:
*
* uiKey.err | the error message to be displayed
* |
* @param uiKey the base name of the resource to be used
* @param args an array of arguments to be formatted into the content using
* @param trace an array of arguments containing stack trace information
* to be added to scrollable pane
* The method will block until the dialog is dismissed by the user.
*/
public void showError(String uiKey, Object[] args, Object[] trace) {
String title = local_i18n.getString("uif.error", ProductInfo.getName());
JButton okBtn = createOptionButton("uif.ok");
StringBuffer traceString = new StringBuffer(getI18NString(uiKey + ".err", args));
traceString.append(":\n");
for (int i = 0; i < trace.length; i++) {
traceString.append(trace[i]);
if (i != (trace.length -1))
traceString.append("\n\tat ");
}
JTextArea ta = createLocalizedMessageArea(uiKey, traceString.toString(), true);
ta.setLineWrap(false);
JScrollPane sp = new JScrollPane(ta);
sp.setPreferredSize(new Dimension(Math.round(6.f * DOTS_PER_INCH),
Math.round(2.f * DOTS_PER_INCH)));
JOptionPane.showOptionDialog(parent,
sp,
title,
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE,
null,
new Object[] { okBtn },
null);
}
/**
* Show a error dialog to the user, using previously localized (or
* unlocalized) strings for the message and title.
* @param title Title string for the dialog. If null, a generic title
* will be used.
* @param msg Message to show to the user.
* @see #showError(String)
* @see #showError(String,Object[])
* @see #showError(String,Object[],Object[])
*/
public void showLiteralError(String title, String msg) {
JButton okBtn = createOptionButton("uif.ok");
if (title == null)
title = local_i18n.getString("uif.error", ProductInfo.getName());
JOptionPane.showOptionDialog(parent,
createLiteralMessageArea(msg),
title,
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE,
null,
new Object[] { okBtn },
null);
}
private void showLocalizedError(String uiKey, String text) {
String title = local_i18n.getString("uif.error", ProductInfo.getName());
JButton okBtn = createOptionButton("uif.ok");
JOptionPane.showOptionDialog(parent,
createLocalizedMessageArea(uiKey, text, true),
title,
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE,
null,
new Object[] { okBtn },
null);
}
private void showLocalizedInfo(String uiKey, String text) {
String title = i18n.getString(uiKey + ".title");
JButton okBtn = createOptionButton("uif.ok");
JOptionPane.showOptionDialog(parent,
createLocalizedMessageArea(uiKey, text, true),
title,
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
new Object[] { okBtn },
null);
}
/**
* Show a confirmation dialog with OK and Cancel buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @return an integer signifying how the dialog was dismissed
* @see JOptionPane#OK_OPTION
* @see JOptionPane#CANCEL_OPTION
*/
public int showOKCancelDialog(String uiKey) {
return showLocalizedOKCancelDialog(uiKey, getI18NString(uiKey + ".txt"));
}
/**
* Show a confirmation dialog with OK and Cancel buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @param arg an argument to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @return an integer signifying how the dialog was dismissed
* @see JOptionPane#OK_OPTION
* @see JOptionPane#CANCEL_OPTION
*/
public int showOKCancelDialog(String uiKey, Object arg) {
return showLocalizedOKCancelDialog(uiKey, getI18NString(uiKey + ".txt", arg));
}
/**
* Show a confirmation dialog with OK and Cancel buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @return an integer signifying how the dialog was dismissed
* @param args an array of arguments to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @see JOptionPane#OK_OPTION
* @see JOptionPane#CANCEL_OPTION
*/
public int showOKCancelDialog(String uiKey, Object[] args) {
return showLocalizedOKCancelDialog(uiKey, getI18NString(uiKey + ".txt", args));
}
private int showLocalizedOKCancelDialog(String uiKey, String text) {
JTextArea msg = createLocalizedMessageArea(uiKey, text, true);
String title = getI18NString(uiKey + ".title");
JButton okBtn = createOptionButton("uif.ok");
JButton cancelBtn = createOptionButton("uif.cancel");
int rc = JOptionPane.showOptionDialog(parent,
msg,
title,
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
new Object[] { okBtn, cancelBtn },
null);
return (rc == 0 ? JOptionPane.OK_OPTION /*0*/
: rc == 1 ? JOptionPane.CANCEL_OPTION /*2*/
: rc);
}
/**
* Show a confirmation dialog with Yes and No buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @return an integer signifying how the dialog was dismissed
* @see JOptionPane#YES_OPTION
* @see JOptionPane#NO_OPTION
*/
public int showYesNoDialog(String uiKey) {
return showLocalizedYesNoDialog(uiKey, getI18NString(uiKey + ".txt"));
}
/**
* Show a confirmation dialog with Yes and No buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @param arg an argument to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @return an integer signifying how the dialog was dismissed
* @see JOptionPane#YES_OPTION
* @see JOptionPane#NO_OPTION
*/
public int showYesNoDialog(String uiKey, Object arg) {
return showLocalizedYesNoDialog(uiKey, getI18NString(uiKey + ".txt", arg));
}
/**
* Show a confirmation dialog with Yes and No buttons,
* using a resource to specify the title and component for the message.
* The resources used are:
*
* uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @param msg the GUI component to be used as the dialogs message payload
* @return an integer signifying how the dialog was dismissed
* @see JOptionPane#YES_OPTION
* @see JOptionPane#NO_OPTION
*/
public int showCustomYesNoDialog(String uiKey, Component msg) {
return showComponentYesNoDialog(uiKey, msg);
}
/**
* Show a confirmation dialog with Yes and No buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @return an integer signifying how the dialog was dismissed
* @param args an array of arguments to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @see JOptionPane#YES_OPTION
* @see JOptionPane#NO_OPTION
*/
public int showYesNoDialog(String uiKey, Object[] args) {
return showLocalizedYesNoDialog(uiKey, getI18NString(uiKey + ".txt", args));
}
private int showLocalizedYesNoDialog(String uiKey, String text) {
JTextArea msg = createLocalizedMessageArea(uiKey, text, true);
return showComponentYesNoDialog(uiKey, msg);
}
/**
* Show a Yes/No dialog with the given text and title.
* Use this with care and only when really really needed.
*/
int showLiteralYesNoDialog(String title, String text) {
// warning, this only works because createLocalizedMessageArea
// does not use the uikey for anything except the component name
JTextArea msg = createLocalizedMessageArea("literal", text, true);
// update showComponentYesNoDialog if you change this!
JButton yesBtn = createOptionButton("uif.yes");
JButton noBtn = createOptionButton("uif.no");
return JOptionPane.showOptionDialog(parent,
msg,
title,
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
new Object[] { yesBtn, noBtn },
null);
}
private int showComponentYesNoDialog(String uiKey, Component msg) {
// update showLiteralYesNoDialog if you change this!
String title = getI18NString(uiKey + ".title");
JButton yesBtn = createOptionButton("uif.yes");
JButton noBtn = createOptionButton("uif.no");
return JOptionPane.showOptionDialog(parent,
msg,
title,
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
new Object[] { yesBtn, noBtn },
null);
}
/**
* Show a confirmation dialog with Yes, No and Cancel buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @return an integer signifying how the dialog was dismissed
* @see JOptionPane#YES_OPTION
* @see JOptionPane#NO_OPTION
* @see JOptionPane#CANCEL_OPTION
*/
public int showYesNoCancelDialog(String uiKey) {
return showLocalizedYesNoCancelDialog(uiKey, getI18NString(uiKey + ".txt"));
}
/**
* Show a confirmation dialog with Yes and No buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @param arg an argument to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @return an integer signifying how the dialog was dismissed
* @see JOptionPane#YES_OPTION
* @see JOptionPane#NO_OPTION
* @see JOptionPane#CANCEL_OPTION
*/
public int showYesNoCancelDialog(String uiKey, Object arg) {
return showLocalizedYesNoCancelDialog(uiKey, getI18NString(uiKey + ".txt", arg));
}
/**
* Show a confirmation dialog with Yes and No buttons,
* using a resource to specify the message and title.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* The method will block until the dialog is dismissed by the user.
* @param uiKey the base name of the resource to be used
* @return an integer signifying how the dialog was dismissed
* @param args an array of arguments to be formatted into the content using
* {@link java.text.MessageFormat#format}
* @see JOptionPane#YES_OPTION
* @see JOptionPane#NO_OPTION
* @see JOptionPane#CANCEL_OPTION
*/
public int showYesNoCancelDialog(String uiKey, Object[] args) {
return showLocalizedYesNoCancelDialog(uiKey, getI18NString(uiKey + ".txt", args));
}
private int showLocalizedYesNoCancelDialog(String uiKey, String text) {
JTextArea msg = createLocalizedMessageArea(uiKey, text, true);
String title = getI18NString(uiKey + ".title");
JButton yesBtn = createOptionButton("uif.yes");
JButton noBtn = createOptionButton("uif.no");
JButton cancelBtn = createOptionButton("uif.cancel");
return JOptionPane.showOptionDialog(parent,
msg,
title,
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
new Object[] { yesBtn, noBtn, cancelBtn },
null);
}
/**
* Show a message only dialog, no user feedback.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* @param uiKey the base name of the resource to be used
* @param args any arguments to be used to create the message
*/
public void showInformationDialog(String uiKey, Object[] args) {
showLocalizedInformationDialog(uiKey,
getI18NString(uiKey + ".title"),
getI18NString(uiKey + ".txt", args), parent);
}
public void showInformationDialog(String uiKey, Object[] args, Component parent) {
showLocalizedInformationDialog(uiKey,
getI18NString(uiKey + ".title"),
getI18NString(uiKey + ".txt", args), parent);
}
private void showLocalizedInformationDialog(String uiKey, String title,
String text, Component localParent) {
JTextArea msg = createLocalizedMessageArea(uiKey, text, true);
Dimension d = msg.getMinimumSize();
Object content = msg;
// need scrolling ?
if (d.width > Math.round(6.f * DOTS_PER_INCH) || d.height > Math.round(2.f * DOTS_PER_INCH)) {
JScrollPane sp = new JScrollPane(msg);
sp.setPreferredSize(new Dimension(Math.round(6.f * DOTS_PER_INCH),
Math.round(2.f * DOTS_PER_INCH)));
content = sp;
}
JOptionPane.showMessageDialog(localParent,
content,
title,
JOptionPane.INFORMATION_MESSAGE,
null);
}
//----------------------------------------------------------------------------
//
// don't show this again message box
/**
* Show a dialog which provides the user with an informational message.
*
* The resources used are:
*
* uiKey.title | the title for the dialog
* |
* @param uiKey the base name of the resource to be used
* @param msg the body of the dialog, which should have already been localized
*/
public void showCustomInfoDialog(String uiKey, Object msg) {
JOptionPane.showMessageDialog(parent,
msg,
getI18NString(uiKey + ".title"),
JOptionPane.INFORMATION_MESSAGE,
null);
}
//----------------------------------------------------------------------------
//
// panels
/**
* Create a horizontal placeholder "box".
* The name of this new box component will be set to uiKey.
* @param uiKey the base name of the resource to be used
* @return A Box component
* @see javax.swing.Box
*/
public Box createHorizontalBox(String uiKey) {
Box box = Box.createHorizontalBox();
box.setName(uiKey);
box.setFocusable(false);
return box;
}
/**
* Create an empty panel.
* In the J2SE 1.4 and greater world, panels are focusable by default,
* so this panel will be focusable. Because of this, accessibility
* information must be set, therefore the following resources are
* required from the resource bundle:
*
* uiKey.name | the accessible name of the panel
* |
uiKey.desc | accessible description text
* |
* The name of this new component will be set to uiKey.
* @param uiKey the base name of the resource to be used
* @return An empty panel component
*/
public JPanel createPanel(String uiKey) {
return createPanel(uiKey, true);
}
/**
* Create an empty panel.
* In the J2SE 1.4 and greater world, panels are focusable by default,
* so this panel will be focusable. Use this method to control
* whether or not the panel remains focusable. If you choose 'true',
* the following must be provided in the resource bundle:
*
* uiKey.name | the accessible name of the panel
* |
uiKey.desc | accessible description text
* |
* The name of this new component will be set to uiKey.
* @param uiKey the base name of the resource to be used
* @param focusable If true, the panel will accept focus in the GUI.
* If false it will not. Note that if it is focusable, you need to
* provide accessibility text.
* @return An empty panel component
*/
public JPanel createPanel(String uiKey, boolean focusable) {
JPanel p = new JPanel();
initPanel(p, uiKey, focusable);
return p;
}
/**
* Create an empty panel with a specific layout manager.
* In the J2SE 1.4 and greater world, panels are focusable by default,
* so this panel will be focusable. Because of this, accessibility
* information must be set, therefore the following resources are
* required from the resource bundle:
*
* uiKey.name | the accessible name of the panel
* |
uiKey.desc | accessible description text
* |
* The name of this new component will be set to uiKey.
* @param uiKey the base name of the resource to be used
* @param layout the layout manager instance to use in this panel
* @return An empty panel component
*/
public JPanel createPanel(String uiKey, LayoutManager layout) {
return createPanel(uiKey, layout, true);
}
/**
* Create an empty panel with a specific layout manager.
* In the J2SE 1.4 and greater world, panels are focusable by default,
* so this panel will be focusable. Use this method to control
* whether or not the panel remains focusable. If you choose 'true',
* the following must be provided in the resource bundle:
*
* uiKey.name | the accessible name of the panel
* |
uiKey.desc | accessible description text
* |
* The name of this new component will be set to uiKey.
* @param uiKey the base name of the resource to be used
* @param layout the layout manager instance to use in this panel
* @param focusable If true, the panel will accept focus in the GUI.
* If false it will not. Note that if it is focusable, you need to
* provide accessibility text.
* @return An empty panel component
*/
public JPanel createPanel(String uiKey, LayoutManager layout, boolean focusable) {
JPanel p = new JPanel();
initPanel(p, uiKey, layout, focusable);
return p;
}
/**
* Set properties on an existing panel.
* @param p the panel to modify
* @param uiKey the base name of the resource to be used
* @param focusable If true, the panel will accept focus in the GUI.
* If false it will not. Note that if it is focusable, you need to
* provide accessibility text.
*/
public void initPanel(JPanel p, String uiKey, boolean focusable) {
p.setName(uiKey);
if (focusable)
setAccessibleInfo(p, uiKey);
else
p.setFocusable(false);
}
/**
* Set properties on an existing panel, including the layout manager.
* @param p the panel to modify
* @param uiKey the base name of the resource to be used
* @param layout the layout manager instance that this panel should use
* @param focusable If true, the panel will accept focus in the GUI.
* If false it will not. Note that if it is focusable, you need to
* provide accessibility text.
*/
public void initPanel(JPanel p, String uiKey, LayoutManager layout, boolean focusable) {
initPanel(p, uiKey, focusable);
p.setLayout(layout);
}
//----------------------------------------------------------------------------
//
// dialogs
/**
* Create an empty dialog.
* See initDialog(JDialog,String)
for required resources.
* @param uiKey the base name of the resource to be used
* @param parent the parent component of this dialog
* @return an empty dialog component
* @see #initDialog
*/
public JDialog createDialog(String uiKey, Component parent) {
JFrame owner = (JFrame) (SwingUtilities.getAncestorOfClass(JFrame.class, parent));
return createDialog(uiKey, owner);
}
/**
* Create an empty dialog.
* See initDialog(JDialog,String)
for required resources.
* @param uiKey the base name of the resource to be used
* @param owner the parent frame of this dialog
* @return an empty dialog component
* @see #initDialog
*/
public JDialog createDialog(String uiKey, JFrame owner) {
JDialog d = new JDialog(owner);
initDialog(d, uiKey);
return d;
}
/**
* Create an empty dialog.
* See initDialog(JDialog,String)
for required resources.
* @param uiKey the base name of the resource to be used
* @param owner the parent frame of this dialog. If owner is null - icon is set to the dialog
* @param title the localized title of this new dialog
* @param content the content to go into the dialog
* @return an dialog component with the given content component and title
* @see #initDialog
*/
public JDialog createDialog(String uiKey, JFrame owner, String title, Container content) {
return createDialog(uiKey, owner, title, content, Dialog.ModalityType.MODELESS);
}
/**
* Create an empty dialog.
* See initDialog(JDialog,String)
for required resources.
* @param uiKey the base name of the resource to be used
* @param owner the parent frame of this dialog. If owner is null - icon is set to the dialog
* @param title the localized title of this new dialog
* @param content the content to go into the dialog
* @param type specifies whether dialog blocks input to other windows when shown.
* null value and unsupported modality types are equivalent to MODELESS
* @return an dialog component with the given content component and title
* @see #initDialog
*/
public JDialog createDialog(String uiKey, JFrame owner, String title, Container content, Dialog.ModalityType type) {
// can't use constructor JDialog(Window, String, Dialog.ModalityType) -
// it has different behavior from JDialog(Frame, String, boolean)
JDialog d = new JDialog(owner, title, false);
d.setModalityType(type);
if (owner == null) {
d.setIconImage(createImage("images/jticon.gif"));
}
initDialog(d, uiKey);
d.setContentPane(content);
return d;
}
/**
* Create an empty frame. Unlike to dialog createDialog(String uiKey,
* JFrame owner, String title, Container content)
it can't be modal,
* it's always free-floating and it has minimize and maximize buttons
* See initFrame(JFrame,String)
for required resources.
* @param uiKey the base name of the resource to be used
* @param title the localized title of this new frame
* @param content the content to go into the frame
* @return a frame component with the given content component and title
* @see #initFrame
*/
public JFrame createFrame(String uiKey, String title, Container content) {
JFrame frame = new JFrame(title);
initFrame(frame, uiKey);
frame.setContentPane(content);
return frame;
}
/**
* Create a dialog which will ask the user to wait.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
* @param uiKey The prefix to retrieve strings to be displayed.
* @param parent The parent component of this new dialog.
* @return a dialog appropriate for asking the user to wait
*/
public JDialog createWaitDialog(String uiKey, Component parent) {
JFrame owner = (JFrame) (SwingUtilities.getAncestorOfClass(JFrame.class, parent));
return createWaitDialog(uiKey, owner);
}
/**
* Create a dialog which will ask the user to wait.
* The resources used are:
*
* uiKey.txt | the message to be displayed
* |
uiKey.title | the title for the dialog
* |
uiKey.desc | accessible description of the dialog
* |
uiKey.name | accessible name of the dialog
* |
* @param uiKey The prefix to retrieve strings to be displayed.
* @param owner The frame which will own this new dialog.
* @return a dialog appropriate for asking the user to wait
*/
public JDialog createWaitDialog(String uiKey, JFrame owner) {
final int msgWidth = 50;
JDialog d = new JDialog(owner);
initDialog(d, uiKey);
d.setTitle(getI18NString(uiKey + ".title"));
JProgressBar pb = new JProgressBar(SwingConstants.HORIZONTAL);
pb.setName(uiKey);
pb.setIndeterminate(true);
pb.setBorderPainted(true);
pb.setPreferredSize(new Dimension(Math.round(2.5f * DOTS_PER_INCH),
15));
JPanel body = createPanel(uiKey, new GridBagLayout(), false);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.CENTER;
gbc.insets.left = 12; // JL&F spacing
gbc.insets.right = 12; // JL&F spacing
gbc.insets.top = 12; // JL&F spacing
gbc.gridy = 0;
gbc.weightx = 0;
JTextArea msg = createLocalizedMessageArea(uiKey,
getI18NString(uiKey + ".txt"),
false);
// uif sets the size, but too large for this dialog
msg.setSize(new Dimension(Math.round(4.0f * DOTS_PER_INCH),
Integer.MAX_VALUE));
body.add(msg, gbc);
// add progress bar
gbc.gridy = 1;
gbc.insets.top = 11; // JL&F spacing
gbc.insets.bottom = 12; // JL&F spacing
body.add(pb, gbc);
d.setContentPane(body);
d.pack();
d.setLocationRelativeTo(owner);
return d;
}
/**
* Configure a dialog with accessibility information.
*
* uiKey.desc | accessible description of the dialog
* |
uiKey.name | accessible name of the dialog
* |
uiKey.root | component name for the root pane of the
* dialog
* |
* @param d the dialog to upgrade
* @param uiKey Key to retrieve the new properties with
*/
public void initDialog(JDialog d, String uiKey) {
d.setName(uiKey);
setAccessibleInfo(d, uiKey);
d.setLocationRelativeTo(d.getParent());
JRootPane root = d.getRootPane();
root.setName(uiKey + ".root");
AccessibleContext ac = d.getAccessibleContext();
AccessibleContext r_ac = root.getAccessibleContext();
r_ac.setAccessibleName(ac.getAccessibleName());
r_ac.setAccessibleDescription(ac.getAccessibleDescription());
}
/**
* Configure a frame with accessibility information and an icon.
*
* uiKey.desc | accessible description of the frame
* |
uiKey.name | accessible name of the frame
* |
uiKey.root | component name for the root pane of the
* frame
* |
* @param d the frame to upgrade
* @param uiKey Key to retrieve the new properties with
*/
public void initFrame(JFrame d, String uiKey) {
d.setName(uiKey);
setAccessibleInfo(d, uiKey);
d.setLocationRelativeTo(d.getParent());
d.setIconImage(createImage("images/jticon.gif"));
JRootPane root = d.getRootPane();
root.setName(uiKey + ".root");
AccessibleContext ac = d.getAccessibleContext();
AccessibleContext r_ac = root.getAccessibleContext();
r_ac.setAccessibleName(ac.getAccessibleName());
r_ac.setAccessibleDescription(ac.getAccessibleDescription());
}
//----------------------------------------------------------------------------
/**
* Dispose of any owned resources.
*/
public void dispose() {
clientClass = null;
parent = null;
}
//----------------------------------------------------------------------------
private static Font baseFont = new JLabel().getFont();
private static final ActionListener closeListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
Component src = (Component) (e.getSource());
for (Container p = src.getParent(); p != null; p = p.getParent()) {
if (p instanceof JInternalFrame || p instanceof Window) {
p.setVisible(false);
return;
}
}
}
};
private Class clientClass;
private Component parent;
private I18NResourceBundle i18n;
private HelpBroker helpBroker;
private static I18NResourceBundle local_i18n = I18NResourceBundle.getBundleForClass(UIFactory.class);
private static final int DOTS_PER_INCH = Toolkit.getDefaultToolkit().getScreenResolution();
/**
* Extension to the UIFactory that allows to use more than one resource
* bundle. All methods accessing the resource bundle are overridden to
* search for a resource in the alternative bundle first, and, if not found,
* look up it in the original one.
*
* This class might be helpful, when a component extends another components
* from a different package.
*/
public static class UIFactoryExt extends UIFactory {
private I18NResourceBundle i18n_alt;
private Class altClass;
public UIFactoryExt(UIFactory uif, Class altClass) {
super(uif.clientClass, uif.parent, uif.helpBroker);
i18n_alt = I18NResourceBundle.getBundleForClass(altClass);
this.altClass = altClass;
}
@Override
public Color getI18NColor(String key) {
if (!hasKey(i18n_alt,key)) {
return super.getI18NColor(key);
}
String value = i18n_alt.getString(key + ".clr");
try {
if (value != null)
return Color.decode(value);
}
catch (Exception e) {
// ignore
}
return Color.BLACK;
}
@Override
public String getI18NString(String key) {
if (hasKey(i18n_alt,key)) {
return i18n_alt.getString(key);
} else {
return super.getI18NString(key);
}
}
@Override
public String getI18NString(String key, Object arg) {
if (hasKey(i18n_alt,key)) {
return i18n_alt.getString(key, arg);
} else {
return super.getI18NString(key, arg);
}
}
@Override
public String getI18NString(String key, Object[] args) {
if (hasKey(i18n_alt,key)) {
return i18n_alt.getString(key, args);
} else {
return super.getI18NString(key, args);
}
}
@Override
public URL getIconURL(String uiKey) {
String r = getI18NString(uiKey + ".icon");
URL url = altClass.getResource(r);
if (url == null)
url = super.getIconURL(uiKey);
return url;
}
/**
* It would be much better to use containsKey() instead, but
* it's available since 1.6
*/
static boolean hasKey(ResourceBundle rb, String key) {
Enumeration keys = rb.getKeys();
if (keys == null || key == null) {
return false;
}
while(keys.hasMoreElements()) {
if (key.equals(keys.nextElement())) {
return true;
}
}
return false;
}
}
}