Monday, May 4, 2009

Java: JOptionPane Examples Part 2 - Intermediate

In my previous JOptionPane article, JOptionPane Examples Part 1 - Basic, I covered several examples of basic usage of the JOptionPane dialog. In this installment, we go beyond basic usage and into some functionality that is documented, but not quite so obviously.

In most examples of the JOptionPane dialog, you'll see a String value used for the "message" argument, which is usually the 2nd argument. In the JOptonPane documentation, the "message" argument is listed generically as type Object in the list of methods.

However, if you read at the beginning where the parameters are discussed, the docs state that "message" can not only be a String, but also any subclassed object of the Component class, which is just about any GUI object you could hope to use! But wait there's more!

Not only can it accept practically any GUI object, but it also can accept an array of GUI objects! If an array is provided, the elements of the array are displayed vertically in the dialog box. This is not a very flexible layout, but it is simple and straightforward.

Example 1: Login/Password Dialog

To create a login/password dialog box, we need more than just the login and password fields, but also label fields so the user knows where to type and what goes there.

Here the two field are defined using a JTextField for the login name and a JPassword field for the password. Each field has a corresponding JLabel. Also included, just for fun, is a "remember me" checkbox.

    // Components related to "login" field
JLabel label_loginname = new JLabel("Enter your login name:");
JTextField loginname = new JTextField(15);
// loginname.setText("EnterLoginNameHere"); // Pre-set some text

// Components related to "password" field
JLabel label_password = new JLabel("Enter your password:");
JPasswordField password = new JPasswordField();
// password.setEchoChar('@'); // Sets @ as masking character
// password.setEchoChar('\000'); // Turns off masking

JCheckBox rememberCB = new JCheckBox("Remember me");
 

The components are wrapped up into an Object array.

    Object[] array = { label_loginname, 
loginname,
label_password,
password,
rememberCB };
 

Then the dialog is initiated using showConfirmDialog(), with "OK" and "Cancel" buttons, and without any icon decorations.

    int res = JOptionPane.showConfirmDialog(null, array, "Login", 
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
 

We can respond properly to the user's input, by analyzing the int return value of showConfirmDialog().

    // User hit OK
if (res == JOptionPane.OK_OPTION) { System.out.println( "OK_OPTION" ); }

// User hit CANCEL
if (res == JOptionPane.CANCEL_OPTION) { System.out.println( "CANCEL_OPTION" ); }

// User closed the window without hitting any button
if (res == JOptionPane.CLOSED_OPTION) { System.out.println( "CLOSED_OPTION" ); }
 

Even though, at this point, the dialog is gone, we can still interact with the GUI components. We can determine if the user entered values, regardless if the user hit OK, Cancel, or just closed the window without hitting any buttons, by using the methods of the various objects.

For example, we'll use getText() to get the login name from the "login name" JTextField object. The password is obtained using getPassword() from the "password" JPasswordField object. The state of the "remember me" checkbox can be determined using the isSelected() method.

    // Output data in "login" field, if any
String newloginname = loginname.getText();
System.out.println( "newloginname: " + newloginname );

// Output data in "password" field, if any
String newpassword = new String(password.getPassword());
System.out.println( "newpassword: " + newpassword );

// Output state of "remember me" check box
boolean selectedCB = rememberCB.isSelected();
System.out.println( "selectedCB: " + selectedCB );
 

Example 2: Editable JTextArea with JScrollPane scrollbars

In this example, the showMessageDialog() method of the JOptionPane class is used to display a JTextArea, which is going to be pre-populated with some sample text. The size will be set to show 5 rows and 10 columns. The JTextArea is then set to be editable, so the user can change the data.

    JTextArea area = new JTextArea();
area.setText("line1\nline2\nline3\nline4\nline5\nline6");
area.setRows(5);
area.setColumns(10);
area.setEditable(true);
JScrollPane scrollpane = new JScrollPane(area);
 

Along with a JLabel, the JScrollPane object is added to an Object[] array.

    Object[] array = {
new JLabel("Enter some text:"),
scrollpane,
};
 

The showMessageDialog() method produces a dialog with only an "OK" button and does not return any value.

    JOptionPane.showMessageDialog(null, array, "Text", 
JOptionPane.PLAIN_MESSAGE);
 

The JTextArea can still be interrogated to see if the user changed the value, if desired.

    String newtext = area.getText();
System.out.println( "newtext: " + newtext );
 

Example 3: JRadioButton and ButtonGroup

In this example, a dialog will be created consisting of three JRadioButtons and a JTextField. The radio buttons will be associated with a ButtonGroup, which will cause only one of them to be selected at a time.

Create the button objects and make the first button selected by default.

    JRadioButton b1 = new JRadioButton("Option 1");
JRadioButton b2 = new JRadioButton("Option 2");
JRadioButton b3 = new JRadioButton("Option 3");
b1.setSelected(true);
 

Tie the JRadioButtons together into a group, allowing only one of the group to be selected.

    ButtonGroup group = new ButtonGroup();
group.add(b1);
group.add(b2);
group.add(b3);
 

Define a "name" field as well.

    JTextField name = new JTextField(30);
 

Add the elements together in an array with a few JLabels.

    Object[] array = {
new JLabel("Select an option:"),
b1,
b2,
b3,
new JLabel("Enter a name:"),
name
};
 

Make the dialog appear using showConfirmDialog().

    int res = JOptionPane.showConfirmDialog(null, array, "Select", 
JOptionPane.OK_CANCEL_OPTION);
 

As in the first example, we can analyze the int return value of showConfirmDialog().

    // User hit OK
if (res == JOptionPane.OK_OPTION) { System.out.println( "OK_OPTION" ); }

// User hit CANCEL
if (res == JOptionPane.CANCEL_OPTION) { System.out.println( "CANCEL_OPTION" ); }

// User closed the window without hitting any button
if (res == JOptionPane.CLOSED_OPTION) { System.out.println( "CLOSED_OPTION" ); }
 

The selected button can be determined using the isSelected() method.

    // User selected button 1
if (b1.isSelected()) { System.out.println( "Selected: Option 1" ); }

// User selected button 2
if (b2.isSelected()) { System.out.println( "Selected: Option 2" ); }

// User selected button 3
if (b3.isSelected()) { System.out.println( "Selected: Option 3" ); }
 

The name field can be extracted using getText().

    System.out.println( "name=" + name.getText() );
 

These are just a few examples showing how the JOptionPane class was designed to be very versatile and flexible, allowing for moderately complicated GUI dialog to be created quite easily. Perhaps this usage would have been more obvious if the documentation was clearer, but it is documented.

next time ... part 3 advanced

No comments: