Sunday, March 30, 2008

Java: A JDialog and JProgressBar Example

If you have an application that runs for a long time, providing feedback that something is still happening is a really useful thing. Java provides a very wide range of GUI components.

One that fits the need is the JProgressBar. As you might expect, the JProgressBar allows you to draw a progress meter, either horizontally or vertically, and update it while your program is running.

Here is an example of using JProgressBar within a JDialog. JDialog allows you to set the dialog as modal, which will stop the application until the dialog is dismissed (as a JOptionPane does). There are many ways to create a dialog in java, this example includes both and is merely one (very minimalistic) way to do it.

First the JProgressBar object is created and attributes set, including min and max values of 0 and 100, respectively, and size of the progress bar:

JProgressBar pb = new JProgressBar(0,100);
pb.setPreferredSize(new Dimension(175,20));
pb.setString("Working");
pb.setStringPainted(true);
pb.setValue(0);


A JLabel object is created to display some text in the dialog:

JLabel label = new JLabel("Progress: ");


Then the label and progress bar are added to the panel:

JPanel center_panel = new JPanel();
center_panel.add(label);
center_panel.add(pb);



Once the panel is populated, the JDialog object is created, the panel is added,
and it is made visible:

dialog = new JDialog((JFrame)null, "Working ...");
dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);



Some useful actions to perform on the dialog, though not all at the same time:

dialog.setLocationRelativeTo(null); // center on screen
dialog.setLocation(550,25); // position by coordinates
dialog.toFront(); // raise above other java windows



While your program is running, you can update the progress bar by feeding it an integer value between the min and max values:

pb.setValue(25);


You have a couple of options when your program is done. The simplest thing to do is to close the dialog, and then display a JOptionPane, for example, informing the user:

dialog.dispose();


To get more creative, one can add a button to the dialog, which will can close the dialog when pressed. The action is defined by adding an action listener to the button. Here we dynamically add the button, but it could be done at the beginning.

JButton button = new JButton("Done");
button.setActionCommand("done");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt){
if ( evt.getActionCommand().equals("done") ) {
dialog.dispose();
}
}
});


The button is added to a new JPanel object:

JPanel page_end_panel = new JPanel();
page_end_panel.add(button);


Then the new panel is added to the dialog, which will make it appear immediately:

dialog.getContentPane().add(page_end_panel, BorderLayout.PAGE_END);


It's not required, but if you wish to force the user to hit the button, the dialog can be made "modal", which will cause it to act like a JOptionPane. It seems that the visibility of the dialog must be toggled for the change in modality to take effect:

dialog.setModal(true);
dialog.pack();
dialog.setVisible(false);
dialog.setVisible(true);



This will cause the program to wait until the button is pressed, which will dismiss the dialog.

Just in case the dialog is dismissed by closing the window, without hitting the button, you might want to add a call to dispose() anyway. Perhaps that is unnecessary.
dialog.dispose();

No comments: