So far, all of our user interface components have appeared inside a frame window that was created in the app. This is the most common situation if you write applets that run inside a web browser. But if you write apps, you usually want separate dialog boxes to pop up to give information to or get information from the user. Just as with most windowing systems, AWT distinguishes between modal and modeless dialog boxes. A modal dialog box won't let the user interact with the remaining windows of the app until he or she deals with it. You use a modal dialog box when you need information from the user before you can proceed with execution. For example, when the user wants to read a file, a modal file dialog box is the one to pop up. The user must specify a file name before the program can begin the read operation. Only when the user closes the (modal) dialog box can the app proceed. A modeless dialog box lets the user enter information in both the dialog box and the remainder of the app. One example of a modeless dialog is a toolbar. The toolbar can stay in place as long as needed, and the user can interact with both the app window and the toolbar as needed. We start this section with the simplest dialogs-modal dialogs with just a single message. Swing has a convenient JOptionPane class that lets you put up a simple dialog without writing any special dialog box code. Next, you will see how to write more complex dialogs by implementing your own dialog windows. Finally, you will see how to transfer data from your app into a dialog and back. We conclude this section by looking at two standard dialogs: file dialogs and color dialogs. File dialogs are complex, and you definitely want to be familiar with the Swing JFileChooser for this purpose-it would be a real challenge to write your own. The JColorChooser dialog is useful when you want users to pick colors.

Option Dialogs

The Swing set has a set of ready-made simple dialogs that suffice when you need to ask the user for a single piece of information. The JOptionPane has four static methods to show these simple dialogs:

showMessageDialog Show a message and wait for the user to click OK.
showConfirmDialog Show a message and get a confirmation (like OK/Cancel).
showOptionDialog Show a message and get a user option from a set of options.
showInputDialog Show a message and get one line of user input. shows a typical dialog. As you can see, the dialog has the following components:
  • An icon;
  • A message;
  • One or more option buttons.

An option dialog

Java graphics 09fig46

The input dialog has an additional component for user input. This can be a text field into which the user can type an arbitrary string, or a combo box from which the user can select one item. The exact layout of these dialogs, and the choice of icons for standard message types, depend on the pluggable look and feel. The icon on the left side depends on the message type. There are five message types:

ERROR_MESSAGE INFORMATION_MESSAGE WARNING_MESSAGE QUESTION_MESSAGE PLAIN_MESSAGE

The PLAIN_MESSAGE type has no icon. For each of the dialog types, there is also a method that lets you supply your own icon instead. For each dialog type, you can specify a message. This message can be a string, an icon, a user interface component, or any other object. Here is how the message object is displayed:

String: Draw the string
Icon: Show the icon
Component: Show the component
Object[]: Show all objects in the array, stacked on top of each other
any other object: Apply toString and show the resulting stringYou can see these options by running the program in . Of course, supplying a message string is by far the most common case. Supplying a Component gives you ultimate flexibility since you can make the paintComponent method draw anything you want. Supplying an array of objects isn't all that useful since there isn't enough room in the dialog to show more than a couple of them-the dialog does not grow to accommodate all message objects. The buttons on the bottom depend on the dialog type and the option type. When calling showMessageDialog and showInputDialog, you get only a standard set of buttons (OK and OK/Cancel, respectively). When calling showConfirmDialog, you can choose among four option types:
DEFAULT_OPTION YES_NO_OPTION YES_NO_CANCEL_OPTION OK_CANCEL_OPTION

With the showOptionDialog you can specify an arbitrary set of options. You supply an array of objects for the options. Each array element is rendered as follows:

String: Make a button with the string as label
Icon: Make a button with the icon as label
Component: Show the component
any other object: Apply toString and make a button with the resulting string as labelThe return values of these functions are as follows:
showMessageDialog None
showConfirmDialog An integer representing the chosen option
showOptionDialog An integer representing the chosen option
showInputDialog The string that the user supplied or selectedThe showConfirmDialog and showOptionDialog return integers to indicate which button the user chose. For the option dialog, this is simply the index of the chosen option, or the value CLOSED_OPTION if the user closed the dialog instead of choosing an option. For the confirmation dialog, the return value can be one of the following:
OK_OPTION CANCEL_OPTION YES_OPTION NO_OPTION CLOSED_OPTION

This all sounds like a bewildering set of choices, but in practice it is simple:

  1. Choose the dialog type (message, confirmation, option, or input).
  2. Choose the icon (error, information, warning, question, none, or custom).
  3. Choose the message (string, icon, custom component, or a stack of them).
  4. For a confirmation dialog, choose the option type (default, Yes/No, Yes/No/Cancel, or OK/Cancel).
  5. For an option dialog, choose the options (strings, icons, or custom components) and the default option.
  6. For an input dialog, choose between a text field and a combo box.
  7. Locate the appropriate method to call in the JOptionPane API.

For example, suppose you want to show the dialog in . The dialog shows a message and asks the user to confirm or cancel. Thus, it is a confirmation dialog. The icon is a warning icon. The message is a string. The option type is OK_CANCEL_OPTION. Here is the call you need to make:

int selection = JOptionPane.showConfirmDialog(parent,
 "Message", "Title",
 JOptionPane.OK_CANCEL_OPTION,
 JOptionPane.WARNING_MESSAGE);
if (selection == JOptionPane.OK_OPTION) . . .

Java graphics exclamatory_icon

The message string can contain newline ('\n') characters. Such a string is displayed in multiple lines.The program in lets you make these selections (see ). It then shows you the resulting dialog.

