Into Java - Part XVIII
Last time I promised you an overview of Java GUI stuff. In the past we have used menus, buttons and a few more. Java offers you an extensive bunch of GUI stuff ready for use. Most of them you can twist and tune to your needs, although it is not that easy all of the time. This time we will use some of the most oft used items.
Today's little app is of no use at all, it will only show some useful GUI tools and most of the ways you can tune the ever-so-handy JOptionPane. Furthermore, the code is not as elegant as I have tried to write before, but I hope it is readable and understandable. The idea is not the code itself but the items we wil explore, and the resulting panes. ShowOptionDialog.java and OptionPanel.java.
Admittedly the bottom idea is borrowed from Core Java 2, Volume 1 by Horstmann&Cornell, but their OptionDialogTest does not offer all of the option panes, and I wanted to use most of the GUI tools developers are used to seeing. Hence, this is a completely new application.
As you can see, we will make use of radio buttons, check boxes, text input fields, a combo box and a selection list. All of these are heavily used in most applications. Unfortunately, this column would grow into a booklet if I covered every aspect of these items, so I will only briefly show you one or two ways to use them.
Radio buttons differ from check boxes, which look quite similar, in that they only allow one choice at a time. Hence there must be some mechanism that sees that this restriction is maintained. This is done by grouping radio buttons together. Here is a short excerpt from the source code.
In the source code you will see that quite a few variables (objects) are declared as instance variables. They are declard this way since they must be available later in the code. Otherwise it is preferred to only declare them locally and so reduce the variable list.
The first line here shows how we create a ButtonGroup. That seems confusing, until we realize that most clickable items are considered buttons, inheriting from jawax.swing.AbstractButton. It is also possible to add other items than JRadioButtons to such a group.
Nevertheless, we will create a group that will assure that only one of the JRadioButtons added to this group will be selected. We continue creating JRadioButtons one at a time and add these to the group. We only show two of the radio buttons here. (The n seen here is only a Box to hold the items.)
We add an actionListener, since we will change some information on the application's panels depending on which radio button is selected. As usual we have a method, actionPerformed, that takes care of the events resulting from selecting radio buttons issuing several if/else if-clauses.
The actionCommand is used when we would like to find out which radio button is selected from a group. Note that if we would like to get the actionCommand, then we must add an actionCommand. That differs from JButton were the button text is the command if a command is not explicitly set.
We ask the group for its selection which is a somewhat cumbersome way to get the item that is selected. Once we have this item we ask for its actionCommand, the string we set before.
It will not become more complex than this. I have used a vertical box, but any layout is possible. The button group is a question of code, not layout. Naturally, most users will be surprised if they find the radio buttons spread about rather than together.
In conclusion, radio buttons are very useful when you look for a visible GUI item, and only one choice is permitted at a time. They are grouped together.
On the other hand, check boxes are handy when you look for visible GUI items, but one or more options are possible. Hence they do not need any group, but if for any purpose a ButtonGroup is needed, JCheckBox implements the button model as well.
As with the radio buttons the check boxes are declared as instance variables. As a convenience to the user we add a tool-tip. Finally we add it to the vertical box of that pane, but any layout is possible.
When we want to control if a check box is selected we can ask them one after another, as
within several if/if else-clauses. In the source code you can find examples of this in the method getMessage.
Many times we have to ask the user for written input, for this, text fields are useful. Here we simply create one text field with an initial text.
Developers need to take caution when they use input text fields in any form, why? Because we can not be assured of a clean input. A user can type rubbish, and we need to be cautious; when we expect a number typed, what happens if we try to parse a value from nonsense input? When we expect one of a set of key words, what happens if it is misspelled or rubbish? Look at the method getMessage and see how I took care of getting things straightened out.
One item often used is the combo box. Having a number of options but not the place to show them all, a combo box seems to be very flexible. It takes a minimum of space but still shows the currently selected option, and it can show quite a few options in its scrollable pane when needed.
We create a JComboBox and then add a few String items to it. It is possible to add objects other than text strings to the list, but I suppose strings are the most used. We have the option to select an initial item, but that is not needed. Though, consider what will happen if you ask the control which item is selected and it has none selected.
As you see, it is possible to ask for the selected index, which is relevant when the index matches some code lines of yours, as we see in this case. It is also possible to get the selected object, or objects if the option to select multiple items is set.
The list selector looks quite similar to the combo box, but it shows more than one item at once. It is also rather complex to work with, compared to the combo box. We have to set quite a few more options. Horstmann&Cornell also consider them overworked. In short, Java hands you every possible way to tune the list, add items dynamically to it, or remove items, you name it. The price is a more complex product.
We need to make a list of items to select from. Then we use that list when we create the JList. Unfortunately, the default for the JList is multiple selection. We need to change that using one of the constants available. Continuing, we tell the list how many rows we would like to view, how big the list's window will be. Finally we have to hand it a JScrollPane to rest in. This is the minimum possible code, and I will not show you more than that.
As with combo boxes, we can ask for the selected index if single selection is set. It is also possible to ask for the selected value to get one object back. Otherwise, with multiple selection, we can ask for the selected indices or the selected values.
So far we have seen the most often used GUI tools, and you can make the choice yourself. There are many more to study, but for this I'll recommed you read Sun's Java Tutorial on GUI Components. The source code ties them together on six panes where you can make your selections to get the option pane you wish.
Swing's Option Panes
There are basically four kinds of option panes, the message pane, the confirm-pane, the input-pane and finally the option-pane offering as many options as you give it. The three first ones are the most oft used, and the ones we don't need to worry much about.
All of these three have a basic constructor that takes only two parameters, the parent and the message. Simple, is it not? The best thing about them is if you do not want to, you do not need do any more than use this one. Although most of us would like to try something stronger once in a while. When this is the case, we have to know a little about the other options to use.
- Message Type
- Option Type
- An Object array
The title needs no explanation I suppose. There are default titles to the three panes, but why not type one yourself?
The message type simply chooses an appropriate default style of the pane. The three have default types, but you can pick one yourself. Then you use constants held by the JOptionPane class:
JOptionPane.PLAIN_MESSAGE JOptionPane.ERROR_MESSAGE JOptionPane.INFORMATION_MESSAGE JOptionPane.WARNING_MESSAGE JOptionPane.QUESTION_MESSAGE
The option type determines the set of buttons on the dialog pane. If the constants are not satisfactory you can create anything with the showOptionDialog choice.
JOptionPane.DEFAULT_OPTION JOptionPane.YES_NO_OPTION JOptionPane.YES_NO_CANCEL_OPTION JOptionPane.OK_CANCEL_OPTION
You are free to use any icon of your choice. It will then appear at the left of the dialog box. I have rarely used this option since the message type icons are most useful.
The object array can hold most objects, but I will not dig into that since it is more tricky than I like. If you need these, it is maybe better to use the JDialog class and make a dialog of your own design instead.
So far you might want to study this table, and at the same time run the enclosed application.
|Message||Title||Message Type||Option Type||Icon||Options|
X = required, O = optional, -- = not applicable
To use the JOptionPane I suggest you have the Java API ready to consult. Which is the correct order of the options? Can I do this or that? The API is your helper, having to use it is not something to be ashamed of.
As I said, this is not the most elegant source code ever written. It serves its purpose this time. The first part of it is the creation part, creating six panels to hold the options. Each of them hold one kind, or at most two kinds, of GUI tools.
Somewhat after the middle of the file the method actionPerformed begins. The first clause takes care of the "Show" button. Since each dialog type has its pros and cons I had to take care of it in a special way, I only use the most complex type of each dialog type but feed them with the true default values if you have not selected one.
After that button we take care of when you select another radio button, that is another dialog type. That action causes a few labels to express if an option is required, optional or N/A. Again the code can be shortened at the price of readability.
So far a bunch of small methods take care of parsing the different options, whether they are selected or not. When looking at getMessage we can see a mishmash of objects added to an object array. Recall that the message can consist of any kind of object, and an array of them too. The result? Sometimes it does not look that nice (grin).
There is not much to say about the rest of the methods, they deliver the selected value, or the equality to no value at all, that is as if we called a constructor with fewer parameters. In fact, when you use the simple constructors they, behind the curtains, call the more complex ones with default values or simply with null pointers until they reach the most complex one. Hence, they are all using the same fundamental dialog, but they offer simpler ways to get to it.
We have not learned much theory this time, but we have touched on many useful tools that can extend your Java apps quite a lot. I will not go further into GUI items in future columns, perhaps using one or two, that's all. There are better ways to learn about them than this column.
Next time I will present threading in Java. Since an application "hangs" when it is executing a lengthy task, it does not listen to mouse clicks nor exit itself, we have to use at least one more thread to takes care of time consuming tasks. Threading is the answer, but is it easily done? Are they safe? Next month you will get the answers. CU then.