Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Façade clears complexity

Develop dialog boxes and Swing apps faster

  • Print
  • Feedback

Page 3 of 5

Use JOptionPane

Swing's JOptionPane, depicted in Figure 4, is a façade that creates different types of dialogs and displays them.

Figure 4. JOptionPane is a façade that creates dialog boxes

Example 2 shows a rewritten action listener from Example 1 that uses JOptionPane to create a message dialog instead of creating it from scratch.

Example 2. JOptionPane creates a simple message dialog

      ...
      openButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(TLDViewer.this, "You must follow directions!",
               "Error!", JOptionPane.ERROR_MESSAGE);
         }
      });
   ...


Could any infomercial rival the amazing results you get from using JOptionPane? Compare Example 1 to Example 2 and decide which block of code you'd rather write the next time you need a message dialog. Thankfully, we have the Façade pattern.

A Swing application façade

Swing is one of my all-time favorite GUI frameworks, but even after writing a 1,600-page book on the subject, I have to refer to the book and Javadocs almost every time I write a Swing application. Just getting a Swing application off the ground can require heavy lifting, especially if you follow best practices by internationalizing your application. This section shows you how to implement a façade that encapsulates much of the grunt work involved in setting up a Swing application.

Figure 5's application is a library for cataloging books, DVDs, and VHS tapes.

Figure 5. The library in English. Click on thumbnail to view full-size image.

The application's features are unimportant to us, except for the fact that the application is internationalized and localized in English and French; Figure 6 shows the application localized for French.

Figure 6. The library in French. Click on thumbnail to view full-size image.

The library uses a façade—ApplicationSupport—I wrote so I could create Swing applications in a hurry. That façade provides the following methods:

  • Launch application:
    • public static void launch(final JFrame f, String title, final int x, final int y, final int w, int h)
  • Menus and locale:
    • public static JMenu addMenu(final JFrame f, String titleKey, String[] itstrong)
    • public static Locale getLocale()
  • Status area:
    • public static JPanel getStatusArea()
    • public static void showStatus(String s)
  • Internationlization:
    • public static String getResource(String key)
    • public static String formatMessage(String patternKey, String[] params)


Rather than show you the tedium involved in getting an application like the one in Figure 6 off the ground and then contrast it with the use of a façade, let's save some time and proceed directly to the latter. Example 3 illustrates how Figure 5's application uses the ApplicationSupport class.

Example 3. Use a Swing application façade

public class LibraryViewer extends JFrame {
   ...
   private static final String
      FILEMENU_TITLE = "app.frame.menus.file.title",
      FILEMENU_NEW   = "app.frame.menus.file.new",
      FILEMENU_EXIT  = "app.frame.menus.file.exit",
      EDITMENU_TITLE = "app.frame.menus.edit.title",
      EDITMENU_CUT   = "app.frame.menus.edit.cut",
      EDITMENU_COPY  = "app.frame.menus.edit.copy";
   ...
   public static void main(String args[]) {
      ApplicationSupport.launch(new LibraryViewer(), 
                   ApplicationSupport.getResource("app.frame.title"),
                   windowX, windowY, windowW, windowH);
   }
   public void clearStatusArea() {
      ApplicationSupport.showStatus("");
   }
   public void selectDVD(boolean valueIsAdjusting) {
      ...
      ApplicationSupport.showStatus((String)table.getValueAt(table.getSelectedRow(), 0));
   }
   private JMenu makeEditMenu() {
      return ApplicationSupport.addMenu(this, EDITMENU_TITLE,
               new String[] { EDITMENU_CUT, EDITMENU_COPY });
   }
   private JMenu makeFileMenu() {
      JMenu fileMenu = ApplicationSupport.addMenu(this, FILEMENU_TITLE, 
                              new String[] {FILEMENU_NEW, FILEMENU_EXIT});
      fileMenu.getItem(1).addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            System.exit(1);
         }
      });
   }
   public void categoryChanged(JTabbedPane pane) {
      int selectedIndex = pane.getSelectedIndex();
      if(selectedIndex >= 0)
         ApplicationSupport.showStatus(pane.getTitleAt(selectedIndex));
   }
   private void makeCategoryTabs() {
      categoryPane.addTab(ApplicationSupport.getResource("app.books.tab"), booksPanel);
      categoryPane.addTab(ApplicationSupport.getResource("app.dvds.tab"),  dvdPanel);
      categoryPane.addTab(ApplicationSupport.getResource("app.vhs.tab"),   vhsPanel);
   }
   private void initializeTable() {
      String[] columnNames = new String[] {
         ApplicationSupport.getResource("dvd.title.column.heading"),
         ApplicationSupport.getResource("dvd.rating.column.heading"),
         ApplicationSupport.getResource("dvd.languages.column.heading"),
         ApplicationSupport.getResource("dvd.length.column.heading"),
      };
      DefaultTableModel model = new LibraryTableModel();
      for(int i=0; i < columnNames.length; ++i)
         model.addColumn(columnNames[i]);
      table.setModel(model);
   }
   private JComponent makeToolbar() {
      JToolBar toolbar = new JToolBar(); 
      JButton newButton = new JButton(new ImageIcon(ApplicationSupport.getResource(
                                                     TOOLBAR_NEW_ICON)));
      JButton openButton = new JButton(new ImageIcon(ApplicationSupport.getResource(
                                                   TOOLBAR_OPEN_ICON)));
      JButton saveButton = new JButton(new ImageIcon(ApplicationSupport.getResource(
                                                   TOOLBAR_SAVE_ICON)));
      JButton cutButton = new JButton(new ImageIcon(ApplicationSupport.getResource(
                                                   TOOLBAR_CUT_ICON)));
      JButton copyButton = new JButton(new ImageIcon(ApplicationSupport.getResource(
                                                   TOOLBAR_COPY_ICON)));
      JButton pasteButton = new JButton(new ImageIcon(ApplicationSupport.getResource(
                                                   TOOLBAR_PASTE_ICON)));
      JButton redoButton = new JButton(new ImageIcon(ApplicationSupport.getResource(
                                                   TOOLBAR_REDO_ICON)));
      ...
      return toolbar;
   }


The preceding code uses ApplicationSupport.launch() to position and size the application's window, set the window's title, and set up a window listener that closes the application when the close box in the window is activated. The application uses the façade's getResource() method to internationalize text displayed to the user based on key/value entries in a resource file. The application also uses the façade to display information in a status panel (created by the façade) and the façade's addMenu() method to easily create a menu.

  • Print
  • Feedback

Resources