Java/Swing Components/Dialog

Материал из Java эксперт
Перейти к: навигация, поиск

About dialog

   <source lang="java">
 

import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; class AboutDialog extends JDialog {

 public AboutDialog() {
   setTitle("About");
   setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
   add(Box.createRigidArea(new Dimension(0, 10)));
   JLabel name = new JLabel("Notes");
   name.setAlignmentX(0.5f);
   add(name);
   add(Box.createRigidArea(new Dimension(0, 100)));
   JButton close = new JButton("Close");
   close.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       dispose();
     }
   });
   close.setAlignmentX(0.5f);
   add(close);
   setModalityType(ModalityType.APPLICATION_MODAL);
   setDefaultCloseOperation(DISPOSE_ON_CLOSE);
   setSize(300, 200);
 }

} public class SimpleDialog {

 public static void main(String[] args) {
   JMenuBar menubar = new JMenuBar();
   JMenu file = new JMenu("File");
   file.setMnemonic(KeyEvent.VK_F);
   JMenu help = new JMenu("Help");
   help.setMnemonic(KeyEvent.VK_H);
   JMenuItem about = new JMenuItem("About");
   help.add(about);
   about.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent event) {
       AboutDialog ad = new AboutDialog();
       ad.setVisible(true);
     }
   });
   menubar.add(file);
   menubar.add(help);
   JFrame f = new JFrame();
   f.setJMenuBar(menubar);
   f.setSize(300, 200);
   f.setLocationRelativeTo(null);
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



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

   <source lang="java">
  

/*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; /**

*

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.

* 
*

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.

* 
*

This dialog is somewhat styled after * {@link javax.swing.JOptionPane} and uses the message-type constants * from JOptionPane.

* 
* @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;
 
/**

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.

  * 
*

The default sizing, message type, and icon are used. All the * items are selected by default.

  * 
  * @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);
 }
 
/**

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.

  * 
*

The message type must be one of the message types from * {@link javax.swing.JOptionPane}. The message type controlls which * default icon is used.

  * 
*

The default sizing and icon are used.

  * 
  * @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);
 }
 
/**

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.

  * 
*

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.

  * 
  * @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);
 }
 
/**

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.

  * 
*

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.

  * 
  * @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 "Select All" and "Select None" 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
  * "OK" 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 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 "Select All" and
  * "Select None" 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);
     }
   });
 }

}


 </source>
   
  
 
  



Custom dialog box to enter dates

   <source lang="java">
  

/**

*  This file is part of the jcrontab package
*  Copyright (C) 2002 Alexandre Pereira Calsavara
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free
*  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
*  MA 02111-1307, USA
*
*  For questions, suggestions:
*
*  iolalla@yahoo.ru
*
*/

import java.awt.Color; import java.awt.Container; import java.awt.Dialog; import java.awt.Frame; import java.awt.GridLayout; import java.awt.LayoutManager; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.Border;

/**

* Custom dialog box to enter dates. The DateChooser
* class presents a calendar and allows the user to visually select a
* day, month and year so that it is impossible to enter an invalid
* date.
* @author $Author: iolalla $
* @version $Revision: 1.1 $
**/

public class DateChooser extends JDialog

   implements ItemListener, MouseListener, FocusListener, KeyListener, ActionListener

{

   /** Names of the months. */
   private static final String[] MONTHS = 
 new String[] {
     "January",
     "February",
     "March",
     "April",
     "May",
     "June",
     "July",
     "August",
     "September",
     "October",
     "November",
     "December"
 };
   /** Names of the days of the week. */
   private static final String[] DAYS =
 new String[] {
     "Sun",
     "Mon",
     "Tue",
     "Wed",
     "Thu",
     "Fri",
     "Sat"
 };
   /** Text color of the days of the weeks, used as column headers in
       the calendar. */
   private static final Color WEEK_DAYS_FOREGROUND = Color.black;
   /** Text color of the days" numbers in the calendar. */
   private static final Color DAYS_FOREGROUND = Color.blue;
   /** Background color of the selected day in the calendar. */
   private static final Color SELECTED_DAY_FOREGROUND = Color.white;
   /** Text color of the selected day in the calendar. */
   private static final Color SELECTED_DAY_BACKGROUND = Color.blue;
   /** Empty border, used when the calendar does not have the focus. */
   private static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(1,1,1,1);
   /** Border used to highlight the selected day when the calendar
       has the focus. */
   private static final Border FOCUSED_BORDER = BorderFactory.createLineBorder(Color.yellow,1);
   /** First year that can be selected. */
   private static final int FIRST_YEAR = 1900;
   /** Last year that can be selected. */
   private static final int LAST_YEAR = 2100;
   /** Auxiliary variable to compute dates. */
   private GregorianCalendar calendar;
   /** Calendar, as a matrix of labels. The first row represents the
       first week of the month, the second row, the second week, and
       so on. Each column represents a day of the week, the first is
       Sunday, and the last is Saturday. The label"s text is the
       number of the corresponding day. */
   private JLabel[][] days;
   /** Day selection control. It is just a panel that can receive the
       focus. The actual user interaction is driven by the
       DateChooser class. */
   private FocusablePanel daysGrid;
   /** Month selection control. */
   private JComboBox month;
   /** Year selection control. */
   private JComboBox year;
   /** "Ok" button. */
   private JButton ok;
   /** "Cancel" button. */
   private JButton cancel;
   /** Day of the week (0=Sunday) corresponding to the first day of
       the selected month. Used to calculate the position, in the
       calendar ({@link #days}), corresponding to a given day. */
   private int offset;
   /** Last day of the selected month. */
   private int lastDay;
   /** Selected day. */
   private JLabel day;
   /** true if the "Ok" button was clicked to close the
       dialog box, false otherwise. */
   private boolean okClicked;
   /**
    * Custom panel that can receive the focus. Used to implement the
    * calendar control.
    **/
   private static class FocusablePanel extends JPanel
   {
 /**
  * Constructs a new FocusablePanel with the given
  * layout manager.
  *
  * @param layout layout manager
  **/
 public FocusablePanel( LayoutManager layout ) {
     super( layout );
 }
 /**
  * Always returns true, since
  * FocusablePanel can receive the focus.
  *
  * @return true
  **/
 public boolean isFocusTraversable() {
     return true;
 }
   }
   /**
    * Initializes this DateChooser object. Creates the
    * controls, registers listeners and initializes the dialog box.
    **/
   private void construct()
   {
 calendar = new GregorianCalendar();
 month = new JComboBox(MONTHS);
 month.addItemListener( this );
 year = new JComboBox();
 for ( int i=FIRST_YEAR; i<=LAST_YEAR; i++ )
     year.addItem( Integer.toString(i) );
 year.addItemListener( this );
 days = new JLabel[7][7];
 for ( int i=0; i<7; i++ ) {
     days[0][i] = new JLabel(DAYS[i],JLabel.RIGHT);
     days[0][i].setForeground( WEEK_DAYS_FOREGROUND );
 }
 for ( int i=1; i<7; i++ )
     for ( int j=0; j<7; j++ )
   {
       days[i][j] = new JLabel(" ",JLabel.RIGHT);
       days[i][j].setForeground( DAYS_FOREGROUND );
       days[i][j].setBackground( SELECTED_DAY_BACKGROUND );
       days[i][j].setBorder( EMPTY_BORDER );
       days[i][j].addMouseListener( this );
   }
 ok = new JButton("Ok");
 ok.addActionListener( this );
 cancel = new JButton("Cancel");
 cancel.addActionListener( this );
 JPanel monthYear = new JPanel();
 monthYear.add( month );
 monthYear.add( year );
 daysGrid = new FocusablePanel(new GridLayout(7,7,5,0));
 daysGrid.addFocusListener( this );
 daysGrid.addKeyListener( this );
 for ( int i=0; i<7; i++ )
     for ( int j=0; j<7; j++ )
   daysGrid.add( days[i][j] );
 daysGrid.setBackground( Color.white );
 daysGrid.setBorder( BorderFactory.createLoweredBevelBorder() );
 JPanel daysPanel = new JPanel();
 daysPanel.add( daysGrid );
 JPanel buttons = new JPanel();
 buttons.add( ok );
 buttons.add( cancel );
 Container dialog = getContentPane();
 dialog.add( "North", monthYear );
 dialog.add( "Center", daysPanel );
 dialog.add( "South", buttons );
 pack();
 setResizable( false );
   }
   /**
    * Gets the selected day, as an int. Parses the text
    * of the selected label in the calendar to get the day.
    *
    * @return the selected day or -1 if there is no day selected
    **/
   private int getSelectedDay()
   {
 if ( day == null )
     return -1 ;
 try {
     return Integer.parseInt(day.getText());
 } catch ( NumberFormatException e ) {
 }
 return -1;
   }
   /**
    * Sets the selected day. The day is specified as the label
    * control, in the calendar, corresponding to the day to select.
    *
    * @param newDay day to select
    **/
   private void setSelected( JLabel newDay )
   {
 if ( day != null ) {
     day.setForeground( DAYS_FOREGROUND );
     day.setOpaque( false );
     day.setBorder( EMPTY_BORDER );
 }
 day = newDay;
 day.setForeground( SELECTED_DAY_FOREGROUND );
 day.setOpaque( true );
 if ( daysGrid.hasFocus() )
     day.setBorder( FOCUSED_BORDER );
   }
   /**
    * Sets the selected day. The day is specified as the number of
    * the day, in the month, to selected. The function compute the
    * corresponding control to select.
    *
    * @param newDay day to select
    **/
   private void setSelected( int newDay )
   {
 setSelected( days[(newDay+offset-1)/7+1][(newDay+offset-1)%7] );
   }
   /**
    * Updates the calendar. This function updates the calendar panel
    * to reflect the month and year selected. It keeps the same day
    * of the month that was selected, except if it is beyond the last
    * day of the month. In this case, the last day of the month is
    * selected.
    **/
   private void update()
   {
 int iday = getSelectedDay();
 for ( int i=0; i<7; i++ ) {
     days[1][i].setText( " " );
     days[5][i].setText( " " );
     days[6][i].setText( " " );
 }
 calendar.set( Calendar.DATE, 1 );
 calendar.set( Calendar.MONTH, month.getSelectedIndex()+Calendar.JANUARY );
 calendar.set( Calendar.YEAR, year.getSelectedIndex()+FIRST_YEAR );
 offset = calendar.get(Calendar.DAY_OF_WEEK)-Calendar.SUNDAY;
 lastDay = calendar.getActualMaximum(Calendar.DATE);
 for ( int i=0; i<lastDay; i++ )
     days[(i+offset)/7+1][(i+offset)%7].setText( String.valueOf(i+1) );
 if ( iday != -1 ) {
     if ( iday > lastDay )
   iday = lastDay;
     setSelected( iday );
 }
   }
   /**
    * Called when the "Ok" button is pressed. Just sets a flag and
    * hides the dialog box.
    **/
   public void actionPerformed( ActionEvent e ) {
 if ( e.getSource() == ok )
     okClicked = true;
 hide();
   }
   /**
    * Called when the calendar gains the focus. Just re-sets the
    * selected day so that it is redrawn with the border that
    * indicate focus.
    **/
   public void focusGained( FocusEvent e ) {
 setSelected( day );
   }
   /**
    * Called when the calendar loses the focus. Just re-sets the
    * selected day so that it is redrawn without the border that
    * indicate focus.
    **/
   public void focusLost( FocusEvent e ) {
 setSelected( day );
   }
   /**
    * Called when a new month or year is selected. Updates the calendar
    * to reflect the selection.
    **/
   public void itemStateChanged( ItemEvent e ) {
 update();
   }
   /**
    * Called when a key is pressed and the calendar has the
    * focus. Handles the arrow keys so that the user can select a day
    * using the keyboard.
    **/
   public void keyPressed( KeyEvent e ) {
 int iday = getSelectedDay();
 switch ( e.getKeyCode() ) {
 case KeyEvent.VK_LEFT:
     if ( iday > 1 )
   setSelected( iday-1 );
     break;
 case KeyEvent.VK_RIGHT:
     if ( iday < lastDay )
   setSelected( iday+1 );
     break;
 case KeyEvent.VK_UP:
     if ( iday > 7 )
   setSelected( iday-7 );
     break;
 case KeyEvent.VK_DOWN:
     if ( iday <= lastDay-7 )
   setSelected( iday+7 );
     break;
 }
   }
   /**
    * Called when the mouse is clicked on a day in the
    * calendar. Selects the clicked day.
    **/
   public void mouseClicked( MouseEvent e ) {
 JLabel day = (JLabel)e.getSource();
 if ( !day.getText().equals(" ") )
     setSelected( day );
 daysGrid.requestFocus();
   }
   public void keyReleased( KeyEvent e ) {}
   public void keyTyped( KeyEvent e ) {}
   public void mouseEntered( MouseEvent e ) {}
   public void mouseExited( MouseEvent e) {}
   public void mousePressed( MouseEvent e ) {}
   public void mouseReleased( MouseEvent e) {}
   /**
    * Constructs a new DateChooser with the given title.
    *
    * @param owner owner dialog
    *
    * @param title dialog title
    **/
   public DateChooser( Dialog owner, String title )
   {
 super( owner, title, true );
 construct();
   }
   /**
    * Constructs a new DateChooser.
    *
    * @param owner owner dialog
    **/
   public DateChooser( Dialog owner )
   {
 super( owner, true );
 construct();
   }
   /**
    * Constructs a new DateChooser with the given title.
    *
    * @param owner owner frame
    *
    * @param title dialog title
    **/
   public DateChooser( Frame owner, String title )
   {
 super( owner, title, true );
 construct();
   }
   /**
    * Constructs a new DateChooser.
    *
    * @param owner owner frame
    **/
   public DateChooser( Frame owner )
   {
 super( owner, true );
 construct();
   }
   /**
    * Selects a date. Displays the dialog box, with a given date as
    * the selected date, and allows the user select a new date.
    *
    * @param date initial date
    *
    * @return the new date selected or null if the user
    * press "Cancel" or closes the dialog box
    **/
   public Date select( Date date )
   {
 calendar.setTime( date );
 int _day = calendar.get(Calendar.DATE);
 int _month = calendar.get(Calendar.MONTH);
 int _year = calendar.get(Calendar.YEAR);
 year.setSelectedIndex( _year-FIRST_YEAR );
 month.setSelectedIndex( _month-Calendar.JANUARY );
 setSelected( _day );
 okClicked = false;
 show();
 if ( !okClicked )
     return null;
 calendar.set( Calendar.DATE, getSelectedDay() );
 calendar.set( Calendar.MONTH, month.getSelectedIndex()+Calendar.JANUARY );
 calendar.set( Calendar.YEAR, year.getSelectedIndex()+FIRST_YEAR );
 return calendar.getTime();
   }
   /**
    * Selects new date. Just calls {@link #select(Date)} with the
    * system date as the parameter.
    *
    * @return the same as the function {@link #select(Date)}
    **/
   public Date select()
   {
 return select(new Date());
   }

}


 </source>
   
  
 
  