Example OptionDialogTest.java

 1. import java.awt.*;
 2. import java.awt.event.*;
 3. import java.awt.geom.*;
 4. import java.util.*;
 5. import javax.swing.*;
 6. import javax.swing.border.*;
 7.
 8. public class OptionDialogTest
 9. {
 10. public static void main(String[] args)
 11. {
 12. OptionDialogFrame frame = new OptionDialogFrame();
 13. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 14. frame.show();
 15. }
 16. }
 17.
 18. /**
 19. A panel with radio buttons inside a titled border.
 20. */
 21. class ButtonPanel extends JPanel
 22. {
 23. /**
 24. Constructs a button panel.
 25. @param title the title shown in the border
 26. @param options an array of radio button labels
 27. */
 28. public ButtonPanel(String title, String[] options)
 29. {
 30. setBorder(BorderFactory.createTitledBorder
 31. (BorderFactory.createEtchedBorder(), title));
 32. setLayout(new BoxLayout(this,
 33. BoxLayout.Y_AXIS));
 34. group = new ButtonGroup();
 35.
 36. // make one radio button for each option
 37. for (int i = 0; i < options.length; i++)
 38. {
 39. JRadioButton b = new JRadioButton(options[i]);
 40. b.setActionCommand(options[i]);
 41. add(b);
 42. group.add(b);
 43. b.setSelected(i == 0);
 44. }
 45. }
 46.
 47. /**
 48. Gets the currently selected option.
 49. @return the label of the currently selected radio button.
 50. */
 51. public String getSelection()
 52. {
 53. return group.getSelection().getActionCommand();
 54. }
 55.
 56. private ButtonGroup group;
 57. }
 58.
 59. /**
 60. A frame that contains settings for selecting various option
 61. dialogs.
 62. */
 63. class OptionDialogFrame extends JFrame
 64. {
 65. public OptionDialogFrame()
 66. {
 67. setTitle("OptionDialogTest");
 68. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
 69.
 70. JPanel gridPanel = new JPanel();
 71. gridPanel.setLayout(new GridLayout(2, 3));
 72.
 73. typePanel = new ButtonPanel("Type",
 74. new String[]
 75. {
 76. "Message",
 77. "Confirm",
 78. "Option",
 79. "Input"
 80. });
 81.
 82. messageTypePanel = new ButtonPanel("Message Type",
 83. new String[]
 84. {
 85. "ERROR_MESSAGE",
 86. "INFORMATION_MESSAGE",
 87. "WARNING_MESSAGE",
 88. "QUESTION_MESSAGE",
 89. "PLAIN_MESSAGE"
 90. });
 91.
 92. messagePanel = new ButtonPanel("Message",
 93. new String[]
 94. {
 95. "String",
 96. "Icon",
 97. "Component",
 98. "Other",
 99. "Object[]"
100. });
101.
102. optionTypePanel = new ButtonPanel("Confirm",
103. new String[]
104. {
105. "DEFAULT_OPTION",
106. "YES_NO_OPTION",
107. "YES_NO_CANCEL_OPTION",
108. "OK_CANCEL_OPTION"
109. });
110.
111. optionsPanel = new ButtonPanel("Option",
112. new String[]
113. {
114. "String[]",
115. "Icon[]",
116. "Object[]"
117. });
118.
119. inputPanel = new ButtonPanel("Input",
120. new String[]
121. {
122. "Text field",
123. "Combo box"
124. });
125.
126. gridPanel.add(typePanel);
127. gridPanel.add(messageTypePanel);
128. gridPanel.add(messagePanel);
129. gridPanel.add(optionTypePanel);
130. gridPanel.add(optionsPanel);
131. gridPanel.add(inputPanel);
132.
133. // add a panel with a Show button
134.
135. JPanel showPanel = new JPanel();
136. JButton showButton = new JButton("Show");
137. showButton.addActionListener(new ShowAction());
138. showPanel.add(showButton);
139.
140. Container contentPane = getContentPane();
141. contentPane.add(gridPanel, BorderLayout.CENTER);
142. contentPane.add(showPanel, BorderLayout.SOUTH);
143. }
144.
145. /**
146. Gets the currently selected message.
147. @return a string, icon, component or object array,
148. depending on the Message panel selection
149. */
150. public Object getMessage()
151. {
152. String s = messagePanel.getSelection();
153. if (s.equals("String"))
154. return messageString;
155. else if (s.equals("Icon"))
156. return messageIcon;
157. else if (s.equals("Component"))
158. return messageComponent;
159. else if (s.equals("Object[]"))
160. return new Object[]
161. {
162. messageString,
163. messageIcon,
164. messageComponent,
165. messageObject
166. };
167. else if (s.equals("Other"))
168. return messageObject;
169. else return null;
170. }
171.
172. /**
173. Gets the currently selected options.
174. @return an array of strings, icons or objects, depending
175. on the Option panel selection
176. */
177. public Object[] getOptions()
178. {
179. String s = optionsPanel.getSelection();
180. if (s.equals("String[]"))
181. return new String[] { "Yellow", "Blue", "Red" };
182. else if (s.equals("Icon[]"))
183. return new Icon[]
184. {
185. new ImageIcon("yellow-ball-java-image.gif"),
186. new ImageIcon("blue-ball-java-image.gif"),
187. new ImageIcon("red-ball-java-image.gif")
188. };
189. else if (s.equals("Object[]"))
190. return new Object[]
191. {
192. messageString,
193. messageIcon,
194. messageComponent,
195. messageObject
196. };
197. else
198. return null;
199. }
200.
201. /**
202. Gets the selected message or option type
203. @param panel the Message Type or Confirm panel
204. @return the selected XXX_MESSAGE or XXX_OPTION constant
205. from the JOptionPane class
206. */
207. public int getType(ButtonPanel panel)
208. {
209. String s = panel.getSelection();
210. try
211. {
212. return JOptionPane.class.getField(s).getInt(null);
213. }
214. catch(Exception e)
215. {
216. return -1;
217. }
218. }
219.
220. /**
221. The action listener for the Show button shows a
222. Confirm, Input, Message or Option dialog depending
223. on the Type panel selection.
224. */
225. private class ShowAction implements ActionListener
226. {
227. public void actionPerformed(ActionEvent evt)
228. {
229. if (typePanel.getSelection().equals("Confirm"))
230. JOptionPane.showConfirmDialog(
231. OptionDialogFrame.this,
232. getMessage(),
233. "Title",
234. getType(optionTypePanel),
235. getType(messageTypePanel));
236. else if (typePanel.getSelection().equals("Input"))
237. {
238. if (inputPanel.getSelection().equals("Text field"))
239. JOptionPane.showInputDialog(
240. OptionDialogFrame.this,
241. getMessage(),
242. "Title",
243. getType(messageTypePanel));
244. else
245. JOptionPane.showInputDialog(
246. OptionDialogFrame.this,
247. getMessage(),
248. "Title",
249. getType(messageTypePanel),
250. null,
251. new String[] { "Yellow", "Blue", "Red" },
252. "Blue");
253. }
254. else if (typePanel.getSelection().equals("Message"))
255. JOptionPane.showMessageDialog(
256. OptionDialogFrame.this,
257. getMessage(),
258. "Title",
259. getType(messageTypePanel));
260. else if (typePanel.getSelection().equals("Option"))
261. JOptionPane.showOptionDialog(
262. OptionDialogFrame.this,
263. getMessage(),
264. "Title",
265. getType(optionTypePanel),
266. getType(messageTypePanel),
267. null,
268. getOptions(),
269. getOptions()[0]);
270. }
271. }
272.
273. public static final int DEFAULT_WIDTH = 600;
274. public static final int DEFAULT_HEIGHT = 400;
275.
276. private ButtonPanel typePanel;
277. private ButtonPanel messagePanel;
278. private ButtonPanel messageTypePanel;
279. private ButtonPanel optionTypePanel;
280. private ButtonPanel optionsPanel;
281. private ButtonPanel inputPanel;
282.
283. private String messageString = "Message";
284. private Icon messageIcon = new ImageIcon("blue-ball-java-image.gif");
285. private Object messageObject = new Date();
286. private Component messageComponent = new SamplePanel();
287. }
288.
289. /**
290. A panel with a painted surface
291. */
292.
293. class SamplePanel extends JPanel
294. {
295. public void paintComponent(Graphics g)
296. {
297. super.paintComponent(g);
298. Graphics2D g2 = (Graphics2D)g;
299. Rectangle2D rect = new Rectangle2D.Double(0, 0,
300. getWidth() - 1, getHeight() - 1);
301. g2.setPaint(Color.YELLOW);
302. g2.fill(rect);
303. g2.setPaint(Color.BLUE);
304. g2.draw(rect);
305. }
306.
307. public Dimension getMinimumSize()
308. {
309. return new Dimension(10, 10);
310. }
311. }
}

The OptionDialogTest program

Java graphics 09fig47

javax.swing.JOptionPane 1.2

