Javax - Swing: 1. The Swing User Interface
Javax - Swing: 1. The Swing User Interface
SWING
This example creates and shows a frame with a button. To enable the button to respond to
button clicks,.
import java.awt.*;
import javax.swing.*;
JFRAME,JWINDOW,JDIALOG
2. Creating a JFrame
A frame is a component container that displays its contents in a top-level window with a
title bar and buttons to resize, iconify, maximize, and close the frame.
Unlike most Swing containers, adding a component to a frame is not done with the
JFrame.add() method. This is because the frame holds several panes and it is necessary
to specify a particular pane to which to add the component. The pane that holds child
components is called the content pane. This example adds a text area to the content pane
of a frame.
By default, when the close button on a frame is clicked, the frame hides itself. This
example shows how to exit the application when the frame is closed:
// Create a frame
JFrame frame = new JFrame();
By default, when the close button on a frame is clicked, the frame hides itself. This
example shows how to disable the close button:
// Create a frame
JFrame frame = new JFrame();
In order to find the frame that contains a component, it is necessary to walk up the
component's parents until the frame is encountered. SwingUtilities.getRoot() is a
convenience method that finds the frame.
This example implements an action that finds and hides the frame of the component that
triggered the action.
// Create an action
Action action = new AbstractAction("Action Label") {
// This method is called when the action is triggered
public void actionPerformed(ActionEvent evt) {
Component c = (Component)evt.getSource();
jlabel
// Create a label with text and an icon; the icon appears to the
left of the text
JLabel label = new JLabel("Text Label", icon, JLabel.CENTER);
This example associates a label with a text field using setLabelFor(). A mnemonic is
set on the label. When the mnemonic keystroke is pressed, the text field will gain the
focus.
In the following example, when ALT-L is pressed, the text field gains the focus.
This example demonstrates how to modify a label component so that its text can be
dragged and dropped to another component.
// Create a label
JLabel label = new JLabel("Label Text");
jbutton
// To create a button,
// Change the label
button.setText("New Label");
// Remove the label; this is useful for a button with only an icon
button.setText(null);
A button label can show simple HTML tags when surrounded by the tags <HTML> and
</HTML>. This example shows how to create multiple lines by using the <BR> tag. See the
javax.swing.text.html.HTML class documentation for a list of supported tags.
String label = "<html>"+"This is a"+"<br>"+"swing button"+"</html>";
If the action used to create the button contains an icon, the button will be created using
that icon. The icon will appear to the left of the text; to change the icon's position, .
// Retrieve the icon
Icon icon = new ImageIcon("icon.gif");
// Create the button; the icon will appear to the left of the label
JButton button = new JButton(action);
If the action does not have an icon or a different icon must be used, add or change the
icon using setIcon():
// Add or change the icon; it will appear to the left of the text
button.setIcon(icon);
There are two methods for controlling the position of the text relative to the icon - -
setVerticalTextPosition() and setHorizontalTextPosition(). There are three
settings for each axis, which allows for a total of nine positions.
To control the gap between the text and icon, Note: Not all placements are possible. For
example, it is not possible to place the text above the icon with their left edges aligned.
The nine possible placements are demonstrated below.
When the size of the button component is larger than its contents, the label and icon are
always kept together. In fact, the gap size determines the fixed distance between them.
Using two alignment methods, you can place the label/icon pair in one of nine possible
locations.
// To create a button with an icon,
// Place the contents in the nw corner
button.setVerticalAlignment(SwingConstants.TOP);
button.setHorizontalAlignment(SwingConstants.LEFT);
18. Setting the Gap Size Between the Label and Icon in a JButton
Component
// To create a button with an icon,
// Get gap size; default is 4
int gapSize = button.getIconTextGap();
The rollover icon is displayed when the cursor is moved over the button. If no rollover
icon is set, the default icon is displayed when the cursor is moved over the button.
The pressed icon is displayed when the button is armed (i.e., the mouse button is down
while the cursor is on the button). If no pressed icon is set, the default icon is displayed
when the button is armed.
The rollover and pressed icons are never displayed if the button is disabled.
jcheckbox
// Determine status
boolean isSel = cb.isSelected();
if (isSel) {
// The checkbox is now selected
} else {
// The checkbox is now deselected
}
}
};
Unlike a button, setIcon() does not add an icon to the text label. Rather, in a checkbox,
the method is used to customize the icons used to depict its state. However, by using the
HTML capabilities in a label, it is possible to add an icon to the label without affecting
the state-depicting icons. This example demonstrates the technique.
// Define an HTML fragment with an icon on the left and text on the
right.
// The elements are embedded in a 3-column table.
String label = "<html><table cellpadding=0><tr><td><img src=file:"
// The location of the icon
+ icon.gif"
+ "/></td><td width="
The icons used to depict the selected state of a checkbox component can be customized.
The simplest customization requires two icons, one to depict the selected state and one to
depict the unselected state.
// Set the unselected state icon
Icon unselIcon = new ImageIcon("nosel-icon.gif");
checkbox.setIcon(unselIcon);
jcombobox
// If the new value is not in the list of valid items, the call is
ignored
cb.setSelectedItem("item3");
obj = cb.getSelectedItem(); // item2
// Get items
for (int i=0; i<num; i++) {
Object item = cb.getItemAt(i);
}
// [item1, item2, item3]
There is no method for replacing an item. To replace an item, first remove the item and
then insert the new one.
// Create a read-only combobox; the combobox is read-only
// in that it does not allow the user to type in a new item.
// The combobox still allows programmatic changes to its items.
String[] items = {"item1", "item2"};
JComboBox cb = new JComboBox(items);
By default, when the user types a keystroke in a read-only combobox and an item in the
combobox starts with the typed keystroke, the combobox will select that item. This
behavior is not ideal if there are multiple items that start with the same letter.
This example demonstrates how to customize a combobox so that it will select an item
based on multiple keystrokes. More specifically, if a keystroke is typed within 300
milliseconds of the previous keystroke, the new keystroke is appended to the previous
keystroke, and the combobox will select an item that starts with both keystrokes.
By default, typing a key in a read-only combobox selects an item that starts with the
typed key. This example demonstrates how to display the drop-down menu when a key is
typed.
// Create a read-only combobox
String[] items = {"Ant", "Ape", "Bat", "Boa", "Cat", "Cow"};
JComboBox cb = new JComboBox(items);
This example registers a key listener in a read-only combobox that displays the menu if
the newly selected item is not unique.
// Create a read-only combobox
String[] items = {"Ant", "Ape", "Bat", "Boa", "Cat"};
JComboBox cb = new JComboBox(items);
// This key listener displays the menu only if the pressed key
// does not select a new item or if the selected item is not unique.
class MyKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent evt) {
JComboBox cb = (JComboBox)evt.getSource();
By default, the menu of a combobox only shows eight items. If there are more items in
the menu, a scrollbar is automatically created. To change the default of eight, use
JComboBox.setMaximumRowCount().
// Create a read-only combobox with lots of items
String[] items = new String[50];
for (int i=0; i<items.length; i++) {
items[i] = "" + Math.random();
}
JComboBox cb = new JComboBox(items);
Item events are generated whenever the selected item changes. These events are
generated even while the user is moving through items in the displayed popup menu. If
the combobox is editable, this event does not indicate whether the new item is taken from
the predefined list or not. If this information is necessary
// Create an editable combobox
String[] items = {"item1", "item2"};
JComboBox cb = new JComboBox(items);
cb.setEditable(true);
if (evt.getStateChange() == ItemEvent.SELECTED) {
// Item was just selected
} else if (evt.getStateChange() == ItemEvent.DESELECTED) {
// Item is no longer selected
}
}
}
Action events are generated whenever the selected item changes. These events are
generated even while the user is moving through items in the displayed popup menu.
Unlike item events action events are generated even if the new item is the same as the
old item.
// Create component
String[] items = {"item1", "item2"};
JComboBox cb = new JComboBox(items);
cb.setEditable(true);
if ("comboBoxEdited".equals(evt.getActionCommand())) {
// User has typed in a string; only possible with an
editable combobox
} else if ("comboBoxChanged".equals(evt.getActionCommand()))
{
// User has selected an item; it may be the same item
}
}
}
37. Determining When the Menu of a JComboBox Component Is
Displayed
// Create component
String[] items = {"item1", "item2"};
JComboBox cb = new JComboBox(items);
cb.setEditable(true);
jradiobutton
When you ask a button group for the currently selected radio button, it returns the
selected radio button's model (rather than the selected radio button itself). Fortunately,
the button group maintains the list of buttons and so you can iterate over this list looking
for one with the same model.
// This method returns the selected radio button in a button group
public static JRadioButton getSelection(ButtonGroup group) {
for (Enumeration e=group.getElements(); e.hasMoreElements(); ) {
JRadioButton b = (JRadioButton)e.nextElement();
if (b.getModel() == group.getSelection()) {
return b;
}
}
return null;
}
JLIST
44. Creating a JList Component
By default, a list allows more than one item to be selected. Also, the selected items need
not be contiguous.
A list selection event is fired when the set of selected items is changed .
By default, the width of the list is determined by the longest item and the height is
determined by the number of visible lines multiplied by the tallest item. This example
demonstrates how to override these values.
// Create a list
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
// Get item
Object item = getModel().getElementAt(index);
// Search backward, starting from the last item, looking for an item
that starts with "b"
start = list.getModel().getSize()-1;
direction = javax.swing.text.Position.Bias.Backward;
itemIx = list.getNextMatch(prefix, start, direction);
These methods can be used to find the range of visible items:
// Get number of visible items
int visibleSize = list.getVisibleRowCount();
// Get index of first visible item
itemIx = list.getFirstVisibleIndex();
if (itemIx < 0) {
// List is either not visible or there are no items
}
The default model for a list does not allow the addition and removal of items. The list
must be created with a DefaultListModel.
// Create a list that allows adds and removes
DefaultListModel model = new DefaultListModel();
JList list = new JList(model);
// Append an item
int pos = list.getModel().getSize();
model.add(pos, "E");
List selection events are fired when the following methods are used to change the set of
selected items.
// Create a list and get the model
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
list.setSelectionMode(DefaultListSelectionModel.SINGLE_INTERVAL_SELECTIO
N);
list.setSelectionMode(DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECT
ION);
By default, the items in a list are arranged vertically, in a single column, as in:
item1
item2
...
It is possible to arrange the items left-to-right and top-to-bottom, as in:
item1 item2
item3 item4
item5 ...
This example creates and configures a list that displays its items left-to-right and top-to-
bottom. Note that the number of columns can change as the width of the list changes.
// Create a scrollable list
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
JScrollPane scrollingList = new JScrollPane(list);
When the set of selected items is changed, either by the user or programmatically, a list
selection event is fired.
// Create a list
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
When the set of items in a list component is changed, a list data event is fired.
// Create a list that allows adds and removes;
// This method is called when items have been removed from the
list
public void intervalRemoved(ListDataEvent evt) {
// Get range of removed items
int start = evt.getIndex0();
int end = evt.getIndex1();
int count = end-start+1;
JSPINNER
This example demonstrates how to build three kinds of spinners. A number spinner:
// Create a number spinner
JSpinner spinner = new JSpinner();
// Set the margin (add two spaces to the left and right side of the
value)
int top = 0;
int left = 2;
int bottom = 0;
int right = 2;
Insets insets = new Insets(top, left, bottom, right);
tf.setMargin(insets);
Editor(JSpinner spinner) {
// Add the listener
spinner.addChangeListener(this);
By default, if the user is browsing the values in a SpinnerListModel, the iteration stops
when either end is reached. This example demonstrates a subclass that allows the user to
continuously loop through the values.
SpinnerCircularListModel listModel = new SpinnerCircularListModel(
new String[]{"red", "green", "blue"});
JSpinner spinner = new JSpinner(listModel);
JSLIDER
// Create a horizontal slider with custom min and max; value is set
to the middle
int minimum = -255;
int maximum = 256;
slider = new JSlider(minimum, maximum);
// Set the value; the new value will be forced into the bar's range
int newValue = 33;
slider.setValue(newValue);
The slider supports two levels of tick marks, major and minor. Typically, the minor tick-
mark spacing is smaller than the major tick-mark spacing. Also, the minor tick-mark
spacing is a multiple of the major tick-mark spacing. However, the slider does not
enforce any of these constraints.
// Create a horizontal slider that moves left-to-right
JSlider slider = new JSlider();
// Determine if currently showing ticks
boolean b = slider.getPaintTicks(); // false
This example demonstrates how to display labels (numerical values) at the major ticks.
// Create a horizontal slider that moves left-to-right
JSlider slider = new JSlider();
// Paint labels at the major ticks - 0, 25, 50, 75, and 100
slider.setPaintLabels(true);
The slider allows you to use an arbitrary label at any particular major tick mark. This
example configures a slider that shows an icon at the minimum and maximum positions.
The component is only used to render the label and so it can be used at more than one
position. Unfortunately, it also means that if the component is interactive (e.g., a button),
it will not respond to mouse and keyboard gestures.
// Retrieve current table
java.util.Dictionary table = slider.getLabelTable();
// Create icon
ImageIcon icon = new ImageIcon("icon.gif");
JLabel label = new JLabel(icon);
By default, the slider can take on any value from the minimum to the maximum. It is
possible to configure the slider to allow only values at tick marks. This is done by calling
JSlider.setSnapToTicks(true).
The slider's minimum and minor tick-mark spacing determines what values are possible.
For example, if the minimum is 3 and the minor tick-mark spacing is 10, only the values,
3, 13, 23, and so forth, are allowed. If a minor tick-mark spacing has not been set, the
major tick-mark spacing is used. If neither a minor nor a major tick mark spacing has
been set, a tick-mark spacing of 1 is assumed.
Calling setSnapToTicks() also has the effect of causing the slider's knob to snap to the
closest tick mark whenever it is dragged or programmatically moved to a spot between
tick marks.
// Set to a spot between tick marks; the value moves to closest tick
mark
slider.setValue(27);
int value = slider.getValue(); // 25
if (!slider.getValueIsAdjusting()) {
// Get new value
int value = slider.getValue();
}
}
});
JPROGRESSBAR
73. Creating a JProgressBar Component
A progress bar is used to visually indicate how much a task has been progressed. A
progress bar can be oriented horizontally (left-to-right) or vertically (bottom-to-top). By
default, the orientation is horizontal.
// Create a horizontal progress bar
int minimum = 0;
int maximum = 100;
JProgressBar progress = new JProgressBar(minimum, maximum);
A progress bar with an unknown maximum typically displays an animation until the task
is complete.
Note: The percentage display should not be enabled when the maximum is not known.
// Create a horizontal progress bar
int min = 0;
int max = 100;
JProgressBar progress = new JProgressBar(min, max);
// Play animation
progress.setIndeterminate(true);
When information on the task's progress is available, the progress bar can be made
determinate:
int value = 33;
progress.setValue(value);
progress.setIndeterminate(false);
// Set the value; the new value will be forced into the bar's range
int newValue = 33;
progress.setValue(newValue);
It is also possible to set all the values at once by using the model:
progress.getModel().setRangeProperties(newValue, 0, newMin, newMax,
false
The progress bar offers the ability to display the actual value of the bar as a percentage.
This example demonstrates how to enable this display.
Note: The percentage display should not be enabled when the maximum is not known
Whenever the value of a progress bar is changed, a change event is fired. In fact, the
event is also fired when the minimum or maximum values are changed. However, the
event does not specify which values were changed.
// Create a horizontal progress bar
int minimum = 0;
int maximum = 100;
JProgressBar progress = new JProgressBar(minimum, maximum);
progress.addChangeListener(new ChangeListener() {
// This method is called when the value, minimum, or maximum is
changed.
public void stateChanged(ChangeEvent evt) {
JProgressBar comp = (JProgressBar)evt.getSource();
PROGRESS MONITOR
A common feature of a user interface is to show a progress dialog that visually displays
the progress of a long-running task. The dialog automatically disappears when the task is
done. The ProgressMonitor class is a convenient dialog that implements a progress
dialog.
The progress monitor contains a message which describes the long-running task. The
message does not change for the duration of the task. The progress monitor also allows
for a note which is a description of the current subtask. For example, if the task is
copying a set of files, the note could be the name of the current file being copied.
Note: A progress monitor should not be reused. The properties that control when the
dialog should appear are set when the monitor is constructed and cannot be reset.
if (cancelled) {
// Stop task
} else {
// Set new state
pm.setProgress(newValue);
By default, the progress monitor delays for a short period before it is displayed. There are
two properties that control when the dialog is displayed - - millisToPopup and
millisToDecideToPopup. The progress monitor computes a time-to-completion based
on the how fast the value changes. The dialog will not appear as long as the predicted
time-to-completion is less than millisToPopup. millisToDecideToPopup determines a
minimum time, since the progress monitor was created, before the dialog can appear.
// Create a menu
JMenu menu = new JMenu("Menu Label");
menuBar.add(menu);
A separator typically appears as a horizontal line. It is used to group related sets of menu
items in a menu.
// Create a menu
JMenu menu = new JMenu("Menu Label");
// Add separator
menu.add(new JSeparator());
By default, Swing popup menus used by JMenu and JPopupMenu are lightweight. If
heavyweight components are used in the same frame, the popup menus may appear
behind the heavyweight components.
This example demonstrates how to force the popup menu of a JMenu to be heavyweight:
// Create a menu with a menu item
JMenu menu = new JMenu("Menu Label");
menu.add(new JMenuItem("Item Label"));
The menu path also includes nested menus. For example, if the currently selected menu
item is part of a nested menu in a menu bar, the sequence of elements is: JMenuBar,
JMenu, JPopupMenu, JMenu, JPopupMenu, and JMenuItem. Note that a JMenu is always
followed by a JPopupMenu.
If a menu item in a popup menu is selected, the sequence of menu objects is simply
JPopupMenu and JMenuItem. If the menu item is part of a nest menu, the sequence is,
JPopupMenu, JMenu, JPopupMenu, and JMenuItem.
if (path.length == 0) {
// No menus are opened or menu items selected
}
if (c instanceof JMenuItem) {
JMenuItem mi = (JMenuItem)c;
String label = mi.getText();
// Note: JMenu is a subclass of JMenuItem; also JMenuBar
does not have a label
}
}
85. Creating a Menu Item That Listens for Changes to Its Selection Status
86. Listening for Changes to the Currently Selected Menu or Menu Item
if (path.length == 0) {
// All menus are hidden
}
}
}
);
JTOOLBAR
A toolbar can be either horizontal or vertical. When the orientation is horizontal, the
objects in the toolbar are displayed left-to-right. When the orientation is vertical, the
objects in the toolbar are displayed top-to-bottom. This orientation is automatically
changed when the toolbar is moved to the top or side of a container.
// Create a horizontal toolbar
JToolBar toolbar = new JToolBar();
// Add a button to the toolbar; remove the label and margin before
adding
JButton c1 = new JButton(action);
c1.setText(null);
c1.setMargin(new Insets(0, 0, 0, 0));
toolbar.add(c1);
// Add a toggle button; remove the label and margin before adding
JToggleButton c2 = new JToggleButton(action);
c2.setText(null);
c2.setMargin(new Insets(0, 0, 0, 0));
toolbar.add(c2);
// Add a combobox
JComboBox c3 = new JComboBox(new String[]{"A", "B", "C"});
c3.setPrototypeDisplayValue("XXXXXXXX"); // Set a desired width
c3.setMaximumSize(c3.getMinimumSize());
toolbar.add(c3);
When the orientation of a toolbar is changed, either by the user or programmatically, the
toolbar fires a property change event.
// Create a floatable horizontal toolbar
JToolBar toolbar = new JToolBar();
if (newValue.intValue() == JToolBar.HORIZONTAL) {
// toolbar now has horizontal orientation
} else {
// toolbar now has vertical orientation
}
}
}
});
By default, a toolbar can float, that is, it can be dragged to a different edge in its container
or it can be moved into a top-level window.
// Create a horizontal toolbar
JToolBar toolbar = new JToolBar();
// Disable floatability
toolbar.setFloatable(false);
By default, a button in a toolbar does not change its appearance when the cursor is over
the button. However, if the toolbar is in rollover mode, the buttons will highlight while
under a cursor.
// Create a horizontal toolbar
JToolBar toolbar = new JToolBar();
JSCROLLPANE
The Swing components do not typically have scroll bars. In order to automatically
display scroll bars, you need to wrap the component in a scroll pane.
// Create a scrollable text area
JTextArea textArea = new JTextArea();
JScrollPane scrollableTextArea = new JScrollPane(textArea);
A scroll bar in a scroll pane can be set to appear only as needed, always appear, or never
appear. By default, both the vertical and horizontal scrollbars in a scroll pane appear only
when needed.
// Create a scrollable text area
JTextArea textArea = new JTextArea();
JScrollPane pane = new JScrollPane(textArea);
pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAY
S);
pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
);
pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
A scrollbar in a scroll pane fires adjustment events whenever its value changes.
// Create a scrollable text area
JTextArea textArea = new JTextArea();
JScrollPane pane = new JScrollPane(textArea);
JSPLITPANE
94. Creating a JSplitPane Container
A split pane divides its space between two components. The split pane contains a divider
that allows the user to control the amount of space distributed to each component.
// Create a left-right split pane
JSplitPane hpane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
leftComponent, rightComponent);
By default, when the divider is dragged, a shadow is displayed to indicate where the
divider would be when the mouse is released. It is possible for the split pane to
continuously move the divider and resize its child components while the user is dragging
the divider.
boolean b = vpane.isContinuousLayout(); // false by default
vpane.setOneTouchExpandable(true);
The weight of a split pane controls the behavior of the divider when the split pane is
resized. If the weight is 0, all extra space is given to the right or bottom component. If the
weight is 1, all extra space is given to the left or top component. A weight of .3 specifies
that the left or top component gets one-third of the extra space. The weight also
determines how the children lose space when the size of the split pane is reduced. For
example, a weight of 0 means that the left or top component does not lose any space.
The weight also controls the starting location of the divider. For example, if the weight
is .5, the divider is placed in the center.
The location of a divider is measured in pixels from either the left edge (in the case of a
horizontal split pane) or the top edge (in the case of a vertical split pane).
There are two ways to set the location of the divider. The first is to specify an absolute
location based on the distance in pixels from the left or top edge. The second is to specify
a proportional location based on the distance from the left or top edge. For example, a
proportional location of 0 sets the divider at the left or top edge. A proportional location
of 1 sets the divider at the right or bottom edge. A proportional location of .5 sets the
divider at the center.
JTABBEDPANE
A tabbed pane is a container that displays only one child component at a time. Typically,
the children are themselves containers of other components. Each child is associated with
a visible tab on the tabbed pane. The user can choose a child to display by selecting the
tab associated with that child.
// Create a child container which is to be associated with a tab
JPanel panel = new JPanel();
// Add components to the panel...
// Add a tab
String label = "Tab Label";
pane.addTab(label, panel);
// Add a tab with a label taken from the name of the component
component1.setName("Tab Label");
pane.add(component1);
// Add a tab with a label and icon at the end of all tabs
Icon icon = new ImageIcon("icon.gif");
pane.addTab(label, icon, component3);
// Add a tab with a label, icon, and tool tip at the end of all tabs
String tooltip = "Tool Tip Text";
pane.addTab(label, icon, component4, tooltip);
To move a tab, it must first be removed and then reinserted into the tabbed pane as a new
tab. Unfortunately, since there is no object that represents a tab, it is necessary to record
all of the tab's properties before moving it and to restore them after the new tab has been
created.
// Get icon
Icon icon = pane.getIconAt(i);
// Is enabled?
boolean enabled = pane.isEnabledAt(i);
// Get mnemonic
int keycode = pane.getMnemonicAt(i);
// Get the index of the first tab that matches an icon; the supplied
// icon must be the same instance that was used to create the tab
index = pane.indexOfTab(icon);
// Get the index of the tab by matching the child component; the
supplied
// component must be the same instance that was used to create the
tab
index = pane.indexOfComponent(component);
if (index < 0) {
// The tab could not be found
}
The tabs of a tabbed pane can be placed on one of the four edges of its container. By
default, when a tabbed pane is created, the tabs are placed on top.
// Create a tabbed pane with the tabs on top
JTabbedPane pane = new JTabbedPane();
// Add a tab
pane.addTab("Tab Label", component);
There are two ways to set a tool tip on a tab. The first is to specify it when the tab is
created; the second way is to set it using JTabbedPane.setToolTipTextAt().
// Create a tabbed pane
JTabbedPane pane = new JTabbedPane();
// Add a tab
String label = "Tab Label";
pane.addTab(label, component);
// Get index of the new tab
int index = pane.getTabCount()-1;
Setting a mnemonic on a tab allows the tab to be selected with a keystroke. For example,
if the mnemonic for a tab were the key L, then typing ALT-L (on Windows) would select
the tab.
// Create a tabbed pane
JTabbedPane pane = new JTabbedPane();
// Add a tab
pane.addTab("Tab Label", component);
// Set the mnemonic; on some look and feels, the L in the label will
be underlined
int keycode = KeyEvent.VK_L;
pane.setMnemonicAt(index, keycode);
By default, all the tabs in a tabbed pane are displayed. When the tabs are wider than the
width of the tabbed pane, they are displayed in rows. If space is an issue, it is possible to
configure the tabs to appear in a single row along with a scroller that allows the tabs to be
scrolled into view.
// Create a tabbed pane
JTabbedPane pane = new JTabbedPane();
// Add tabs...;
A desktop is a container that can only hold internal frames (JInternalFrame objects).
This example creates a desktop with an internal frame.
// Create an internal frame
boolean resizable = true;
boolean closeable = true;
boolean maximizable = true;
boolean iconifiable = true;
String title = "Frame Title";
JInternalFrame iframe = new JInternalFrame(title, resizable,
closeable, maximizable, iconifiable);
TOOLTIPS
By default, when a tool tip of a component appears, its northwest corner appears at the
same x-coordinate as the cursor and 20 pixels lower than the y-coordinate of the cursor.
To change this default location for a component, the getToolTipLocation() method of
the component must be overridden.
// Set the location of the tool tip such that its nw corner
// coincides with the nw corner of the button
JButton button = new JButton("My Button") {
public Point getToolTipLocation(MouseEvent event) {
return new Point(0, 0);
}
};
// Set the location of the tool tip such that its nw corner
// coincides with the bottom center of the button
button = new JButton("My Button") {
public Point getToolTipLocation(MouseEvent event) {
return new Point(getWidth()/2, getHeight());
}
};
By default, tool tips are enabled for the entire application. So if a component has a tool
tip text, it will be displayed. To enable or disable tool tips for the entire application,
ToolTipManager.setEnabled() is used. Note: Enabling or disabling the tool tip for a
particular component can be done only by adding or removing the tool tip text on the
component.
// Enable tool tips for the entire application
ToolTipManager.sharedInstance().setEnabled(true);
By default, when the cursor enters a component, there is a 750-millisecond delay before
the tool tip is displayed. This example demonstrates how to show the tool tip
immediately.
// Get current delay
int initialDelay =
ToolTipManager.sharedInstance().getInitialDelay();
By default, a tool tip stays visible for 4 seconds. This example demonstrates how to keep
the tool tip showing as long as the cursor is in the component.
// Get current delay
int dismissDelay =
ToolTipManager.sharedInstance().getDismissDelay();
A tool tip can show simple HTML tags when surrounded by the tags <HTML> and
</HTML>. This example shows how to create multiple lines by using the <BR> tag. See the
javax.swing.text.html.HTML class documentation for a list of supported tags.
// Show two lines in the tool tip
component.setToolTipText("<html>"+"This is a"+"<br>"+"tool
tip"+"</html>");
A tool tip can show simple HTML tags when surrounded by the tags <HTML> and
</HTML). This example shows how to include an image in a tool tip by using the <IMG>
tag. See the javax.swing.text.html.HTML class documentation for a list of other
supported tags.
String imageName = "file:image.jpg";
component.setToolTipText("<html>Here is an image <img
src="+imageName+"></html>");
LAYOUT
121. Laying Out Components in a Row or Column
A horizontal box container arranges the components left-to-right in their preferred sizes.
The row of components are vertically centered.
// Create horizontal box container
Box box = new Box(BoxLayout.X_AXIS);
// Add components
box.add(component1);
box.add(component2);
A vertical box container arranges the components top-to-bottom aligned in their preferred
sizes. The column of components are left-aligned.
// Create vertical box container
box = new Box(BoxLayout.Y_AXIS);
// Add components
box.add(component1);
box.add(component2);
When components are added to the container, they fill the grid left-to-right, top-to-
bottom.
int rows = 2;
int cols = 2;
JPanel panel = new JPanel(new GridLayout(rows, cols));
panel.add(component1);
panel.add(component2);
Actions can also contain other optional information, such as a label, icon, or tool tip text.
When the action is attached to a component, the component may use this information if
present. For example, if the action has a label and icon, a button created using that action
will use that label and icon.
This example defines an action and creates a button using the action.
// Set an icon
Icon icon = new ImageIcon("icon.gif");
putValue(Action.SMALL_ICON, icon);
Actions can be bound to many different kinds of components. When an action is enabled
or disabled, components that are bound to that action may automatically alter its display
to match the enabled state of the action. This example creates three components: a button,
a text component, and a menu item - - all bound to the same action. When the action is
disabled, the button and menu item will appear disabled and the text component will not
be able to invoke the action.
JFrame frame = new JFrame();
// Button
JButton button = new JButton(action);
// Text Component
JTextField textfield = new JTextField();
textfield.getInputMap(JComponent.WHEN_FOCUSED).put(
KeyStroke.getKeyStroke("F2"), action.getValue(Action.NAME));
textfield.getActionMap().put(action.getValue(Action.NAME), action);
// Menu Item
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu Label");
menu.add(new JMenuItem(action));
menuBar.add(menu);
frame.setJMenuBar(menuBar);
// The action
public Action action = new AbstractAction("Action Name") {
public void actionPerformed(ActionEvent evt) {
// Perform action
}
};
This example creates a number of keystrokes and adds them to the input map of a
component. When a keystroke is added to an input map, an action name must be
supplied. This action is invoked when the keystroke is pressed while the component has
the focus.
// Create some keystrokes and bind them all to the same action
component.getInputMap().put(KeyStroke.getKeyStroke("F2"),
"actionName");
component.getInputMap().put(KeyStroke.getKeyStroke("control A"),
"actionName");
component.getInputMap().put(KeyStroke.getKeyStroke("shift F2"),
"actionName");
component.getInputMap().put(KeyStroke.getKeyStroke('('),
"actionName");
component.getInputMap().put(KeyStroke.getKeyStroke("button3 F"),
"actionName");
component.getInputMap().put(KeyStroke.getKeyStroke("typed x"),
"actionName");
component.getInputMap().put(KeyStroke.getKeyStroke("released
DELETE"), "actionName");
component.getInputMap().put(KeyStroke.getKeyStroke("shift UP"),
"actionName");
The KeyStroke.toString() method does not return a string that can be parsed by
KeyStroke.getKeyStroke(). The method keyStroke2String() in this example returns
a string that is parseable by KeyStroke.getKeyStroke(). However, there is one
keystroke that cannot be represented as a string that can be parsed back to a keystroke - -
a typed space character. In order to bind an action to a typed space character,
KeyStroke.getKeyStroke(new Character(' '), 0) needs to be called.
public static String keyStroke2String(KeyStroke key) {
StringBuffer s = new StringBuffer(50);
int m = key.getModifiers();
switch (key.getKeyEventType()) {
case KeyEvent.KEY_TYPED:
s.append("typed ");
s.append(key.getKeyChar() + " ");
break;
case KeyEvent.KEY_PRESSED:
s.append("pressed ");
s.append(getKeyText(key.getKeyCode()) + " ");
break;
case KeyEvent.KEY_RELEASED:
s.append("released ");
s.append(getKeyText(key.getKeyCode()) + " ");
break;
default:
s.append("unknown-event-type ");
break;
}
return s.toString();
}
switch(keyCode) {
case KeyEvent.VK_COMMA: return "COMMA";
case KeyEvent.VK_PERIOD: return "PERIOD";
case KeyEvent.VK_SLASH: return "SLASH";
case KeyEvent.VK_SEMICOLON: return "SEMICOLON";
case KeyEvent.VK_EQUALS: return "EQUALS";
case KeyEvent.VK_OPEN_BRACKET: return "OPEN_BRACKET";
case KeyEvent.VK_BACK_SLASH: return "BACK_SLASH";
case KeyEvent.VK_CLOSE_BRACKET: return "CLOSE_BRACKET";
This example demonstrates how to list all the key bindings in a component. Text
components have an additional set of key bindings called a keymap.
// List keystrokes in the WHEN_FOCUSED input map of the component
InputMap map = component.getInputMap(JComponent.WHEN_FOCUSED);
list(map, map.keys());
// List keystrokes in the component and in all parent input maps
list(map, map.allKeys());
component1.setActionMap(am);
component2.setActionMap(am);
This example searches all of a component's inputmaps and keymaps (if the component is
a text component) for a particular keystroke.
FindResult r = find(KeyStroke.getKeyStroke("ctrl pressed C"),
component);
r = find(KeyStroke.getKeyStroke("ctrl released C"), component);
r = find(KeyStroke.getKeyStroke("C"), component);
r = find(KeyStroke.getKeyStroke("typed C"), component);
r = find(KeyStroke.getKeyStroke(new Character('\u0002'), 0),
component);
b.append("inputmap="+inputMap+",keymap="+keymap
+",defaultAction="+defaultAction+",isLocal="+isLocal);
return b.toString();
}
}
// Check keymaps
if (c instanceof JTextComponent) {
JTextComponent tc = (JTextComponent)c;
result = new FindResult();
// Add a KeyStroke
inputMap.put(KeyStroke.getKeyStroke("F2"), "actionName");
inputMap.setParent(component.getInputMap(JComponent.WHEN_FOCUSED));
component.setInputMap(JComponent.WHEN_FOCUSED, inputMap);
THESCREEN
To change the look and feel, you need to know the class name of the new look and feel.
This example installs the Windows look and feel.
// Get the currently installed look and feel
LookAndFeel lf = UIManager.getLookAndFeel();
By default, Swing uses a cross-platform look and feel called Metal. In most cases, it is
more desirable to use a look and feel that is closer to the platform on which the
application is being run. This example demonstrates how to retrieve and install the look
and feel that most closely resembles the current platform.
// Get the native look and feel class name
String nativeLF = UIManager.getSystemLookAndFeelClassName();
141. Setting the Default Look and Feel Using a System Property or
Property File
By default, Swing uses a cross-platform look and feel called Metal. This default can be
changed with a system property on the command line, an entry in a properties file, or
programmatically.
The following example demonstrates how to set the look and feel using a system property
on the command line:
> java
-Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel
MyApp
Alternatively, the default look and feel can be set in a properties file called
`swing.properties' located in the `<JAVAHOME>/lib' directory. The name of the
property is swing.defaultlaf.
# Specify the default look and feel
swing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel
UI DEFAULT VALUES
142. Getting the Default Values for a Look and Feel
This example demonstrates how to retrieve all the default values for the current look and
feel.
// Get the currently installed look and feel
UIDefaults uidefs = UIManager.getLookAndFeelDefaults();
if (v instanceof Integer) {
int intVal = uidefs.getInt(keys[i]);
} else if (v instanceof Boolean) {
boolean boolVal = uidefs.getBoolean(keys[i]);
} else if (v instanceof String) {
String strVal = uidefs.getString(keys[i]);
} else if (v instanceof Dimension) {
Dimension dimVal = uidefs.getDimension(keys[i]);
} else if (v instanceof Insets) {
Insets insetsVal = uidefs.getInsets(keys[i]);
} else if (v instanceof Color) {
Color colorVal = uidefs.getColor(keys[i]);
} else if (v instanceof Font) {
Font fontVal = uidefs.getFont(keys[i]);
} else if (v instanceof Border) {
Border borderVal = uidefs.getBorder(keys[i]);
} else if (v instanceof Icon) {
Icon iconVal = uidefs.getIcon(keys[i]);
} else if (v instanceof
javax.swing.text.JTextComponent.KeyBinding[]) {
javax.swing.text.JTextComponent.KeyBinding[] keyBindsVal =
(javax.swing.text.JTextComponent.KeyBinding[])uidefs.get(keys[i]);
} else if (v instanceof InputMap) {
InputMap imapVal = (InputMap)uidefs.get(keys[i]);
} else {
// Unknown type
}
}
When a UI default value is fairly large and may never be used, the value should be lazily
created. This means that the value should be created only when the value is fetched. The
UIDefaults table allows for such values.
For values that are created every time they are fetched. This example declares a lazy
value (a JPanel) that is created only when fetched.
The UIDefaults table supports values that are created every time they are fetched. Such
values are called active values.
This example declares an active value (a Date) that is created every time it is fetched.
// Fetch the value twice; this causes the value to be created twice
Date d1 = (Date)UIManager.get("key");
Date d2 = (Date)UIManager.get("key");
boolean b = d1.equals(d2); // false
JAVAX.SWING.BORDER
There are several types of borders available, each represented by its own class. A border
can be created using the class' constructor or using a border factory. The border factory is
the typical method for creating a border since it creates the border using values that are
compatible with the current look and feel. However, if custom values are required, the
border should be created using a constructor.
// Create a border
EmptyBorder emptyBorder =
(EmptyBorder)BorderFactory.createEmptyBorder();
LineBorder lineBorder =
(LineBorder)BorderFactory.createLineBorder(Color.black);
EtchedBorder etchedBorder =
(EtchedBorder)BorderFactory.createEtchedBorder();
BevelBorder raisedBevelBorder =
(BevelBorder)BorderFactory.createRaisedBevelBorder();
BevelBorder loweredBevelBorder =
(BevelBorder)BorderFactory.createLoweredBevelBorder();
JAVAX.SWING.COLORCHOSER
The following example creates a temporary color chooser dialog and shows it:
Color initialColor = Color.red;
// Show the dialog; this method does not return until the dialog is
closed
Color newColor = JColorChooser.showDialog(frame, "Dialog Title",
initialColor);
Here is a more elaborate example that defines an action that creates and shows a color
chooser dialog. This action can be used in components such as a button or a menu item.
// This action creates and shows a modeless color chooser dialog.
public class ShowColorChooserAction extends AbstractAction {
JColorChooser chooser;
JDialog dialog;
setEnabled(false);
}
};
Here's some code that demonstrates the use of the action:
JFrame frame = new JFrame();
Normally, the color is retrieved from a color chooser dialog when the dialog is closed.
// Create the chooser
JColorChooser chooser = new JColorChooser();
PREVIEW PANEL
152. Customizing the Preview Panel of a JColorChooser Dialog
The preview panel shows the selected color in a particular context. The default preview
panel colors some text with the selected color.
It may be desirable to change the preview panel to a more relevant setting. For example,
if the color chooser is used to color an image, a miniature version of the image can be
shown in the preview panel.
COLORCHOOSERPANEL
There are three chooser panels in the default JColorChooser dialog. Although each is
implemented by a class in the javax.swing.colorchooser package, these classes are
not public. This example demonstrates how to identify these panels by class name.
JColorChooser chooser = new JColorChooser();
if (clsName.equals(name)) {
return panels[i];
}
}
return null;
}
// Remove panels
for (int i=0; i<oldPanels.length; i++) {
String clsName = oldPanels[i].getClass().getName();
if
(clsName.equals("javax.swing.colorchooser.DefaultSwatchChooserPanel")) {
// Remove swatch chooser if desired
chooser.removeChooserPanel(oldPanels[i]);
} else if
(clsName.equals("javax.swing.colorchooser.DefaultRGBChooserPanel")) {
// Remove rgb chooser if desired
chooser.removeChooserPanel(oldPanels[i]);
} else if
(clsName.equals("javax.swing.colorchooser.DefaultHSBChooserPanel")) {
// Remove hsb chooser if desired
chooser.removeChooserPanel(oldPanels[i]);
}
}
This example creates a color chooser panel with three colored buttons. Clicking on a
button changes the selected color to the color of the button.
JColorChooser chooser = new JColorChooser();
chooser.addChooserPanel(new MyChooserPanel());
getColorSelectionModel().setSelectedColor(button.getBackground());
}
};
}
EVENTS
This example defines an action that creates and shows a color chooser dialog.
// Create the chooser
final JColorChooser chooser = new JColorChooser();
JAVAX.SWING.EVENT