Dialog Panel

   <source lang="java">
  

/*

* Enhydra Java Application Server Project
*
* The contents of this file are subject to the Enhydra Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License on
* the Enhydra web site ( http://www.enhydra.org/ ).
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific terms governing rights and limitations
* under the License.
*
* The Initial Developer of the Enhydra Application Server is Lutris
* Technologies, Inc. The Enhydra Application Server and portions created
* by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
* All Rights Reserved.
*
* Contributor(s):
*
*/

// Standard imports import java.awt.BorderLayout; import java.awt.Window; import java.awt.Dialog; import java.awt.Frame; import java.awt.Point; import java.awt.event.WindowEvent; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JOptionPane; // public class DialogPanel extends JPanel {

   public final static int CANCEL_OPTION = JOptionPane.CANCEL_OPTION;
   public final static int OK_OPTION = JOptionPane.OK_OPTION;
   //
   private int             option = DialogPanel.CANCEL_OPTION;
   private LocalDialog     dialog = null;
   private Window          owner = null;
   private boolean         windowClose = false;
   private boolean         standalone = false;
   private boolean         modal = true;
   private String          title = new String();
   public Window getOwner() {
       return owner;
   }
   public void setOwner(Window w) {
       owner = w;
   }
   public String getTitle() {
       return title;
   }
   public void setTitle(String t) {
       title = t;
   }
   public boolean isModal() {
       return modal;
   }
   public void setModal(boolean b) {
       modal = b;
   }
   public int getOption() {
       return option;
   }
   public void setOption(int o) {
       option = o;
   }
   public LocalDialog getDialog() {
       return dialog;
   }
   public void startDialogThread() {
       Thread dialogThread = new Thread() {
           public void run() {
               showDialog();
           }
       };
       dialogThread.start();
   }
   public int showDialog() {
       BorderLayout layout = null;
       Point        cp = null;
       if (dialog == null) {
           if (getOwner() == null) {
               dialog = new LocalDialog();
           } else if (getOwner() instanceof Frame) {
               dialog = new LocalDialog((Frame) getOwner());
           } else if (getOwner() instanceof Dialog) {
               dialog = new LocalDialog((Dialog) getOwner());
           } else {
               dialog = new LocalDialog();
           }
       }
       dialog.setModal(isModal());
       dialog.setTitle(getTitle());
       layout = new BorderLayout();
       dialog.getRootPane().setLayout(layout);
       dialog.getRootPane().add(this, BorderLayout.CENTER);
       dialog.pack();
 
       dialog.show();
       return option;
   }
   //
   // PROTECTED
   //
   protected void hideDialog() {
       if (dialog != null) {
           dialog.setVisible(false);
       }
   }
   protected void clearDialog() {
       if (dialog != null) {
           dialog.setVisible(false);
           dialog.getRootPane().removeAll();
           dialog.removeAll();
           dialog.dispose();
       }
       if (isStandalone()) {
           System.exit(0);
       }
   }
   protected boolean isWindowClose() {
       return windowClose;
   }
   protected void setWindowClose(boolean b) {
       windowClose = b;
   }
   protected boolean isStandalone() {
       return standalone;
   }
   protected void setStandalone(boolean b) {
       standalone = b;
   }
   private class LocalDialog extends JDialog {
       public LocalDialog() {
           super();
       }
       public LocalDialog(Dialog owner) {
           super(owner);
       }
       public LocalDialog(Frame owner) {
           super(owner);
       }
       protected void processWindowEvent(WindowEvent e) {
           if (isWindowClose()) {
               if (e.getID() == WindowEvent.WINDOW_CLOSING) {
                   clearDialog();
               }
               super.processWindowEvent(e);
           }
       }
   }

}


 </source>
   
  
 
  



Login Dialog

Password Dialog

   <source lang="java">

/*

* Copyright (C) 2001-2007 Stephen Ostermiller
* http://ostermiller.org/contact.pl?regarding=Java+Utilities
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* See COPYING.TXT for details.
*/

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

* A modal dialog that asks the user for a user name and password.
* More information about this class is available from .
*
* 
*
 * PasswordDialog p = new PasswordDialog(null, "Test");
 * if(p.showDialog()){
 *     System.out.println("Name: " + p.getName());
 *     System.out.println("Pass: " + p.getPass());
 * } else {
 *     System.out.println("User selected cancel");
 * }
 * 
* 
*
* @author Stephen Ostermiller http://ostermiller.org/contact.pl?regarding=Java+Utilities
* @since ostermillerutils 1.00.00
*/

public class PasswordDialog extends JDialog {

 /**
  * Serial version id
  */
 private static final long serialVersionUID = -832548326686122133L;
 /**
  * Locale specific strings displayed to the user.
  *
  * @since ostermillerutils 1.00.00
  */
 protected ResourceBundle labels;
 /**
  * Set the locale used for getting localized
  * strings.
  *
  * @param locale Locale used to for i18n.
  *
  * @since ostermillerutils 1.00.00
  */
 @Override public void setLocale(Locale locale){
   labels = ResourceBundle.getBundle("com.Ostermiller.util.PasswordDialog",  locale);
 }
 /**
  * Where the name is typed.
  *
  * @since ostermillerutils 1.00.00
  */
 protected JTextField name;
 /**
  * Where the password is typed.
  *
  * @since ostermillerutils 1.00.00
  */
 protected JPasswordField pass;
 /**
  * The OK button.
  *
  * @since ostermillerutils 1.00.00
  */
 protected JButton okButton;
 /**
  * The cancel button.
  *
  * @since ostermillerutils 1.00.00
  */
 protected JButton cancelButton;
 /**
  * The label for the field in which the name is typed.
  *
  * @since ostermillerutils 1.00.00
  */
 protected JLabel nameLabel;
 /**
  * The label for the field in which the password is typed.
  *
  * @since ostermillerutils 1.00.00
  */
 protected JLabel passLabel;
 /**
  * Set the name that appears as the default
  * An empty string will be used if this in not specified
  * before the dialog is displayed.
  *
  * @param name default name to be displayed.
  *
  * @since ostermillerutils 1.00.00
  */
 @Override public void setName(String name){
   this.name.setText(name);
 }
 /**
  * Set the password that appears as the default
  * An empty string will be used if this in not specified
  * before the dialog is displayed.
  *
  * @param pass default password to be displayed.
  *
  * @since ostermillerutils 1.00.00
  */
 public void setPass(String pass){
   this.pass.setText(pass);
 }
 /**
  * Set the label on the OK button.
  * The default is a localized string.
  *
  * @param ok label for the ok button.
  *
  * @since ostermillerutils 1.00.00
  */
 public void setOKText(String ok){
   this.okButton.setText(ok);
   pack();
 }
 /**
  * Set the label on the cancel button.
  * The default is a localized string.
  *
  * @param cancel label for the cancel button.
  *
  * @since ostermillerutils 1.00.00
  */
 public void setCancelText(String cancel){
   this.cancelButton.setText(cancel);
   pack();
 }
 /**
  * Set the label for the field in which the name is entered.
  * The default is a localized string.
  *
  * @param name label for the name field.
  *
  * @since ostermillerutils 1.00.00
  */
 public void setNameLabel(String name){
   this.nameLabel.setText(name);
   pack();
 }
 /**
  * Set the label for the field in which the password is entered.
  * The default is a localized string.
  *
  * @param pass label for the password field.
  *
  * @since ostermillerutils 1.00.00
  */
 public void setPassLabel(String pass){
   this.passLabel.setText(pass);
   pack();
 }
 /**
  * Get the name that was entered into the dialog before
  * the dialog was closed.
  *
  * @return the name from the name field.
  *
  * @since ostermillerutils 1.00.00
  */
 @Override public String getName(){
   return name.getText();
 }
 /**
  * Get the password that was entered into the dialog before
  * the dialog was closed.
  *
  * @return the password from the password field.
  *
  * @since ostermillerutils 1.00.00
  */
 public String getPass(){
   return new String(pass.getPassword());
 }
 /**
  * Finds out if user used the OK button or an equivalent action
  * to close the dialog.
  * Pressing enter in the password field may be the same as
  * "OK" but closing the dialog and pressing the cancel button
  * are not.
  *
  * @return true if the the user hit OK, false if the user canceled.
  *
  * @since ostermillerutils 1.00.00
  */
 public boolean okPressed(){
   return pressed_OK;
 }
 /**
  * update this variable when the user makes an action
  *
  * @since ostermillerutils 1.00.00
  */
 private boolean pressed_OK = false;
 /**
  * Create this dialog with the given parent and title.
  *
  * @param parent window from which this dialog is launched
  * @param title the title for the dialog box window
  *
  * @since ostermillerutils 1.00.00
  */
 public PasswordDialog(Frame parent, String title) {
   super(parent, title, true);
   setLocale(Locale.getDefault());
   if (title==null){
     setTitle(labels.getString("dialog.title"));
   }
   if (parent != null){
     setLocationRelativeTo(parent);
   }
   // super calls dialogInit, so we don"t need to do it again.
 }
 /**
  * Create this dialog with the given parent and the default title.
  *
  * @param parent window from which this dialog is launched
  *
  * @since ostermillerutils 1.00.00
  */
 public PasswordDialog(Frame parent) {
   this(parent, null);
 }
 /**
  * Create this dialog with the default title.
  *
  * @since ostermillerutils 1.00.00
  */
 public PasswordDialog() {
   this(null, null);
 }
 /**
  * Called by constructors to initialize the dialog.
  *
  * @since ostermillerutils 1.00.00
  */
 @Override protected void dialogInit(){
   if (labels == null){
     setLocale(Locale.getDefault());
   }
   name = new JTextField("", 20);
   pass = new JPasswordField("", 20);
   okButton = new JButton(labels.getString("dialog.ok"));
   cancelButton = new JButton(labels.getString("dialog.cancel"));
   nameLabel = new JLabel(labels.getString("dialog.name") + " ");
   passLabel = new JLabel(labels.getString("dialog.pass") + " ");
   super.dialogInit();
   KeyListener keyListener = (new KeyAdapter() {
     @Override public void keyPressed(KeyEvent e){
       if (e.getKeyCode() == KeyEvent.VK_ESCAPE ||
           (e.getSource() == cancelButton
           && e.getKeyCode() == KeyEvent.VK_ENTER)){
         pressed_OK = false;
         PasswordDialog.this.setVisible(false);
       }
       if (e.getSource() == okButton &&
           e.getKeyCode() == KeyEvent.VK_ENTER){
         pressed_OK = true;
         PasswordDialog.this.setVisible(false);
       }
     }
   });
   addKeyListener(keyListener);
   ActionListener actionListener = new ActionListener() {
     public void actionPerformed(ActionEvent e){
       Object source = e.getSource();
       if (source == name){
         // the user pressed enter in the name field.
         name.transferFocus();
       } else {
         // other actions close the dialog.
         pressed_OK = (source == pass || source == okButton);
         PasswordDialog.this.setVisible(false);
       }
     }
   };
   GridBagLayout gridbag = new GridBagLayout();
   GridBagConstraints c = new GridBagConstraints();
   c.insets.top = 5;
   c.insets.bottom = 5;
   JPanel pane = new JPanel(gridbag);
   pane.setBorder(BorderFactory.createEmptyBorder(10, 20, 5, 20));
   c.anchor = GridBagConstraints.EAST;
   gridbag.setConstraints(nameLabel, c);
   pane.add(nameLabel);
   gridbag.setConstraints(name, c);
   name.addActionListener(actionListener);
   name.addKeyListener(keyListener);
   pane.add(name);
   c.gridy = 1;
   gridbag.setConstraints(passLabel, c);
   pane.add(passLabel);
   gridbag.setConstraints(pass, c);
   pass.addActionListener(actionListener);
   pass.addKeyListener(keyListener);
   pane.add(pass);
   c.gridy = 2;
   c.gridwidth = GridBagConstraints.REMAINDER;
   c.anchor = GridBagConstraints.CENTER;
   JPanel panel = new JPanel();
   okButton.addActionListener(actionListener);
   okButton.addKeyListener(keyListener);
   panel.add(okButton);
   cancelButton.addActionListener(actionListener);
   cancelButton.addKeyListener(keyListener);
   panel.add(cancelButton);
   gridbag.setConstraints(panel, c);
   pane.add(panel);
   getContentPane().add(pane);
   pack();
 }
 /**
  * Shows the dialog and returns true if the user pressed ok.
  *
  * @return true if the the user hit OK, false if the user canceled.
  *
  * @since ostermillerutils 1.00.00
  */
 public boolean showDialog(){
   setVisible(true);
   return okPressed();
 }

}

 </source>
   
  
 
  