Java graphics api_icon
  • static void showMessageDialog(Component parent, Object message, String title, int messageType, Icon icon)
  • static void showMessageDialog(Component parent, Object message, String title, int messageType)
  • static void showMessageDialog(Component parent, Object message)
  • static void showInternalMessageDialog(Component parent, Object message, String title, int messageType, Icon icon)
  • static void showInternalMessageDialog(Component parent, Object message, String title, int messageType)
  • static void showInternalMessageDialog(Component parent, Object message)

    show a message dialog or an internal message dialog. (An internal dialog is rendered entirely within its owner frame.)static int showConfirmDialog(Component parent, Object message, String title, int optionType, int messageType, Icon icon)static int showConfirmDialog(Component parent, Object message, String title, int optionType, int messageType)static int showConfirmDialog(Component parent, Object message, String title, int optionType)static int showConfirmDialog(Component parent, Object message)static int showInternalConfirmDialog(Component parent, Object message, String title, int optionType, int messageType, Icon icon)static int showInternalConfirmDialog(Component parent, Object message, String title, int optionType, int messageType)static int showInternalConfirmDialog(Component parent, Object message, String title, int optionType)static int showInternalConfirmDialog(Component parent, Object message)

    show a confirmation dialog or an internal confirmation dialog. (An internal dialog is rendered entirely within its owner frame.) Returns the option selected by the user (one of OK_OPTION, CANCEL_OPTION, YES_OPTION, NO_OPTION), or CLOSED_OPTION if the user closed the dialog.static int showOptionDialog(Component parent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object default)static int showInternalOptionDialog(Component parent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object default)

    show an option dialog or an internal option dialog. (An internal dialog is rendered entirely within its owner frame.) Returns the index of the option selected by the user, or CLOSED_OPTION if the user canceled the dialog.static Object showInputDialog(Component parent, Object message, String title, int messageType, Icon icon, Object[] values, Object default)static String showInputDialog(Component parent, Object message, String title, int messageType)static String showInputDialog(Component parent, Object message)static String showInputDialog(Object message)static String showInputDialog(Component parent, Object message, Object default) [1.4]static String showInputDialog(Object message, Object default)1.4static Object showInternalInputDialog(Component parent, Object message, String title, int messageType, Icon icon, Object[] values, Object default)static String showInternalInputDialog(Component parent, Object message, String title, int messageType)static String showInternalInputDialog(Component parent, Object message)

    show an input dialog or an internal input dialog. (An internal dialog is rendered entirely within its owner frame.) Returns the input string typed by the user, or null if the user canceled the dialog.

    Creating Dialogs

    In the last section, you saw how to use the JOptionPane class to show a simple dialog. In this section, you will see how to create such a dialog by hand. shows a typical modal dialog box, a program information box that is displayed when the user clicks the About button.

    An About dialog box

    Java graphics 09fig48

    To implement a dialog box, you derive a class from JDialog. This is essentially the same process as deriving the main window for an app from JFrame. More precisely:

    1. In the constructor of your dialog box, call the constructor of the base class JDialog. You will need to tell it the owner frame (the frame window over which the dialog pops up), the title of the dialog frame, and a Boolean flag to indicate if the dialog box is modal or modeless. You should supply the owner frame so that the dialog can be displayed on top of its owner, but you can also supply a null pointer if you don't care where the dialog is displayed. Windowing systems typically require that every pop-up window is owned by another frame. Therefore, Swing constructs a shared hidden frame that becomes the owner of all dialogs with a null owner.
    2. Add the user interface components of the dialog box.
    3. Add the event handlers.
    4. Set the size for the dialog box.

    Here's an example dialog box:

    public AboutDialog extends JDialog
    {
     public AboutDialog(JFrame owner)
     {
     super(owner, "About DialogTest", true);
     Container contentPane = getContentPane();
     contentPane.add(new JLabel(
     "<HTML><H1><I>Core Java</I></H1><HR>"
     + "By Cay Horstmann and Gary Cornell</HTML>"),
     BorderLayout.CENTER);
     JPanel panel = new JPanel();
     JButton ok = new JButton("Ok");
     ok.addActionListener(new
     ActionListener()
     {
     public void actionPerformed(ActionEvent evt)
     {
     setVisible(false);
     }
     });
     panel.add(ok);
     contentPane.add(panel, BorderLayout.SOUTH);
     setSize(250, 150);
     }
    }
    

    As you can see, the constructor adds user interface elements: in this case, labels and a button. It adds a handler to the button and sets the size of the dialog. To display the dialog box, you create a new dialog object and invoke the show method.

    JDialog dialog = new AboutDialog(this);
    dialog.show();
    

    Actually, in the sample code below, we create the dialog box only once, and so we can reuse it whenever the user clicks the About button.

    if (dialog == null) // first time
     dialog = new AboutDialog(this);
    dialog.show();
    

    When the user clicks on the OK button, the dialog box should close. This is handled in the event handler of the OK button:

    ok.addActionListener(new
     ActionListener()
     {
     public void actionPerformed(ActionEvent evt)
     {
     setVisible(false);
     }
     });
    

    When the user closes the dialog by clicking on the Close box, then the dialog is also hidden. Just as with a JFrame, you can override this behavior with the setDefaultCloseOperation method. is the code for the About dialog box test program.

    Example DialogTest.java

     1. import java.awt.*;
     2. import java.awt.event.*;
     3. import javax.swing.*;
     4.
     5. public class DialogTest
     6. {
     7. public static void main(String[] args)
     8. {
     9. DialogFrame frame = new DialogFrame();
     10. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     11. frame.show();
     12. }
     13. }
     14.
     15. /**
     16. A frame with a menu whose File->About action shows a dialog.
     17. */
     18. class DialogFrame extends JFrame
     19. {
     20. public DialogFrame()
     21. {
     22. setTitle("DialogTest");
     23. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
     24.
     25. // construct a File menu
     26.
     27. JMenuBar menuBar = new JMenuBar();
     28. setJMenuBar(menuBar);
     29. JMenu fileMenu = new JMenu("File");
     30. menuBar.add(fileMenu);
     31.
     32. // add About and Exit menu items
     33.
     34. // The About item shows the About dialog
     35.
     36. JMenuItem aboutItem = new JMenuItem("About");
     37. aboutItem.addActionListener(new
     38. ActionListener()
     39. {
     40. public void actionPerformed(ActionEvent event)
     41. {
     42. if (dialog == null) // first time
     43. dialog = new AboutDialog(DialogFrame.this);
     44. dialog.show(); // pop up dialog
     45. }
     46. });
     47. fileMenu.add(aboutItem);
     48.
     49. // The Exit item exits the program
     50.
     51. JMenuItem exitItem = new JMenuItem("Exit");
     52. exitItem.addActionListener(new
     53. ActionListener()
     54. {
     55. public void actionPerformed(ActionEvent event)
     56. {
     57. System.exit(0);
     58. }
     59. });
     60. fileMenu.add(exitItem);
     61. }
     62.
     63. public static final int DEFAULT_WIDTH = 300;
     64. public static final int DEFAULT_HEIGHT = 200;
     65.
     66. private AboutDialog dialog;
     67. }
     68.
     69. /**
     70. A sample modal dialog that displays a message and
     71. waits for the user to click the Ok button.
     72. */
     73. class AboutDialog extends JDialog
     74. {
     75. public AboutDialog(JFrame owner)
     76. {
     77. super(owner, "About DialogTest", true);
     78. Container contentPane = getContentPane();
     79.
     80. // add HTML label to center
     81.
     82. contentPane.add(new JLabel(
     83. "<HTML><H1><I>Core Java</I></H1><HR>"
     84. + "By Cay Horstmann and Gary Cornell</HTML>"),
     85. BorderLayout.CENTER);
     86.
     87. // Ok button closes the dialog
     88.
     89. JButton ok = new JButton("Ok");
     90. ok.addActionListener(new
     91. ActionListener()
     92. {
     93. public void actionPerformed(ActionEvent evt)
     94. {
     95. setVisible(false);
     96. }
     97. });
     98.
     99. // add Ok button to southern border
    100.
    101. JPanel panel = new JPanel();
    102. panel.add(ok);
    103. contentPane.add(panel, BorderLayout.SOUTH);
    104.
    105. setSize(250, 150);
    106. }
    107. }
    

    javax.swing.JDialog 1.2

    Java graphics api_icon
    • public JDialog(JFrame parent, String title, boolean modal)

      constructs a dialog. The dialog is not visible until it is explicitly shown.

      Data Exchange

      The most common reason to put up a dialog box is to get information from the user. You have already seen how easy it is to make a dialog box object: give it initial data and then call show() to display the dialog box on the screen. Now let us see how to transfer data in and out of a dialog box. Consider the dialog box in that could be used to obtain a user name and a password to connect to some on-line service.

      Password dialog box

      Java graphics 09fig49

      Your dialog box should provide methods to set default data. For example, the PasswordChooser class of the example program has a method setUser to place default values into the next fields:

      public void setUser(User u)
      {
       username.setText(u.getName());
      }
      

      Once you set the defaults (if desired), you show the dialog by calling a method such as the following:

      boolean showDialog()
      {
       ok = false;
       show();
       return ok;
      }
      

      The user then fills in the information and clicks the OK or Cancel button. Only the event handler for the OK button sets the ok flag to true. The event handlers for both buttons call setVisible(false), which terminates the show method. Alternatively, the user may close the dialog. If you did not install a window listener for the dialog, then the default window closing operation applies: the dialog becomes invisible, which also terminates the show method. Note that the call to show() does not return until the dialog becomes invisible. This is a welcome change in how the AWT works. In the first version of the AWT, the call to show returned immediately, even for modal dialog boxes. That made it extremely challenging to get the data out of the dialog box. You should test the return value of the showDialog method. If it is true, then the user accepted the dialog. In that case, call the appropriate methods to retrieve the user input. Here is a sample method:

      public User getUser()
      {
       return new User(username.getText(), password.getPassword());
      }
      

      In this example, we use a single class for the data that the dialog box manipulates. Some programmers simply provide methods for each user interface component (getUsername, getPassword). However, as you edit more complex objects, you want to leave it up to the dialog to find appropriate ways for displaying and editing your objects.Java graphics notes_icon

      Transferring data out of a modeless dialog is not as simple. When displaying a modeless dialog, the call to show does not block and the program continues running while the dialog is displayed. If the user selects items on a modeless dialog and then clicks OK, the dialog needs to send an event to some listener in the program. That is, another class must implement an appropriate listener interface, and an object of that class should be registered as a listener. You can implement this by sending a custom event (see ) or by sending a property change event (see the chapter onJavaBeans in Volume 2).The example program contains another useful improvement. When you construct a JDialogobject, you need to specify the owner frame. However, quite often you want to show the same dialog with different owner frames. It is better if you can pick the owner frame when you are ready to show the dialog, not when you construct the PasswordChooserobject. The trick is to have the PasswordChooserextend JPanelinstead of JDialog. Build a JDialogobject on the fly in the showDialogmethod:

      public boolean showDialog(Frame owner, String title)
      {
       ok = false;
       if (dialog == null || dialog.getOwner() != owner)
       {
       dialog = new JDialog(owner, true);
       dialog.getContentPane().add(this);
       dialog.pack();
       }
       dialog.setTitle(title);
       dialog.show();
       return ok;
      }
      

      Note that it is safe to have owner equal to null. You can do even better. Sometimes, the owner frame isn't readily available. It is easy enough to compute it from any parent component, like this:

      Frame owner;
      if (parent instanceof Frame)
       owner = (Frame) parent;
      else
       owner = (Frame)SwingUtilities.getAncestorOfClass(
       Frame.class, parent);
      

      We use this enhancement in our sample program. The JOptionPane class also uses this mechanism. Many dialogs have a default button, which is automatically selected if the user hits a trigger key (ENTER in most "look and feel" implementations). The default button is specially marked, often with a thick outline. You set the default button in the root pane of the dialog:

      dialog.getRootPane().setDefaultButton(okButton);
      

      If you follow our suggestion of laying out the dialog in a panel, then you need to be careful to only set the default button after you wrapped the panel into a dialog. The panel itself has no root pane. is the complete code that illustrates the data flow into and out of a dialog box.

      Example DataExchangeTest.java

       1. import java.awt.*;
       2. import java.awt.event.*;
       3. import javax.swing.*;
       4.
       5. public class DataExchangeTest
       6. {
       7. public static void main(String[] args)
       8. {
       9. DataExchangeFrame frame = new DataExchangeFrame();
       10. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       11. frame.show();
       12. }
       13. }
       14.
       15. /**
       16. A frame with a menu whose File->Connect action shows a
       17. password dialog.
       18. */
       19. class DataExchangeFrame extends JFrame
       20. {
       21. public DataExchangeFrame()
       22. {
       23. setTitle("DataExchangeTest");
       24. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
       25.
       26. // construct a File menu
       27.
       28. JMenuBar mbar = new JMenuBar();
       29. setJMenuBar(mbar);
       30. JMenu fileMenu = new JMenu("File");
       31. mbar.add(fileMenu);
       32.
       33. // add Connect and Exit menu items
       34.
       35. JMenuItem connectItem = new JMenuItem("Connect");
       36. connectItem.addActionListener(new ConnectAction());
       37. fileMenu.add(connectItem);
       38.
       39. // The Exit item exits the program
       40.
       41. JMenuItem exitItem = new JMenuItem("Exit");
       42. exitItem.addActionListener(new
       43. ActionListener()
       44. {
       45. public void actionPerformed(ActionEvent event)
       46. {
       47. System.exit(0);
       48. }
       49. });
       50. fileMenu.add(exitItem);
       51.
       52. textArea = new JTextArea();
       53. getContentPane().add(new JScrollPane(textArea),
       54. BorderLayout.CENTER);
       55. }
       56.
       57. public static final int DEFAULT_WIDTH = 300;
       58. public static final int DEFAULT_HEIGHT = 200;
       59.
       60. private PasswordChooser dialog = null;
       61. private JTextArea textArea;
       62.
       63. /**
       64. The Connect action pops up the password dialog.
       65. */
       66.
       67. private class ConnectAction implements ActionListener
       68. {
       69. public void actionPerformed(ActionEvent event)
       70. {
       71. // if first time, construct dialog
       72.
       73. if (dialog == null)
       74. dialog = new PasswordChooser();
       75.
       76. // set default values
       77. dialog.setUser(new User("yourname", null));
       78.
       79. // pop up dialog
       80. if (dialog.showDialog(DataExchangeFrame.this,
       81. "Connect"))
       82. {
       83. // if accepted, retrieve user input
       84. User u = dialog.getUser();
       85. textArea.append(
       86. "user name = " + u.getName()
       87. + ", password = " + (new String(u.getPassword()))
       88. + "\n");
       89. }
       90. }
       91. }
       92. }
       93.
       94. /**
       95. A password chooser that is shown inside a dialog
       96. */
       97. class PasswordChooser extends JPanel
       98. {
       99. public PasswordChooser()
      100. {
      101. setLayout(new BorderLayout());
      102.
      103. // construct a panel with user name and password fields
      104.
      105. JPanel panel = new JPanel();
      106. panel.setLayout(new GridLayout(2, 2));
      107. panel.add(new JLabel("User name:"));
      108. panel.add(username = new JTextField(""));
      109. panel.add(new JLabel("Password:"));
      110. panel.add(password = new JPasswordField(""));
      111. add(panel, BorderLayout.CENTER);
      112.
      113. // create Ok and Cancel buttons that terminate the dialog
      114.
      115. okButton = new JButton("Ok");
      116. okButton.addActionListener(new
      117. ActionListener()
      118. {
      119. public void actionPerformed(ActionEvent event)
      120. {
      121. ok = true;
      122. dialog.setVisible(false);
      123. }
      124. });
      125.
      126. JButton cancelButton = new JButton("Cancel");
      127. cancelButton.addActionListener(new
      128. ActionListener()
      129. {
      130. public void actionPerformed(ActionEvent event)
      131. {
      132. dialog.setVisible(false);
      133. }
      134. });
      135.
      136. // add buttons to southern border
      137.
      138. JPanel buttonPanel = new JPanel();
      139. buttonPanel.add(okButton);
      140. buttonPanel.add(cancelButton);
      141. add(buttonPanel, BorderLayout.SOUTH);
      142. }
      143.
      144. /**
      145. Sets the dialog defaults.
      146. @param u the default user information
      147. */
      148. public void setUser(User u)
      149. {
      150. username.setText(u.getName());
      151. }
      152.
      153. /**
      154. Gets the dialog entries.
      155. @return a User object whose state represents
      156. the dialog entries
      157. */
      158. public User getUser()
      159. {
      160. return new User(username.getText(),
      161. password.getPassword());
      162. }
      163.
      164. /**
      165. Show the chooser panel in a dialog
      166. @param parent a component in the owner frame or null
      167. @param title the dialog window title
      168. */
      169. public boolean showDialog(Component parent, String title)
      170. {
      171. ok = false;
      172.
      173. // locate the owner frame
      174.
      175. Frame owner = null;
      176. if (parent instanceof Frame)
      177. owner = (Frame) parent;
      178. else
      179. owner = (Frame)SwingUtilities.getAncestorOfClass(
      180. Frame.class, parent);
      181.
      182. // if first time, or if owner has changed, make new dialog
      183.
      184. if (dialog == null || dialog.getOwner() != owner)
      185. {
      186. dialog = new JDialog(owner, true);
      187. dialog.getContentPane().add(this);
      188. dialog.getRootPane().setDefaultButton(okButton);
      189. dialog.pack();
      190. }
      191.
      192. // set title and show dialog
      193.
      194. dialog.setTitle(title);
      195. dialog.show();
      196. return ok;
      197. }
      198.
      199. private JTextField username;
      200. private JPasswordField password;
      201. private JButton okButton;
      202. private boolean ok;
      203. private JDialog dialog;
      204. }
      205.
      206. /**
      207. A user has a name and password. For security reasons, the
      208. password is stored as a char[], not a String.
      209. */
      210. class User
      211. {
      212. public User(String aName, char[] aPassword)
      213. {
      214. name = aName;
      215. password = aPassword;
      216. }
      217.
      218. public String getName() { return name; }
      219. public char[] getPassword() { return password; }
      220.
      221. public void setName(String aName) { name = aName; }
      222. public void setPassword(char[] aPassword)
      223. { password = aPassword; }
      224.
      225. private String name;
      226. private char[] password;
      227. }
      

      javax.swing.SwingUtilities 1.2

      Java graphics api_icon
      • Container getAncestorOfClass(Class c, Component comp)

        Returns the innermost parent container of the given component that belongs to the given class or one of its subclasses.

      javax.swing.JComponent 1.2

      Java graphics api_icon
      • JRootPane getRootPane()

        Gets the root pane enclosing this component, or null if this component does not have an ancestor with a root pane.

      javax.swing.JRootPane 1.2

      Java graphics api_icon
      • void setDefaultButton(JButton button)

        Sets the default button for this root pane. To deactivate the default button, this method with a null parameter.

      javax.swing.JButton 1.2

      Java graphics api_icon
      • boolean isDefaultButton()

        Returns true if this button is the default button of its root pane.

      File Dialogs

      When you write an app, you often want to be able to open and save files. A good file dialog box that shows files and directories and lets the user navigate the file system is hard to write, and you definitely don't want to reinvent that wheel. Fortunately, Swing provides a JFileChooser class that allows you to display a file dialog box similar to the one that most native apps use. JFileChooser dialogs are always modal. Note that the JFileChooser class is not a subclass of JDialog. Instead of calling show, you call showOpenDialog to display a dialog for opening a file or showSaveDialog to display a dialog for saving a file. The button for accepting a file is then automatically labeled Open or Save. You can also supply your own button label with the showDialog method. shows an example of the file chooser dialog box.

      File chooser dialog box

      Java graphics 09fig50

      Here are the steps needed to put up a file dialog box and recover what the user chooses from the box.

      1. Make a JFileChooser object. Unlike the constructor for the JDialog class, you do not supply the parent component. This allows you to reuse a file chooser dialog with multiple frames. For example:
        JFileChooser chooser = new JFileChooser();
        

        Java graphics exclamatory_icon

        Reusing a file chooser object is a good idea because the JFileChooser constructor can be quite slow, especially on Windows if the user has many mapped network drives.

      2. Set the directory by calling the setCurrentDirectory method. For example, use
        chooser.setCurrentDirectory(new File("."));
        

        to use the current working directory. You need to supply a File object. File objects are explained in detail in . All you need to know for now is that there is a constructor File(String filename) that turns a file or directory name into a File object.

      3. If you have a default file name that you expect the user to choose, supply it with the setSelectedFile method:
        chooser.setSelectedFile(new File(filename));
        
      4. To enable the user to select multiple files in the dialog, call the setMultiSelectionEnabled method. This is, of course, entirely optional and not all that common.
        chooser.setMultiSelectionEnabled(true);
        
      5. If you want to restrict the display of files in the dialog to those of a particular type (for example, all files with extension .gif), then you need to set a file filter. We discuss file filters later in this section.
      6. By default, a user can select only files with a file chooser. If you want the user to select directories, use the setFileSelectionMode method. Call it with JFileChooser. FILES_ONLY (the default), JFileChooser.DIRECTORIES_ONLY, or JFileChooser. FILES_AND_DIRECTORIES.
      7. Show the dialog box by calling the showOpenDialog or showSaveDialog method. You must supply the parent component in these calls:
        int result = chooser.showOpenDialog(parent);
        

        or

        int result = chooser.showSaveDialog(parent);
        

        The only difference between these calls is the label of the "approve button," the button that the user clicks to finish the file selection. You can also call the showDialog method and pass an explicit text for the approve button:

        int result = chooser.showDialog(parent, "Select");
        

        These calls return only when the user has approved or canceled the file dialog. The return value is JFileChooser.APPROVE_OPTION or JFile-Chooser.CANCEL_OPTION.

      8. You get the selected file or files with the getSelectedFile()or getSelectedFiles() method. These methods return either a single File object or an array of File objects. If you just need the name of the file object, call its getPath method. For example,
        String filename = chooser.getSelectedFile().getPath();
        

      For the most part, these steps are simple. The major difficulty with using a file dialog is to specify a subset of files from which the user should choose. For example, suppose the user should choose a GIF image file. Then, the file chooser should only display files with extension .gif. It should also give the user some kind of feedback that the displayed files are of a particular category, such as "GIF Images." But the situation can be more complex. If the user should choose a JPEG image file, then the extension can be either .jpg or .jpeg. Rather than coming up with a mechanism to codify these complexities, the designers of the file chooser supply a more elegant mechanism: to restrict the displayed files, you supply an object that implements the javax.swing.filechooser.FileFilter interface. The file chooser passes each file to the file filter and displays only the files that the file filter accepts. To restrict the files shown in a dialog, you need to create an object of a class that extends the FileFilter class. At the time of this writing, only one such subclass is supplied: the default filter that accepts all files. It is easy to write ad hoc file filters. You simply implement the two methods of the FileFilter interface:

      public boolean accept(File f);
      public String getDescription();
      

      Java graphics notes_icon

      There is an unrelated FileFilter interface in the java.io package that has a single method, boolean accept(File f). It is used in the listFiles method of the File class to list files in a directory. We do not know why the designers of Swing didn't extend this interface-perhaps the Java class library has now become so complex that even the programmers at Sun are no longer aware of all the standard classes and interfaces. You will need to resolve the name conflict between these two identically named types if you import both the java.io and the javax.swing.filechooser package. The simplest remedy is to import javax.swing.filechooser.FileFilter, not javax.swing.filechooser.*.The first method tests whether a file should be accepted. The second method returns a description of the file type that can be displayed in the file chooser dialog. For example, to filter for GIF files, you might use

      public class GifFilter extends FileFilter
      {
       public boolean accept(File f)
       {
       return f.getName().toLowerCase().endsWith("-java-image.gif")
       || f.isDirectory();
       }
       public String getDescription()
       {
       return "GIF Image";
       }
      }
      

      Once you have a file filter object, you use the setFileFilter method of the JFileChooser class to install it into the file chooser object:

      chooser.setFileFilter(new GifFilter());
      

      In our sample program, we supply a class ExtensionFileFilter, to be used as follows:

      ExtensionFileFilter filter = new ExtensionFileFilter();
      filter.addExtension("jpg");
      filter.addExtension("gif");
      filter.setDescription("Image files");
      

      The implementation of the ExtensionFileFilter is a straightforward generalization of the GifFilter class. You may want to use that class in your own programs.Java graphics notes_icon

      The Java SDK contains a similar class ExampleFileFilter in the demo/jfc/FileChooserDemo directory.You can install multiple filters to the file chooser by calling

      chooser.addChoosableFileFilter(new GifFilter());
      chooser.addChoosableFileFilter(new JpegFilter());
      . . .
      

      The user selects a filter from the combo box at the bottom of the file dialog. By default, the "All files" filter is always present in the combo box. This is a good idea, just in case a user of your program needs to select a file with a non-standard extension. However, if you want to suppress the "All files" filter, call

      chooser.setAcceptAllFileFilterUsed(false)
      

      Java graphics caution_icon

      If you reuse a single file chooser for loading and saving different file types, call

      chooser.resetChoosableFilters()
      

      to clear any old file filters before adding new ones.Finally, you can customize the file chooser by providing special icons and file descriptions for each file that the file chooser displays. You do this by supplying an object of a class extending the FileViewclass in the javax.swing.filechooserpackage. This is definitely an advanced technique. Normally, you don't need to supply a file view-the pluggable look and feel supplies one for you. But if you want to show different icons for special file types, you can install your own file view. You need to extend the FileViewclass and implement five methods:

      Icon getIcon(File f);
      String getName(File f);
      String getDescription(File f);
      String getTypeDescription(File f);
      Boolean isTraversable(File f);
      

      Then you use the setFileView method to install your file view into the file chooser. The file chooser calls your methods for each file or directory that it wants to display. If your method returns null for the icon, name, or description, the file chooser then consults the default file view of the look and feel. That is good, because it means you need to deal only with the file types for which you want to do something different. The file chooser calls the isTraversable method to decide whether to open a directory when a user clicks on it. Note that this method returns a Boolean object, not a boolean value! This seems weird, but it is actually convenient-if you aren't interested in deviating from the default file view, just return null. The file chooser will then consult the default file view. In other words, the method returns a Boolean to give you the choice between three options: true (Boolean.TRUE), false (Boolean.FALSE), and don't care (null). The example program contains a simple file view class. That class shows a particular icon whenever a file matches a file filter. We use it to display a palette icon for all image files.

      class FileIconView extends FileView
      {
       public FileIconView(FileFilter aFilter, Icon anIcon)
       {
       filter = aFilter;
       icon = anIcon;
       }
       public Icon getIcon(File f)
       {
       if (!f.isDirectory() && filter.accept(f))
       return icon;
       else return null;
       }
       private FileFilter filter;
       private Icon icon;
      }
      

      Java graphics caution_icon

      In SDK version 1.2, you must define all five methods of your FileView subclass. Simply return null in the methods that you don't need. In SDK version 1.3, the FileView methods are no longer abstract.You install this file view into your file chooser with the setFileViewmethod:

      chooser.setFileView(new FileIconView(filter,
       new ImageIcon("palette-java-image.gif")));
      

      The file chooser will then show the palette icon next to all files that pass the filter, and use the default file view to show all other files. Naturally, we use the same filter that we set in the file chooser.Java graphics exclamatory_icon

      You can find a more useful ExampleFileView class in the demo/jfc/FileChooserDemo directory of the SDK. That class lets you associate icons and descriptions with arbitrary extensions.Finally, you can customize a file dialog by adding an accessory component. For example, shows a preview accessory next to the file list. This accessory displays a thumbnail view of the currently selected file.

      A file dialog with a preview accessory

      Java graphics 09fig51

      An accessory can be any Swing component. In our case, we extend the JLabel class and set its icon to a scaled copy of the graphics image:

      class ImagePreviewer extends JLabel
      {
       public ImagePreviewer(JFileChooser chooser)
       {
       setPreferredSize(new Dimension(100, 100));
       setBorder(BorderFactory.createEtchedBorder());
       }
       public void loadImage(File f)
       {
       ImageIcon icon = new ImageIcon(f.getPath());
       if(icon.getIconWidth() > getWidth())
       icon = new ImageIcon(icon.getImage().getScaledInstance(
       getWidth(), -1, Image.SCALE_DEFAULT));
       setIcon(icon);
       repaint();
       }
      }
      

      There is just one challenge. We want to update the preview image whenever the user selects a different file. The file chooser uses the "Java Beans" mechanism of notifying interested listeners whenever one of its properties changes. The selected file is a property that you can monitor by installing a PropertyChangeListener. We will discuss this mechanism in greater detail in Volume 2. Here is the code that you need to trap the notifications:

      chooser.addPropertyChangeListener(new
       PropertyChangeListener()
       {
       public void propertyChange(PropertyChangeEvent event)
       {
       if (event.getPropertyName() ==
       JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)
       {
       File newFile = (File)event.getNewValue()
       // update the accessory
       }
       }
      });
      

      In our example program, we add this code to the ImagePreviewer constructor. contains a modification of the ImageViewer program from , in which the file chooser has been enhanced by a custom file view and a preview accessory.

      Example FileChooserTest.java

       1. import java.awt.*;
       2. import java.awt.event.*;
       3. import java.awt.image.*;
       4. import java.beans.*;
       5. import java.util.*;
       6. import java.io.*;
       7. import javax.swing.*;
       8. import javax.swing.filechooser.FileFilter;
       9. import javax.swing.filechooser.FileView;
       10.
       11. public class FileChooserTest
       12. {
       13. public static void main(String[] args)
       14. {
       15. ImageViewerFrame frame = new ImageViewerFrame();
       16. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       17. frame.show();
       18. }
       19. }
       20.
       21. /**
       22. A frame that has a menu for loading an image and a display
       23. area for the loaded image.
       24. */
       25. class ImageViewerFrame extends JFrame
       26. {
       27. public ImageViewerFrame()
       28. {
       29. setTitle("FileChooserTest");
       30. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
       31.
       32. // set up menu bar
       33. JMenuBar menuBar = new JMenuBar();
       34. setJMenuBar(menuBar);
       35.
       36. JMenu menu = new JMenu("File");
       37. menuBar.add(menu);
       38.
       39. JMenuItem openItem = new JMenuItem("Open");
       40. menu.add(openItem);
       41. openItem.addActionListener(new FileOpenListener());
       42.
       43. JMenuItem exitItem = new JMenuItem("Exit");
       44. menu.add(exitItem);
       45. exitItem.addActionListener(new
       46. ActionListener()
       47. {
       48. public void actionPerformed(ActionEvent event)
       49. {
       50. System.exit(0);
       51. }
       52. });
       53.
       54. // use a label to display the images
       55. label = new JLabel();
       56. Container contentPane = getContentPane();
       57. contentPane.add(label);
       58.
       59. // set up file chooser
       60. chooser = new JFileChooser();
       61.
       62. // accept all image files ending with .jpg, .jpeg, .gif
       63. final ExtensionFileFilter filter
       64. = new ExtensionFileFilter();
       65. filter.addExtension("jpg");
       66. filter.addExtension("jpeg");
       67. filter.addExtension("gif");
       68. filter.setDescription("Image files");
       69. chooser.setFileFilter(filter);
       70.
       71. chooser.setAccessory(new ImagePreviewer(chooser));
       72.
       73. chooser.setFileView(new FileIconView(filter,
       74. new ImageIcon("palette-java-image.gif")));
       75. }
       76.
       77. /**
       78. This is the listener for the File->Open menu item.
       79. */
       80. private class FileOpenListener implements ActionListener
       81. {
       82. public void actionPerformed(ActionEvent evt)
       83. {
       84. chooser.setCurrentDirectory(new File("."));
       85. // accept all image files ending with .jpg, .jpeg, .gif
       86. final ExtensionFileFilter filter
       87. = new ExtensionFileFilter();
       88. filter.addExtension("jpg");
       89. filter.addExtension("jpeg");
       90. filter.addExtension("gif");
       91. filter.setDescription("Image files");
       92. chooser.setFileFilter(filter);
       93.
       94. // show file chooser dialog
       95. int result
       96. = chooser.showOpenDialog(ImageViewerFrame.this);
       97.
       98. // if image file accepted, set it as icon of the label
       99. if(result == JFileChooser.APPROVE_OPTION)
      100. {
      101. String name
      102. = chooser.getSelectedFile().getPath();
      103. label.setIcon(new ImageIcon(name));
      104. }
      105. }
      106. }
      107.
      108. public static final int DEFAULT_WIDTH = 300;
      109. public static final int DEFAULT_HEIGHT = 400;
      110.
      111. private JLabel label;
      112. private JFileChooser chooser;
      113. }
      114.
      115. /**
      116. This file filter matches all files with a given set of
      117. extensions.
      118. */
      119. class ExtensionFileFilter extends FileFilter
      120. {
      121. /**
      122. Adds an extension that this file filter recognizes.
      123. @param extension a file extension (such as ".txt" or "txt")
      124. */
      125. public void addExtension(String extension)
      126. {
      127. if (!extension.startsWith("."))
      128. extension = "." + extension;
      129. extensions.add(extension.toLowerCase());
      130. }
      131.
      132. /**
      133. Sets a description for the file set that this file filter
      134. recognizes.
      135. @param aDescription a description for the file set
      136. */
      137. public void setDescription(String aDescription)
      138. {
      139. description = aDescription;
      140. }
      141.
      142. /**
      143. Returns a description for the file set that this file
      144. filter recognizes.
      145. @return a description for the file set
      146. */
      147. public String getDescription()
      148. {
      149. return description;
      150. }
      151.
      152. public boolean accept(File f)
      153. {
      154. if (f.isDirectory()) return true;
      155. String name = f.getName().toLowerCase();
      156.
      157. // check if the file name ends with any of the extensions
      158. for (int i = 0; i < extensions.size(); i++)
      159. if (name.endsWith((String)extensions.get(i)))
      160. return true;
      161. return false;
      162. }
      163.
      164. private String description = "";
      165. private ArrayList extensions = new ArrayList();
      166. }
      167.
      168. /**
      169. A file view that displays an icon for all files that match
      170. a file filter.
      171. */
      172. class FileIconView extends FileView
      173. {
      174. /**
      175. Constructs a FileIconView.
      176. @param aFilter a file filter--all files that this filter
      177. accepts will be shown with the icon.
      178. @param anIcon--the icon shown with all accepted files.
      179. */
      180. public FileIconView(FileFilter aFilter, Icon anIcon)
      181. {
      182. filter = aFilter;
      183. icon = anIcon;
      184. }
      185.
      186. public Icon getIcon(File f)
      187. {
      188. if (!f.isDirectory() && filter.accept(f))
      189. return icon;
      190. else return null;
      191. }
      192.
      193. private FileFilter filter;
      194. private Icon icon;
      195. }
      196.
      197. /**
      198. A file chooser accessory that previews images.
      199. */
      200. class ImagePreviewer extends JLabel
      201. {
      202. /**
      203. Constructs an ImagePreviewer.
      204. @param chooser the file chooser whose property changes
      205. trigger an image change in this previewer
      206. */
      207. public ImagePreviewer(JFileChooser chooser)
      208. {
      209. setPreferredSize(new Dimension(100, 100));
      210. setBorder(BorderFactory.createEtchedBorder());
      211.
      212. chooser.addPropertyChangeListener(new
      213. PropertyChangeListener()
      214. {
      215. public void propertyChange(PropertyChangeEvent
      216. event)
      217. {
      218. if (event.getPropertyName() ==
      219. JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)
      220. {
      221. // the user has selected a new file
      222. File f = (File)event.getNewValue();
      223.
      224. // read the image into an icon
      225. ImageIcon icon = new ImageIcon(f.getPath());
      226.
      227. // if the icon is too large to fit, scale it
      228. if(icon.getIconWidth() > getWidth())
      229. icon = new ImageIcon(
      230. icon.getImage().getScaledInstance(
      231. getWidth(), -1, Image.SCALE_DEFAULT));
      232.
      233. setIcon(icon);
      234. }
      235. }
      236. });
      237. }
      238. }
      

      javax.swing.JFileChooser 1.2

      Java graphics api_icon
      • JFileChooser()

        creates a file chooser dialog box that can be used for multiple frames.

      • void setCurrentDirectory(File dir)

        sets the initial directory for the file dialog box.

      • void setSelectedFile(File file)
      • void setSelectedFiles(File[] file)

        set the default file choice for the file dialog box.

      • void setMultiSelectionEnabled(boolean b)

        sets or clears multiple selection mode.

      • void setFileSelectionMode(int mode)

        lets the user select files only (the default), directories only, or both files and directories. The mode parameter is one of JFileChooser.FILES_ONLY, JFileChooser.DIRECTORIES_ONLY, and JFileChooser.FILES_AND_DIRECTORIES

      • int showOpenDialog(Component parent)
      • int showSaveDialog(Component parent)
      • int showDialog(Component parent, String approveButtonText)

        show a dialog in which the approve button is labeled "Open," "Save," or with the approveButtonText string. Returns APPROVE_OPTION or CANCEL_OPTION.

      • File getSelectedFile()
      • File[] getSelectedFiles()

        get the file or files that the user selected (or returns null if the user didn't select any file).

      • void setFileFilter(FileFilter filter)

        sets the file mask for the file dialog box. All files for which filter.accept returns true will be displayed. Also adds the filter to the list of choosable filters.

      • void addChoosableFileFilter(FileFilter filter)

        adds a file filter to the list of choosable filters.

      • void setAcceptAllFileFilterUsed(boolean b)

        includes or suppresses an "All files" filter in the filter combo box.

      • void resetChoosableFileFilters()

        clears the list of choosable filters. Only the "All files" filter remains unless it is explicitly suppressed.

      • void setFileView(FileView view)

        sets a file view to provide information about the files that the file chooser displays.

      • void setAccessory(JComponent component)

        sets an accessory component.

      javax.swing.filechooser.FileFilter 1.2

      Java graphics api_icon
      • boolean accept(File f)

        returns true if the file chooser should display this file.

      • String getDescription()

        returns a description of this file filter, for example "Image files (*.gif,*.jpeg)".

      javax.swing.filechooser.FileView 1.2

      Java graphics api_icon
      • String getName(File f)

        returns the name of the file f, or null. Normally, this method simply returns f.getName().

      • String getDescription(File f)

        returns a humanly readable description of the file f, or null. For example, if f is an HTML document, this method might return its title.

      • String getTypeDescription(File f)

        returns a humanly readable description of the type of the file f, or null. For example, if f is an HTML document, this method might return a string "Hypertext document".

      • Icon getIcon(File f)

        returns an icon for the file f, or null. For example, if f is a JPEG file, this method might return a thumbnail icon.

      • Boolean isTraversable(File f)

        returns Boolean.TRUE if f is a directory that the user can open. This method might return false if a directory is conceptually a compound document. Like all FileView methods, this method can return null to indicate that the file chooser should consult the default view instead.

      Color Choosers

      As you saw in the preceding section, a high quality file chooser is an intricate user interface component that you definitely do not want to implement yourself. There are other common dialogs to choose a date/time, currency value, font, color, and so on that many user interface toolkits provide. The benefit is twofold. Programmers can simply use a high-quality implementation rather than rolling their own. And users have a common experience for these selections. At this point, Swing only provides one additional chooser, the JColorChooser (see through ). You use it to let users pick a color value. Like the JFileChooser class, the color chooser is a component, not a dialog, but it contains convenience methods to create dialogs that contain a color chooser component.

      The "swatches" pane of a color chooser

      Java graphics 09fig52

      The RGB pane of a color chooser

      Java graphics 09fig54

      The HSB pane of a color chooser

      Java graphics 09fig53

      Here is how you show a modal dialog with a color chooser

      Color selectedColor = JColorChooser.showDialog(parent,
       title, initialColor);
      

      Alternatively, you can display a modeless color chooser dialog. You supply:

      • A parent component;
      • The title of the dialog;
      • A flag to select either a modal or a modeless dialog;
      • A color chooser;
      • Listeners for the OK and Cancel buttons (or null if you don't want a listener).

      Here is how you make a modeless dialog that sets the background color when the user presses the OK button:

      chooser = new JColorChooser();
      dialog = JColorChooser.createDialog(
       parent,
       "Background Color",
       false /* not modal */,
       chooser,
       new ActionListener() // OK button listener
       {
       public void actionPerformed(ActionEvent event)
       {
       setBackground(chooser.getColor());
       }
       },
       null /* no Cancel button listener */);
      

      You can do even better than that, and give the user immediate feedback of the color selection. To monitor the color selections, you need to obtain the selection model of the chooser and add a change listener:

      chooser.getSelectionModel().addChangeListener(new
       ChangeListener()
       {
       public void stateChanged(ChangeEvent event)
       {
       do something with chooser.getColor();
       }
       });
      

      In this case, there is no benefit to the OK and Cancel buttons that the color chooser dialog provides. You can just add the color chooser component directly into a modeless dialog:

      dialog = new JDialog(parent, false /* not modal */);
      dialog.getContentPane().add(chooser);
      dialog.pack();
      

      The program in shows the three types of dialog. If you click on the Modal button, you must select a color before you can do anything else. If you click on the Modeless button, you get a modeless dialog, but the color change only happens when you click the OK button on the dialog. If you click the Immediate button, you get a modeless dialog without buttons. As soon as you pick a different color in the dialog, the background color of the panel is updated. This ends our discussion of user interface components. The material in through showed you how to implement simple graphical user interfaces in Swing. Please turn to Volume 2 for more advanced Swing components and sophisticated graphics techniques.

      Example ColorChooserTest.java

       1. import java.awt.*;
       2. import java.awt.event.*;
       3. import javax.swing.*;
       4. import javax.swing.event.*;
       5.
       6. public class ColorChooserTest
       7. {
       8. public static void main(String[] args)
       9. {
       10. ColorChooserFrame frame = new ColorChooserFrame();
       11. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       12. frame.show();
       13. }
       14. }
       15.
       16. /**
       17. A frame with a color chooser panel
       18. */
       19. class ColorChooserFrame extends JFrame
       20. {
       21. public ColorChooserFrame()
       22. {
       23. setTitle("ColorChooserTest");
       24. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
       25.
       26. // add color chooser panel to frame
       27.
       28. ColorChooserPanel panel = new ColorChooserPanel();
       29. Container contentPane = getContentPane();
       30. contentPane.add(panel);
       31. }
       32.
       33. public static final int DEFAULT_WIDTH = 300;
       34. public static final int DEFAULT_HEIGHT = 200;
       35. }
       36.
       37. /**
       38. A panel with buttons to pop up three types of color choosers
       39. */
       40. class ColorChooserPanel extends JPanel
       41. {
       42. public ColorChooserPanel()
       43. {
       44. JButton modalButton = new JButton("Modal");
       45. modalButton.addActionListener(new ModalListener());
       46. add(modalButton);
       47.
       48. JButton modelessButton = new JButton("Modeless");
       49. modelessButton.addActionListener(new ModelessListener());
       50. add(modelessButton);
       51.
       52. JButton immediateButton = new JButton("Immediate");
       53. immediateButton.addActionListener(new ImmediateListener());
       54. add(immediateButton);
       55. }
       56.
       57. /**
       58. This listener pops up a modal color chooser
       59. */
       60. private class ModalListener implements ActionListener
       61. {
       62. public void actionPerformed(ActionEvent event)
       63. {
       64. Color defaultColor = getBackground();
       65. Color selected = JColorChooser.showDialog(
       66. ColorChooserPanel.this,
       67. "Set background",
       68. defaultColor);
       69. setBackground(selected);
       70. }
       71. }
       72.
       73. /**
       74. This listener pops up a modeless color chooser.
       75. The panel color is changed when the user clicks the Ok
       76. button.
       77. */
       78. private class ModelessListener implements ActionListener
       79. {
       80. public ModelessListener()
       81. {
       82. chooser = new JColorChooser();
       83. dialog = JColorChooser.createDialog(
       84. ColorChooserPanel.this,
       85. "Background Color",
       86. false /* not modal */,
       87. chooser,
       88. new ActionListener() // OK button listener
       89. {
       90. public void actionPerformed(ActionEvent event)
       91. {
       92. setBackground(chooser.getColor());
       93. }
       94. },
       95. null /* no Cancel button listener */);
       96. }
       97.
       98. public void actionPerformed(ActionEvent event)
       99. {
      100. chooser.setColor(getBackground());
      101. dialog.show();
      102. }
      103.
      104. private JDialog dialog;
      105. private JColorChooser chooser;
      106. }
      107.
      108. /**
      109. This listener pops up a modeless color chooser.
      110. The panel color is changed immediately when the
      111. user picks a new color.
      112. */
      113. private class ImmediateListener implements ActionListener
      114. {
      115. public ImmediateListener()
      116. {
      117. chooser = new JColorChooser();
      118. chooser.getSelectionModel().addChangeListener(new
      119. ChangeListener()
      120. {
      121. public void stateChanged(ChangeEvent event)
      122. {
      123. setBackground(chooser.getColor());
      124. }
      125. });
      126.
      127. dialog = new JDialog(
      128. (Frame)null,
      129. false /* not modal */);
      130. dialog.getContentPane().add(chooser);
      131. dialog.pack();
      132. }
      133.
      134. public void actionPerformed(ActionEvent event)
      135. {
      136. chooser.setColor(getBackground());
      137. dialog.show();
      138. }
      139.
      140. private JDialog dialog;
      141. private JColorChooser chooser;
      142. }
      143. }
      

      javax.swing.JColorChooser 1.2

      Java graphics api_icon
      • JColorChooser()

        constructs a color chooser with an initial color of white.

      • Color getColor()
      • void setColor(Color c)

        get and set the current color of this color chooser.

      • static Color showDialog(Component parent, String title, Color initialColor)

        shows a modal dialog that contains a color chooser.static JDialog createDialog(Component parent, String title, boolean modal, JColorChooser chooser, ActionListener okListener, ActionListener cancelListener)

        creates a dialog box that contains a color chooser.


        Parameters: parent The component over which to pop up the dialog
        title The title for the dialog box frame
        initialColor The initial color to show in the color chooser
        Parameters: parent The component over which to pop up the dialog
        title The title for the dialog box frame
        modal true if this call should block until the dialog is closed
        chooser The color chooser to add to the dialog
        okListener, cancelListener The listeners of the OK and Cancel buttons
      Parameters: parent The frame that is the owner of the dialog
      title The title of the dialog
      modal True for modal dialogs (a modal dialog blocks input to other windows)
    Parameters: parent The parent component (can be null)
    message The message to show on the dialog (can be a string, icon, component, or an array of them)
    title The string in the title bar of the dialog
    messageType One of ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE
    icon An icon to show instead of one of the standard icons
    Parameters: parent The parent component (can be null)
    message The message to show on the dialog (can be a string, icon, component, or an array of them)
    title The string in the title bar of the dialog
    messageType One of ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE
    optionType One of DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION
    icon An icon to show instead of one of the standard icons
    Parameters: parent The parent component (can be null)
    message The message to show on the dialog (can be a string, icon, component, or an array of them)
    title The string in the title bar of the dialog
    messageType One of ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE
    optionType One of DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION
    icon An icon to show instead of one of the standard icons
    options An array of options (can be strings, icons, or components)
    default The default option to present to the user
    Parameters: parent The parent component (can be null)
    message The message to show on the dialog (can be a string, icon, component, or an array of them)
    title The string in the title bar of the dialog
    messageType One of ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE
    icon An icon to show instead of one of the standard icons
    values An array of values to show in a combo box
    default The default value to present to the user