A popup dialog with a message and a scrollable list of items : Dialog « Swing Components « Java






A popup dialog with a message and a scrollable list of items

     

/*BEGIN_COPYRIGHT_BLOCK
 *
 * Copyright (c) 2001-2008, JavaPLT group at Rice University (drjava@rice.edu)
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software is Open Source Initiative approved Open Source Software.
 * Open Source Initative Approved is a trademark of the Open Source Initiative.
 * 
 * This file is part of DrJava.  Download the current version of this project
 * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 * 
 * END_COPYRIGHT_BLOCK*/


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.table.AbstractTableModel;

/**
 * <p>The ScrollableListSelectionDialog is a popup dialog with a message
 * and a scrollable list of items. Each item may be either selected or
 * unselected. A ScrollableListSelectionDialog should be used when
 * an operation needs to act on a variable number of items, for
 * example, when saving modified files.</p>
 * 
 * <p>The message (also know as the leader text) is displayed above the
 * items with an optional icon. The items are displayed in a scrollable
 * table. A column of checkboxes allows selection of the items. Buttons
 * are added below the list of items.</p>
 * 
 * <p>This dialog is somewhat styled after
 * {@link javax.swing.JOptionPane} and uses the message-type constants
 * from JOptionPane.</p>
 * 
 * @author Chris Warrington
 * @version $Id$
 * @since 2007-04-08
 */
public class ScrollableListSelectionDialog extends JDialog {
  /** A enumeration of the various selection states.
   */
  public enum SelectionState {
    /** Indicates that an item is selected. */
    SELECTED,
      /** Indicates that an item is not selected. */
      UNSELECTED
  };
  
  /** The default width for this dialog. */
  private static final int DEFAULT_WIDTH = 400;
  /** The default height for this dialog. */
  private static final int DEFAULT_HEIGHT = 450;
  
  /** The ratio of the screen width to use by default. */
  private static final double WIDTH_RATIO = .75;
  /** The ratio of the screen height to use by default. */
  private static final double HEIGHT_RATIO = .50;
  
  /** The table displaying the items. */
  protected final JTable table;
  /** The AbstractTableModel backing the table. */
  protected final AbstractTableModel tableModel;
  
  /** The number of columns in the table. */
  private static final int NUM_COLUMNS = 2;
  /** The column index of the checkboxes column. */
  private static final int CHECKBOXES_COLUMN_INDEX = 0;
  /** The column index of the strings column. */
  private static final int STRINGS_COLUMN_INDEX = 1;
  
  /** The items in the table. */
  protected final Vector<String> dataAsStrings;
  /** The selected items in the table. This Vector maps to
    * _dataAsStrings by index. This value may be accessed by multiple
    * threads. Threads wishing to access it should acquire its
    * intrinsic lock. */
  protected final Vector<Boolean> selectedItems;
  
  /** <p>Creates a new ScrollableListSelectionDialog with the given
   * title, leader text, and items. The list of items is used to
   * construct an internal string list that is not backed by the original
   * list. Changes made to the list or items after dialog construction
   * will not be reflected in the dialog.</p>
   * 
   * <p>The default sizing, message type, and icon are used. All the
   * items are selected by default.</p>
   * 
   * @param owner The frame that owns this dialog. May be {@code null}.
   * @param dialogTitle The text to use as the dialog title.
   * @param leaderText Text to display before the list of items.
   * @param listItems The items to display in the list.
   * @param itemDescription A textual description of the items. This is used as the column heading for the items.
   * 
   * @throws IllegalArgumentException if {@code listItems} is {@code null.}
   */
  public ScrollableListSelectionDialog(final Frame owner,
                                       final String dialogTitle,
                                       final String leaderText,
                                       final Collection<?> listItems,
                                       final String itemDescription) {
    this(owner, dialogTitle, leaderText, listItems, itemDescription, SelectionState.SELECTED, JOptionPane.PLAIN_MESSAGE);
  }
  
  /** <p>Creates a new ScrollableListSelectionDialog with the given
   * title, leader text, items, and message type. The list of items is
   * used to construct an internal string list that is not backed by the
   * original list. Changes made to the list or items after dialog
   * construction will not be reflected in the dialog.</p>
   * 
   * <p>The message type must be one of the message types from
   * {@link javax.swing.JOptionPane}. The message type controlls which
   * default icon is used.</p>
   * 
   * <p>The default sizing and icon are used.</p>
   * 
   * @param owner The frame that owns this dialog. May be {@code null}.
   * @param dialogTitle The text to use as the dialog title.
   * @param leaderText Text to display before the list of items.
   * @param listItems The items to display in the list.
   * @param itemDescription A textual description of the items. This is used as the column heading for the items.
   * @param defaultSelection The default selection state (selected or unselected) for the items.
   * @param messageType The type of dialog message.
   * 
   * @throws IllegalArgumentException if {@code listItems} is {@code null.}
   * @throws IllegalArgumentException if the message type is unknown or {@code listItems} is {@code null.}
   */
  public ScrollableListSelectionDialog(final Frame owner,
                                       final String dialogTitle,
                                       final String leaderText,
                                       final Collection<?> listItems,
                                       final String itemDescription,
                                       final SelectionState defaultSelection,
                                       final int messageType) {
    this(owner,
         dialogTitle,
         leaderText,
         listItems,
         itemDescription,
         defaultSelection,
         messageType,
         DEFAULT_WIDTH,
         DEFAULT_HEIGHT,
         null,
         true);
  }
  
  /** <p>Creates a new ScrollableListSelectionDialog with the given
   * title, leader text, items, message type, width, height, and icon.
   * The list of items is used to construct an internal string list that
   * is not backed by the original list. Changes made to the list or
   * items after dialog construction will not be reflected in the
   * dialog.</p>
   * 
   * <p>The message type must be one of the message types from
   * {@link javax.swing.JOptionPane}. The message type controlls which
   * default icon is used. If {@code icon} is non-null, it is used
   * instead of the default icon.</p>
   * 
   * @param owner The frame that owns this dialog. May be {@code null}.
   * @param dialogTitle The text to use as the dialog title.
   * @param leaderText Text to display before the list of items.
   * @param listItems The items to display in the list.
   * @param itemDescription A textual description of the items. This is used as the column heading for the items.
   * @param defaultSelection The default selection state (selected or unselected) for the items.
   * @param messageType The type of dialog message.
   * @param width The width of the dialog box.
   * @param height The height of the dialog box.
   * @param icon The icon to display. May be {@code null}.
   * 
   * @throws IllegalArgumentException if {@code listItems} is {@code null.}
   * @throws IllegalArgumentException if the message type is unknown or {@code listItems} is {@code null.}
   */
  public ScrollableListSelectionDialog(final Frame owner,
                                       final String dialogTitle,
                                       final String leaderText,
                                       final Collection<?> listItems,
                                       final String itemDescription,
                                       final SelectionState defaultSelection,
                                       final int messageType,
                                       final int width,
                                       final int height,
                                       final Icon icon) {
    this(owner,
         dialogTitle,
         leaderText,
         listItems,
         itemDescription,
         defaultSelection,
         messageType,
         width,
         height,
         icon,
         false);
  }
  
  /** <p>Creates a new ScrollableListSelectionDialog with the given
   * title, leader text, items, message type, width, height, and icon.
   * The list of items is used to construct an internal string list that
   * is not backed by the original list. Changes made to the list or
   * items after dialog construction will not be reflected in the
   * dialog.</p>
   * 
   * <p>The message type must be one of the message types from
   * {@link javax.swing.JOptionPane}. The message type controlls which
   * default icon is used. If {@code icon} is non-null, it is used
   * instead of the default icon.</p>
   * 
   * @param owner The frame that owns this dialog. May be {@code null}.
   * @param dialogTitle The text to use as the dialog title.
   * @param leaderText Text to display before the list of items.
   * @param listItems The items to display in the list.
   * @param itemDescription A textual description of the items. This is used as the column heading for the items.
   * @param defaultSelection The default selection state (selected or unselected) for the items.
   * @param messageType The type of dialog message.
   * @param width The width of the dialog box.
   * @param height The height of the dialog box.
   * @param icon The icon to display. May be {@code null}.
   * @param fitToScreen If {@code true}, the width and height of the dialog will be calculated using the screen 
   *        dimensions, {@link #WIDTH_RATIO}, and {@link #HEIGHT_RATIO}. If {@code false}, the provided width and
   *        height will be used. 
   * @throws IllegalArgumentException if {@code listItems} is {@code null.}
   * @throws IllegalArgumentException if the message type is unknown or {@code listItems} is {@code null.}
   */
  private ScrollableListSelectionDialog(final Frame owner,
                                        final String dialogTitle,
                                        final String leaderText,
                                        final Collection<?> listItems,
                                        final String itemDescription,
                                        final SelectionState defaultSelection,
                                        final int messageType,
                                        final int width,
                                        final int height,
                                        final Icon icon,
                                        final boolean fitToScreen) {
    super(owner, dialogTitle, true);
    
    if (!_isknownMessageType(messageType)) {
      throw new IllegalArgumentException("The message type \"" + messageType + "\" is unknown");
    }
    
    if (listItems == null) {
      throw new IllegalArgumentException("listItems cannot be null");
    }
    
    /* create the leader text panel */
    JLabel dialogIconLabel = null;
    if (icon != null) {
      //use the user-provided icon
      dialogIconLabel = new JLabel(icon);
    } else {
      //lookup the message-dependent icon
      Icon messageIcon = _getIcon(messageType);
      if (messageIcon != null) {
        dialogIconLabel = new JLabel(messageIcon); 
      }
    }
    
    final JPanel leaderPanel = new JPanel();
    final JLabel leaderLabel = new JLabel(leaderText);
    leaderPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    if (dialogIconLabel != null) {
      leaderPanel.add(dialogIconLabel);
    }
    leaderPanel.add(leaderLabel);
    
    /* create the table */
    //copy the items string representations into a vector
    dataAsStrings = new Vector<String>(listItems.size());
    for (Object obj : listItems) {
      if (obj != null) {
        final String objAsString = obj.toString();
        dataAsStrings.add(objAsString);
      }
    }
    dataAsStrings.trimToSize();
    
    final int numItems = dataAsStrings.size();
    
    selectedItems = new Vector<Boolean>(numItems);
    synchronized(selectedItems) {
      for (int i = 0; i < numItems; ++i) {
        selectedItems.add(i, defaultSelection == SelectionState.SELECTED);
      }
      selectedItems.trimToSize();
    }
    assert selectedItems.size() == dataAsStrings.size();
    
    tableModel = new AbstractTableModel() {
      //@Override - uncomment when we start compiling with Java 6
      public int getRowCount() {
        return numItems;
      }
      
      //@Override - uncomment when we start compiling with Java 6
      public int getColumnCount() {
        return NUM_COLUMNS;
      }
      
      //@Override - uncomment when we start compiling with Java 6
      public Object getValueAt(int row, int column) {
        if (column == CHECKBOXES_COLUMN_INDEX) {
          assert row >= 0;
          assert row < numItems;
          synchronized(selectedItems) {
            return selectedItems.get(row);
          }
        } else if (column == STRINGS_COLUMN_INDEX) {
          assert row >= 0;
          assert row < numItems;
          return dataAsStrings.get(row);
        } else {
          assert false;
          return null;
        }
      }
      
      @Override
      public String getColumnName(int column) {
        if (column == CHECKBOXES_COLUMN_INDEX) {
          return "";
        } else if (column == STRINGS_COLUMN_INDEX) {
          return itemDescription;
        } else {
          assert false;
          return "";
        }
      }
      
      @Override
      public Class<?> getColumnClass(final int columnIndex) {
        if (columnIndex == CHECKBOXES_COLUMN_INDEX) {
          return Boolean.class;
        } else if (columnIndex == STRINGS_COLUMN_INDEX) {
          return String.class;
        } else {
          assert false;
          return Object.class;
        }
      }
      
      @Override
      public boolean isCellEditable(final int rowIndex, final int columnIndex) {
        return columnIndex == CHECKBOXES_COLUMN_INDEX; //only checkboxes are editable
      }
      
      @Override
      public void setValueAt(final Object newValue, final int rowIndex, final int columnIndex) {
        assert columnIndex == CHECKBOXES_COLUMN_INDEX;
        assert rowIndex >= 0;
        assert rowIndex < numItems;
        assert newValue instanceof Boolean;
        
        final Boolean booleanValue = (Boolean)newValue;
        
        synchronized(selectedItems) {
          selectedItems.set(rowIndex, booleanValue);
        }
      }
    };
    
    table = new JTable(tableModel);
    
    /*
     * this listener enabled clicking in the string column to update the
     * checkbox.
     */
    table.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(final MouseEvent e) {
        final Point clickPoint = e.getPoint();
        // which column was clicked on
        final int clickColumn = table.columnAtPoint(clickPoint);
        
        if (clickColumn == STRINGS_COLUMN_INDEX) {
          //it was the strings column, so update the check status of the row
          //Swing does not do this automatically
          final int clickRow = table.rowAtPoint(clickPoint);
          
          if (clickRow >= 0 && clickRow < numItems) {
            synchronized(selectedItems) {
              final boolean currentValue = selectedItems.get(clickRow);
              final boolean newValue = !currentValue;
              
              selectedItems.set(clickRow, newValue);
              /* We are deliberately holding on to the lock while the
               * listeners are notified. This, in theory, speeds up the
               * listeners because they don't have to re-acquire the
               * lock. Because the internals of Swing are unknown, the
               * lock may need to be released before the listeners are
               * notified. Only time will tell.
               * 
               * PS: If it turns out that holding the lock during
               * the listener updates is a problem, modify this comment
               * accordingly. Thank you.
               */
              tableModel.fireTableCellUpdated(clickRow, CHECKBOXES_COLUMN_INDEX);
            }
          }
        }
      }
    });
    
    //set the column sizes
    table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX).setMinWidth(15);
    table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX).setMaxWidth(30);
    table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX).setPreferredWidth(20);
    table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX).sizeWidthToFit();
    
    //create a scrollable view around the table
    final JScrollPane scrollPane = new JScrollPane(table);
    
    /* create the select all/select none panel */
    final JPanel selectButtonsPanel = new JPanel();
    selectButtonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
    _addSelectButtons(selectButtonsPanel);
    
    /* create the button panel */
    final JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
    //allow children to add additional buttons, if overridden
    _addButtons(buttonPanel);
    
    /* create the center panel which contains the scroll pane and the
     * select all/select none buttons */
    final JPanel centerPanel = new JPanel();
    centerPanel.setLayout(new BorderLayout());
    centerPanel.add(selectButtonsPanel, BorderLayout.NORTH);
    centerPanel.add(scrollPane, BorderLayout.CENTER);
    
    /* create the dialog */
    final JPanel contentPanel = new JPanel();
    contentPanel.setLayout(new BorderLayout(10, 5));
    contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10));
    
    contentPanel.add(leaderPanel, BorderLayout.NORTH);
    contentPanel.add(centerPanel, BorderLayout.CENTER);
    contentPanel.add(buttonPanel, BorderLayout.SOUTH);
    
    getContentPane().add(contentPanel);
    
    /* calculate the dialog's dimensions */
    final Dimension dialogSize = new Dimension();
    
    if (fitToScreen) {
      //use the screen dimensions to calculate the dialog's
      final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      int screenBasedWidth = (int) (WIDTH_RATIO * screenSize.getWidth());
      int screenBasedHeight = (int) (HEIGHT_RATIO * screenSize.getHeight());
      
      dialogSize.setSize(Math.max(DEFAULT_WIDTH, screenBasedWidth),
                         Math.max(DEFAULT_HEIGHT, screenBasedHeight));
    } else {
      //use the user-provided dimensions
      dialogSize.setSize(width, height);
    }
    
    setSize(dialogSize);
  }
  
  /** A method to check if they given message type is a know message
   * type.
   * 
   * @param messageType The message type to check
   * @return {@code true} if the message type is known, {@code false} otherwise
   */
  private boolean _isknownMessageType(final int messageType) {
    return messageType == JOptionPane.ERROR_MESSAGE ||
      messageType == JOptionPane.INFORMATION_MESSAGE ||
      messageType == JOptionPane.WARNING_MESSAGE ||
      messageType == JOptionPane.QUESTION_MESSAGE ||
      messageType == JOptionPane.PLAIN_MESSAGE;
  }
  
  /** Lookup the icon associated with the given messageType. The message
   * type must be one of the message types from
   * {@link javax.swing.JOptionPane}.
   * 
   * @param messageType The message for which the icon is requested.
   * @return The message's icon or {@code null} is no icon was found.
   */
  private Icon _getIcon(final int messageType) {
    assert _isknownMessageType(messageType);
    
    /* The OptionPane.xxxIcon constants were taken from 
     * javax.swing.plaf.basic.BasicOptionPaneUI, which may changed
     * without notice.
     */
    if (messageType == JOptionPane.ERROR_MESSAGE) {
      return UIManager.getIcon("OptionPane.errorIcon");
    } else if (messageType == JOptionPane.INFORMATION_MESSAGE) {
      return UIManager.getIcon("OptionPane.informationIcon");
    } else if (messageType == JOptionPane.WARNING_MESSAGE) {
      return UIManager.getIcon("OptionPane.warningIcon");
    } else if (messageType == JOptionPane.QUESTION_MESSAGE) {
      return UIManager.getIcon("OptionPane.questionIcon");
    } else if (messageType == JOptionPane.PLAIN_MESSAGE) {
      return null;
    } else {
      //should never get here
      assert false;
    }
    
    return null;
  }
  
  /** Adds the &quot;Select All&quot; and &quot;Select None&quot; buttons
   * to the given panel.
   * 
   * @param selectButtonsPanel The panel that should contain the buttons.
   */
  private void _addSelectButtons(final JPanel selectButtonsPanel) {
    final JButton selectAllButton = new JButton("Select All");
    selectAllButton.addActionListener(new SelectAllNoneActionListener(SelectionState.SELECTED));
    selectButtonsPanel.add(selectAllButton);
    
    final JButton selectNoneButton = new JButton("Select None");
    selectNoneButton.addActionListener(new SelectAllNoneActionListener(SelectionState.UNSELECTED));
    selectButtonsPanel.add(selectNoneButton);
  }
  
  /** Adds buttons to the bottom of the dialog. By default, a single
   * &quot;OK&quot; button is added that calls {@link #closeDialog}. It
   * is also set as the dialog's default button.
   *
   * Inheritors should feel free the change settings of the panel such
   * as the layout manager. However, no guarantees are made that every
   * change will work with every version of this class.
   * 
   * @param buttonPanel The JPanel that should contain the buttons.
   */
  protected void _addButtons(final JPanel buttonPanel) {
    final JButton okButton = new JButton("OK");
    okButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent notUsed) {
        closeDialog();
      }
    });
    
    buttonPanel.add(okButton);
    getRootPane().setDefaultButton(okButton);
  }
  
  /**
   * Shows the dialog.
   */
  public void showDialog() {
    pack();
    setVisible(true);
  }
  
  /** Should be called when the dialog should be closed. The default implementation
   * simply hides the dialog.
   */
  protected void closeDialog() {
    setVisible(false);
  }
  
  /** Returns the string representation of those items that are
   * currently selected. The items will be in the same relative order
   * as they were at construction time. The resultant collection may be
   * empty. The resultant collection is unmodifiable. The resultant
   * collection is simply a snapshot (i.e., It will not be updated as
   * more items are selected.). This method may be called from
   * non-event&nbsp;queue threads.
   * 
   * @return The currently selected items.
   */
  public java.util.List<String> selectedItems() {
    final java.util.List<String> results = new ArrayList<String>();
    
    synchronized(selectedItems) {
      /* This entire loop is synchronized so that we get a consistent
       * view of the selected items. It is also faster.
       */
      for (int i = 0; i < dataAsStrings.size(); ++i) {
        if (selectedItems.get(i)) {
          results.add(dataAsStrings.get(i));
        }
      }
    }
    
    return Collections.unmodifiableList(results);
  }
  
  /** An ActionListener that handles the &quot;Select All&quot; and
   * &quot;Select None&quot; buttons. It will set the selection state
   * of every item to the given selection state.
   */
  private class SelectAllNoneActionListener implements ActionListener {
    /** The value that the selection state will be set to when this
      * listener runs. */
    private final boolean _setToValue;
    
    /**
     * Creates a new SelectAllNoneActionListener that will set the state
     * of every item to the given state.
     * 
     * @param setToState The state to set all the items to.
     */
    public SelectAllNoneActionListener(SelectionState setToState) {
      _setToValue = setToState == SelectionState.SELECTED;
    }
    
    /**
     * The code that runs in response to the button's action.
     * This is the code that actually sets the selection state of the
     * items.
     * 
     * @param notUsed Not used.
     */
    public void actionPerformed(ActionEvent notUsed) {
      /* See comment in the table's mouse listener for a discussion
       * about the duration of the lock.
       */
      synchronized(selectedItems) {
        for (int i = 0; i < selectedItems.size(); ++i) {
          selectedItems.set(i, _setToValue);
        }
        tableModel.fireTableRowsUpdated(0, Math.max(0, selectedItems.size() - 1));
      }
    }
  }
  
  /** A simple main method for testing purposes.
   * 
   * @param args Not used.
   */
  public static void main(String args[]) {
    final Collection<String> data = new java.util.ArrayList<String>();
    data.add("how");
    data.add("now");
    data.add("brown");
    data.add("cow");
    
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        ScrollableListSelectionDialog ld = 
          new ScrollableListSelectionDialog(null, "TITLE", "LEADER", data, "Words", SelectionState.SELECTED, 
                                            JOptionPane.ERROR_MESSAGE) {
          @Override
          protected void closeDialog() {
            super.closeDialog();
            Collection<String> si = selectedItems();
            for (String i : si) {
              System.out.println(i);
            }
          }
        };
        ld.pack();
        ld.setVisible(true);
      }
    });
  }
}

   
    
    
    
    
  








Related examples in the same category

1.Vista Transparent DialogVista Transparent Dialog
2.Use this modal dialog to let the user choose one string from a long list
3.Tip Of Day Dialog
4.Swing error dialog (Exception dialog)Swing error dialog (Exception dialog)
5.Swing Login Domain Dialog with animationSwing Login Domain Dialog with animation
6.Shake a dialog
7.About dialog
8.Login DialogLogin Dialog
9.The base class for standard dialogs.
10.Password Dialog
11.Custom dialog box to enter dates
12.Dialog Panel
13.Login Panel
14.Exception dump and Dialog Box