Shake a dialog

   <source lang="java">
 

import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.Timer; public class Main {

 JDialog dialog;
 Point naturalLocation;
 Timer shakeTimer;
 public Main(JDialog d) {
   dialog = d;
 }
 public void startShake() {
   final long startTime;
   
   naturalLocation = dialog.getLocation();
   startTime = System.currentTimeMillis();
   shakeTimer = new Timer(5, new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       double TWO_PI = Math.PI * 2.0;
       double SHAKE_CYCLE = 50;
       long elapsed = System.currentTimeMillis() - startTime;
       double waveOffset = (elapsed % SHAKE_CYCLE) / SHAKE_CYCLE;
       double angle = waveOffset * TWO_PI;
       int SHAKE_DISTANCE = 10;
       int shakenX = (int) ((Math.sin(angle) * SHAKE_DISTANCE) + naturalLocation.x);
       dialog.setLocation(shakenX, naturalLocation.y);
       dialog.repaint();
       int SHAKE_DURATION = 1000;
       if (elapsed >= SHAKE_DURATION)
         stopShake();
     }
   });
   shakeTimer.start();
 }
 public void stopShake() {
   shakeTimer.stop();
   dialog.setLocation(naturalLocation);
   dialog.repaint();
 }
 public static void main(String[] args) {
   JOptionPane pane = new JOptionPane("your message",JOptionPane.ERROR_MESSAGE, JOptionPane.OK_OPTION);
   JDialog d = pane.createDialog(null, "title");
   Main dec = new Main(d);
   d.pack();
   d.setModal(false);
   d.setVisible(true);
   dec.startShake();
 }

}


 </source>
   
  
 
  



Swing error dialog (Exception dialog)

Swing Login Domain Dialog with animation

The base class for standard dialogs.

   <source lang="java">

/*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
*
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -------------------
* StandardDialog.java
* -------------------
* (C) Copyright 2000-2008, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   Arnaud Lelievre;
*
* $Id: StandardDialog.java,v 1.7 2008/12/18 09:57:32 mungady Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
* 08-Sep-2003 : Added internationalization via use of properties
*               resourceBundle (RFE 690236) (AL);
* 18-Dec-2008 : Use ResourceBundleWrapper - see JFreeChart patch 1607918 by
*               Jess Thrysoee (DG);
*
*/

import java.awt.BorderLayout; import java.awt.Dialog; import java.awt.Frame; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JPanel;

/**

* The base class for standard dialogs.
*
* @author David Gilbert
*/

public class StandardDialog extends JDialog implements ActionListener {

   /** Flag that indicates whether or not the dialog was cancelled. */
   private boolean cancelled;
   /**
    * Standard constructor - builds a dialog...
    *
    * @param owner  the owner.
    * @param title  the title.
    * @param modal  modal?
    */
   public StandardDialog(final Frame owner, final String title,
           final boolean modal) {
       super(owner, title, modal);
       this.cancelled = false;
   }
   /**
    * Standard constructor - builds a dialog...
    *
    * @param owner  the owner.
    * @param title  the title.
    * @param modal  modal?
    */
   public StandardDialog(final Dialog owner, final String title,
           final boolean modal) {
       super(owner, title, modal);
       this.cancelled = false;
   }
   /**
    * Returns a flag that indicates whether or not the dialog has been
    * cancelled.
    *
    * @return boolean.
    */
   public boolean isCancelled() {
       return this.cancelled;
   }
   /**
    * Handles clicks on the standard buttons.
    *
    * @param event  the event.
    */
   public void actionPerformed(final ActionEvent event) {
       final String command = event.getActionCommand();
       if (command.equals("helpButton")) {
           // display help information
       }
       else if (command.equals("okButton")) {
           this.cancelled = false;
           setVisible(false);
       }
       else if (command.equals("cancelButton")) {
           this.cancelled = true;
           setVisible(false);
       }
   }
   /**
    * Builds and returns the user interface for the dialog.  This method is
    * shared among the constructors.
    *
    * @return the button panel.
    */
   protected JPanel createButtonPanel() {
       final L1R2ButtonPanel buttons = new L1R2ButtonPanel(
               "Help",
               "OK",
               "Cancel");
       final JButton helpButton = buttons.getLeftButton();
       helpButton.setActionCommand("helpButton");
       helpButton.addActionListener(this);
       final JButton okButton = buttons.getRightButton1();
       okButton.setActionCommand("okButton");
       okButton.addActionListener(this);
       final JButton cancelButton = buttons.getRightButton2();
       cancelButton.setActionCommand("cancelButton");
       cancelButton.addActionListener(this);
       buttons.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
       return buttons;
   }

} /*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
* 
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it 
* under the terms of the GNU Lesser General Public License as published by 
* the Free Software Foundation; either version 2.1 of the License, or 
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
* USA.  
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
* in the United States and other countries.]
* 
* --------------------
* L1R2ButtonPanel.java
* --------------------
* (C) Copyright 2000-2004, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   -;
*
* $Id: L1R2ButtonPanel.java,v 1.4 2007/11/02 17:50:36 taqua Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
* 26-Jun-2002 : Removed unnecessary import (DG);
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/

/**

* A "ready-made" panel that has one button on the left and two buttons on the right - nested
* panels and layout managers take care of resizing.
*
* @author David Gilbert
*/

class L1R2ButtonPanel extends JPanel {

   /** The left button. */
   private JButton left;
   /** The first button on the right of the panel. */
   private JButton right1;
   /** The second button on the right of the panel. */
   private JButton right2;
   /**
    * Standard constructor - creates a three button panel with the specified button labels.
    *
    * @param label1  the label for button 1.
    * @param label2  the label for button 2.
    * @param label3  the label for button 3.
    */
   public L1R2ButtonPanel(final String label1, final String label2, final String label3) {
       setLayout(new BorderLayout());
       // create the pieces...
       this.left = new JButton(label1);
       final JPanel rightButtonPanel = new JPanel(new GridLayout(1, 2));
       this.right1 = new JButton(label2);
       this.right2 = new JButton(label3);
       rightButtonPanel.add(this.right1);
       rightButtonPanel.add(this.right2);
       // ...and put them together
       add(this.left, BorderLayout.WEST);
       add(rightButtonPanel, BorderLayout.EAST);
   }
   /**
    * Returns a reference to button 1, allowing the caller to set labels, action-listeners etc.
    *
    * @return the left button.
    */
   public JButton getLeftButton() {
       return this.left;
   }
   /**
    * Returns a reference to button 2, allowing the caller to set labels, action-listeners etc.
    *
    * @return the right button 1.
    */
   public JButton getRightButton1() {
       return this.right1;
   }
   /**
    * Returns a reference to button 3, allowing the caller to set labels, action-listeners etc.
    *
    * @return  the right button 2.
    */
   public JButton getRightButton2() {
       return this.right2;
   }

}

 </source>
   
  
 
  



Tip Of Day Dialog

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.event.KeyEvent; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTextPane; public class TipOfDay {

 public static void main(String[] args) {
   JDialog d = new JDialog((Frame)null,"Tip of the Day");
   JPanel basic = new JPanel();
   basic.setLayout(new BoxLayout(basic, BoxLayout.Y_AXIS));
   d.add(basic);
   JPanel topPanel = new JPanel(new BorderLayout(0, 0));
   topPanel.setMaximumSize(new Dimension(450, 0));
   JLabel hint = new JLabel("This is the tip");
   hint.setBorder(BorderFactory.createEmptyBorder(10, 25, 10, 10));
   topPanel.add(hint);
   JSeparator separator = new JSeparator();
   separator.setForeground(Color.gray);
   topPanel.add(separator, BorderLayout.SOUTH);
   basic.add(topPanel);
   JPanel textPanel = new JPanel(new BorderLayout());
   textPanel.setBorder(BorderFactory.createEmptyBorder(15, 25, 15, 25));
   JTextPane pane = new JTextPane();
   pane.setContentType("text/html");
String text = "

Content

";
   pane.setText(text);
   pane.setEditable(false);
   textPanel.add(new JScrollPane(pane));
   basic.add(textPanel);
   JPanel boxPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0));
   JCheckBox box = new JCheckBox("Show Tips at startup");
   box.setMnemonic(KeyEvent.VK_S);
   boxPanel.add(box);
   basic.add(boxPanel);
   JPanel bottom = new JPanel(new FlowLayout(FlowLayout.RIGHT));
   JButton ntip = new JButton("Next Tip");
   ntip.setMnemonic(KeyEvent.VK_N);
   JButton close = new JButton("Close");
   close.setMnemonic(KeyEvent.VK_C);
   bottom.add(ntip);
   bottom.add(close);
   basic.add(bottom);
   bottom.setMaximumSize(new Dimension(450, 0));
   d.setSize(new Dimension(450, 350));
   d.setResizable(false);
   d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
   d.setVisible(true);
 }

}


 </source>
   
  
 
  



Use this modal dialog to let the user choose one string from a long list

   <source lang="java">
 

/*

* Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  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 name of Sun Microsystems 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.
*/

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; /**

* A 1.4 application that brings up a ListDialog.
*/

public class ListDialogRunner {

 static JFrame frame;
 static String[] names = { "Arlo", "Cosmo", "Elmo", "Hugo", "Jethro",
     "Laszlo", "Milo", "Nemo", "Otto", "Ringo", "Rocco", "Rollo" };
 public static JPanel createUI() {
   // Create the labels.
   JLabel intro = new JLabel("The chosen name:");
   final JLabel name = new JLabel(names[1]);
   intro.setLabelFor(name);
   // Use a wacky font if it exists. If not, this falls
   // back to a font we know exists.
   name.setFont(getAFont());
   // Create the button.
   final JButton button = new JButton("Pick a new name...");
   button.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       String selectedName = ListDialog.showDialog(frame, button,
           "Baby names ending in O:", "Name Chooser", names, name.getText(),
           "Cosmo  ");
       name.setText(selectedName);
     }
   });
   // Create the panel we"ll return and set up the layout.
   JPanel panel = new JPanel();
   panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
   panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 10, 20));
   intro.setAlignmentX(JComponent.CENTER_ALIGNMENT);
   name.setAlignmentX(JComponent.CENTER_ALIGNMENT);
   button.setAlignmentX(JComponent.CENTER_ALIGNMENT);
   // Add the labels to the content pane.
   panel.add(intro);
   panel.add(Box.createVerticalStrut(5)); // extra space
   panel.add(name);
   // Add a vertical spacer that also guarantees us a minimum width:
   panel.add(Box.createRigidArea(new Dimension(150, 10)));
   // Add the button.
   panel.add(button);
   return panel;
 }
 /**
  * Finds a cursive font to use, or falls back to using an italic serif font.
  */
 protected static Font getAFont() {
   // initial strings of desired fonts
   String[] desiredFonts = { "French Script", "FrenchScript", "Script" };
   String[] existingFamilyNames = null; // installed fonts
   String fontName = null; // font we"ll use
   // Search for all installed font families. The first
   // call may take a while on some systems with hundreds of
   // installed fonts, so if possible execute it in idle time,
   // and certainly not in a place that delays painting of
   // the UI (for example, when bringing up a menu).
   //
   // In systems with malformed fonts, this code might cause
   // serious problems; use the latest JRE in this case. (You"ll
   // see the same problems if you use Swing"s HTML support or
   // anything else that searches for all fonts.) If this call
   // causes problems for you under the latest JRE, please let
   // us know:
   // http://java.sun.ru/docs/books/tutorial/forms/sendusmail.html
   GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
   if (ge != null) {
     existingFamilyNames = ge.getAvailableFontFamilyNames();
   }
   // See if there"s one we like.
   if ((existingFamilyNames != null) && (desiredFonts != null)) {
     int i = 0;
     while ((fontName == null) && (i < desiredFonts.length)) {
       // Look for a font whose name starts with desiredFonts[i].
       int j = 0;
       while ((fontName == null) && (j < existingFamilyNames.length)) {
         if (existingFamilyNames[j].startsWith(desiredFonts[i])) {
           // We"ve found a match. Test whether it can display
           // the Latin character "A". (You might test for
           // a different character if you"re using a different
           // language.)
           Font f = new Font(existingFamilyNames[j], Font.PLAIN, 1);
           if (f.canDisplay("A")) {
             fontName = existingFamilyNames[j];
             System.out.println("Using font: " + fontName);
           }
         }
         j++; // Look at next existing font name.
       }
       i++; // Look for next desired font.
     }
   }
   // Return a valid Font.
   if (fontName != null) {
     return new Font(fontName, Font.PLAIN, 36);
   } else {
     return new Font("Serif", Font.ITALIC, 36);
   }
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   // Create and set up the window.
   frame = new JFrame("Name That Baby");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   // Create and set up the content pane.
   JComponent newContentPane = createUI();
   newContentPane.setOpaque(true); // content panes must be opaque
   frame.setContentPane(newContentPane);
   // Display the window.
   frame.pack();
   frame.setVisible(true);
 }
 public static void main(String[] args) {
   // Schedule a job for the event-dispatching thread:
   // creating and showing this application"s GUI.
   javax.swing.SwingUtilities.invokeLater(new Runnable() {
     public void run() {
       createAndShowGUI();
     }
   });
 }

} /*

* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. 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 name of Sun Microsystems 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.
*/

/*

* ListDialog.java is meant to be used by programs such as ListDialogRunner. It
* requires no additional files.
*/

/**

* Use this modal dialog to let the user choose one string from a long list. See
* ListDialogRunner.java for an example of using ListDialog. The basics:
* 
*
 * String[] choices = { "A", "long", "array", "of", "strings" };
 * String selectedName = ListDialog.showDialog(componentInControllingFrame,
 *     locatorComponent, "A description of the list:", "Dialog Title", choices,
 *     choices[0]);
 * 
*/

class ListDialog extends JDialog implements ActionListener {

 private static ListDialog dialog;
 private static String value = "";
 private JList list;
 /**
  * Set up and show the dialog. The first Component argument determines which
  * frame the dialog depends on; it should be a component in the dialog"s
  * controlling frame. The second Component argument should be null if you want
  * the dialog to come up with its left corner in the center of the screen;
  * otherwise, it should be the component on top of which the dialog should
  * appear.
  */
 public static String showDialog(Component frameComp, Component locationComp,
     String labelText, String title, String[] possibleValues,
     String initialValue, String longValue) {
   Frame frame = JOptionPane.getFrameForComponent(frameComp);
   dialog = new ListDialog(frame, locationComp, labelText, title,
       possibleValues, initialValue, longValue);
   dialog.setVisible(true);
   return value;
 }
 private void setValue(String newValue) {
   value = newValue;
   list.setSelectedValue(value, true);
 }
 private ListDialog(Frame frame, Component locationComp, String labelText,
     String title, Object[] data, String initialValue, String longValue) {
   super(frame, title, true);
   // Create and initialize the buttons.
   JButton cancelButton = new JButton("Cancel");
   cancelButton.addActionListener(this);
   //
   final JButton setButton = new JButton("Set");
   setButton.setActionCommand("Set");
   setButton.addActionListener(this);
   getRootPane().setDefaultButton(setButton);
   // main part of the dialog
   list = new JList(data) {
     // Subclass JList to workaround bug 4832765, which can cause the
     // scroll pane to not let the user easily scroll up to the beginning
     // of the list. An alternative would be to set the unitIncrement
     // of the JScrollBar to a fixed value. You wouldn"t get the nice
     // aligned scrolling, but it should work.
     public int getScrollableUnitIncrement(Rectangle visibleRect,
         int orientation, int direction) {
       int row;
       if (orientation == SwingConstants.VERTICAL && direction < 0
           && (row = getFirstVisibleIndex()) != -1) {
         Rectangle r = getCellBounds(row, row);
         if ((r.y == visibleRect.y) && (row != 0)) {
           Point loc = r.getLocation();
           loc.y--;
           int prevIndex = locationToIndex(loc);
           Rectangle prevR = getCellBounds(prevIndex, prevIndex);
           if (prevR == null || prevR.y >= r.y) {
             return 0;
           }
           return prevR.height;
         }
       }
       return super.getScrollableUnitIncrement(visibleRect, orientation,
           direction);
     }
   };
   list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
   if (longValue != null) {
     list.setPrototypeCellValue(longValue); // get extra space
   }
   list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
   list.setVisibleRowCount(-1);
   list.addMouseListener(new MouseAdapter() {
     public void mouseClicked(MouseEvent e) {
       if (e.getClickCount() == 2) {
         setButton.doClick(); // emulate button click
       }
     }
   });
   JScrollPane listScroller = new JScrollPane(list);
   listScroller.setPreferredSize(new Dimension(250, 80));
   listScroller.setAlignmentX(LEFT_ALIGNMENT);
   // Create a container so that we can add a title around
   // the scroll pane. Can"t add a title directly to the
   // scroll pane because its background would be white.
   // Lay out the label and scroll pane from top to bottom.
   JPanel listPane = new JPanel();
   listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
   JLabel label = new JLabel(labelText);
   label.setLabelFor(list);
   listPane.add(label);
   listPane.add(Box.createRigidArea(new Dimension(0, 5)));
   listPane.add(listScroller);
   listPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
   // Lay out the buttons from left to right.
   JPanel buttonPane = new JPanel();
   buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
   buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
   buttonPane.add(Box.createHorizontalGlue());
   buttonPane.add(cancelButton);
   buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
   buttonPane.add(setButton);
   // Put everything together, using the content pane"s BorderLayout.
   Container contentPane = getContentPane();
   contentPane.add(listPane, BorderLayout.CENTER);
   contentPane.add(buttonPane, BorderLayout.PAGE_END);
   // Initialize values.
   setValue(initialValue);
   pack();
   setLocationRelativeTo(locationComp);
 }
 // Handle clicks on the Set and Cancel buttons.
 public void actionPerformed(ActionEvent e) {
   if ("Set".equals(e.getActionCommand())) {
     ListDialog.value = (String) (list.getSelectedValue());
   }
   ListDialog.dialog.setVisible(false);
 }

}


 </source>
   
  
 
  



Vista Transparent Dialog

   <source lang="java">
 

/*

* Copyright (c) 2007, Romain Guy
* 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 name of the TimingFramework project 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.
*/

import java.awt.Color; import java.awt.ruponent; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; import java.util.HashMap; import java.util.Map; import javax.swing.UIManager; import javax.swing.border.Border; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.awt.GraphicsConfiguration; import java.awt.Transparency; import java.awt.Graphics; import java.awt.GraphicsEnvironment; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; /**

*
* @author Romain Guy <romain.guy@mac.ru>
*/

public class TextHighlightingDemo extends JFrame {

   private VistaSearchDialog dialog;
   
   public TextHighlightingDemo() {
       super("Text Highlighting");
       
       add(new DummyPanel());
       JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING));
       JButton button = new JButton("Show Dialog");
       button.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               dialog = new VistaSearchDialog(TextHighlightingDemo.this);
               installInLayeredPane(dialog);
               dialog.setVisible(true);
           }
       });
       panel.add(button);
       add(panel, BorderLayout.SOUTH);
       
       pack();
       setLocationRelativeTo(null);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
   }
   private void installInLayeredPane(JComponent component) {
       JLayeredPane layeredPane = getRootPane().getLayeredPane();
       layeredPane.add(component, JLayeredPane.PALETTE_LAYER, 20);
       Dimension size = component.getPreferredSize();
       component.setSize(size);
       component.setLocation((getWidth() - size.width) / 2,
               (getHeight() - size.height) / 2);
       component.revalidate();
       component.setVisible(true);
   }
   
   public static void main(String[] args) {
       SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               new TextHighlightingDemo().setVisible(true);
           }
       });
   }

} /*

* Copyright (c) 2007, Romain Guy
* 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 name of the TimingFramework project 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.
*/

class VistaSearchDialog extends JComponent {

   private static final int BLUR_SIZE = 7;
   private BufferedImage image;
   private float alpha = 0.0f;
   public VistaSearchDialog(JFrame frame) {
       Container contentPane = frame.getRootPane();
       image = GraphicsUtilities.createCompatibleTranslucentImage(contentPane.getWidth() +
                                                  2 * (int) BLUR_SIZE,
                                                  contentPane.getHeight() +
                                                  2 * (int) BLUR_SIZE);
       Graphics2D g2 = image.createGraphics();
       g2.translate(BLUR_SIZE, BLUR_SIZE);
       contentPane.paint(g2);
       g2.translate(-BLUR_SIZE, -BLUR_SIZE);
       g2.dispose();
       // 1.5 second vs 0.3 second

// long start = System.currentTimeMillis();

       image = changeImageWidth(image, image.getWidth() / 2);
       ConvolveOp gaussianFilter = getGaussianBlurFilter(BLUR_SIZE, true);
       image = gaussianFilter.filter(image, null);
       gaussianFilter = getGaussianBlurFilter(BLUR_SIZE, false);
       image = gaussianFilter.filter(image, null);
       ColorTintFilter colorMixFilter = new ColorTintFilter(Color.WHITE, 0.4f);
       image = colorMixFilter.filter(image, null);
       image = changeImageWidth(image, image.getWidth() * 2);

// System.out.println("time = " + // ((System.currentTimeMillis() - start) / 1000.0f));

       setBorder(new DropShadowBorder(Color.BLACK, 0, 11, .2f, 16,
                                      false, true, true, true));
       setLayout(new BorderLayout());
       initComponents();
   }
   
