Using ButtonGroup to Manage Selection
A JToolBar is created with new JToolBar() and placed in a container, such as along BorderLayout.NORTH, using an add call with a region name.
Predicting the Toolbar Before Reading On
This article works from a real example rather than from a list of rules. The example is the constructor of a Swing application that draws with the mouse and offers a small toolbar at the top of the window. The toolbar holds three color choices, presented as radio buttons, followed by a separator and a clear button.
Before reading any explanation, look at the constructor and try to form your own picture of what the window will look like and in what order its pieces appear. The goal is to connect each line of the constructor to one visible or structural result. Once you can do that, you can also find the exact line where a toolbar behaves differently from what you expected, which is the skill that matters most when a GUI does not look right.
Where the Toolbar Lives in the Window
The toolbar is a JToolBar, created with new JToolBar(). Creating the object does not by itself put it on screen. It is placed in a container by an add call that names a region. In this example the region is BorderLayout.NORTH, which places the toolbar along the top edge of the container. The CENTER region is left for the main drawing area.
The toolbar itself does not decide where it goes. The container's layout manager decides, based on the region name given in the add call. The same toolbar object placed under a different region name would sit in a different part of the window.
- new
JToolBar()creates the toolbar object; nothing is displayed yet. - new
ButtonGroup()creates one selection group, shared by all three color buttons. - Each
makeColorRadioButtoncall passes the samecolorGroupobject. The source excerpt does not show the body of this helper, so only its arguments are explained here. addSeparatorwith a Dimension argument adds a visual divider between the color choices and the clear button.add(toolbar, BorderLayout.NORTH)places the toolbar in the top region of the container.
How Add Order Sets the Layout
A toolbar's contents follow the order of the add calls. Swing does not reorder components for you. The first component added appears first, the next appears after it, and so on. A separator added with addSeparator takes its own position in that sequence, just like a button does.
Reading the toolbar from its add calls
Given the five add calls in the sample constructor, determine which item sits at the far right end of the toolbar once the constructor finishes.
- 1Find the toolbar's add calls
Only calls that target the toolbar object place items on it. The three color buttons, the separator, and the clear button are all added to the toolbar, in that order.
- 2Apply the order rule
Components appear in the order their add calls run. So the first call sits leftmost and the last call sits rightmost.
- 3Identify the last call
The last add call on the toolbar is the one for the clear button, which runs after the separator.
- 4Compare with your prediction
If you guessed a color button at the far right, the gap between your guess and the add order is the place to look for the misunderstanding.
The clear button sits at the far right end of the toolbar, because its add call is the last one on the toolbar.
What do you think happens?
Once the constructor finishes, which item sits at the far right end of the toolbar?
Reveal answer
The clear button
Components appear in the order their add calls run, and the clear button is added last on the toolbar. Swing does not reorder components, so the last add call determines the rightmost item.
Why Radio Buttons Need a Shared Group
The three color choices are radio buttons. Radio buttons are meant to offer mutually exclusive options: the user picks one color, and picking another should release the first. Swing does not get this behavior automatically just because the buttons sit next to each other on a toolbar. The grouping must be declared, and in this example it is declared with a ButtonGroup.
A ButtonGroup must be created and shared by the radio buttons for them to be mutually exclusive. In this example one group object serves all of the color buttons. The group, not the individual buttons, is responsible for the rule that only one choice can be selected at a time. This is why the code creates the group once and passes the same group object to each call of makeColorRadioButton.
The diagram shows the behavior the shared group produces. Picking Green releases Red, and Blue is untouched because it was never selected. The rule lives in the group. Each button is registered with the same group, so selecting one causes the group to deselect the others.
Display Versus Selection Logic
Two separate structures are involved, and it helps to keep them apart. The toolbar is the display: it holds the components and shows them in the order of their add calls, in the region named by the container's add call. The ButtonGroup is the selection logic: it holds the rule that only one radio button in the group can be selected at a time.
The source describes the toolbar and the group as separate roles, so the safe reading is that placing a button on the toolbar and registering it with the group are two distinct steps. Keeping them distinct is what lets you ask the right question when something is wrong: is the button missing from the display, or is its selection behaving incorrectly?
Tracing an Unexpected Toolbar
When a toolbar behaves unexpectedly, trace the constructor line by line and compare each line's effect with what you expected. The first line that diverges from your expectation is the failure location. The constructor serves as the trace: you do not need to guess where the problem is, you walk the lines in order.
- 1Write down what you expect each line to produce, such as a toolbar object, a shared group, or a component at a given position.
- 2Run through the constructor from the first line, checking each line's effect against your expectation.
- 3Stop at the first line where the actual result differs from what you wrote down.
- 4Check whether that line adds to the right container, uses the right region name, or shares the right group object.
Common mistake Assuming radio buttons are exclusive just because they sit together on a toolbar
What it looks likeThree radio buttons added to the toolbar with no shared group, and all three remain selectable at once.
Why it failsThe source states that Swing does not get mutual exclusion automatically from placement. The grouping must be declared.
Do this insteadCreate one ButtonGroup and pass the same group object to every radio button that should be mutually exclusive.
Common mistake Creating a new ButtonGroup for each radio button
What it looks likeEach color button is given its own group object, so selecting one never releases another.
Why it failsThe group is what enforces the one-selection rule. Separate groups have no relationship to each other.
Do this insteadCreate the group once and pass that same object to each call.
Common mistake Expecting Swing to reorder components on the toolbar
What it looks likePredicting that the separator moves to the far left because it looks like a divider.
Why it failsComponents appear in the order their add calls run. Swing does not reorder them.
Do this insteadRead the add calls top to bottom and place each component in that sequence.
Practicing the Trace
Using only the toolbar lines of the sample constructor, list the components on the toolbar from left to right. Then say which line you would check first if the toolbar showed the clear button before the green radio button.
Hints
- Start with the first add call that targets the toolbar.
- A separator takes a position in the sequence just like a button.
- If the order is wrong, look for an add call that runs earlier than you expected.
Key Takeaways
- A
JToolBaris created with newJToolBar()and placed in a container with an add call that names a region, such asBorderLayout.NORTH. - Components on a toolbar appear in the order their add calls run, including separators, and Swing does not reorder them.
- Radio buttons are mutually exclusive only when they share one ButtonGroup object, which holds the one-selection rule.
- The toolbar handles display and the ButtonGroup handles selection; keeping these roles separate helps you locate a fault.
- When a toolbar behaves unexpectedly, trace the constructor line by line and stop at the first line whose result differs from your expectation.