   public static BufferedImage changeImageWidth(BufferedImage image, int width) {
       float ratio = (float) image.getWidth() / (float) image.getHeight();
       int height = (int) (width / ratio);
       
       BufferedImage temp = new BufferedImage(width, height,
               image.getType());
       Graphics2D g2 = temp.createGraphics();
       g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                           RenderingHints.VALUE_INTERPOLATION_BILINEAR);
       g2.drawImage(image, 0, 0, temp.getWidth(), temp.getHeight(), null);
       g2.dispose();
       return temp;
   }
   
   public static ConvolveOp getGaussianBlurFilter(int radius,
           boolean horizontal) {
       if (radius < 1) {
           throw new IllegalArgumentException("Radius must be >= 1");
       }
       
       int size = radius * 2 + 1;
       float[] data = new float[size];
       
       float sigma = radius / 3.0f;
       float twoSigmaSquare = 2.0f * sigma * sigma;
       float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI);
       float total = 0.0f;
       
       for (int i = -radius; i <= radius; i++) {
           float distance = i * i;
           int index = i + radius;
           data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot;
           total += data[index];
       }
       
       for (int i = 0; i < data.length; i++) {
           data[i] /= total;
       }        
       
       Kernel kernel = null;
       if (horizontal) {
           kernel = new Kernel(size, 1, data);
       } else {
           kernel = new Kernel(1, size, data);
       }
       return new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
   }
   private void initComponents() {
       TitleBar titleBar =
               new TitleBar("Search in this Message");
       add(titleBar, BorderLayout.NORTH);
       SearchPanel contentPane = new SearchPanel();
       contentPane.setOpaque(false);
       contentPane.setBorder(BorderFactory.createEmptyBorder(16, 2, 16, 2));
       add(contentPane);
   }
   @Override
   public boolean isOpaque() {
       return false;
   }
   @Override
   protected void paintComponent(Graphics g) {
       setupGraphics((Graphics2D) g);
       Point location = getLocation();
       location.x = (int) (-location.x - BLUR_SIZE);
       location.y = (int) (-location.y - BLUR_SIZE);
       Insets insets = getInsets();
       Shape oldClip = g.getClip();
       g.setClip(insets.left, insets.top,
                 getWidth() - insets.left - insets.right,
                 getHeight() - insets.top - insets.bottom);
       g.drawImage(image, location.x, location.y, null);
       g.setClip(oldClip);
   }
   public float getAlpha() {
       return alpha;
   }
   public void setAlpha(float alpha) {
       this.alpha = alpha;
       repaint();
   }
   private static void setupGraphics(Graphics2D g2) {
       g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
      
       Toolkit tk = Toolkit.getDefaultToolkit();
       Map desktopHints = (Map) (tk.getDesktopProperty("awt.font.desktophints"));
       if (desktopHints != null) {
           g2.addRenderingHints(desktopHints);
       }
   }
   private class TitleBar extends JComponent {
       private String title;
       private TitleBar(String title) {
           this.title = title;
           setName("vistaTitleBar");
           setFont(new Font("Dialog", Font.BOLD, 12));
           setLayout(new GridBagLayout());
           JButton button = new JButton();
           button.setMargin(new Insets(0, 0, 0, 0));
           button.setBorder(null);
           button.setIconTextGap(0);
           button.setVerticalAlignment(SwingConstants.TOP);
           button.setContentAreaFilled(false);
           button.setBorderPainted(false);
           button.setFocusPainted(false);
           button.setIcon(new ImageIcon(getClass().getResource("close-title-bar.png")));
           button.setRolloverIcon(new ImageIcon(getClass().getResource("close-title-bar-rollover.png")));
           button.setOpaque(false);
           button.setName("vistaCloseButton");
           add(Box.createVerticalStrut(24),
               new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
                                      GridBagConstraints.LINE_START,
                                      GridBagConstraints.HORIZONTAL,
                                      new Insets(0, 0, 0, 0), 0, 0));
           add(button, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
                                              GridBagConstraints.FIRST_LINE_END,
                                              GridBagConstraints.VERTICAL,
                                              new Insets(0, 0, 0, 0), 0, 0));
           button.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                   VistaSearchDialog.this.setVisible(false);
               }
           });
           Locator locator = new Locator();
           addMouseListener(locator);
           addMouseMotionListener(locator);
       }
       @Override
       public boolean isOpaque() {
           return false;
       }
       @Override
       protected void paintComponent(Graphics g) {
           Graphics2D g2 = (Graphics2D) g;
           setupGraphics(g2);
           Paint oldPaint = g2.getPaint();
           float rgb[] = new Color(0xe9efff).getRGBColorComponents(null);
           g2.setPaint(new GradientPaint(0.0f, 0.0f,
                                         new Color(rgb[0], rgb[1], rgb[2], 0.2f * getAlpha()),
                                         0.0f, getHeight(),
                                         new Color(rgb[0], rgb[1], rgb[2], 0.8f * getAlpha())));
           g2.fillRect(0, 0, getWidth(), getHeight());
           drawText(g2, 3, 0.8f);
           g2.setPaint(oldPaint);
           g2.setColor(new Color(rgb[0], rgb[1], rgb[2], 0.6f * getAlpha()));
           g2.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
           g2.drawLine(0, getHeight() - 2, getWidth(), getHeight() - 2);
       }
       private void drawText(Graphics2D g2, int size, float opacity) {
           Composite oldComposite = g2.getComposite();
           float preAlpha = 1.0f;
           if (oldComposite instanceof AlphaComposite &&
               ((AlphaComposite) oldComposite).getRule() == AlphaComposite.SRC_OVER) {
               preAlpha = ((AlphaComposite) oldComposite).getAlpha();
           }
           g2.setFont(getFont());
           FontMetrics metrics = g2.getFontMetrics();
           int ascent = metrics.getAscent();
           int heightDiff = (metrics.getHeight() - ascent) / 2;
           g2.setColor(Color.BLACK);
           double tx = 2.0;
           double ty = 2.0 + heightDiff - size;
           g2.translate(tx, ty);
           for (int i = -size; i <= size; i++) {
               for (int j = -size; j <= size; j++) {
                   double distance = i * i + j * j;
                   float alpha = opacity;
                   if (distance > 0.0d) {
                       alpha = (float) (1.0f / ((distance * size) * opacity));
                   }
                   alpha *= preAlpha;
                   if (alpha > 1.0f) {
                       alpha = 1.0f;
                   }
                   g2.setComposite(AlphaComposite.SrcOver.derive(alpha));
                   g2.drawString(title, i + size, j + size + ascent);
               }
           }
           g2.setComposite(oldComposite);
           g2.setColor(Color.WHITE);
           g2.drawString(title, size, size + ascent);
           g2.translate(-tx, -ty);
       }
   }
   private class Locator extends MouseAdapter {
       private Point startPoint;
       @Override
       public void mousePressed(MouseEvent e) {
           startPoint = e.getPoint();
           SwingUtilities.convertPointToScreen(startPoint, (Component) e.getSource());
       }
       @Override
       public void mouseReleased(MouseEvent e) {
           VistaSearchDialog.this.setCursor(Cursor.getDefaultCursor());
       }
       @Override
       public void mouseDragged(MouseEvent e) {
           Point point = e.getPoint();
           SwingUtilities.convertPointToScreen(point, (Component) e.getSource());
           int distance_x = point.x - startPoint.x;
           int distance_y = point.y - startPoint.y;
           VistaSearchDialog.this.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
           Point location = VistaSearchDialog.this.getLocation();
           Point oldLocation = (Point) location.clone();
           location.x += distance_x;
           location.y += distance_y;
           VistaSearchDialog.this.setLocation(location);
           Rectangle clip = new Rectangle(oldLocation.x, oldLocation.y,
                                          VistaSearchDialog.this.getWidth(),
                                          VistaSearchDialog.this.getHeight());
           clip.intersects(new Rectangle(location.x, location.y,
                                         VistaSearchDialog.this.getWidth(),
                                         VistaSearchDialog.this.getHeight()));
           VistaSearchDialog.this.getParent().repaint(clip.x, clip.y,
                                                      clip.width, clip.height);
           startPoint = point;
       }
   }

} /*

* Copyright (c) 2007, Romain Guy
* 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 name of the TimingFramework project 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.
*/

/**

*
* @author Romain Guy
*/

class SearchPanel extends javax.swing.JPanel {

   /** Creates new form SearchPanel */
   public SearchPanel() {
       initComponents();
   }
   
   /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */
   // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
   private void initComponents() {
       java.awt.GridBagConstraints gridBagConstraints;
       jRadioButton2 = new javax.swing.JRadioButton();
       jLabel1 = new javax.swing.JLabel();
       jTextField1 = new javax.swing.JTextField();
       jButton1 = new javax.swing.JButton();
       jCheckBox1 = new javax.swing.JCheckBox();
       jLabel2 = new javax.swing.JLabel();
       jRadioButton1 = new javax.swing.JRadioButton();
       jButton2 = new javax.swing.JButton();
       jCheckBox2 = new javax.swing.JCheckBox();
       jRadioButton3 = new javax.swing.JRadioButton();
       jRadioButton2.setText("jRadioButton2");
       jRadioButton2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
       jRadioButton2.setMargin(new java.awt.Insets(0, 0, 0, 0));
       jLabel1.setText("Find what:");
       jTextField1.setColumns(15);
       jButton1.setText("Search Next");
       jButton1.setOpaque(false);
       jCheckBox1.setText("Match case");
       jCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
       jCheckBox1.setMargin(new java.awt.Insets(0, 0, 0, 0));
       jCheckBox1.setOpaque(false);
       jLabel2.setText("Direction:");
       jRadioButton1.setSelected(true);
       jRadioButton1.setText("Up");
       jRadioButton1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
       jRadioButton1.setMargin(new java.awt.Insets(0, 0, 0, 0));
       jRadioButton1.setOpaque(false);
       jButton2.setText("Cancel");
       jButton2.setOpaque(false);
       jButton2.setPreferredSize(new java.awt.Dimension(91, 23));
       jCheckBox2.setText("Wrap");
       jCheckBox2.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
       jCheckBox2.setMargin(new java.awt.Insets(0, 0, 0, 0));
       jCheckBox2.setOpaque(false);
       jRadioButton3.setText("Down");
       jRadioButton3.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
       jRadioButton3.setMargin(new java.awt.Insets(0, 0, 0, 0));
       jRadioButton3.setOpaque(false);
       org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
       this.setLayout(layout);
       layout.setHorizontalGroup(
           layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
           .add(layout.createSequentialGroup()
               .addContainerGap()
               .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                   .add(layout.createSequentialGroup()
                       .add(jLabel1)
                       .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                       .add(jTextField1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE)
                       .addContainerGap())
                   .add(layout.createSequentialGroup()
                       .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                           .add(layout.createSequentialGroup()
                               .add(jCheckBox1)
                               .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 26, Short.MAX_VALUE)
                               .add(jLabel2))
                           .add(jCheckBox2))
                       .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                       .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                           .add(jRadioButton3)
                           .add(jRadioButton1))
                       .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                       .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                           .add(org.jdesktop.layout.GroupLayout.TRAILING, jButton2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 75, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                           .add(org.jdesktop.layout.GroupLayout.TRAILING, jButton1))
                       .add(23, 23, 23))))
       );
       layout.linkSize(new java.awt.ruponent[] {jButton1, jButton2}, org.jdesktop.layout.GroupLayout.HORIZONTAL);
       layout.setVerticalGroup(
           layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
           .add(layout.createSequentialGroup()
               .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
               .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                   .add(jLabel1)
                   .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
               .add(8, 8, 8)
               .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                   .add(jButton1)
                   .add(jRadioButton1)
                   .add(jLabel2)
                   .add(jCheckBox1))
               .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
               .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                   .add(jButton2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 29, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                   .add(jRadioButton3)
                   .add(jCheckBox2))
               .addContainerGap())
       );
   }// </editor-fold>//GEN-END:initComponents
   
   
   // Variables declaration - do not modify//GEN-BEGIN:variables
   private javax.swing.JButton jButton1;
   private javax.swing.JButton jButton2;
   private javax.swing.JCheckBox jCheckBox1;
   private javax.swing.JCheckBox jCheckBox2;
   private javax.swing.JLabel jLabel1;
   private javax.swing.JLabel jLabel2;
   private javax.swing.JRadioButton jRadioButton1;
   private javax.swing.JRadioButton jRadioButton2;
   private javax.swing.JRadioButton jRadioButton3;
   private javax.swing.JTextField jTextField1;
   // End of variables declaration//GEN-END:variables
   

} /*

* Copyright (c) 2007, Romain Guy
* 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 name of the TimingFramework project 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.
*/

/**

*
* @author  Romain Guy <romain.guy@mac.ru>
*/
class DummyPanel extends javax.swing.JPanel {
   
   /** Creates new form DummyPanel */
   public DummyPanel() {
       initComponents();
   }
   
   /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */
   // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
   private void initComponents() {
       jLabel1 = new javax.swing.JLabel();
       jTextField1 = new javax.swing.JTextField();
       jScrollPane1 = new javax.swing.JScrollPane();
       jTable1 = new javax.swing.JTable();
       jScrollPane2 = new javax.swing.JScrollPane();
       jTree1 = new javax.swing.JTree();
       jScrollPane3 = new javax.swing.JScrollPane();
       jList1 = new javax.swing.JList();
       jScrollPane4 = new javax.swing.JScrollPane();
       jList2 = new javax.swing.JList();
       jLabel1.setText("Filter:");
       jTable1.setModel(new javax.swing.table.DefaultTableModel(
           new Object [][] {
               {null, null, null, null},
               {null, null, null, null},
               {null, null, null, null},
               {null, null, null, null}
           },
           new String [] {
               "Title 1", "Title 2", "Title 3", "Title 4"
           }
       ));
       jScrollPane1.setViewportView(jTable1);
       jScrollPane2.setViewportView(jTree1);
       jList1.setModel(new javax.swing.AbstractListModel() {
           String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
           public int getSize() { return strings.length; }
           public Object getElementAt(int i) { return strings[i]; }
       });
       jScrollPane3.setViewportView(jList1);
       jList2.setModel(new javax.swing.AbstractListModel() {
           String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
           public int getSize() { return strings.length; }
           public Object getElementAt(int i) { return strings[i]; }
       });
       jScrollPane4.setViewportView(jList2);
       javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
       this.setLayout(layout);
       layout.setHorizontalGroup(
           layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
           .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
               .addContainerGap()
               .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                   .addGroup(layout.createSequentialGroup()
                       .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 181, Short.MAX_VALUE)
                       .addPreferredGap(javax.swing.LayoutStyle.ruponentPlacement.RELATED)
                       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                           .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                               .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 165, javax.swing.GroupLayout.PREFERRED_SIZE)
                               .addPreferredGap(javax.swing.LayoutStyle.ruponentPlacement.RELATED)
                               .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 211, Short.MAX_VALUE))
                           .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE)))
                   .addGroup(layout.createSequentialGroup()
                       .addComponent(jLabel1)
                       .addPreferredGap(javax.swing.LayoutStyle.ruponentPlacement.RELATED)
                       .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 531, Short.MAX_VALUE)))
               .addContainerGap())
       );
       layout.setVerticalGroup(
           layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
           .addGroup(layout.createSequentialGroup()
               .addContainerGap()
               .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                   .addComponent(jLabel1)
                   .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
               .addPreferredGap(javax.swing.LayoutStyle.ruponentPlacement.RELATED)
               .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                   .addGroup(layout.createSequentialGroup()
                       .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
                       .addPreferredGap(javax.swing.LayoutStyle.ruponentPlacement.RELATED)
                       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                           .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE)
                           .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE)))
                   .addComponent(jScrollPane2))
               .addContainerGap())
       );
   }// </editor-fold>//GEN-END:initComponents
   
   
   // Variables declaration - do not modify//GEN-BEGIN:variables
   private javax.swing.JLabel jLabel1;
   private javax.swing.JList jList1;
   private javax.swing.JList jList2;
   private javax.swing.JScrollPane jScrollPane1;
   private javax.swing.JScrollPane jScrollPane2;
   private javax.swing.JScrollPane jScrollPane3;
   private javax.swing.JScrollPane jScrollPane4;
   private javax.swing.JTable jTable1;
   private javax.swing.JTextField jTextField1;
   private javax.swing.JTree jTree1;
   // End of variables declaration//GEN-END:variables
   

} /*

* $Id: GraphicsUtilities.java,v 1.1 2007/01/16 18:31:51 gfx Exp $
*
* Dual-licensed under LGPL (Sun and Romain Guy) and BSD (Romain Guy).
*
* Copyright 2005 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* Copyright (c) 2006 Romain Guy <romain.guy@mac.ru>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/

/**

*

GraphicsUtilities contains a set of tools to perform * common graphics operations easily. These operations are divided into * several themes, listed below.

*

Compatible Images

*

Compatible images can, and should, be used to increase drawing * performance. This class provides a number of methods to load compatible * images directly from files or to convert existing images to compatibles * images.

*

Creating Thumbnails

*

This class provides a number of methods to easily scale down images. * Some of these methods offer a trade-off between speed and result quality and * shouuld be used all the time. They also offer the advantage of producing * compatible images, thus automatically resulting into better runtime * performance.

*

All these methodes are both faster than * {@link java.awt.Image#getScaledInstance(int, int, int)} and produce * better-looking results than the various drawImage() methods * in {@link java.awt.Graphics}, which can be used for image scaling.

*

Image Manipulation

*

This class provides two methods to get and set pixels in a buffered image. * These methods try to avoid unmanaging the image in order to keep good * performance.

*
* @author Romain Guy <romain.guy@mac.ru>
*/

class GraphicsUtilities {

   private GraphicsUtilities() {
   }
   // Returns the graphics configuration for the primary screen
   private static GraphicsConfiguration getGraphicsConfiguration() {
       return GraphicsEnvironment.getLocalGraphicsEnvironment().
                   getDefaultScreenDevice().getDefaultConfiguration();
   }
   /**
*

Returns a new BufferedImage using the same color model * as the image passed as a parameter. The returned image is only compatible * with the image passed as a parameter. This does not mean the returned * image is compatible with the hardware.

    *
    * @param image the reference image from which the color model of the new
    *   image is obtained
    * @return a new BufferedImage, compatible with the color model
    *   of image
    */
   public static BufferedImage createColorModelCompatibleImage(BufferedImage image) {
       ColorModel cm = image.getColorModel();
       return new BufferedImage(cm,
           cm.createCompatibleWritableRaster(image.getWidth(),
                                             image.getHeight()),
           cm.isAlphaPremultiplied(), null);
   }
   /**
*

Returns a new compatible image with the same width, height and * transparency as the image specified as a parameter.

    *
    * @see java.awt.Transparency
    * @see #createCompatibleImage(int, int)
    * @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
    * @see #createCompatibleTranslucentImage(int, int)
    * @see #loadCompatibleImage(java.net.URL)
    * @see #toCompatibleImage(java.awt.image.BufferedImage)
    * @param image the reference image from which the dimension and the
    *   transparency of the new image are obtained
    * @return a new compatible BufferedImage with the same
    *   dimension and transparency as image
    */
   public static BufferedImage createCompatibleImage(BufferedImage image) {
       return createCompatibleImage(image, image.getWidth(), image.getHeight());
   }
   /**
*

Returns a new compatible image of the specified width and height, and * the same transparency setting as the image specified as a parameter.

    *
    * @see java.awt.Transparency
    * @see #createCompatibleImage(java.awt.image.BufferedImage)
    * @see #createCompatibleImage(int, int)
    * @see #createCompatibleTranslucentImage(int, int)
    * @see #loadCompatibleImage(java.net.URL)
    * @see #toCompatibleImage(java.awt.image.BufferedImage)
    * @param width the width of the new image
    * @param height the height of the new image
    * @param image the reference image from which the transparency of the new
    *   image is obtained
    * @return a new compatible BufferedImage with the same
    *   transparency as image and the specified dimension
    */
   public static BufferedImage createCompatibleImage(BufferedImage image,
                                                     int width, int height) {
       return getGraphicsConfiguration().createCompatibleImage(width, height,
                                                  image.getTransparency());
   }
   /**
*

Returns a new opaque compatible image of the specified width and * height.

    *
    * @see #createCompatibleImage(java.awt.image.BufferedImage)
    * @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
    * @see #createCompatibleTranslucentImage(int, int)
    * @see #loadCompatibleImage(java.net.URL)
    * @see #toCompatibleImage(java.awt.image.BufferedImage)
    * @param width the width of the new image
    * @param height the height of the new image
    * @return a new opaque compatible BufferedImage of the
    *   specified width and height
    */
   public static BufferedImage createCompatibleImage(int width, int height) {
       return getGraphicsConfiguration().createCompatibleImage(width, height);
   }
   /**
*

Returns a new translucent compatible image of the specified width * and height.

    *
    * @see #createCompatibleImage(java.awt.image.BufferedImage)
    * @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
    * @see #createCompatibleImage(int, int)
    * @see #loadCompatibleImage(java.net.URL)
    * @see #toCompatibleImage(java.awt.image.BufferedImage)
    * @param width the width of the new image
    * @param height the height of the new image
    * @return a new translucent compatible BufferedImage of the
    *   specified width and height
    */
   public static BufferedImage createCompatibleTranslucentImage(int width,
                                                                int height) {
       return getGraphicsConfiguration().createCompatibleImage(width, height,
                                                  Transparency.TRANSLUCENT);
   }
   /**
*

Returns a new compatible image from a URL. The image is loaded from the * specified location and then turned, if necessary into a compatible * image.

    *
    * @see #createCompatibleImage(java.awt.image.BufferedImage)
    * @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
    * @see #createCompatibleImage(int, int)
    * @see #createCompatibleTranslucentImage(int, int)
    * @see #toCompatibleImage(java.awt.image.BufferedImage)
    * @param resource the URL of the picture to load as a compatible image
    * @return a new translucent compatible BufferedImage of the
    *   specified width and height
    * @throws java.io.IOException if the image cannot be read or loaded
    */
   public static BufferedImage loadCompatibleImage(URL resource)
           throws IOException {
       BufferedImage image = ImageIO.read(resource);
       return toCompatibleImage(image);
   }
   /**
*

Return a new compatible image that contains a copy of the specified * image. This method ensures an image is compatible with the hardware, * and therefore optimized for fast blitting operations.

    *
    * @see #createCompatibleImage(java.awt.image.BufferedImage)
    * @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
    * @see #createCompatibleImage(int, int)
    * @see #createCompatibleTranslucentImage(int, int)
    * @see #loadCompatibleImage(java.net.URL)
    * @param image the image to copy into a new compatible image
    * @return a new compatible copy, with the
    *   same width and height and transparency and content, of image
    */
   public static BufferedImage toCompatibleImage(BufferedImage image) {
       if (image.getColorModel().equals(
               getGraphicsConfiguration().getColorModel())) {
           return image;
       }
       BufferedImage compatibleImage =
               getGraphicsConfiguration().createCompatibleImage(
                   image.getWidth(), image.getHeight(),
                   image.getTransparency());
       Graphics g = compatibleImage.getGraphics();
       g.drawImage(image, 0, 0, null);
       g.dispose();
       return compatibleImage;
   }
   /**
*

Returns a thumbnail of a source image. newSize defines * the length of the longest dimension of the thumbnail. The other * dimension is then computed according to the dimensions ratio of the * original picture.

*

This method favors speed over quality. When the new size is less than * half the longest dimension of the source image, * {@link #createThumbnail(BufferedImage, int)} or * {@link #createThumbnail(BufferedImage, int, int)} should be used instead * to ensure the quality of the result without sacrificing too much * performance.

    *
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int, int)
    * @see #createThumbnail(java.awt.image.BufferedImage, int)
    * @see #createThumbnail(java.awt.image.BufferedImage, int, int)
    * @param image the source image
    * @param newSize the length of the largest dimension of the thumbnail
    * @return a new compatible BufferedImage containing a
    *   thumbnail of image
    * @throws IllegalArgumentException if newSize is larger than
    *   the largest dimension of image or <= 0
    */
   public static BufferedImage createThumbnailFast(BufferedImage image,
                                                   int newSize) {
       float ratio;
       int width = image.getWidth();
       int height = image.getHeight();
       if (width > height) {
           if (newSize >= width) {
               throw new IllegalArgumentException("newSize must be lower than" +
                                                  " the image width");
           } else if (newSize <= 0) {
                throw new IllegalArgumentException("newSize must" +
                                                   " be greater than 0");
           }
           ratio = (float) width / (float) height;
           width = newSize;
           height = (int) (newSize / ratio);
       } else {
           if (newSize >= height) {
               throw new IllegalArgumentException("newSize must be lower than" +
                                                  " the image height");
           } else if (newSize <= 0) {
                throw new IllegalArgumentException("newSize must" +
                                                   " be greater than 0");
           }
           ratio = (float) height / (float) width;
           height = newSize;
           width = (int) (newSize / ratio);
       }
       BufferedImage temp = createCompatibleImage(image, width, height);
       Graphics2D g2 = temp.createGraphics();
       g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                           RenderingHints.VALUE_INTERPOLATION_BILINEAR);
       g2.drawImage(image, 0, 0, temp.getWidth(), temp.getHeight(), null);
       g2.dispose();
       return temp;
   }
   /**
*

Returns a thumbnail of a source image.

*

This method favors speed over quality. When the new size is less than * half the longest dimension of the source image, * {@link #createThumbnail(BufferedImage, int)} or * {@link #createThumbnail(BufferedImage, int, int)} should be used instead * to ensure the quality of the result without sacrificing too much * performance.

    *
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int)
    * @see #createThumbnail(java.awt.image.BufferedImage, int)
    * @see #createThumbnail(java.awt.image.BufferedImage, int, int)
    * @param image the source image
    * @param newWidth the width of the thumbnail
    * @param newHeight the height of the thumbnail
    * @return a new compatible BufferedImage containing a
    *   thumbnail of image
    * @throws IllegalArgumentException if newWidth is larger than
    *   the width of image or if code>newHeight</code> is larger
    *   than the height of image or if one of the dimensions
    *   is <= 0
    */
   public static BufferedImage createThumbnailFast(BufferedImage image,
                                                   int newWidth, int newHeight) {
       if (newWidth >= image.getWidth() ||
           newHeight >= image.getHeight()) {
           throw new IllegalArgumentException("newWidth and newHeight cannot" +
                                              " be greater than the image" +
                                              " dimensions");
       } else if (newWidth <= 0 || newHeight <= 0) {
           throw new IllegalArgumentException("newWidth and newHeight must" +
                                              " be greater than 0");
       }
       BufferedImage temp = createCompatibleImage(image, newWidth, newHeight);
       Graphics2D g2 = temp.createGraphics();
       g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                           RenderingHints.VALUE_INTERPOLATION_BILINEAR);
       g2.drawImage(image, 0, 0, temp.getWidth(), temp.getHeight(), null);
       g2.dispose();
       return temp;
   }
   /**
*

Returns a thumbnail of a source image. newSize defines * the length of the longest dimension of the thumbnail. The other * dimension is then computed according to the dimensions ratio of the * original picture.

*

This method offers a good trade-off between speed and quality. * The result looks better than * {@link #createThumbnailFast(java.awt.image.BufferedImage, int)} when * the new size is less than half the longest dimension of the source * image, yet the rendering speed is almost similar.

    *
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int, int)
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int)
    * @see #createThumbnail(java.awt.image.BufferedImage, int, int)
    * @param image the source image
    * @param newSize the length of the largest dimension of the thumbnail
    * @return a new compatible BufferedImage containing a
    *   thumbnail of image
    * @throws IllegalArgumentException if newSize is larger than
    *   the largest dimension of image or <= 0
    */
   public static BufferedImage createThumbnail(BufferedImage image,
                                               int newSize) {
       int width = image.getWidth();
       int height = image.getHeight();
       boolean isWidthGreater = width > height;
       if (isWidthGreater) {
           if (newSize >= width) {
               throw new IllegalArgumentException("newSize must be lower than" +
                                                  " the image width");
           }
       } else if (newSize >= height) {
           throw new IllegalArgumentException("newSize must be lower than" +
                                              " the image height");
       }
       if (newSize <= 0) {
           throw new IllegalArgumentException("newSize must" +
                                              " be greater than 0");
       }
       float ratioWH = (float) width / (float) height;
       float ratioHW = (float) height / (float) width;
       BufferedImage thumb = image;
       do {
           if (isWidthGreater) {
               width /= 2;
               if (width < newSize) {
                   width = newSize;
               }
               height = (int) (width / ratioWH);
           } else {
               height /= 2;
               if (height < newSize) {
                   height = newSize;
               }
               width = (int) (height / ratioHW);
           }
           BufferedImage temp = createCompatibleImage(image, width, height);
           Graphics2D g2 = temp.createGraphics();
           g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                               RenderingHints.VALUE_INTERPOLATION_BILINEAR);
           g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
           g2.dispose();
           thumb = temp;
       } while (newSize != (isWidthGreater ? width : height));
       return thumb;
   }
   /**
*

Returns a thumbnail of a source image.

*

This method offers a good trade-off between speed and quality. * The result looks better than * {@link #createThumbnailFast(java.awt.image.BufferedImage, int)} when * the new size is less than half the longest dimension of the source * image, yet the rendering speed is almost similar.

    *
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int)
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int, int)
    * @see #createThumbnail(java.awt.image.BufferedImage, int)
    * @param image the source image
    * @param newWidth the width of the thumbnail
    * @param newHeight the height of the thumbnail
    * @return a new compatible BufferedImage containing a
    *   thumbnail of image
    * @throws IllegalArgumentException if newWidth is larger than
    *   the width of image or if code>newHeight</code> is larger
    *   than the height of image or if one the dimensions is not > 0
    */
   public static BufferedImage createThumbnail(BufferedImage image,
                                               int newWidth, int newHeight) {
       int width = image.getWidth();
       int height = image.getHeight();
       if (newWidth >= width || newHeight >= height) {
           throw new IllegalArgumentException("newWidth and newHeight cannot" +
                                              " be greater than the image" +
                                              " dimensions");
       } else if (newWidth <= 0 || newHeight <= 0) {
           throw new IllegalArgumentException("newWidth and newHeight must" +
                                              " be greater than 0");
       }
       BufferedImage thumb = image;
       do {
           if (width > newWidth) {
               width /= 2;
               if (width < newWidth) {
                   width = newWidth;
               }
           }
           if (height > newHeight) {
               height /= 2;
               if (height < newHeight) {
                   height = newHeight;
               }
           }
           BufferedImage temp = createCompatibleImage(image, width, height);
           Graphics2D g2 = temp.createGraphics();
           g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                               RenderingHints.VALUE_INTERPOLATION_BILINEAR);
           g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
           g2.dispose();
           thumb = temp;
       } while (width != newWidth || height != newHeight);
       return thumb;
   }
   /**
*

Returns an array of pixels, stored as integers, from a * BufferedImage. The pixels are grabbed from a rectangular * area defined by a location and two dimensions. Calling this method on * an image of type different from BufferedImage.TYPE_INT_ARGB * and BufferedImage.TYPE_INT_RGB will unmanage the image.

    *
    * @param img the source image
    * @param x the x location at which to start grabbing pixels
    * @param y the y location at which to start grabbing pixels
    * @param w the width of the rectangle of pixels to grab
    * @param h the height of the rectangle of pixels to grab
    * @param pixels a pre-allocated array of pixels of size w*h; can be null
    * @return pixels if non-null, a new array of integers
    *   otherwise
    * @throws IllegalArgumentException is pixels is non-null and
    *   of length < w*h
    */
   public static int[] getPixels(BufferedImage img,
                                 int x, int y, int w, int h, int[] pixels) {
       if (w == 0 || h == 0) {
           return new int[0];
       }
       if (pixels == null) {
           pixels = new int[w * h];
       } else if (pixels.length < w * h) {
           throw new IllegalArgumentException("pixels array must have a length" +
                                              " >= w*h");
       }
       int imageType = img.getType();
       if (imageType == BufferedImage.TYPE_INT_ARGB ||
           imageType == BufferedImage.TYPE_INT_RGB) {
           Raster raster = img.getRaster();
           return (int[]) raster.getDataElements(x, y, w, h, pixels);
       }
       // Unmanages the image
       return img.getRGB(x, y, w, h, pixels, 0, w);
   }
   /**
*

Writes a rectangular area of pixels in the destination * BufferedImage. Calling this method on * an image of type different from BufferedImage.TYPE_INT_ARGB * and BufferedImage.TYPE_INT_RGB will unmanage the image.

    *
    * @param img the destination image
    * @param x the x location at which to start storing pixels
    * @param y the y location at which to start storing pixels
    * @param w the width of the rectangle of pixels to store
    * @param h the height of the rectangle of pixels to store
    * @param pixels an array of pixels, stored as integers
    * @throws IllegalArgumentException is pixels is non-null and
    *   of length < w*h
    */
   public static void setPixels(BufferedImage img,
                                int x, int y, int w, int h, int[] pixels) {
       if (pixels == null || w == 0 || h == 0) {
           return;
       } else if (pixels.length < w * h) {
           throw new IllegalArgumentException("pixels array must have a length" +
                                              " >= w*h");
       }
       int imageType = img.getType();
       if (imageType == BufferedImage.TYPE_INT_ARGB ||
           imageType == BufferedImage.TYPE_INT_RGB) {
           WritableRaster raster = img.getRaster();
           raster.setDataElements(x, y, w, h, pixels);
       } else {
           // Unmanages the image
           img.setRGB(x, y, w, h, pixels, 0, w);
       }
   }

} /*

* $Id: AbstractFilter.java,v 1.1 2007/01/16 18:31:50 gfx Exp $
*
* Dual-licensed under LGPL (Sun and Romain Guy) and BSD (Romain Guy).
*
* Copyright 2005 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* Copyright (c) 2006 Romain Guy <romain.guy@mac.ru>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/

/**

*

Provides an abstract implementation of the BufferedImageOp * interface. This class can be used to created new image filters based * on BufferedImageOp.

*
* @author Romain Guy <romain.guy@mac.ru>
*/
abstract class AbstractFilter implements BufferedImageOp {
   public abstract BufferedImage filter(BufferedImage src, BufferedImage dest);
   /**
    * {@inheritDoc}
    */
   public Rectangle2D getBounds2D(BufferedImage src) {
       return new Rectangle(0, 0, src.getWidth(), src.getHeight());
   }
   /**
    * {@inheritDoc}
    */
   public BufferedImage createCompatibleDestImage(BufferedImage src,
                                                  ColorModel destCM) {
       if (destCM == null) {
           destCM = src.getColorModel();
       }
       return new BufferedImage(destCM,
                                destCM.createCompatibleWritableRaster(
                                        src.getWidth(), src.getHeight()),
                                destCM.isAlphaPremultiplied(), null);
   }
   /**
    * {@inheritDoc}
    */
   public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
       return (Point2D) srcPt.clone();
   }
   /**
    * {@inheritDoc}
    */
   public RenderingHints getRenderingHints() {
       return null;
   }

} /*

* $Id: ColorTintFilter.java,v 1.2 2007/01/28 01:45:47 gfx Exp $
*
* Dual-licensed under LGPL (Sun and Romain Guy) and BSD (Romain Guy).
*
* Copyright 2005 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* Copyright (c) 2006 Romain Guy <romain.guy@mac.ru>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/

/**

*

A color tint filter can be used to mix a solid color to an image. The * result is an image tinted by the specified color. The force of the effect * can be controlled with the mixValue, a number between 0.0 and * 1.0 that can be seen as the percentage of the mix (0.0 does not affect the * source image and 1.0 replaces all the pixels by the solid color).

*

The color of the pixels in the resulting image is computed as follows:

*
 * cR = cS * (1 - mixValue) + cM * mixValue
 * 
*

Definition of the parameters:

*
    *
  • cR: color of the resulting pixel
  • *
  • cS: color of the source pixel
  • *
  • cM: the solid color to mix with the source image
  • *
  • mixValue: strength of the mix, a value between 0.0 and 1.0
  • *
*
* @author Romain Guy <romain.guy@mac.ru>
*/

class ColorTintFilter extends AbstractFilter {

   private final Color mixColor;
   private final float mixValue;
   private int[] preMultipliedRed;
   private int[] preMultipliedGreen;
   private int[] preMultipliedBlue;
   /**
*

Creates a new color mixer filter. The specified color will be used * to tint the source image, with a mixing strength defined by * mixValue.

    *
    * @param mixColor the solid color to mix with the source image
    * @param mixValue the strength of the mix, between 0.0 and 1.0; if the
    *   specified value lies outside this range, it is clamped
    * @throws IllegalArgumentException if mixColor is null
    */
   public ColorTintFilter(Color mixColor, float mixValue) {
       if (mixColor == null) {
           throw new IllegalArgumentException("mixColor cannot be null");
       }
       this.mixColor = mixColor;
       if (mixValue < 0.0f) {
           mixValue = 0.0f;
       } else if (mixValue > 1.0f) {
           mixValue = 1.0f;
       }
       this.mixValue = mixValue;
       
       int mix_r = (int) (mixColor.getRed()   * mixValue);
       int mix_g = (int) (mixColor.getGreen() * mixValue);
       int mix_b = (int) (mixColor.getBlue()  * mixValue);
       
       // Since we use only lookup tables to apply the filter, this filter
       // could be implemented as a LookupOp.
       float factor = 1.0f - mixValue;
       preMultipliedRed   = new int[256];
       preMultipliedGreen = new int[256];
       preMultipliedBlue  = new int[256];
       for (int i = 0; i < 256; i++) {
           int value = (int) (i * factor);
           preMultipliedRed[i]   = value + mix_r;
           preMultipliedGreen[i] = value + mix_g;
           preMultipliedBlue[i]  = value + mix_b;
       }
   }
   /**
*

Returns the mix value of this filter.

    *
    * @return the mix value, between 0.0 and 1.0
    */
   public float getMixValue() {
       return mixValue;
   }
   /**
*

Returns the solid mix color of this filter.

    *
    * @return the solid color used for mixing
    */
   public Color getMixColor() {
       return mixColor;
   }
   /**
    * {@inheritDoc}
    */
   @Override
   public BufferedImage filter(BufferedImage src, BufferedImage dst) {
       if (dst == null) {
           dst = createCompatibleDestImage(src, null);
       }
       int width = src.getWidth();
       int height = src.getHeight();
       int[] pixels = new int[width * height];
       GraphicsUtilities.getPixels(src, 0, 0, width, height, pixels);
       mixColor(pixels);
       GraphicsUtilities.setPixels(dst, 0, 0, width, height, pixels);
       return dst;
   }
   private void mixColor(int[] pixels) {
       for (int i = 0; i < pixels.length; i++) {
           int argb = pixels[i];
           pixels[i] = (argb & 0xFF000000) |
                       preMultipliedRed[(argb >> 16)   & 0xFF] << 16 |
                       preMultipliedGreen[(argb >> 8)  & 0xFF] <<  8 |
                       preMultipliedBlue[argb & 0xFF];
       }
   }

} /*

* $Id: DropShadowBorder.java,v 1.1 2007/01/16 18:31:49 gfx Exp $
*
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* 
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/**

* Implements a DropShadow for components. In general, the DropShadowBorder will
* work with any rectangular components that do not have a default border installed
* as part of the look and feel, or otherwise. For example, DropShadowBorder works
* wonderfully with JPanel, but horribly with JComboBox.
*
* @author rbair
*/

class DropShadowBorder implements Border {

   private static enum Position {TOP, TOP_LEFT, LEFT, BOTTOM_LEFT,
                   BOTTOM, BOTTOM_RIGHT, RIGHT, TOP_RIGHT};
                   
   private static final Map<Integer,Map<Position,BufferedImage>> CACHE 
           = new HashMap<Integer,Map<Position,BufferedImage>>();
                       
   private final Color lineColor;
   private final int lineWidth;
   private final int shadowSize;
   private final float shadowOpacity;
   private final int cornerSize;
   private final boolean showTopShadow;
   private final boolean showLeftShadow;
   private final boolean showBottomShadow;
   private final boolean showRightShadow;
   
   public DropShadowBorder() {
       this(UIManager.getColor("Control"), 1, 5);
   }
   
   public DropShadowBorder(Color lineColor, int lineWidth, int shadowSize) {
       this(lineColor, lineWidth, shadowSize, .5f, 12, false, false, true, true);
   }
   
   public DropShadowBorder(Color lineColor, int lineWidth, boolean showLeftShadow) {
       this(lineColor, lineWidth, 5, .5f, 12, false, showLeftShadow, true, true);
   }
   
   public DropShadowBorder(Color lineColor, int lineWidth, int shadowSize,
           float shadowOpacity, int cornerSize, boolean showTopShadow,
           boolean showLeftShadow, boolean showBottomShadow, boolean showRightShadow) {
       this.lineColor = lineColor;
       this.lineWidth = lineWidth;
       this.shadowSize = shadowSize;
       this.shadowOpacity = shadowOpacity;
       this.cornerSize = cornerSize;
       this.showTopShadow = showTopShadow;
       this.showLeftShadow = showLeftShadow;
       this.showBottomShadow = showBottomShadow;
       this.showRightShadow = showRightShadow;
   }
   
   /**
    * @inheritDoc
    */
   public void paintBorder(Component c, Graphics graphics, int x, int y, int width, int height) {
       /*
        * 1) Get images for this border
        * 2) Paint the images for each side of the border that should be painted
        */
        Map<Position,BufferedImage> images = getImages((Graphics2D)graphics);
       
       //compute the edges of the component -- not including the border

// Insets borderInsets = getBorderInsets(c); // int leftEdge = x + borderInsets.left; // int rightEdge = x + width - borderInsets.right; // int topEdge = y + borderInsets.top; // int bottomEdge = y + height - borderInsets.bottom;

       Graphics2D g2 = (Graphics2D)graphics.create();
       g2.setColor(lineColor);
       
       //The location and size of the shadows depends on which shadows are being
       //drawn. For instance, if the left & bottom shadows are being drawn, then
       //the left shadow extends all the way down to the corner, a corner is drawn,
       //and then the bottom shadow begins at the corner. If, however, only the
       //bottom shadow is drawn, then the bottom-left corner is drawn to the
       //right of the corner, and the bottom shadow is somewhat shorter than before.
       
       Point topLeftShadowPoint = null;
       if (showLeftShadow || showTopShadow) {
           topLeftShadowPoint = new Point();
           if (showLeftShadow && !showTopShadow) {
               topLeftShadowPoint.setLocation(x, y + shadowSize);
           } else if (showLeftShadow && showTopShadow) {
               topLeftShadowPoint.setLocation(x, y);
           } else if (!showLeftShadow && showTopShadow) {
               topLeftShadowPoint.setLocation(x + shadowSize, y);
           }
       }
 
       Point bottomLeftShadowPoint = null;
       if (showLeftShadow || showBottomShadow) {
           bottomLeftShadowPoint = new Point();
           if (showLeftShadow && !showBottomShadow) {
               bottomLeftShadowPoint.setLocation(x, y + height - shadowSize - shadowSize);
           } else if (showLeftShadow && showBottomShadow) {
               bottomLeftShadowPoint.setLocation(x, y + height - shadowSize);
           } else if (!showLeftShadow && showBottomShadow) {
               bottomLeftShadowPoint.setLocation(x + shadowSize, y + height - shadowSize);
           }
       }
       
       Point bottomRightShadowPoint = null;
       if (showRightShadow || showBottomShadow) {
           bottomRightShadowPoint = new Point();
           if (showRightShadow && !showBottomShadow) {
               bottomRightShadowPoint.setLocation(x + width - shadowSize, y + height - shadowSize - shadowSize);
           } else if (showRightShadow && showBottomShadow) {
               bottomRightShadowPoint.setLocation(x + width - shadowSize, y + height - shadowSize);
           } else if (!showRightShadow && showBottomShadow) {
               bottomRightShadowPoint.setLocation(x + width - shadowSize - shadowSize, y + height - shadowSize);
           }
       }
       
       Point topRightShadowPoint = null;
       if (showRightShadow || showTopShadow) {
           topRightShadowPoint = new Point();
           if (showRightShadow && !showTopShadow) {
               topRightShadowPoint.setLocation(x + width - shadowSize, y + shadowSize);
           } else if (showRightShadow && showTopShadow) {
               topRightShadowPoint.setLocation(x + width - shadowSize, y);
           } else if (!showRightShadow && showTopShadow) {
               topRightShadowPoint.setLocation(x + width - shadowSize - shadowSize, y);
           }
       }

       g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                           RenderingHints.VALUE_INTERPOLATION_BILINEAR);
       g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                           RenderingHints.VALUE_RENDER_SPEED);
       
       if (showLeftShadow) {
           Rectangle leftShadowRect =
               new Rectangle(x,
                             topLeftShadowPoint.y + shadowSize,
                             shadowSize,
                             bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize);
           g2.drawImage(images.get(Position.LEFT),
                        leftShadowRect.x, leftShadowRect.y,
                        leftShadowRect.width, leftShadowRect.height, null);
       }
       if (showBottomShadow) {
           Rectangle bottomShadowRect =
               new Rectangle(bottomLeftShadowPoint.x + shadowSize,
                             y + height - shadowSize,
                             bottomRightShadowPoint.x - bottomLeftShadowPoint.x - shadowSize,
                             shadowSize);
           g2.drawImage(images.get(Position.BOTTOM),
                        bottomShadowRect.x, bottomShadowRect.y,
                        bottomShadowRect.width, bottomShadowRect.height, null);
       }
       
       if (showRightShadow) {
           Rectangle rightShadowRect =
               new Rectangle(x + width - shadowSize,
                             topRightShadowPoint.y + shadowSize,
                             shadowSize,
                             bottomRightShadowPoint.y - topRightShadowPoint.y - shadowSize);
           g2.drawImage(images.get(Position.RIGHT),
                        rightShadowRect.x, rightShadowRect.y,
                        rightShadowRect.width, rightShadowRect.height, null);
       }
       
       if (showTopShadow) {
           Rectangle topShadowRect =
               new Rectangle(topLeftShadowPoint.x + shadowSize,
                             y,
                             topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize,
                             shadowSize);
           g2.drawImage(images.get(Position.TOP),
                        topShadowRect.x, topShadowRect.y,
                        topShadowRect.width, topShadowRect.height, null);
       }
       
       if (showLeftShadow || showTopShadow) {
           g2.drawImage(images.get(Position.TOP_LEFT),
                        topLeftShadowPoint.x, topLeftShadowPoint.y, null);
       }
       if (showLeftShadow || showBottomShadow) {
           g2.drawImage(images.get(Position.BOTTOM_LEFT),
                        bottomLeftShadowPoint.x, bottomLeftShadowPoint.y, null);
       }
       if (showRightShadow || showBottomShadow) {
           g2.drawImage(images.get(Position.BOTTOM_RIGHT),
                        bottomRightShadowPoint.x, bottomRightShadowPoint.y, null);
       }
       if (showRightShadow || showTopShadow) {
           g2.drawImage(images.get(Position.TOP_RIGHT),
                        topRightShadowPoint.x, topRightShadowPoint.y, null);
       }
       
       g2.dispose();
   }
   
   private Map<Position,BufferedImage> getImages(Graphics2D g2) {
       //first, check to see if an image for this size has already been rendered
       //if so, use the cache. Else, draw and save
       Map<Position,BufferedImage> images = CACHE.get(shadowSize);
       if (images == null) {
           images = new HashMap<Position,BufferedImage>();
           /*
            * Do draw a drop shadow, I have to:
            *  1) Create a rounded rectangle
            *  2) Create a BufferedImage to draw the rounded rect in
            *  3) Translate the graphics for the image, so that the rectangle
            *     is centered in the drawn space. The border around the rectangle
            *     needs to be shadowWidth wide, so that there is space for the
            *     shadow to be drawn.
            *  4) Draw the rounded rect as black, with an opacity of 50%
            *  5) Create the BLUR_KERNEL
            *  6) Blur the image
            *  7) copy off the corners, sides, etc into images to be used for
            *     drawing the Border
            */
           int rectWidth = cornerSize + 1;
           RoundRectangle2D rect = new RoundRectangle2D.Double(0, 0, rectWidth, rectWidth, cornerSize, cornerSize);
           int imageWidth = rectWidth + shadowSize * 2;
           BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(imageWidth, imageWidth);
           Graphics2D buffer = (Graphics2D)image.getGraphics();
           buffer.setColor(new Color(0.0f, 0.0f, 0.0f, shadowOpacity));
           buffer.translate(shadowSize, shadowSize);
           buffer.fill(rect);
           buffer.dispose();
           
           float blurry = 1.0f / (float)(shadowSize * shadowSize);
           float[] blurKernel = new float[shadowSize * shadowSize];
           for (int i=0; i<blurKernel.length; i++) {
               blurKernel[i] = blurry;
           }
           ConvolveOp blur = new ConvolveOp(new Kernel(shadowSize, shadowSize, blurKernel));
           BufferedImage targetImage = GraphicsUtilities.createCompatibleTranslucentImage(imageWidth, imageWidth);
           ((Graphics2D)targetImage.getGraphics()).drawImage(image, blur, -(shadowSize/2), -(shadowSize/2));
           int x = 1;
           int y = 1;
           int w = shadowSize;
           int h = shadowSize;
           images.put(Position.TOP_LEFT, getSubImage(targetImage, x, y, w, h));
           x = 1;
           y = h;
           w = shadowSize;
           h = 1;
           images.put(Position.LEFT, getSubImage(targetImage, x, y, w, h));
           x = 1;
           y = rectWidth;
           w = shadowSize;
           h = shadowSize;
           images.put(Position.BOTTOM_LEFT, getSubImage(targetImage, x, y, w, h));
           x = cornerSize + 1;
           y = rectWidth;
           w = 1;
           h = shadowSize;
           images.put(Position.BOTTOM, getSubImage(targetImage, x, y, w, h));
           x = rectWidth;
           y = x;
           w = shadowSize;
           h = shadowSize;
           images.put(Position.BOTTOM_RIGHT, getSubImage(targetImage, x, y, w, h));
           x = rectWidth;
           y = cornerSize + 1;
           w = shadowSize;
           h = 1;
           images.put(Position.RIGHT, getSubImage(targetImage, x, y, w, h));
           x = rectWidth;
           y = 1;
           w = shadowSize;
           h = shadowSize;
           images.put(Position.TOP_RIGHT, getSubImage(targetImage, x, y, w, h));
           x = shadowSize;
           y = 1;
           w = 1;
           h = shadowSize;
           images.put(Position.TOP, getSubImage(targetImage, x, y, w, h));
           image.flush();
           CACHE.put(shadowSize, images);
       }
       return images;
   }
   
   /**
    * Returns a new BufferedImage that represents a subregion of the given
    * BufferedImage.  (Note that this method does not use
    * BufferedImage.getSubimage(), which will defeat image acceleration
    * strategies on later JDKs.)
    */
   private BufferedImage getSubImage(BufferedImage img,
                                     int x, int y, int w, int h) {
       BufferedImage ret = GraphicsUtilities.createCompatibleTranslucentImage(w, h);
       Graphics2D g2 = ret.createGraphics();
       g2.drawImage(img,
                    0, 0, w, h,
                    x, y, x+w, y+h,
                    null);
       g2.dispose();
       return ret;
   }
   
   /**
    * @inheritDoc
    */
   public Insets getBorderInsets(Component c) {
       int top = showTopShadow ? lineWidth + shadowSize : lineWidth;
       int left = showLeftShadow ? lineWidth + shadowSize : lineWidth;
       int bottom = showBottomShadow ? lineWidth + shadowSize : lineWidth;
       int right = showRightShadow ? lineWidth + shadowSize : lineWidth;
       return new Insets(top, left, bottom, right);
   }
   
   /**
    * @inheritDoc
    */
   public boolean isBorderOpaque() {
       return false;
   }
   
   public boolean isShowTopShadow() {
       return showTopShadow;
   }
   
   public boolean isShowLeftShadow() {
       return showLeftShadow;
   }
   
   public boolean isShowRightShadow() {
       return showRightShadow;
   }
   
   public boolean isShowBottomShadow() {
       return showBottomShadow;
   }
   
   public int getLineWidth() {
       return lineWidth;
   }
   
   public Color getLineColor() {
       return lineColor;
   }
   
   public int getShadowSize() {
       return shadowSize;
   }
   
   public float getShadowOpacity() {
       return shadowOpacity;
   }
   
   public int getCornerSize() {
       return cornerSize;
   }

}



 </source>