[llvm-commits] [llvm-gcc-4.2] r43913 [49/80] - in /llvm-gcc-4.2/trunk: boehm-gc/ boehm-gc/Mac_files/ boehm-gc/cord/ boehm-gc/doc/ boehm-gc/include/ boehm-gc/include/private/ boehm-gc/tests/ libffi/ libffi/include/ libffi/src/ libffi/src/alpha/ libffi/src/arm/ libffi/src/cris/ libffi/src/frv/ libffi/src/ia64/ libffi/src/m32r/ libffi/src/m68k/ libffi/src/mips/ libffi/src/pa/ libffi/src/powerpc/ libffi/src/s390/ libffi/src/sh/ libffi/src/sh64/ libffi/src/sparc/ libffi/src/x86/ libffi/testsuite/ libffi/testsuite/config/ li...

Bill Wendling isanbard at gmail.com
Thu Nov 8 14:57:11 PST 2007


Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFileChooser.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFileChooser.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFileChooser.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFileChooser.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1624 @@
+/* JFileChooser.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.beans.PropertyChangeEvent;
+import java.io.File;
+import java.util.ArrayList;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.filechooser.FileSystemView;
+import javax.swing.filechooser.FileView;
+import javax.swing.plaf.FileChooserUI;
+
+
+/**
+ * A component that provides the user a dialog box to browse through a
+ * filesystem and choose one or more files or directories.
+ *
+ * A JFileChooser can be configured to filter the displayed file list
+ * by adding a {@link FileFilter} instance using
+ * {@link #addChoosableFileFilter(FileFilter)}. Additional components can
+ * be embedded in the file chooser using {@link #setAccessory(JComponent)}.
+ * The JFileChooser properties also provide mechanisms to customize the
+ * behaviour of the file chooser.
+ *
+ * @author Kim Ho (kho at luxsci.net)
+ */
+public class JFileChooser extends JComponent implements Accessible
+{
+  private static final long serialVersionUID = 3162921138695327837L;
+
+  /** 
+   * A dialog type for selecting a file to open. 
+   * @see #setDialogType(int)
+   */
+  public static final int OPEN_DIALOG = 0;
+
+  /** 
+   * A dialog type for selecting a file to save.  
+   * @see #setDialogType(int)
+   */
+  public static final int SAVE_DIALOG = 1;
+
+  /** 
+   * A dialog type for some custom purpose.
+   * @see #setDialogType(int)
+   */
+  public static final int CUSTOM_DIALOG = 2;
+
+  /** 
+   * A return value indicating the file chooser has been closed by cancelling.
+   * 
+   * @see #showOpenDialog(Component)
+   * @see #showSaveDialog(Component) 
+   */
+  public static final int CANCEL_OPTION = 1;
+
+  /** 
+   * A return value indicating the file chooser has been closed by approving
+   * the selection.
+   * @see #showOpenDialog(Component)
+   * @see #showSaveDialog(Component) 
+   */
+  public static final int APPROVE_OPTION = 0;
+
+  /** 
+   * A return value indicating the file chooser has been closed by some error.
+   * @see #showOpenDialog(Component)
+   * @see #showSaveDialog(Component) 
+   */
+  public static final int ERROR_OPTION = -1;
+
+  /** 
+   * A selection mode constant indicating acceptance of files only.
+   * @see #setFileSelectionMode(int)
+   */
+  public static final int FILES_ONLY = 0;
+
+  /** 
+   * A selection mode constant indicating acceptance of directories only. 
+   * @see #setFileSelectionMode(int)
+   */
+  public static final int DIRECTORIES_ONLY = 1;
+
+  /** 
+   * A selection mode constant indicating acceptance of files and directories.
+   * @see #setFileSelectionMode(int)
+   */
+  public static final int FILES_AND_DIRECTORIES = 2;
+
+  /** 
+   * Action command string for cancelling the current selection.
+   * @see #cancelSelection()
+   */
+  public static final String CANCEL_SELECTION = "CancelSelection";
+
+  /** 
+   * Action command string for approving the current selection.
+   * @see #cancelSelection()
+   */
+  public static final String APPROVE_SELECTION = "ApproveSelection";
+
+  /**
+   * The name of the property for the approve button text.
+   * @see #setApproveButtonText(String) 
+   */
+  public static final String APPROVE_BUTTON_TEXT_CHANGED_PROPERTY =
+    "ApproveButtonTextChangedProperty";
+
+  /**
+   * The name of the property for the approve button tool tip text.
+   * @see #setApproveButtonToolTipText(String)
+   */
+  public static final String APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY =
+    "ApproveButtonToolTipTextChangedProperty";
+
+  /**
+   * The name of the property for the approve button mnemonic.
+   * @see #setApproveButtonMnemonic(int)
+   */
+  public static final String APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY =
+    "ApproveButtonMnemonicChangedProperty";
+
+  /**
+   * The name of the property for control button visibility.
+   * @see #setControlButtonsAreShown(boolean)
+   */
+  public static final String CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY =
+    "ControlButtonsAreShownChangedProperty";
+
+  /**
+   * The name of the property for the current directory.
+   * @see #setCurrentDirectory(File)  
+   */
+  public static final String DIRECTORY_CHANGED_PROPERTY = "directoryChanged";
+
+  /**
+   * The name of the property for the selected file.
+   * @see #setSelectedFile(File)
+   */
+  public static final String SELECTED_FILE_CHANGED_PROPERTY =
+    "SelectedFileChangedProperty";
+
+  /**
+   * The name of the property for the selected files.
+   * @see #setSelectedFiles(File[])
+   */
+  public static final String SELECTED_FILES_CHANGED_PROPERTY =
+    "SelectedFilesChangedProperty";
+
+  /** 
+   * The name of the property for multi-selection.
+   * @see #setMultiSelectionEnabled(boolean) 
+   */
+  public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY =
+    "MultiSelectionEnabledChangedProperty";
+
+  /**
+   * The name of the 'file system view' property.
+   * @see #setFileSystemView(FileSystemView) 
+   */
+  public static final String FILE_SYSTEM_VIEW_CHANGED_PROPERTY =
+    "FileSystemViewChanged";
+
+  /**
+   * The name of the 'file view' property.
+   * @see #setFileView(FileView) 
+   */
+  public static final String FILE_VIEW_CHANGED_PROPERTY = "fileViewChanged";
+
+  /**
+   * The name of the 'file hiding enabled' property.
+   * @see #setFileHidingEnabled(boolean)
+   */
+  public static final String FILE_HIDING_CHANGED_PROPERTY =
+    "FileHidingChanged";
+
+  /**
+   * The name of the 'file filter' property.
+   * @see #setFileFilter(FileFilter)
+   */
+  public static final String FILE_FILTER_CHANGED_PROPERTY =
+    "fileFilterChanged";
+
+  /**
+   * The name of the 'file selection mode' property.
+   * @see #setFileSelectionMode(int)
+   */
+  public static final String FILE_SELECTION_MODE_CHANGED_PROPERTY =
+    "fileSelectionChanged";
+
+  /**
+   * The name of the 'accessory' property.
+   * @see #setAccessory(JComponent)
+   */
+  public static final String ACCESSORY_CHANGED_PROPERTY =
+    "AccessoryChangedProperty";
+
+  /**
+   * The name of the 'accept all file filter used' property.
+   * @see #setAcceptAllFileFilterUsed(boolean)
+   */
+  public static final String ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY =
+    "acceptAllFileFilterUsedChanged";
+
+  /**
+   * The name of the 'dialog title' property.
+   * @see #setDialogTitle(String)
+   */
+  public static final String DIALOG_TITLE_CHANGED_PROPERTY =
+    "DialogTitleChangedProperty";
+
+  /**
+   * The name of the 'dialog type' property.
+   * @see #setDialogType(int)
+   */
+  public static final String DIALOG_TYPE_CHANGED_PROPERTY =
+    "DialogTypeChangedProperty";
+
+  /**
+   * The name of the 'choosable file filters' property.
+   * @see #addChoosableFileFilter(FileFilter)
+   */
+  public static final String CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY =
+    "ChoosableFileFilterChangedProperty";
+
+  /** 
+   * The accessible context. 
+   * @see #getAccessibleContext()
+   */
+  protected AccessibleContext accessibleContext;
+
+  /** 
+   * The file system view.
+   * @see #setFileSystemView(FileSystemView)
+   */
+  private FileSystemView fsv;
+
+  /**
+   * The accessory component.
+   * @see #setAccessory(JComponent)
+   */
+  private JComponent accessory;
+
+  /**
+   * The approve button mnemonic.
+   * @see #setApproveButtonMnemonic(int)
+   */
+  private int approveButtonMnemonic = 0;
+
+  /**
+   * The approve button text.
+   * @see #setApproveButtonText(String)
+   */
+  private String approveButtonText;
+
+  /**
+   * The approve button tool tip text.
+   * @see #setApproveButtonToolTipText(String)
+   */
+  private String approveButtonToolTipText;
+
+  /**
+   * The choosable file filters.
+   * @see #addChoosableFileFilter(FileFilter)
+   */
+  private ArrayList choosableFilters = new ArrayList();
+
+  /**
+   * A flag controlling whether the accept all file filter is used.
+   * @see #setAcceptAllFileFilterUsed(boolean)
+   */
+  private boolean isAcceptAll = true;
+
+  /**
+   * The dialog title.
+   * @see #setDialogTitle(String)
+   */
+  private String dialogTitle;
+
+  /**
+   * The dialog type.
+   * @see #setDialogType(int)
+   */
+  private int dialogType = OPEN_DIALOG;
+
+  /**
+   * The return value for the dialog.
+   * @see #showOpenDialog(Component)
+   * @see #showSaveDialog(Component)
+   */
+  private int retval = ERROR_OPTION;
+
+  /**
+   * A flag indicating whether the file chooser allows multiple selection.
+   * @see #isMultiSelectionEnabled()
+   */
+  private boolean multiSelection = false;
+
+  /**
+   * A flag indicating whether file hiding is enabled.
+   * @see #isFileHidingEnabled()
+   */
+  private boolean fileHiding = true;
+
+  /**
+   * The file selection mode.
+   * @see #setFileSelectionMode(int) 
+   */
+  private int fileSelectionMode = FILES_ONLY;
+
+  /** 
+   * The file view.
+   * @see #setFileView(FileView)
+   */
+  private FileView fv = null;
+
+  /** 
+   * A flag controlling whether or not the control buttons are visible. 
+   * @see #setControlButtonsAreShown(boolean) 
+   */
+  private boolean controlButtonsShown = true;
+
+  /** 
+   * The current directory. 
+   * @see #setCurrentDirectory(File)
+   */
+  private File currentDir = null;
+
+  /** 
+   * The current file filter.
+   * @see #setFileFilter(FileFilter)
+   */
+  private FileFilter currentFilter = null;
+
+  /** 
+   * An array of selected files.
+   * @see #setSelectedFiles(File[]) 
+   */
+  private File[] selectedFiles;
+
+  /** 
+   * The selected file. 
+   * @see #setSelectedFile(File)
+   */
+  private File selectedFile;
+  
+  /**
+   * The drag enabled property.
+   * @see #setDragEnabled(boolean)
+   * @see #getDragEnabled()
+   */
+  private boolean dragEnabled;
+
+  /**
+   * Creates a new <code>JFileChooser</code> object.
+   */
+  public JFileChooser()
+  {
+    setup(null);
+    setCurrentDirectory(null);
+  }
+
+  /**
+   * Creates a new <code>JFileChooser</code> object.
+   *
+   * @param currentDirectoryPath the directory that should initially be
+   *        shown in the filechooser (if <code>null</code>, the user's home 
+   *        directory is used).
+   */
+  public JFileChooser(String currentDirectoryPath)
+  {
+    this(currentDirectoryPath, null);
+  }
+
+  /**
+   * Creates a new <code>JFileChooser</code> object with the specified 
+   * directory and {@link FileSystemView}.
+   *
+   * @param currentDirectoryPath  the directory that should initially be
+   *        shown in the filechooser (if <code>null</code>, the user's home 
+   *        directory is used).
+   * @param fsv  the file system view (if <code>null</code>, the default file
+   *             system view is used).
+   */
+  public JFileChooser(String currentDirectoryPath, FileSystemView fsv)
+  {
+    setup(fsv);
+    File dir = null;
+    if (currentDirectoryPath != null)
+      dir = getFileSystemView().createFileObject(currentDirectoryPath);
+    setCurrentDirectory(dir);
+  }
+
+  /**
+   * Creates a new <code>JFileChooser</code> object.
+   *
+   * @param currentDirectory  the directory that should initially be
+   *        shown in the filechooser (if <code>null</code>, the user's home 
+   *        directory is used).
+   */
+  public JFileChooser(File currentDirectory)
+  {
+    setup(null);
+    setCurrentDirectory(currentDirectory);
+  }
+
+  /**
+   * Creates a new <code>JFileChooser</code> object.
+   *
+   * @param fsv  the file system view (if <code>null</code>, the default file
+   *             system view is used).
+   */
+  public JFileChooser(FileSystemView fsv)
+  {
+    setup(fsv);
+    setCurrentDirectory(null);
+  }
+
+  /**
+   * Creates a new <code>JFileChooser</code> object.
+   *
+   * @param currentDirectory  the directory that should initially be
+   *        shown in the filechooser (if <code>null</code>, the user's home 
+   *        directory is used).
+   * @param fsv  the file system view (if <code>null</code>, the default file
+   *             system view is used).
+   */
+  public JFileChooser(File currentDirectory, FileSystemView fsv)
+  {
+    setup(fsv);
+    setCurrentDirectory(currentDirectory);
+  }
+
+  /**
+   * Sets up the file chooser.  This method is called by all the constructors.
+   *
+   * @param view  the file system view (if <code>null</code>, the default file
+   *              system view is used).
+   * 
+   * @see FileSystemView#getFileSystemView()
+   */
+  protected void setup(FileSystemView view)
+  {
+    if (view == null)
+      view = FileSystemView.getFileSystemView();
+    setFileSystemView(view);
+    updateUI();
+  }
+
+  /**
+   * Sets the dragEnabled property, this disables/enables automatic drag
+   * handling (drag and drop) on this component. The default value of the
+   * dragEnabled property is false. 
+   * 
+   * Some look and feels might not support automatic drag and drop; they
+   * will ignore this property.
+   * 
+   * @param b - the new dragEnabled value
+   */
+  public void setDragEnabled(boolean b)
+  {
+    if (b && GraphicsEnvironment.isHeadless())
+      throw new HeadlessException();
+    
+    dragEnabled = b;
+  }
+
+  /**
+   * Returns true if dragging is enabled.
+   *
+   * @return true if dragging is enabled.
+   */
+  public boolean getDragEnabled()
+  {
+    return dragEnabled;
+  }
+
+  /**
+   * Returns the selected file, if there is one.
+   *
+   * @return The selected file (possibly <code>null</code>).
+   * 
+   * @see #setSelectedFile(File)
+   */
+  public File getSelectedFile()
+  {
+    return selectedFile;
+  }
+
+  /**
+   * Sets the selected file and sends a {@link PropertyChangeEvent} to all
+   * registered listeners.  The property name is 
+   * {@link #SELECTED_FILE_CHANGED_PROPERTY}.
+   *
+   * @param file  the file (<code>null</code> permitted).
+   */
+  public void setSelectedFile(File file)
+  {
+    if (selectedFile == null || !selectedFile.equals(file))
+      {
+	File old = selectedFile;
+	selectedFile = file;
+	firePropertyChange(SELECTED_FILE_CHANGED_PROPERTY, old, selectedFile);
+      }
+  }
+
+  /**
+   * Returns the selected file or files in an array.  If no files are selected,
+   * an empty array is returned.
+   *
+   * @return An array of the selected files (possibly empty).
+   */
+  public File[] getSelectedFiles()
+  {
+    if (selectedFiles != null)
+      return selectedFiles;
+    if (selectedFile != null)
+      return new File[] { selectedFile };
+    return new File[0];
+  }
+
+  /**
+   * Sets the selected files and sends a {@link PropertyChangeEvent} (with the 
+   * name {@link #SELECTED_FILES_CHANGED_PROPERTY}) to all registered 
+   * listeners.  
+   *
+   * @param selectedFiles  the selected files (<code>null</code> permitted).
+   */
+  public void setSelectedFiles(File[] selectedFiles)
+  {
+    if (selectedFiles == null)
+      selectedFiles = new File[0];
+    if (selectedFiles.length > 0)
+      setSelectedFile(selectedFiles[0]);
+    else
+      setSelectedFile(null);
+    if (this.selectedFiles != selectedFiles)
+      {
+	File[] old = this.selectedFiles;
+	this.selectedFiles = selectedFiles;
+	firePropertyChange(SELECTED_FILES_CHANGED_PROPERTY, old, selectedFiles);
+      }
+
+  }
+
+  /**
+   * Returns the current directory.
+   *
+   * @return The current directory.
+   */
+  public File getCurrentDirectory()
+  {
+    return currentDir;
+  }
+
+  /**
+   * Sets the current directory and fires a {@link PropertyChangeEvent} (with 
+   * the property name {@link #DIRECTORY_CHANGED_PROPERTY}) to all registered 
+   * listeners.  If <code>dir</code> is <code>null</code>, the current 
+   * directory is set to the default directory returned by the file system
+   * view.
+   *
+   * @param dir  the new directory (<code>null</code> permitted).
+   * 
+   * @see FileSystemView#getDefaultDirectory()
+   */
+  public void setCurrentDirectory(File dir)
+  {
+    if (currentDir != dir || dir == null)
+      {
+	if (dir == null)
+	  dir = fsv.getDefaultDirectory();
+
+	File old = currentDir;
+	currentDir = dir;
+	firePropertyChange(DIRECTORY_CHANGED_PROPERTY, old, currentDir);
+      }
+  }
+
+  /**
+   * Called by the UI delegate when the parent directory is changed.
+   */
+  public void changeToParentDirectory()
+  {
+    setCurrentDirectory(fsv.getParentDirectory(currentDir));
+  }
+
+  /**
+   * Rescans the current directory (this is handled by the UI delegate).
+   */
+  public void rescanCurrentDirectory()
+  {
+    getUI().rescanCurrentDirectory(this);
+  }
+
+  /**
+   * Ensures the the specified file is visible (this is handled by the 
+   * UI delegate).
+   *
+   * @param f  the file.
+   */
+  public void ensureFileIsVisible(File f)
+  {
+    getUI().ensureFileIsVisible(this, f);
+  }
+
+  /**
+   * Displays the file chooser in a modal dialog using the 
+   * {@link #OPEN_DIALOG} type.
+   *
+   * @param parent  the parent component.
+   *
+   * @return A return value indicating how the dialog was closed (one of 
+   *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and 
+   *         {@link #ERROR_OPTION}).
+   *
+   * @throws HeadlessException DOCUMENT ME!
+   */
+  public int showOpenDialog(Component parent) throws HeadlessException
+  {
+    JDialog d = createDialog(parent);
+
+    // FIXME: Remove when we get ancestor property
+    d.setTitle("Open");
+    setDialogType(OPEN_DIALOG);
+
+    retval = ERROR_OPTION;
+
+    d.pack();
+    d.show();
+    return retval;
+  }
+
+  /**
+   * Displays the file chooser in a modal dialog using the 
+   * {@link #SAVE_DIALOG} type.
+   *
+   * @param parent  the parent component.
+   *
+   * @return A return value indicating how the dialog was closed (one of 
+   *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and 
+   *         {@link #ERROR_OPTION}).
+   *
+   * @throws HeadlessException DOCUMENT ME!
+   */
+  public int showSaveDialog(Component parent) throws HeadlessException
+  {
+    JDialog d = createDialog(parent);
+    setDialogType(SAVE_DIALOG);
+
+    retval = ERROR_OPTION;
+
+    d.pack();
+    d.show();
+    return retval;
+  }
+
+  /**
+   * Displays the file chooser in a modal dialog using the 
+   * {@link #CUSTOM_DIALOG} type.
+   *
+   * @param parent  the parent component.
+   *
+   * @return A return value indicating how the dialog was closed (one of 
+   *         {@link #APPROVE_OPTION}, {@link #CANCEL_OPTION} and 
+   *         {@link #ERROR_OPTION}).
+   *
+   * @throws HeadlessException DOCUMENT ME!
+   */
+  public int showDialog(Component parent, String approveButtonText)
+                 throws HeadlessException
+  {
+    JDialog d = createDialog(parent);
+    setApproveButtonText(approveButtonText);
+    setDialogType(CUSTOM_DIALOG);
+
+    retval = ERROR_OPTION;
+
+    d.pack();
+    d.show();
+    return retval;
+  }
+
+  /**
+   * Creates a modal dialog in which to display the file chooser.
+   *
+   * @param parent  the parent component.
+   *
+   * @return The dialog.
+   *
+   * @throws HeadlessException DOCUMENT ME!
+   */
+  protected JDialog createDialog(Component parent) throws HeadlessException
+  {
+    Frame toUse = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);
+    if (toUse == null)
+      toUse = (Frame) SwingUtilities.getOwnerFrame(null);
+
+    JDialog dialog = new JDialog(toUse);
+    setSelectedFile(null);
+    dialog.getContentPane().add(this);
+    dialog.addWindowListener( new WindowAdapter()
+      {
+	public void windowClosing(WindowEvent e)
+	{
+	  cancelSelection();
+	}
+      });
+    dialog.setModal(true);
+    dialog.invalidate();
+    dialog.repaint();
+    return dialog;
+  }
+
+  /**
+   * Returns the flag that controls whether or not the control buttons are
+   * shown on the file chooser.
+   *
+   * @return A boolean.
+   * 
+   * @see #setControlButtonsAreShown(boolean)
+   */
+  public boolean getControlButtonsAreShown()
+  {
+    return controlButtonsShown;
+  }
+
+  /**
+   * Sets the flag that controls whether or not the control buttons are
+   * shown and, if it changes, sends a {@link PropertyChangeEvent} (with the
+   * property name {@link #CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY}) to
+   * all registered listeners.
+   *
+   * @param b  the new value for the flag.
+   */
+  public void setControlButtonsAreShown(boolean b)
+  {
+    if (controlButtonsShown != b)
+      {
+	controlButtonsShown = b;
+	firePropertyChange(CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY,
+	                   ! controlButtonsShown, controlButtonsShown);
+      }
+  }
+
+  /**
+   * Returns the type of file chooser.
+   *
+   * @return {@link #OPEN_DIALOG}, {@link #SAVE_DIALOG} or 
+   * {@link #CUSTOM_DIALOG}.
+   * 
+   * @see #setDialogType(int)
+   */
+  public int getDialogType()
+  {
+    return dialogType;
+  }
+
+  /**
+   * Sets the dialog type and fires a {@link PropertyChangeEvent} (with the
+   * property name {@link #DIALOG_TYPE_CHANGED_PROPERTY}) to all 
+   * registered listeners.
+   *
+   * @param dialogType  the dialog type (one of: {@link #OPEN_DIALOG},
+   * {@link #SAVE_DIALOG}, {@link #CUSTOM_DIALOG}).
+   * 
+   * @throws IllegalArgumentException if <code>dialogType</code> is not valid.
+   */
+  public void setDialogType(int dialogType)
+  {
+    if (dialogType != OPEN_DIALOG && dialogType != SAVE_DIALOG
+        && dialogType != CUSTOM_DIALOG)
+      throw new IllegalArgumentException("Choose allowable dialogType.");
+
+    if (this.dialogType != dialogType)
+      {
+	int old = this.dialogType;
+	this.dialogType = dialogType;
+	firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, old, this.dialogType);
+      }
+  }
+
+  /**
+   * Sets the dialog title and sends a {@link PropertyChangeEvent} (with the 
+   * property name {@link #DIALOG_TITLE_CHANGED_PROPERTY}) to all 
+   * registered listeners.
+   *
+   * @param dialogTitle  the dialog title (<code>null</code> permitted).
+   * 
+   * @see #getDialogTitle()
+   */
+  public void setDialogTitle(String dialogTitle)
+  {
+    if (this.dialogTitle != dialogTitle)
+      {
+	String old = this.dialogTitle;
+	this.dialogTitle = dialogTitle;
+	firePropertyChange(DIALOG_TITLE_CHANGED_PROPERTY, old, this.dialogTitle);
+      }
+  }
+
+  /**
+   * Returns the dialog title.
+   *
+   * @return The dialog title (possibly <code>null</code>).
+   * 
+   * @see #setDialogTitle(String)
+   */
+  public String getDialogTitle()
+  {
+    return dialogTitle;
+  }
+
+  /**
+   * Sets the tool tip text for the approve button and sends a 
+   * {@link PropertyChangeEvent} (with the property name
+   * {@link #APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY}) to all 
+   * registered listeners.
+   *
+   * @param toolTipText  the text.
+   */
+  public void setApproveButtonToolTipText(String toolTipText)
+  {
+    if (approveButtonToolTipText != toolTipText)
+      {
+	String oldText = approveButtonToolTipText;
+	approveButtonToolTipText = toolTipText;
+	firePropertyChange(APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY,
+	                   oldText, approveButtonToolTipText);
+      }
+  }
+
+  /**
+   * Returns the tool tip text for the approve button.
+   *
+   * @return The tool tip text for the approve button.
+   * 
+   * @see #setApproveButtonToolTipText(String)
+   */
+  public String getApproveButtonToolTipText()
+  {
+    return approveButtonToolTipText;
+  }
+
+  /**
+   * Returns the approve button mnemonic, or zero if no mnemonic has been set.
+   *
+   * @return The approve button mnemonic.
+   * 
+   * @see #setApproveButtonMnemonic(int)
+   */
+  public int getApproveButtonMnemonic()
+  {
+    return approveButtonMnemonic;
+  }
+
+  /**
+   * Sets the mnemonic for the approve button and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered 
+   * listeners.
+   *
+   * @param mnemonic  the mnemonic.
+   * 
+   * @see #setApproveButtonMnemonic(char)
+   */
+  public void setApproveButtonMnemonic(int mnemonic)
+  {
+    if (approveButtonMnemonic != mnemonic)
+      {
+	int oldMnemonic = approveButtonMnemonic;
+	approveButtonMnemonic = mnemonic;
+	firePropertyChange(APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY,
+	                   oldMnemonic, approveButtonMnemonic);
+      }
+  }
+
+  /**
+   * Sets the mnemonic for the approve button and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * {@link #APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY}) to all registered 
+   * listeners.
+   *
+   * @param mnemonic  the mnemonic.
+   * 
+   * @see #setApproveButtonMnemonic(int)
+   */
+  public void setApproveButtonMnemonic(char mnemonic)
+  {
+    setApproveButtonMnemonic((int) Character.toUpperCase(mnemonic));
+  }
+
+  /**
+   * Sets the approve button text and fires a {@link PropertyChangeEvent} 
+   * (with the property name {@link #APPROVE_BUTTON_TEXT_CHANGED_PROPERTY}) to 
+   * all registered listeners.
+   *
+   * @param approveButtonText  the text (<code>null</code> permitted).
+   * 
+   * @see #getApproveButtonText()
+   */
+  public void setApproveButtonText(String approveButtonText)
+  {
+    if (this.approveButtonText != approveButtonText)
+      {
+	String oldText = this.approveButtonText;
+	this.approveButtonText = approveButtonText;
+	firePropertyChange(APPROVE_BUTTON_TEXT_CHANGED_PROPERTY, oldText,
+	                   this.approveButtonText);
+      }
+  }
+
+  /**
+   * Returns the approve button text.
+   *
+   * @return The approve button text (possibly <code>null</code>).
+   * 
+   * @see #setApproveButtonText(String)
+   */
+  public String getApproveButtonText()
+  {
+    return approveButtonText;
+  }
+
+  /**
+   * Returns the available file filters for this file chooser.
+   *
+   * @return The available file filters.
+   */
+  public FileFilter[] getChoosableFileFilters()
+  {
+    return (FileFilter[]) choosableFilters.toArray(new FileFilter[choosableFilters.size()]);
+  }
+
+  /**
+   * Adds a file filter to the list of available filters and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered 
+   * listeners.
+   *
+   * @param filter  the filter (<code>null</code> permitted).
+   */
+  public void addChoosableFileFilter(FileFilter filter)
+  {
+    if (filter != null)
+      {
+        FileFilter[] old = getChoosableFileFilters();
+        choosableFilters.add(filter);
+        FileFilter[] newFilters = getChoosableFileFilters();
+        firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old, 
+              newFilters);
+      }
+    setFileFilter(filter);
+  }
+
+  /**
+   * Removes a file filter from the list of available filters and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered 
+   * listeners.
+   *
+   * @param f  the file filter.
+   *
+   * @return <code>true</code> if the filter was removed and 
+   *         <code>false</code> otherwise.
+   */
+  public boolean removeChoosableFileFilter(FileFilter f)
+  {
+    if (f == currentFilter)
+      setFileFilter(null);
+    FileFilter[] old = getChoosableFileFilters();
+    if (! choosableFilters.remove(f))
+      return false;
+    FileFilter[] newFilters = getChoosableFileFilters();
+    firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old, newFilters);
+    return true;
+  }
+
+  /**
+   * Clears the list of choosable file filters and installs the 'accept all'
+   * filter from the UI delegate.
+   */
+  public void resetChoosableFileFilters()
+  {
+    choosableFilters.clear();
+    choosableFilters.add(getUI().getAcceptAllFileFilter(this));
+    setFileFilter((FileFilter) choosableFilters.get(0));
+  }
+
+  /**
+   * Returns the 'accept all' file filter from the UI delegate.
+   *
+   * @return The 'accept all' file filter.
+   */
+  public FileFilter getAcceptAllFileFilter()
+  {
+    return getUI().getAcceptAllFileFilter(this);
+  }
+
+  /**
+   * Returns the flag that controls whether or not the 'accept all' file 
+   * filter is included in the list of filters.
+   *
+   * @return A boolean.
+   * 
+   * @see #setAcceptAllFileFilterUsed(boolean)
+   */
+  public boolean isAcceptAllFileFilterUsed()
+  {
+    return isAcceptAll;
+  }
+
+  /**
+   * Sets the flag that controls whether or not the 'accept all' file filter
+   * is included in the list of filters, and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * {@link #ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY}) to all registered 
+   * listeners.
+   *
+   * @param b  the new value of the flag.
+   */
+  public void setAcceptAllFileFilterUsed(boolean b)
+  {
+    if (isAcceptAll != b)
+      {
+	isAcceptAll = b;
+        if (b)
+          addChoosableFileFilter(getAcceptAllFileFilter());
+        else 
+          removeChoosableFileFilter(getAcceptAllFileFilter());
+	firePropertyChange(ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY,
+	                   ! isAcceptAll, isAcceptAll);
+      }
+  }
+
+  /**
+   * Returns the accessory component for the file chooser.  The default
+   * value is <code>null</code>.
+   *
+   * @return The accessory component (possibly <code>null</code>).
+   * 
+   * @see #setAccessory(JComponent)
+   */
+  public JComponent getAccessory()
+  {
+    return accessory;
+  }
+
+  /**
+   * Sets the accessory component for the file chooser and sends a 
+   * {@link PropertyChangeEvent} to all registered listeners.  The property
+   * name is {@link #ACCESSORY_CHANGED_PROPERTY}.
+   *
+   * @param newAccessory  the accessory component.
+   */
+  public void setAccessory(JComponent newAccessory)
+  {
+    if (accessory != newAccessory)
+      {
+	JComponent old = accessory;
+	accessory = newAccessory;
+	firePropertyChange(ACCESSORY_CHANGED_PROPERTY, old, accessory);
+      }
+  }
+
+  /**
+   * Sets the file selection mode and sends a {@link PropertyChangeEvent}
+   * to all registered listeners.  The property name is 
+   * {@link #FILE_SELECTION_MODE_CHANGED_PROPERTY}.
+   *
+   * @param mode  the mode ({@link #FILES_ONLY}, {@link #DIRECTORIES_ONLY} or
+   *              {@link #FILES_AND_DIRECTORIES}).
+   * 
+   * @throws IllegalArgumentException if the mode is invalid.
+   */
+  public void setFileSelectionMode(int mode)
+  {
+    if (mode != FILES_ONLY && mode != DIRECTORIES_ONLY
+        && mode != FILES_AND_DIRECTORIES)
+      throw new IllegalArgumentException("Choose a correct file selection mode.");
+    if (fileSelectionMode != mode)
+      {
+	int old = fileSelectionMode;
+	fileSelectionMode = mode;
+	firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY, old,
+	                   fileSelectionMode);
+      }
+  }
+
+  /**
+   * Returns the file selection mode, one of: {@link #FILES_ONLY}, 
+   * {@link #DIRECTORIES_ONLY} or {@link #FILES_AND_DIRECTORIES}.  The
+   * default is {@link #FILES_ONLY}.
+   *
+   * @return The file selection mode.
+   * 
+   * @see #setFileSelectionMode(int)
+   */
+  public int getFileSelectionMode()
+  {
+    return fileSelectionMode;
+  }
+
+  /**
+   * Returns <code>true</code> if file selection is enabled, and 
+   * <code>false</code> otherwise.  File selection is enabled when the
+   * file selection mode is {@link #FILES_ONLY} or 
+   * {@link #FILES_AND_DIRECTORIES}.
+   *
+   * @return <code>true</code> if file selection is enabled.
+   * 
+   * @see #getFileSelectionMode()
+   */
+  public boolean isFileSelectionEnabled()
+  {
+    return (fileSelectionMode == FILES_ONLY
+           || fileSelectionMode == FILES_AND_DIRECTORIES);
+  }
+
+  /**
+   * Returns <code>true</code> if directory selection is enabled, and 
+   * <code>false</code> otherwise.  Directory selection is enabled when the
+   * file selection mode is {@link #DIRECTORIES_ONLY} or 
+   * {@link #FILES_AND_DIRECTORIES}.
+   *
+   * @return <code>true</code> if file selection is enabled.
+   * 
+   * @see #getFileSelectionMode()
+   */
+  public boolean isDirectorySelectionEnabled()
+  {
+    return (fileSelectionMode == DIRECTORIES_ONLY
+           || fileSelectionMode == FILES_AND_DIRECTORIES);
+  }
+
+  /**
+   * Sets the flag that controls whether multiple selections are allowed in 
+   * this filechooser and sends a {@link PropertyChangeEvent} (with the 
+   * property name {@link #MULTI_SELECTION_ENABLED_CHANGED_PROPERTY}) to all 
+   * registered listeners.
+   *
+   * @param b  the new value of the flag.
+   */
+  public void setMultiSelectionEnabled(boolean b)
+  {
+    if (multiSelection != b)
+      {
+	multiSelection = b;
+	firePropertyChange(MULTI_SELECTION_ENABLED_CHANGED_PROPERTY,
+	                   ! multiSelection, multiSelection);
+      }
+  }
+
+  /**
+   * Returns <code>true</code> if multiple selections are allowed within this
+   * file chooser, and <code>false</code> otherwise.
+   *
+   * @return A boolean.
+   * 
+   * @see #setMultiSelectionEnabled(boolean)
+   */
+  public boolean isMultiSelectionEnabled()
+  {
+    return multiSelection;
+  }
+
+  /**
+   * Returns <code>true</code> if hidden files are to be hidden, and 
+   * <code>false</code> otherwise.
+   *
+   * @return A boolean.
+   * 
+   * @see #setFileHidingEnabled(boolean)
+   */
+  public boolean isFileHidingEnabled()
+  {
+    return fileHiding;
+  }
+
+  /**
+   * Sets the flag that controls whether or not hidden files are displayed,
+   * and sends a {@link PropertyChangeEvent} (with the property name
+   * {@link #FILE_HIDING_CHANGED_PROPERTY}) to all registered listeners.
+   *
+   * @param b  the new value of the flag.
+   */
+  public void setFileHidingEnabled(boolean b)
+  {
+    if (fileHiding != b)
+      {
+	fileHiding = b;
+	firePropertyChange(FILE_HIDING_CHANGED_PROPERTY, ! fileHiding,
+	                   fileHiding);
+      }
+  }
+
+  /**
+   * Sets the file filter and sends a {@link PropertyChangeEvent} (with the
+   * property name {@link #FILE_FILTER_CHANGED_PROPERTY}) to all registered 
+   * listeners.
+   *
+   * @param filter  the filter (<code>null</code> permitted).
+   */
+  public void setFileFilter(FileFilter filter)
+  {
+    if (currentFilter != filter)
+      {
+        if (filter != null && !choosableFilters.contains(filter))
+          addChoosableFileFilter(filter);
+        FileFilter old = currentFilter;
+        currentFilter = filter;
+        firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, old, currentFilter);
+      }
+  }
+
+  /**
+   * Returns the file filter.
+   *
+   * @return The file filter.
+   * 
+   * @see #setFileFilter(FileFilter)
+   */
+  public FileFilter getFileFilter()
+  {
+    return currentFilter;
+  }
+
+  /**
+   * Sets a custom {@link FileView} for the file chooser and sends a 
+   * {@link PropertyChangeEvent} to all registered listeners.  The property
+   * name is {@link #FILE_VIEW_CHANGED_PROPERTY}.
+   *
+   * @param fileView  the file view (<code>null</code> permitted).
+   *
+   * @see #getFileView()
+   */
+  public void setFileView(FileView fileView)
+  {
+    if (fv != fileView)
+      {
+	FileView old = fv;
+	fv = fileView;
+	firePropertyChange(FILE_VIEW_CHANGED_PROPERTY, old, fv);
+      }
+  }
+
+  /**
+   * Returns the custom {@link FileView} for the file chooser.
+   *
+   * @return The file view (possibly <code>null</code>).
+   */
+  public FileView getFileView()
+  {
+    return fv;
+  }
+
+  /**
+   * Returns the name of the file, generated by the current (or default)
+   * {@link FileView}.
+   *
+   * @param f  the file.
+   *
+   * @return The file name.
+   */
+  public String getName(File f)
+  {
+    String name = null;
+    if (fv != null)
+      name = fv.getName(f);
+    if (name == null)
+      name = getUI().getFileView(this).getName(f);
+    return name;
+  }
+
+  /**
+   * Returns the description of the file, generated by the current (or default)
+   * {@link FileView}.
+   *
+   * @param f  the file.
+   *
+   * @return The file description.
+   */
+  public String getDescription(File f)
+  {
+    String result = null;
+    if (fv != null)
+      result = fv.getDescription(f);
+    if (result == null)
+      result = getUI().getFileView(this).getDescription(f);
+    return result;
+  }
+
+  /**
+   * Returns the type description for the file, generated by the current (or 
+   * default) {@link FileView}.
+   *
+   * @param f  the file.
+   *
+   * @return The file type description.
+   */
+  public String getTypeDescription(File f)
+  {
+    String result = null;
+    if (fv != null)
+      result = getFileView().getTypeDescription(f);
+    if (result == null)
+      result = getUI().getFileView(this).getTypeDescription(f);
+    return result;
+  }
+
+  /**
+   * Returns the icon provided by the current (or default) {@link FileView}.
+   *
+   * @param f  the file.
+   *
+   * @return An icon representing the file.
+   */
+  public Icon getIcon(File f)
+  {
+    Icon result = null;
+    if (fv != null)
+      result = fv.getIcon(f);
+    if (result == null)
+      result = getUI().getFileView(this).getIcon(f);
+    return result;
+  }
+
+  /**
+   * Returns <code>true</code> if the file is traversable, and 
+   * <code>false</code> otherwise.
+   *
+   * @param f  the file or directory.
+   *
+   * @return A boolean.
+   */
+  public boolean isTraversable(File f)
+  {
+    return getFileSystemView().isTraversable(f).booleanValue();
+  }
+
+  /**
+   * Returns <code>true</code> if the file is accepted by the current
+   * file filter.
+   *
+   * @param f  the file.
+   *
+   * @return A boolean.
+   */
+  public boolean accept(File f)
+  {
+    if (f == null)
+      return true;
+    FileFilter ff = getFileFilter();
+    if (ff != null) 
+      return ff.accept(f);
+    else
+      return true;
+  }
+
+  /**
+   * Sets the file system view for the file chooser and sends a 
+   * {@link PropertyChangeEvent} to all registered listeners.
+   *
+   * @param fsv  the file system view.
+   */
+  public void setFileSystemView(FileSystemView fsv)
+  {
+    if (this.fsv != fsv)
+      {
+	FileSystemView old = this.fsv;
+	this.fsv = fsv;
+	firePropertyChange(FILE_SYSTEM_VIEW_CHANGED_PROPERTY, old, this.fsv);
+      }
+  }
+
+  /**
+   * Returns the file system view being used by this file chooser.
+   *
+   * @return The file system view.
+   * 
+   * @see #setFileSystemView(FileSystemView)
+   */
+  public FileSystemView getFileSystemView()
+  {
+    return fsv;
+  }
+
+  /**
+   * Approves the selection.  An {@link ActionEvent} is sent to all registered
+   * listeners.
+   */
+  public void approveSelection()
+  {
+    retval = APPROVE_OPTION;
+    fireActionPerformed(APPROVE_SELECTION);
+  }
+
+  /**
+   * Cancels the selection. An {@link ActionEvent} is sent to all registered
+   * listeners.
+   */
+  public void cancelSelection()
+  {
+    retval = CANCEL_OPTION;
+    fireActionPerformed(CANCEL_SELECTION);
+  }
+
+  /**
+   * Adds an {@link ActionListener} to the file chooser.
+   *
+   * @param l  the listener.
+   */
+  public void addActionListener(ActionListener l)
+  {
+    listenerList.add(ActionListener.class, l);
+  }
+
+  /**
+   * Removes an {@link ActionListener} from this file chooser.
+   *
+   * @param l  the listener.
+   */
+  public void removeActionListener(ActionListener l)
+  {
+    try
+      {
+	listenerList.remove(ActionListener.class, l);
+      }
+    catch (IllegalArgumentException e)
+      {
+	e.printStackTrace();
+      }
+  }
+
+  /**
+   * Returns the action listeners registered with this file chooser.
+   *
+   * @return An array of listeners.
+   */
+  public ActionListener[] getActionListeners()
+  {
+    return (ActionListener[]) getListeners(ActionListener.class);
+  }
+
+  /**
+   * Sends an @link {ActionEvent} to all registered listeners.
+   *
+   * @param command  the action command.
+   */
+  protected void fireActionPerformed(String command)
+  {
+    ActionListener[] list = getActionListeners();
+    ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
+                                        command);
+
+    for (int i = 0; i < list.length; i++)
+      list[i].actionPerformed(event);
+  }
+
+  /**
+   * Installs the UI delegate for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((FileChooserUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Returns the UI delegate class identifier.
+   *
+   * @return <code>FileChooserUI</code>.
+   */
+  public String getUIClassID()
+  {
+    return "FileChooserUI";
+  }
+
+  /**
+   * Returns the UI delegate for the component.
+   *
+   * @return The UI delegate.
+   */
+  public FileChooserUI getUI()
+  {
+    return (FileChooserUI) ui;
+  }
+
+  /**
+   * Returns a string describing the attributes for the 
+   * <code>JFileChooser</code> component, for use in debugging.  The return 
+   * value is guaranteed to be non-<code>null</code>, but the format of the 
+   * string may vary between implementations.
+   *
+   * @return A string describing the attributes of the 
+   *     <code>JFileChooser</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",approveButtonText=");
+    if (approveButtonText != null)
+      sb.append(approveButtonText);
+    sb.append(",currentDirectory=");
+    if (currentDir != null)
+      sb.append(currentDir);
+    sb.append(",dialogTitle=");
+    if (dialogTitle != null)
+      sb.append(dialogTitle);
+    sb.append(",dialogType=");
+    if (dialogType == OPEN_DIALOG)
+      sb.append("OPEN_DIALOG");
+    if (dialogType == SAVE_DIALOG)
+      sb.append("SAVE_DIALOG");
+    if (dialogType == CUSTOM_DIALOG)
+      sb.append("CUSTOM_DIALOG");
+    sb.append(",fileSelectionMode=");
+    if (fileSelectionMode == FILES_ONLY)
+      sb.append("FILES_ONLY");
+    if (fileSelectionMode == DIRECTORIES_ONLY)
+      sb.append("DIRECTORIES_ONLY");
+    if (fileSelectionMode == FILES_AND_DIRECTORIES)
+      sb.append("FILES_AND_DIRECTORIES");
+    sb.append(",returnValue=");
+    if (retval == APPROVE_OPTION)
+      sb.append("APPROVE_OPTION");
+    if (retval == CANCEL_OPTION)
+      sb.append("CANCEL_OPTION");
+    if (retval == ERROR_OPTION)
+      sb.append("ERROR_OPTION");
+    sb.append(",selectedFile=");
+    if (selectedFile != null)
+      sb.append(selectedFile);
+    sb.append(",useFileHiding=").append(fileHiding);
+    return sb.toString();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JFileChooser</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJFileChooser}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJFileChooser();
+    return accessibleContext;
+  }
+
+  /**
+   * Provides the accessibility features for the <code>JFileChooser</code>
+   * component.
+   */
+  protected class AccessibleJFileChooser 
+    extends JComponent.AccessibleJComponent
+  {
+    /**
+     * Creates a new instance of <code>AccessibleJFileChooser</code>.
+     */
+    protected AccessibleJFileChooser()
+    {
+      // Nothing to do here.
+    }
+    
+    /**
+     * Returns the accessible role for the <code>JFileChooser</code> 
+     * component.
+     *
+     * @return {@link AccessibleRole#FILE_CHOOSER}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.FILE_CHOOSER;
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFormattedTextField.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFormattedTextField.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFormattedTextField.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFormattedTextField.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,648 @@
+/* JFormattedTextField.java --
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.event.FocusEvent;
+import java.io.Serializable;
+import java.text.DateFormat;
+import java.text.Format;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Date;
+
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.DateFormatter;
+import javax.swing.text.DefaultFormatter;
+import javax.swing.text.DefaultFormatterFactory;
+import javax.swing.text.Document;
+import javax.swing.text.DocumentFilter;
+import javax.swing.text.InternationalFormatter;
+import javax.swing.text.NavigationFilter;
+import javax.swing.text.NumberFormatter;
+
+/**
+ * A text field that makes use of a formatter to display and edit a specific
+ * type of data. The value that is displayed can be an arbitrary object. The
+ * formatter is responsible for displaying the value in a textual form and
+ * it may allow editing of the value.
+ *
+ * Formatters are usually obtained using an instance of
+ * {@link AbstractFormatterFactory}. This factory is responsible for providing
+ * an instance of {@link AbstractFormatter} that is able to handle the
+ * formatting of the value of the JFormattedTextField.
+ *
+ * @author Michael Koch
+ * @author Anthony Balkissoon abalkiss at redhat dot com
+ *
+ * @since 1.4
+ */
+public class JFormattedTextField extends JTextField
+{
+  private static final long serialVersionUID = 5464657870110180632L;
+
+  /**
+   * An abstract base implementation for a formatter that can be used by
+   * a JTextField. A formatter can display a specific type of object and
+   * may provide a way to edit this value.
+   */
+  public abstract static class AbstractFormatter implements Serializable
+  {
+    private static final long serialVersionUID = -5193212041738979680L;
+    
+    private JFormattedTextField textField;
+    
+    public AbstractFormatter ()
+    {
+      //Do nothing here.
+    }
+
+    /**
+     * Clones the AbstractFormatter and removes the association to any 
+     * particular JFormattedTextField.
+     * 
+     * @return a clone of this formatter with no association to any particular
+     * JFormattedTextField
+     * @throws CloneNotSupportedException if the Object's class doesn't support
+     * the {@link Cloneable} interface
+     */
+    protected Object clone()
+      throws CloneNotSupportedException
+    {
+      // Clone this formatter.
+      AbstractFormatter newFormatter = (AbstractFormatter) super.clone();
+      
+      // And remove the association to the JFormattedTextField.
+      newFormatter.textField = null;
+      return newFormatter;
+    }
+
+    /**
+     * Returns a custom set of Actions that this formatter supports.  Should
+     * be subclassed by formatters that have a custom set of Actions.
+     * 
+     * @return <code>null</code>.  Should be subclassed by formatters that want
+     * to install custom Actions on the JFormattedTextField.
+     */
+    protected Action[] getActions()
+    {
+      return null;
+    }
+
+    /**
+     * Gets the DocumentFilter for this formatter.  Should be subclassed
+     * by formatters wishing to install a filter that oversees Document
+     * mutations.
+     * 
+     * @return <code>null</code>.  Should be subclassed by formatters
+     * that want to restrict Document mutations.
+     */
+    protected DocumentFilter getDocumentFilter()
+    {
+      // Subclasses should override this if they want to install a 
+      // DocumentFilter.
+      return null;
+    }
+
+    /**
+     * Returns the JFormattedTextField on which this formatter is
+     * currently installed.
+     * 
+     * @return the JFormattedTextField on which this formatter is currently
+     * installed
+     */
+    protected JFormattedTextField getFormattedTextField()
+    {
+      return textField;
+    }
+
+    /**
+     * Gets the NavigationFilter for this formatter.  Should be subclassed
+     * by formatters (such as {@link DefaultFormatter}) that wish to 
+     * restrict where the cursor can be placed within the text field.
+     * 
+     * @return <code>null</code>.  Subclassed by formatters that want to restrict
+     * cursor location within the JFormattedTextField.
+     */
+    protected NavigationFilter getNavigationFilter()
+    {
+      // This should be subclassed if the formatter wants to install 
+      // a NavigationFilter on the JFormattedTextField.
+      return null;
+    }
+
+    /**
+     * Installs this formatter on the specified JFormattedTextField.  This 
+     * converts the current value to a displayable String and displays it, 
+     * and installs formatter specific Actions from <code>getActions</code>.
+     * It also installs a DocumentFilter and NavigationFilter on the 
+     * JFormattedTextField.  
+     * <p>
+     * If there is a <code>ParseException</code> this sets the text to an 
+     * empty String and marks the text field in an invalid state.
+     * 
+     * @param textField the JFormattedTextField on which to install this
+     * formatter
+     */
+    public void install(JFormattedTextField textField)
+    {
+      // Uninstall the current textfield.
+      if (this.textField != null)
+        uninstall();
+      
+      this.textField = textField;
+      
+      // Install some state on the text field, including display text, 
+      // DocumentFilter, NavigationFilter, and formatter specific Actions.
+      if (textField != null)
+        {
+          try
+          {
+            // Set the text of the field.
+            textField.setText(valueToString(textField.getValue()));
+            Document doc = textField.getDocument();
+            
+            // Set the DocumentFilter for the field's Document.
+            if (doc instanceof AbstractDocument)
+              ((AbstractDocument) doc).setDocumentFilter(getDocumentFilter());
+            
+            // Set the NavigationFilter.
+            textField.setNavigationFilter(getNavigationFilter());
+            
+            // Set the Formatter Actions
+            // FIXME: Have to add the actions from getActions()            
+          }
+          catch (ParseException pe)
+          {
+            // Set the text to an empty String and mark the field as invalid.
+            textField.setText("");
+            setEditValid(false);
+          }
+        }
+    }
+
+    /**
+     * Clears the state installed on the JFormattedTextField by the formatter.
+     * This resets the DocumentFilter, NavigationFilter, and any additional 
+     * Actions (returned by <code>getActions()</code>).     
+     */
+    public void uninstall()
+    {
+      // Set the DocumentFilter for the field's Document.
+      Document doc = textField.getDocument();
+      if (doc instanceof AbstractDocument)
+        ((AbstractDocument) doc).setDocumentFilter(null);
+      textField.setNavigationFilter(null);
+      // FIXME: Have to remove the Actions from getActions()
+      this.textField = null;
+    }
+
+    /**
+     * Invoke this method when invalid values are entered.  This forwards the
+     * call to the JFormattedTextField.     
+     */
+    protected void invalidEdit()
+    {
+      textField.invalidEdit();
+    }
+
+    /**
+     * This method updates the <code>editValid</code> property of 
+     * JFormattedTextField.
+     * 
+     * @param valid the new state for the <code>editValid</code> property
+     */
+    protected void setEditValid(boolean valid)
+    {
+      textField.editValid = valid;
+    }
+
+    /**
+     * Parses <code>text</code> to return a corresponding Object.
+     * 
+     * @param text the String to parse
+     * @return an Object that <code>text</code> represented
+     * @throws ParseException if there is an error in the conversion
+     */
+    public abstract Object stringToValue(String text)
+      throws ParseException;
+
+    /**
+     * Returns a String to be displayed, based on the Object
+     * <code>value</code>.
+     * 
+     * @param value the Object from which to generate a String
+     * @return a String to be displayed
+     * @throws ParseException if there is an error in the conversion
+     */
+    public abstract String valueToString(Object value)
+      throws ParseException;
+  }
+
+  /**
+   * Delivers instances of an {@link AbstractFormatter} for
+   * a specific value type for a JFormattedTextField. 
+   */
+  public abstract static class AbstractFormatterFactory
+  {
+    public AbstractFormatterFactory()
+    {
+      // Do nothing here.
+    }
+
+    public abstract AbstractFormatter getFormatter(JFormattedTextField tf);
+  }
+
+  /** The possible focusLostBehavior options **/
+  public static final int COMMIT = 0;
+  public static final int COMMIT_OR_REVERT = 1;
+  public static final int REVERT = 2;
+  public static final int PERSIST = 3;
+
+  /** The most recent valid and committed value **/
+  private Object value;
+  
+  /** The behaviour for when this text field loses focus **/
+  private int focusLostBehavior = COMMIT_OR_REVERT;
+  
+  /** The formatter factory currently being used **/
+  private AbstractFormatterFactory formatterFactory;
+  
+  /** The formatter currently being used **/
+  private AbstractFormatter formatter;
+  
+  // Package-private to avoid an accessor method.
+  boolean editValid = true;
+  
+  /**
+   * Creates a JFormattedTextField with no formatter factory.  
+   * <code>setValue</code> or <code>setFormatterFactory</code> will 
+   * properly configure this text field to edit a particular type
+   * of value.
+   */
+  public JFormattedTextField()
+  {
+    this((AbstractFormatterFactory) null, null);
+  }
+
+  /**
+   * Creates a JFormattedTextField that can handle the specified Format.  
+   * An appopriate AbstractFormatter and AbstractFormatterFactory will 
+   * be created for the specified Format.
+   * 
+   * @param format the Format that this JFormattedTextField should be able
+   * to handle
+   */
+  public JFormattedTextField(Format format)
+  {
+    this ();
+    setFormatterFactory(getAppropriateFormatterFactory(format));
+  }
+
+  /**
+   * Creates a JFormattedTextField with the specified formatter.  This will 
+   * create a {@link DefaultFormatterFactory} with this formatter as the default
+   * formatter.
+   * 
+   * @param formatter the formatter to use for this JFormattedTextField
+   */
+  public JFormattedTextField(AbstractFormatter formatter)
+  {
+    this(new DefaultFormatterFactory(formatter));
+  }
+
+  /**
+   * Creates a JFormattedTextField with the specified formatter factory.
+   * 
+   * @param factory the formatter factory to use for this JFormattedTextField
+   */
+  public JFormattedTextField(AbstractFormatterFactory factory)
+  {
+    setFormatterFactory(factory);
+  }
+
+  /**
+   * Creates a JFormattedTextField with the specified formatter factory and
+   * initial value.
+   * 
+   * @param factory the initial formatter factory for this JFormattedTextField
+   * @param value the initial value for the text field
+   */
+  public JFormattedTextField(AbstractFormatterFactory factory, Object value)
+  {    
+    setFormatterFactory(factory);
+    setValue(value);
+  }
+
+  /**
+   * Creates a JFormattedTextField with the specified value.  This creates a
+   * formatter and formatterFactory that are appropriate for the value.
+   * 
+   * @param value the initial value for this JFormattedTextField
+   */
+  public JFormattedTextField(Object value)
+  {
+    setValue(value);
+  }
+  
+  /**
+   * Returns an AbstractFormatterFactory that will give an appropriate
+   * AbstractFormatter for the given Format.
+   * @param format the Format to match with an AbstractFormatter.
+   * @return a DefaultFormatterFactory whose defaultFormatter is appropriate
+   * for the given Format.
+   */
+  private AbstractFormatterFactory getAppropriateFormatterFactory(Format format)
+  {
+    AbstractFormatter newFormatter;
+    if (format instanceof DateFormat)
+      newFormatter = new DateFormatter((DateFormat) format);
+    else if (format instanceof NumberFormat)
+      newFormatter = new NumberFormatter ((NumberFormat) format);
+    else
+      newFormatter = new InternationalFormatter(format);
+    
+    return new DefaultFormatterFactory(newFormatter);
+  }
+
+  /**
+   * Forces the current value from the editor to be set as the current
+   * value.  If there is no current formatted this has no effect.
+   * 
+   * @throws ParseException if the formatter cannot format the current value
+   */
+  public void commitEdit()
+    throws ParseException
+  {
+    if (formatter == null)
+      return;
+    // Note: this code is a lot like setValue except that we don't want
+    // to create a new formatter.
+    Object oldValue = this.value;
+    
+    this.value = formatter.stringToValue(getText());;
+    editValid = true;
+    
+    firePropertyChange("value", oldValue, this.value); 
+  }
+
+  /**
+   * Gets the command list supplied by the UI augmented by the specific
+   * Actions for JFormattedTextField.
+   * 
+   * @return an array of Actions that this text field supports
+   */
+  public Action[] getActions()
+  {
+    // FIXME: Add JFormattedTextField specific actions
+    // These are related to committing or cancelling edits.
+    return super.getActions();
+  }
+
+  /**
+   * Returns the behaviour of this JFormattedTextField upon losing focus.  This
+   * is one of <code>COMMIT</code>, <code>COMMIT_OR_REVERT</code>, 
+   * <code>PERSIST</code>, or <code>REVERT</code>.  
+   * @return the behaviour upon losing focus
+   */
+  public int getFocusLostBehavior()
+  {
+    return focusLostBehavior;
+  }
+
+  /**
+   * Returns the current formatter used for this JFormattedTextField.
+   * @return the current formatter used for this JFormattedTextField
+   */
+  public AbstractFormatter getFormatter()
+  {
+    return formatter;
+  }
+  
+  /**
+   * Returns the factory currently used to generate formatters for this
+   * JFormattedTextField.
+   * @return the factory currently used to generate formatters
+   */
+  public AbstractFormatterFactory getFormatterFactory()
+  {
+    return formatterFactory;
+  }
+
+  public String getUIClassID()
+  {
+    return "FormattedTextFieldUI";
+  }
+
+  /**
+   * Returns the last valid value.  This may not be the value currently shown 
+   * in the text field depending on whether or not the formatter commits on 
+   * valid edits and allows invalid input to be temporarily displayed.  
+   * @return the last committed valid value
+   */
+  public Object getValue()
+  {
+    return value;
+  }
+
+  /**
+   * This method is used to provide feedback to the user when an invalid value
+   * is input during editing.   
+   */
+  protected void invalidEdit()
+  {
+    UIManager.getLookAndFeel().provideErrorFeedback(this);
+  }
+
+  /**
+   * Returns true if the current value being edited is valid.  This property is
+   * managed by the current formatted.
+   * @return true if the value being edited is valid.
+   */
+  public boolean isEditValid()
+  {
+    return editValid;
+  }
+
+  /**
+   * Processes focus events.  This is overridden because we may want to 
+   * change the formatted depending on whether or not this field has 
+   * focus.
+   * 
+   * @param evt the FocusEvent
+   */
+  protected void processFocusEvent(FocusEvent evt)
+  {
+    super.processFocusEvent(evt);
+    // Let the formatterFactory change the formatter for this text field
+    // based on whether or not it has focus.
+    setFormatter (formatterFactory.getFormatter(this));
+  }
+  
+  /**
+   * Associates this JFormattedTextField with a Document and propagates
+   * a PropertyChange event to each listener.
+   * 
+   * @param newDocument the Document to associate with this text field
+   */
+  public void setDocument(Document newDocument)
+  {
+    // FIXME: This method should do more than this.  Must do some handling
+    // of the DocumentListeners.
+    Document oldDocument = getDocument();
+
+    if (oldDocument == newDocument)
+      return;
+    
+    super.setDocument(newDocument);
+  }
+
+  /**
+   * Sets the behaviour of this JFormattedTextField upon losing focus.
+   * This must be <code>COMMIT</code>, <code>COMMIT_OR_REVERT</code>, 
+   * <code>PERSIST</code>, or <code>REVERT</code> or an 
+   * IllegalArgumentException will be thrown.
+   * 
+   * @param behavior
+   * @throws IllegalArgumentException if <code>behaviour</code> is not 
+   * one of the above
+   */
+  public void setFocusLostBehavior(int behavior)
+  {
+    if (behavior != COMMIT
+	&& behavior != COMMIT_OR_REVERT
+	&& behavior != PERSIST
+	&& behavior != REVERT)
+      throw new IllegalArgumentException("invalid behavior");
+
+    this.focusLostBehavior = behavior;
+  }
+
+  /**
+   * Sets the formatter for this JFormattedTextField.  Normally the formatter
+   * factory will take care of this, or calls to setValue will also make sure
+   * that the formatter is set appropriately.  
+   * 
+   * @param formatter the AbstractFormatter to use for formatting the value for
+   * this JFormattedTextField
+   */
+  protected void setFormatter(AbstractFormatter formatter)
+  {
+    AbstractFormatter oldFormatter = null;
+    
+    oldFormatter = this.formatter;
+
+    if (oldFormatter != null)
+      oldFormatter.uninstall();
+    
+    this.formatter = formatter;
+    
+    if (formatter != null)
+      formatter.install(this);
+
+    firePropertyChange("formatter", oldFormatter, formatter);
+  }
+
+  /**
+   * Sets the factory from which this JFormattedTextField should obtain 
+   * its formatters.  
+   * 
+   * @param factory the AbstractFormatterFactory that will be used to generate
+   * formatters for this JFormattedTextField
+   */
+  public void setFormatterFactory(AbstractFormatterFactory factory)
+  {
+    if (formatterFactory == factory)
+      return;
+    
+    AbstractFormatterFactory oldFactory = formatterFactory;
+    formatterFactory = factory;
+    firePropertyChange("formatterFactory", oldFactory, factory);
+    
+    // Now set the formatter according to our new factory.
+    if (formatterFactory != null)
+      setFormatter(formatterFactory.getFormatter(this));
+    else
+      setFormatter(null);
+  }
+
+  /**
+   * Sets the value that will be formatted and displayed.
+   *   
+   * @param newValue the value to be formatted and displayed
+   */
+  public void setValue(Object newValue)
+  {
+    if (value == newValue)
+      return;
+
+    Object oldValue = value;
+    value = newValue;
+    
+    // If there is no formatterFactory then make one.
+    if (formatterFactory == null)
+      setFormatterFactory(createFormatterFactory(newValue));
+    
+    // Set the formatter appropriately.  This is because there may be a new
+    // formatterFactory from the line above, or we may want a new formatter
+    // depending on the type of newValue (or if newValue is null).
+    setFormatter (formatterFactory.getFormatter(this));
+    firePropertyChange("value", oldValue, newValue);
+  }
+
+  /**
+   * A helper method that attempts to create a formatter factory that is 
+   * suitable to format objects of the type like <code>value</code>.
+   *
+   * @param value an object which should be formatted by the formatter factory.
+   *
+   * @return a formatter factory able to format objects of the class of
+   *     <code>value</code>
+   */
+  AbstractFormatterFactory createFormatterFactory(Object value)
+  {
+    AbstractFormatter formatter = null;
+    if (value instanceof Date)
+      formatter = new DateFormatter();
+    else if (value instanceof Number)
+      formatter = new NumberFormatter();
+    else
+      formatter = new DefaultFormatter();        
+    return new DefaultFormatterFactory(formatter);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFrame.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFrame.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFrame.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JFrame.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,421 @@
+/* JFrame.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.AWTEvent;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.LayoutManager;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+
+/**
+ * A window that supports window decorations (titlebar and borders).
+ * This is an extension of {@link java.awt.Frame} that provides support
+ * for the Swing architecture. Most importantly it contains a {@link JRootPane}
+ * as it's only top-level child, that manages the content pane, the menu and
+ * a glass pane.
+ *
+ * Also, unlike <code>java.awt.Frame</code>s, JFrames support the
+ * Swing Pluggable Look & Feel architecture.
+ * 
+ * @author Ronald Veldema (rveldema at cs.vu.nl)
+ */
+public class JFrame extends Frame
+  implements WindowConstants, RootPaneContainer, Accessible
+{
+  /**
+   * Provides accessibility support for <code>JFrame</code>s.
+   */
+  protected class AccessibleJFrame extends Frame.AccessibleAWTFrame
+  {
+    /**
+     * Creates a new instance of <code>AccessibleJFrame</code>.
+     */
+    protected AccessibleJFrame()
+    {
+      super();
+      // Nothing to do here.
+    }
+  }
+
+  /**
+   * A flag for {@link #setDefaultCloseOperation(int)}, indicating that the
+   * application should be exited, when this <code>JFrame</code> is closed.
+   * Note that in version 1.4, the equivalent constant has been added to
+   * {@link WindowConstants}.
+   *
+   * @since 1.3
+   */
+  public static final int EXIT_ON_CLOSE = 3;
+
+  private static final long serialVersionUID = -3362141868504252139L;
+  private static boolean defaultLookAndFeelDecorated;
+  private int closeAction = HIDE_ON_CLOSE;
+  protected AccessibleContext accessibleContext;
+  protected JRootPane rootPane;
+  
+  /**
+   * @specnote rootPaneCheckingEnabled is false to comply with J2SE 5.0
+   */
+  protected boolean rootPaneCheckingEnabled = false;
+
+  /**
+   * Creates a new frame with an empty string for the title.
+   */
+  public JFrame()
+  {
+    super("");
+    frameInit();
+  }
+
+  /**
+   * Creates a new <code>JFrame</code> with the specified title.
+   * 
+   * @param title  the frame title (<code>null</code> permitted).
+   */
+  public JFrame(String title)
+  {
+    super(title);
+    frameInit();
+  }
+
+  /**
+   * Creates a new JFrame in the specified {@link GraphicsConfiguration}
+   * and with an empty title.
+   *
+   * @param gc the <code>GraphicsConfiguration</code> that is used for
+   *     the new <code>JFrame</code>
+   *
+   * @see Frame#Frame(GraphicsConfiguration)
+   */
+  public JFrame(GraphicsConfiguration gc)
+  {
+    super(gc);
+    frameInit();
+  }
+
+  /**
+   * Creates a new JFrame in the specified {@link GraphicsConfiguration}
+   * and with the specified title.
+   *
+   * @param title the title for the new <code>JFrame</code>
+   * @param gc the <code>GraphicsConfiguration</code> that is used for
+   *     the new <code>JFrame</code>
+   *
+   * @see Frame#Frame(String, GraphicsConfiguration)
+   */
+  public JFrame(String title, GraphicsConfiguration gc)
+  {
+    super(title, gc);
+    frameInit();
+  }
+
+  protected void frameInit()
+  {
+    super.setLayout(new BorderLayout());
+    setBackground(UIManager.getDefaults().getColor("control"));
+    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+    getRootPane(); // will do set/create
+
+    // Setup the defaultLookAndFeelDecoration if requested.
+    if (isDefaultLookAndFeelDecorated()
+        && UIManager.getLookAndFeel().getSupportsWindowDecorations())
+      {
+        setUndecorated(true);
+        getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
+      }
+
+    // We're now done the init stage.
+    setRootPaneCheckingEnabled(true);
+  }
+
+  public Dimension getPreferredSize()
+  {
+    return super.getPreferredSize();
+  }
+
+  public JMenuBar getJMenuBar()
+  {
+    return getRootPane().getJMenuBar();
+  }
+
+  public void setJMenuBar(JMenuBar menubar)
+  {
+    getRootPane().setJMenuBar(menubar);
+  }
+
+  public void setLayout(LayoutManager manager)
+  {
+    // Check if we're in initialization stage.  If so, call super.setLayout
+    // otherwise, valid calls go to the content pane.
+    if (isRootPaneCheckingEnabled())
+      getContentPane().setLayout(manager);
+    else
+      super.setLayout(manager);
+  }
+
+  public void setLayeredPane(JLayeredPane layeredPane)
+  {
+    getRootPane().setLayeredPane(layeredPane);
+  }
+
+  public JLayeredPane getLayeredPane()
+  {
+    return getRootPane().getLayeredPane();
+  }
+
+  public JRootPane getRootPane()
+  {
+    if (rootPane == null)
+      setRootPane(createRootPane());
+    return rootPane;
+  }
+
+  protected void setRootPane(JRootPane root)
+  {
+    if (rootPane != null)
+      remove(rootPane);
+
+    rootPane = root;
+    add(rootPane, BorderLayout.CENTER);
+  }
+
+  protected JRootPane createRootPane()
+  {
+    return new JRootPane();
+  }
+
+  public Container getContentPane()
+  {
+    return getRootPane().getContentPane();
+  }
+
+  public void setContentPane(Container contentPane)
+  {
+    getRootPane().setContentPane(contentPane);
+  }
+
+  public Component getGlassPane()
+  {
+    return getRootPane().getGlassPane();
+  }
+
+  public void setGlassPane(Component glassPane)
+  {
+    getRootPane().setGlassPane(glassPane);
+  }
+
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    // If we're adding in the initialization stage use super.add.
+    // Otherwise pass the add onto the content pane.
+    if (isRootPaneCheckingEnabled())
+      getContentPane().add(comp,constraints,index);
+    else
+      super.addImpl(comp, constraints, index);
+  }
+
+  public void remove(Component comp)
+  {
+    // If we're removing the root pane, use super.remove. Otherwise
+    // pass it on to the content pane instead.
+    if (comp==rootPane)
+      super.remove(rootPane);
+    else
+      getContentPane().remove(comp);
+  }
+
+  protected boolean isRootPaneCheckingEnabled()
+  {
+    return rootPaneCheckingEnabled;
+  }
+
+  protected void setRootPaneCheckingEnabled(boolean enabled)
+  {
+    rootPaneCheckingEnabled = enabled;
+  }
+
+  public void update(Graphics g)
+  {
+    paint(g);
+  }
+
+  protected void processKeyEvent(KeyEvent e)
+  {
+    super.processKeyEvent(e);
+  }
+
+  public static void setDefaultLookAndFeelDecorated(boolean decorated)
+  {
+    defaultLookAndFeelDecorated = decorated;
+  }
+
+  public static boolean isDefaultLookAndFeelDecorated()
+  {
+    return defaultLookAndFeelDecorated;
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this 
+   * <code>JFrame</code>.
+   *
+   * @return The accessible context (an instance of {@link AccessibleJFrame}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJFrame();
+    return accessibleContext;
+  }
+
+  /**
+   * Returns a code for the default operation when the frame is closed.  The
+   * default value is {@link WindowConstants#HIDE_ON_CLOSE}.
+   * 
+   * @return One of: {@link WindowConstants#DO_NOTHING_ON_CLOSE},
+   *     {@link WindowConstants#HIDE_ON_CLOSE}, 
+   *     {@link WindowConstants#DISPOSE_ON_CLOSE}, {@link #EXIT_ON_CLOSE}.
+   * 
+   * @see #setDefaultCloseOperation(int)
+   */
+  public int getDefaultCloseOperation()
+  {
+    return closeAction;
+  }
+
+  /**
+   * Returns a string describing the attributes for the <code>JFrame</code>,
+   * for use in debugging.  The return value is guaranteed to be 
+   * non-<code>null</code>, but the format may vary between implementations.
+   * 
+   * @return A string describing the attributes of the <code>JFrame</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",defaultCloseOperation=");
+    sb.append(SwingUtilities.convertWindowConstantToString(
+        getDefaultCloseOperation()));
+    sb.append(",rootPane=");
+    if (rootPane != null)
+      sb.append(rootPane);
+    sb.append(",rootPaneCheckingEnabled=").append(rootPaneCheckingEnabled);
+    return sb.toString();
+  }
+
+  protected void processWindowEvent(WindowEvent e)
+  {
+    super.processWindowEvent(e);
+    switch (e.getID())
+      {
+      case WindowEvent.WINDOW_CLOSING:
+        {
+	  switch (closeAction)
+	    {
+	    case EXIT_ON_CLOSE:
+	      {
+		System.exit(0);
+		break;
+	      }
+	    case DISPOSE_ON_CLOSE:
+	      {
+		dispose();
+		break;
+	      }
+	    case HIDE_ON_CLOSE:
+	      {
+		setVisible(false);
+		break;
+	      }
+	    case DO_NOTHING_ON_CLOSE:
+	      break;
+	    }
+	  break;
+        }
+      case WindowEvent.WINDOW_CLOSED:
+      case WindowEvent.WINDOW_OPENED:
+      case WindowEvent.WINDOW_ICONIFIED:
+      case WindowEvent.WINDOW_DEICONIFIED:
+      case WindowEvent.WINDOW_ACTIVATED:
+      case WindowEvent.WINDOW_DEACTIVATED:
+	break;
+      }
+  }
+
+  /**
+   * Sets the default operation that is performed when this frame is closed.
+   * The default is <code>HIDE_ON_CLOSE</code>.  When 
+   * <code>EXIT_ON_CLOSE</code> is specified this method calls
+   * <code>SecurityManager.checkExit(0)</code> which might throw a
+   * <code>SecurityException</code>.
+   * 
+   * @param operation  a code for the operation (one of: 
+   *     {@link WindowConstants#DO_NOTHING_ON_CLOSE}, 
+   *     {@link WindowConstants#HIDE_ON_CLOSE}, 
+   *     {@link WindowConstants#DISPOSE_ON_CLOSE} and 
+   *     {@link WindowConstants#EXIT_ON_CLOSE}).
+   * 
+   * @throws IllegalArgumentException if <code>operation</code> is not one of
+   *     the specified codes.
+   * 
+   * @see #getDefaultCloseOperation()
+   */
+  public void setDefaultCloseOperation(int operation)
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null && operation == EXIT_ON_CLOSE)
+      sm.checkExit(0);
+
+    if (operation != EXIT_ON_CLOSE && operation != DISPOSE_ON_CLOSE
+        && operation != HIDE_ON_CLOSE && operation != DO_NOTHING_ON_CLOSE)
+      throw new IllegalArgumentException("operation must be EXIT_ON_CLOSE, " 
+          + "HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or DO_NOTHING_ON_CLOSE");
+
+    closeAction = operation;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JInternalFrame.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JInternalFrame.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JInternalFrame.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JInternalFrame.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1820 @@
+/* JInternalFrame.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Graphics;
+import java.awt.IllegalComponentStateException;
+import java.awt.KeyboardFocusManager;
+import java.awt.LayoutManager;
+import java.awt.Rectangle;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyVetoException;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleValue;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.InternalFrameListener;
+import javax.swing.plaf.DesktopIconUI;
+import javax.swing.plaf.InternalFrameUI;
+
+/**
+ * This class implements a Swing widget that looks and acts like a native
+ * frame. The frame can be dragged, resized, closed, etc. Typically,
+ * JInternalFrames are placed in JDesktopPanes. The actions that the
+ * JInternalFrame performs (maximizing, minimizing, etc.) are performed by a
+ * DesktopManager. As with regular frames, components are added by calling
+ * frame.getContentPane().add.
+ */
+public class JInternalFrame extends JComponent implements Accessible,
+                                                          WindowConstants,
+                                                          RootPaneContainer
+{
+
+  private static final long serialVersionUID = -5425177187760785402L;
+
+  /**
+   * Provides the accessibility features for the <code>JInternalFrame</code>
+   * component.
+   */
+  protected class AccessibleJInternalFrame extends AccessibleJComponent
+    implements AccessibleValue
+  {
+    private static final long serialVersionUID = 5931936924175476797L;
+
+    /**
+     * Creates a new <code>AccessibleJInternalFrame</code> instance.
+     */
+    protected AccessibleJInternalFrame()
+    {
+      super();
+    }
+
+    /**
+     * Returns the frame title.
+     *
+     * @return The frame title.
+     */
+    public String getAccessibleName()
+    {
+      return getTitle();
+    }
+
+    /**
+     * Returns the accessible role for the <code>JInternalFrame</code> 
+     * component.
+     *
+     * @return {@link AccessibleRole#INTERNAL_FRAME}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.INTERNAL_FRAME;
+    }
+
+    /**
+     * Returns an object that provides access to the current, minimum and 
+     * maximum values for the {@link JInternalFrame}.  Since this class 
+     * implements {@link AccessibleValue}, it returns itself.
+     *
+     * @return The accessible value.
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the current layer for the {@link JInternalFrame} component, 
+     * as an {@link Integer}.
+     *
+     * @return The layer for the {@link JInternalFrame} component.
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return new Integer(getLayer());
+    }
+
+    /**
+     * Returns the maximum permitted accessible value.
+     *
+     * @return <code>Integer(Integer.MAX_VALUE)</code>.
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return new Integer(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Returns the minimum permitted accessible value.
+     *
+     * @return <code>Integer(Integer.MIN_VALUE)</code>.
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return new Integer(Integer.MIN_VALUE);
+    }
+
+    /**
+     * Sets the layer for the internal frame.
+     *
+     * @param n  the layer (see the constants defined in {@link JLayeredPane}).
+     *
+     * @return <code>true</code> if the value is set, and <code>false</code>
+     *         if it was not set.
+     */
+    public boolean setCurrentAccessibleValue(Number n)
+    {
+      if (n == null)
+        return false;
+      setLayer(n.intValue());
+      return true;
+    }
+  }
+
+  /**
+   * This class represents the JInternalFrame while it is iconified.
+   */
+  public static class JDesktopIcon extends JComponent implements Accessible
+  {
+    /**
+     * Provides the accessibility features for the <code>JDesktopIcon</code>
+     * component.
+     */
+    protected class AccessibleJDesktopIcon extends AccessibleJComponent
+      implements AccessibleValue
+    {
+      private static final long serialVersionUID = 5035560458941637802L;
+
+      /**
+       * Creates a new <code>AccessibleJDesktopIcon</code> instance.
+       */
+      protected AccessibleJDesktopIcon()
+      {
+        super();
+      }
+
+      /**
+       * Returns the accessible role for the <code>JDesktopIcon</code> 
+       * component.
+       *
+       * @return {@link AccessibleRole#DESKTOP_ICON}.
+       */
+      public AccessibleRole getAccessibleRole()
+      {
+        return AccessibleRole.DESKTOP_ICON;
+      }
+
+      /**
+       * Returns an object that provides access to the current, minimum and 
+       * maximum values for the {@link JDesktopIcon}.  Since this class 
+       * implements {@link AccessibleValue}, it returns itself.
+       *
+       * @return The accessible value.
+       */
+      public AccessibleValue getAccessibleValue()
+      {
+        return this;
+      }
+
+      /**
+       * Returns the current layer for the {@link JInternalFrame} component
+       * represented by this <code>JDesktopIcon</code>, as an {@link Integer}.
+       *
+       * @return The layer.
+       */
+      public Number getCurrentAccessibleValue()
+      {
+        return new Integer(frame.getLayer());
+      }
+
+      /**
+       * Returns the maximum permitted accessible value.
+       *
+       * @return <code>Integer(Integer.MAX_VALUE)</code>.
+       */
+      public Number getMaximumAccessibleValue()
+      {
+        return new Integer(Integer.MAX_VALUE);
+      }
+
+      /**
+       * Returns the minimum permitted accessible value.
+       *
+       * @return <code>Integer(Integer.MIN_VALUE)</code>.
+       */
+      public Number getMinimumAccessibleValue()
+      {
+        return new Integer(Integer.MIN_VALUE);
+      }
+
+      /**
+       * Sets the layer for the internal frame represented by this 
+       * <code>JDesktopIcon</code> component.
+       *
+       * @param n  the layer (see the constants defined in 
+       *           {@link JLayeredPane}).
+       *
+       * @return <code>true</code> if the value is set, and <code>false</code>
+       *         if it was not set.
+       */
+      public boolean setCurrentAccessibleValue(Number n)
+      {
+        if (n == null)
+          return false;
+        frame.setLayer(n.intValue());
+        return true;
+      }
+    }
+
+    private static final long serialVersionUID = 4672973344731387687L;
+
+    /** The JInternalFrame this DesktopIcon represents. */
+    JInternalFrame frame;
+
+    /**
+     * Creates a new JDesktopIcon object for representing the given frame.
+     *
+     * @param f The JInternalFrame to represent.
+     */
+    public JDesktopIcon(JInternalFrame f)
+    {
+      frame = f;
+      updateUI();
+    }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JDesktopIcon</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *         {@link AccessibleJDesktopIcon}).
+   */
+    public AccessibleContext getAccessibleContext()
+    {
+      if (accessibleContext == null)
+        accessibleContext = new AccessibleJDesktopIcon();
+      return accessibleContext;
+    }
+
+    /**
+     * This method returns the JDesktopPane this JDesktopIcon is in.
+     *
+     * @return The JDesktopPane this JDesktopIcon is in.
+     */
+    public JDesktopPane getDesktopPane()
+    {
+      JDesktopPane p = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                                        this);
+      return p;
+    }
+
+    /**
+     * This method returns the JInternalFrame this JDesktopIcon represents.
+     *
+     * @return The JInternalFrame this JDesktopIcon represents.
+     */
+    public JInternalFrame getInternalFrame()
+    {
+      return frame;
+    }
+
+    /**
+     * This method returns the UI that is responsible for the JDesktopIcon.
+     *
+     * @return The UI that is responsible for the JDesktopIcon.
+     */
+    public DesktopIconUI getUI()
+    {
+      return (DesktopIconUI) ui;
+    }
+
+    /**
+     * This method returns the String identifier that is used to determine
+     * which class is used for JDesktopIcon's UI.
+     *
+     * @return A String identifier for the UI class.
+     */
+    public String getUIClassID()
+    {
+      return "DesktopIconUI";
+    }
+
+    /**
+     * This method sets the JInternalFrame that this JDesktopIcon represents.
+     *
+     * @param f The JInternalFrame that this JDesktopIcon represents.
+     */
+    public void setInternalFrame(JInternalFrame f)
+    {
+      frame = f;
+    }
+
+    /**
+     * This method sets the UI used for this JDesktopIcon.
+     *
+     * @param ui The UI to use.
+     */
+    public void setUI(DesktopIconUI ui)
+    {
+      super.setUI(ui);
+    }
+
+    /**
+     * This method restores the UI property to the defaults.
+     */
+    public void updateUI()
+    {
+      setUI((DesktopIconUI) UIManager.getUI(this));
+    }
+  }
+
+  /**
+   * The property fired in a PropertyChangeEvent when the contentPane property
+   * changes.
+   */
+  public static final String CONTENT_PANE_PROPERTY = "contentPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the frameIcon property
+   * changes.
+   */
+  public static final String FRAME_ICON_PROPERTY = "frameIcon";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the glassPane property
+   * changes.
+   */
+  public static final String GLASS_PANE_PROPERTY = "glassPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the closed property
+   * changes.
+   */
+  public static final String IS_CLOSED_PROPERTY = "closed";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the icon property
+   * changes.
+   */
+  public static final String IS_ICON_PROPERTY = "icon";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the maximum property
+   * changes.
+   */
+  public static final String IS_MAXIMUM_PROPERTY = "maximum";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the selected property
+   * changes.
+   */
+  public static final String IS_SELECTED_PROPERTY = "selected";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the layeredPane property
+   * changes.
+   */
+  public static final String LAYERED_PANE_PROPERTY = "layeredPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the jMenuBar property
+   * changes.
+   */
+  public static final String MENU_BAR_PROPERTY = "JMenuBar";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the rootPane property
+   * changes.
+   */
+  public static final String ROOT_PANE_PROPERTY = "rootPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the title property
+   * changes.
+   */
+  public static final String TITLE_PROPERTY = "title";
+
+  /** Whether the JInternalFrame is closable. */
+  protected boolean closable;
+
+  /** Whether the JInternalFrame can be iconified. */
+  protected boolean iconable;
+
+  /** Whether the JInternalFrame is closed. */
+  protected boolean isClosed;
+
+  /** Whether the JInternalFrame has been iconified. */
+  protected boolean isIcon;
+
+  /** Whether the JInternalFrame has been maximized. */
+  protected boolean isMaximum;
+
+  /** Whether the JInternalFrame is the active frame. */
+  protected boolean isSelected;
+
+  /** Whether the JInternalFrame can be maximized. */
+  protected boolean maximizable;
+
+  /**
+   * Whether the JInternalFrame has rootPaneChecking enabled.
+   *
+   * @specnote Should be false to comply with J2SE 5.0
+   */
+  protected boolean rootPaneCheckingEnabled = false;
+
+  /** Whether the JInternalFrame is resizable. */
+  protected boolean resizable;
+
+  /**
+   * The JDesktopIcon that represents the JInternalFrame while it is
+   * iconified.
+   */
+  protected JDesktopIcon desktopIcon;
+
+  /** The icon used in the JMenuBar in the TitlePane. */
+  protected Icon frameIcon;
+
+  /** The rootPane of the JInternalFrame. */
+  protected JRootPane rootPane;
+
+  /** The title on the TitlePane of the JInternalFrame. */
+  protected String title;
+
+  /** The bounds of the JInternalFrame before it was maximized. */
+  private transient Rectangle storedBounds;
+
+  /** The Component that receives focus by default. */
+  private transient Component defaultFocus;
+
+  /** The default close action taken, */
+  private transient int defaultCloseOperation = DISPOSE_ON_CLOSE;
+
+  /** Whether the JInternalFrame has become visible for the very first time. */
+  private transient boolean isFirstTimeVisible = true;
+
+  /** DOCUMENT ME! */
+  private transient boolean wasIcon = false;
+
+  /**
+   * Creates a new JInternalFrame object that has an empty string for its 
+   * title, and is non-resizable, non-maximizable, non-iconifiable, and 
+   * non-closable.
+   */
+  public JInternalFrame()
+  {
+    this("", false, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title and is
+   * non-resizable, non-maximizable, non-iconifiable, and non-closable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   */
+  public JInternalFrame(String title)
+  {
+    this(title, false, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title and resizable
+   * properties. The JInternalFrame is non-maximizable, non-iconifiable, and
+   * non-closable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   */
+  public JInternalFrame(String title, boolean resizable)
+  {
+    this(title, resizable, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable, and
+   * closable properties. The JInternalFrame is non-maximizable and
+   * non-iconifiable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable)
+  {
+    this(title, resizable, closable, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable,
+   * closable and maximizable properties. The JInternalFrame is
+   * non-iconifiable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   * @param maximizable Whether the JInternalFrame is maximizable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable,
+                        boolean maximizable)
+  {
+    this(title, resizable, closable, maximizable, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable,
+   * closable, maximizable and iconifiable properties.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   * @param maximizable Whether the JInternalFrame is maximizable.
+   * @param iconifiable Whether the JInternalFrame is iconifiable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable,
+                        boolean maximizable, boolean iconifiable)
+  {
+    this.title = title;
+    this.resizable = resizable;
+    this.closable = closable;
+    this.maximizable = maximizable;
+    this.iconable = iconifiable;
+    isMaximum = false;
+    setRootPane(createRootPane());
+    // JInternalFrames are invisible and opaque by default.
+    setVisible(false);
+    setOpaque(true);
+    desktopIcon = new JDesktopIcon(this);
+    updateUI();
+    setRootPaneCheckingEnabled(true); // Done the init stage, now adds go to content pane.
+  }
+
+  /**
+   * This method adds Components to this Container. For JInternalFrames,
+   * instead of calling add directly on the JInternalFrame, it should be
+   * called with JInternalFrame.getContentPane().add. If root pane checking
+   * is enabled, calling this method will cause an exception to be thrown.
+   *
+   * @param comp The Component to add.
+   * @param constraints The constraints on the Component added.
+   * @param index The position to place the Component.
+   *
+   * @throws Error DOCUMENT ME!
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    // If we're in the initialization stage use super.add. Here we add the
+    // rootPane as well as the title bar and other stuff.
+    // Otherwise pass the add onto the content pane.
+    if (isRootPaneCheckingEnabled())
+      getContentPane().add(comp, constraints, index);
+    else
+      super.addImpl(comp,constraints, index);
+  }
+
+  /**
+   * This method adds an InternalFrameListener to this JInternalFrame.
+   *
+   * @param l The listener to add.
+   */
+  public void addInternalFrameListener(InternalFrameListener l)
+  {
+    listenerList.add(InternalFrameListener.class, l);
+  }
+
+  /**
+   * This method is used to create a root pane for the JInternalFrame. This
+   * method is called by the constructors.
+   *
+   * @return A root pane for the JInternalFrame to use.
+   */
+  protected JRootPane createRootPane()
+  {
+    return new JRootPane();
+  }
+
+  /**
+   * This method makes this JInternalFrame invisible, unselected and closed.
+   * If this JInternalFrame is not closed already, it will fire an
+   * INTERNAL_FRAME_CLoSED event. This method is similar to setClosed but it
+   * doesn't give vetoable listeners a chance to veto and it will not fire an
+   * INTERNAL_FRAME_CLOSING event.
+   */
+  public void dispose()
+  {
+    if (isVisible())
+      setVisible(false);
+    if (isSelected())
+      {
+        try
+          {
+            setSelected(false);
+          }
+        catch (PropertyVetoException e)
+          {
+            // Do nothing if they don't want to be unselected.
+          }
+      }
+    if (! isClosed)
+      {
+        firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
+        isClosed = true;
+      }
+    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
+  }
+
+  /**
+   * This method is used for closing this JInternalFrame. It fires an
+   * INTERNAL_FRAME_CLOSING event and then performs the action specified by
+   * the default close operation.
+   */
+  public void doDefaultCloseAction()
+  {
+    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
+    switch (getDefaultCloseOperation())
+      {
+      case HIDE_ON_CLOSE:
+	    setVisible(false);
+	    break;
+      case DISPOSE_ON_CLOSE:
+	    dispose();
+	    break;
+      }
+  }
+
+  /**
+   * This method fires an InternalFrameEvent to the listeners.
+   *
+   * @param id The type of event being fired. See InternalFrameEvent.
+   */
+  protected void fireInternalFrameEvent(int id)
+  {
+    Object[] ifListeners = listenerList.getListenerList();
+    InternalFrameEvent evt = new InternalFrameEvent(this, id);
+    switch (id)
+      {
+      case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameClosing(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameActivated(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1]).internalFrameClosed(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameDeactivated(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameDeiconified(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameIconified(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_OPENED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1]).internalFrameOpened(evt);
+	  }
+	break;
+      }
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JInternalFrame</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJInternalFrame}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJInternalFrame();
+    return accessibleContext;
+  }
+
+  /**
+   * This method returns the Content Pane for this JInternalFrame.
+   *
+   * @return The Content Pane for this JInternalFrame.
+   */
+  public Container getContentPane()
+  {
+    return getRootPane().getContentPane();
+  }
+
+  /**
+   * Returns a code for the default action taken when this 
+   * <code>JInternalFrame</code> is closed.
+   *
+   * @return The action code (usually one of 
+   *     {@link WindowConstants#DO_NOTHING_ON_CLOSE}, 
+   *     {@link WindowConstants#HIDE_ON_CLOSE}, or 
+   *     {@link WindowConstants#DISPOSE_ON_CLOSE}).
+   * 
+   * @see #setDefaultCloseOperation(int)
+   * @see #doDefaultCloseAction()
+   */
+  public int getDefaultCloseOperation()
+  {
+    return defaultCloseOperation;
+  }
+
+  /**
+   * Returns the <code>JDesktopIcon</code> that represents this 
+   * <code>JInternalFrame</code> while it is iconified.
+   *
+   * @return The desktop icon component.
+   */
+  public JDesktopIcon getDesktopIcon()
+  {
+    return desktopIcon;
+  }
+
+  /**
+   * This method searches this JInternalFrame ancestors for an instance of
+   * JDesktopPane. If one is found, it is returned. If none is found, then it
+   * will search the JDesktopIcon for a JDesktopPane.
+   *
+   * @return The JDesktopPane that this JInternalFrame belongs to.
+   */
+  public JDesktopPane getDesktopPane()
+  {
+    JDesktopPane value = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                                          this);
+    if (value == null && desktopIcon != null)
+      value = desktopIcon.getDesktopPane();
+    return value;
+  }
+
+  /**
+   * This method returns null because this must always be the root of a focus
+   * traversal.
+   *
+   * @return always null
+   *
+   * @since 1.4
+   */
+  public final Container getFocusCycleRootAncestor()
+  {
+    // as defined.
+    return null;
+  }
+
+  /**
+   * This method returns the child Component that will receive focus if this
+   * JInternalFrame is selected.
+   *
+   * @return The child Component that will receive focus.
+   */
+  public Component getFocusOwner()
+  {
+    if (isSelected())
+      {
+	Component focus = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+	if (SwingUtilities.isDescendingFrom(focus, this))
+	  {
+	    defaultFocus = focus;
+	    return focus;
+	  }
+      }
+    return null;
+  }
+
+  /**
+   * This method returns the Frame Icon (the icon used in the JInternalFrame
+   * TitlePane and iconified frame).
+   *
+   * @return The Frame Icon.
+   */
+  public Icon getFrameIcon()
+  {
+    return frameIcon;
+  }
+
+  /**
+   * This method returns the Glass Pane used with this JInternalFrame.
+   *
+   * @return The Glass Pane used with this JInternalFrame.
+   */
+  public Component getGlassPane()
+  {
+    return getRootPane().getGlassPane();
+  }
+
+  /**
+   * This method returns an array of InternalFrameListeners that are listening
+   * to this JInternalFrame.
+   *
+   * @return An array of InternalFrameListeners that are listening to this
+   *         JInternalFrame.
+   */
+  public InternalFrameListener[] getInternalFrameListeners()
+  {
+    return (InternalFrameListener[]) listenerList.getListeners(InternalFrameListener.class);
+  }
+
+  /**
+   * This method returns the JMenuBar for this JInternalFrame.
+   *
+   * @return The JMenuBar for this JInternalFrame.
+   */
+  public JMenuBar getJMenuBar()
+  {
+    return getRootPane().getJMenuBar();
+  }
+
+  /**
+   * This method returns the layer that this JInternalFrame resides in.
+   *
+   * @return The layer that this JInternalFrame resides in.
+   */
+  public int getLayer()
+  {
+    return JLayeredPane.getLayer(this);
+  }
+
+  /**
+   * This method returns the LayeredPane for this JInternalFrame.
+   *
+   * @return The LayeredPane for this JInternalFrame.
+   */
+  public JLayeredPane getLayeredPane()
+  {
+    return getRootPane().getLayeredPane();
+  }
+
+  /**
+   * This method is deprecated. This method returns the JMenuBar for this
+   * JInternalFrame.
+   *
+   * @return The JMenuBar for this JInternalFrame.
+   *
+   * @deprecated 1.0.3
+   */
+  public JMenuBar getMenuBar()
+  {
+    return getJMenuBar();
+  }
+
+  /**
+   * This method returns the child Component that will receive focus when the
+   * JInternalFrame is selected. If the JInternalFrame is selected, this
+   * method returns getFocusOwner(). Otherwise, it will return the child
+   * Component that most recently requested focus. If that is null, then the
+   * initial focus Component is returned. If that is null, then the default
+   * focus component is returned.
+   *
+   * @return The most recent focus owner.
+   */
+  public Component getMostRecentFocusOwner()
+  {
+    if (isSelected())
+      return getFocusOwner();
+    else
+      return defaultFocus;
+  }
+
+  /**
+   * This method returns the bounds of the JInternalFrame if it is not
+   * maximized. If it is maximized, it returns the bounds of the
+   * JInternalFrame before it was maximized (the bounds that it will be
+   * restored to).
+   *
+   * @return A Rectangle that contains this JInternalFrame's normal bounds (or
+   *         just its bounds if it is not maximized).
+   */
+  public Rectangle getNormalBounds()
+  {
+    if (storedBounds == null)
+      return getBounds();
+    else
+      return storedBounds;
+  }
+
+  /**
+   * This method returns the Root Pane for this JInternalFrame.
+   *
+   * @return The Root Pane for this JInternalFrame.
+   */
+  public JRootPane getRootPane()
+  {
+    return rootPane;
+  }
+
+  /**
+   * Returns the frame's title.
+   *
+   * @return The frame's title (can be <code>null</code>).
+   * 
+   * @see #setTitle(String)
+   */
+  public String getTitle()
+  {
+    return title;
+  }
+
+  /**
+   * This method returns the UI used to represent the JInternalFrame.
+   *
+   * @return The UI used to represent the JInternalFrame.
+   */
+  public InternalFrameUI getUI()
+  {
+    return (InternalFrameUI) ui;
+  }
+
+  /**
+   * This method returns a String identifier that is used to determine which
+   * class acts as the JInternalFrame's UI.
+   *
+   * @return A String identifier to determine a UI class.
+   */
+  public String getUIClassID()
+  {
+    return "InternalFrameUI";
+  }
+
+  /**
+   * This method returns null.
+   *
+   * @return null.
+   */
+  public final String getWarningString()
+  {
+    // as defined.
+    return null;
+  }
+
+  /**
+   * This method deselects this JInternalFrame and hides it.
+   */
+  public void hide()
+  {
+    if (isIcon())
+      getDesktopIcon().hide();
+    super.hide();
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is closable.
+   *
+   * @return Whether this JInternalFrame is closable.
+   */
+  public boolean isClosable()
+  {
+    return closable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame has been closed.
+   *
+   * @return Whether this JInternalFrame is closed.
+   */
+  public boolean isClosed()
+  {
+    return isClosed;
+  }
+
+  /**
+   * This must always return true.
+   *
+   * @return always true
+   *
+   * @since 1.4
+   */
+  public final boolean isFocusCycleRoot()
+  {
+    return true;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is currently iconified.
+   *
+   * @return Whether this JInternalFrame is currently iconified.
+   */
+  public boolean isIcon()
+  {
+    return isIcon;
+  }
+
+  /**
+   * This method returns whether the JInternalFrame can be iconified.
+   *
+   * @return Whether the JInternalFrame can be iconified.
+   */
+  public boolean isIconifiable()
+  {
+    return iconable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame can be maximized.
+   *
+   * @return Whether this JInternalFrame can be maximized.
+   */
+  public boolean isMaximizable()
+  {
+    return maximizable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is currently maximized.
+   *
+   * @return Whether this JInternalFrame is maximized.
+   */
+  public boolean isMaximum()
+  {
+    return isMaximum;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is resizable.
+   *
+   * @return Whether this JInternalFrame is resizable.
+   */
+  public boolean isResizable()
+  {
+    return resizable;
+  }
+
+  /**
+   * This method returns whether root pane checking is enabled. If root pane
+   * checking is enabled, then calls to addImpl and setLayout will throw
+   * exceptions.
+   *
+   * @return Whether root pane checking is enabled.
+   */
+  protected boolean isRootPaneCheckingEnabled()
+  {
+    return rootPaneCheckingEnabled;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is selected.
+   *
+   * @return Whether this JInternalFrame is selected.
+   */
+  public boolean isSelected()
+  {
+    return isSelected;
+  }
+
+  /**
+   * A helper method that moves this JInternalFrame to the back if the parent
+   * is a JLayeredPane.
+   */
+  public void moveToBack()
+  {
+    Container p = getParent();
+    if (p instanceof JLayeredPane)
+      ((JLayeredPane) p).moveToBack(this);
+  }
+
+  /**
+   * A helper method that moves this JInternalFrame to the front if the parent
+   * is a JLayeredPane.
+   */
+  public void moveToFront()
+  {
+    Container p = getParent();
+    if (p != null && p instanceof JLayeredPane)
+      ((JLayeredPane) p).moveToFront(this);
+  }
+
+  /**
+   * This method causes the children of this JInternalFrame to be laid out.
+   * Before it begins, if this JInternalFrame is an icon, then it will be
+   * deiconified. If it is maximized, then it will be restored. If either
+   * operation fails, then this method will return.
+   */
+  public void pack()
+  {
+    try
+      {
+	if (isIcon())
+	  setIcon(false);
+	else if (isMaximum())
+	  setMaximum(false);
+      }
+    catch (PropertyVetoException e)
+      {
+	// Do nothing if they don't want to be restored first.
+      }
+    setSize(getPreferredSize());
+    validate();
+  }
+
+  /**
+   * This method is overridden to allow for speedier painting while this
+   * JInternalFramme is being dragged.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  protected void paintComponent(Graphics g)
+  {
+    super.paintComponent(g);
+  }
+
+  /**
+   * An implementation dependent string describing the current state of this 
+   * <code>JInternalFrame</code> instance.
+   *
+   * @return A string describing the current state of this 
+   *     <code>JInternalFrame</code> instance.
+   */
+  protected String paramString()
+  {
+    return super.paramString() + ",title=" + getTitle();
+  }
+
+  /**
+   * This method removes the given Component from the Container.
+   *
+   * @param comp The Component to remove.
+   */
+  public void remove(Component comp)
+  {
+    // If we're removing the root pane, use super.remove.  Otherwise
+    // pass it on to the content pane instead.
+    if (comp==rootPane || ! isRootPaneCheckingEnabled())
+      super.remove(comp);
+    else
+      getContentPane().remove(comp);
+  }
+
+  /**
+   * This method removes an InternalFrameListener from this JInternalFrame.
+   *
+   * @param l The listener to remove.
+   */
+  public void removeInternalFrameListener(InternalFrameListener l)
+  {
+    listenerList.remove(InternalFrameListener.class, l);
+  }
+
+  /**
+   * This method resizes and positions this JInternalFrame. It also forces a
+   * relayout of the Container.
+   *
+   * @param x The x position of this JInternalFrame.
+   * @param y The y position of this JInternalFrame.
+   * @param width The width of this JInternalFrame.
+   * @param height The height of this JInternalFrame.
+   */
+  public void reshape(int x, int y, int width, int height)
+  {
+    super.reshape(x, y, width, height);
+    revalidate();
+  }
+
+  /**
+   * This method gives focus to the last child Component that had focus. This
+   * is used by the UI when this JInternalFrame is activated.
+   */
+  public void restoreSubcomponentFocus()
+  {
+    Component c = getMostRecentFocusOwner();
+    if (c != null)
+      c.requestFocus();
+  }
+
+  /**
+   * This method sets whether this JInternalFrame can be closed.
+   *
+   * @param b Whether this JInternalFrame can be closed.
+   */
+  public void setClosable(boolean b)
+  {
+    if (closable != b)
+      {
+        closable = b;
+        firePropertyChange("closable", ! closable, closable);
+      }
+  }
+
+  /**
+   * This method closes the JInternalFrame if the given boolean is true. If it
+   * is false, then the result of this method is unspecified. If the
+   * JInternalFrame is closed, this method does nothing. This method will
+   * first fire an INTERNAL_FRAME_CLOSING event and give a chance for veto
+   * listeners to cancel the close. If no listener vetoes the change, the
+   * closed property is set to true and the JInternalFrame is hidden and
+   * unselected. The method will finish by firing an INTERNAL_FRAME_CLOSED
+   * event.
+   *
+   * @param b Whether the JInternalFrame will be closed.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setClosed(boolean b) throws PropertyVetoException
+  {
+    if (b && ! isClosed())
+      {
+        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
+        fireVetoableChange(IS_CLOSED_PROPERTY, false, true);
+
+        isClosed = b;
+        dispose();
+
+        firePropertyChange(IS_CLOSED_PROPERTY, false, true);
+      }
+  }
+
+  /**
+   * This method sets the Container to be used as a Content Pane for this
+   * JInternalFrame.
+   *
+   * @param c The Container to use as a Content Pane.
+   */
+  public void setContentPane(Container c)
+  {
+    if (c != getContentPane())
+      {
+	Container old = getContentPane();
+	getRootPane().setContentPane(c);
+	firePropertyChange(CONTENT_PANE_PROPERTY, old, c);
+      }
+  }
+
+  /**
+   * Sets a code for the action to be taken when this 
+   * <code>JInternalFrame</code> is closed.  Note that no validation is 
+   * performed on the <code>operation</code> code, any integer will be 
+   * accepted (nevertheless, you should pass in one of the listed values).
+   *
+   * @param operation  one of {@link WindowConstants#DO_NOTHING_ON_CLOSE}, 
+   *   {@link WindowConstants#HIDE_ON_CLOSE} or 
+   *   {@link WindowConstants#DISPOSE_ON_CLOSE}.
+   *   
+   * @see #getDefaultCloseOperation()
+   * @see #doDefaultCloseAction()
+   */
+  public void setDefaultCloseOperation(int operation)
+  {
+    /* Reference implementation allows invalid operations to be specified.
+       In that case, behaviour defaults to DO_NOTHING_ON_CLOSE.
+       processWindowEvent handles the behaviour. getDefaultCloseOperation
+       must return the invalid operator code. */
+    defaultCloseOperation = operation;
+  }
+
+  /**
+   * Sets the <code>JDesktopIcon</code> instance that represents this 
+   * <code>JInternalFrame</code> while it is iconified and, if the new icon is
+   * not the same instance as the existing icon, sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * <code>"desktopIcon"</code>) to all registered listeners..
+   *
+   * @param d  the icon.
+   * 
+   * @see #getDesktopIcon()
+   */
+  public void setDesktopIcon(JDesktopIcon d)
+  {
+    if (desktopIcon != d)
+      {
+        JDesktopIcon oldIcon = desktopIcon;
+        desktopIcon = d;
+        firePropertyChange("desktopIcon", oldIcon, d);
+      }
+  }
+
+  /**
+   * This method does nothing because this must be the root of a focus
+   * traversal cycle.
+   *
+   * @param focusCycleRoot Not used.
+   */
+  public final void setFocusCycleRoot(boolean focusCycleRoot)
+  {
+    // Do nothing
+  }
+
+  /**
+   * This method sets the Icon to be used in two places. The first is icon
+   * that is painted at the top left corner of the JInternalFrame when it is
+   * not iconified (clicking on that icon will activate the TitlePane
+   * JMenuBar). When the JInternalFrame is iconified, it will be the icon
+   * displayed in the JDesktopIcon. If no icon is set, the JInternalFrame
+   * will use a Look and Feel default.
+   *
+   * @param icon The Icon used in the TitlePane JMenuBar and iconified frames.
+   */
+  public void setFrameIcon(Icon icon)
+  {
+    if (icon != frameIcon)
+      {
+	Icon old = frameIcon;
+	frameIcon = icon;
+	firePropertyChange(FRAME_ICON_PROPERTY, old, frameIcon);
+      }
+  }
+
+  /**
+   * This method sets the Glass Pane used with this JInternalFrame.
+   *
+   * @param glass The Glass Pane to use with this JInternalFrame.
+   */
+  public void setGlassPane(Component glass)
+  {
+    if (glass != getGlassPane())
+      {
+	Component old = getGlassPane();
+	getRootPane().setGlassPane(glass);
+	firePropertyChange(GLASS_PANE_PROPERTY, old, glass);
+      }
+  }
+
+  /**
+   * This method iconifies or deiconifies this JInternalFrame given the
+   * boolean argument. If the JInternalFrame becomes iconified, it will fire
+   * an INTERNAL_FRAME_ICONIFIED event. If the JInternalFrame becomes
+   * deiconified, it will fire anINTERNAL_FRAME_DEICONIFIED event.
+   *
+   * @param b Whether this JInternalFrame is to be iconified or deiconified.
+   *
+   * @throws PropertyVetoException DOCUMENT ME!
+   */
+  public void setIcon(boolean b) throws PropertyVetoException
+  {
+    if (b != isIcon())
+      {
+	fireVetoableChange(IS_ICON_PROPERTY, b, isIcon);
+
+	isIcon = b;
+
+	firePropertyChange(IS_ICON_PROPERTY, ! isIcon, isIcon);
+	if (b)
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
+	else
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
+      }
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be iconified. (This means
+   * that the JInternalFrame can be turned into an icon if minimized).
+   *
+   * @param b Whether the JInternalFrame can be iconified.
+   */
+  public void setIconifiable(boolean b)
+  {
+    if (iconable != b)
+      {
+        iconable = b;
+        firePropertyChange("iconable", ! iconable, iconable);
+      }
+  }
+
+  /**
+   * This method sets the JMenuBar to be used with this JInternalFrame.
+   *
+   * @param b The JMenuBar to be used with this JInternalFrame.
+   */
+  public void setJMenuBar(JMenuBar b)
+  {
+    JMenuBar old = getJMenuBar();
+    getRootPane().setJMenuBar(b);
+    firePropertyChange(MENU_BAR_PROPERTY, old, b);
+  }
+
+  /**
+   * A helper method that set the layer that this JInternalFrame resides in.
+   * Using this version of the method means that the user should not set it
+   * to values that are already defined in JLayeredPane. If predefined values
+   * are to be used, the user should use the setLayer(Integer) version.
+   *
+   * @param layer The layer to place this JInternalFrame in.
+   */
+  public void setLayer(int layer)
+  {
+    setLayer(new Integer(layer));
+  }
+
+  /**
+   * A helper method that sets the layer that this JInternalFrame resides in.
+   * Calling this version of the method should use layer values that are
+   * already defined in JLayeredPane.
+   *
+   * @param layer The layer to place this JInternalFrame in.
+   */
+  public void setLayer(Integer layer)
+  {
+    Container p = getParent();
+    if (p instanceof JLayeredPane)
+      {
+        JLayeredPane lp = (JLayeredPane) p;
+        lp.setLayer(this, layer.intValue(), lp.getPosition(this));
+      }
+    else
+      {
+        JLayeredPane.putLayer(this, layer.intValue());
+        if (p != null)
+          p.repaint(getX(), getY(), getWidth(), getHeight());
+      }
+  }
+
+  /**
+   * This method sets the JLayeredPane to use with this JInternalFrame.
+   *
+   * @param layered The JLayeredPane to use as a layeredPane.
+   */
+  public void setLayeredPane(JLayeredPane layered)
+  {
+    if (layered == null)
+      throw new IllegalComponentStateException("LayeredPane must not be null");
+
+    if (layered != getLayeredPane())
+      {
+	JLayeredPane old = getLayeredPane();
+	getRootPane().setLayeredPane(layered);
+	firePropertyChange(LAYERED_PANE_PROPERTY, old, layered);
+      }
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be maximized.
+   *
+   * @param b Whether this JInternalFrame can be maximized.
+   */
+  public void setMaximizable(boolean b)
+  {
+    if (maximizable != b)
+      {
+        maximizable = b;
+        firePropertyChange("maximizable", ! maximizable, maximizable);
+      }
+  }
+
+  /**
+   * This method sets the Layout Manager used in the JInternalFrame. SetLayout
+   * should not be called on the JInternalFrame directly. Instead, it should
+   * be called with JInternalFrame.getContentPane().setLayout. Calls to this
+   * method with root pane checking enabled will cause exceptions to be
+   * thrown.
+   *
+   * @param manager The Layout Manager to be used with the JInternalFrame.
+   *
+   * @throws Error If rootPaneChecking is enabled.
+   */
+  public void setLayout(LayoutManager manager)
+  {
+    // Check if we're in initialization stage.  If so, call super.setLayout
+    // otherwise, valid calls go to the content pane.
+    if (isRootPaneCheckingEnabled())
+      getContentPane().setLayout(manager);
+    else
+      super.setLayout(manager);
+  }
+
+  /**
+   * This method sets the JInternalFrame to maximized (if the given argument
+   * is true) or restores the JInternalFrame to its normal bounds otherwise.
+   *
+   * @param b Whether this JInteralFrame will be maximized or restored.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setMaximum(boolean b) throws PropertyVetoException
+  {
+    if (b != isMaximum)
+      {
+	fireVetoableChange(IS_MAXIMUM_PROPERTY, isMaximum, b);
+	isMaximum = b;
+	firePropertyChange(IS_MAXIMUM_PROPERTY, ! isMaximum, isMaximum);
+      }
+  }
+
+  /**
+   * This method is deprecated. This method sets the JMenuBar used with this
+   * JInternalFrame.
+   *
+   * @param m The JMenuBar to use with this JInternalFrame.
+   *
+   * @deprecated 1.0.3
+   */
+  public void setMenuBar(JMenuBar m)
+  {
+    setJMenuBar(m);
+  }
+
+  /**
+   * This method sets the bounds that this JInternalFrame will be restored to.
+   *
+   * @param r The bounds that this JInternalFrame will be restored to.
+   */
+  public void setNormalBounds(Rectangle r)
+  {
+    storedBounds = r;
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be resized by a user
+   * action (like dragging at the frame borders).
+   *
+   * @param b Whether this JInternalFramer can be resized.
+   */
+  public void setResizable(boolean b)
+  {
+    if (b != resizable)
+      {
+        resizable = b;
+        firePropertyChange("resizable", ! resizable, resizable);
+      }
+  }
+
+  /**
+   * This method sets the Root Pane for this JInternalFrame.
+   *
+   * @param root The Root Pane for this JInternalFrame.
+   */
+  protected void setRootPane(JRootPane root)
+  {
+    if (rootPane != null)
+      remove(rootPane);
+
+    JRootPane old = rootPane;
+    rootPane = root;
+
+    if (rootPane != null)
+      {
+        boolean checkingEnabled = isRootPaneCheckingEnabled();
+        try
+          {
+            setRootPaneCheckingEnabled(false);
+            add(rootPane, BorderLayout.CENTER);
+          }
+        finally
+          {
+            setRootPaneCheckingEnabled(checkingEnabled);
+          }
+      }
+    firePropertyChange(ROOT_PANE_PROPERTY, old, rootPane);
+  }
+
+  /**
+   * This method sets whether root pane checking is enabled. If root pane
+   * checking is enabled, then calls to addImpl and setLayout will throw
+   * exceptions.
+   *
+   * @param enabled Whether root pane checking is enabled.
+   */
+  protected void setRootPaneCheckingEnabled(boolean enabled)
+  {
+    rootPaneCheckingEnabled = enabled;
+  }
+
+  /**
+   * This method sets whether this JInternalFrame is the selected frame in the
+   * JDesktopPane (or other container). When selected, a JInternalFrame will
+   * have focus and paint its TitlePane differently (usually a different
+   * colour). If this method selects the frame, this JInternalFrame will fire
+   * an INTERNAL_FRAME_ACTIVATED event. If it deselects this frame, it will
+   * fire an INTERNAL_FRAME_DEACTIVATED event.
+   *
+   * @param selected Whether this JInternalFrame will become selected or
+   *        deselected.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setSelected(boolean selected) throws PropertyVetoException
+  {
+    if (selected != isSelected
+        && (! selected || (isIcon ? desktopIcon.isShowing() : isShowing())))
+      {
+        fireVetoableChange(IS_SELECTED_PROPERTY, isSelected, selected);
+
+        if (! selected)
+          defaultFocus = getMostRecentFocusOwner();
+
+        isSelected = selected;
+        firePropertyChange(IS_SELECTED_PROPERTY, ! isSelected, isSelected);
+
+        if (isSelected)
+          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
+        else
+          fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
+
+        if (selected)
+          restoreSubcomponentFocus();
+
+        repaint();
+      }
+  }
+
+  /**
+   * Sets the title for the <code>JInternalFrame</code> and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * {@link #TITLE_PROPERTY}) to all registered listeners.
+   *
+   * @param title  the new title (<code>null</code> permitted).
+   * 
+   * @see #getTitle()
+   */
+  public void setTitle(String title)
+  {
+    String old = this.title;
+    this.title = title;
+    firePropertyChange(TITLE_PROPERTY, old, this.title);
+  }
+
+  /**
+   * This method displays the JInternalFrame. If it is not visible, this
+   * method will bring this JInternalFrame to the front, make it visible and
+   * select it. If this is the first time this JInternalFrame is made
+   * visible, an INTERNAL_FRAME_OPENED event will be fired.
+   */
+  public void show()
+  {
+    if (! isVisible())
+      {
+        if (isFirstTimeVisible)
+          {
+            isFirstTimeVisible = false;
+            fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
+          }
+
+        getDesktopIcon().setVisible(true);
+
+        toFront();
+        super.show();
+
+        if (isIcon())
+          return;
+
+        if (! isSelected())
+          {
+            try
+              {
+                setSelected(true);
+              }
+            catch (PropertyVetoException e)
+              {
+                // Do nothing. if they don't want to be selected.
+              }
+          }
+      }
+  }
+
+  /**
+   * This method is used to set the UI responsible for the JInternalFrame.
+   *
+   * @param ui The UI responsible for the JInternalFrame.
+   */
+  public void setUI(InternalFrameUI ui)
+  {
+    // We must temporarily go into init mode so that the UI can directly
+    // manipulate the JInternalFrame.
+    boolean old = isRootPaneCheckingEnabled();
+    setRootPaneCheckingEnabled(false);
+    super.setUI(ui);
+    setRootPaneCheckingEnabled(old);
+  }
+
+  /**
+   * This method causes the JInternalFrame to be brough to back in the
+   * z-order.
+   */
+  public void toBack()
+  {
+    moveToBack();
+  }
+
+  /**
+   * This method causes the JInternalFrame to be brought to front in the
+   * z-order.
+   */
+  public void toFront()
+  {
+    moveToFront();
+  }
+
+  /**
+   * This method resets the UI to the Look and Feel defaults.
+   */
+  public void updateUI()
+  {
+    // We must go into the init stage when updating the UI, so the UI can
+    // set layout and components directly on the internal frame, not its
+    // content pane.
+	boolean old = isRootPaneCheckingEnabled();
+    setRootPaneCheckingEnabled(false);
+    setUI((InternalFrameUI) UIManager.getUI(this));
+    setRootPaneCheckingEnabled(old);
+  }
+
+  /**
+   * This helper method allows JInternalFrames to signal that they were
+   * iconned for the first time.
+   *
+   * @param b Whether the JInternalFrame was iconned.
+   * @param ID The identifier of the property change event to fire if the
+   *        JInternalFrame is iconned for the first time.
+   */
+  void setWasIcon(boolean b, String ID)
+  {
+    if (b && ! wasIcon)
+      {
+	wasIcon = b;
+	firePropertyChange(ID, ! b, b);
+      }
+  }
+
+  /**
+   * This helper method returns whether the JInternalFrame has been iconned
+   * once already.
+   *
+   * @return Whether the JInternalFrame has been iconned once already.
+   */
+  boolean getWasIcon()
+  {
+    return wasIcon;
+  }
+
+  /**
+   * This method is a convenience method to fire vetoable property changes.
+   *
+   * @param name The identifier of the property change.
+   * @param oldValue The old value.
+   * @param newValue The new value.
+   *
+   * @throws PropertyVetoException Fired if a vetoable change listener vetoes
+   *         the change.
+   */
+  private void fireVetoableChange(String name, boolean oldValue,
+                                  boolean newValue)
+                           throws PropertyVetoException
+  {
+    super.fireVetoableChange(name, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLabel.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLabel.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLabel.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLabel.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1055 @@
+/* JLabel.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import gnu.classpath.NotImplementedException;
+
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleExtendedComponent;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleText;
+import javax.swing.plaf.LabelUI;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+
+/**
+ * A component that displays a static text message and/or an icon.
+ */
+public class JLabel extends JComponent implements Accessible, SwingConstants
+{
+
+  /**
+   * Provides the accessibility features for the <code>JLabel</code>
+   * component.
+   */
+  protected class AccessibleJLabel
+    extends JComponent.AccessibleJComponent
+    implements AccessibleText, AccessibleExtendedComponent
+  {
+    
+    /**
+     * Returns the accessible name.
+     * 
+     * @return The accessible name.
+     */
+    public String getAccessibleName()
+    {
+      if (accessibleName != null)
+        return accessibleName;
+      if (text != null)
+        return text;
+      else
+        return super.getAccessibleName();
+    }
+    
+    /**
+     * Returns the accessible role for the <code>JLabel</code> component.
+     *
+     * @return {@link AccessibleRole#LABEL}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.LABEL;
+    }
+    
+    /**
+     * Returns the selected text. This is null since JLabels
+     * are not selectable.
+     *
+     * @return <code>null</code> because JLabels cannot have selected text
+     */
+    public String getSelectedText()
+    {
+      // We return null here since JLabel's text is not selectable.
+      return null;
+    }
+
+    /**
+     * Returns the start index of the selected text.
+     *
+     * @return the start index of the selected text
+     */
+    public int getSelectionStart()
+    {
+      // JLabel don't have selected text, so we return -1 here.
+      return -1;
+    }
+
+    /**
+     * Returns the end index of the selected text.
+     *
+     * @return the end index of the selected text
+     */
+    public int getSelectionEnd()
+    {
+      // JLabel don't have selected text, so we return -1 here.
+      return -1;
+    }
+
+    /**
+     * Returns an {@link AttributeSet} that reflects the text attributes of
+     * the specified character. We return an empty
+     * <code>AttributeSet</code> here, because JLabels don't support text
+     * attributes (at least not yet).
+     *
+     * @param index the index of the character
+     *
+     * @return an {@link AttributeSet} that reflects the text attributes of
+     *         the specified character
+     */
+    public AttributeSet getCharacterAttribute(int index)
+    {
+      // FIXME: Return null here for simple labels, and query the HTML
+      // view for HTML labels.
+      return new SimpleAttributeSet();
+    }
+
+    /**
+     * Returns the character, word or sentence at the specified index. The
+     * <code>part</code> parameter determines what is returned, the character,
+     * word or sentence after the index.
+     *
+     * @param part one of {@link AccessibleText#CHARACTER},
+     *             {@link AccessibleText#WORD} or
+     *             {@link AccessibleText#SENTENCE}, specifying what is returned
+     * @param index the index
+     *
+     * @return the character, word or sentence after <code>index</code>
+     */
+    public String getAtIndex(int part, int index)
+    {
+      String result = "";
+      int startIndex = -1;
+      int endIndex = -1;
+      switch(part)
+        {
+        case AccessibleText.CHARACTER:
+          result = String.valueOf(text.charAt(index));
+          break;
+        case AccessibleText.WORD:
+          startIndex = text.lastIndexOf(' ', index);
+          endIndex = text.indexOf(' ', startIndex + 1);
+          if (endIndex == -1)
+            endIndex = startIndex + 1;
+          result = text.substring(startIndex + 1, endIndex);
+          break;
+        case AccessibleText.SENTENCE:
+        default:
+          startIndex = text.lastIndexOf('.', index);
+          endIndex = text.indexOf('.', startIndex + 1);
+          if (endIndex == -1)
+            endIndex = startIndex + 1;
+          result = text.substring(startIndex + 1, endIndex);
+          break;
+        }
+      return result;
+    }
+
+    /**
+     * Returns the character, word or sentence after the specified index. The
+     * <code>part</code> parameter determines what is returned, the character,
+     * word or sentence after the index.
+     *
+     * @param part one of {@link AccessibleText#CHARACTER},
+     *             {@link AccessibleText#WORD} or
+     *             {@link AccessibleText#SENTENCE}, specifying what is returned
+     * @param index the index
+     *
+     * @return the character, word or sentence after <code>index</code>
+     */
+    public String getAfterIndex(int part, int index)
+    {
+      String result = "";
+      int startIndex = -1;
+      int endIndex = -1;
+      switch(part)
+        {
+        case AccessibleText.CHARACTER:
+          result = String.valueOf(text.charAt(index + 1));
+          break;
+        case AccessibleText.WORD:
+          startIndex = text.indexOf(' ', index);
+          endIndex = text.indexOf(' ', startIndex + 1);
+          if (endIndex == -1)
+            endIndex = startIndex + 1;
+          result = text.substring(startIndex + 1, endIndex);
+          break;
+        case AccessibleText.SENTENCE:
+        default:
+          startIndex = text.indexOf('.', index);
+          endIndex = text.indexOf('.', startIndex + 1);
+          if (endIndex == -1)
+            endIndex = startIndex + 1;
+          result = text.substring(startIndex + 1, endIndex);
+          break;
+        }
+      return result;
+    }
+
+    /**
+     * Returns the character, word or sentence before the specified index. The
+     * <code>part</code> parameter determines what is returned, the character,
+     * word or sentence before the index.
+     *
+     * @param part one of {@link AccessibleText#CHARACTER},
+     *             {@link AccessibleText#WORD} or
+     *             {@link AccessibleText#SENTENCE}, specifying what is returned
+     * @param index the index
+     *
+     * @return the character, word or sentence before <code>index</code>
+     */
+    public String getBeforeIndex(int part, int index)
+    {
+      String result = "";
+      int startIndex = -1;
+      int endIndex = -1;
+      switch(part)
+        {
+        case AccessibleText.CHARACTER:
+          result = String.valueOf(text.charAt(index - 1));
+          break;
+        case AccessibleText.WORD:
+          endIndex = text.lastIndexOf(' ', index);
+          if (endIndex == -1)
+            endIndex = 0;
+          startIndex = text.lastIndexOf(' ', endIndex - 1);
+          result = text.substring(startIndex + 1, endIndex);
+          break;
+        case AccessibleText.SENTENCE:
+        default:
+          endIndex = text.lastIndexOf('.', index);
+          if (endIndex == -1)
+            endIndex = 0;
+          startIndex = text.lastIndexOf('.', endIndex - 1);
+          result = text.substring(startIndex + 1, endIndex);
+          break;
+        }
+      return result;
+    }
+
+    /**
+     * Returns the caret position. This method returns -1 because JLabel don't
+     * have a caret.
+     *
+     * @return the caret position
+     */
+    public int getCaretPosition()
+    {
+      return -1;
+    }
+
+    /**
+     * Returns the number of characters that are displayed by the JLabel.
+     *
+     * @return the number of characters that are displayed by the JLabel
+     */
+    public int getCharCount()
+    {
+      // FIXME: Query HTML view for HTML labels.
+      return text.length();
+    }
+
+    /**
+     * Returns the bounding box of the character at the specified index.
+     *
+     * @param index the index of the character that we return the
+     *        bounds for
+     *
+     * @return the bounding box of the character at the specified index
+     */
+    public Rectangle getCharacterBounds(int index)
+      throws NotImplementedException
+    {
+      // FIXME: Implement this correctly.
+      return new Rectangle();
+    }
+
+    /**
+     * Returns the index of the character that is located at the specified
+     * point.
+     *
+     * @param point the location that we lookup the character for
+     *
+     * @return the index of the character that is located at the specified
+     *         point
+     */
+    public int getIndexAtPoint(Point point)
+      throws NotImplementedException
+    {
+      // FIXME: Implement this correctly.
+      return 0;
+    }
+  }
+
+  private static final long serialVersionUID = 5496508283662221534L;
+
+  static final String LABEL_PROPERTY = "labeledBy";
+
+  /**
+   * The Component the label will give focus to when its mnemonic is
+   * activated.
+   */
+  protected Component labelFor;
+
+  /** The label's text. */
+  transient String text;
+
+  /** Where the label will be positioned horizontally. */
+  private transient int horizontalAlignment = LEADING;
+
+  /** Where the label text will be placed horizontally relative to the icon. */
+  private transient int horizontalTextPosition = TRAILING;
+
+  /** Where the label will be positioned vertically. */
+  private transient int verticalAlignment = CENTER;
+
+  /** Where the label text will be place vertically relative to the icon. */
+  private transient int verticalTextPosition = CENTER;
+
+  /** The icon painted when the label is enabled. */
+  private transient Icon icon;
+
+  /** The icon painted when the label is disabled. */
+  private transient Icon disabledIcon;
+
+  /** The label's mnemnonic key. */
+  private transient int displayedMnemonic = KeyEvent.VK_UNDEFINED;
+
+  /** The index of the mnemonic character in the text. */
+  private transient int displayedMnemonicIndex = -1;
+
+  /** The gap between the icon and the text. */
+  private transient int iconTextGap = 4;
+
+  /**
+   * Creates a new vertically centered, horizontally on the leading edge
+   * JLabel object with text and no icon.
+   */
+  public JLabel()
+  {
+    this("", null, LEADING);
+  }
+
+  /**
+   * Creates a new vertically and horizontally centered
+   * JLabel object with no text and the given icon.
+   *
+   * @param image The icon to use with the label.
+   */
+  public JLabel(Icon image)
+  {
+    this("", image, CENTER);
+  }
+
+  /**
+   * Creates a new vertically centered JLabel object with no text and the
+   * given icon and horizontal alignment. By default, the text is TRAILING
+   * the image.
+   *
+   * @param image The icon to use with the label.
+   * @param horizontalAlignment The horizontal alignment of the label.
+   */
+  public JLabel(Icon image, int horizontalAlignment)
+  {
+    this("", image, horizontalAlignment);
+  }
+
+  /**
+   * Creates a new horizontally leading and vertically centered JLabel 
+   * object with no icon and the given text.
+   *
+   * @param text The text to use with the label.
+   */
+  public JLabel(String text)
+  {
+    this(text, null, LEADING);
+  }
+
+  /**
+   * Creates a new vertically centered JLabel object with no icon and the
+   * given text and horizontal alignment.
+   *
+   * @param text The text to use with the label.
+   * @param horizontalAlignment The horizontal alignment of the label.
+   */
+  public JLabel(String text, int horizontalAlignment)
+  {
+    this(text, null, horizontalAlignment);
+  }
+
+  /**
+   * Creates a new vertically centered JLabel object with the given text,
+   * icon, and horizontal alignment.
+   *
+   * @param text The text to use with the label.
+   * @param icon The icon to use with the label.
+   * @param horizontalAlignment The horizontal alignment of the label.
+   */
+  public JLabel(String text, Icon icon, int horizontalAlignment)
+  {
+    this.text = text;
+    this.icon = icon;
+    this.horizontalAlignment = horizontalAlignment;
+    setAlignmentX(0.0F);
+    setInheritsPopupMenu(true);
+    updateUI();
+  }
+
+  /**
+   * Returns the label's UI delegate.
+   *
+   * @return The label's UI delegate.
+   */
+  public LabelUI getUI()
+  {
+    return (LabelUI) ui;
+  }
+
+  /**
+   * Sets the label's UI delegate.
+   *
+   * @param ui The label's UI delegate (<code>null</code> not permitted).
+   */
+  public void setUI(LabelUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Resets the label's UI delegate to the default UI for the current look and 
+   * feel.
+   */
+  public void updateUI()
+  {
+    setUI((LabelUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Returns a name to identify which look and feel class will be
+   * the UI delegate for this label.
+   *
+   * @return <code>"LabelUI"</code>
+   */
+  public String getUIClassID()
+  {
+    return "LabelUI";
+  }
+
+  /**
+   * Returns a string describing the attributes for the <code>JLabel</code>
+   * component, for use in debugging.  The return value is guaranteed to be 
+   * non-<code>null</code>, but the format of the string may vary between
+   * implementations.
+   *
+   * @return A string describing the attributes of the <code>JLabel</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",defaultIcon=");
+    if (icon != null)
+      sb.append(icon);
+    sb.append(",disabledIcon=");
+    if (disabledIcon != null)
+      sb.append(disabledIcon);
+    sb.append(",horizontalAlignment=");
+    sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString(
+        horizontalAlignment));
+    sb.append(",horizontalTextPosition=");
+    sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString(
+        horizontalTextPosition));
+    sb.append(",iconTextGap=").append(iconTextGap);
+    sb.append(",labelFor=");
+    if (labelFor != null)
+      sb.append(labelFor);
+    sb.append(",text=");
+    if (text != null)
+      sb.append(text);
+    sb.append(",verticalAlignment=");
+    sb.append(SwingUtilities.convertVerticalAlignmentCodeToString(
+        verticalAlignment));
+    sb.append(",verticalTextPosition=");
+    sb.append(SwingUtilities.convertVerticalAlignmentCodeToString(
+        verticalTextPosition));
+    return sb.toString();
+  }
+
+  /**
+   * Returns the text displayed by the label.
+   *
+   * @return The label text (possibly <code>null</code>).
+   * 
+   * @see #setText(String)
+   */
+  public String getText()
+  {
+    return text;
+  }
+
+  /**
+   * Sets the text for the label and sends a {@link PropertyChangeEvent} (with
+   * the name 'text') to all registered listeners.  This method will also 
+   * update the <code>displayedMnemonicIndex</code>, if necessary.
+   *
+   * @param newText The text (<code>null</code> permitted).
+   * 
+   * @see #getText()
+   * @see #getDisplayedMnemonicIndex()
+   */
+  public void setText(String newText)
+  {
+    if (text == null && newText == null)
+      return;
+    if (text != null && text.equals(newText))
+      return;
+
+    String oldText = text;
+    text = newText;
+    firePropertyChange("text", oldText, newText);
+
+    if (text != null)
+      setDisplayedMnemonicIndex(text.toUpperCase().indexOf(displayedMnemonic));
+    else
+      setDisplayedMnemonicIndex(-1);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Returns the active icon. The active icon is painted when the label is 
+   * enabled.
+   *
+   * @return The active icon.
+   * 
+   * @see #setIcon(Icon)
+   * @see #getDisabledIcon()
+   */
+  public Icon getIcon()
+  {
+    return icon;
+  }
+
+  /**
+   * Sets the icon for the label (this is a bound property with the name 
+   * 'icon'). This icon will be displayed when the label is enabled.
+   *
+   * @param newIcon The icon (<code>null</code> permitted).
+   * 
+   * @see #getIcon()
+   * @see #setDisabledIcon(Icon)
+   */
+  public void setIcon(Icon newIcon)
+  {
+    if (icon != newIcon)
+      {
+        Icon oldIcon = icon;
+        icon = newIcon;
+        firePropertyChange("icon", oldIcon, newIcon);
+        repaint();
+      }
+  }
+
+  /**
+   * Returns the disabled icon. The disabled icon is painted when the label is 
+   * disabled. If the disabled icon is <code>null</code> and the active icon
+   * is an {@link ImageIcon}, this method returns a grayed version of the icon. 
+   * The grayed version of the icon becomes the <code>disabledIcon</code>.
+   *
+   * @return The disabled icon.
+   * 
+   * @see #setDisabledIcon(Icon)
+   */
+  public Icon getDisabledIcon()
+  {
+    if (disabledIcon == null && icon instanceof ImageIcon)
+      disabledIcon = new ImageIcon(
+          GrayFilter.createDisabledImage(((ImageIcon) icon).getImage()));
+
+    return disabledIcon;
+  }
+
+  /**
+   * Sets the icon displayed when the label is disabled (this is a bound
+   * property with the name 'disabledIcon').
+   *
+   * @param newIcon The disabled icon (<code>null</code> permitted).
+   * 
+   * @see #getDisabledIcon()
+   */
+  public void setDisabledIcon(Icon newIcon)
+  {
+    if (disabledIcon != newIcon)
+      {
+        Icon oldIcon = disabledIcon;
+        disabledIcon = newIcon;
+        firePropertyChange("disabledIcon", oldIcon, newIcon);
+      }
+  }
+
+  /**
+   * Sets the keycode that will be the label's mnemonic (this is a bound
+   * property with the name 'displayedMnemonic').  If the label is used as a 
+   * label for another component, the label will give focus to that component 
+   * when the mnemonic is activated.
+   *
+   * @param mnemonic The keycode to use for the mnemonic.
+   * 
+   * @see #getDisplayedMnemonic()
+   */
+  public void setDisplayedMnemonic(int mnemonic)
+  {
+    if (displayedMnemonic != mnemonic)
+      {
+        int old = displayedMnemonic;
+        displayedMnemonic = mnemonic;
+        firePropertyChange("displayedMnemonic", old, displayedMnemonic);
+        if (text != null)
+          setDisplayedMnemonicIndex(text.toUpperCase().indexOf(mnemonic));
+      }
+  }
+
+  /**
+   * Sets the character that will be the label's mnemonic. If the
+   * label is used as a label for another component, the label will give
+   * focus to that component when the mnemonic is activated via the keyboard.
+   *
+   * @param mnemonic The character to use for the mnemonic (this will be
+   *     converted to the equivalent upper case character).
+   *     
+   * @see #getDisplayedMnemonic()
+   */
+  public void setDisplayedMnemonic(char mnemonic)
+  {
+    setDisplayedMnemonic((int) Character.toUpperCase(mnemonic));
+  }
+
+  /**
+   * Returns the keycode that is used for the label's mnemonic.
+   *
+   * @return The keycode that is used for the label's mnemonic.
+   * 
+   * @see #setDisplayedMnemonic(int)
+   */
+  public int getDisplayedMnemonic()
+  {
+    return displayedMnemonic;
+  }
+
+  /**
+   * Sets the index of the character in the text that will be underlined to
+   * indicate that it is the mnemonic character for the label.  You only need
+   * to call this method if you wish to override the automatically calculated
+   * character index.  For instance, for a label "Find Next" with the mnemonic
+   * character 'n', you might wish to underline the second occurrence of 'n'
+   * rather than the first (which is the default).
+   * <br><br>
+   * Note that this method does not validate the character at the specified 
+   * index to ensure that it matches the key code returned by
+   * {@link #getDisplayedMnemonic()}.
+   *
+   * @param newIndex The index of the character to underline.
+   *
+   * @throws IllegalArgumentException If index less than -1 or index is greater
+   *         than or equal to the label length.
+   *         
+   * @see #getDisplayedMnemonicIndex()
+   * @since 1.4
+   */
+  public void setDisplayedMnemonicIndex(int newIndex)
+    throws IllegalArgumentException
+  {
+    int maxValid = -1;
+    if (text != null)
+      maxValid = text.length() - 1;
+    if (newIndex < -1 || newIndex > maxValid)
+      throw new IllegalArgumentException();
+
+    if (newIndex != displayedMnemonicIndex)
+      {
+        int oldIndex = displayedMnemonicIndex;
+        displayedMnemonicIndex = newIndex;
+        firePropertyChange("displayedMnemonicIndex", oldIndex, newIndex);
+      }
+  }
+
+  /**
+   * Returns the index of the character in the label's text that will be
+   * underlined (to indicate that it is the mnemonic character), or -1 if no
+   * character is to be underlined.
+   *
+   * @return The index of the character that will be underlined.
+   * 
+   * @see #setDisplayedMnemonicIndex(int)
+   * @since 1.4
+   */
+  public int getDisplayedMnemonicIndex()
+  {
+    return displayedMnemonicIndex;
+  }
+
+  /**
+   * Checks the specified key to ensure that it is valid as a horizontal 
+   * alignment, throwing an {@link IllegalArgumentException} if the key is
+   * invalid.  Valid keys are {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, 
+   * {@link #LEADING} and {@link #TRAILING}.
+   *
+   * @param key The key to check.
+   * @param message The message of the exception to be thrown if the key is
+   *        invalid.
+   *
+   * @return The key if it is valid.
+   *
+   * @throws IllegalArgumentException If the key is invalid.
+   */
+  protected int checkHorizontalKey(int key, String message)
+  {
+    if (key != LEFT && key != CENTER && key != RIGHT && key != LEADING
+        && key != TRAILING)
+      throw new IllegalArgumentException(message);
+    else
+      return key;
+  }
+
+  /**
+   * Checks the specified key to ensure that it is valid as a vertical 
+   * alignment, throwing an {@link IllegalArgumentException} if the key is
+   * invalid.  Valid keys are {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}.
+   *
+   * @param key The key to check.
+   * @param message The message of the exception to be thrown if the key is
+   *        invalid.
+   *
+   * @return The key if it is valid.
+   *
+   * @throws IllegalArgumentException If the key is invalid.
+   */
+  protected int checkVerticalKey(int key, String message)
+  {
+    if (key != TOP && key != BOTTOM && key != CENTER)
+      throw new IllegalArgumentException(message);
+    else
+      return key;
+  }
+
+  /**
+   * Returns the gap between the icon and the text.
+   *
+   * @return The gap between the icon and the text.
+   * 
+   * @see #setIconTextGap(int)
+   */
+  public int getIconTextGap()
+  {
+    return iconTextGap;
+  }
+
+  /**
+   * Sets the gap between the icon and the text, in the case that both are 
+   * visible (this is a bound property with the name 'iconTextGap'). 
+   *
+   * @param newGap The gap (in pixels).
+   * 
+   * @see #getIconTextGap()
+   */
+  public void setIconTextGap(int newGap)
+  {
+    if (iconTextGap != newGap)
+      {
+	firePropertyChange("iconTextGap", iconTextGap, newGap);
+	iconTextGap = newGap;
+      }
+  }
+
+  /**
+   * Returns the vertical alignment of the label (one of
+   * {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}).  The default value
+   * depends on the installed look and feel, but is usually {@link #CENTER}.
+   *
+   * @return The vertical alignment.
+   * 
+   * @see #setVerticalAlignment(int)
+   */
+  public int getVerticalAlignment()
+  {
+    return verticalAlignment;
+  }
+
+  /**
+   * Sets the vertical alignment for the label (this is a bound property with
+   * the name 'verticalAlignment').  The vertical alignment determines where 
+   * the label (icon and text) will be placed vertically within the component 
+   * bounds.  Valid alignment codes are {@link #TOP}, {@link #CENTER} and 
+   * {@link #BOTTOM}.
+   *
+   * @param alignment The vertical alignment of the label.
+   * 
+   * @throws IllegalArgumentException if <code>alignment</code> is not one of 
+   *     the specified values.
+   *     
+   * @see #getVerticalAlignment()
+   */
+  public void setVerticalAlignment(int alignment)
+  {
+    if (alignment == verticalAlignment)
+      return;
+
+    int oldAlignment = verticalAlignment;
+    verticalAlignment = checkVerticalKey(alignment, "verticalAlignment");
+    firePropertyChange("verticalAlignment", oldAlignment, verticalAlignment);
+  }
+
+  /**
+   * Returns the horizontal alignment of the label (one of {@link #LEFT}, 
+   * {@link #CENTER}, {@link #RIGHT}, {@link #LEADING} and {@link #TRAILING}).
+   * The default value depends on the installed look and feel, but is usually 
+   * {@link #LEFT}.
+   *
+   * @return The horizontal alignment.
+   * 
+   * @see #setHorizontalAlignment(int)
+   */
+  public int getHorizontalAlignment()
+  {
+    return horizontalAlignment;
+  }
+
+  /**
+   * Sets the horizontal alignment for the label (this is a bound property with
+   * the name 'horizontalAlignment').  The horizontal alignment determines where 
+   * the label (icon and text) will be placed horizontally within the 
+   * component bounds.  Valid alignment codes are {@link #LEFT}, 
+   * {@link #CENTER}, {@link #RIGHT}, {@link #LEADING} and {@link #TRAILING}.
+   *
+   * @param alignment The horizontal alignment of the label.
+   * 
+   * @throws IllegalArgumentException if <code>alignment</code> is not one of 
+   *     the specified values.
+   *     
+   * @see #getHorizontalAlignment()
+   */
+  public void setHorizontalAlignment(int alignment)
+  {
+    if (horizontalAlignment == alignment)
+      return;
+    
+    int oldAlignment = horizontalAlignment;
+    horizontalAlignment = checkHorizontalKey(alignment, "horizontalAlignment");
+    firePropertyChange("horizontalAlignment", oldAlignment,
+                       horizontalAlignment);
+  }
+
+  /**
+   * Returns the vertical position of the label's text relative to the icon. 
+   * This will be one of {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}.
+   * 
+   * @return The vertical position of the label's text relative to the icon.
+   * 
+   * @see #setVerticalTextPosition(int)
+   */
+  public int getVerticalTextPosition()
+  {
+    return verticalTextPosition;
+  }
+
+  /**
+   * Sets the vertical position of the label's text relative to the icon (this
+   * is a bound property with the name 'verticalTextPosition').  Valid 
+   * positions are {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}.
+   *
+   * @param textPosition The vertical text position.
+   * 
+   * @throws IllegalArgumentException if <code>textPosition</code> is not one
+   *     of the specified values.
+   */
+  public void setVerticalTextPosition(int textPosition)
+  {
+    if (textPosition != verticalTextPosition)
+      {
+        int oldPos = verticalTextPosition;
+        verticalTextPosition = checkVerticalKey(textPosition,
+	                                            "verticalTextPosition");
+        firePropertyChange("verticalTextPosition", oldPos, 
+                           verticalTextPosition);
+      }
+  }
+
+  /**
+   * Returns the horizontal position of the label's text relative to the icon. 
+   * This will be one of {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, 
+   * {@link #LEADING} and {@link #TRAILING}.
+   * 
+   * @return The horizontal position of the label's text relative to the icon.
+   * 
+   * @see #setHorizontalTextPosition(int)
+   */
+  public int getHorizontalTextPosition()
+  {
+    return horizontalTextPosition;
+  }
+
+  /**
+   * Sets the horizontal position of the label's text relative to the icon (this
+   * is a bound property with the name 'horizontalTextPosition').  Valid 
+   * positions are {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, 
+   * {@link #LEADING} and {@link #TRAILING}.
+   *
+   * @param textPosition The horizontal text position.
+   * 
+   * @throws IllegalArgumentException if <code>textPosition</code> is not one
+   *     of the specified values.
+   */
+  public void setHorizontalTextPosition(int textPosition)
+  {
+    if (textPosition != horizontalTextPosition)
+      {
+        int oldPos = horizontalTextPosition;
+        horizontalTextPosition = checkHorizontalKey(textPosition,
+                                                    "horizontalTextPosition");
+        firePropertyChange("horizontalTextPosition", oldPos, 
+                           horizontalTextPosition);
+      }
+  }
+
+  /**
+   * Returns false if the current icon image (current icon will depend on 
+   * whether the label is enabled) is not equal to the passed in image.
+   *
+   * @param img The image to check.
+   * @param infoflags The bitwise inclusive OR of ABORT, ALLBITS, ERROR,
+   *        FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, and WIDTH
+   * @param x The x position
+   * @param y The y position
+   * @param w The width
+   * @param h The height
+   *
+   * @return Whether the current icon image is equal to the image given.
+   */
+  public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
+                             int h)
+  {
+    Icon currIcon = isEnabled() ? icon : disabledIcon;
+
+    // XXX: Is this the correct way to check for image equality?
+    if (currIcon != null && currIcon instanceof ImageIcon)
+      return (((ImageIcon) currIcon).getImage() == img);
+
+    return false;
+  }
+
+  /**
+   * Returns the component that this <code>JLabel</code> is providing the label
+   * for.  This component will typically receive the focus when the label's 
+   * mnemonic key is activated via the keyboard.
+   *
+   * @return The component (possibly <code>null</code>).
+   */
+  public Component getLabelFor()
+  {
+    return labelFor;
+  }
+
+  /**
+   * Sets the component that this <code>JLabel</code> is providing the label
+   * for (this is a bound property with the name 'labelFor').  This component
+   * will typically receive the focus when the label's mnemonic key is 
+   * activated via the keyboard.
+   *
+   * @param c  the component (<code>null</code> permitted).
+   * 
+   * @see #getLabelFor()
+   */
+  public void setLabelFor(Component c)
+  {
+    if (c != labelFor)
+      {
+        Component oldLabelFor = labelFor;
+        labelFor = c;
+        firePropertyChange("labelFor", oldLabelFor, labelFor);
+
+        // We put the label into the client properties for the labeled
+        // component so that it can be read by the AccessibleJComponent.
+        // The other option would be to reserve a default visible field
+        // in JComponent, but since this is relatively seldomly used, it
+        // would be unnecessary waste of memory to do so.
+        if (oldLabelFor instanceof JComponent)
+          {
+            ((JComponent) oldLabelFor).putClientProperty(LABEL_PROPERTY, null);
+          }
+
+        if (labelFor instanceof JComponent)
+          {
+            ((JComponent) labelFor).putClientProperty(LABEL_PROPERTY, this);
+          }
+
+      }
+  }
+
+  /**
+   * Sets the font for the label (this a bound property with the name 'font').
+   *
+   * @param f The font (<code>null</code> permitted).
+   */
+  public void setFont(Font f)
+  {
+    super.setFont(f);
+    repaint();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JLabel</code> component.
+   *
+   * @return The accessible context (an instance of {@link AccessibleJLabel}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJLabel();
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLayeredPane.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLayeredPane.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLayeredPane.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JLayeredPane.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,755 @@
+/* JLayeredPane.java -- 
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * A container that adds depth to the usual <code>Container</code> semantics.
+ * Each child component of a <code>Layered Pane</code> is placed within one
+ * of several layers. <code>JLayeredPane</code> defines a set of standard
+ * layers. The pre-defined sets are (in the order from button to top):
+ *
+ *  <dl>
+ *    <dt>{@link #DEFAULT_LAYER}</dt>
+ *    <dd>The layer where most of the normal components are placed. This
+ *      is the bottommost layer.</dd>
+ *
+ *    <dt>{@link #PALETTE_LAYER}</dt>
+ *    <dd>Palette windows are placed in this layer.</dd>
+ *
+ *    <dt>{@link #MODAL_LAYER}</dt>
+ *    <dd>The layer where internal modal dialog windows are placed.</dd>
+ *
+ *    <dt>{@link #POPUP_LAYER}</dt>
+ *    <dd>The layer for popup menus</dd>
+ *
+ *    <dt>{@link #DRAG_LAYER}</dt>
+ *    <dd>Components that are beeing dragged are temporarily placed in
+ *       this layer.</dd>
+ *  </dl>
+ *
+ * <p>A child is in exactly one of these layers at any time, though there may
+ * be other layers if someone creates them.</p>
+ *
+ * <p>You can add a component to a specific layer using the
+ * {@link Container#add(Component, Object)} method. I.e.
+ * <code>layeredPane.add(comp, JLayeredPane.MODAL_LAYER)</code> will add the
+ * component <code>comp</code> to the modal layer of <code>layeredPane</code>.
+ * </p>
+ *
+ * <p>To change the layer of a component that is already a child of
+ * a <code>JLayeredPane</code>, use the {@link #setLayer(Component, int)} 
+ * method.</p>
+ *
+ * <p>The purpose of this class is to translate this view of "layers" into a
+ * contiguous array of components: the one held in our ancestor,
+ * {@link java.awt.Container}.</p>
+ *
+ * <p>There is a precise set of words we will use to refer to numbers within
+ * this class:</p>
+ * 
+ * <dl>
+ * <dt>Component Index:</dt> 
+ * <dd>An offset into the <code>component</code> array held in our ancestor,
+ * {@link java.awt.Container}, from <code>[0 .. component.length)</code>. The drawing
+ * rule with indices is that 0 is drawn last.</dd>
+ *
+ * <dt>Layer Number:</dt>
+ * <dd>A general <code>int</code> specifying a layer within this component.  Negative
+ * numbers are drawn first, then layer 0, then positive numbered layers, in
+ * ascending order.</dd>
+ *
+ * <dt>Position:</dt> 
+ * <dd>An offset into a layer's "logical drawing order". Layer position 0
+ * is drawn last. Layer position -1 is a synonym for the first layer
+ * position (the logical "bottom").</dd>
+ * </dl>
+ *
+ * <p><b>Note:</b> the layer numbering order is the <em>reverse</em> of the
+ * component indexing and position order</p>
+ *
+ * @author Graydon Hoare (graydon at redhat.com)
+ * @author Roman Kennke (kennke at aicas.com)
+ */
+public class JLayeredPane extends JComponent implements Accessible
+{
+  
+  /**
+   * Provides accessibility support for <code>JLayeredPane</code>.
+   */
+  protected class AccessibleJLayeredPane extends AccessibleJComponent
+  {
+    /**
+     * Creates a new instance of <code>AccessibleJLayeredPane</code>.
+     */
+    protected AccessibleJLayeredPane()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns the accessble role of <code>JLayeredPane</code>,
+     * {@link AccessibleRole#LAYERED_PANE}. 
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.LAYERED_PANE;
+    }
+  }
+
+  private static final long serialVersionUID = 5534920399324590459L;
+  
+  public static final String LAYER_PROPERTY = "layeredContainerLayer";
+
+  public static final Integer FRAME_CONTENT_LAYER = new Integer(-30000);
+
+  public static final Integer DEFAULT_LAYER = new Integer(0);
+  public static final Integer PALETTE_LAYER = new Integer(100);
+  public static final Integer MODAL_LAYER   = new Integer(200);
+  public static final Integer POPUP_LAYER   = new Integer(300);
+  public static final Integer DRAG_LAYER    = new Integer(400);
+
+  private Hashtable componentToLayer;   // Component -> Layer Number (Integer)
+
+  public JLayeredPane()
+  {
+    componentToLayer = new Hashtable();
+    setLayout(null);
+  }
+
+  /** 
+   * Looks up the layer a child component is currently assigned to.
+   *
+   * If <code>c</code> is an instance of {@link JComponent}, then the layer
+   * is fetched from the client property with the key {@link #LAYER_PROPERTY}.
+   * Otherwise it is looked up in an internal hashtable that maps
+   * non-JComponent components to layers. If the components cannot be found
+   * in either way, the {@link #DEFAULT_LAYER} is returned.
+   *
+   * @param c the component to look up.
+   *
+   * @return the layer the component is currently assigned to; if the component
+   *         is not in this layered pane, then 0 (DEFAULT_LAYER) is returned
+   */
+  public int getLayer(Component c)
+  {
+    Integer layerObj;
+    if (c instanceof JComponent)
+      {
+        JComponent jc = (JComponent) c;
+        layerObj = (Integer) jc.getClientProperty(LAYER_PROPERTY);
+      }
+    else
+      layerObj = (Integer) componentToLayer.get(c);
+
+    if (layerObj == null)
+      layerObj = DEFAULT_LAYER;
+
+    return layerObj.intValue();
+  }
+
+  /**
+   * Looks up the layer in the client property with the key
+   * {@link #LAYER_PROPERTY} of <code>comp</code>. If no such property can be
+   * found, we return <code>0</code> ({@link #DEFAULT_LAYER}).
+   * 
+   * @param comp the component for which the layer is looked up
+   *
+   * @return the layer of <code>comp</code> as stored in the corresponding
+   *         client property, or <code>0</code> if there is no such property
+   */
+  public static int getLayer(JComponent comp)
+  {
+    Integer layerObj = (Integer) comp.getClientProperty(LAYER_PROPERTY);
+    if (layerObj == null)
+      layerObj = DEFAULT_LAYER;
+    return layerObj.intValue();
+  }
+
+  /**
+   * Returns the first JLayeredPane that contains the Component
+   * <code>comp</code> or <code>null</code> if <code>comp</code> is
+   * not contained in a JLayeredPane.
+   *
+   * @param comp the component for which we are searching the JLayeredPane
+   *     ancestor
+   *
+   * @return the first JLayeredPane that contains the Component
+   *     <code>comp</code> or <code>null</code> if <code>comp</code> is
+   *     not contained in a JLayeredPane
+   */
+  public static JLayeredPane getLayeredPaneAbove(Component comp)
+  {
+    JLayeredPane lp = (JLayeredPane) SwingUtilities.getAncestorOfClass
+      (JLayeredPane.class, comp);
+    return lp;
+  }
+
+  /**
+   * Return the greatest layer number currently in use, in this container.
+   * This number may legally be positive <em>or</em> negative.
+   *
+   * @return the highest layer number
+   *
+   * @see #lowestLayer()
+   */
+  public int highestLayer()
+  {
+    Component[] components = getComponents();
+    int highest;
+    if (components.length == 0)
+      highest = 0;
+    else
+      {
+        highest = Integer.MIN_VALUE;
+        for (int i = 0; i < components.length; i++)
+          highest = Math.max(highest, getLayer(components[i]));
+      }
+    return highest;
+  }
+
+  /**
+   * Return the least layer number currently in use, in this container.
+   * This number may legally be positive <em>or</em> negative.
+   *
+   * @return the least layer number
+   *
+   * @see #highestLayer()
+   */
+  public int lowestLayer()
+  {
+    Component[] components = getComponents();
+    int lowest;
+    if (components.length == 0)
+      lowest = 0;
+    else
+      {
+        lowest = Integer.MAX_VALUE;
+        for (int i = 0; i < components.length; i++)
+          lowest = Math.max(lowest, getLayer(components[i]));
+      }
+    return lowest;
+  }
+
+  /**
+   * Moves a component to the "front" of its layer. The "front" is a
+   * synonym for position 0, which is also the last position drawn in each
+   * layer, so is usually the component which occludes the most other
+   * components in its layer.
+   *
+   * @param c the component to move to the front of its layer
+   *
+   * @see #moveToBack
+   */
+  public void moveToFront(Component c)
+  {
+    setPosition (c, 0);
+  }
+
+  /**
+   * <p>Moves a component to the "back" of its layer. The "back" is a
+   * synonym for position N-1 (also known as position -1), where N is the
+   * size of the layer.</p>
+   *
+   * <p>The "back" of a layer is the first position drawn, so the component at
+   * the "back" is usually the component which is occluded by the most
+   * other components in its layer.</p>
+   *
+   * @param c the component to move to the back of its layer.
+   *
+   * @see #moveToFront
+   */
+  public void moveToBack(Component c)
+  {
+    setPosition (c, -1);
+  }
+
+  /**
+   * Return the position of a component within its layer. Positions are assigned
+   * from the "front" (position 0) to the "back" (position N-1), and drawn from 
+   * the back towards the front.
+   *
+   * @param c the component to get the position of
+   *
+   * @return the position of <code>c</code> within its layer or -1 if
+   *         <code>c</code> is not a child of this layered pane
+   *
+   * @see #setPosition
+   */
+  public int getPosition(Component c)
+  {
+    int pos = -1;
+    int index = getIndexOf(c);
+    if (index >= 0)
+      {
+        pos = 0;
+        int layer = getLayer(c);
+        for (int i = index - 1; i >= 0; --i)
+          {
+            if (layer == getLayer(getComponent(i)))
+              pos++;
+            else
+              break;
+          }
+      }
+    return pos;
+  }
+
+  /**
+   * Change the position of a component within its layer. Positions are assigned
+   * from the "front" (position 0) to the "back" (position N-1), and drawn from 
+   * the back towards the front.
+   *
+   * @param c the component to change the position of
+   * @param position the position to assign the component to
+   *
+   * @see #getPosition
+   */
+  public void setPosition(Component c, int position)
+  {
+    setLayer(c, getLayer(c), position);
+  }
+    
+  /**
+   * Return an array of all components within a layer of this
+   * container. Components are ordered front-to-back, with the "front"
+   * element (which draws last) at position 0 of the returned array.
+   *
+   * @param layer the layer to return components from
+   *
+   * @return the components in the layer
+   */
+  public Component[] getComponentsInLayer(int layer)
+  {
+    Component[] inLayer = new Component[getComponentCountInLayer(layer)];
+    Component[] components = getComponents();
+    int j = 0;
+    for (int i = 0; i < components.length; ++i)
+      {
+        if (layer == getLayer(components[i]))
+          {
+            inLayer[j] = components[i];
+            j++;
+          }
+      }
+    return inLayer;
+  }
+
+  /**
+   * Return the number of components within a layer of this
+   * container.
+   *
+   * @param layer the layer count components in
+   *
+   * @return the number of components in the layer
+   */
+  public int getComponentCountInLayer(int layer)
+  {
+    Component[] components = getComponents();
+    int count = 0;
+    for (int i = components.length - 1; i >= 0; --i)
+      {
+        if (getLayer(components[i]) == layer)
+          count++;
+      }
+    return count;
+  }
+
+  /**
+   * Return a hashtable mapping child components of this container to
+   * Integer objects representing the component's layer assignments.
+   */
+  protected Hashtable getComponentToLayer()
+  {
+    return componentToLayer;
+  }
+
+  /**
+   * Return the index of a component within the underlying (contiguous)
+   * array of children. This is a "raw" number which does not represent the
+   * child's position in a layer, but rather its position in the logical
+   * drawing order of all children of the container.
+   *
+   * @param c the component to look up.
+   *
+   * @return the external index of the component or <code>-1</code> if
+   *         <code>c</code> is not a child of this layered pane 
+   */
+  public int getIndexOf(Component c) 
+  {
+    return getComponentZOrder(c);
+  }
+
+  /**
+   * Return an Integer object which holds the same int value as the
+   * parameter. This is strictly an optimization to minimize the number of
+   * identical Integer objects which we allocate.
+   *
+   * @param layer the layer number as an int.
+   *
+   * @return the layer number as an Integer, possibly shared.
+   */
+  protected Integer getObjectForLayer(int layer)
+  {
+    switch (layer)
+	    {
+	    case -30000:
+        return FRAME_CONTENT_LAYER;
+
+	    case 0:
+        return DEFAULT_LAYER;
+
+	    case 100:
+        return PALETTE_LAYER;
+
+	    case 200:
+        return MODAL_LAYER;
+
+	    case 300:
+        return POPUP_LAYER;
+
+	    case 400:
+        return DRAG_LAYER;
+
+	    default:
+        break;
+	    }
+
+    return new Integer(layer);
+  }
+
+  /**
+   * Computes an index at which to request the superclass {@link
+   * java.awt.Container} inserts a component, given an abstract layer and
+   * position number.
+   *
+   * @param layer the layer in which to insert a component.
+   * @param position the position in the layer at which to insert a component.
+   *
+   * @return the index at which to insert the component.
+   */
+  protected int insertIndexForLayer(int layer, int position)
+  {
+    return insertIndexForLayer(null, layer, position);
+  }
+
+  /**
+   * Similar to {@link #insertIndexForLayer(int, int)}, only that it takes a
+   * component parameter, which should be ignored in the search. This is
+   * necessary to support {@link #setLayer(Component, int, int)} which uses
+   * Container.setComponentZOrder(), which doesn't remove the component.
+   *
+   * @param comp the component to ignore
+   * @param layer the layer
+   * @param position the position
+   *
+   * @return the insertion index
+   */
+  private int insertIndexForLayer(Component comp, int layer, int position)
+  {
+    // Create the component list to search through.
+    ArrayList l = new ArrayList();
+    int count = getComponentCount();
+    for (int i = 0; i < count; i++)
+      {
+        Component c = getComponent(i);
+        if (c != comp)
+          l.add(c);
+      }
+
+    count = l.size();
+    int layerStart = -1;
+    int layerEnd = -1;
+    for (int i = 0; i < count; i++)
+      {
+        int layerOfComponent = getLayer((Component) l.get(i));
+        if (layerStart == -1 && layerOfComponent == layer)
+          layerStart = i;
+        if (layerOfComponent < layer)
+          {
+            // We are beyond the layer that we are looking for. Update the
+            // layerStart and layerEnd and exit the loop.
+            if (i == 0)
+              {
+                layerStart = 0;
+                layerEnd = 0;
+              }
+            else
+              layerEnd = i;
+            break;
+          }
+      }
+
+    // No layer found. The requested layer is lower than any existing layer,
+    // put the component at the end.
+    int insertIndex;
+    if (layerStart == -1 && layerEnd == -1)
+      {
+        insertIndex = count;
+      }
+    else
+      {
+        // Corner cases.
+        if (layerStart != -1 && layerEnd == -1)
+          layerEnd = count;
+        if (layerStart == -1 && layerEnd != -1)
+          layerStart = layerEnd;
+
+        // Adding to the bottom of a layer returns the end index
+        // in the layer.
+        if (position == -1)
+          insertIndex = layerEnd;
+        else
+          {
+            // Insert into a layer.
+            if (position > -1 && layerStart + position <= layerEnd)
+              insertIndex = layerStart + position;
+            else
+              insertIndex = layerEnd;
+          }
+      }
+    return insertIndex;
+  }
+
+  /**
+   * Removes a child from this container. The child is specified by
+   * index. After removal, the child no longer occupies a layer.
+   *
+   * @param index the index of the child component to remove.
+   */
+  public void remove(int index)
+  {
+    Component c = getComponent(index);
+    if (! (c instanceof JComponent))
+      componentToLayer.remove(c);
+    super.remove(index);
+  }
+
+  /**
+   * Removes all components from this container.
+   *
+   * @since 1.5
+   */
+  public void removeAll()
+  {
+	componentToLayer.clear();
+	super.removeAll();
+  }
+
+  /**
+   * <p>Set the layer property for a component, within this container. The
+   * component will be implicitly mapped to the bottom-most position in the
+   * layer, but only if added <em>after</em> calling this method.</p>
+   *
+   * <p>Read that carefully: this method should be called <em>before</em> the
+   * component is added to the container.</p>
+   *
+   * @param c the component to set the layer property for.
+   * @param layer the layer number to assign to the component.
+   */
+  public void setLayer(Component c, int layer)
+  {
+    setLayer(c, layer, -1);
+  }
+
+  /**
+   * Set the layer and position of a component, within this container.
+   *
+   * @param c the child component to set the layer property for.
+   * @param layer the layer number to assign to the component.
+   * @param position the position number to assign to the component.
+   */
+  public void setLayer(Component c, int layer, int position)
+  {
+    Integer layerObj = getObjectForLayer(layer);
+
+    // Nothing to do if neither the layer nor the position is
+    // changed.
+    if (layer != getLayer(c) || position != getPosition(c))
+      {
+        // Store the layer either in the JComponent or in the hashtable
+        if (c instanceof JComponent)
+          {
+            JComponent jc = (JComponent) c;
+            jc.putClientProperty(LAYER_PROPERTY, layerObj);
+          }
+        else
+          componentToLayer.put (c, layerObj);
+
+        // Update the component in the Z order of the Container.
+        Container parent = c.getParent();
+        if (parent == this)
+          {
+            int index = insertIndexForLayer(c, layer, position);
+            setComponentZOrder(c, index);
+          }
+      }
+    repaint(c.getX(), c.getY(), c.getWidth(), c.getHeight());
+  }
+
+  /**
+   * Overrides the default implementation from {@link java.awt.Container}
+   * such that <code>layerConstraint</code> is interpreted as an {@link
+   * Integer}, specifying the layer to which the component will be added
+   * (at the bottom position).
+   *
+   * The argument <code>index</code> specifies the position within the layer
+   * at which the component should be added, where <code>0</code> is the top
+   * position greater values specify positions below that and <code>-1</code>
+   * specifies the bottom position.
+   *
+   * @param comp the component to add
+   * @param layerConstraint an integer specifying the layer to add the
+   *        component to
+   * @param index the position within the layer
+   */
+  protected void addImpl(Component comp, Object layerConstraint, int index) 
+  {
+    int layer;
+    if (layerConstraint != null && layerConstraint instanceof Integer)
+      {
+        layer = ((Integer) layerConstraint).intValue();
+        setLayer(comp, layer);
+      }
+    else
+      layer = getLayer(comp);
+
+    int newIdx = insertIndexForLayer(layer, index);
+    super.addImpl(comp, layerConstraint, newIdx);
+    comp.validate();
+    comp.repaint();
+  }
+
+  /**
+   * Sets the layer property for a JComponent.
+   *
+   * @param component the component for which to set the layer
+   * @param layer the layer property to set
+   */
+  public static void putLayer(JComponent component, int layer)
+  {
+    component.putClientProperty(LAYER_PROPERTY, new Integer(layer));
+  }
+
+  /**
+   * Returns the accessible context for this <code>JLayeredPane</code>.
+   *
+   * @return the accessible context for this <code>JLayeredPane</code>
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJLayeredPane();
+    return accessibleContext;
+  }
+
+  /**
+   * This method is overridden order to provide a reasonable painting
+   * mechanism for <code>JLayeredPane</code>. This is necessary since
+   * <code>JLayeredPane</code>'s do not have an own UI delegate.
+   *
+   * Basically this method clears the background for the
+   * <code>JLayeredPane</code> and then calls <code>super.paint(g)</code>.
+   *
+   * @param g the graphics context to use
+   */
+  public void paint(Graphics g)
+  {
+    if (isOpaque())
+      {
+        Color oldColor = g.getColor();
+        Rectangle clip = g.getClipBounds();
+        g.setColor(getBackground());
+        g.fillRect(clip.x, clip.y, clip.width, clip.height);
+        g.setColor(oldColor);
+      }
+    super.paint(g);
+  }
+
+  /**
+   * Returns <code>false</code> if components in this layered pane can overlap,
+   * otherwise <code>true</code>.
+   *
+   * @return <code>false</code> if components in this layered pane can overlap,
+   *         otherwise <code>true</code>
+   */
+  public boolean isOptimizedDrawingEnabled()
+  {
+    int numChildren = getComponentCount();
+    boolean result = true;
+    for (int i = 0; i < numChildren; ++i)
+      {
+    	Component c1 = getComponent(i);
+    	if (! c1.isVisible())
+          continue;
+    	Rectangle r1 = c1.getBounds();
+    	if (r1.isEmpty())
+          continue;
+
+    	for (int j = i + 1; j < numChildren; ++j)
+          {
+            Component c2 = getComponent(j);
+            if (! c2.isVisible())
+              continue;
+            Rectangle r2 = c2.getBounds();
+            if (r2.isEmpty())
+              continue;
+            if (r1.intersects(r2))
+              {
+                result = false;
+                break;
+              }
+            if (result == false)
+              break;
+          }
+      }
+    return result;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JList.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JList.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JList.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JList.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,2374 @@
+/* JList.java --
+   Copyright (C) 2002, 2003, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.FocusListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.plaf.ListUI;
+import javax.swing.text.Position;
+
+/**
+ * <p>This class is a facade over three separate objects: {@link
+ * javax.swing.ListModel}, {@link javax.swing.ListSelectionModel} and
+ * {@link javax.swing.plaf.ListUI}. The facade represents a unified "list"
+ * concept, with independently replacable (possibly client-provided) models
+ * for its contents and its current selection. In addition, each element in
+ * the list is rendered via a strategy class {@link
+ * javax.swing.ListCellRenderer}.</p>
+ *
+ * <p>Lists have many properties, some of which are stored in this class
+ * while others are delegated to the list's model or selection. The
+ * following properties are available:</p>
+ *
+ * <table>
+ * <tr><th>Property                       </th><th>Stored in</th><th>Bound?</th></tr>
+ * <tr><td>accessibleContext              </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>anchorSelectionIndex           </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>cellRenderer                   </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>dragEnabled                    </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>firstVisibleIndex              </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>fixedCellHeight                </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>fixedCellWidth                 </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>lastVisibleIndex               </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>layoutOrientation              </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>leadSelectionIndex             </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>maxSelectionIndex              </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>minSelectionIndex              </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>model                          </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>opaque                         </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>preferredScrollableViewportSize</td><td>list     </td><td>no    </td></tr>
+ * <tr><td>prototypeCellValue             </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>scrollableTracksViewportHeight </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>scrollableTracksViewportWidth  </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>selectedIndex                  </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectedIndices                </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectedValue                  </td><td>model    </td><td>no    </td></tr>
+ * <tr><td>selectedValues                 </td><td>model    </td><td>no    </td></tr>
+ * <tr><td>selectionBackground            </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>selectionEmpty                 </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectionForeground            </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>selectionMode                  </td><td>selection</td><td>no    </td></tr>
+ * <tr><td>selectionModel                 </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>UI                             </td><td>list     </td><td>yes   </td></tr>
+ * <tr><td>UIClassID                      </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>valueIsAdjusting               </td><td>list     </td><td>no    </td></tr>
+ * <tr><td>visibleRowCount                </td><td>list     </td><td>no    </td></tr>
+ * </table> 
+ *
+ * @author Graydon Hoare (graydon at redhat.com)
+ */
+
+public class JList extends JComponent implements Accessible, Scrollable
+{
+
+  /**
+   * Provides accessibility support for <code>JList</code>.
+   */
+  protected class AccessibleJList extends AccessibleJComponent
+    implements AccessibleSelection, PropertyChangeListener,
+               ListSelectionListener, ListDataListener
+  {
+
+    /**
+     * Provides accessibility support for list elements in <code>JList</code>s.
+     */
+    protected class AccessibleJListChild extends AccessibleContext
+      implements Accessible, AccessibleComponent
+    {
+
+      /**
+       * The parent list.
+       */
+      JList parent;
+
+      /**
+       * The index in the list for that child.
+       */
+      int listIndex;
+
+      /**
+       * The cursor for this list child.
+       */
+      // TODO: Testcases show that this class somehow stores state about the
+      // cursor. I cannot make up though how that could affect
+      // the actual list.
+      Cursor cursor = Cursor.getDefaultCursor();
+
+      /**
+       * Creates a new instance of <code>AccessibleJListChild</code>.
+       *
+       * @param list the list of which this is an accessible child
+       * @param index the list index for this child
+       */
+      public AccessibleJListChild(JList list, int index)
+      {
+        parent = list;
+        listIndex = index;
+      }
+
+      /**
+       * Returns the accessible context of this object. Returns
+       * <code>this</code> since <code>AccessibleJListChild</code>s are their
+       * own accessible contexts.
+       *
+       * @return the accessible context of this object, <code>this</code>
+       */
+      public AccessibleContext getAccessibleContext()
+      {
+        return this;
+      }
+
+      /**
+       * Returns the background color for this list child. This returns the
+       * background of the <code>JList</code> itself since the background
+       * cannot be set on list children individually
+       *
+       * @return the background color for this list child
+       */
+      public Color getBackground()
+      {
+        return parent.getBackground();
+      }
+
+      /**
+       * Calling this method has no effect, since the background color cannot be
+       * set on list children individually.
+       *
+       * @param color not used here.
+       */
+      public void setBackground(Color color)
+      {
+        // Calling this method has no effect, since the background color cannot
+        // be set on list children individually.
+      }
+
+      /**
+       * Returns the foreground color for this list child. This returns the
+       * background of the <code>JList</code> itself since the foreground
+       * cannot be set on list children individually.
+       *
+       * @return the background color for this list child
+       */
+      public Color getForeground()
+      {
+        return parent.getForeground();
+      }
+
+      /**
+       * Calling this method has no effect, since the foreground color cannot be
+       * set on list children individually.
+       *
+       * @param color not used here.
+       */
+      public void setForeground(Color color)
+      {
+        // Calling this method has no effect, since the foreground color cannot
+        // be set on list children individually.
+      }
+
+      /**
+       * Returns the cursor for this list child.
+       *
+       * @return the cursor for this list child
+       */
+      public Cursor getCursor()
+      {
+        // TODO: Testcases show that this method returns the cursor that has
+        // been set by setCursor. I cannot make up though how that could affect
+        // the actual list.
+        return cursor;
+      }
+
+      /**
+       * Sets the cursor for this list child.
+       */
+      public void setCursor(Cursor cursor)
+      {
+        this.cursor = cursor;
+        // TODO: Testcases show that this method returns the cursor that has
+        // been set by setCursor. I cannot make up though how that could affect
+        // the actual list.
+      }
+
+      /**
+       * Returns the font of the <code>JList</code> since it is not possible to
+       * set fonts for list children individually.
+       *
+       * @return the font of the <code>JList</code>
+       */
+      public Font getFont()
+      {
+        return parent.getFont();
+      }
+
+      /**
+       * Does nothing since it is not possible to set the font on list children
+       * individually.
+       *
+       * @param font not used here
+       */
+      public void setFont(Font font)
+      {
+        // Does nothing since it is not possible to set the font on list
+        // children individually.
+      }
+
+      /**
+       * Returns the font metrics for the specified font. This method forwards
+       * to the parent <code>JList</code>. 
+       *
+       * @param font the font for which the font metrics is queried
+       *
+       * @return the font metrics for the specified font
+       */
+      public FontMetrics getFontMetrics(Font font)
+      {
+        return parent.getFontMetrics(font);
+      }
+
+      /**
+       * Returns <code>true</code> if the parent <code>JList</code> is enabled,
+       * <code>false</code> otherwise. The list children cannot have an enabled
+       * flag set individually.
+       *
+       * @return <code>true</code> if the parent <code>JList</code> is enabled,
+       *         <code>false</code> otherwise
+       */
+      public boolean isEnabled()
+      {
+        return parent.isEnabled();
+      }
+
+      /**
+       * Does nothing since the enabled flag cannot be set for list children
+       * individually.
+       *
+       * @param b not used here
+       */
+      public void setEnabled(boolean b)
+      {
+        // Does nothing since the enabled flag cannot be set for list children
+        // individually.
+      }
+
+      /**
+       * Returns <code>true</code> if this list child is visible,
+       * <code>false</code> otherwise. The value of this property depends
+       * on {@link JList#getFirstVisibleIndex()} and
+       * {@link JList#getLastVisibleIndex()}.
+       *
+       * @return <code>true</code> if this list child is visible,
+       *         <code>false</code> otherwise
+       */
+      public boolean isVisible()
+      {
+        return listIndex >= parent.getFirstVisibleIndex()
+               && listIndex <= parent.getLastVisibleIndex();
+      }
+
+      /**
+       * The value of the visible property cannot be modified, so this method
+       * does nothing.
+       *
+       * @param b not used here
+       */
+      public void setVisible(boolean b)
+      {
+        // The value of the visible property cannot be modified, so this method
+        // does nothing.
+      }
+
+      /**
+       * Returns <code>true</code> if this list child is currently showing on
+       * screen and <code>false</code> otherwise. The list child is showing if
+       * it is visible and if it's parent JList is currently showing.
+       *
+       * @return <code>true</code> if this list child is currently showing on
+       *         screen and <code>false</code> otherwise
+       */
+      public boolean isShowing()
+      {
+        return isVisible() && parent.isShowing();
+      }
+
+      /**
+       * Returns <code>true</code> if this list child covers the screen location
+       * <code>point</code> (relative to the <code>JList</code> coordinate
+       * system, <code>false</code> otherwise.
+       *
+       * @return <code>true</code> if this list child covers the screen location
+       *         <code>point</code> , <code>false</code> otherwise
+       */
+      public boolean contains(Point point)
+      {
+        return getBounds().contains(point);
+      }
+
+      /**
+       * Returns the absolute screen location of this list child.
+       *
+       * @return the absolute screen location of this list child
+       */
+      public Point getLocationOnScreen()
+      {
+        Point loc = getLocation();
+        SwingUtilities.convertPointToScreen(loc, parent);
+        return loc;
+      }
+
+      /**
+       * Returns the screen location of this list child relative to it's parent.
+       *
+       * @return the location of this list child relative to it's parent
+       *
+       * @see JList#indexToLocation(int)
+       */
+      public Point getLocation()
+      {
+        return parent.indexToLocation(listIndex);
+      }
+
+      /**
+       * Does nothing since the screen location cannot be set on list children
+       * explictitly.
+       *
+       * @param point not used here
+       */
+      public void setLocation(Point point)
+      {
+        // Does nothing since the screen location cannot be set on list children
+        // explictitly.
+      }
+
+      /**
+       * Returns the bounds of this list child.
+       *
+       * @return the bounds of this list child
+       *
+       * @see JList#getCellBounds(int, int)
+       */
+      public Rectangle getBounds()
+      {
+        return parent.getCellBounds(listIndex, listIndex);
+      }
+
+      /**
+       * Does nothing since the bounds cannot be set on list children
+       * individually.
+       *
+       * @param rectangle not used here
+       */
+      public void setBounds(Rectangle rectangle)
+      {
+        // Does nothing since the bounds cannot be set on list children
+        // individually.
+      }
+
+      /**
+       * Returns the size of this list child.
+       *
+       * @return the size of this list child
+       */
+      public Dimension getSize()
+      {
+        Rectangle b = getBounds();
+        return b.getSize();
+      }
+
+      /**
+       * Does nothing since the size cannot be set on list children
+       * individually.
+       *
+       * @param dimension not used here
+       */
+      public void setSize(Dimension dimension)
+      {
+        // Does nothing since the size cannot be set on list children
+        // individually.
+      }
+
+      /**
+       * Returns <code>null</code> because list children do not have children
+       * themselves
+       *
+       * @return <code>null</code>
+       */
+      public Accessible getAccessibleAt(Point point)
+      {
+        return null;
+      }
+
+      /**
+       * Returns <code>true</code> since list children are focus traversable.
+       *
+       * @return true
+       */
+      public boolean isFocusTraversable()
+      {
+        // TODO: Is this 100% ok?
+        return true;
+      }
+
+      /**
+       * Requests focus on the parent list. List children cannot request focus
+       * individually.
+       */
+      public void requestFocus()
+      {
+        // TODO: Is this 100% ok?
+        parent.requestFocus();
+      }
+
+      /**
+       * Adds a focus listener to the parent list. List children do not have
+       * their own focus management.
+       *
+       * @param listener the focus listener to add
+       */
+      public void addFocusListener(FocusListener listener)
+      {
+        // TODO: Is this 100% ok?
+        parent.addFocusListener(listener);
+      }
+
+      /**
+       * Removes a focus listener from the parent list. List children do not
+       * have their own focus management.
+       *
+       * @param listener the focus listener to remove
+       */
+      public void removeFocusListener(FocusListener listener)
+      {
+        // TODO: Is this 100%
+        parent.removeFocusListener(listener);
+      }
+
+      /**
+       * Returns the accessible role of this list item, which is
+       * {@link AccessibleRole#LABEL}.
+       *
+       * @return {@link AccessibleRole#LABEL}
+       */
+      public AccessibleRole getAccessibleRole()
+      {
+        return AccessibleRole.LABEL;
+      }
+
+      /**
+       * Returns the accessible state set of this list item.
+       *
+       * @return the accessible state set of this list item
+       */
+      public AccessibleStateSet getAccessibleStateSet()
+      {
+        AccessibleStateSet states = new AccessibleStateSet();
+        if (isVisible())
+          states.add(AccessibleState.VISIBLE);
+        if (isShowing())
+          states.add(AccessibleState.SHOWING);
+        if (isFocusTraversable())
+          states.add(AccessibleState.FOCUSABLE);
+        // TODO: How should the active state be handled? The API docs
+        // suggest that this state is set on the activated list child,
+        // that is the one that is drawn with a box. However, I don't know how
+        // to implement this.
+
+        // TODO: We set the selectable state here because list children are
+        // selectable. Is there a way to disable single children?
+        if (parent.isEnabled())
+          states.add(AccessibleState.SELECTABLE);
+ 
+        if (parent.isSelectedIndex(listIndex))
+          states.add(AccessibleState.SELECTED);
+
+        // TODO: Handle more states here?
+        return states;
+      }
+
+      /**
+       * Returns the index of this list child within it's parent list.
+       *
+       * @return the index of this list child within it's parent list
+       */
+      public int getAccessibleIndexInParent()
+      {
+        return listIndex;
+      }
+
+      /**
+       * Returns <code>0</code> since list children don't have children
+       * themselves.
+       *
+       * @return <code>0</code>
+       */
+      public int getAccessibleChildrenCount()
+      {
+        return 0;
+      }
+
+      /**
+       * Returns <code>null</code> since list children don't have children
+       * themselves.
+       *
+       * @return <code>null</code>
+       */
+      public Accessible getAccessibleChild(int i)
+      {
+        return null;
+      }
+
+      /**
+       * Returns the locale of this component. This call is forwarded to the
+       * parent list since list children don't have a separate locale setting.
+       *
+       * @return the locale of this component
+       */
+      public Locale getLocale()
+      {
+        return parent.getLocale();
+      }
+
+      /**
+       * This method does
+       * nothing, list children are transient accessible objects which means
+       * that they don't fire property change events.
+       *
+       * @param l not used here
+       */
+      public void addPropertyChangeListener(PropertyChangeListener l)
+      {
+        // Do nothing here.
+      }
+
+      /**
+       * This method does
+       * nothing, list children are transient accessible objects which means
+       * that they don't fire property change events.
+       *
+       * @param l not used here
+       */
+      public void removePropertyChangeListener(PropertyChangeListener l)
+      {
+        // Do nothing here.
+      }
+      
+      // TODO: Implement the remaining methods of this class.
+    }
+    
+    /**
+     * Create a new AccessibleJList.
+     */
+    public AccessibleJList()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns the number of selected accessible children.
+     *
+     * @return the number of selected accessible children
+     */
+    public int getAccessibleSelectionCount()
+    {
+      return getSelectedIndices().length;
+    }
+
+    /**
+     * Returns the n-th selected accessible child.
+     *
+     * @param n the index of the selected child to return
+     *
+     * @return the n-th selected accessible child
+     */
+    public Accessible getAccessibleSelection(int n)
+    {
+      return new AccessibleJListChild(JList.this, getSelectedIndices()[n]);
+    }
+
+    /**
+     * Returns <code>true</code> if the n-th child is selected,
+     * <code>false</code> otherwise.
+     *
+     * @param n the index of the child of which the selected state is queried
+     *
+     * @return <code>true</code> if the n-th child is selected,
+     *         <code>false</code> otherwise
+     */
+    public boolean isAccessibleChildSelected(int n)
+    {
+      return isSelectedIndex(n);
+    }
+
+    /**
+     * Adds the accessible item with the specified index to the selected items.
+     * If multiple selections are supported, the item is added to the selection,
+     * otherwise the item replaces the current selection.
+     *
+     * @param i the index of the item to add to the selection
+     */
+    public void addAccessibleSelection(int i)
+    {
+      addSelectionInterval(i, i);
+    }
+
+    /**
+     * Removes the accessible item with the specified index to the selection.
+     *
+     * @param i the index of the item to be removed from the selection
+     */
+    public void removeAccessibleSelection(int i)
+    {
+      removeSelectionInterval(i, i);
+    }
+
+    /**
+     * Remove all selection items from the selection.
+     */
+    public void clearAccessibleSelection()
+    {
+      clearSelection();
+    }
+
+    /**
+     * Selects all items if multiple selections are supported.
+     * Otherwise do nothing.
+     */
+    public void selectAllAccessibleSelection()
+    {
+      addSelectionInterval(0, getModel().getSize());
+    }
+
+    /**
+     * Receices notification when the list selection is changed. This method
+     * fires two property change events, the first with
+     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY} and the second
+     * with {@link AccessibleContext#ACCESSIBLE_SELECTION_PROPERTY}.
+     *
+     * @param event the list selection event
+     */
+    public void valueChanged(ListSelectionEvent event)
+    {
+      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
+                         Boolean.TRUE);
+      firePropertyChange(ACCESSIBLE_SELECTION_PROPERTY, Boolean.FALSE,
+                         Boolean.TRUE);
+    }
+
+    /**
+     * Receives notification when items have changed in the
+     * <code>JList</code>. This method fires a property change event with
+     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY}.
+     *
+     * @param event the list data event
+     */
+    public void contentsChanged(ListDataEvent event)
+    {
+      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
+                         Boolean.TRUE);
+    }
+
+    /**
+     * Receives notification when items are inserted into the
+     * <code>JList</code>. This method fires a property change event with
+     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY}.
+     *
+     * @param event the list data event
+     */
+    public void intervalAdded(ListDataEvent event)
+    {
+      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
+                         Boolean.TRUE);
+    }
+
+    /**
+     * Receives notification when items are removed from the
+     * <code>JList</code>. This method fires a property change event with
+     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY}.
+     *
+     * @param event the list data event
+     */
+    public void intervalRemoved(ListDataEvent event)
+    {
+      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
+                         Boolean.TRUE);
+    }
+
+
+    /**
+     * Receives notification about changes of the <code>JList</code>'s
+     * properties. This is used to re-register this object as listener to
+     * the data model and selection model when the data model or selection model
+     * changes.
+     *
+     * @param e the property change event
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      String propertyName = e.getPropertyName();
+      if (propertyName.equals("model"))
+        {
+          ListModel oldModel = (ListModel) e.getOldValue();
+          oldModel.removeListDataListener(this);
+          ListModel newModel = (ListModel) e.getNewValue();
+          newModel.addListDataListener(this);
+        }
+      else if (propertyName.equals("selectionModel"))
+        {
+          ListSelectionModel oldModel = (ListSelectionModel) e.getOldValue();
+          oldModel.removeListSelectionListener(this);
+          ListSelectionModel newModel = (ListSelectionModel) e.getNewValue();
+          oldModel.addListSelectionListener(this);
+        }
+    }
+
+    /**
+     * Return the state set of the <code>JList</code>.
+     *
+     * @return the state set of the <code>JList</code>
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      // TODO: Figure out if there is possibly more state that must be
+      // handled here.
+      AccessibleStateSet s = super.getAccessibleStateSet();
+      if (getSelectionMode() != ListSelectionModel.SINGLE_SELECTION)
+        s.add(AccessibleState.MULTISELECTABLE);
+      return s;
+    }
+
+    /**
+     * Returns the accessible role for <code>JList</code>,
+     * {@link AccessibleRole#LIST}.
+     *
+     * @return the accessible role for <code>JList</code>
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.LIST;
+    }
+
+    /**
+     * Returns the accessible child at the visual location <code>p</code>
+     * (relative to the upper left corner of the <code>JList</code>). If there
+     * is no child at that location, this returns <code>null</code>.
+     *
+     * @param p the screen location for which to return the accessible child
+     *
+     * @return the accessible child at the specified location, or
+     *         <code>null</code> if there is no child at that location
+     */
+    public Accessible getAccessibleAt(Point p)
+    {
+      int childIndex = locationToIndex(p);
+      return getAccessibleChild(childIndex);
+    }
+
+    /**
+     * Returns the number of accessible children in the <code>JList</code>.
+     *
+     * @return the number of accessible children in the <code>JList</code>
+     */
+    public int getAccessibleChildrenCount()
+    {
+      return getModel().getSize();
+    }
+
+    /**
+     * Returns the n-th accessible child of this <code>JList</code>. This will
+     * be an instance of {@link AccessibleJListChild}. If there is no child
+     * at that index, <code>null</code> is returned.
+     *
+     * @param n the index of the child to return
+     *
+     * @return the n-th accessible child of this <code>JList</code>
+     */
+    public Accessible getAccessibleChild(int n)
+    {
+      if (getModel().getSize() <= n)
+        return null;
+      return new AccessibleJListChild(JList.this, n);
+    }
+  }
+
+  private static final long serialVersionUID = 4406629526391098046L;
+
+  /** 
+   * Constant value used in "layoutOrientation" property. This value means
+   * that cells are laid out in a single vertical column. This is the default. 
+   */
+  public static final int VERTICAL = 0;
+
+  /** 
+   * Constant value used in "layoutOrientation" property. This value means
+   * that cells are laid out in multiple columns "newspaper style", filling
+   * vertically first, then horizontally. 
+   */
+  public static final int VERTICAL_WRAP = 1;
+  
+  /** 
+   * Constant value used in "layoutOrientation" property. This value means
+   * that cells are laid out in multiple columns "newspaper style",
+   * filling horizontally first, then vertically. 
+   */
+  public static final int HORIZONTAL_WRAP = 2;
+
+  /**
+   * This property indicates whether "drag and drop" functions are enabled
+   * on the list.
+   */
+  boolean dragEnabled;
+
+  /** This property provides a strategy for rendering cells in the list. */
+  ListCellRenderer cellRenderer;
+
+  /**
+   * This property indicates an fixed width to assign to all cells in the
+   * list. If its value is <code>-1</code>, no width has been
+   * assigned. This value can be set explicitly, or implicitly by setting
+   * the {@link #prototypeCellValue} property.
+   */
+  int fixedCellWidth;
+  
+  /**
+   * This property indicates an fixed height to assign to all cells in the
+   * list. If its value is <code>-1</code>, no height has been
+   * assigned. This value can be set explicitly, or implicitly by setting
+   * the {@link #prototypeCellValue} property.
+   */
+  int fixedCellHeight;
+
+  /** 
+   * This property holds the current layout orientation of the list, which
+   * is one of the integer constants {@link #VERTICAL}, {@link
+   * #VERTICAL_WRAP}, or {@link #HORIZONTAL_WRAP}. 
+   */
+  int layoutOrientation;
+  
+  /** This property holds the data elements displayed by the list. */
+  ListModel model;
+
+  /**
+   * <p>This property holds a reference to a "prototype" data value --
+   * typically a String -- which is used to calculate the {@link
+   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
+   * {@link #cellRenderer} property to acquire a component to render the
+   * prototype.</p>
+   *
+   * <p>It is important that you <em>not</em> set this value to a
+   * component. It has to be a <em>data value</em> such as the objects you
+   * would find in the list's model. Setting it to a component will have
+   * undefined (and undesirable) affects. </p>
+   */
+  Object prototypeCellValue;
+
+  /** 
+   * This property specifies a foreground color for the selected cells in
+   * the list. When {@link ListCellRenderer#getListCellRendererComponent}
+   * is called with a selected cell object, the component returned will
+   * have its "foreground" set to this color.
+   */
+  Color selectionBackground;
+
+  /** 
+   * This property specifies a background color for the selected cells in
+   * the list. When {@link ListCellRenderer#getListCellRendererComponent}
+   * is called with a selected cell object, the component returned will
+   * have its "background" property set to this color.
+   */
+  Color selectionForeground;
+
+  /** 
+   * This property holds a description of which data elements in the {@link
+   * #model} property should be considered "selected", when displaying and
+   * interacting with the list.
+   */
+  ListSelectionModel selectionModel;
+
+  /** 
+   * This property indicates a <em>preference</em> for the number of rows
+   * displayed in the list, and will scale the
+   * {@link #getPreferredScrollableViewportSize} property accordingly. The actual
+   * number of displayed rows, when the list is placed in a real {@link
+   * JViewport} or other component, may be greater or less than this number.
+   */
+  int visibleRowCount;
+
+  /**
+   * Fire a {@link ListSelectionEvent} to all the registered 
+   * ListSelectionListeners.
+   * 
+   * @param firstIndex  the lowest index covering the selection change.
+   * @param lastIndex  the highest index covering the selection change.
+   * @param isAdjusting  a flag indicating if this event is one in a series
+   *     of events updating the selection.
+   */
+  protected void fireSelectionValueChanged(int firstIndex, int lastIndex, 
+                                           boolean isAdjusting) 
+  {
+    ListSelectionEvent evt = new ListSelectionEvent(this, firstIndex, 
+                                                    lastIndex, isAdjusting);
+    ListSelectionListener listeners[] = getListSelectionListeners();
+    for (int i = 0; i < listeners.length; ++i)
+      {
+        listeners[i].valueChanged(evt);
+      }
+  }
+
+  /**
+   * This private listener propagates {@link ListSelectionEvent} events
+   * from the list's "selectionModel" property to the list's {@link
+   * ListSelectionListener} listeners. It also listens to {@link
+   * ListDataEvent} events from the list's {@link #model} property. If this
+   * class receives either type of event, it triggers repainting of the
+   * list.
+   */
+  private class ListListener 
+    implements ListSelectionListener, ListDataListener
+  {
+    // ListDataListener events
+    public void contentsChanged(ListDataEvent event)
+    {
+      JList.this.revalidate();
+      JList.this.repaint();
+    }
+    public void intervalAdded(ListDataEvent event)
+    {
+      JList.this.revalidate();
+      JList.this.repaint();
+    }
+    public void intervalRemoved(ListDataEvent event)
+    {
+      JList.this.revalidate();
+      JList.this.repaint();
+    }
+    // ListSelectionListener events
+    public void valueChanged(ListSelectionEvent event)
+    {
+      JList.this.fireSelectionValueChanged(event.getFirstIndex(),
+                                           event.getLastIndex(),
+                                           event.getValueIsAdjusting());
+      JList.this.repaint();
+    }
+  }
+
+  /** 
+   * Shared ListListener instance, subscribed to both the current {@link
+   * #model} and {@link #selectionModel} properties of the list.
+   */
+  ListListener listListener;
+
+
+  /**
+   * Creates a new <code>JList</code> object.
+   */
+  public JList()
+  {
+    init(new DefaultListModel());
+  }
+
+  /**
+   * Creates a new <code>JList</code> object.
+   *
+   * @param items  the initial list items.
+   */
+  public JList(Object[] items)
+  {
+    init(createListModel(items));
+  }
+
+  /**
+   * Creates a new <code>JList</code> object.
+   *
+   * @param items  the initial list items.
+   */
+  public JList(Vector items)
+  {
+    init(createListModel(items));
+  }
+
+  /**
+   * Creates a new <code>JList</code> object.
+   *
+   * @param model  a model containing the list items (<code>null</code> not
+   *     permitted).
+   *     
+   * @throws IllegalArgumentException if <code>model</code> is 
+   *     <code>null</code>.
+   */
+  public JList(ListModel model)
+  {
+    init(model);
+  }
+
+  /**
+   * Initializes the list.
+   *
+   * @param m  the list model (<code>null</code> not permitted).
+   */
+  private void init(ListModel m)
+  {
+    if (m == null)
+      throw new IllegalArgumentException("Null model not permitted.");
+    dragEnabled = false;
+    fixedCellHeight = -1;
+    fixedCellWidth = -1;
+    layoutOrientation = VERTICAL;
+    opaque = true;
+    visibleRowCount = 8;
+
+    cellRenderer = new DefaultListCellRenderer();
+    listListener = new ListListener();
+
+    model = m;
+    if (model != null)
+      model.addListDataListener(listListener);
+
+    selectionModel = createSelectionModel();
+    if (selectionModel != null)
+      {
+        selectionModel.addListSelectionListener(listListener);
+        selectionModel.setSelectionMode
+                              (ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+      }
+    setLayout(null);
+    
+    updateUI();
+  }
+
+  /**
+   * Creates the default <code>ListSelectionModel</code>.
+   *
+   * @return the <code>ListSelectionModel</code>
+   */
+  protected ListSelectionModel createSelectionModel()
+  {
+    return new DefaultListSelectionModel();
+  }
+  
+  /**
+   * Gets the value of the {@link #fixedCellHeight} property. This property
+   * may be <code>-1</code> to indicate that no cell height has been
+   * set. This property is also set implicitly when the
+   * {@link #prototypeCellValue} property is set.
+   *
+   * @return The current value of the property 
+   * 
+   * @see #fixedCellHeight
+   * @see #setFixedCellHeight
+   * @see #setPrototypeCellValue
+   */
+  public int getFixedCellHeight()
+  {
+    return fixedCellHeight;
+  }
+
+  /**
+   * Sets the value of the {@link #fixedCellHeight} property. This property
+   * may be <code>-1</code> to indicate that no cell height has been
+   * set. This property is also set implicitly when the {@link
+   * #prototypeCellValue} property is set, but setting it explicitly
+   * overrides the height computed from {@link #prototypeCellValue}.
+   *
+   * @param h  the height.
+   * 
+   * @see #getFixedCellHeight
+   * @see #getPrototypeCellValue
+   */
+  public void setFixedCellHeight(int h)
+  {
+    if (fixedCellHeight == h)
+      return;
+
+    int old = fixedCellHeight;
+    fixedCellHeight = h;
+    firePropertyChange("fixedCellHeight", old, h);
+  }
+
+
+  /**
+   * Gets the value of the {@link #fixedCellWidth} property. This property
+   * may be <code>-1</code> to indicate that no cell width has been
+   * set. This property is also set implicitly when the {@link
+   * #prototypeCellValue} property is set.
+   *
+   * @return The current value of the property 
+   * 
+   * @see #setFixedCellWidth
+   * @see #setPrototypeCellValue
+   */
+  public int getFixedCellWidth()
+  {
+    return fixedCellWidth;
+  }
+
+  /**
+   * Sets the value of the {@link #fixedCellWidth} property. This property
+   * may be <code>-1</code> to indicate that no cell width has been
+   * set. This property is also set implicitly when the {@link
+   * #prototypeCellValue} property is set, but setting it explicitly
+   * overrides the width computed from {@link #prototypeCellValue}.
+   *
+   * @param w  the width.
+   * 
+   * @see #getFixedCellHeight
+   * @see #getPrototypeCellValue
+   */
+  public void setFixedCellWidth(int w)
+  {
+    if (fixedCellWidth == w)
+      return;
+    
+    int old = fixedCellWidth;
+    fixedCellWidth = w;
+    firePropertyChange("fixedCellWidth", old, w);
+  }
+
+  /** 
+   * Gets the value of the {@link #visibleRowCount} property.  The default 
+   * value is 8.
+   *
+   * @return the current value of the property.
+   * 
+   * @see #setVisibleRowCount(int)
+   */
+  public int getVisibleRowCount()
+  {
+    return visibleRowCount;
+  }
+
+  /**
+   * Sets the value of the {@link #visibleRowCount} property. 
+   *
+   * @param vc The new property value
+   * 
+   * @see #getVisibleRowCount()
+   */
+  public void setVisibleRowCount(int vc)
+  {
+    if (visibleRowCount != vc)
+      {
+        int oldValue = visibleRowCount;
+        visibleRowCount = Math.max(vc, 0);
+        firePropertyChange("visibleRowCount", oldValue, vc);
+        revalidate();
+        repaint();
+      }
+  }
+
+  /**
+   * Adds a {@link ListSelectionListener} to the listener list for this
+   * list. The listener will be called back with a {@link
+   * ListSelectionEvent} any time the list's {@link #selectionModel}
+   * property changes. The source of such events will be the JList,
+   * not the selection model.
+   *
+   * @param listener The new listener to add
+   */
+  public void addListSelectionListener(ListSelectionListener listener)
+  {
+    listenerList.add (ListSelectionListener.class, listener);
+  }
+
+  /**
+   * Removes a {@link ListSelectionListener} from the listener list for
+   * this list. The listener will no longer be called when the list's
+   * {@link #selectionModel} changes.
+   *
+   * @param listener The listener to remove
+   */
+  public void removeListSelectionListener(ListSelectionListener listener)
+  {
+    listenerList.remove(ListSelectionListener.class, listener);
+  }
+
+  /**
+   * Returns an array of all ListSelectionListeners subscribed to this
+   * list. 
+   *
+   * @return The current subscribed listeners
+   *
+   * @since 1.4
+   */
+  public ListSelectionListener[] getListSelectionListeners()
+  {
+    return (ListSelectionListener[]) getListeners(ListSelectionListener.class);
+  }
+
+  /**
+   * Returns the selection mode for the list (one of: 
+   * {@link ListSelectionModel#SINGLE_SELECTION}, 
+   * {@link ListSelectionModel#SINGLE_INTERVAL_SELECTION} and 
+   * {@link ListSelectionModel#MULTIPLE_INTERVAL_SELECTION}).
+   * 
+   * @return The selection mode.
+   * 
+   * @see #setSelectionMode(int)
+   */
+  public int getSelectionMode()
+  {
+    return selectionModel.getSelectionMode();
+  }
+  
+  /**
+   * Sets the list's "selectionMode" property, which simply mirrors the
+   * same property on the list's {@link #selectionModel} property. This
+   * property should be one of the integer constants
+   * <code>SINGLE_SELECTION</code>, <code>SINGLE_INTERVAL_SELECTION</code>,
+   * or <code>MULTIPLE_INTERVAL_SELECTION</code> from the {@link
+   * ListSelectionModel} interface.
+   *
+   * @param a The new selection mode
+   */
+  public void setSelectionMode(int a)
+  {
+    selectionModel.setSelectionMode(a);
+  }
+
+  /**
+   * Adds the interval <code>[a,a]</code> to the set of selections managed
+   * by this list's {@link #selectionModel} property. Depending on the
+   * selection mode, this may cause existing selections to become invalid,
+   * or may simply expand the set of selections. 
+   *
+   * @param a A number in the half-open range <code>[0, x)</code> where
+   * <code>x = getModel.getSize()</code>, indicating the index of an
+   * element in the list to select. When < 0 the selection is cleared.
+   *
+   * @see #setSelectionMode
+   * @see #selectionModel
+   */
+  public void setSelectedIndex(int a)
+  {
+    if (a < 0)
+      selectionModel.clearSelection();
+    else
+      selectionModel.setSelectionInterval(a, a);
+  }
+
+  /**
+   * For each element <code>a[i]</code> of the provided array
+   * <code>a</code>, calls {@link #setSelectedIndex} on <code>a[i]</code>.
+   *
+   * @param a  an array of selected indices (<code>null</code> not permitted).
+   * 
+   * @throws NullPointerException if <code>a</code> is <code>null</code>.
+   * @see #setSelectionMode
+   * @see #selectionModel
+   */
+  public void setSelectedIndices(int [] a)
+  {
+    for (int i = 0; i < a.length; ++i)
+      setSelectedIndex(a[i]);
+  }
+
+  /**
+   * Returns the minimum index of an element in the list which is currently
+   * selected.
+   *
+   * @return A number in the half-open range <code>[0, x)</code> where
+   * <code>x = getModel.getSize()</code>, indicating the minimum index of
+   * an element in the list for which the element is selected, or
+   * <code>-1</code> if no elements are selected
+   */
+  public int getSelectedIndex()
+  {
+    return selectionModel.getMinSelectionIndex();
+  }
+
+  /**
+   * Returns <code>true</code> if the model's selection is empty, otherwise
+   * <code>false</code>. 
+   *
+   * @return The return value of {@link ListSelectionModel#isSelectionEmpty}
+   */
+  public boolean isSelectionEmpty()
+  {
+    return selectionModel.isSelectionEmpty();
+  }
+
+  /**
+   * Returns the list index of the upper left or upper right corner of the
+   * visible rectangle of this list, depending on the {@link
+   * Component#getComponentOrientation} property.
+   *
+   * @return The index of the first visible list cell, or <code>-1</code>
+   * if none is visible.
+   */
+  public int getFirstVisibleIndex()
+  {
+    ComponentOrientation or = getComponentOrientation();
+    Rectangle r = getVisibleRect();
+    if (or == ComponentOrientation.RIGHT_TO_LEFT)
+      r.translate((int) r.getWidth() - 1, 0);
+    return getUI().locationToIndex(this, r.getLocation());      
+  }
+
+
+  /**
+   * Returns index of the cell to which specified location is closest to. If
+   * the location is outside the bounds of the list, then the greatest index
+   * in the list model is returned. If the list model is empty, then
+   * <code>-1</code> is returned.
+   *
+   * @param location for which to look for in the list
+   * 
+   * @return index of the cell to which specified location is closest to.
+   */
+   public int locationToIndex(Point location)
+   {
+     return getUI().locationToIndex(this, location);      
+   }
+
+  /**
+   * Returns location of the cell located at the specified index in the list.
+   * @param index of the cell for which location will be determined
+   * 
+   * @return location of the cell located at the specified index in the list.
+   */
+   public Point indexToLocation(int index)
+   {
+     return getUI().indexToLocation(this, index);
+   }
+
+  /**
+   * Returns the list index of the lower right or lower left corner of the
+   * visible rectangle of this list, depending on the {@link
+   * Component#getComponentOrientation} property.
+   *
+   * @return The index of the last visible list cell, or <code>-1</code>
+   * if none is visible.
+   */
+  public int getLastVisibleIndex()
+  {
+    ComponentOrientation or = getComponentOrientation();
+    Rectangle r = getVisibleRect();
+    r.translate(0, (int) r.getHeight() - 1);
+    if (or == ComponentOrientation.LEFT_TO_RIGHT)
+      r.translate((int) r.getWidth() - 1, 0);
+    if (getUI().locationToIndex(this, r.getLocation()) == -1
+        && indexToLocation(getModel().getSize() - 1).y < r.y)
+      return getModel().getSize() - 1;
+    return getUI().locationToIndex(this, r.getLocation());
+  }
+
+  /**
+   * Returns the indices of values in the {@link #model} property which are
+   * selected.
+   *
+   * @return An array of model indices, each of which is selected according
+   *         to the {@link #getSelectedValues} property
+   */
+  public int[] getSelectedIndices()
+  {
+    int lo, hi, n, i, j;
+    if (selectionModel.isSelectionEmpty())
+      return new int[0];
+    lo = selectionModel.getMinSelectionIndex();
+    hi = selectionModel.getMaxSelectionIndex();
+    n = 0;
+    for (i = lo; i <= hi; ++i)
+      if (selectionModel.isSelectedIndex(i))
+        n++;
+    int [] v = new int[n];
+    j = 0;
+    for (i = lo; i <= hi; ++i)
+      if (selectionModel.isSelectedIndex(i))
+        v[j++] = i;
+    return v;
+  }
+
+  /**
+   * Indicates whether the list element at a given index value is
+   * currently selected.
+   *
+   * @param a The index to check 
+   * @return <code>true</code> if <code>a</code> is the index of a selected
+   * list element
+   */
+  public boolean isSelectedIndex(int a)
+  {
+    return selectionModel.isSelectedIndex(a);
+  }
+
+  /**
+   * Returns the first value in the list's {@link #model} property which is
+   * selected, according to the list's {@link #selectionModel} property.
+   * This is equivalent to calling
+   * <code>getModel()getElementAt(getSelectedIndex())</code>, with a check
+   * for the special index value of <code>-1</code> which returns null
+   * <code>null</code>.
+   *
+   * @return The first selected element, or <code>null</code> if no element
+   * is selected.
+   *
+   * @see #getSelectedValues
+   */
+  public Object getSelectedValue()
+  {
+    int index = getSelectedIndex();
+    if (index == -1)
+      return null;
+    return getModel().getElementAt(index);
+  }
+
+  /**
+   * Returns all the values in the list's {@link #model} property which are
+   * selected, according to the list's {@link #selectionModel} property.
+   * 
+   * @return An array containing all the selected values
+   * @see #setSelectedValue
+   */
+  public Object[] getSelectedValues()
+  {
+    int[] idx = getSelectedIndices();
+    Object[] v = new Object[idx.length];
+    for (int i = 0; i < idx.length; ++i)
+      v[i] = getModel().getElementAt(idx[i]);
+    return v;
+  }
+
+  /**
+   * Gets the value of the {@link #selectionBackground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionBackground()
+  {
+    return selectionBackground;
+  }
+
+  /**
+   * Sets the value of the {@link #selectionBackground} property.
+   *
+   * @param c The new value of the property
+   */
+  public void setSelectionBackground(Color c)
+  {
+    if (selectionBackground == c)
+      return;
+
+    Color old = selectionBackground;
+    selectionBackground = c;
+    firePropertyChange("selectionBackground", old, c);
+    repaint();
+  }
+
+  /**
+   * Gets the value of the {@link #selectionForeground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionForeground()
+  {
+    return selectionForeground;
+  }
+  
+  /**
+   * Sets the value of the {@link #selectionForeground} property.
+   *
+   * @param c The new value of the property
+   */
+  public void setSelectionForeground(Color c)
+  {
+    if (selectionForeground == c)
+      return;
+
+    Color old = selectionForeground;
+    selectionForeground = c;
+    firePropertyChange("selectionForeground", old, c);
+  }
+
+  /**
+   * Sets the selection to cover only the specified value, if it
+   * exists in the model. 
+   *
+   * @param obj The object to select
+   * @param scroll Whether to scroll the list to make the newly selected
+   * value visible
+   *
+   * @see #ensureIndexIsVisible
+   */
+
+  public void setSelectedValue(Object obj, boolean scroll)
+  {
+    for (int i = 0; i < model.getSize(); ++i)
+      {
+        if (model.getElementAt(i).equals(obj))
+          {
+            setSelectedIndex(i);
+            if (scroll)
+              ensureIndexIsVisible(i);
+            break;
+          }
+      }
+  }
+
+  /**
+   * Scrolls this list to make the specified cell visible. This
+   * only works if the list is contained within a viewport.
+   *
+   * @param i The list index to make visible
+   *
+   * @see JComponent#scrollRectToVisible
+   */
+  public void ensureIndexIsVisible(int i)
+  {
+    Rectangle r = getUI().getCellBounds(this, i, i);
+    if (r != null)
+      scrollRectToVisible(r);
+  }
+
+  /**
+   * Sets the {@link #model} property of the list to a new anonymous
+   * {@link AbstractListModel} subclass which accesses the provided Object
+   * array directly.
+   *
+   * @param listData The object array to build a new list model on
+   * @see #setModel
+   */
+  public void setListData(Object[] listData)
+  {
+    setModel(createListModel(listData));
+  }
+
+  /**
+   * Returns a {@link ListModel} backed by the specified array.
+   * 
+   * @param items  the list items (don't use <code>null</code>).
+   * 
+   * @return A list model containing the specified items.
+   */
+  private ListModel createListModel(final Object[] items)
+  {
+    return new AbstractListModel()
+      {
+        public int getSize()
+        {
+          return items.length;
+        }
+        public Object getElementAt(int i)
+        {
+          return items[i];
+        }
+      };
+  }
+  
+  /**
+   * Returns a {@link ListModel} backed by the specified vector.
+   * 
+   * @param items  the list items (don't use <code>null</code>).
+   * 
+   * @return A list model containing the specified items.
+   */
+  private ListModel createListModel(final Vector items)
+  {
+    return new AbstractListModel()
+      {
+        public int getSize()
+        {
+          return items.size();
+        }
+        public Object getElementAt(int i)
+        {
+          return items.get(i);
+        }
+      };
+  }
+
+  /**
+   * Sets the {@link #model} property of the list to a new anonymous {@link
+   * AbstractListModel} subclass which accesses the provided vector
+   * directly.
+   *
+   * @param listData The object array to build a new list model on
+   * @see #setModel
+   */
+  public void setListData(Vector listData)
+  {
+    setModel(createListModel(listData));
+  }
+
+  /**
+   * Gets the value of the {@link #cellRenderer} property. 
+   *
+   * @return The current value of the property
+   */
+  public ListCellRenderer getCellRenderer()
+  {
+    return cellRenderer;
+  }
+
+  /**
+   * Sets the value of the {@link #getCellRenderer} property.
+   *
+   * @param renderer The new property value
+   */
+  public void setCellRenderer(ListCellRenderer renderer)
+  {
+    if (cellRenderer == renderer)
+      return;
+    
+    ListCellRenderer old = cellRenderer;
+    cellRenderer = renderer;
+    firePropertyChange("cellRenderer", old, renderer);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Gets the value of the {@link #model} property. 
+   *
+   * @return The current value of the property
+   */
+  public ListModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * Sets the value of the {@link #model} property. The list's {@link
+   * #listListener} is unsubscribed from the existing model, if it exists,
+   * and re-subscribed to the new model.
+   *
+   * @param model  the new model (<code>null</code> not permitted).
+   * 
+   * @throws IllegalArgumentException if <code>model</code> is 
+   *         <code>null</code>.
+   */
+  public void setModel(ListModel model)
+  {
+    if (model == null) 
+      throw new IllegalArgumentException("Null 'model' argument.");
+    if (this.model == model)
+      return;
+    
+    if (this.model != null)
+      this.model.removeListDataListener(listListener);
+    
+    ListModel old = this.model;
+    this.model = model;
+    
+    if (this.model != null)
+      this.model.addListDataListener(listListener);
+    
+    firePropertyChange("model", old, model);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Returns the selection model for the {@link JList} component.  Note that
+   * this class contains a range of convenience methods for configuring the
+   * selection model:<br>
+   * <ul>
+   *   <li>{@link #clearSelection()};</li>
+   *   <li>{@link #setSelectionMode(int)};</li>
+   *   <li>{@link #addSelectionInterval(int, int)};</li>
+   *   <li>{@link #setSelectedIndex(int)};</li>
+   *   <li>{@link #setSelectedIndices(int[])};</li>
+   *   <li>{@link #setSelectionInterval(int, int)}.</li>
+   * </ul>
+   * 
+   * @return The selection model.
+   */
+  public ListSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  }
+
+  /**
+   * Sets the value of the {@link #selectionModel} property. The list's
+   * {@link #listListener} is unsubscribed from the existing selection
+   * model, if it exists, and re-subscribed to the new selection model.
+   *
+   * @param model The new property value
+   */
+  public void setSelectionModel(ListSelectionModel model)
+  {
+    if (selectionModel == model)
+      return;
+    
+    if (selectionModel != null)
+      selectionModel.removeListSelectionListener(listListener);
+    
+    ListSelectionModel old = selectionModel;
+    selectionModel = model;
+    
+    if (selectionModel != null)
+      selectionModel.addListSelectionListener(listListener);
+    
+    firePropertyChange("selectionModel", old, model);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Gets the value of the UI property.
+   *
+   * @return The current property value
+   */
+  public ListUI getUI()
+  {
+    return (ListUI) ui;
+  }
+
+  /**
+   * Sets the value of the UI property.
+   *
+   * @param ui The new property value
+   */
+  public void setUI(ListUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Calls {@link #setUI} with the {@link ListUI} subclass
+   * returned from calling {@link UIManager#getUI}.
+   */
+  public void updateUI()
+  {
+    setUI((ListUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Return the class identifier for the list's UI property.  This should
+   * be the constant string <code>"ListUI"</code>, and map to an
+   * appropriate UI class in the {@link UIManager}.
+   *
+   * @return The class identifier
+   */
+  public String getUIClassID()
+  {
+    return "ListUI";
+  }
+
+
+  /**
+   * Returns the current value of the {@link #prototypeCellValue}
+   * property. This property holds a reference to a "prototype" data value
+   * -- typically a String -- which is used to calculate the {@link
+   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
+   * {@link #cellRenderer} property to acquire a component to render the
+   * prototype.
+   *
+   * @return The current prototype cell value
+   * @see #setPrototypeCellValue
+   */
+  public Object getPrototypeCellValue()
+  {
+    return prototypeCellValue;
+  }
+
+  /**
+   * <p>Set the {@link #prototypeCellValue} property. This property holds a
+   * reference to a "prototype" data value -- typically a String -- which
+   * is used to calculate the {@link #fixedCellWidth} and {@link
+   * #fixedCellHeight} properties, using the {@link #cellRenderer} property
+   * to acquire a component to render the prototype.</p>
+   *
+   * <p>It is important that you <em>not</em> set this value to a
+   * component. It has to be a <em>data value</em> such as the objects you
+   * would find in the list's model. Setting it to a component will have
+   * undefined (and undesirable) affects. </p>
+   *
+   * @param obj The new prototype cell value
+   * @see #getPrototypeCellValue
+   */
+  public void setPrototypeCellValue(Object obj)
+  {
+    if (prototypeCellValue == obj)
+      return;
+
+    Object old = prototypeCellValue;
+    Component comp = getCellRenderer()
+      .getListCellRendererComponent(this, obj, 0, false, false); 
+    Dimension d = comp.getPreferredSize();
+    fixedCellWidth = d.width;
+    fixedCellHeight = d.height;
+    prototypeCellValue = obj;
+    firePropertyChange("prototypeCellValue", old, obj);
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    return new AccessibleJList();
+  }
+
+  /**
+   * Returns a size indicating how much space this list would like to
+   * consume, when contained in a scrollable viewport. This is part of the
+   * {@link Scrollable} interface, which interacts with {@link
+   * ScrollPaneLayout} and {@link JViewport} to define scrollable objects.
+   *
+   * @return The preferred size
+   */
+  public Dimension getPreferredScrollableViewportSize()
+  {
+    //If the layout orientation is not VERTICAL, then this will 
+    //return the value from getPreferredSize. The current ListUI is 
+    //expected to override getPreferredSize to return an appropriate value.
+    if (getLayoutOrientation() != VERTICAL)
+      return getPreferredSize();        
+
+    int size = getModel().getSize();
+    
+    // Trivial case: if fixedCellWidth and fixedCellHeight were set 
+    // just use them
+    if (fixedCellHeight != -1 && fixedCellWidth != -1)
+      return new Dimension(fixedCellWidth, size * fixedCellHeight);
+        
+    // If the model is empty we use 16 * the number of visible rows
+    // for the height and either fixedCellWidth (if set) or 256
+    // for the width
+    if (size == 0)
+      {
+        if (fixedCellWidth == -1)
+          return new Dimension(256, 16 * getVisibleRowCount());
+        else
+          return new Dimension(fixedCellWidth, 16 * getVisibleRowCount());
+      }
+
+    // Calculate the width: if fixedCellWidth was set use that, otherwise
+    // use the preferredWidth
+    int prefWidth;
+    if (fixedCellWidth != -1)
+      prefWidth = fixedCellWidth;
+    else
+      prefWidth = getPreferredSize().width;
+
+    // Calculate the height: if fixedCellHeight was set use that, otherwise
+    // use the height of the first row multiplied by the number of visible
+    // rows
+    int prefHeight;
+    if (fixedCellHeight != -1)
+      prefHeight = fixedCellHeight;
+    else
+      prefHeight = getVisibleRowCount() * getCellBounds(0, 0).height;
+
+    return new Dimension (prefWidth, prefHeight);
+  }
+
+  /**
+   * <p>Return the number of pixels the list must scroll in order to move a
+   * "unit" of the list into the provided visible rectangle. When the
+   * provided direction is positive, the call describes a "downwards"
+   * scroll, which will be exposing a cell at a <em>greater</em> index in
+   * the list than those elements currently showing. Then the provided
+   * direction is negative, the call describes an "upwards" scroll, which
+   * will be exposing a cell at a <em>lesser</em> index in the list than
+   * those elements currently showing.</p>
+   *
+   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
+   * comments refer to "rightwards" for positive direction, and "leftwards"
+   * for negative.</p>
+   * 
+   *
+   * @param visibleRect The rectangle to scroll an element into
+   * @param orientation One of the numeric consants <code>VERTICAL</code>
+   * or <code>HORIZONTAL</code>
+   * @param direction An integer indicating the scroll direction: positive means
+   * forwards (down, right), negative means backwards (up, left)
+   *
+   * @return The scrollable unit increment, in pixels
+   */
+  public int getScrollableUnitIncrement(Rectangle visibleRect,
+                                        int orientation, int direction)
+  {
+    ListUI lui = this.getUI();
+    if (orientation == SwingConstants.VERTICAL)
+      {
+        if (direction > 0)
+          {
+            // Scrolling down
+            Point bottomLeft = new Point(visibleRect.x,
+                                         visibleRect.y + visibleRect.height);
+            int curIdx = lui.locationToIndex(this, bottomLeft);
+            Rectangle curBounds = lui.getCellBounds(this, curIdx, curIdx);
+            if (curBounds.y + curBounds.height == bottomLeft.y)
+              {
+                // we are at the exact bottom of the current cell, so we 
+                // are being asked to scroll to the end of the next one
+                if (curIdx + 1 < model.getSize())
+                  {
+                    // there *is* a next item in the list
+                    Rectangle nxtBounds = lui.getCellBounds(this, curIdx + 1, curIdx + 1);
+                    return nxtBounds.height;
+                  }
+                else
+                  {
+                    // no next item, no advance possible
+                    return 0;
+                  }
+              }
+            else
+              {
+                // we are part way through an existing cell, so we are being
+                // asked to scroll to the bottom of it
+                return (curBounds.y + curBounds.height) - bottomLeft.y;
+              }		      
+          }
+        else
+          {
+            // scrolling up
+            Point topLeft = new Point(visibleRect.x, visibleRect.y);
+            int curIdx = lui.locationToIndex(this, topLeft);
+            Rectangle curBounds = lui.getCellBounds(this, curIdx, curIdx);
+            if (curBounds.y == topLeft.y)
+              {
+                // we are at the exact top of the current cell, so we 
+                // are being asked to scroll to the top of the previous one
+                if (curIdx > 0)
+                  {
+                    // there *is* a previous item in the list
+                    Rectangle nxtBounds = lui.getCellBounds(this, curIdx - 1, curIdx - 1);
+                    return -nxtBounds.height;
+                  }
+                else
+                  {
+                    // no previous item, no advance possible
+                    return 0;
+                  }
+              }
+            else
+              {
+                // we are part way through an existing cell, so we are being
+                // asked to scroll to the top of it
+                return curBounds.y - topLeft.y;
+              }		      
+          }
+      }
+
+    // FIXME: handle horizontal scrolling (also wrapping?)
+    return 1;
+  }
+
+  /**
+   * <p>Return the number of pixels the list must scroll in order to move a
+   * "block" of the list into the provided visible rectangle. When the
+   * provided direction is positive, the call describes a "downwards"
+   * scroll, which will be exposing a cell at a <em>greater</em> index in
+   * the list than those elements currently showing. Then the provided
+   * direction is negative, the call describes an "upwards" scroll, which
+   * will be exposing a cell at a <em>lesser</em> index in the list than
+   * those elements currently showing.</p>
+   *
+   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
+   * comments refer to "rightwards" for positive direction, and "leftwards"
+   * for negative.</p>
+   * 
+   *
+   * @param visibleRect The rectangle to scroll an element into
+   * @param orientation One of the numeric consants <code>VERTICAL</code>
+   * or <code>HORIZONTAL</code>
+   * @param direction An integer indicating the scroll direction: positive means
+   * forwards (down, right), negative means backwards (up, left)
+   *
+   * @return The scrollable unit increment, in pixels
+   */
+  public int getScrollableBlockIncrement(Rectangle visibleRect,
+                                         int orientation, int direction)
+  {
+      if (orientation == VERTICAL)
+	  return visibleRect.height * direction;
+      else
+	  return visibleRect.width * direction;
+  }
+
+  /**
+   * Gets the value of the <code>scrollableTracksViewportWidth</code> property.
+   *
+   * @return <code>true</code> if the viewport is larger (horizontally)
+   * than the list and the list should be expanded to fit the viewport;
+   * <code>false</code> if the viewport is smaller than the list and the
+   * list should scroll (horizontally) within the viewport
+   */
+  public boolean getScrollableTracksViewportWidth()
+  {
+    Component parent = getParent();
+    boolean retVal = false;
+    if (parent instanceof JViewport)
+      {
+        JViewport viewport = (JViewport) parent;
+        Dimension pref = getPreferredSize();
+        if (viewport.getSize().width > pref.width)
+          retVal = true;
+        if ((getLayoutOrientation() == HORIZONTAL_WRAP)
+            && (getVisibleRowCount() <= 0))
+          retVal = true;
+      }
+    return retVal;
+  }
+
+  /**
+   * Gets the value of the </code>scrollableTracksViewportWidth</code> property.
+   *
+   * @return <code>true</code> if the viewport is larger (vertically)
+   * than the list and the list should be expanded to fit the viewport;
+   * <code>false</code> if the viewport is smaller than the list and the
+   * list should scroll (vertically) within the viewport
+   */
+  public boolean getScrollableTracksViewportHeight()
+  {
+    Component parent = getParent();
+    boolean retVal = false;
+    if (parent instanceof JViewport)
+      {
+        JViewport viewport = (JViewport) parent;
+        Dimension pref = getPreferredSize();
+        if (viewport.getSize().height > pref.height)
+          retVal = true;
+        if ((getLayoutOrientation() == VERTICAL_WRAP)
+            && (getVisibleRowCount() <= 0))
+          retVal = true;
+      }
+    return retVal;
+  }
+
+  /**
+   * Returns the index of the anchor item in the current selection, or
+   * <code>-1</code> if there is no anchor item.
+   * 
+   * @return The item index.
+   */
+  public int getAnchorSelectionIndex()
+  {
+    return selectionModel.getAnchorSelectionIndex();
+  }
+
+  /**
+   * Returns the index of the lead item in the current selection, or
+   * <code>-1</code> if there is no lead item.
+   * 
+   * @return The item index.
+   */
+  public int getLeadSelectionIndex()
+  {
+    return selectionModel.getLeadSelectionIndex();
+  }
+
+  /**
+   * Returns the lowest item index in the current selection, or <code>-1</code>
+   * if there is no selection.
+   * 
+   * @return The index.
+   * 
+   * @see #getMaxSelectionIndex()
+   */
+  public int getMinSelectionIndex()
+  {
+    return selectionModel.getMinSelectionIndex();
+  }
+
+  /**
+   * Returns the highest item index in the current selection, or 
+   * <code>-1</code> if there is no selection.
+   * 
+   * @return The index.
+   * 
+   * @see #getMinSelectionIndex()
+   */
+  public int getMaxSelectionIndex()
+  {
+    return selectionModel.getMaxSelectionIndex();
+  }
+
+  /**
+   * Clears the current selection.
+   */
+  public void clearSelection()
+  {
+    selectionModel.clearSelection();
+  }
+
+  /**
+   * Sets the current selection to the items in the specified range (inclusive).
+   * Note that <code>anchor</code> can be less than, equal to, or greater than 
+   * <code>lead</code>.
+   * 
+   * @param anchor  the index of the anchor item.
+   * @param lead  the index of the anchor item.
+   */
+  public void setSelectionInterval(int anchor, int lead)
+  {
+    selectionModel.setSelectionInterval(anchor, lead);
+  }
+
+  /**
+   * Adds the specified interval to the current selection.  Note that 
+   * <code>anchor</code> can be less than, equal to, or greater than 
+   * <code>lead</code>.
+   * 
+   * @param anchor  the index of the anchor item.
+   * @param lead  the index of the lead item.
+   */
+  public void addSelectionInterval(int anchor, int lead)
+  {
+    selectionModel.addSelectionInterval(anchor, lead);
+  }
+
+  /**
+   * Removes the specified interval from the current selection.  Note that 
+   * <code>index0</code> can be less than, equal to, or greater than 
+   * <code>index1</code>.
+   * 
+   * @param index0  an index for one end of the range.
+   * @param index1  an index for the other end of the range.
+   */
+  public void removeSelectionInterval(int index0, int index1)
+  {
+    selectionModel.removeSelectionInterval(index0, index1);
+  }
+
+  /**
+   * Returns the <code>valueIsAdjusting</code> flag from the list's selection
+   * model.
+   *
+   * @return the value
+   */
+  public boolean getValueIsAdjusting()
+  {
+    return selectionModel.getValueIsAdjusting();
+  }
+
+  /**
+   * Sets the <code>valueIsAdjusting</code> flag in the list's selection 
+   * model.
+   *
+   * @param isAdjusting the new value
+   */
+  public void setValueIsAdjusting(boolean isAdjusting)
+  {
+    selectionModel.setValueIsAdjusting(isAdjusting);
+  }
+
+  /**
+   * Return the value of the <code>dragEnabled</code> property.
+   *
+   * @return the value
+   * 
+   * @since 1.4
+   */
+  public boolean getDragEnabled()
+  {
+    return dragEnabled;
+  }
+
+  /**
+   * Set the <code>dragEnabled</code> property.
+   *
+   * @param enabled new value
+   * 
+   * @since 1.4
+   */
+  public void setDragEnabled(boolean enabled)
+  {
+    dragEnabled = enabled;
+  }
+
+  /**
+   * Returns the layout orientation, which will be one of {@link #VERTICAL}, 
+   * {@link #VERTICAL_WRAP} and {@link #HORIZONTAL_WRAP}.  The default value
+   * is {@link #VERTICAL}.
+   *
+   * @return the orientation.
+   *
+   * @see #setLayoutOrientation(int)
+   * @since 1.4
+   */
+  public int getLayoutOrientation()
+  {
+    return layoutOrientation;
+  }
+
+  /**
+   * Sets the layout orientation (this is a bound property with the name
+   * 'layoutOrientation').  Valid orientations are {@link #VERTICAL}, 
+   * {@link #VERTICAL_WRAP} and {@link #HORIZONTAL_WRAP}.
+   *
+   * @param orientation the orientation.
+   *
+   * @throws IllegalArgumentException if <code>orientation</code> is not one
+   *     of the specified values.
+   * @since 1.4
+   * @see #getLayoutOrientation()
+   */
+  public void setLayoutOrientation(int orientation)
+  {
+    if (orientation < JList.VERTICAL || orientation > JList.HORIZONTAL_WRAP)
+      throw new IllegalArgumentException();
+    if (layoutOrientation == orientation)
+      return;
+
+    int old = layoutOrientation;
+    layoutOrientation = orientation;
+    firePropertyChange("layoutOrientation", old, orientation);
+  }
+
+  /**
+   * Returns the bounds of the rectangle that encloses both list cells
+   * with index0 and index1.
+   *
+   * @param index0 the index of the first cell
+   * @param index1 the index of the second cell
+   *
+   * @return  the bounds of the rectangle that encloses both list cells
+   *     with index0 and index1, <code>null</code> if one of the indices is
+   *     not valid
+   */
+  public Rectangle getCellBounds(int index0, int index1)
+  {
+    ListUI ui = getUI();
+    Rectangle bounds = null;
+    if (ui != null)
+      {
+        bounds = ui.getCellBounds(this, index0, index1);
+      }
+    // When the UI is null, this method also returns null in the RI.
+    return bounds;
+  }
+
+  /**
+   * Returns the index of the next list element (beginning at 
+   * <code>startIndex</code> and moving in the specified direction through the
+   * list, looping around if necessary) that starts with <code>prefix</code>
+   * (ignoring case).
+   *
+   * @param prefix the prefix to search for in the cell values
+   * @param startIndex the index where to start searching from
+   * @param direction the search direction, either {@link Position.Bias#Forward}
+   *     or {@link Position.Bias#Backward} (<code>null</code> is interpreted
+   *     as {@link Position.Bias#Backward}.
+   *
+   * @return the index of the found element or -1 if no such element has
+   *     been found
+   *
+   * @throws IllegalArgumentException if prefix is <code>null</code> or
+   *     startIndex is not valid
+   *
+   * @since 1.4
+   */
+  public int getNextMatch(String prefix, int startIndex, 
+                          Position.Bias direction)
+  {
+    if (prefix == null)
+      throw new IllegalArgumentException("The argument 'prefix' must not be"
+                                         + " null.");
+    if (startIndex < 0)
+      throw new IllegalArgumentException("The argument 'startIndex' must not"
+                                         + " be less than zero.");
+
+    int size = model.getSize();
+    if (startIndex >= model.getSize())
+      throw new IllegalArgumentException("The argument 'startIndex' must not"
+                                         + " be greater than the number of"
+                                         + " elements in the ListModel.");
+
+    int result = -1;
+    int current = startIndex;
+    int delta = -1;
+    int itemCount = model.getSize();
+    boolean finished = false;
+    prefix = prefix.toUpperCase();
+    
+    if (direction == Position.Bias.Forward)
+      delta = 1;
+    while (!finished)
+      {
+        String itemStr = model.getElementAt(current).toString().toUpperCase();
+        if (itemStr.startsWith(prefix))
+          return current;
+        current = (current + delta);
+        if (current == -1)
+          current += itemCount;
+        else
+          current = current % itemCount; 
+        finished = current == startIndex;
+      }
+    return result;
+  }
+  
+  /**
+   * Returns a string describing the attributes for the <code>JList</code>
+   * component, for use in debugging.  The return value is guaranteed to be 
+   * non-<code>null</code>, but the format of the string may vary between
+   * implementations.
+   *
+   * @return A string describing the attributes of the <code>JList</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",fixedCellHeight=").append(getFixedCellHeight());
+    sb.append(",fixedCellWidth=").append(getFixedCellWidth());
+    sb.append(",selectionBackground=");
+    if (getSelectionBackground() != null)
+      sb.append(getSelectionBackground());
+    sb.append(",selectionForeground=");
+    if (getSelectionForeground() != null)
+      sb.append(getSelectionForeground());
+    sb.append(",visibleRowCount=").append(getVisibleRowCount());
+    sb.append(",layoutOrientation=").append(getLayoutOrientation());
+    return sb.toString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenu.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenu.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenu.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenu.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1183 @@
+/* JMenu.java --
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.PopupMenu;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+import javax.swing.plaf.MenuItemUI;
+
+/**
+ * This class represents a menu that can be added to a menu bar or
+ * can be a submenu in some other menu. When JMenu is selected it
+ * displays JPopupMenu containing its menu items.
+ *
+ * <p>
+ * JMenu's fires MenuEvents when this menu's selection changes. If this menu
+ * is selected, then fireMenuSelectedEvent() is invoked. In case when menu is
+ * deselected or cancelled, then fireMenuDeselectedEvent() or 
+ * fireMenuCancelledEvent() is invoked, respectivelly.
+ * </p>
+ */
+public class JMenu extends JMenuItem implements Accessible, MenuElement
+{
+  private static final long serialVersionUID = 4227225638931828014L;
+
+  /** A Popup menu associated with this menu, which pops up when menu is selected */
+  private JPopupMenu popupMenu = null;
+
+  /** Whenever menu is selected or deselected the MenuEvent is fired to
+     menu's registered listeners. */
+  private MenuEvent menuEvent = new MenuEvent(this);
+
+  /*Amount of time, in milliseconds, that should pass before popupMenu
+    associated with this menu appears or disappers */
+  private int delay;
+
+  /* PopupListener */
+  protected WinListener popupListener;
+
+  /** Location at which popup menu associated with this menu will be
+     displayed */
+  private Point menuLocation;
+
+  /**
+   * Creates a new JMenu object.
+   */
+  public JMenu()
+  {
+    super();
+    setOpaque(false);
+    setDelay(200);
+  }
+
+  /**
+   * Creates a new <code>JMenu</code> with the specified label.
+   *
+   * @param text label for this menu
+   */
+  public JMenu(String text)
+  {
+    super(text);
+    popupMenu = new JPopupMenu(); 
+    popupMenu.setInvoker(this);
+    setOpaque(false);
+    setDelay(200);
+  }
+
+  /**
+   * Creates a new <code>JMenu</code> object.
+   *
+   * @param action Action that is used to create menu item tha will be
+   * added to the menu.
+   */
+  public JMenu(Action action)
+  {
+    super(action);
+    createActionChangeListener(this);
+    popupMenu = new JPopupMenu();
+    popupMenu.setInvoker(this);
+    setOpaque(false);
+    setDelay(200);
+  }
+
+  /**
+   * Creates a new <code>JMenu</code> with specified label and an option
+   * for this menu to be tear-off menu.
+   *
+   * @param text label for this menu
+   * @param tearoff true if this menu should be tear-off and false otherwise
+   */
+  public JMenu(String text, boolean tearoff)
+  {
+    // FIXME: tearoff not implemented
+    this(text);
+    setDelay(200);
+  }
+
+  /**
+   * Adds specified menu item to this menu
+   *
+   * @param item Menu item to add to this menu
+   *
+   * @return Menu item that was added
+   */
+  public JMenuItem add(JMenuItem item)
+  {
+    return getPopupMenu().add(item);
+  }
+
+  /**
+   * Adds specified component to this menu.
+   *
+   * @param component Component to add to this menu
+   *
+   * @return Component that was added
+   */
+  public Component add(Component component)
+  {
+    getPopupMenu().insert(component, -1);
+    return component;
+  }
+
+  /**
+   * Adds specified component to this menu at the given index
+   *
+   * @param component Component to add
+   * @param index Position of this menu item in the menu
+   *
+   * @return Component that was added
+   */
+  public Component add(Component component, int index)
+  {
+    return getPopupMenu().add(component, index);
+  }
+
+  /**
+   * Adds JMenuItem constructed with the specified label to this menu
+   *
+   * @param text label for the menu item that will be added
+   *
+   * @return Menu Item that was added to this menu
+   */
+  public JMenuItem add(String text)
+  {
+    return getPopupMenu().add(text);
+  }
+
+  /**
+   * Adds JMenuItem constructed using properties from specified action.
+   *
+   * @param action action to construct the menu item with
+   *
+   * @return Menu Item that was added to this menu
+   */
+  public JMenuItem add(Action action)
+  {
+    return getPopupMenu().add(action);
+  }
+
+  /**
+   * Removes given menu item from this menu. Nothing happens if
+   * this menu doesn't contain specified menu item.
+   *
+   * @param item Menu Item which needs to be removed
+   */
+  public void remove(JMenuItem item)
+  {
+    getPopupMenu().remove(item);
+  }
+
+  /**
+   * Removes component at the specified index from this menu
+   *
+   * @param index Position of the component that needs to be removed in the menu
+   */
+  public void remove(int index)
+  {
+    if (index < 0 || (index > 0 && getMenuComponentCount() == 0))
+      throw new IllegalArgumentException();
+  
+    if (getMenuComponentCount() > 0)
+      popupMenu.remove(index);
+  }
+
+  /**
+   * Removes given component from this menu.
+   *
+   * @param component Component to remove
+   */
+  public void remove(Component component)
+  {
+    int index = getPopupMenu().getComponentIndex(component);
+    if (index >= 0)
+      getPopupMenu().remove(index);
+  }
+
+  /**
+   * Removes all menu items from the menu
+   */
+  public void removeAll()
+  {
+    if (popupMenu != null)
+      popupMenu.removeAll();
+  }
+
+  /**
+   * Creates JMenuItem with the specified text and inserts it in the
+   * at the specified index
+   *
+   * @param text label for the new menu item
+   * @param index index at which to insert newly created menu item.
+   */
+  public void insert(String text, int index)
+  {
+    this.insert(new JMenuItem(text), index);
+  }
+
+  /**
+   * Creates JMenuItem with the specified text and inserts it in the
+   * at the specified index. IllegalArgumentException is thrown
+   * if index is less than 0
+   *
+   * @param item menu item to insert
+   * @param index index at which to insert menu item.
+   * @return Menu item that was added to the menu
+   */
+  public JMenuItem insert(JMenuItem item, int index)
+  {
+    if (index < 0)
+      throw new IllegalArgumentException("index less than zero");
+
+    getPopupMenu().insert(item, index);
+    return item;
+  }
+
+  /**
+   * Creates JMenuItem with the associated action and inserts it to the menu
+   * at the specified index. IllegalArgumentException is thrown
+   * if index is less than 0
+   *
+   * @param action Action for the new menu item
+   * @param index index at which to insert newly created menu item.
+   * @return Menu item that was added to the menu
+   */
+  public JMenuItem insert(Action action, int index)
+  {
+    JMenuItem item = new JMenuItem(action);
+    this.insert(item, index);
+
+    return item;
+  }
+
+  /**
+   * This method sets this menuItem's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((MenuItemUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menu.
+   *
+   * @return The Look and Feel classID. "MenuUI"
+   */
+  public String getUIClassID()
+  {
+    return "MenuUI";
+  }
+
+  /**
+   * Sets model for this menu.
+   *
+   * @param model model to set
+   */
+  public void setModel(ButtonModel model)
+  {
+    super.setModel(model);
+  }
+
+  /**
+   * Returns true if the menu is selected and false otherwise
+   *
+   * @return true if the menu is selected and false otherwise
+   */
+  public boolean isSelected()
+  {
+    return super.isSelected();
+  }
+
+  /**
+   * A helper method to handle setSelected calls from both mouse events and 
+   * direct calls to setSelected.  Direct calls shouldn't expand the popup
+   * menu and should select the JMenu even if it is disabled.  Mouse events
+   * only select the JMenu if it is enabled and should expand the popup menu
+   * associated with this JMenu.
+   * @param selected whether or not the JMenu was selected
+   * @param menuEnabled whether or not selecting the menu is "enabled".  This
+   * is always true for direct calls, and is set to isEnabled() for mouse 
+   * based calls.
+   * @param showMenu whether or not to show the popup menu
+   */
+  private void setSelectedHelper(boolean selected, boolean menuEnabled, boolean showMenu)
+  {
+    // If menu is selected and enabled, activates the menu and 
+    // displays associated popup.	
+    if (selected && menuEnabled)
+      {
+	super.setArmed(true);
+	super.setSelected(true);
+
+        // FIXME: The popup menu should be shown on the screen after certain
+        // number of seconds pass. The 'delay' property of this menu indicates
+        // this amount of seconds. 'delay' property is 0 by default.
+	if (isShowing())
+	  {
+	    fireMenuSelected();
+            
+	    int x = 0;
+	    int y = 0;
+            if (showMenu)
+              if (menuLocation == null)
+                {
+                  // Calculate correct position of the popup. Note that location of the popup 
+                  // passed to show() should be relative to the popup's invoker
+                  if (isTopLevelMenu())
+                    y = this.getHeight();
+                  else
+                    x = this.getWidth();
+                  getPopupMenu().show(this, x, y);
+                }
+              else
+                {
+                  getPopupMenu().show(this, menuLocation.x, menuLocation.y);
+                }
+	  }
+      }
+    
+    else
+      {
+	super.setSelected(false);
+	super.setArmed(false);
+	fireMenuDeselected();
+        getPopupMenu().setVisible(false);
+      }
+  }
+
+  /**
+   * Changes this menu selected state if selected is true and false otherwise
+   * This method fires menuEvents to menu's registered listeners.
+   *
+   * @param selected true if the menu should be selected and false otherwise
+   */
+  public void setSelected(boolean selected)
+  {
+    setSelectedHelper(selected, true, false); 
+  }
+
+  /**
+   * Checks if PopupMenu associated with this menu is visible
+   *
+   * @return true if the popup associated with this menu is currently visible
+   * on the screen and false otherwise.
+   */
+  public boolean isPopupMenuVisible()
+  {
+    return getPopupMenu().isVisible();
+  }
+
+  /**
+   * Sets popup menu visibility
+   *
+   * @param popup true if popup should be visible and false otherwise
+   */
+  public void setPopupMenuVisible(boolean popup)
+  {
+    if (getModel().isEnabled())
+      getPopupMenu().setVisible(popup);
+  }
+
+  /**
+   * Returns origin point of the popup menu
+   *
+   * @return Point containing
+   */
+  protected Point getPopupMenuOrigin()
+  {
+    // if menu in the menu bar
+    if (isTopLevelMenu())
+      return new Point(0, this.getHeight());
+
+    // if submenu            
+    return new Point(this.getWidth(), 0);
+  }
+
+  /**
+   * Returns delay property.
+   *
+   * @return delay property, indicating number of milliseconds before
+   * popup menu associated with the menu appears or disappears after
+   * menu was selected or deselected respectively
+   */
+  public int getDelay()
+  {
+    return delay;
+  }
+
+  /**
+   * Sets delay property for this menu. If given time for the delay
+   * property is negative, then IllegalArgumentException is thrown
+   *
+   * @param delay number of milliseconds before
+   * popup menu associated with the menu appears or disappears after
+   * menu was selected or deselected respectively
+   */
+  public void setDelay(int delay)
+  {
+    if (delay < 0)
+      throw new IllegalArgumentException("delay less than 0");
+    this.delay = delay;
+  }
+
+  /**
+   * Sets location at which popup menu should be displayed
+   * The location given is relative to this menu item
+   *
+   * @param x x-coordinate of the menu location
+   * @param y y-coordinate of the menu location
+   */
+  public void setMenuLocation(int x, int y)
+  {
+    menuLocation = new Point(x, y);
+  }
+
+  /**
+   * Creates and returns JMenuItem associated with the given action
+   *
+   * @param action Action to use for creation of JMenuItem
+   *
+   * @return JMenuItem that was creted with given action
+   */
+  protected JMenuItem createActionComponent(Action action)
+  {
+    return new JMenuItem(action);
+  }
+
+  /**
+   * Creates ActionChangeListener to listen for PropertyChangeEvents occuring
+   * in the action that is associated with this menu
+   *
+   * @param item menu that contains action to listen to
+   *
+   * @return The PropertyChangeListener
+   */
+  protected PropertyChangeListener createActionChangeListener(JMenuItem item)
+  {
+    return new ActionChangedListener(item);
+  }
+
+  /**
+   * Adds separator to the end of the menu items in the menu.
+   */
+  public void addSeparator()
+  {
+    getPopupMenu().addSeparator();
+  }
+
+  /**
+   * Inserts separator in the menu at the specified index.
+   *
+   * @param index Index at which separator should be inserted
+   */
+  public void insertSeparator(int index)
+  {
+    if (index < 0)
+      throw new IllegalArgumentException("index less than 0");
+
+    getPopupMenu().insert(new JPopupMenu.Separator(), index);
+  }
+
+  /**
+   * Returns menu item located at the specified index in the menu
+   *
+   * @param index Index at which to look for the menu item
+   *
+   * @return menu item located at the specified index in the menu
+   */
+  public JMenuItem getItem(int index)
+  {
+    if (index < 0)
+      throw new IllegalArgumentException("index less than 0");
+
+    if (getItemCount() == 0)
+      return null;
+    
+    Component c = popupMenu.getComponentAtIndex(index);
+
+    if (c instanceof JMenuItem)
+      return (JMenuItem) c;
+    else
+      return null;
+  }
+
+  /**
+   * Returns number of items in the menu including separators.
+   *
+   * @return number of items in the menu
+   *
+   * @see #getMenuComponentCount()
+   */
+  public int getItemCount()
+  {
+    return getMenuComponentCount();
+  }
+
+  /**
+   * Checks if this menu is a tear-off menu.
+   *
+   * @return true if this menu is a tear-off menu and false otherwise
+   */
+  public boolean isTearOff()
+  {
+    // NOT YET IMPLEMENTED 
+    throw new Error("The method isTearOff() has not yet been implemented.");
+  }
+
+  /**
+   * Returns number of menu components in this menu
+   *
+   * @return number of menu components in this menu
+   */
+  public int getMenuComponentCount()
+  {
+    return getPopupMenu().getComponentCount();
+  }
+
+  /**
+   * Returns menu component located at the givent index
+   * in the menu
+   *
+   * @param index index at which to get the menu component in the menu
+   *
+   * @return Menu Component located in the menu at the specified index
+   */
+  public Component getMenuComponent(int index)
+  {
+    if (getPopupMenu() == null || getMenuComponentCount() == 0)
+      return null;
+    
+    return (Component) popupMenu.getComponentAtIndex(index);
+  }
+
+  /**
+   * Return components belonging to this menu
+   *
+   * @return components belonging to this menu
+   */
+  public Component[] getMenuComponents()
+  {
+    return getPopupMenu().getComponents();
+  }
+
+  /**
+   * Checks if this menu is a top level menu. The menu is top
+   * level menu if it is inside the menu bar. While if the menu
+   * inside some other menu, it is considered to be a pull-right menu.
+   *
+   * @return true if this menu is top level menu, and false otherwise
+   */
+  public boolean isTopLevelMenu()
+  {
+    return getParent() instanceof JMenuBar;
+  }
+
+  /**
+   * Checks if given component exists in this menu. The submenus of
+   * this menu are checked as well
+   *
+   * @param component Component to look for
+   *
+   * @return true if the given component exists in this menu, and false otherwise
+   */
+  public boolean isMenuComponent(Component component)
+  {
+    return false;
+  }
+
+  /**
+   * Returns popup menu associated with the menu.
+   *
+   * @return popup menu associated with the menu.
+   */
+  public JPopupMenu getPopupMenu()
+  {
+    if (popupMenu == null)
+      {
+        popupMenu = new JPopupMenu();
+        popupMenu.setInvoker(this);
+      }
+    return popupMenu;
+  }
+
+  /**
+   * Adds MenuListener to the menu
+   *
+   * @param listener MenuListener to add
+   */
+  public void addMenuListener(MenuListener listener)
+  {
+    listenerList.add(MenuListener.class, listener);
+  }
+
+  /**
+   * Removes MenuListener from the menu
+   *
+   * @param listener MenuListener to remove
+   */
+  public void removeMenuListener(MenuListener listener)
+  {
+    listenerList.remove(MenuListener.class, listener);
+  }
+
+  /**
+   * Returns all registered <code>MenuListener</code> objects.
+   *
+   * @return an array of listeners
+   * 
+   * @since 1.4
+   */
+  public MenuListener[] getMenuListeners()
+  {
+    return (MenuListener[]) listenerList.getListeners(MenuListener.class);
+  }
+
+  /**
+   * This method fires MenuEvents to all menu's MenuListeners. In this case
+   * menuSelected() method of MenuListeners is called to indicated that the menu
+   * was selected.
+   */
+  protected void fireMenuSelected()
+  {
+    MenuListener[] listeners = getMenuListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].menuSelected(menuEvent);
+  }
+
+  /**
+   * This method fires MenuEvents to all menu's MenuListeners. In this case
+   * menuDeselected() method of MenuListeners is called to indicated that the menu
+   * was deselected.
+   */
+  protected void fireMenuDeselected()
+  {
+    EventListener[] ll = listenerList.getListeners(MenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuListener) ll[i]).menuDeselected(menuEvent);
+  }
+
+  /**
+   * This method fires MenuEvents to all menu's MenuListeners. In this case
+   * menuSelected() method of MenuListeners is called to indicated that the menu
+   * was cancelled. The menu is cancelled when it's popup menu is close without selection.
+   */
+  protected void fireMenuCanceled()
+  {
+    EventListener[] ll = listenerList.getListeners(MenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuListener) ll[i]).menuCanceled(menuEvent);
+  }
+
+  /**
+   * Creates WinListener that listens to the menu;s popup menu.
+   *
+   * @param popup JPopupMenu to listen to
+   *
+   * @return The WinListener
+   */
+  protected WinListener createWinListener(JPopupMenu popup)
+  {
+    return new WinListener(popup);
+  }
+
+  /**
+   * Method of the MenuElementInterface. It reacts to the selection
+   * changes in the menu. If this menu was selected, then it
+   * displayes popup menu associated with it and if this menu was
+   * deselected it hides the popup menu.
+   *
+   * @param changed true if the menu was selected and false otherwise
+   */
+  public void menuSelectionChanged(boolean changed)
+  {
+    // if this menu selection is true, then activate this menu and 
+    // display popup associated with this menu
+    setSelectedHelper(changed, isEnabled(), true);
+  }
+
+  /**
+   * Method of MenuElement interface. Returns sub components of
+   * this menu.
+   *
+   * @return array containing popupMenu that is associated with this menu
+   */
+  public MenuElement[] getSubElements()
+  {
+    return new MenuElement[] { popupMenu };
+  }
+
+  /**
+   * @return Returns reference to itself
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * This method is overriden with empty implementation, s.t the
+   * accelerator couldn't be set for the menu. The mnemonic should
+   * be used for the menu instead.
+   *
+   * @param keystroke accelerator for this menu
+   */
+  public void setAccelerator(KeyStroke keystroke)
+  {
+    throw new Error("setAccelerator() is not defined for JMenu.  Use setMnemonic() instead.");
+  }
+
+  /**
+   * This method process KeyEvent occuring when the menu is visible
+   *
+   * @param event The KeyEvent
+   */
+  protected void processKeyEvent(KeyEvent event)
+  {
+    MenuSelectionManager.defaultManager().processKeyEvent(event);
+  }
+
+  /**
+   * Programatically performs click
+   *
+   * @param time Number of milliseconds for which this menu stays pressed
+   */
+  public void doClick(int time)
+  {
+    getModel().setArmed(true);
+    getModel().setPressed(true);
+    try
+      {
+	java.lang.Thread.sleep(time);
+      }
+    catch (java.lang.InterruptedException e)
+      {
+	// probably harmless
+      }
+
+    getModel().setPressed(false);
+    getModel().setArmed(false);
+    popupMenu.show(this, this.getWidth(), 0);
+  }
+
+  /**
+   * A string that describes this JMenu. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JMenu
+   */
+  protected String paramString()
+  {
+    return super.paramString();
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJMenu();
+
+    return accessibleContext;
+  }
+
+  /**
+   * Implements support for assisitive technologies for <code>JMenu</code>.
+   */
+  protected class AccessibleJMenu extends AccessibleJMenuItem
+    implements AccessibleSelection
+  {
+    private static final long serialVersionUID = -8131864021059524309L;
+
+    protected AccessibleJMenu()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns the number of accessible children of this object.
+     *
+     * @return the number of accessible children of this object
+     */
+    public int getAccessibleChildrenCount()
+    {
+      Component[] children = getMenuComponents();
+      int count = 0;
+      for (int i = 0; i < children.length; i++)
+        {
+          if (children[i] instanceof Accessible)
+            count++;
+        }
+      return count;
+    }
+
+    /**
+     * Returns the accessible child with the specified <code>index</code>.
+     *
+     * @param index the index of the child to fetch
+     *
+     * @return the accessible child with the specified <code>index</code>
+     */
+    public Accessible getAccessibleChild(int index)
+    {
+      Component[] children = getMenuComponents();
+      int count = 0;
+      Accessible found = null;
+      for (int i = 0; i < children.length; i++)
+        {
+          if (children[i] instanceof Accessible)
+            {
+              if (count == index)
+                {
+                  found = (Accessible) children[i];
+                  break;
+                }
+              count++;
+            }
+        }
+      return found;
+    }
+
+    /**
+     * Returns the accessible selection of this object. AccessibleJMenus handle
+     * their selection themselves, so we always return <code>this</code> here.
+     *
+     * @return the accessible selection of this object
+     */
+    public AccessibleSelection getAccessibleSelection()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the selected accessible child with the specified
+     * <code>index</code>.
+     *
+     * @param index the index of the accessible selected child to return
+     *
+     * @return the selected accessible child with the specified
+     *         <code>index</code>
+     */
+    public Accessible getAccessibleSelection(int index)
+    {
+      Accessible selected = null;
+      // Only one item can be selected, which must therefore have index == 0.
+      if (index == 0)
+        {
+          MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+          MenuElement[] me = msm.getSelectedPath();
+          if (me != null)
+            {
+              for (int i = 0; i < me.length; i++)
+                {
+                  if (me[i] == JMenu.this)
+                    {
+                      // This JMenu is selected, find and return the next
+                      // JMenuItem in the path.
+                      do
+                        {
+                          if (me[i] instanceof Accessible)
+                            {
+                              selected = (Accessible) me[i];
+                              break;
+                            }
+                          i++;
+                        } while (i < me.length);
+                    }
+                  if (selected != null)
+                    break;
+                }
+            }
+        }
+      return selected;
+    }
+
+    /**
+     * Returns <code>true</code> if the accessible child with the specified
+     * index is selected, <code>false</code> otherwise.
+     *
+     * @param index the index of the accessible child to check
+     *
+     * @return <code>true</code> if the accessible child with the specified
+     *         index is selected, <code>false</code> otherwise
+     */
+    public boolean isAccessibleChildSelected(int index)
+    {
+      boolean selected = false;
+      MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+      MenuElement[] me = msm.getSelectedPath();
+      if (me != null)
+        {
+          Accessible toBeFound = getAccessibleChild(index);
+          for (int i = 0; i < me.length; i++)
+            {
+              if (me[i] == toBeFound)
+                {
+                  selected = true;
+                  break;
+                }
+            }
+        }
+      return selected;
+    }
+
+    /**
+     * Returns the accessible role of this object, which is
+     * {@link AccessibleRole#MENU} for the AccessibleJMenu.
+     *
+     * @return the accessible role of this object
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.MENU;
+    }
+
+    /**
+     * Returns the number of selected accessible children. This will be
+     * <code>0</code> if no item is selected, or <code>1</code> if an item
+     * is selected. AccessibleJMenu can have maximum 1 selected item.
+     *
+     * @return the number of selected accessible children
+     */
+    public int getAccessibleSelectionCount()
+    {
+      int count = 0;
+      MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+      MenuElement[] me = msm.getSelectedPath();
+      if (me != null)
+        {
+          for (int i = 0; i < me.length; i++)
+            {
+              if (me[i] == JMenu.this)
+                {
+                  if (i + 1 < me.length)
+                    {
+                      count = 1;
+                      break;
+                    }
+                }
+            }
+        }
+      return count;
+    }
+
+    /**
+     * Selects the accessible child with the specified index.
+     *
+     * @param index the index of the accessible child to select
+     */
+    public void addAccessibleSelection(int index)
+    {
+      Accessible child = getAccessibleChild(index);
+      if (child != null && child instanceof JMenuItem)
+        {
+          JMenuItem mi = (JMenuItem) child;
+          MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+          msm.setSelectedPath(createPath(JMenu.this));
+        }
+    }
+
+    /**
+     * Removes the item with the specified index from the selection.
+     *
+     * @param index the index of the selected item to remove from the selection
+     */
+    public void removeAccessibleSelection(int index)
+    {
+      Accessible child = getAccessibleChild(index);
+      if (child != null)
+        {
+          MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+          MenuElement[] oldSelection = msm.getSelectedPath();
+          for (int i = 0; i < oldSelection.length; i++)
+            {
+              if (oldSelection[i] == child)
+                {
+                  // Found the specified child in the selection. Remove it
+                  // from the selection.
+                  MenuElement[] newSel = new MenuElement[i - 1];
+                  System.arraycopy(oldSelection, 0, newSel, 0, i - 1);
+                  msm.setSelectedPath(newSel);
+                  break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes all possibly selected accessible children of this object from
+     * the selection.
+     */
+    public void clearAccessibleSelection()
+    {
+      MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+      MenuElement[] oldSelection = msm.getSelectedPath();
+      for (int i = 0; i < oldSelection.length; i++)
+        {
+          if (oldSelection[i] == JMenu.this)
+            {
+              // Found this menu in the selection. Remove all children from
+              // the selection.
+              MenuElement[] newSel = new MenuElement[i];
+              System.arraycopy(oldSelection, 0, newSel, 0, i);
+              msm.setSelectedPath(newSel);
+              break;
+            }
+        }
+    }
+
+    /**
+     * AccessibleJMenu don't support multiple selection, so this method
+     * does nothing.
+     */
+    public void selectAllAccessibleSelection()
+    {
+      // Nothing to do here.
+    }
+  }
+
+  protected class WinListener extends WindowAdapter implements Serializable
+  {
+    private static final long serialVersionUID = -6415815570638474823L;
+
+    /**
+     * Creates a new <code>WinListener</code>.
+     *
+     * @param popup the popup menu which is observed
+     */
+    public WinListener(JPopupMenu popup)
+    {
+      // TODO: What should we do with the popup argument?
+    }
+
+    /**
+     * Receives notification when the popup menu is closing and deselects
+     * the menu.
+     *
+     * @param event the window event
+     */
+    public void windowClosing(WindowEvent event)
+    {
+      setSelected(false);
+    }
+  }
+
+  /**
+   * This class listens to PropertyChangeEvents occuring in menu's action
+   */
+  private class ActionChangedListener implements PropertyChangeListener
+  {
+    /** menu item associated with the action */
+    private JMenuItem menuItem;
+
+    /** Creates new ActionChangedListener and adds it to menuItem's action */
+    public ActionChangedListener(JMenuItem menuItem)
+    {
+      this.menuItem = menuItem;
+
+      Action a = menuItem.getAction();
+      if (a != null)
+	a.addPropertyChangeListener(this);
+    }
+
+    /**This method is invoked when some change occures in menuItem's action*/
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      // FIXME: Need to implement
+    }
+  }
+
+  /**
+   * Creates an array to be feeded as argument to
+   * {@link MenuSelectionManager#setSelectedPath(MenuElement[])} for the
+   * specified element. This has the effect of selecting the specified element
+   * and all its parents.
+   *
+   * @param leaf the leaf element for which to create the selected path
+   *
+   * @return the selected path array
+   */
+  MenuElement[] createPath(JMenu leaf)
+  {
+    ArrayList path = new ArrayList();
+    MenuElement[] array = null;
+    Component current = leaf.getPopupMenu();
+    while (true)
+      {
+        if (current instanceof JPopupMenu)
+          {
+            JPopupMenu popupMenu = (JPopupMenu) current;
+            path.add(0, popupMenu);
+            current = popupMenu.getInvoker();
+          }
+        else if (current instanceof JMenu)
+          {
+            JMenu menu = (JMenu) current;
+            path.add(0, menu);
+            current = menu.getParent();
+          }
+        else if (current instanceof JMenuBar)
+          {
+            JMenuBar menuBar = (JMenuBar) current;
+            path.add(0, menuBar);
+            array = new MenuElement[path.size()];
+            array = (MenuElement[]) path.toArray(array);
+            break;
+          }
+      }
+    return array;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuBar.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuBar.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuBar.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuBar.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,685 @@
+/* JMenuBar.java --
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.plaf.MenuBarUI;
+
+import javax.swing.border.Border;
+
+/**
+ * JMenuBar is a container for menu's. For a menu bar to be seen on the
+ * screen, at least one menu should be added to it. Just like adding
+ * components to container, one can use add() to add menu's to the menu bar.
+ * Menu's will be displayed in the menu  bar in the order they were added.
+ * The JMenuBar uses selectionModel to keep track of selected menu index.
+ * JMenuBar's selectionModel will fire ChangeEvents to its registered 
+ * listeners when the selected index changes.
+ */
+public class JMenuBar extends JComponent implements Accessible, MenuElement
+{
+  /**
+   * Provides accessibility support for <code>JMenuBar</code>.
+   * 
+   * @author Roman Kennke (kennke at aicas.com)
+   */
+  protected class AccessibleJMenuBar extends AccessibleJComponent
+    implements AccessibleSelection
+  {
+
+    /**
+     * Returns the number of selected items in the menu bar. Possible values
+     * are <code>0</code> if nothing is selected, or <code>1</code> if one
+     * item is selected.
+     *
+     * @return the number of selected items in the menu bar
+     */
+    public int getAccessibleSelectionCount()
+    {
+      int count = 0;
+      if (getSelectionModel().getSelectedIndex() != -1)
+        count = 1;
+      return count;
+    }
+
+    /**
+     * Returns the selected with index <code>i</code> menu, or
+     * <code>null</code> if the specified menu is not selected.
+     *
+     * @param i the index of the menu to return
+     *
+     * @return the selected with index <code>i</code> menu, or
+     *         <code>null</code> if the specified menu is not selected
+     */
+    public Accessible getAccessibleSelection(int i)
+    {
+      if (getSelectionModel().getSelectedIndex() != i)
+        return null;
+      return getMenu(i);
+    }
+
+    /**
+     * Returns <code>true</code> if the specified menu is selected,
+     * <code>false</code> otherwise.
+     *
+     * @param i the index of the menu to check
+     *
+     *@return <code>true</code> if the specified menu is selected,
+     *        <code>false</code> otherwise
+     */
+    public boolean isAccessibleChildSelected(int i)
+    {
+      return getSelectionModel().getSelectedIndex() == i;
+    }
+
+    /**
+     * Selects the menu with index <code>i</code>. If another menu is already
+     * selected, this will be deselected.
+     *
+     * @param i the menu to be selected
+     */
+    public void addAccessibleSelection(int i)
+    {
+      getSelectionModel().setSelectedIndex(i);
+    }
+
+    /**
+     * Deselects the menu with index <code>i</code>.
+     *
+     * @param i the menu index to be deselected
+     */
+    public void removeAccessibleSelection(int i)
+    {
+      if (getSelectionModel().getSelectedIndex() == i)
+        getSelectionModel().clearSelection();
+    }
+
+    /**
+     * Deselects all possibly selected menus.
+     */
+    public void clearAccessibleSelection()
+    {
+      getSelectionModel().clearSelection();
+    }
+
+    /**
+     * In menu bars it is not possible to select all items, so this method
+     * does nothing.
+     */
+    public void selectAllAccessibleSelection()
+    {
+      // In menu bars it is not possible to select all items, so this method
+      // does nothing.
+    }
+
+    /**
+     * Returns the accessible role of <code>JMenuBar</code>, which is
+     * {@link AccessibleRole#MENU_BAR}.
+     *
+     * @return the accessible role of <code>JMenuBar</code>, which is
+     *         {@link AccessibleRole#MENU_BAR}
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.MENU_BAR;
+    }
+
+    /**
+     * Returns the <code>AccessibleSelection</code> for this object. This
+     * method returns <code>this</code>, since the
+     * <code>AccessibleJMenuBar</code> manages its selection itself.
+     *
+     * @return the <code>AccessibleSelection</code> for this object
+     */
+    public AccessibleSelection getAccessibleSelection()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the state of this <code>AccessibleJMenuBar</code>.
+     *
+     * @return the state of this <code>AccessibleJMenuBar</code>.
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleStateSet stateSet = super.getAccessibleStateSet();
+      // TODO: Figure out what state must be added to the super state set.
+      return stateSet;
+    }
+  }
+
+  private static final long serialVersionUID = -8191026883931977036L;
+
+  /** JMenuBar's model. It keeps track of selected menu's index */
+  private transient SingleSelectionModel selectionModel;
+
+  /* borderPainted property indicating if the menuBar's border will be painted*/
+  private boolean borderPainted;
+
+  /* margin between menu bar's border and its menues*/
+  private Insets margin;
+
+  /**
+   * Creates a new JMenuBar object.
+   */
+  public JMenuBar()
+  {
+    selectionModel = new DefaultSingleSelectionModel();
+    borderPainted = true;
+    updateUI();
+  }
+
+  /**
+   * Adds menu to the menu bar
+   *
+   * @param c menu to add
+   *
+   * @return reference to the added menu
+   */
+  public JMenu add(JMenu c)
+  {
+    c.setAlignmentX(Component.LEFT_ALIGNMENT);
+    super.add(c);
+    return c;
+  }
+
+  /**
+   * This method overrides addNotify() in the Container to register
+   * this menu bar with the current keyboard manager.
+   */
+  public void addNotify()
+  {
+    super.addNotify();
+    KeyboardManager.getManager().registerJMenuBar(this);
+  }
+
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJMenuBar();
+    return accessibleContext;
+  }
+
+  /**
+   * Returns reference to this menu bar
+   *
+   * @return reference to this menu bar
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * Returns component at the specified index.
+   *
+   * @param i index of the component to get
+   *
+   * @return component at the specified index. Null is returned if
+   * component at the specified index doesn't exist.
+   * @deprecated Replaced by getComponent(int)
+   */
+  public Component getComponentAtIndex(int i)
+  {
+    return getComponent(i);
+  }
+
+  /**
+   * Returns index of the specified component
+   *
+   * @param c Component to search for
+   *
+   * @return index of the specified component. -1 is returned if
+   * specified component doesnt' exist in the menu bar.
+   */
+  public int getComponentIndex(Component c)
+  {
+    Component[] comps = getComponents();
+
+    int index = -1;
+
+    for (int i = 0; i < comps.length; i++)
+      {
+	if (comps[i].equals(c))
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+
+    return index;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public JMenu getHelpMenu()
+  {
+    return null;
+  }
+
+  /**
+   * Returns margin betweeen menu bar's border and its menues
+   *
+   * @return margin between menu bar's border and its menues
+   */
+  public Insets getMargin()
+  {
+    if (margin == null)
+      return new Insets(0, 0, 0, 0);
+    else
+      return margin;
+  }
+
+  /**
+   * Return menu at the specified index. If component at the
+   * specified index is not a menu, then null is returned.
+   *
+   * @param index index to look for the menu
+   *
+   * @return menu at specified index, or null if menu doesn't exist
+   * at the specified index.
+   */
+  public JMenu getMenu(int index)
+  {
+    if (getComponentAtIndex(index) instanceof JMenu)
+      return (JMenu) getComponentAtIndex(index);
+    else
+      return null;
+  }
+
+  /**
+   * Returns number of menu's in this menu bar
+   *
+   * @return number of menu's in this menu bar
+   */
+  public int getMenuCount()
+  {
+    return getComponentCount();
+  }
+
+  /**
+   * Returns selection model for this menu bar. SelectionModel
+   * keeps track of the selected menu in the menu bar. Whenever
+   * selected property of selectionModel changes, the ChangeEvent
+   * will be fired its ChangeListeners.
+   *
+   * @return selection model for this menu bar.
+   */
+  public SingleSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  }
+
+  /**
+   * Method of MenuElement interface. It returns subcomponents
+   * of the menu bar, which are all the menues that it contains.
+   *
+   * @return MenuElement[] array containing menues in this menu bar
+   */
+  public MenuElement[] getSubElements()
+  {
+    MenuElement[] subElements = new MenuElement[getComponentCount()];
+
+    int j = 0;
+    boolean doResize = false;
+    MenuElement menu;
+    for (int i = 0; i < getComponentCount(); i++)
+      {
+        menu = getMenu(i);
+        if (menu != null)
+          {
+            subElements[j++] = (MenuElement) menu;
+          }
+        else
+          doResize = true;
+      }
+
+    if (! doResize)
+      return subElements;
+    else
+      {
+        MenuElement[] subElements2 = new MenuElement[j];
+        for (int i = 0; i < j; i++)
+          subElements2[i] = subElements[i];
+
+        return subElements2;
+      }
+  }
+
+  /**
+    * Set the "UI" property of the menu bar, which is a look and feel class
+    * responsible for handling the menuBar's input events and painting it.
+    *
+    * @return The current "UI" property
+    */
+  public MenuBarUI getUI()
+  {
+    return (MenuBarUI) ui;
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menu bar.
+   *
+   * @return The Look and Feel classID. "MenuBarUI"
+   */
+  public String getUIClassID()
+  {
+    return "MenuBarUI";
+  }
+
+  /**
+   * Returns true if menu bar paints its border and false otherwise
+   *
+   * @return true if menu bar paints its border and false otherwise
+   */
+  public boolean isBorderPainted()
+  {
+    return borderPainted;
+  }
+
+  /**
+   * Returns true if some menu in menu bar is selected.
+   *
+   * @return true if some menu in menu bar is selected and false otherwise
+   */
+  public boolean isSelected()
+  {
+    return selectionModel.isSelected();
+  }
+
+  /**
+   * This method does nothing by default. This method is need for the
+   * MenuElement interface to be implemented.
+   *
+   * @param isIncluded true if menuBar is included in the selection
+   * and false otherwise
+   */
+  public void menuSelectionChanged(boolean isIncluded)
+  {
+    // Do nothing - needed for implementation of MenuElement interface
+  }
+
+  /**
+   * Paints border of the menu bar, if its borderPainted property is set to
+   * true.
+   *
+   * @param g The graphics context with which to paint the border
+   */
+  protected void paintBorder(Graphics g)
+  {
+    if (borderPainted)
+      {
+        Border border = getBorder();
+        if (border != null)
+          getBorder().paintBorder(this, g, 0, 0, getSize(null).width,
+                                  getSize(null).height);
+      }
+  }
+
+  /**
+   * A string that describes this JMenuBar. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JMenuBar
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer();
+    sb.append(super.paramString());
+    sb.append(",margin=");
+    if (getMargin() != null)
+      sb.append(getMargin());
+    sb.append(",paintBorder=").append(isBorderPainted());
+    return sb.toString();
+  }
+
+  /**
+   * Process key events forwarded from MenuSelectionManager. This method
+   * doesn't do anything. It is here to conform to the MenuElement interface.
+   *
+   * @param e event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   *
+   */
+  public void processKeyEvent(KeyEvent e, MenuElement[] path,
+                              MenuSelectionManager manager)
+  {
+    // Do nothing - needed for implementation of MenuElement interface
+  }
+
+  /**
+   * This method overrides JComponent.processKeyBinding to allow the 
+   * JMenuBar to check all the child components (recursiveley) to see 
+   * if they'll consume the event.
+   * 
+   * @param ks the KeyStroke for the event
+   * @param e the KeyEvent for the event
+   * @param condition the focus condition for the binding
+   * @param pressed true if the key is pressed 
+   */
+  protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition,
+                                      boolean pressed)
+  {
+    // See if the regular JComponent behavior consumes the event
+    if (super.processKeyBinding(ks, e, condition, pressed))
+      return true;
+    
+    // If not, have to recursively check all the child menu elements to see 
+    // if they want it    
+    MenuElement[] children = getSubElements();
+    for (int i = 0; i < children.length; i++)
+      if (processKeyBindingHelper(children[i], ks, e, condition, pressed))
+        return true;
+    return false;
+  }
+  
+  /**
+   * This is a helper method to recursively check the children of this
+   * JMenuBar to see if they will consume a key event via key bindings.  
+   * This is used for menu accelerators.
+   * @param menuElement the menuElement to check (and check all its children)
+   * @param ks the KeyStroke for the event
+   * @param e the KeyEvent that may be consumed
+   * @param condition the focus condition for the binding
+   * @param pressed true if the key was pressed
+   * @return true <code>menuElement</code> or one of its children consume
+   * the event (processKeyBinding returns true for menuElement or one of
+   * its children).
+   */
+  static boolean processKeyBindingHelper(MenuElement menuElement, KeyStroke ks,
+                                         KeyEvent e, int condition,
+                                         boolean pressed)
+  {
+    if (menuElement == null)
+      return false;
+
+    // First check the menuElement itself, if it's a JComponent
+    if (menuElement instanceof JComponent
+        && ((JComponent) menuElement).processKeyBinding(ks, e, condition,
+                                                        pressed))
+      return true;
+    
+    // If that didn't consume it, check all the children recursively
+    MenuElement[] children = menuElement.getSubElements();
+    for (int i = 0; i < children.length; i++)
+      if (processKeyBindingHelper(children[i], ks, e, condition, pressed))
+        return true;
+    return false;
+  }
+  
+  /**
+   * Process mouse events forwarded from MenuSelectionManager. This method
+   * doesn't do anything. It is here to conform to the MenuElement interface.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   *
+   */
+  public void processMouseEvent(MouseEvent event, MenuElement[] path,
+                                MenuSelectionManager manager)
+  {
+    // Do nothing - needed for implementation of MenuElement interface
+  }
+
+  /**
+   * This method overrides removeNotify() in the Container to
+   * unregister this menu bar from the current keyboard manager.
+   */
+  public void removeNotify()
+  {
+    KeyboardManager.getManager().unregisterJMenuBar(this);
+    super.removeNotify();
+  }
+
+  /**
+   * Sets painting status of the border. If 'b' is true then menu bar's
+   * border will be painted, and it will not be painted otherwise.
+   *
+   * @param b indicates if menu bar's border should be painted.
+   */
+  public void setBorderPainted(boolean b)
+  {
+    if (b != borderPainted)
+      {
+	boolean old = borderPainted;
+	borderPainted = b;
+	firePropertyChange("borderPainted", old, b);
+	revalidate();
+	repaint();
+      }
+  }
+
+  /**
+   * Sets help menu for this menu bar
+   *
+   * @param menu help menu
+   *
+   * @specnote The specification states that this method is not yet implemented
+   *           and should throw an exception.
+   */
+  public void setHelpMenu(JMenu menu)
+  {
+    // We throw an Error here, just as Sun's JDK does.
+    throw new Error("setHelpMenu() not yet implemented.");
+  }
+
+  /**
+   * Sets the menu bar's "margin" bound property,  which represents
+   * distance between the menubar's border and its menus.
+   * icon. When marging property is modified, PropertyChangeEvent will
+   * be fired to menuBar's PropertyChangeListener's.
+   *
+   * @param m distance between the menubar's border and its menus.
+   *
+   */
+  public void setMargin(Insets m)
+  {
+    if (m != margin)
+      {
+	Insets oldMargin = margin;
+	margin = m;
+	firePropertyChange("margin", oldMargin, margin);
+      }
+  }
+
+  /**
+   * Changes menu bar's selection to the specified menu.
+   * This method updates selected index of menu bar's selection model,
+   * which results in a model firing change event.
+   *
+   * @param sel menu to select
+   */
+  public void setSelected(Component sel)
+  {
+    int index = getComponentIndex(sel);
+    selectionModel.setSelectedIndex(index);
+  }
+
+  /**
+   * Sets menuBar's selection model to the one specified
+   *
+   * @param model SingleSelectionModel that needs to be set for this menu bar
+   */
+  public void setSelectionModel(SingleSelectionModel model)
+  {
+    if (selectionModel != model)
+      {
+	SingleSelectionModel oldModel = selectionModel;
+	selectionModel = model;
+	firePropertyChange("model", oldModel, selectionModel);
+      }
+  }
+
+  /**
+   * Set the "UI" property of the menu bar, which is a look and feel class
+   * responsible for handling menuBar's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(MenuBarUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Set the "UI" property to a class constructed, via the {@link
+   * UIManager}, from the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((MenuBarUI) UIManager.getUI(this));
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuItem.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuItem.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuItem.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JMenuItem.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,836 @@
+/* JMenuItem.java --
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.MenuDragMouseEvent;
+import javax.swing.event.MenuDragMouseListener;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.plaf.MenuItemUI;
+
+/**
+ * JMenuItem represents element in the menu. It inherits most of
+ * its functionality from AbstractButton, however its behavior somewhat
+ * varies from it. JMenuItem fire different kinds of events.
+ * PropertyChangeEvents are fired when menuItems properties are modified;
+ * ChangeEvents are fired when menuItem's state changes and actionEvents are
+ * fired when menu item is selected. In addition to this events menuItem also
+ * fire MenuDragMouseEvent and MenuKeyEvents when mouse is dragged over
+ * the menu item or associated key with menu item is invoked respectively.
+ */
+public class JMenuItem extends AbstractButton implements Accessible,
+                                                         MenuElement
+{
+  private static final long serialVersionUID = -1681004643499461044L;
+
+  /** Combination of keyboard keys that can be used to activate this menu item */
+  private KeyStroke accelerator;
+
+  /**
+   * Creates a new JMenuItem object.
+   */
+  public JMenuItem()
+  {
+    super();
+    init(null, null);
+  }
+
+  /**
+   * Creates a new JMenuItem with the given icon.
+   *
+   * @param icon Icon that will be displayed on the menu item
+   */
+  public JMenuItem(Icon icon)
+  {
+    // FIXME: The requestedFocusEnabled property should
+    // be set to false, when only icon is set for menu item.
+    super();
+    init(null, icon);
+  }
+
+  /**
+   * Creates a new JMenuItem with the given label.
+   *
+   * @param text label for the menu item
+   */
+  public JMenuItem(String text)
+  {
+    this(text, null);
+  }
+
+  /**
+   * Creates a new JMenuItem associated with the specified action.
+   *
+   * @param action action for this menu item
+   */
+  public JMenuItem(Action action)
+  {
+    super();
+    super.setAction(action);
+    init(null, null);
+    if (action != null)
+      {
+	String name = (String) action.getValue(Action.NAME);
+	if (name != null)
+          setName(name);
+
+	KeyStroke accel = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY);
+	if (accel != null)
+          setAccelerator(accel);
+
+	Integer mnemonic = (Integer) action.getValue(Action.MNEMONIC_KEY);
+	if (mnemonic != null)
+          setMnemonic(mnemonic.intValue());
+
+	String command = (String) action.getValue(Action.ACTION_COMMAND_KEY);
+	if (command != null)
+          setActionCommand(command);
+      }
+  }
+
+  /**
+   * Creates a new JMenuItem with specified text and icon.
+   * Text is displayed to the left of icon by default.
+   *
+   * @param text label for this menu item
+   * @param icon icon that will be displayed on this menu item
+   */
+  public JMenuItem(String text, Icon icon)
+  {
+    super();
+    init(text, icon);
+  }
+
+  /**
+   * Creates a new JMenuItem object.
+   *
+   * @param text label for this menu item
+   * @param mnemonic - Single key that can be used with a
+   * look-and-feel meta key to activate this menu item. However
+   * menu item should be visible on the screen when mnemonic is used.
+   */
+  public JMenuItem(String text, int mnemonic)
+  {
+    this(text, null);
+    setMnemonic(mnemonic);
+  }
+
+  /**
+   * Initializes this menu item
+   *
+   * @param text label for this menu item
+   * @param icon icon to be displayed for this menu item
+   */
+  protected void init(String text, Icon icon)
+  {
+    super.init(text, icon);
+    setModel(new DefaultButtonModel());
+
+    // Initializes properties for this menu item, that are different
+    // from Abstract button properties. 
+    /* NOTE: According to java specifications paint_border should be set to false,
+      since menu item should not have a border. However running few java programs
+      it seems that menu items and menues can have a border. Commenting
+      out statement below for now. */
+    //borderPainted = false;
+    focusPainted = false;
+    horizontalAlignment = JButton.LEADING;
+    horizontalTextPosition = JButton.TRAILING;
+  }
+
+  /**
+   * Set the "UI" property of the menu item, which is a look and feel class
+   * responsible for handling menuItem's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(MenuItemUI ui)
+  {
+    super.setUI(ui);
+  }
+  
+  /**
+   * This method sets this menuItem's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((MenuItemUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menuItem.
+   *
+   * @return The Look and Feel classID. "MenuItemUI"
+   */
+  public String getUIClassID()
+  {
+    return "MenuItemUI";
+  }
+
+  /**
+   * Returns true if button's model is armed and false otherwise. The
+   * button model is armed if menu item has focus or it is selected.
+   *
+   * @return $boolean$ true if button's model is armed and false otherwise
+   */
+  public boolean isArmed()
+  {
+    return getModel().isArmed();
+  }
+
+  /**
+   * Sets menuItem's "ARMED" property
+   *
+   * @param armed DOCUMENT ME!
+   */
+  public void setArmed(boolean armed)
+  {
+    getModel().setArmed(armed);
+  }
+
+  /**
+   * Enable or disable menu item. When menu item is disabled,
+   * its text and icon are grayed out if they exist.
+   *
+   * @param enabled if true enable menu item, and disable otherwise.
+   */
+  public void setEnabled(boolean enabled)
+  {
+    super.setEnabled(enabled);
+  }
+
+  /**
+   * Return accelerator for this menu item.
+   *
+   * @return $KeyStroke$ accelerator for this menu item.
+   */
+  public KeyStroke getAccelerator()
+  {
+    return accelerator;
+  }
+
+  /**
+   * Sets the key combination which invokes the menu item's action 
+   * listeners without navigating the menu hierarchy. Note that when the 
+   * keyboard accelerator is typed, it will work whether or not the 
+   * menu is currently displayed.
+   * 
+   * @param keystroke accelerator for this menu item.
+   */
+  public void setAccelerator(KeyStroke keystroke)
+  {
+    KeyStroke old = this.accelerator;
+    this.accelerator = keystroke;
+    firePropertyChange ("accelerator", old, keystroke);
+  }
+
+  /**
+   * Configures menu items' properties from properties of the specified action.
+   * This method overrides configurePropertiesFromAction from AbstractButton
+   * to also set accelerator property.
+   *
+   * @param action action to configure properties from
+   */
+  protected void configurePropertiesFromAction(Action action)
+  {
+    super.configurePropertiesFromAction(action);
+
+    if (! (this instanceof JMenu) && action != null)
+      {
+        setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
+        if (accelerator != null)
+          super.registerKeyboardAction(action, accelerator, 
+                                       JComponent.WHEN_IN_FOCUSED_WINDOW);
+      }
+  }
+
+  /**
+   * Creates PropertyChangeListener to listen for the changes in action
+   * properties.
+   *
+   * @param action action to listen to for property changes
+   *
+   * @return $PropertyChangeListener$ Listener that listens to changes in
+   * action properties.
+   */
+  protected PropertyChangeListener createActionPropertyChangeListener(Action action)
+  {
+    return new PropertyChangeListener()
+      {
+	public void propertyChange(PropertyChangeEvent e)
+	{
+	  Action act = (Action) (e.getSource());
+	  configurePropertiesFromAction(act);
+	}
+      };
+  }
+
+  /**
+   * Process mouse events forwarded from MenuSelectionManager.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   */
+  public void processMouseEvent(MouseEvent event, MenuElement[] path,
+                                MenuSelectionManager manager)
+  {
+    // Fire MenuDragMouseEvents if mouse is being dragged.
+    boolean dragged
+      = (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0;
+    if (dragged)
+      processMenuDragMouseEvent(createMenuDragMouseEvent(event, path, manager));
+
+    switch (event.getID())
+      {
+      case MouseEvent.MOUSE_CLICKED:
+	break;
+      case MouseEvent.MOUSE_ENTERED:
+	if (isRolloverEnabled())
+	  model.setRollover(true);
+	break;
+      case MouseEvent.MOUSE_EXITED:
+	if (isRolloverEnabled())
+	  model.setRollover(false);
+
+	// for JMenu last element on the path is its popupMenu.
+	// JMenu shouldn't me disarmed.	
+	if (! (path[path.length - 1] instanceof JPopupMenu) && ! dragged)
+	  setArmed(false);
+	break;
+      case MouseEvent.MOUSE_PRESSED:
+	if ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
+	  {
+	    model.setArmed(true);
+	    model.setPressed(true);
+	  }
+	break;
+      case MouseEvent.MOUSE_RELEASED:
+	break;
+      case MouseEvent.MOUSE_MOVED:
+	break;
+      case MouseEvent.MOUSE_DRAGGED:
+	break;
+      }
+  }
+
+  /**
+   * Creates MenuDragMouseEvent.
+   *
+   * @param event MouseEvent that occured while mouse was pressed.
+   * @param path Path the the menu element where the dragging event was
+   *        originated
+   * @param manager MenuSelectionManager for the current menu hierarchy.
+   *
+   * @return new MenuDragMouseEvent
+   */
+  private MenuDragMouseEvent createMenuDragMouseEvent(MouseEvent event,
+                                                      MenuElement[] path,
+                                                      MenuSelectionManager manager)
+  {
+    return new MenuDragMouseEvent((Component) event.getSource(),
+                                  event.getID(), event.getWhen(),
+                                  event.getModifiers(), event.getX(),
+                                  event.getY(), event.getClickCount(),
+                                  event.isPopupTrigger(), path, manager);
+  }
+
+  /**
+   * Process key events forwarded from MenuSelectionManager.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   */
+  public void processKeyEvent(KeyEvent event, MenuElement[] path,
+                              MenuSelectionManager manager)
+  {
+    MenuKeyEvent e = new MenuKeyEvent(event.getComponent(), event.getID(),
+                                      event.getWhen(), event.getModifiers(),
+                                      event.getKeyCode(), event.getKeyChar(),
+                                      path, manager);
+    processMenuKeyEvent(e);
+
+    // Consume original key event, if the menu key event has been consumed.
+    if (e.isConsumed())
+      event.consume();
+  }
+
+  /**
+   * This method fires MenuDragMouseEvents to registered listeners.
+   * Different types of MenuDragMouseEvents are fired depending
+   * on the observed mouse event.
+   *
+   * @param event Mouse
+   */
+  public void processMenuDragMouseEvent(MenuDragMouseEvent event)
+  {
+    switch (event.getID())
+      {
+      case MouseEvent.MOUSE_ENTERED:
+	fireMenuDragMouseEntered(event);
+	break;
+      case MouseEvent.MOUSE_EXITED:
+	fireMenuDragMouseExited(event);
+	break;
+      case MouseEvent.MOUSE_DRAGGED:
+	fireMenuDragMouseDragged(event);
+	break;
+      case MouseEvent.MOUSE_RELEASED:
+	fireMenuDragMouseReleased(event);
+	break;
+      }
+  }
+
+  /**
+   * This method fires MenuKeyEvent to registered listeners.
+   * Different types of MenuKeyEvents are fired depending
+   * on the observed key event.
+   *
+   * @param event DOCUMENT ME!
+   */
+  public void processMenuKeyEvent(MenuKeyEvent event)
+  {
+    switch (event.getID())
+    {
+      case KeyEvent.KEY_PRESSED:
+        fireMenuKeyPressed(event);
+        break;
+      case KeyEvent.KEY_RELEASED:
+        fireMenuKeyReleased(event);
+        break;
+      case KeyEvent.KEY_TYPED:
+        fireMenuKeyTyped(event);
+        break;
+      default:
+        break;
+    }
+  }
+
+  /**
+   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse entered menuItem while it was dragged
+   */
+  protected void fireMenuDragMouseEntered(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event);
+  }
+
+  /**
+   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse has exited menu item, while it was dragged
+   */
+  protected void fireMenuDragMouseExited(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event);
+  }
+
+  /**
+   * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse is being dragged over the menuItem
+   */
+  protected void fireMenuDragMouseDragged(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event);
+  }
+
+  /**
+   * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners.
+   *
+   * @param event The event signifying that mouse was released while it was dragged over the menuItem
+   */
+  protected void fireMenuDragMouseReleased(MenuDragMouseEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event);
+  }
+
+  /**
+   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
+   *
+   * @param event The event signifying that key associated with this menu was pressed
+   */
+  protected void fireMenuKeyPressed(MenuKeyEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuKeyListener) ll[i]).menuKeyPressed(event);
+  }
+
+  /**
+   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
+   *
+   * @param event The event signifying that key associated with this menu was released
+   */
+  protected void fireMenuKeyReleased(MenuKeyEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuKeyListener) ll[i]).menuKeyTyped(event);
+  }
+
+  /**
+   * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
+   *
+   * @param event The event signifying that key associated with this menu was typed.
+   *        The key is typed when it was pressed and then released
+   */
+  protected void fireMenuKeyTyped(MenuKeyEvent event)
+  {
+    EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((MenuKeyListener) ll[i]).menuKeyTyped(event);
+  }
+
+  /**
+   * Method of the MenuElement interface.
+   * This method is invoked by MenuSelectionManager when selection of
+   * this menu item has changed. If this menu item was selected then
+   * arm it's model, and disarm the model otherwise. The menu item
+   * is considered to be selected, and thus highlighted when its model
+   * is armed.
+   *
+   * @param changed indicates selection status of this menu item. If changed is
+   * true then menu item is selected and deselected otherwise.
+   */
+  public void menuSelectionChanged(boolean changed)
+  {
+    Component parent = this.getParent();
+    if (changed)
+      {
+	model.setArmed(true);
+
+	if (parent != null && parent instanceof JPopupMenu)
+	  ((JPopupMenu) parent).setSelected(this);
+      }
+    else
+      {
+	model.setArmed(false);
+
+	if (parent != null && parent instanceof JPopupMenu)
+	  ((JPopupMenu) parent).getSelectionModel().clearSelection();
+      }
+  }
+
+  /**
+   * Method of the MenuElement interface.
+   *
+   * @return $MenuElement[]$ Returns array of sub-components for this menu
+   *         item. By default menuItem doesn't have any subcomponents and so
+   *         empty array is returned instead.
+   */
+  public MenuElement[] getSubElements()
+  {
+    return new MenuElement[0];
+  }
+
+  /**
+   * Returns reference to the component that will paint this menu item.
+   *
+   * @return $Component$ Component that will paint this menu item.
+   *         Simply returns reference to this menu item.
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * Adds a MenuDragMouseListener to this menu item. When mouse
+   * is dragged over the menu item the MenuDragMouseEvents will be
+   * fired, and these listeners will be called.
+   *
+   * @param listener The new listener to add
+   */
+  public void addMenuDragMouseListener(MenuDragMouseListener listener)
+  {
+    listenerList.add(MenuDragMouseListener.class, listener);
+  }
+
+  /**
+   * Removes a MenuDragMouseListener from the menuItem's listener list.
+   *
+   * @param listener The listener to remove
+   */
+  public void removeMenuDragMouseListener(MenuDragMouseListener listener)
+  {
+    listenerList.remove(MenuDragMouseListener.class, listener);
+  }
+
+  /**
+   * Returns all added MenuDragMouseListener objects.
+   *
+   * @return an array of listeners
+   *
+   * @since 1.4
+   */
+  public MenuDragMouseListener[] getMenuDragMouseListeners()
+  {
+    return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class);
+  }
+
+  /**
+   * Adds an MenuKeyListener to this menu item.  This listener will be
+   * invoked when MenuKeyEvents will be fired by this menu item.
+   *
+   * @param listener The new listener to add
+   */
+  public void addMenuKeyListener(MenuKeyListener listener)
+  {
+    listenerList.add(MenuKeyListener.class, listener);
+  }
+
+  /**
+   * Removes an MenuKeyListener from the menuItem's listener list.
+   *
+   * @param listener The listener to remove
+   */
+  public void removeMenuKeyListener(MenuKeyListener listener)
+  {
+    listenerList.remove(MenuKeyListener.class, listener);
+  }
+
+  /**
+   * Returns all added MenuKeyListener objects.
+   *
+   * @return an array of listeners
+   *
+   * @since 1.4
+   */
+  public MenuKeyListener[] getMenuKeyListeners()
+  {
+    return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class);
+  }
+
+  /**
+   * Returns a string describing the attributes for the <code>JMenuItem</code>
+   * component, for use in debugging.  The return value is guaranteed to be 
+   * non-<code>null</code>, but the format of the string may vary between
+   * implementations.
+   *
+   * @return A string describing the attributes of the <code>JMenuItem</code>.
+   */
+  protected String paramString()
+  {
+    // calling super seems to be sufficient here...
+    return super.paramString();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JMenuItem</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJMenuItem}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      {
+        AccessibleJMenuItem ctx = new AccessibleJMenuItem(); 
+        addChangeListener(ctx);
+        accessibleContext = ctx;
+      }
+
+    return accessibleContext;
+  }
+
+  /**
+   * Provides the accessibility features for the <code>JMenuItem</code> 
+   * component.
+   * 
+   * @see JMenuItem#getAccessibleContext()
+   */
+  protected class AccessibleJMenuItem extends AccessibleAbstractButton
+    implements ChangeListener
+  {
+    private static final long serialVersionUID = 6748924232082076534L;
+
+    private boolean armed;
+    private boolean focusOwner;
+    private boolean pressed;
+    private boolean selected;
+
+    /**
+     * Creates a new <code>AccessibleJMenuItem</code> instance.
+     */
+    AccessibleJMenuItem()
+    {
+      //super(component);
+    }
+
+    /**
+     * Receives notification when the menu item's state changes and fires
+     * appropriate property change events to registered listeners.
+     *
+     * @param event the change event
+     */
+    public void stateChanged(ChangeEvent event)
+    {
+      // This is fired in all cases.
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+                         Boolean.FALSE, Boolean.TRUE);
+
+      ButtonModel model = getModel();
+
+      // Handle the armed property.
+      if (model.isArmed())
+        {
+          if (! armed)
+            {
+              armed = true;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 AccessibleState.ARMED, null);
+            }
+        }
+      else
+        {
+          if (armed)
+            {
+              armed = false;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 null, AccessibleState.ARMED);
+            }
+        }
+
+      // Handle the pressed property.
+      if (model.isPressed())
+        {
+          if (! pressed)
+            {
+              pressed = true;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 AccessibleState.PRESSED, null);
+            }
+        }
+      else
+        {
+          if (pressed)
+            {
+              pressed = false;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 null, AccessibleState.PRESSED);
+            }
+        }
+
+      // Handle the selected property.
+      if (model.isSelected())
+        {
+          if (! selected)
+            {
+              selected = true;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 AccessibleState.SELECTED, null);
+            }
+        }
+      else
+        {
+          if (selected)
+            {
+              selected = false;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 null, AccessibleState.SELECTED);
+            }
+        }
+
+      // Handle the focusOwner property.
+      if (isFocusOwner())
+        {
+          if (! focusOwner)
+            {
+              focusOwner = true;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 AccessibleState.FOCUSED, null);
+            }
+        }
+      else
+        {
+          if (focusOwner)
+            {
+              focusOwner = false;
+              firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                                 null, AccessibleState.FOCUSED);
+            }
+        }
+    }
+
+    /**
+     * Returns the accessible role for the <code>JMenuItem</code> component.
+     *
+     * @return {@link AccessibleRole#MENU_ITEM}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.MENU_ITEM;
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JOptionPane.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JOptionPane.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JOptionPane.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JOptionPane.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1637 @@
+/* JOptionPane.java
+   Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.MenuComponent;
+import java.awt.Toolkit;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseMotionAdapter;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.OptionPaneUI;
+
+/**
+ * This class creates different types of JDialogs and JInternalFrames that can
+ * ask users for input or pass on information. JOptionPane can be used by
+ * calling one of the show static methods or  by creating an instance of
+ * JOptionPane and calling createDialog or createInternalFrame.
+ */
+public class JOptionPane extends JComponent implements Accessible
+{
+  /**
+   * Provides the accessibility features for the <code>JOptionPane</code>
+   * component.
+   */
+  protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent
+  {
+    private static final long serialVersionUID = 686071432213084821L;
+    
+    /**
+     * Creates a new <code>AccessibleJOptionPane</code> instance.
+     */
+    protected AccessibleJOptionPane()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns the accessible role of this object, which is always
+     * {@link AccessibleRole#OPTION_PANE}.
+     *
+     * @return the accessible role of this object
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.OPTION_PANE;
+    }
+  }
+
+  private static final long serialVersionUID = 5231143276678566796L;
+
+  /** The value returned when cancel option is selected. */
+  public static final int CANCEL_OPTION = 2;
+
+  /** The value returned when the dialog is closed without a selection. */
+  public static final int CLOSED_OPTION = -1;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int DEFAULT_OPTION = -1;
+
+  /** The value returned when the no option is selected. */
+  public static final int NO_OPTION = 1;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int OK_CANCEL_OPTION = 2;
+
+  /** The value returned when the ok option is selected. */
+  public static final int OK_OPTION = 0;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int YES_NO_CANCEL_OPTION = 1;
+
+  /** An option used in confirmation dialog methods. */
+  public static final int YES_NO_OPTION = 0;
+
+  /** The value returned when the yes option is selected. */
+  public static final int YES_OPTION = 0;
+
+  /** Identifier for the error message type. */
+  public static final int ERROR_MESSAGE = 0;
+
+  /** Identifier for the information message type. */
+  public static final int INFORMATION_MESSAGE = 1;
+
+  /** Identifier for the plain message type. */
+  public static final int PLAIN_MESSAGE = -1;
+
+  /** Identifier for the question message type. */
+  public static final int QUESTION_MESSAGE = 3;
+
+  /** Identifier for the warning message type. */
+  public static final int WARNING_MESSAGE = 2;
+
+  /**
+   * The identifier for the propertyChangeEvent when the icon property
+   * changes.
+   */
+  public static final String ICON_PROPERTY = "icon";
+
+  /**
+   * The identifier for the propertyChangeEvent when the initialSelectionValue
+   * property changes.
+   */
+  public static final String INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
+
+  /**
+   * The identifier for the propertyChangeEvent when the initialValue property
+   * changes.
+   */
+  public static final String INITIAL_VALUE_PROPERTY = "initialValue";
+
+  /**
+   * The identifier for the propertyChangeEvent when the inputValue property
+   * changes.
+   */
+  public static final String INPUT_VALUE_PROPERTY = "inputValue";
+
+  /**
+   * The identifier for the propertyChangeEvent when the message property
+   * changes.
+   */
+  public static final String MESSAGE_PROPERTY = "message";
+
+  /**
+   * The identifier for the propertyChangeEvent when the messageType property
+   * changes.
+   */
+  public static final String MESSAGE_TYPE_PROPERTY = "messageType";
+
+  /**
+   * The identifier for the propertyChangeEvent when the optionType property
+   * changes.
+   */
+  public static final String OPTION_TYPE_PROPERTY = "optionType";
+
+  /**
+   * The identifier for the propertyChangeEvent when the options property
+   * changes.
+   */
+  public static final String OPTIONS_PROPERTY = "options";
+
+  /**
+   * The identifier for the propertyChangeEvent when the selectionValues
+   * property changes.
+   */
+  public static final String SELECTION_VALUES_PROPERTY = "selectionValues";
+
+  /**
+   * The identifier for the propertyChangeEvent when the value property
+   * changes.
+   */
+  public static final String VALUE_PROPERTY = "value";
+
+  /**
+   * The identifier for the propertyChangeEvent when the wantsInput property
+   * changes.
+   */
+  public static final String WANTS_INPUT_PROPERTY = "wantsInput";
+
+  /** The value returned when the inputValue is uninitialized. */
+  public static final Object UNINITIALIZED_VALUE = "uninitializedValue";
+
+  /** The icon displayed in the dialog/internal frame. */
+  protected Icon icon;
+
+  /** The initial selected value in the input component. */
+  protected Object initialSelectionValue;
+
+  /** The object that is initially selected for options. */
+  protected Object initialValue;
+
+  /** The value the user inputs. */
+  protected Object inputValue = UNINITIALIZED_VALUE;
+
+  /** The message displayed in the dialog/internal frame. */
+  protected Object message;
+
+  /** The type of message displayed. */
+  protected int messageType = PLAIN_MESSAGE;
+
+  /**
+   * The options (usually buttons) aligned at the bottom for the user to
+   * select.
+   */
+  protected Object[] options;
+
+  /** The type of options to display. */
+  protected int optionType = DEFAULT_OPTION;
+
+  /** The input values the user can select. */
+  protected Object[] selectionValues;
+
+  /** The value returned by selecting an option. */
+  protected Object value = UNINITIALIZED_VALUE;
+
+  /** Whether the Dialog/InternalFrame needs input. */
+  protected boolean wantsInput;
+
+  /** The common frame used when no parent is provided. */
+  private static Frame privFrame = (Frame) SwingUtilities.getOwnerFrame(null);
+
+  /**
+   * Creates a new JOptionPane object using a message of "JOptionPane
+   * message", using the PLAIN_MESSAGE type and DEFAULT_OPTION.
+   */
+  public JOptionPane()
+  {
+    this("JOptionPane message", PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message using the
+   * PLAIN_MESSAGE type and DEFAULT_OPTION.
+   *
+   * @param message The message to display.
+   */
+  public JOptionPane(Object message)
+  {
+    this(message, PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message and messageType
+   * and DEFAULT_OPTION.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   */
+  public JOptionPane(Object message, int messageType)
+  {
+    this(message, messageType, DEFAULT_OPTION, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType and
+   * optionType.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   */
+  public JOptionPane(Object message, int messageType, int optionType)
+  {
+    this(message, messageType, optionType, null, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType,
+   * optionType and icon.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   * @param icon The icon to display.
+   */
+  public JOptionPane(Object message, int messageType, int optionType, Icon icon)
+  {
+    this(message, messageType, optionType, icon, null, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType,
+   * optionType, icon and options.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   * @param icon The icon to display.
+   * @param options The options given.
+   */
+  public JOptionPane(Object message, int messageType, int optionType,
+                     Icon icon, Object[] options)
+  {
+    this(message, messageType, optionType, icon, options, null);
+  }
+
+  /**
+   * Creates a new JOptionPane object using the given message, messageType,
+   * optionType, icon, options and initialValue. The initialValue will be
+   * focused initially.
+   *
+   * @param message The message to display.
+   * @param messageType The type of message.
+   * @param optionType The type of options.
+   * @param icon The icon to display.
+   * @param options The options given.
+   * @param initialValue The component to focus on initially.
+   *
+   * @throws IllegalArgumentException If the messageType or optionType are not
+   *         legal values.
+   */
+  public JOptionPane(Object message, int messageType, int optionType,
+                     Icon icon, Object[] options, Object initialValue)
+  {
+    this.message = message;
+    if (! validMessageType(messageType))
+      throw new IllegalArgumentException("Message Type not legal value.");
+    this.messageType = messageType;
+    if (! validOptionType(optionType))
+      throw new IllegalArgumentException("Option Type not legal value.");
+    this.optionType = optionType;
+    this.icon = icon;
+    this.options = options;
+    this.initialValue = initialValue;
+
+    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+    updateUI();
+  }
+
+  /**
+   * This method creates a new JDialog that is either centered around the
+   * parent's frame or centered on the screen (if the parent is null). The
+   * JDialog will not be resizable and will be modal. Once the JDialog is
+   * disposed, the inputValue and value properties will  be set by the
+   * optionPane.
+   *
+   * @param parentComponent The parent of the Dialog.
+   * @param title The title in the bar of the JDialog.
+   *
+   * @return A new JDialog based on the JOptionPane configuration.
+   */
+  public JDialog createDialog(Component parentComponent, String title)
+  {
+    Frame toUse = getFrameForComponent(parentComponent);
+    if (toUse == null)
+      toUse = getRootFrame();
+
+    JDialog dialog = new JDialog(toUse, title);
+    inputValue = UNINITIALIZED_VALUE;
+    value = UNINITIALIZED_VALUE;
+
+    dialog.getContentPane().add(this);
+    dialog.setModal(true);
+    dialog.setResizable(false);
+    dialog.pack();
+    dialog.setLocationRelativeTo(parentComponent);
+
+    addPropertyChangeListener(new ValuePropertyHandler(dialog));
+    return dialog;
+  }
+
+  /**
+   * Handles changes of the value property. Whenever this property changes,
+   * the JOptionPane dialog should be closed.
+   */
+  private static class ValuePropertyHandler
+    implements PropertyChangeListener
+  {
+    /**
+     * The dialog to close.
+     */
+    JDialog dialog;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param d the dialog to be closed
+     */
+    ValuePropertyHandler(JDialog d)
+    {
+      dialog = d;
+    }
+
+    /**
+     * Receives notification when any of the properties change.
+     */
+    public void propertyChange(PropertyChangeEvent p)
+    {
+      String prop = p.getPropertyName();
+      Object val = p.getNewValue();
+      if (prop.equals(VALUE_PROPERTY) && val != null
+          && val != UNINITIALIZED_VALUE)
+        {
+          dialog.setVisible(false);
+        }
+    }
+  }
+
+  /**
+   * This method creates a new JInternalFrame that is in the JLayeredPane
+   * which contains the parentComponent given. If no suitable JLayeredPane
+   * can be found from the parentComponent given, a RuntimeException will be
+   * thrown.
+   *
+   * @param parentComponent The parent to find a JDesktopPane from.
+   * @param title The title of the JInternalFrame.
+   *
+   * @return A new JInternalFrame based on the JOptionPane configuration.
+   *
+   * @throws RuntimeException If no suitable JDesktopPane is found.
+   *
+   * @specnote The specification says that the internal frame is placed
+   *           in the nearest <code>JDesktopPane</code> that is found in
+   *           <code>parent</code>'s ancestors. The behaviour of the JDK
+   *           is that it actually looks up the nearest
+   *           <code>JLayeredPane</code> in <code>parent</code>'s ancestors.
+   *           So do we.
+   */
+  public JInternalFrame createInternalFrame(Component parentComponent,
+                                            String title)
+                                     throws RuntimeException
+  {
+    // Try to find a JDesktopPane.
+    JLayeredPane toUse = getDesktopPaneForComponent(parentComponent);
+    // If we don't have a JDesktopPane, we try to find a JLayeredPane.
+    if (toUse == null)
+      toUse = JLayeredPane.getLayeredPaneAbove(parentComponent);
+    // If this still fails, we throw a RuntimeException.
+    if (toUse == null)
+      throw new RuntimeException
+        ("parentComponent does not have a valid parent");
+
+    JInternalFrame frame = new JInternalFrame(title);
+
+    inputValue = UNINITIALIZED_VALUE;
+    value = UNINITIALIZED_VALUE;
+
+    frame.setContentPane(this);
+    frame.setClosable(true);
+
+    toUse.add(frame);
+    frame.setLayer(JLayeredPane.MODAL_LAYER);
+
+    frame.pack();
+    frame.setVisible(true);
+
+    return frame;
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JOptionPane</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJOptionPane}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJOptionPane();
+    return accessibleContext;
+  }
+
+  /**
+   * This method returns the JDesktopPane for the given parentComponent or
+   * null if none can be found.
+   *
+   * @param parentComponent The component to look in.
+   *
+   * @return The JDesktopPane for the given component or null if none can be
+   *         found.
+   */
+  public static JDesktopPane getDesktopPaneForComponent(Component parentComponent)
+  {
+    return (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                            parentComponent);
+  }
+
+  /**
+   * This method returns the Frame for the given parentComponent or null if
+   * none can be found.
+   *
+   * @param parentComponent The component to look in.
+   *
+   * @return The Frame for the given component or null if none can be found.
+   */
+  public static Frame getFrameForComponent(Component parentComponent)
+  {
+    return (Frame) SwingUtilities.getAncestorOfClass(Frame.class,
+                                                     parentComponent);
+  }
+
+  /**
+   * This method returns the icon displayed.
+   *
+   * @return The icon displayed.
+   */
+  public Icon getIcon()
+  {
+    return icon;
+  }
+
+  /**
+   * This method returns the value initially selected from the list of values
+   * the user can input.
+   *
+   * @return The initial selection value.
+   */
+  public Object getInitialSelectionValue()
+  {
+    return initialSelectionValue;
+  }
+
+  /**
+   * This method returns the value that is focused from the list of options.
+   *
+   * @return The initial value from options.
+   */
+  public Object getInitialValue()
+  {
+    return initialValue;
+  }
+
+  /**
+   * This method returns the value that the user input.
+   *
+   * @return The user's input value.
+   */
+  public Object getInputValue()
+  {
+    if (getValue().equals(new Integer(CANCEL_OPTION)))
+      setInputValue(null);
+    return inputValue;
+  }
+
+  /**
+   * This method returns the maximum characters per line. By default, this is
+   * Integer.MAX_VALUE.
+   *
+   * @return The maximum characters per line.
+   */
+  public int getMaxCharactersPerLineCount()
+  {
+    return Integer.MAX_VALUE;
+  }
+
+  /**
+   * This method returns the message displayed.
+   *
+   * @return The message displayed.
+   */
+  public Object getMessage()
+  {
+    return message;
+  }
+
+  /**
+   * This method returns the message type.
+   *
+   * @return The message type.
+   */
+  public int getMessageType()
+  {
+    return messageType;
+  }
+
+  /**
+   * This method returns the options.
+   *
+   * @return The options.
+   */
+  public Object[] getOptions()
+  {
+    return options;
+  }
+
+  /**
+   * This method returns the option type.
+   *
+   * @return The option type.
+   */
+  public int getOptionType()
+  {
+    return optionType;
+  }
+
+  /**
+   * This method returns the Frame used by JOptionPane dialog's that have no
+   * parent.
+   *
+   * @return The Frame used by dialogs that have no parent.
+   */
+  public static Frame getRootFrame()
+  {
+    return privFrame;
+  }
+
+  /**
+   * This method returns the selection values.
+   *
+   * @return The selection values.
+   */
+  public Object[] getSelectionValues()
+  {
+    return selectionValues;
+  }
+
+  /**
+   * This method returns the UI used by the JOptionPane.
+   *
+   * @return The UI used by the JOptionPane.
+   */
+  public OptionPaneUI getUI()
+  {
+    return (OptionPaneUI) ui;
+  }
+
+  /**
+   * This method returns an identifier to determine which UI class will act as
+   * the UI.
+   *
+   * @return The UI identifier.
+   */
+  public String getUIClassID()
+  {
+    return "OptionPaneUI";
+  }
+
+  /**
+   * This method returns the value that the user selected out of options.
+   *
+   * @return The value that the user selected out of options.
+   */
+  public Object getValue()
+  {
+    return value;
+  }
+
+  /**
+   * This method returns whether this JOptionPane wants input.
+   *
+   * @return Whether this JOptionPane wants input.
+   */
+  public boolean getWantsInput()
+  {
+    return wantsInput;
+  }
+
+  /**
+   * This method returns a String that describes this JOptionPane.
+   *
+   * @return A String that describes this JOptionPane.
+   */
+  protected String paramString()
+  {
+    return "JOptionPane";
+  }
+
+  /**
+   * This method requests focus for the initial value.
+   */
+  public void selectInitialValue()
+  {
+    if (ui != null)
+      ((OptionPaneUI) ui).selectInitialValue(this);
+  }
+
+  /**
+   * This method changes the icon property.
+   *
+   * @param newIcon The new icon to use.
+   */
+  public void setIcon(Icon newIcon)
+  {
+    if (icon != newIcon)
+      {
+	Icon old = icon;
+	icon = newIcon;
+	firePropertyChange(ICON_PROPERTY, old, icon);
+      }
+  }
+
+  /**
+   * This method changes the initial selection property.
+   *
+   * @param newValue The new initial selection.
+   */
+  public void setInitialSelectionValue(Object newValue)
+  {
+    if (initialSelectionValue != newValue)
+      {
+	Object old = initialSelectionValue;
+	initialSelectionValue = newValue;
+	firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, old,
+	                   initialSelectionValue);
+      }
+  }
+
+  /**
+   * This method changes the initial value property.
+   *
+   * @param newValue The new initial value.
+   */
+  public void setInitialValue(Object newValue)
+  {
+    if (initialValue != newValue)
+      {
+	Object old = initialValue;
+	initialValue = newValue;
+	firePropertyChange(INITIAL_VALUE_PROPERTY, old, initialValue);
+      }
+  }
+
+  /**
+   * This method changes the inputValue property.
+   *
+   * @param newValue The new inputValue.
+   */
+  public void setInputValue(Object newValue)
+  {
+    if (inputValue != newValue)
+      {
+	Object old = inputValue;
+	inputValue = newValue;
+	firePropertyChange(INPUT_VALUE_PROPERTY, old, inputValue);
+      }
+  }
+
+  /**
+   * This method changes the message property.
+   *
+   * @param newMessage The new message.
+   */
+  public void setMessage(Object newMessage)
+  {
+    if (message != newMessage)
+      {
+	Object old = message;
+	message = newMessage;
+	firePropertyChange(MESSAGE_PROPERTY, old, message);
+      }
+  }
+
+  /**
+   * This method changes the messageType property.
+   *
+   * @param newType The new messageType.
+   *
+   * @throws IllegalArgumentException If the messageType is not valid.
+   */
+  public void setMessageType(int newType)
+  {
+    if (! validMessageType(newType))
+      throw new IllegalArgumentException("Message Type not legal value.");
+    if (newType != messageType)
+      {
+	int old = messageType;
+	messageType = newType;
+	firePropertyChange(MESSAGE_TYPE_PROPERTY, old, messageType);
+      }
+  }
+
+  /**
+   * This method changes the options property.
+   *
+   * @param newOptions The new options.
+   */
+  public void setOptions(Object[] newOptions)
+  {
+    if (options != newOptions)
+      {
+	Object[] old = options;
+	options = newOptions;
+	firePropertyChange(OPTIONS_PROPERTY, old, options);
+      }
+  }
+
+  /**
+   * This method changes the optionType property.
+   *
+   * @param newType The new optionType.
+   *
+   * @throws IllegalArgumentException If the optionType is not valid.
+   */
+  public void setOptionType(int newType)
+  {
+    if (! validOptionType(newType))
+      throw new IllegalArgumentException("Option Type not legal value.");
+    if (newType != optionType)
+      {
+	int old = optionType;
+	optionType = newType;
+	firePropertyChange(OPTION_TYPE_PROPERTY, old, optionType);
+      }
+  }
+
+  /**
+   * This method changes the Frame used for JOptionPane dialogs that have no
+   * parent.
+   *
+   * @param newRootFrame The Frame to use for dialogs that have no parent.
+   */
+  public static void setRootFrame(Frame newRootFrame)
+  {
+    privFrame = newRootFrame;
+  }
+
+  /**
+   * This method changes the selectionValues property.
+   *
+   * @param newValues The new selectionValues.
+   */
+  public void setSelectionValues(Object[] newValues)
+  {
+    if (newValues != selectionValues)
+      {
+	if (newValues != null)
+	  wantsInput = true;
+	Object[] old = selectionValues;
+	selectionValues = newValues;
+	firePropertyChange(SELECTION_VALUES_PROPERTY, old, selectionValues);
+      }
+  }
+
+  /**
+   * This method sets the UI used with the JOptionPane.
+   *
+   * @param ui The UI used with the JOptionPane.
+   */
+  public void setUI(OptionPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets the value has been selected out of options.
+   *
+   * @param newValue The value that has been selected out of options.
+   */
+  public void setValue(Object newValue)
+  {
+    if (value != newValue)
+      {
+	Object old = value;
+	value = newValue;
+	firePropertyChange(VALUE_PROPERTY, old, value);
+      }
+  }
+
+  /**
+   * This method changes the wantsInput property.
+   *
+   * @param newValue Whether this JOptionPane requires input.
+   */
+  public void setWantsInput(boolean newValue)
+  {
+    if (wantsInput != newValue)
+      {
+	boolean old = wantsInput;
+	wantsInput = newValue;
+	firePropertyChange(WANTS_INPUT_PROPERTY, old, wantsInput);
+      }
+  }
+
+  /**
+   * This method shows a confirmation dialog with the title "Select an Option"
+   * and displays the given message. The parent frame will be the same as the
+   * parent frame of the given parentComponent. This method returns the
+   * option chosen by the user.
+   *
+   * @param parentComponent The parentComponent to find a frame in.
+   * @param message The message to display.
+   *
+   * @return The option that was selected.
+   */
+  public static int showConfirmDialog(Component parentComponent, Object message)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    JDialog dialog = pane.createDialog(parentComponent, "Select an Option");
+    dialog.show();
+    
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows a confirmation dialog with the given message,
+   * optionType and title. The frame that owns the dialog will be the same
+   * frame that holds the given parentComponent. This method returns the
+   * option that was chosen.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   *
+   * @return The option that was chosen.
+   */
+  public static int showConfirmDialog(Component parentComponent,
+                                      Object message, String title,
+                                      int optionType)
+  {
+    JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows a confirmation dialog with the given message, title,
+   * messageType and optionType. The frame owner will be the same frame as
+   * the one that holds the given parentComponent. This method returns the
+   * option selected by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   * @param messageType The messageType.
+   *
+   * @return The selected option.
+   */
+  public static int showConfirmDialog(Component parentComponent,
+                                      Object message, String title,
+                                      int optionType, int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows a confirmation dialog with the given message, title,
+   * optionType, messageType and icon. The frame owner will be the same as
+   * the one that holds the given parentComponent. This method returns the
+   * option selected by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   * @param messageType The messsageType.
+   * @param icon The icon displayed.
+   *
+   * @return The selected option.
+   */
+  public static int showConfirmDialog(Component parentComponent,
+                                      Object message, String title,
+                                      int optionType, int messageType,
+                                      Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method will show a QUESTION_MESSAGE input dialog with the given
+   * message. No selectionValues is set so the Look and Feel will usually
+   * give the user a TextField to fill out. The frame owner will be the same
+   * frame that holds the given parentComponent. This method will return the
+   * value entered by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   *
+   * @return The value entered by the user.
+   */
+  public static String showInputDialog(Component parentComponent,
+                                       Object message)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(parentComponent, null);
+    dialog.show();
+    
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method will show a QUESTION_MESSAGE type input dialog with the given
+   * message and initialSelectionValue. Since there is no selectionValues
+   * set, the Look and Feel will usually give a TextField to fill out. The
+   * frame owner will be the same as the one that holds the given
+   * parentComponent. This method will return the value entered by the user.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message to display.
+   * @param initialSelectionValue The initially selected value.
+   *
+   * @return The value the user input.
+   */
+  public static String showInputDialog(Component parentComponent,
+                                       Object message,
+                                       Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(parentComponent, null);
+    dialog.show();
+    
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method displays a new input dialog with the given message, title and
+   * messageType. Since no selectionValues value is given, the Look and Feel
+   * will usually give the user a TextField to input data to. This method
+   * returns the value the user inputs.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message to display.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   *
+   * @return The value the user input.
+   */
+  public static String showInputDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+    
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an input dialog with the given message, title,
+   * messageType, icon, selectionValues, and initialSelectionValue. This
+   * method returns the value that the user selects.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   * @param icon The icon displayed.
+   * @param selectionValues The list of values to select from.
+   * @param initialSelectionValue The initially selected value.
+   *
+   * @return The user selected value.
+   */
+  public static Object showInputDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType, Icon icon,
+                                       Object[] selectionValues,
+                                       Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    pane.setIcon(icon);
+    pane.setSelectionValues(selectionValues);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+    
+    return pane.getInputValue();
+  }
+
+  /**
+   * This method shows a QUESTION_MESSAGE type input dialog. Since no
+   * selectionValues is set, the Look and Feel will usually give the user a
+   * TextField to input data to. This method returns the value the user
+   * inputs.
+   *
+   * @param message The message to display.
+   *
+   * @return The user selected value.
+   */
+  public static String showInputDialog(Object message)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setWantsInput(true);
+    JDialog dialog = pane.createDialog(null, null);
+    dialog.show();
+    
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows a QUESTION_MESSAGE type input dialog. Since no
+   * selectionValues is set, the Look and Feel will usually give the user a
+   * TextField to input data to. The input component will be initialized with
+   * the initialSelectionValue. This method returns the value the user
+   * inputs.
+   *
+   * @param message The message to display.
+   * @param initialSelectionValue The initialSelectionValue.
+   *
+   * @return The user selected value.
+   */
+  public static String showInputDialog(Object message,
+                                       Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
+    pane.setWantsInput(true);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    JDialog dialog = pane.createDialog(null, null);
+    dialog.show();
+    
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message.
+   * The internal frame dialog will be placed in the first JDesktopPane
+   * ancestor of the given parentComponent. This method will return the value
+   * selected.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   *
+   * @return The value selected.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message)
+  {
+    JOptionPane pane = new JOptionPane(message);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
+
+    startModal(frame);
+    
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message,
+   * optionType and title. The internal frame dialog will be placed in the
+   * first JDesktopPane ancestor of the given parentComponent.  This method
+   * will return the selected value.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param optionType The option type.
+   *
+   * @return The selected value.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message, String title,
+                                              int optionType)
+  {
+    JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message,
+   * title, optionTypes and icon for the given message type. The internal
+   * confirmation dialog will be placed in the first  instance of
+   * JDesktopPane ancestor of the given parentComponent.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title of the dialog.
+   * @param optionType The option type.
+   * @param messageType The message type.
+   *
+   * @return The selected value.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message, String title,
+                                              int optionType, int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows an internal confirmation dialog with the given message,
+   * title, option type, message type, and icon. The internal frame dialog
+   * will be placed in the first JDesktopPane ancestor  that is found in the
+   * given parentComponent. This method returns  the selected value.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param optionType The option type.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   *
+   * @return The selected value.
+   */
+  public static int showInternalConfirmDialog(Component parentComponent,
+                                              Object message, String title,
+                                              int optionType, int messageType,
+                                              Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows an internal input dialog with the given message. The
+   * internal frame dialog will be placed in the first JDesktopPane ancestor
+   * of the given parent component. This method returns the value input by
+   * the user.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   *
+   * @return The user selected value.
+   */
+  public static String showInternalInputDialog(Component parentComponent,
+                                               Object message)
+  {
+    JOptionPane pane = new JOptionPane(message);
+    pane.setWantsInput(true);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
+
+    startModal(frame);
+    
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal input dialog with the given message,  title
+   * and message type. The internal input dialog will be placed in the first
+   * JDesktopPane ancestor found in the given parent component. This method
+   * will return the input value given by the user.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   *
+   * @return The user input value.
+   */
+  public static String showInternalInputDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+    
+    return (String) pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal input dialog with the given message, title
+   * message type, icon, selection value list and initial selection value.
+   * The internal frame dialog will be placed in the first JDesktopPane
+   * ancestor found in the given parent component. This method returns the
+   * input value from the user.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   * @param selectionValues The selection value list.
+   * @param initialSelectionValue The initial selection value.
+   *
+   * @return The user input value.
+   */
+  public static Object showInternalInputDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType, Icon icon,
+                                               Object[] selectionValues,
+                                               Object initialSelectionValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setWantsInput(true);
+    pane.setIcon(icon);
+    pane.setSelectionValues(selectionValues);
+    pane.setInitialSelectionValue(initialSelectionValue);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+    
+    return pane.getInputValue();
+  }
+
+  /**
+   * This method shows an internal message dialog with the given message. The
+   * internal frame dialog will be placed in the first JDesktopPane ancestor
+   * found in the given parent component.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   */
+  public static void showInternalMessageDialog(Component parentComponent,
+                                               Object message)
+  {
+    JOptionPane pane = new JOptionPane(message);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);
+
+    startModal(frame);
+  }
+
+  /**
+   * This method shows an internal message dialog with the given message,
+   * title and message type. The internal message dialog is placed in the
+   * first JDesktopPane ancestor found in the given parent component.
+   *
+   * @param parentComponent The parent component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   */
+  public static void showInternalMessageDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+  }
+
+  /**
+   * This method shows an internal message dialog with the given message,
+   * title, message type and icon. The internal message dialog is placed in
+   * the first JDesktopPane ancestor found in the given parent component.
+   *
+   * @param parentComponent The component to find a JDesktopPane in.
+   * @param message The message to display.
+   * @param title The title to display.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   */
+  public static void showInternalMessageDialog(Component parentComponent,
+                                               Object message, String title,
+                                               int messageType, Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setIcon(icon);
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+  }
+
+  /**
+   * This method displays an internal option dialog with the given message,
+   * title, option type, message type, icon, option list, and initial option
+   * value. The internal option dialog is placed in the first JDesktopPane
+   * ancestor found in the parent component. This method returns the option
+   * selected.
+   *
+   * @param parentComponent The parent to find a JDesktopPane in.
+   * @param message The message displayed.
+   * @param title The title displayed.
+   * @param optionType The option type.
+   * @param messageType The message type.
+   * @param icon The icon to display.
+   * @param options The array of options.
+   * @param initialValue The initial value selected.
+   *
+   * @return The option that was selected.
+   */
+  public static int showInternalOptionDialog(Component parentComponent,
+                                             Object message, String title,
+                                             int optionType, int messageType,
+                                             Icon icon, Object[] options,
+                                             Object initialValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
+                                       options, initialValue);
+
+    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);
+
+    startModal(frame);
+ 
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method shows an INFORMATION_MESSAGE type message dialog.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   */
+  public static void showMessageDialog(Component parentComponent,
+                                       Object message)
+  {
+    JOptionPane pane = new JOptionPane(message, INFORMATION_MESSAGE);
+    JDialog dialog = pane.createDialog(parentComponent, null);
+    dialog.show();   
+  }
+
+  /**
+   * This method shows a message dialog with the given message, title and
+   * messageType.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   */
+  public static void showMessageDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+  }
+
+  /**
+   * This method shows a message dialog with the given message, title,
+   * messageType and icon.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param messageType The messageType.
+   * @param icon The icon displayed.
+   */
+  public static void showMessageDialog(Component parentComponent,
+                                       Object message, String title,
+                                       int messageType, Icon icon)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType);
+    pane.setIcon(icon);
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+  }
+
+  /**
+   * This method shows an option dialog with the given message, title,
+   * optionType, messageType, icon, options and initialValue. This method
+   * returns the option that was selected.
+   *
+   * @param parentComponent The component to find a frame in.
+   * @param message The message displayed.
+   * @param title The title of the dialog.
+   * @param optionType The optionType.
+   * @param messageType The messageType.
+   * @param icon The icon displayed.
+   * @param options The options to choose from.
+   * @param initialValue The initial value.
+   *
+   * @return The selected option.
+   */
+  public static int showOptionDialog(Component parentComponent,
+                                     Object message, String title,
+                                     int optionType, int messageType,
+                                     Icon icon, Object[] options,
+                                     Object initialValue)
+  {
+    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
+                                       options, initialValue);
+
+    JDialog dialog = pane.createDialog(parentComponent, title);
+    dialog.show();
+
+    if (pane.getValue() instanceof Integer)
+      return ((Integer) pane.getValue()).intValue();
+    return -1;
+  }
+
+  /**
+   * This method resets the UI to the Look and Feel default.
+   */
+  public void updateUI()
+  {
+    setUI((OptionPaneUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns true if the key is a valid messageType.
+   *
+   * @param key The key to check.
+   *
+   * @return True if key is valid.
+   */
+  private boolean validMessageType(int key)
+  {
+    switch (key)
+      {
+      case ERROR_MESSAGE:
+      case INFORMATION_MESSAGE:
+      case PLAIN_MESSAGE:
+      case QUESTION_MESSAGE:
+      case WARNING_MESSAGE:
+	return true;
+      }
+    return false;
+  }
+
+  /**
+   * This method returns true if the key is a valid optionType.
+   *
+   * @param key The key to check.
+   *
+   * @return True if key is valid.
+   */
+  private boolean validOptionType(int key)
+  {
+    switch (key)
+      {
+      case DEFAULT_OPTION:
+      case OK_CANCEL_OPTION:
+      case YES_NO_CANCEL_OPTION:
+      case YES_NO_OPTION:
+	return true;
+      }
+    return false;
+  }
+
+  /**
+   * This helper method makes the JInternalFrame wait until it is notified by
+   * an InternalFrameClosing event. This method also adds the given
+   * JOptionPane to the JInternalFrame and sizes it according to the
+   * JInternalFrame's preferred size.
+   *
+   * @param f The JInternalFrame to make modal.
+   */
+  private static void startModal(JInternalFrame f)
+  {
+    // We need to add an additional glasspane-like component directly
+    // below the frame, which intercepts all mouse events that are not
+    // directed at the frame itself.
+    JPanel modalInterceptor = new JPanel();
+    modalInterceptor.setOpaque(false);
+    JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f);
+    lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue());
+    modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight());
+    modalInterceptor.addMouseListener(new MouseAdapter(){});
+    modalInterceptor.addMouseMotionListener(new MouseMotionAdapter(){});
+    lp.add(modalInterceptor);
+    f.toFront();
+
+    // We need to explicitly dispatch events when we are blocking the event
+    // dispatch thread.
+    EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
+    try
+      {
+        while (! f.isClosed())
+          {
+            if (EventQueue.isDispatchThread())
+              {
+                // The getNextEventMethod() issues wait() when no
+                // event is available, so we don't need do explicitly wait().
+                AWTEvent ev = queue.getNextEvent();
+                // This mimics EventQueue.dispatchEvent(). We can't use
+                // EventQueue.dispatchEvent() directly, because it is
+                // protected, unfortunately.
+                if (ev instanceof ActiveEvent)
+                  ((ActiveEvent) ev).dispatch();
+                else if (ev.getSource() instanceof Component)
+                  ((Component) ev.getSource()).dispatchEvent(ev);
+                else if (ev.getSource() instanceof MenuComponent)
+                  ((MenuComponent) ev.getSource()).dispatchEvent(ev);
+                // Other events are ignored as per spec in
+                // EventQueue.dispatchEvent
+              }
+            else
+              {
+                // Give other threads a chance to become active.
+                Thread.yield();
+              }
+          }
+      }
+    catch (InterruptedException ex)
+      {
+        // If we get interrupted, then leave the modal state.
+      }
+    finally
+      {
+        // Clean up the modal interceptor.
+        lp.remove(modalInterceptor);
+
+        // Remove the internal frame from its parent, so it is no longer
+        // lurking around and clogging memory.
+        Container parent = f.getParent();
+        if (parent != null)
+          parent.remove(f);
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPanel.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPanel.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPanel.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPanel.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,203 @@
+/* JPanel.java --
+   Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.FlowLayout;
+import java.awt.LayoutManager;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.PanelUI;
+
+/**
+ * An instance of JPanel can be added to a panel, frame etc
+ *
+ * @author Ronald Veldema (rveldema at cs.vu.nl)
+ */
+public class JPanel extends JComponent implements Accessible
+{
+  /**
+   * Provides accessibility support for <code>JPanel</code>.
+   *
+   * @author Roman Kennke (roman at kennke.org)
+   */
+  protected class AccessibleJPanel extends AccessibleJComponent
+  {
+    /**
+     * Creates a new instance of <code>AccessibleJPanel</code>.
+     */
+    protected AccessibleJPanel()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns the accessible role for <code>JPanel</code>, which is
+     * {@link AccessibleRole#PANEL}.
+     *
+     * @return the accessible role for <code>JPanel</code>
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PANEL;
+    }
+  }
+
+  /**
+   * Creates a new panel with a new instance of {@link FlowLayout} as the
+   * layout manager and double-buffering enabled.
+   */
+  public JPanel()
+  {
+    this(new FlowLayout(), true);
+  }
+
+  /**
+   * Creates a new panel with double-buffering enabled or disabled as
+   * specified.  The default layout manager is an instance of 
+   * {@link FlowLayout}.
+   * 
+   * @param isDoubleBuffered  a flag that controls whether or not 
+   *     double-buffering is enabled.
+   */
+  public JPanel(boolean isDoubleBuffered)
+  {
+    this(new FlowLayout(), isDoubleBuffered);
+  }
+
+  /**
+   * Creates a new panel with the specified layout manager.  Double-buffering
+   * is enabled by default.
+   * 
+   * @param layout  the layout manager (<code>null</code> permitted).
+   */
+  public JPanel(LayoutManager layout)
+  {
+    this(layout, true);
+  }
+
+  /**
+   * Creates a new panel with the specified layout manager and 
+   * double-buffering.
+   * 
+   * @param layout  the layout manager (<code>null</code> permitted).
+   * @param isDoubleBuffered  a flag that controls whether or not 
+   *     double-buffering is enabled.
+   */
+  public JPanel(LayoutManager layout, boolean isDoubleBuffered)
+  {
+    setLayout(layout); 
+    setOpaque(true);
+    setDoubleBuffered(isDoubleBuffered);
+    updateUI();	
+  } 
+
+  /**
+   * Returns the suffix (<code>"PanelUI"</code> in this case) used to 
+   * determine the class name for a UI delegate that can provide the look and 
+   * feel for a <code>JPanel</code>.
+   *
+   * @return <code>"PanelUI"</code>.
+   */
+  public String getUIClassID()
+  {
+    return "PanelUI";
+  }
+
+  /**
+   * Sets the UI delegate for the <code>JPanel</code> component.
+   * 
+   * @param ui  the UI delegate.
+   * 
+   * @since 1.4
+   * @see #getUI()
+   */
+  public void setUI(PanelUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Returns the UI delegate for the <code>JPanel</code> component.
+   * 
+   * @return The UI delegate.
+   * 
+   * @since 1.4
+   * @see #setUI(PanelUI)
+   */
+  public PanelUI getUI()
+  {
+    return (PanelUI) ui;
+  }
+
+  /**
+   * Sets this panel's UI delegate to the default (obtained from the
+   * {@link UIManager}) for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((PanelUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JPanel</code> component.
+   *
+   * @return The accessible context (an instance of {@link AccessibleJPanel}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJPanel();
+    return accessibleContext;
+  }
+    
+  /**
+   * Returns an implementation-dependent string describing the attributes of
+   * this <code>JPanel</code>.
+   *
+   * @return A string describing the attributes of this <code>JPanel</code>
+   *         (never <code>null</code>).
+   */
+  protected String paramString()
+  {
+	return super.paramString();
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPasswordField.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPasswordField.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPasswordField.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPasswordField.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,297 @@
+/* JPasswordField.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+
+/**
+ * class JPasswordField
+ * 
+ * @author Andrew Selkirk
+ * @author Lillian Angel
+ * @version 1.0
+ */
+public class JPasswordField extends JTextField
+{
+  /**
+   * AccessibleJPasswordField
+   */
+  protected class AccessibleJPasswordField extends AccessibleJTextField
+  {
+    private static final long serialVersionUID = -8477039424200681086L;
+
+    /**
+     * Constructor AccessibleJPasswordField
+     */
+    protected AccessibleJPasswordField()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * getAccessibleRole
+     * 
+     * @return AccessibleRole
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PASSWORD_TEXT;
+    }
+  }
+
+  /**
+   * echoChar.  Default is 0.
+   */
+  private char echoChar = 0;
+
+  /**
+   * Creates a <code>JPasswordField</code> object.
+   */
+  public JPasswordField()
+  {
+    this(null, null, 0);
+  }
+
+  /**
+   * Creates a <code>JPasswordField</code> object.
+   * 
+   * @param text the initial text
+   */
+  public JPasswordField(String text)
+  {
+    this(null, text, 0);
+  }
+
+  /**
+   * Creates a <code>JPasswordField</code> object.
+   * 
+   * @param columns the number of columns
+   */
+  public JPasswordField(int columns)
+  {
+    this(null, null, columns);
+  }
+
+  /**
+   * Creates a <code>JPasswordField</code> object.
+   * 
+   * @param text the initial text
+   * @param columns the number of columns
+   */
+  public JPasswordField(String text, int columns)
+  {
+    this(null, text, columns);
+  }
+
+  /**
+   * Creates a <code>JPasswordField</code> object.
+   * 
+   * @param document the document to use
+   * @param text the initial text
+   * @param columns the number of columns
+   */
+  public JPasswordField(Document document, String text, int columns)
+  {
+    super(document, text, columns);
+  }
+
+  /**
+   * writeObject
+   * 
+   * @param stream the stream to write to
+   * 
+   * @exception IOException if an error occurs
+   */
+  private void writeObject(ObjectOutputStream stream) throws IOException
+  {
+    // TODO: Implement me.
+  }
+
+  /**
+   * Returns the <code>UIClassID</code>
+   * 
+   * @return the string "PasswordFieldUI"
+   */
+  public String getUIClassID()
+  {
+    return "PasswordFieldUI";
+  }
+
+  /**
+   * getEchoChar
+   * 
+   * @return the echo char
+   */
+  public char getEchoChar()
+  {
+    return echoChar;
+  }
+
+  /**
+   * setEchoChar
+   * 
+   * @param echo the echo char
+   */
+  public void setEchoChar(char echo)
+  {
+    this.echoChar = echo;
+  }
+
+  /**
+   * Returns true if this JPasswordField has a character set for echoing. 
+   * A character is considered to be set if the echo character is not 0.
+   * 
+   * @return <code>true</code> if the echo char is set,
+   * <code>false</code> otherwise.
+   */
+  public boolean echoCharIsSet()
+  {
+    return echoChar != 0;
+  }
+
+  /**
+   * Copies the selected text into the clipboard. This operation is not
+   * allowed in a password input field.
+   */
+  public void copy()
+  {
+    UIManager.getLookAndFeel().provideErrorFeedback(this);
+  }
+
+  /**
+   * Cuts the selected text and puts it into the clipboard. This operation
+   * is not allowed in a password input field.
+   */
+  public void cut()
+  {
+    UIManager.getLookAndFeel().provideErrorFeedback(this);
+  }
+
+  /**
+   * Returns the text contained in this TextComponent. If the 
+   * underlying document is null, will give a NullPointerException.
+   * 
+   * @return String
+   * 
+   * @deprecated
+   */
+  public String getText()
+  {
+    try
+      {
+        return getDocument().getText(0, getDocument().getLength());
+      }
+    catch (BadLocationException ble)
+      {
+        // This should never happen.
+        throw new AssertionError(ble);
+      }
+  }
+
+  /**
+   * Fetches a portion of the text represented by the component. 
+   * Returns an empty string if length is 0. If the 
+   * underlying document is null, will give a NullPointerException.
+   * 
+   * @param offset TODO
+   * @param length TODO
+   * 
+   * @return String
+   * 
+   * @exception BadLocationException TODO
+   *
+   * @deprecated
+   */
+  public String getText(int offset, int length) throws BadLocationException
+  {
+    return getDocument().getText(offset, length);
+  }
+
+  /**
+   * Returns the text contained in this TextComponent. If the underlying 
+   * document is null, will give a NullPointerException. 
+   * For stronger security, it is recommended that the returned character 
+   * array be cleared after use by setting each character to zero.
+   * 
+   * @return char[]
+   */
+  public char[] getPassword()
+  {
+    return getText().toCharArray();
+  }
+
+  /**
+   * Returns a string representation of this JPasswordField. This method is 
+   * intended to be used only for debugging purposes, 
+   * and the content and format of the returned string may vary between 
+   * implementations. The returned string may be empty but may not be null.
+   * 
+   * @return String
+   */
+  protected String paramString()
+  {
+    try
+      {
+        return getText();
+      }
+    catch (NullPointerException npe)
+      {
+        return "";
+      }
+  }
+
+  /**
+   * getAccessibleContext
+   * 
+   * @return the <code>AccessibleContext</code> object
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJPasswordField();
+
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPopupMenu.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPopupMenu.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPopupMenu.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JPopupMenu.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,924 @@
+/* JPopupMenu.java --
+   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.EventListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.plaf.PopupMenuUI;
+
+/**
+ * JPopupMenu is a container that is used to display popup menu's menu
+ * items. By default JPopupMenu is a lightweight container, however if it
+ * is the case that JPopupMenu's bounds are outside of main window, then
+ * heawyweight container will be used to display menu items. It is also
+ * possible to change JPopupMenu's default  behavior and set JPopupMenu
+ * to always use heavyweight container.
+ *
+ * JPopupMenu can be displayed anywhere; it is a floating free popup menu.
+ * However before JPopupMenu is diplayed, its invoker property should be set.
+ * JPopupMenu's invoker is a component relative to which popup menu is
+ * displayed.
+ *
+ * JPopupMenu fires PopupMenuEvents to its registered listeners. Whenever
+ * JPopupMenu becomes visible on the screen then PopupMenuEvent indicating
+ * that popup menu became visible will be fired. In the case when
+ * JPopupMenu becomes invisible or cancelled without selection, then
+ * popupMenuBecomeInvisible() or popupMenuCancelled() methods of
+ * PopupMenuListeners will be invoked.
+ *
+ * JPopupMenu also fires PropertyChangeEvents when its bound properties 
+ * change.In addittion to inheritted bound properties, JPopupMenu has 
+ * 'visible' bound property. When JPopupMenu becomes visible/invisible on
+ * the screen it fires PropertyChangeEvents to its registered 
+ * PropertyChangeListeners.
+ */
+public class JPopupMenu extends JComponent implements Accessible, MenuElement
+{
+  private static final long serialVersionUID = -8336996630009646009L;
+
+  /* indicates if popup's menu border should be painted*/
+  private boolean borderPainted = true;
+
+  /** Flag indicating whether lightweight, mediumweight or heavyweight popup
+     is used to display menu items.
+
+     These are the possible cases:
+
+     1. if DefaultLightWeightPopupEnabled true
+         (i)  use lightweight container if popup feets inside top-level window
+         (ii) only use heavyweight container (JDialog) if popup doesn't fit.
+
+     2. if DefaultLightWeightPopupEnabled false
+         (i) if popup fits, use awt.Panel (mediumWeight)
+         (ii) if popup doesn't fit, use JDialog (heavyWeight)
+  */
+  private static boolean DefaultLightWeightPopupEnabled = true;
+
+  /* Component that invokes popup menu. */
+  transient Component invoker;
+
+  /* Label for this popup menu. It is not used in most of the look and feel themes. */
+  private String label;
+
+  /*Amount of space between menuItem's in JPopupMenu and JPopupMenu's border */
+  private Insets margin;
+
+  /** Indicates whether ligthWeight container can be used to display popup
+     menu. This flag is the same as DefaultLightWeightPopupEnabled, but setting
+     this flag can change popup menu after creation of the object */
+  private boolean lightWeightPopupEnabled;
+
+  /** SelectionModel that keeps track of menu selection. */
+  protected SingleSelectionModel selectionModel;
+
+  /* Popup that is used to display JPopupMenu */
+  private transient Popup popup;
+
+  /**
+   * Location of the popup, X coordinate.
+   */
+  private int popupLocationX;
+
+  /**
+   * Location of the popup, Y coordinate.
+   */
+  private int popupLocationY;
+
+  /* Field indicating if popup menu is visible or not */
+  private boolean visible = false;
+  
+  /**
+   * Creates a new JPopupMenu object.
+   */
+  public JPopupMenu()
+  {
+    this(null);
+  }
+
+  /**
+   * Creates a new JPopupMenu with specified label
+   *
+   * @param label Label for popup menu.
+   */
+  public JPopupMenu(String label)
+  {
+    lightWeightPopupEnabled = getDefaultLightWeightPopupEnabled();
+    setLabel(label);
+    setSelectionModel(new DefaultSingleSelectionModel());
+    super.setVisible(false);
+    updateUI();
+  }
+
+  /**
+  * Adds given menu item to the popup menu
+  *
+  * @param item menu item to add to the popup menu
+  *
+  * @return menu item that was added to the popup menu
+  */
+  public JMenuItem add(JMenuItem item)
+  {
+    this.insert(item, -1);
+    return item;
+  }
+
+  /**
+   * Constructs menu item with a specified label and adds it to
+   * popup menu
+   *
+   * @param text label for the menu item to be added
+   *
+   * @return constructed menu item that was added to the popup menu
+   */
+  public JMenuItem add(String text)
+  {
+    JMenuItem item = new JMenuItem(text);
+    return add(item);
+  }
+
+  /**
+   * Constructs menu item associated with the specified action
+   * and adds it to the popup menu
+   *
+   * @param action Action for the new menu item
+   *
+   * @return menu item that was added to the menu
+   */
+  public JMenuItem add(Action action)
+  {
+    JMenuItem item = createActionComponent(action);
+
+    if (action != null)
+      action.addPropertyChangeListener(createActionChangeListener(item));
+
+    return add(item);
+  }
+
+  /**
+   * Revomes component at the given index from the menu.
+   *
+   * @param index index of the component that will be removed in the menu
+   */
+  public void remove(int index)
+  {
+    super.remove(index);
+    revalidate();
+  }
+
+  /**
+   * Create menu item associated with the given action
+   * and inserts it into the popup menu at the specified index
+   *
+   * @param action Action for the new menu item
+   * @param index index in the popup menu at which to insert new menu item.
+   */
+  public void insert(Action action, int index)
+  {
+    JMenuItem item = new JMenuItem(action);
+    this.insert(item, index);
+  }
+
+  /**
+   * Insert given component to the popup menu at the
+   * specified index
+   *
+   * @param component Component to insert
+   * @param index Index at which to insert given component
+   */
+  public void insert(Component component, int index)
+  {
+    super.add(component, index);
+  }
+
+  /**
+   * Returns flag indicating if newly created JPopupMenu will use
+   * heavyweight or lightweight container to display its menu items
+   *
+   * @return true if JPopupMenu will use lightweight container to display
+   * menu items by default, and false otherwise.
+   */
+  public static boolean getDefaultLightWeightPopupEnabled()
+  {
+    return DefaultLightWeightPopupEnabled;
+  }
+
+  /**
+   * Sets whether JPopupMenu should use ligthWeight container to
+   * display it menu items by default
+   *
+   * @param enabled true if JPopupMenu should use lightweight container
+   * for displaying its menu items, and false otherwise.
+   */
+  public static void setDefaultLightWeightPopupEnabled(boolean enabled)
+  {
+    DefaultLightWeightPopupEnabled = enabled;
+  }
+
+  /**
+   * This method returns the UI used to display the JPopupMenu.
+   *
+   * @return The UI used to display the JPopupMenu.
+   */
+  public PopupMenuUI getUI()
+  {
+    return (PopupMenuUI) ui;
+  }
+
+  /**
+   * Set the "UI" property of the menu item, which is a look and feel class
+   * responsible for handling popupMenu's input events and painting it.
+   *
+   * @param ui The new "UI" property
+   */
+  public void setUI(PopupMenuUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets this menuItem's UI to the UIManager's default for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((PopupMenuUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menuItem.
+   *
+   * @return The Look and Feel classID. "PopupMenuUI"
+   */
+  public String getUIClassID()
+  {
+    return "PopupMenuUI";
+  }
+
+  /**
+   * Returns selectionModel used by this popup menu to keep
+   * track of the selection.
+   *
+   * @return popup menu's selection model
+   */
+  public SingleSelectionModel getSelectionModel()
+  {
+    return selectionModel;
+  }
+
+  /**
+   * Sets selection model for this popup menu
+   *
+   * @param model new selection model of this popup menu
+   */
+  public void setSelectionModel(SingleSelectionModel model)
+  {
+	selectionModel = model;
+  }
+
+  /**
+   * Creates new menu item associated with a given action.
+   *
+   * @param action Action used to create new menu item
+   *
+   * @return new created menu item associated with a given action.
+   */
+  protected JMenuItem createActionComponent(Action action)
+  {
+    return new JMenuItem(action);
+  }
+
+  /**
+   * Creates PropertyChangeListener that listens to PropertyChangeEvents
+   * occuring in the Action associated with given menu item in this popup menu.
+   *
+   * @param item MenuItem
+   *
+   * @return The PropertyChangeListener
+   */
+  protected PropertyChangeListener createActionChangeListener(JMenuItem item)
+  {
+    return new ActionChangeListener();
+  }
+
+  /**
+   * Returns true if this popup menu will display its menu item in
+   * a lightweight container and false otherwise.
+   *
+   * @return true if this popup menu will display its menu items
+   * in a lightweight container and false otherwise.
+   */
+  public boolean isLightWeightPopupEnabled()
+  {
+    return lightWeightPopupEnabled;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param enabled DOCUMENT ME!
+   */
+  public void setLightWeightPopupEnabled(boolean enabled)
+  {
+    lightWeightPopupEnabled = enabled;
+  }
+
+  /**
+   * Returns label for this popup menu
+   *
+   * @return label for this popup menu
+   */
+  public String getLabel()
+  {
+    return label;
+  }
+
+  /**
+   * Sets label for this popup menu. This method fires PropertyChangeEvent
+   * when the label property is changed. Please note that most
+   * of the Look & Feel will ignore this property.
+   *
+   * @param label label for this popup menu
+   */
+  public void setLabel(String label)
+  {
+    if (label != this.label)
+      {
+	String oldLabel = this.label;
+	this.label = label;
+	firePropertyChange("label", oldLabel, label);
+      }
+  }
+
+  /**
+   * Adds separator to this popup menu
+   */
+  public void addSeparator()
+  {
+    // insert separator at the end of the list of menu items    
+    this.insert(new Separator(), -1);
+  }
+
+  /**
+   * Adds a MenuKeyListener to the popup.
+   * 
+   * @param l - the listener to add.
+   */
+  public void addMenuKeyListener(MenuKeyListener l)
+  {
+    listenerList.add(MenuKeyListener.class, l);
+  }
+  
+  /**
+   * Removes a MenuKeyListener from the popup.
+   * 
+   * @param l - the listener to remove.
+   */
+  public void removeMenuKeyListener(MenuKeyListener l)
+  {
+    listenerList.remove(MenuKeyListener.class, l);
+  }
+  
+  /**
+   * Returns array of getMenuKeyListeners that are listening to JPopupMenu.
+   * 
+   * @return array of getMenuKeyListeners that are listening to JPopupMenu
+   */
+  public MenuKeyListener[] getMenuKeyListeners()
+  {
+    return ((MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class));
+  }
+  
+  /**
+   * Adds popupMenuListener to listen for PopupMenuEvents fired
+   * by the JPopupMenu
+   *
+   * @param listener PopupMenuListener to add to JPopupMenu
+   */
+  public void addPopupMenuListener(PopupMenuListener listener)
+  {
+    listenerList.add(PopupMenuListener.class, listener);
+  }
+
+  /**
+   * Removes PopupMenuListener from JPopupMenu's list of listeners
+   *
+   * @param listener PopupMenuListener which needs to be removed
+   */
+  public void removePopupMenuListener(PopupMenuListener listener)
+  {
+    listenerList.remove(PopupMenuListener.class, listener);
+  }
+
+  /**
+   * Returns array of PopupMenuListeners that are listening to JPopupMenu
+   *
+   * @return Array of PopupMenuListeners that are listening to JPopupMenu
+   */
+  public PopupMenuListener[] getPopupMenuListeners()
+  {
+    return ((PopupMenuListener[]) listenerList.getListeners(PopupMenuListener.class));
+  }
+
+  /**
+   * This method calls popupMenuWillBecomeVisible() of popup menu's
+   * PopupMenuListeners. This method is invoked just before popup menu
+   * will appear on the screen.
+   */
+  protected void firePopupMenuWillBecomeVisible()
+  {
+    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((PopupMenuListener) ll[i]).popupMenuWillBecomeVisible(new PopupMenuEvent(this));
+  }
+
+  /**
+   * This method calls popupMenuWillBecomeInvisible() of popup
+   * menu's PopupMenuListeners. This method is invoked just before popup
+   * menu will disappear from the screen
+   */
+  protected void firePopupMenuWillBecomeInvisible()
+  {
+    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((PopupMenuListener) ll[i]).popupMenuWillBecomeInvisible(new PopupMenuEvent(this));
+  }
+
+  /**
+   * This method calls popupMenuCanceled() of popup menu's PopupMenuListeners.
+   * This method is invoked just before popup menu is cancelled. This happens
+   * when popup menu is closed without selecting any of its menu items. This
+   * usually happens when the top-level window is resized or moved.
+   */
+  protected void firePopupMenuCanceled()
+  {
+    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);
+
+    for (int i = 0; i < ll.length; i++)
+      ((PopupMenuListener) ll[i]).popupMenuCanceled(new PopupMenuEvent(this));
+  }
+
+  /**
+   * This methods sets popup menu's size to its' preferred size. If the
+   * popup menu's size is previously set it will be ignored.
+   */
+  public void pack()
+  {
+    // Hook up this call so that it gets executed on the event thread in order
+    // to avoid synchronization problems when calling the layout manager.
+    if (! SwingUtilities.isEventDispatchThread())
+      {
+        SwingUtilities.invokeLater(new Runnable()
+          {
+            public void run()
+            {
+              show();
+            }
+          });
+      }
+
+    setSize(getPreferredSize());
+  }
+
+  /**
+   * Return visibility of the popup menu
+   *
+   * @return true if popup menu is visible on the screen and false otherwise.
+   */
+  public boolean isVisible()
+  {
+    return visible;
+  }
+
+  /**
+   * Sets visibility property of this popup menu. If the property is
+   * set to true then popup menu will be dispayed and popup menu will
+   * hide itself if visible property is set to false.
+   *
+   * @param visible true if popup menu will become visible and false otherwise.
+   */
+  public void setVisible(final boolean visible)
+  {
+    // Hook up this call so that it gets executed on the event thread in order
+    // to avoid synchronization problems when calling the layout manager.
+    if (! SwingUtilities.isEventDispatchThread())
+      {
+        SwingUtilities.invokeLater(new Runnable()
+          {
+            public void run()
+            {
+              setVisible(visible);
+            }
+          });
+      }
+
+    if (visible == isVisible())
+      return;
+
+    boolean old = isVisible();
+    this.visible = visible;
+    if (old != isVisible())
+      {
+        if (visible)
+          {
+            if (invoker != null && !(invoker instanceof JMenu))
+              {
+                MenuElement[] menuEls;
+                if (getSubElements().length > 0)
+                  {
+                    menuEls = new MenuElement[2];
+                    menuEls[0] = this;
+                    menuEls[1] = getSubElements()[0];
+                }
+                else
+                  {
+                    menuEls = new MenuElement[1];
+                    menuEls[0] = this;
+                  }
+                MenuSelectionManager.defaultManager().setSelectedPath(menuEls);
+              }
+            firePopupMenuWillBecomeVisible();
+            PopupFactory pf = PopupFactory.getSharedInstance();
+            pack();
+            popup = pf.getPopup(invoker, this, popupLocationX, popupLocationY);
+            popup.show();
+          }
+        else
+          {
+            getSelectionModel().clearSelection();
+            firePopupMenuWillBecomeInvisible();
+            popup.hide();
+          }
+        firePropertyChange("visible", old, isVisible());
+      }
+  }
+
+  /**
+   * Sets location of the popup menu.
+   *
+   * @param x X coordinate of the popup menu's location
+   * @param y Y coordinate of the popup menu's location
+   */
+  public void setLocation(int x, int y)
+  {
+    popupLocationX = x;
+    popupLocationY = y;
+    // Handle the case when the popup is already showing. In this case we need
+    // to fetch a new popup from PopupFactory and use this. See the general
+    // contract of the PopupFactory.
+  }
+
+  /**
+   * Returns popup menu's invoker.
+   *
+   * @return popup menu's invoker
+   */
+  public Component getInvoker()
+  {
+    return invoker;
+  }
+
+  /**
+   * Sets popup menu's invoker.
+   *
+   * @param component The new invoker of this popup menu
+   */
+  public void setInvoker(Component component)
+  {
+    invoker = component;
+  }
+
+  /**
+   * This method displays JPopupMenu on the screen at the specified
+   * location. Note that x and y coordinates given to this method
+   * should be expressed in terms of the popup menus' invoker.
+   *
+   * @param component Invoker for this popup menu
+   * @param x x-coordinate of the popup menu relative to the specified invoker
+   * @param y y-coordiate of the popup menu relative to the specified invoker
+   */
+  public void show(Component component, int x, int y)
+  {
+    if (component.isShowing())
+      {
+        setInvoker(component);
+        Point p = new Point(x, y);
+        SwingUtilities.convertPointToScreen(p, component);
+        setLocation(p.x, p.y);
+        setVisible(true);
+      }
+  }
+
+  /**
+   * Returns component located at the specified index in the popup menu
+   *
+   * @param index index of the component to return
+   *
+   * @return component located at the specified index in the popup menu
+   *
+   * @deprecated Replaced by getComponent(int)
+   */
+  public Component getComponentAtIndex(int index)
+  {
+    return getComponent(index);
+  }
+
+  /**
+   * Returns index of the specified component in the popup menu
+   *
+   * @param component Component to look for
+   *
+   * @return index of the specified component in the popup menu
+   */
+  public int getComponentIndex(Component component)
+  {
+    Component[] items = getComponents();
+
+    for (int i = 0; i < items.length; i++)
+      {
+	if (items[i].equals(component))
+	  return i;
+      }
+
+    return -1;
+  }
+
+  /**
+   * Sets size of the popup
+   *
+   * @param size Dimensions representing new size of the popup menu
+   */
+  public void setPopupSize(Dimension size)
+  {
+    super.setSize(size);
+  }
+
+  /**
+   * Sets size of the popup menu
+   *
+   * @param width width for the new size
+   * @param height height for the new size
+   */
+  public void setPopupSize(int width, int height)
+  {
+    super.setSize(width, height);
+  }
+
+  /**
+   * Selects specified component in this popup menu.
+   *
+   * @param selected component to select
+   */
+  public void setSelected(Component selected)
+  {
+    int index = getComponentIndex(selected);
+    selectionModel.setSelectedIndex(index);
+  }
+
+  /**
+   * Checks if this popup menu paints its border.
+   *
+   * @return true if this popup menu paints its border and false otherwise.
+   */
+  public boolean isBorderPainted()
+  {
+    return borderPainted;
+  }
+
+  /**
+   * Sets if the border of the popup menu should be
+   * painter or not.
+   *
+   * @param painted true if the border should be painted and false otherwise
+   */
+  public void setBorderPainted(boolean painted)
+  {
+    borderPainted = painted;
+  }
+
+  /**
+   * Returns margin for this popup menu.
+   *
+   * @return margin for this popup menu.
+   */
+  public Insets getMargin()
+  {
+    return margin;
+  }
+
+  /**
+   * A string that describes this JPopupMenu. Normally only used
+   * for debugging.
+   *
+   * @return A string describing this JMenuItem
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer();
+    sb.append(super.paramString());
+    sb.append(",label=");
+    if (getLabel() != null)
+      sb.append(getLabel());
+    sb.append(",lightWeightPopupEnabled=").append(isLightWeightPopupEnabled());
+    sb.append(",margin=");
+    if (getMargin() != null)
+      sb.append(margin);
+    sb.append(",paintBorder=").append(isBorderPainted());
+    return sb.toString();
+  }
+
+  /**
+  * Process mouse events forwarded from MenuSelectionManager. This method 
+  * doesn't do anything. It is here to conform to the MenuElement interface.
+  *
+  * @param event event forwarded from MenuSelectionManager
+  * @param path path to the menu element from which event was generated
+  * @param manager MenuSelectionManager for the current menu hierarchy
+  */
+  public void processMouseEvent(MouseEvent event, MenuElement[] path,
+                                MenuSelectionManager manager)
+  {
+    // Empty Implementation. This method is needed for the implementation
+    // of MenuElement interface
+  }
+
+  /**
+   * Process key events forwarded from MenuSelectionManager. This method
+   * doesn't do anything. It is here to conform to the MenuElement interface.
+   *
+   * @param event event forwarded from MenuSelectionManager
+   * @param path path to the menu element from which event was generated
+   * @param manager MenuSelectionManager for the current menu hierarchy
+   *
+   */
+  public void processKeyEvent(KeyEvent event, MenuElement[] path,
+                              MenuSelectionManager manager)
+  {
+    // Empty Implementation. This method is needed for the implementation
+    // of MenuElement interface
+  }
+
+  /**
+   * Method of MenuElement Interface. It is invoked when
+   * popupMenu's selection has changed
+   *
+   * @param changed true if this popupMenu is part of current menu
+   * hierarchy and false otherwise.
+   */
+  public void menuSelectionChanged(boolean changed)
+  {
+    if (! changed)
+      setVisible(false);
+  }
+
+  /**
+   * Return subcomonents of this popup menu. This method returns only
+   * components that implement the <code>MenuElement</code> interface.
+   *
+   * @return array of menu items belonging to this popup menu
+   */
+  public MenuElement[] getSubElements()
+  {
+    Component[] items = getComponents();
+    ArrayList subElements = new ArrayList();
+
+    for (int i = 0; i < items.length; i++)
+      if (items[i] instanceof MenuElement)
+	subElements.add(items[i]);
+
+    return (MenuElement[])
+      subElements.toArray(new MenuElement[subElements.size()]);
+  }
+
+  /**
+   * Method of the MenuElement interface. Returns reference to itself.
+   *
+   * @return Returns reference to itself
+   */
+  public Component getComponent()
+  {
+    return this;
+  }
+
+  /**
+   * Checks if observing mouse event should trigger popup
+   * menu to show on the screen.
+   *
+   * @param event MouseEvent to check
+   *
+   * @return true if the observing mouse event is popup trigger and false otherwise
+   */
+  public boolean isPopupTrigger(MouseEvent event)
+  {
+    return ((PopupMenuUI) getUI()).isPopupTrigger(event);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJPopupMenu();
+
+    return accessibleContext;
+  }
+
+  /**
+   * This is the separator that can be used in popup menu.
+   */
+  public static class Separator extends JSeparator
+  {
+    public Separator()
+    {
+      super();
+    }
+
+    public String getUIClassID()
+    {
+      return "PopupMenuSeparatorUI";
+    }
+  }
+
+  protected class AccessibleJPopupMenu extends AccessibleJComponent
+  {
+    private static final long serialVersionUID = 7423261328879849768L;
+
+    protected AccessibleJPopupMenu()
+    {
+      // Nothing to do here.
+    }
+
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.POPUP_MENU;
+    }
+  }
+
+  /* This class resizes popup menu and repaints popup menu appropriately if one
+   of item's action has changed */
+  private class ActionChangeListener implements PropertyChangeListener
+  {
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      // We used to have a revalidate() and repaint() call here. However I think
+      // this is not needed. Instead, a new Popup has to be fetched from the
+      // PopupFactory and used here.
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JProgressBar.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JProgressBar.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JProgressBar.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JProgressBar.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,859 @@
+/* JProgressBar.java --
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Graphics;
+import java.beans.PropertyChangeEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+import javax.swing.border.Border;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ProgressBarUI;
+
+/**
+ * A component that displays a visual indicator of the progress of a task. The
+ * component has two modes: determinate and indeterminate.  In determinate mode,
+ * the <code>JProgressBar</code> fills a percentage of its bar based on its 
+ * current value. In indeterminate mode, it creates box and bounces it between 
+ * its bounds.
+ * <p>
+ * This component has the following properties:
+ * </p>
+ * <table>
+ * <tr><th> Property         </th><th> Stored in   </th><th> Bound? </th></tr>
+ * <tr><td> borderPainted    </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> changeListeners  </td><td> progressBar </td><td> no     </td></tr>
+ * <tr><td> indeterminate    </td><td> progressBar </td><td> yes    </td></tr> 
+ * <tr><td> maximum          </td><td> model       </td><td> no     </td></tr>
+ * <tr><td> minimum          </td><td> model       </td><td> no     </td></tr>
+ * <tr><td> model            </td><td> progressBar </td><td> no     </td></tr> 
+ * <tr><td> orientation      </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> percentComplete  </td><td> progressBar </td><td> no     </td></tr>
+ * <tr><td> string           </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> stringPainted    </td><td> progressBar </td><td> yes    </td></tr>
+ * <tr><td> value            </td><td> model       </td><td> no     </td></tr>
+ * </table>
+ */
+public class JProgressBar extends JComponent implements SwingConstants,
+                                                        Accessible
+{
+  /**
+   * Provides the accessibility features for the <code>JProgressBar</code>
+   * component.
+   */
+  protected class AccessibleJProgressBar extends AccessibleJComponent
+    implements AccessibleValue
+  {
+    private static final long serialVersionUID = -2938130009392721813L;
+  
+    /**
+     * Creates a new <code>AccessibleJProgressBar</code> instance.
+     */
+    protected AccessibleJProgressBar()
+    {
+      // Nothing to do here.
+    } 
+
+    /**
+     * Returns a set containing the current state of the {@link JProgressBar} 
+     * component.
+     *
+     * @return The accessible state set.
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleStateSet result = super.getAccessibleStateSet();
+      if (orientation == JProgressBar.HORIZONTAL)
+        result.add(AccessibleState.HORIZONTAL);
+      else if (orientation == JProgressBar.VERTICAL)
+        result.add(AccessibleState.VERTICAL);
+      return result;
+    } 
+
+    /**
+     * Returns the accessible role for the <code>JProgressBar</code> component.
+     *
+     * @return {@link AccessibleRole#PROGRESS_BAR}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PROGRESS_BAR;
+    } 
+
+    /**
+     * Returns an object that provides access to the current, minimum and 
+     * maximum values.
+     *
+     * @return The accessible value.
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return this;
+    } 
+
+    /**
+     * Returns the current value of the {@link JProgressBar} component, as an
+     * {@link Integer}.
+     *
+     * @return The current value of the {@link JProgressBar} component.
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return new Integer(getValue());
+    }
+
+    /**
+     * Sets the current value of the {@link JProgressBar} component and sends a
+     * {@link PropertyChangeEvent} (with the property name 
+     * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
+     * listeners.  If the supplied value is <code>null</code>, this method 
+     * does nothing and returns <code>false</code>.
+     *
+     * @param value  the new progress bar value (<code>null</code> permitted).
+     *
+     * @return <code>true</code> if the slider value is updated, and 
+     *     <code>false</code> otherwise.
+     */
+    public boolean setCurrentAccessibleValue(Number value)
+    {
+      if (value == null)
+        return false;
+      Number oldValue = getCurrentAccessibleValue();
+      setValue(value.intValue());
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, 
+                         new Integer(getValue()));
+      return true;
+    }
+
+    /**
+     * Returns the minimum value of the {@link JProgressBar} component, as an
+     * {@link Integer}.
+     *
+     * @return The minimum value of the {@link JProgressBar} component.
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return new Integer(getMinimum());
+    }
+
+    /**
+     * Returns the maximum value of the {@link JProgressBar} component, as an
+     * {@link Integer}.
+     *
+     * @return The maximum value of the {@link JProgressBar} component.
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return new Integer(getMaximum());
+    }
+  } 
+
+  private static final long serialVersionUID = 1980046021813598781L;
+  
+  /** 
+   * A flag that determines the mode (<code>true</code> for indeterminate, 
+   * <code>false</code> for determinate).
+   */
+  private transient boolean indeterminate = false;
+
+  /** 
+   * The orientation of the <code>JProgressBar</code> 
+   * ({@link SwingConstants#HORIZONTAL} or {@link SwingConstants#VERTICAL}). 
+   * Defaults to {@link SwingConstants#HORIZONTAL}.
+   * @see #setOrientation(int)
+   */
+  protected int orientation;
+
+  /** 
+   * A flag the controls whether or not the component's border is painted.
+   * The default is <code>true</code>. 
+   * @see #setBorderPainted(boolean)
+   */
+  protected boolean paintBorder = true;
+
+  /** 
+   * The model defining the bounds and current value for the progress bar.
+   * @see #setModel(BoundedRangeModel) 
+   */
+  protected BoundedRangeModel model;
+
+  /** 
+   * A custom string for display in the progress bar.  If this is 
+   * <code>null</code>, a default string will be generated. 
+   * @see #setString(String)
+   */
+  protected String progressString;
+
+  /** 
+   * A flag that controls whether a string is displayed within the progress 
+   * bar. 
+   * @see #setStringPainted(boolean)
+   */
+  protected boolean paintString = false;
+
+  /** 
+   * A single change event reused for all events.
+   * @see #fireStateChanged() 
+   */
+  protected transient ChangeEvent changeEvent;
+
+  /** 
+   * The listener that is registered with the model. */
+  protected ChangeListener changeListener;
+
+  /**
+   * Creates a new <code>JProgressBar</code> with default attributes.  The 
+   * following defaults are used:
+   * <p>
+   * <ul>
+   * <li><code>value</code>: 0;</li>
+   * <li><code>minimum</code>: 0;</li>
+   * <li><code>maximum</code>: 100;</li>
+   * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
+   * </ul>  
+   */
+  public JProgressBar()
+  {
+    this(HORIZONTAL, 0, 100);
+  }
+
+  /**
+   * Creates a new <code>JProgressBar</code> with the specified 
+   * <code>orientation</code>.  The following defaults are used:
+   * <p>
+   * <ul>
+   * <li><code>value</code>: 0;</li>
+   * <li><code>minimum</code>: 0;</li>
+   * <li><code>maximum</code>: 100;</li>
+   * </ul>  
+   * 
+   * @param orientation  the orientation ({@link #HORIZONTAL} or 
+   *     {@link #VERTICAL}).
+   * 
+   * @throws IllegalArgumentException if <code>orientation</code> is not one of
+   *     the specified values.
+   */
+  public JProgressBar(int orientation)
+  {
+    this(orientation, 0, 100);
+  }
+
+  /**
+   * Creates a new <code>JProgressBar</code> with the specified value range.
+   * The following defaults are used:
+   * <p>
+   * <ul>
+   * <li><code>value</code>: <code>minimum</code>;</li>
+   * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
+   * </ul>  
+   * 
+   * @param minimum  the lower bound of the value range.
+   * @param maximum  the upper bound of the value range.
+   */
+  public JProgressBar(int minimum, int maximum)
+  {
+    this(HORIZONTAL, minimum, maximum);
+  }
+
+  /**
+   * Creates a new <code>JProgressBar</code> with the specified range and
+   * orientation.  The following defaults are used:
+   * <p>
+   * <ul>
+   * <li><code>value</code>: <code>minimum</code>;</li>
+   * </ul>  
+   * 
+   * @param minimum  the lower bound of the value range.
+   * @param maximum  the upper bound of the value range.
+   * @param orientation  the orientation ({@link #HORIZONTAL} or 
+   *     {@link #VERTICAL}).
+   * 
+   * @throws IllegalArgumentException if <code>orientation</code> is not one of
+   *     the specified values.
+   */
+  public JProgressBar(int orientation, int minimum, int maximum)
+  {
+    model = new DefaultBoundedRangeModel(minimum, 0, minimum, maximum);
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a legal orientation");    
+    this.orientation = orientation;
+    changeListener = createChangeListener();
+    model.addChangeListener(changeListener);
+    updateUI();
+  }
+
+  /**
+   * Creates a new <code>JProgressBar</code> with the specified model.  The
+   * following defaults are used:
+   * <p>
+   * <ul>
+   * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
+   * </ul>  
+   * 
+   * @param model  the model (<code>null</code> not permitted).
+   */
+  public JProgressBar(BoundedRangeModel model)
+  {
+    this.model = model;
+    changeListener = createChangeListener();
+    if (model != null)
+      model.addChangeListener(changeListener);
+    updateUI();    
+  }
+
+  /**
+   * Returns the current value for the <code>JProgressBar</code>.  This value 
+   * is fetched from the model.
+   *
+   * @return The current value.
+   * 
+   * @see #setValue(int)
+   */
+  public int getValue()
+  {
+    return model.getValue();
+  }
+
+  /**
+   * Sets the current value for the <code>JProgressBar</code>.  The value is
+   * stored in the component's <code>model</code> (see {@link #getModel()}).  
+   * If the new value is different to the old value, a {@link ChangeEvent} is 
+   * sent to the model's registered listeners.  In turn, this triggers a call 
+   * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> 
+   * to this component's registered listeners.
+   * <p>
+   * If <code>value</code> is outside the range <code>minimum</code> to 
+   * <code>maximum</code>, it will be set to the nearest of those boundary 
+   * values.
+   *
+   * @param value  the new value.
+   * 
+   * @see #getValue()
+   */
+  public void setValue(int value)
+  {
+    model.setValue(value);
+  }
+
+  /**
+   * Paints the component's border, but only if {@link #isBorderPainted()}
+   * returns <code>true</code>.
+   *
+   * @param graphics  the graphics object to paint with.
+   * 
+   * @see #setBorderPainted(boolean)
+   */
+  protected void paintBorder(Graphics graphics)
+  {
+    Border border = getBorder();
+    if (paintBorder && border != null)
+      border.paintBorder(this, graphics, 0, 0, getWidth(), getHeight());
+  }
+
+  /**
+   * Returns the orientation of the <code>JProgressBar</code> component, which
+   * is either {@link SwingConstants#HORIZONTAL} or 
+   * {@link SwingConstants#VERTICAL}.  The default orientation is 
+   * <code>HORIZONTAL</code>.
+   *
+   * @return The orientation.
+   * 
+   * @see #setOrientation(int)
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * Sets the orientation for this <code>JProgressBar</code> component and,
+   * if the value changes, sends a {@link PropertyChangeEvent} (with the 
+   * property name <code>"orientation"</code>) to all registered listeners.
+   *
+   * @param orientation  the orientation ({@link #HORIZONTAL} or 
+   *     {@link #VERTICAL}).
+   * 
+   * @throws IllegalArgumentException if <code>orientation</code> is not
+   *     one of the listed values.
+   *     
+   * @see #getOrientation()
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != VERTICAL && orientation != HORIZONTAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a legal orientation");    
+    if (this.orientation != orientation)
+      {
+        int oldOrientation = this.orientation;
+        this.orientation = orientation;
+        firePropertyChange("orientation", oldOrientation, this.orientation);
+      }
+  }
+
+  /**
+   * Returns the flag that controls whether or not the string returned by
+   * {@link #getString()} is displayed by the <code>JProgressBar</code> 
+   * component.
+   *
+   * @return <code>true</code> if the string should be displayed, and 
+   *     <code>false</code> otherwise.
+   * 
+   * @see #setStringPainted(boolean)
+   */
+  public boolean isStringPainted()
+  {
+    return paintString;
+  }
+
+  /**
+   * Sets the flag that controls whether or not the string returned by
+   * {@link #getString()} is displayed by the <code>JProgressBar</code> 
+   * component.  If the flag value changes, a {@link PropertyChangeEvent} (with 
+   * the property name <code>"stringPainted"</code>) is sent to all registered 
+   * listeners.
+   *
+   * @param painted  the new flag value.
+   * 
+   * @see #isStringPainted()
+   * @see #setString(String)
+   */
+  public void setStringPainted(boolean painted)
+  {
+    if (paintString != painted)
+      {
+        boolean oldPainted = paintString;
+        paintString = painted;
+        firePropertyChange("stringPainted", oldPainted, paintString);
+      }
+  }
+
+  /**
+   * Returns the string that is painted on the <code>JProgressBar</code> if 
+   * {@link #isStringPainted()} returns <code>true</code>.  If no string has 
+   * been explicitly set, this method will return a string displaying the 
+   * value of {@link #getPercentComplete()}.
+   *
+   * @return The string.
+   * 
+   * @see #setString(String)
+   * @see #setStringPainted(boolean)
+   */
+  public String getString()
+  {
+    if (progressString != null)
+      return progressString;
+    else
+      return (int) (getPercentComplete() * 100) + "%";
+  }
+
+  /**
+   * Sets the string to display within the progress bar and, if the new value
+   * is different to the old value, sends a {@link PropertyChangeEvent} (with 
+   * the property name <code>"string"</code>) to all registered listeners. If 
+   * the string is set to <code>null</code>, {@link #getString()} will return
+   * a default string.
+   *
+   * @param string  the string (<code>null</code> permitted).
+   * 
+   * @see #getString()
+   * @see #setStringPainted(boolean)
+   */
+  public void setString(String string)
+  {
+    if (((string == null || progressString == null) &&
+        string != progressString) || (string != null &&
+	! string.equals(progressString)))
+      {
+        String oldString = progressString;
+        progressString = string;
+        firePropertyChange("string", oldString, progressString);
+      }
+  }
+
+  /**
+   * Returns the current value expressed as a percentage.  This is calculated 
+   * as <code>(value - min) / (max - min)</code>.
+   *
+   * @return The percentage (a value in the range 0.0 to 1.0).
+   */
+  public double getPercentComplete()
+  {
+    if (getMaximum() == getMinimum())
+      return 1.0;
+    else
+      return (double) (model.getValue() - model.getMinimum()) 
+          / (model.getMaximum() - model.getMinimum());
+  }
+
+  /**
+   * Returns a flag that controls whether or not the component's border is
+   * painted.  The default value is <code>true</code>.
+   *
+   * @return <code>true</code> if the component's border should be painted,
+   *     and <code>false</code> otherwise.
+   *     
+   * @see #setBorderPainted(boolean)
+   */
+  public boolean isBorderPainted()
+  {
+    return paintBorder;
+  }
+
+  /**
+   * Sets the flag that controls whether or not the component's border is
+   * painted.  If the flag value is changed, this method sends a 
+   * {@link PropertyChangeEvent} (with the property name "borderPainted") to 
+   * all registered listeners.
+   *
+   * @param painted  the new flag value.
+   * 
+   * @see #isBorderPainted()
+   * @see #paintBorder
+   */
+  public void setBorderPainted(boolean painted)
+  {
+    if (painted != paintBorder)
+      {
+        boolean oldPainted = paintBorder;
+        paintBorder = painted;
+        firePropertyChange("borderPainted", oldPainted, paintBorder);
+      }
+  }
+
+  /**
+   * Returns the UI delegate for this <code>JProgressBar</code>.
+   *
+   * @return The UI delegate.
+   */
+  public ProgressBarUI getUI()
+  {
+    return (ProgressBarUI) ui;
+  }
+
+  /**
+   * Sets the UI delegate for this component.
+   *
+   * @param ui  the new UI delegate.
+   */
+  public void setUI(ProgressBarUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Sets this <code>JProgressBar</code>'s UI delegate to the default 
+   * (obtained from the {@link UIManager}) for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((ProgressBarUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Returns the suffix (<code>"ProgressBarUI"</code> in this case) used to 
+   * determine the class name for a UI delegate that can provide the look and 
+   * feel for a <code>JProgressBar</code>.
+   *
+   * @return <code>"ProgressBarUI"</code>.
+   */
+  public String getUIClassID()
+  {
+    return "ProgressBarUI";
+  }
+
+  /**
+   * Creates a new {@link ChangeListener} that calls 
+   * {@link #fireStateChanged()} whenever it receives a {@link ChangeEvent}
+   * (typically from the component's <code>model</code>).  This listener is 
+   * registered with the progress bar's model, so that changes made to the 
+   * model directly will automatically result in the progress bar's listeners 
+   * being notified also.
+   *
+   * @return A new listener.
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new ChangeListener()
+      {
+        public void stateChanged(ChangeEvent ce)
+        {
+          fireStateChanged();
+	    }
+      };
+  }
+
+  /**
+   * Registers a listener with this component so that it will receive 
+   * notification of component state changes.
+   *
+   * @param listener  the listener.
+   * 
+   * @see #removeChangeListener(ChangeListener)
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * Deregisters a listener so that it no longer receives notification of
+   * component state changes.
+   *
+   * @param listener  the listener.
+   * 
+   * @see #addChangeListener(ChangeListener)
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+  
+  /**
+   * Returns an array of the listeners that are registered with this component.
+   * The array may be empty, but is never <code>null</code>.
+   *
+   * @return An array of listeners.
+   * 
+   * @since 1.4
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }  
+
+  /**
+   * Sends a {@link ChangeEvent} to all registered listeners to indicate that
+   * the state of the <code>JProgressBar</code> has changed.  
+   * 
+   * @see #createChangeListener()
+   */
+  protected void fireStateChanged()
+  {
+    Object[] changeListeners = listenerList.getListenerList();
+    if (changeEvent == null)
+      changeEvent = new ChangeEvent(this);
+    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+      {
+        if (changeListeners[i] == ChangeListener.class)
+          ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+      }
+  }
+
+  /**
+   * Returns the model for the <code>JProgressBar</code>.
+   *
+   * @return The model (never <code>null</code>).
+   * 
+   * @see #setModel(BoundedRangeModel)
+   */
+  public BoundedRangeModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * Sets the model for the <code>JProgressBar</code> and sends a 
+   * {@link ChangeEvent} to all registered listeners.
+   *
+   * @param model  the model (<code>null</code> not permitted).
+   * 
+   * @see #getModel()
+   */
+  public void setModel(BoundedRangeModel model)
+  {
+    if (model != this.model)
+      {
+        this.model.removeChangeListener(changeListener);
+        this.model = model;
+        this.model.addChangeListener(changeListener);
+        fireStateChanged();
+      }
+  }
+
+  /**
+   * Returns the minimum value for the <code>JProgressBar</code>. This defines 
+   * the lower bound for the current value, and is stored in the component's 
+   * <code>model</code>.
+   *
+   * @return The minimum value.
+   * 
+   * @see #setMinimum(int)
+   */
+  public int getMinimum()
+  {
+    return model.getMinimum();
+  }
+
+  /**
+   * Sets the minimum value for the <code>JProgressBar</code>.  The value is
+   * stored in the component's <code>model</code> (see {@link #getModel()}).  
+   * If the new value is different to the old value, a {@link ChangeEvent} is 
+   * sent to the model's registered listeners.  In turn, this triggers a call 
+   * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> 
+   * to this component's registered listeners.
+   * 
+   * @param minimum  the minimum value.
+   * 
+   * @see #getMinimum()
+   */
+  public void setMinimum(int minimum)
+  {
+    model.setMinimum(minimum);
+  }
+
+  /**
+   * Returns the maximum value for the <code>JProgressBar</code>.  This defines 
+   * the upper bound for the current value, and is stored in the component's 
+   * <code>model</code>.
+   *
+   * @return The maximum value.
+   * 
+   * @see #setMaximum(int)
+   */
+  public int getMaximum()
+  {
+    return model.getMaximum();
+  }
+
+  /**
+   * Sets the maximum value for the <code>JProgressBar</code>.  The value is
+   * stored in the component's <code>model</code> (see {@link #getModel()}).  
+   * If the new value is different to the old value, a {@link ChangeEvent} is 
+   * sent to the model's registered listeners.  In turn, this triggers a call 
+   * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> 
+   * to this component's registered listeners.
+   *
+   * @param maximum  the maximum value.
+   * 
+   * @see #getMaximum()
+   */
+  public void setMaximum(int maximum)
+  {
+    model.setMaximum(maximum);
+  }
+
+  /**
+   * Returns an implementation-dependent string describing the attributes of
+   * this <code>JProgressBar</code>.
+   *
+   * @return A string describing the attributes of this 
+   *     <code>JProgressBar</code> (never <code>null</code>).
+   */
+  protected String paramString()
+  {
+    String superParamStr = super.paramString();
+    StringBuffer sb = new StringBuffer();
+    sb.append(",orientation=");
+    if (orientation == HORIZONTAL)
+      sb.append("HORIZONTAL");
+    else
+      sb.append("VERTICAL");
+    sb.append(",paintBorder=").append(isBorderPainted());
+    sb.append(",paintString=").append(isStringPainted());
+    sb.append(",progressString=");
+    if (progressString != null)
+      sb.append(progressString);
+    sb.append(",indeterminateString=").append(isIndeterminate());
+    return superParamStr + sb.toString();
+  }
+
+  /**
+   * Sets the flag that controls the mode for this <code>JProgressBar</code>
+   * (<code>true</code> for indeterminate mode, and <code>false</code> for
+   * determinate mode).  If the flag value changes, this method sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * <code>"indeterminate"</code>) to all registered listeners.
+   * <p>
+   * If the <code>JProgressBar</code> is determinate, it paints a percentage
+   * of the bar described by its value. If it is indeterminate, it simply 
+   * bounces a box between the ends of the bar; the value of the 
+   * <code>JProgressBar</code> is ignored.
+   *
+   * @param flag  the new flag value.
+   * 
+   * @see #isIndeterminate()
+   * @since 1.4
+   */
+  public void setIndeterminate(boolean flag)
+  {
+    if (indeterminate != flag)
+      {
+        indeterminate = flag;
+        firePropertyChange("indeterminate", !flag, indeterminate);
+      }
+  }
+
+  /**
+   * Returns a flag that indicates the mode for this <code>JProgressBar</code>
+   * (<code>true</code> for indeterminate mode, and <code>false</code> for 
+   * determinate mode).  
+   *
+   * @return A flag indicating the mode for the <code>JProgressBar</code>.
+   * 
+   * @see #setIndeterminate(boolean)
+   * @since 1.4
+   */
+  public boolean isIndeterminate()
+  {
+    return indeterminate;
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JProgressBar</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJProgressBar}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJProgressBar();
+    
+    return accessibleContext;
+  } 
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButton.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButton.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButton.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButton.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,259 @@
+/* JRadioButton.java -- 
+   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.ButtonUI;
+
+/**
+ * The <code>JRadioButton</code> component provides a visually selectable
+ * button with mutually exclusive behaviour within a <code>ButtonGroup</code>.
+ * A series of radio buttons can be used to provide options to the user,
+ * where the user can only select one of the available options.  The state
+ * of the button is provided by the superclass, <code>JToggleButton</code>.
+ * <code>JRadioButton</code> adds the additional behaviour, that if two
+ * or more radio buttons are grouped together, the selection of one implies
+ * the deselection of the other buttons within the group.
+ * <p>
+ *
+ * Buttons are grouped by adding each instance to a <code>ButtonGroup</code>.
+ * The existence of such a grouping is not reflected visually, so other means
+ * should be used to denote this.  For instance, the grouped buttons can be placed
+ * within the same panel, possibly with an appropriate border to denote
+ * the connection between the components.
+ *
+ * @author Michael Koch  (konqueror at gmx.de)
+ * @author Graydon Hoare  (graydon at redhat.com)
+ * @author Andrew John Hughes  (gnu_andrew at member.fsf.org)
+ * @see JToggleButton
+ * @see ButtonGroup
+ * @since 1.2
+ */
+public class JRadioButton extends JToggleButton
+{
+  /**
+   * Compatible with Sun's JDK.
+   */
+  private static final long serialVersionUID = 7751949583255506856L;
+
+  /**
+   * This class provides accessibility support for the toggle button.
+   */
+  protected class AccessibleJRadioButton
+    extends AccessibleJToggleButton
+  {
+    private static final long serialVersionUID = 4850967637026120674L;
+
+    /**
+     * Constructor for the accessible toggle button.
+     */
+    protected AccessibleJRadioButton()
+    {
+        /* Call the superclass to register for events */
+        super();
+    }
+
+    /**
+     * Returns the accessible role for the toggle button.
+     *
+     * @return An instance of <code>AccessibleRole</code>, describing
+     *         the role of the toggle button.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.RADIO_BUTTON;
+    }
+
+  }
+
+  /**
+   * Constructs an unselected radio button with no text or icon.
+   */ 
+  public JRadioButton()
+  {
+    this(null, null, false);
+  }
+    
+  /**
+   * Constructs a radio button using the labelling, state
+   * and icon specified by the supplied action.
+   *
+   * @param a the action to use to define the properties of the button.
+   */
+  public JRadioButton(Action a)
+  {
+    this();
+    setAction(a);
+  }
+
+  /**
+   * Constructs an unselected radio button with the supplied icon
+   * and no text.
+   *
+   * @param icon the icon to use.
+   */
+  public JRadioButton(Icon icon)
+  { 
+    this(null, icon, false);
+  }    
+  
+  /**
+   * Constructs a radio button with the supplied icon and state.
+   *
+   * @param icon the icon to use.
+   * @param selected if true, the radio button is initially in the
+   *        selected state.  Otherwise, the button is unselected.
+   */
+  public JRadioButton(Icon icon, boolean selected)
+  { 
+    this(null, icon, selected);
+  }    
+  
+  /**
+   * Constructs an unselected radio button using the supplied text
+   * and no icon.
+   *
+   * @param text the text to use.
+   */
+  public JRadioButton(String text)
+  {
+    this(text, null, false);
+  }
+
+  /**
+   * Constructs a radio button with the supplied text and state.
+   *
+   * @param text the text to use.
+   * @param selected if true, the radio button is initially in the
+   *        selected state.  Otherwise, the button is unselected.
+   */
+  public JRadioButton(String text, boolean selected)
+  {
+    this(text, null, selected);
+  }
+      
+  /**
+   * Constructs an unselected radio button with the supplied text
+   * and icon.
+   *
+   * @param text the text to use.
+   * @param icon the icon to use.
+   */
+  public JRadioButton(String text, Icon icon)
+  {
+    this(text, icon, false);
+  }
+  
+  /**
+   * Constructs a radio button with the supplied text, icon and state.
+   *
+   * @param text the text to use.
+   * @param icon the icon to use.
+   * @param selected if true, the radio button is initially in the
+   *        selected state.  Otherwise, the button is unselected.
+   */
+  public JRadioButton(String text, Icon icon, boolean selected)
+  {
+    super(text, icon, selected);
+    setBorderPainted(false);
+    setHorizontalAlignment(LEADING);
+  }
+      
+  /**
+   * Returns the accessible context for this <code>JRadioButton</code>,
+   * in the form of an instance of <code>AccessibleJRadioButton</code>.
+   * The context is created, if necessary.
+   *
+   * @return the associated context
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    /* Create the context if this is the first request */
+    if (accessibleContext == null)
+      {
+        /* Create the context */
+	accessibleContext = new AccessibleJRadioButton();
+      }
+    return accessibleContext;
+  }
+  
+  /**
+   * Returns a string specifying the name of the Look and Feel UI class
+   * that renders this component.
+   *
+   * @return the Look and Feel UI class for <code>JRadioButton</code>s
+   *         as a <code>String</code>.
+   */  
+  public String getUIClassID()
+  {
+    return "RadioButtonUI";
+  }
+  
+  /**
+   * Returns a string representation of this component for debugging use.
+   * Users should not depend on anything as regards the content or formatting
+   * of this string, except for the fact that the returned string may never be
+   * null (only empty).
+   *
+   * @return the component in <code>String</code> form for debugging.
+   */  
+  protected  String paramString()
+  {
+    return super.paramString();
+  }
+  
+  /**
+   * This method resets the radio button's UI delegate to the default UI for
+   * the current look and feel.
+   */
+  public void updateUI()
+  {
+    /* 
+       I can't see any difference between this and the superclass one,
+       but Sun reimplements it... there is no RadioButtonUI class for it
+       to be cast to.
+    */
+    setUI((ButtonUI) UIManager.getUI(this));
+  }
+
+}
+
+
+

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButtonMenuItem.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButtonMenuItem.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButtonMenuItem.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRadioButtonMenuItem.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,230 @@
+/* JRadioButtonMenuItem.java --
+   Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * This class represents JRadioButtonMenuItem. Its behaviour is very similar
+ * to JRadioButton. Just like JRadioButton, user can check and uncheck this
+ * menu item by clicking on it. JRadioButtonMenuItem uses ToggleButtonModel
+ * to keep track of its selection. If the JRadioButtonMenuItem is included in
+ * the button group, then only one JRadioButtonMenuItem can be selected at
+ * one time.
+ */
+public class JRadioButtonMenuItem extends JMenuItem implements Accessible
+{
+  private static final long serialVersionUID = 8482658191548521743L;
+
+  /** name for the UI delegate for this radio button menu item. */
+  private static final String uiClassID = "RadioButtonMenuItemUI";
+
+  /**
+   * Creates a new JRadioButtonMenuItem object.
+   */
+  public JRadioButtonMenuItem()
+  {
+    this(null, null);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified icon
+   *
+   * @param icon Icon to be used for this menu item
+   */
+  public JRadioButtonMenuItem(Icon icon)
+  {
+    this(null, icon);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label
+   *
+   * @param text Label for this menu item
+   */
+  public JRadioButtonMenuItem(String text)
+  {
+    this(text, null);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem using specified action
+   *
+   * @param action Action for this menu item
+   */
+  public JRadioButtonMenuItem(Action action)
+  {
+    this();
+    setAction(action);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label and icon
+   *
+   * @param text Label for this menu item
+   * @param icon Icon for this menu item
+   */
+  public JRadioButtonMenuItem(String text, Icon icon)
+  {
+    this(text, icon, false);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label
+   * and marked selected if 'selected' is true.
+   *
+   * @param text Text for this menu item
+   * @param selected Selected state of this menu item
+   */
+  public JRadioButtonMenuItem(String text, boolean selected)
+  {
+    this(text, null, selected);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified icon
+   * and given selected state
+   *
+   * @param icon Icon for this menu item
+   * @param selected Selected state for this menu item
+   */
+  public JRadioButtonMenuItem(Icon icon, boolean selected)
+  {
+    this(null, icon, selected);
+  }
+
+  /**
+   * Creates a new JRadioButtonMenuItem with specified label,
+   * icon and selected state.
+   *
+   * @param text Label for this menu item
+   * @param icon Icon to be use for this menu item
+   * @param selected selected state of this menu item
+   */
+  public JRadioButtonMenuItem(String text, Icon icon, boolean selected)
+  {
+    super(text, icon);
+    setModel(new JToggleButton.ToggleButtonModel());
+    model.setSelected(selected);
+    setFocusable(false);
+  }
+
+  /**
+   * This method returns a name to identify which look and feel class will be
+   * the UI delegate for the menuItem.
+   *
+   * @return The Look and Feel classID. "JRadioButtonMenuItemUI"
+   */
+  public String getUIClassID()
+  {
+    return uiClassID;
+  }
+
+  /**
+   * This method overrides JComponent.requestFocus with an empty
+   * implementation, since JRadioButtonMenuItems should not
+   * receve focus in general.
+   */
+  public void requestFocus()
+  {
+    //  Should do nothing here
+  }
+
+  /**
+   * Returns a string describing the attributes for the 
+   * <code>JRadioButtonMenuItem</code> component, for use in debugging.  The 
+   * return value is guaranteed to be non-<code>null</code>, but the format of 
+   * the string may vary between implementations.
+   *
+   * @return A string describing the attributes of the 
+   *     <code>JRadioButtonMenuItem</code>.
+   */
+  protected String paramString()
+  {
+    // calling super seems to be sufficient here...
+    return super.paramString();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JRadioButtonMenuItem</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJRadioButtonMenuItem}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJRadioButtonMenuItem();
+
+    return accessibleContext;
+  }
+
+  /**
+   * Provides the accessibility features for the 
+   * <code>JRadioButtonMenuItem</code> component.
+   * 
+   * @see JRadioButtonMenuItem#getAccessibleContext()
+   */
+  protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem
+  {
+    private static final long serialVersionUID = 4381471510145292179L;
+
+    /**
+     * Creates a new <code>AccessibleJRadioButtonMenuItem</code> instance.
+     */
+    protected AccessibleJRadioButtonMenuItem()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns the accessible role for the <code>JRadioButtonMenuItem</code> 
+     * component.
+     *
+     * @return {@link AccessibleRole#RADIO_BUTTON}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.RADIO_BUTTON;
+    }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRootPane.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRootPane.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRootPane.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JRootPane.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,694 @@
+/* JRootPane.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.IllegalComponentStateException;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.LayoutManager2;
+import java.awt.Rectangle;
+import java.io.Serializable;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.RootPaneUI;
+
+/**
+ * This class is where JComponents are added to. Unlike awt where you could
+ * just say frame.add(), with swing you need to say frame.getRootPane()
+ * (which delivers an instance of this class) and add your components to
+ * that. It is implemented by several 'layers' (pane() should be read as
+ * plane()) each on top of the others where you can add components to.
+ * (getContentPane(), getGlassPane(), getLayeredPane())
+ *
+ * @author Ronald Veldema (rveldema at cs.vu.nl)
+ */
+public class JRootPane extends JComponent implements Accessible
+{
+  //  The class used to obtain the accessible role for this object.
+  protected class AccessibleJRootPane extends AccessibleJComponent
+  {
+    /**
+     * For compatability with Sun's JDK
+     */
+    private static final long serialVersionUID = 1082432482784468088L;
+
+    /**
+     * Creates a new <code>AccessibleJRootPane</code> object.
+     */
+    protected AccessibleJRootPane()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.ROOT_PANE;
+    }
+  }
+
+  // Custom Layout Manager for JRootPane. It positions contentPane and 
+  // menuBar withing its layeredPane.
+  protected class RootLayout implements LayoutManager2, Serializable
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = -4100116998559815027L;
+
+    /**
+     * The cached layout info for the glass pane.
+     */
+    private Rectangle glassPaneBounds;
+
+    /**
+     * The cached layout info for the layered pane.
+     */
+    private Rectangle layeredPaneBounds;
+
+    /**
+     * The cached layout info for the content pane.
+     */
+    private Rectangle contentPaneBounds;
+
+    /**
+     * The cached layout info for the menu bar.
+     */
+    private Rectangle menuBarBounds;
+
+    /**
+     * Creates a new <code>RootLayout</code> object.
+     */
+    protected RootLayout()
+    {
+      // Nothing to do here. 
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param comp DOCUMENT ME!
+     * @param constraints DOCUMENT ME!
+     */
+    public void addLayoutComponent(Component comp, Object constraints)
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name DOCUMENT ME!
+     * @param comp DOCUMENT ME!
+     */
+    public void addLayoutComponent(String name, Component comp)
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float getLayoutAlignmentX(Container target)
+    {
+      return 0.0F;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public float getLayoutAlignmentY(Container target)
+    {
+      return 0.0F;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     */
+    public void invalidateLayout(Container target)
+    {
+      synchronized (this)
+        {
+          glassPaneBounds = null;
+          layeredPaneBounds = null;
+          contentPaneBounds = null;
+          menuBarBounds = null;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     */
+    public void layoutContainer(Container c)
+    {
+      if (glassPaneBounds == null || layeredPaneBounds == null
+          || contentPaneBounds == null || menuBarBounds == null)
+        {
+          Insets i = getInsets();
+          int containerWidth = c.getBounds().width - i.left - i.right;
+          int containerHeight = c.getBounds().height - i.top - i.bottom;
+
+          // 1. the glassPane fills entire viewable region (bounds - insets).
+          // 2. the layeredPane filles entire viewable region.
+          // 3. the menuBar is positioned at the upper edge of layeredPane.
+          // 4. the contentPane fills viewable region minus menuBar, if present.
+      
+
+          // +-------------------------------+
+          // |  JLayeredPane                 |
+          // |  +--------------------------+ |
+          // |  | menuBar                  | |
+          // |  +--------------------------+ |
+          // |  +--------------------------+ |
+          // |  |contentPane               | |
+          // |  |                          | |
+          // |  |                          | |
+          // |  |                          | |
+          // |  +--------------------------+ |
+          // +-------------------------------+
+
+          if (menuBar != null)
+            {
+              Dimension menuBarSize = menuBar.getPreferredSize();
+              if (menuBarSize.height > containerHeight)
+                menuBarSize.height = containerHeight;
+              menuBarBounds = new Rectangle(0, 0, containerWidth,
+                                            menuBarSize.height);
+              contentPaneBounds = new Rectangle(0, menuBarSize.height,
+                                                containerWidth,
+                                         containerHeight - menuBarSize.height);
+            }
+          else
+            contentPaneBounds = new Rectangle(0, 0, containerWidth,
+                                              containerHeight);
+              
+          glassPaneBounds = new Rectangle(i.left, i.top, containerWidth, containerHeight);
+          layeredPaneBounds = new Rectangle(i.left, i.top, containerWidth, containerHeight);
+        }
+
+      glassPane.setBounds(glassPaneBounds);
+      layeredPane.setBounds(layeredPaneBounds);
+      if (menuBar != null)
+        menuBar.setBounds(menuBarBounds);
+      getContentPane().setBounds(contentPaneBounds);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension maximumLayoutSize(Container target)
+    {
+      return preferredLayoutSize(target);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param target DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension minimumLayoutSize(Container target)
+    {
+      return preferredLayoutSize(target);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param c DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Dimension preferredLayoutSize(Container c)
+    {
+      Dimension prefSize = new Dimension();
+      Insets i = getInsets();
+      prefSize = new Dimension(i.left + i.right, i.top + i.bottom);
+      Dimension contentPrefSize = getContentPane().getPreferredSize();
+      prefSize.width += contentPrefSize.width;
+      prefSize.height += contentPrefSize.height;
+      if (menuBar != null)
+        {
+          Dimension menuBarSize = menuBar.getPreferredSize();
+          if (menuBarSize.width > contentPrefSize.width)
+            prefSize.width += menuBarSize.width - contentPrefSize.width;
+          prefSize.height += menuBarSize.height;
+        }
+      return prefSize;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param comp DOCUMENT ME!
+     */
+    public void removeLayoutComponent(Component comp)
+    {
+      // Nothing to do here.
+    }
+  }
+
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = 8690748000348575668L;
+
+  public static final int NONE = 0;
+  public static final int FRAME = 1;
+  public static final int PLAIN_DIALOG = 2;
+  public static final int INFORMATION_DIALOG = 3;
+  public static final int ERROR_DIALOG = 4;
+  public static final int COLOR_CHOOSER_DIALOG = 5;
+  public static final int FILE_CHOOSER_DIALOG = 6;
+  public static final int QUESTION_DIALOG = 7;
+  public static final int WARNING_DIALOG = 8;
+          
+  /** DOCUMENT ME! */
+  protected Component glassPane;
+
+  /** DOCUMENT ME! */
+  protected JLayeredPane layeredPane;
+
+  /** DOCUMENT ME! */
+  protected JMenuBar menuBar;
+
+  /** DOCUMENT ME! */
+  protected Container contentPane;
+
+  protected JButton defaultButton;
+
+  /**
+   * This field is unused since JDK1.3. To override the default action you
+   * should modify the JRootPane's ActionMap.
+   *
+   * @deprecated since JDK1.3
+   *
+   * @specnote the specs indicate that the type of this field is
+   *           a package private inner class
+   *           javax.swing.JRootPane.DefaultAction. I assume that the closest
+   *           public superclass is javax.swing.Action.
+   */
+  protected Action defaultPressAction;
+
+  /**
+   * This field is unused since JDK1.3. To override the default action you
+   * should modify the JRootPane's ActionMap.
+   *
+   * @deprecated since JDK1.3
+   *
+   * @specnote the specs indicate that the type of this field is
+   *           a package private inner class
+   *           javax.swing.JRootPane.DefaultAction. I assume that the closest
+   *           public superclass is javax.swing.Action.
+   */
+  protected Action defaultReleaseAction;
+
+  /**
+   * @since 1.4
+   */
+  private int windowDecorationStyle = NONE;
+  
+  /**
+   * DOCUMENT ME!
+   *
+   * @param m DOCUMENT ME!
+   */
+  public void setJMenuBar(JMenuBar m)
+  {
+    JLayeredPane jlPane = getLayeredPane();
+    if (menuBar != null)
+      jlPane.remove(menuBar);
+    menuBar = m;
+    if (menuBar != null)
+      jlPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
+  }
+
+  /**
+   * @deprecated Replaced by <code>setJMenuBar()</code>
+   */
+  public void setMenuBar(JMenuBar m)
+  {
+    setJMenuBar(m);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public JMenuBar getJMenuBar()
+  {
+    return menuBar;
+  }
+
+  /**
+   * @deprecated Replaced by <code>getJMenuBar()</code>
+   */
+  public JMenuBar getMenuBar()
+  {
+    return getJMenuBar();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean isValidateRoot()
+  {
+    return true;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public Container getContentPane()
+  {
+    if (contentPane == null)
+      setContentPane(createContentPane());
+    return contentPane;
+  }
+
+  /**
+   * Sets the JRootPane's content pane.  The content pane should typically be
+   * opaque for painting to work properly.  This method also 
+   * removes the old content pane from the layered pane.
+   *
+   * @param p the Container that will be the content pane
+   * @throws IllegalComponentStateException if p is null
+   */
+  public void setContentPane(Container p)
+  {
+    if (p == null)
+      throw new IllegalComponentStateException ("cannot " +
+            "have a null content pane");
+    else
+      {
+        if (contentPane != null && contentPane.getParent() == layeredPane)
+          layeredPane.remove(contentPane);
+        contentPane = p;
+        getLayeredPane().add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
+      }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param comp DOCUMENT ME!
+   * @param constraints DOCUMENT ME!
+   * @param index DOCUMENT ME!
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    super.addImpl(comp, constraints, index);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public Component getGlassPane()
+  {
+    if (glassPane == null)
+      setGlassPane(createGlassPane());
+    return glassPane;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param f DOCUMENT ME!
+   */
+  public void setGlassPane(Component f)
+  {
+    if (glassPane != null)
+      remove(glassPane);
+
+    glassPane = f;
+
+    glassPane.setVisible(false);
+    add(glassPane, 0);
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public JLayeredPane getLayeredPane()
+  {
+    if (layeredPane == null)
+      setLayeredPane(createLayeredPane());
+    return layeredPane;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param f DOCUMENT ME!
+   */
+  public void setLayeredPane(JLayeredPane f)
+  {
+    if (layeredPane != null)
+      remove(layeredPane);
+
+    layeredPane = f;
+    add(f, -1);
+  }
+
+  /**
+   * Creates a new <code>JRootPane</code> object.
+   */
+  public JRootPane()
+  {
+    setLayout(createRootLayout());
+    getGlassPane();
+    getLayeredPane();
+    getContentPane();
+    setOpaque(true);
+    updateUI();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected LayoutManager createRootLayout()
+  {
+    return new RootLayout();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected Container createContentPane()
+  {
+    JPanel p = new JPanel();
+    p.setName(this.getName() + ".contentPane");
+    p.setLayout(new BorderLayout());
+    return p;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected Component createGlassPane()
+  {
+    JPanel p = new JPanel();
+    p.setName(this.getName() + ".glassPane");
+    p.setVisible(false);
+    p.setOpaque(false);
+    return p;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected JLayeredPane createLayeredPane()
+  {
+    JLayeredPane l = new JLayeredPane();
+    l.setLayout(null);
+    return l;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public RootPaneUI getUI()
+  {
+    return (RootPaneUI) ui;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param ui DOCUMENT ME!
+   */
+  public void setUI(RootPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void updateUI()
+  {
+    setUI((RootPaneUI) UIManager.getUI(this));
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public String getUIClassID()
+  {
+    return "RootPaneUI";
+  }
+
+  public JButton getDefaultButton()
+  {
+    return defaultButton;
+  }
+  
+  public void setDefaultButton(JButton newButton)
+  {
+    // We only change the default button if the new button is defaultCapable
+    // or null and the old and new button are different objects.
+    if (defaultButton != newButton
+        && (newButton == null || newButton.isDefaultCapable()))
+      {
+        JButton oldButton = defaultButton;
+        defaultButton = newButton;
+        firePropertyChange("defaultButton", oldButton, newButton);
+      }
+  }
+
+  /**
+   * @since 1.4
+   */
+  public int getWindowDecorationStyle()
+  {
+    return windowDecorationStyle;
+  }
+
+  /**
+   * @since 1.4
+   */
+  public void setWindowDecorationStyle(int style)
+  {
+    if (style != NONE
+        && style != FRAME
+        && style != INFORMATION_DIALOG
+        && style != ERROR_DIALOG
+        && style != COLOR_CHOOSER_DIALOG
+        && style != FILE_CHOOSER_DIALOG
+        && style != QUESTION_DIALOG
+        && style != WARNING_DIALOG
+        && style != PLAIN_DIALOG)
+      throw new IllegalArgumentException("invalid style");
+    
+    int oldStyle = windowDecorationStyle;
+    windowDecorationStyle = style;
+    firePropertyChange("windowDecorationStyle", oldStyle, style);
+  }
+
+  /**
+   * This returns <code>true</code> if the <code>glassPane</code> is not
+   * visible because then the root pane can guarantee to tile its children
+   * (the only other direct child is a JLayeredPane which must figure its
+   * <code>optimizeDrawingEnabled</code> state on its own).
+   *
+   * @return <code>true</code> if the <code>glassPane</code> is not
+   *         visible
+   */
+  public boolean isOptimizedDrawingEnable()
+  {
+    return ! glassPane.isVisible();
+  }
+
+  /**
+   * Returns the accessible context for this JRootPane. This will be
+   * an instance of {@link AccessibleJRootPane}.
+   *
+   * @return the accessible context for this JRootPane
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJRootPane();
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollBar.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollBar.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollBar.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollBar.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,679 @@
+/* JScrollBar.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Adjustable;
+import java.awt.Dimension;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.beans.PropertyChangeEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+import javax.swing.plaf.ScrollBarUI;
+
+/**
+ * The JScrollBar. Two buttons control how the values that the 
+ * scroll bar can take. You can also drag the thumb or click the track
+ * to move the scroll bar. Typically, the JScrollBar is used with
+ * other components to translate the value of the bar to the viewable
+ * contents of the other components.
+ */
+public class JScrollBar extends JComponent implements Adjustable, Accessible
+{
+  /**
+   * Provides the accessibility features for the <code>JScrollBar</code>
+   * component.
+   */
+  protected class AccessibleJScrollBar extends JComponent.AccessibleJComponent
+    implements AccessibleValue
+  {
+    private static final long serialVersionUID = -7758162392045586663L;
+    
+    /**
+     * Creates a new <code>AccessibleJScrollBar</code> instance.
+     */
+    protected AccessibleJScrollBar()
+    {
+      super();
+    }
+
+    /**
+     * Returns a set containing the current state of the {@link JScrollBar} 
+     * component.
+     *
+     * @return The accessible state set.
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleStateSet result = super.getAccessibleStateSet();
+      if (orientation == JScrollBar.HORIZONTAL)
+        result.add(AccessibleState.HORIZONTAL);
+      else if (orientation == JScrollBar.VERTICAL)
+        result.add(AccessibleState.VERTICAL);
+      return result;
+    }
+
+    /**
+     * Returns the accessible role for the <code>JScrollBar</code> component.
+     *
+     * @return {@link AccessibleRole#SCROLL_BAR}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.SCROLL_BAR;
+    }
+
+    /**
+     * Returns an object that provides access to the current, minimum and 
+     * maximum values.
+     *
+     * @return The accessible value.
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the current value of the {@link JScrollBar} component, as an
+     * {@link Integer}.
+     *
+     * @return The current value of the {@link JScrollBar} component.
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return new Integer(getValue());
+    }
+
+    /**
+     * Sets the current value of the {@link JScrollBar} component and sends a
+     * {@link PropertyChangeEvent} (with the property name 
+     * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
+     * listeners.  If the supplied value is <code>null</code>, this method 
+     * does nothing and returns <code>false</code>.
+     *
+     * @param value  the new slider value (<code>null</code> permitted).
+     *
+     * @return <code>true</code> if the slider value is updated, and 
+     *     <code>false</code> otherwise.
+     */
+    public boolean setCurrentAccessibleValue(Number value)
+    {
+      if (value == null)
+        return false;
+      Number oldValue = getCurrentAccessibleValue();
+      setValue(value.intValue());
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, 
+                         new Integer(getValue()));
+      return true;
+    }
+
+    /**
+     * Returns the minimum value of the {@link JScrollBar} component, as an
+     * {@link Integer}.
+     *
+     * @return The minimum value of the {@link JScrollBar} component.
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return new Integer(getMinimum());
+    }
+
+    /**
+     * Returns the maximum value of the {@link JScrollBar} component, as an
+     * {@link Integer}.
+     *
+     * @return The maximum value of the {@link JScrollBar} component.
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return new Integer(getMaximum() - model.getExtent());
+    }
+  }
+
+  private static final long serialVersionUID = -8195169869225066566L;
+  
+  /** How much the thumb moves when moving in a block. */
+  protected int blockIncrement = 10;
+
+  /** The model that holds the scroll bar's data. */
+  protected BoundedRangeModel model;
+
+  /** The orientation of the scroll bar. */
+  protected int orientation = SwingConstants.VERTICAL;
+
+  /** How much the thumb moves when moving in a unit. */
+  protected int unitIncrement = 1;
+
+  /** 
+   * Creates a new horizontal JScrollBar object with a minimum
+   * of 0, a maxmium of 100, a value of 0 and an extent of 10.
+   */
+  public JScrollBar()
+  {
+    this(SwingConstants.VERTICAL, 0, 10, 0, 100);
+  }
+
+  /**
+   * Creates a new JScrollBar object with a minimum of 0, a 
+   * maximum of 100, a value of 0, an extent of 10 and the given
+   * orientation.
+   *
+   * @param orientation The orientation of the JScrollBar.
+   */
+  public JScrollBar(int orientation)
+  {
+    this(orientation, 0, 10, 0, 100);
+  }
+
+  /**
+   * Creates a new JScrollBar object with the given orientation, 
+   * value, min, max, and extent.
+   *
+   * @param orientation The orientation to use.
+   * @param value The value to use.
+   * @param extent The extent to use.
+   * @param min The minimum value of the scrollbar.
+   * @param max The maximum value of the scrollbar.
+   */
+  public JScrollBar(int orientation, int value, int extent, int min, int max)
+  {
+    model = new DefaultBoundedRangeModel(value, extent, min, max);
+    if (orientation != SwingConstants.HORIZONTAL
+        && orientation != SwingConstants.VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a legal orientation");
+    this.orientation = orientation;
+    updateUI();
+  }
+
+  /**
+   * This method sets the UI of this scrollbar to
+   * the given UI.
+   *
+   * @param ui The UI to use with this scrollbar.
+   */
+  public void setUI(ScrollBarUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method returns the UI that is being used
+   * with this scrollbar.
+   *
+   * @return The scrollbar's current UI.
+   */
+  public ScrollBarUI getUI()
+  {
+    return (ScrollBarUI) ui;
+  }
+
+  /**
+   * This method changes the UI to be the
+   * default for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((ScrollBarUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns an identifier to 
+   * choose the correct UI delegate for the
+   * scrollbar.
+   *
+   * @return The identifer to choose the UI delegate; "ScrollBarUI"
+   */
+  public String getUIClassID()
+  {
+    return "ScrollBarUI";
+  }
+
+  /**
+   * This method returns the orientation of the scrollbar.
+   *
+   * @return The orientation of the scrollbar.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * This method sets the orientation of the scrollbar.
+   *
+   * @param orientation The orientation of the scrollbar.
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != SwingConstants.HORIZONTAL
+        && orientation != SwingConstants.VERTICAL)
+      throw new IllegalArgumentException("orientation must be one of HORIZONTAL or VERTICAL");
+    if (orientation != this.orientation)
+      {
+	int oldOrientation = this.orientation;
+	this.orientation = orientation;
+	firePropertyChange("orientation", oldOrientation,
+	                   this.orientation);
+      }
+  }
+
+  /**
+   * This method returns the model being used with 
+   * the scrollbar.
+   *
+   * @return The scrollbar's model.
+   */
+  public BoundedRangeModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * This method sets the model to use with
+   * the scrollbar.
+   *
+   * @param newModel The new model to use with the scrollbar.
+   */
+  public void setModel(BoundedRangeModel newModel)
+  {
+    if (model != newModel)
+      {
+	BoundedRangeModel oldModel = model;
+	model = newModel;
+	firePropertyChange("model", oldModel, model);
+      }
+  }
+
+  /**
+   * This method returns how much the scrollbar's value
+   * should change for a unit increment depending on the 
+   * given direction.
+   *
+   * @param direction The direction to scroll in.
+   *
+   * @return The amount the scrollbar's value will change given the direction.
+   */
+  public int getUnitIncrement(int direction)
+  {
+    return direction * unitIncrement;
+  }
+
+  /**
+   * This method sets the unitIncrement property.
+   *
+   * @param unitIncrement The new unitIncrement.
+   */
+  public void setUnitIncrement(int unitIncrement)
+  {
+    if (unitIncrement != this.unitIncrement)
+      {
+	int oldInc = this.unitIncrement;
+	this.unitIncrement = unitIncrement;
+	firePropertyChange("unitIncrement", oldInc,
+	                   this.unitIncrement);
+      }
+  }
+
+  /**
+   * The method returns how much the scrollbar's value
+   * should change for a block increment depending on
+   * the given direction.
+   *
+   * @param direction The direction to scroll in.
+   *
+   * @return The amount the scrollbar's value will change given the direction.
+   */
+  public int getBlockIncrement(int direction)
+  {
+    return direction * blockIncrement;
+  }
+
+  /**
+   * This method sets the blockIncrement property.
+   *
+   * @param blockIncrement The new blockIncrement.
+   */
+  public void setBlockIncrement(int blockIncrement)
+  {
+    if (blockIncrement != this.blockIncrement)
+      {
+	int oldInc = this.blockIncrement;
+	this.blockIncrement = blockIncrement;
+	firePropertyChange("blockIncrement", oldInc,
+	                   this.blockIncrement);
+      }
+  }
+
+  /**
+   * This method returns the unitIncrement.
+   *
+   * @return The unitIncrement.
+   */
+  public int getUnitIncrement()
+  {
+    return unitIncrement;
+  }
+
+  /**
+   * This method returns the blockIncrement.
+   *
+   * @return The blockIncrement.
+   */
+  public int getBlockIncrement()
+  {
+    return blockIncrement;
+  }
+
+  /**
+   * This method returns the value of the scrollbar.
+   *
+   * @return The value of the scrollbar.
+   */
+  public int getValue()
+  {
+    return model.getValue();
+  }
+
+  /**
+   * This method changes the value of the scrollbar.
+   *
+   * @param value The new value of the scrollbar.
+   */
+  public void setValue(int value)
+  {
+    if (isEnabled() && value != getValue())
+    {
+      model.setValue(value);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, value);
+    }
+  }
+
+  /**
+   * This method returns the visible amount (AKA extent). 
+   * The visible amount can be used by UI delegates to 
+   * determine the size of the thumb.
+   *
+   * @return The visible amount (AKA extent).
+   */
+  public int getVisibleAmount()
+  {
+    return model.getExtent();
+  }
+
+  /**
+   * This method sets the visible amount (AKA extent).
+   *
+   * @param extent The visible amount (AKA extent).
+   */
+  public void setVisibleAmount(int extent)
+  {
+    if (extent != getVisibleAmount())
+    {
+      model.setExtent(extent);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, extent);
+    }
+  }
+
+  /**
+   * This method returns the minimum value of the scrollbar.
+   *
+   * @return The minimum value of the scrollbar.
+   */
+  public int getMinimum()
+  {
+    return model.getMinimum();
+  }
+
+  /**
+   * This method sets the minimum value of the scrollbar.
+   *
+   * @param minimum The minimum value of the scrollbar.
+   */
+  public void setMinimum(int minimum)
+  {
+    if (minimum != getMinimum())
+    {
+      model.setMinimum(minimum);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, minimum);
+    }
+  }
+
+  /**
+   * This method returns the maximum value of the scrollbar.
+   *
+   * @return The maximum value of the scrollbar.
+   */
+  public int getMaximum()
+  {
+    return model.getMaximum();
+  }
+
+  /**
+   * This method sets the maximum value of the scrollbar.
+   *
+   * @param maximum The maximum value of the scrollbar.
+   */
+  public void setMaximum(int maximum)
+  {
+    if (maximum != getMaximum())
+    {
+      model.setMaximum(maximum);
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, maximum);
+    }
+  }
+
+  /**
+   * This method returns the model's isAjusting value.
+   *
+   * @return The model's isAdjusting value.
+   */
+  public boolean getValueIsAdjusting()
+  {
+    return model.getValueIsAdjusting();
+  }
+
+  /**
+   * This method sets the model's isAdjusting value.
+   *
+   * @param b The new isAdjusting value.
+   */
+  public void setValueIsAdjusting(boolean b)
+  {
+    model.setValueIsAdjusting(b);
+  }
+
+  /**
+   * This method sets the value, extent, minimum and 
+   * maximum.
+   *
+   * @param newValue The new value.
+   * @param newExtent The new extent.
+   * @param newMin The new minimum.
+   * @param newMax The new maximum.
+   */
+  public void setValues(int newValue, int newExtent, int newMin, int newMax)
+  {
+    if (!isEnabled())
+      newValue = model.getValue();
+    // It seems to be that on any change the value is fired.
+    if (newValue != getValue() || newExtent != getVisibleAmount() ||
+        newMin != getMinimum() || newMax != getMaximum())
+    {
+      model.setRangeProperties(newValue, newExtent, newMin, newMax,
+                               model.getValueIsAdjusting());
+      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                 AdjustmentEvent.TRACK, newValue);
+    }
+  }
+
+  /**
+   * This method adds an AdjustmentListener to the scroll bar.
+   *
+   * @param listener The listener to add.
+   */
+  public void addAdjustmentListener(AdjustmentListener listener)
+  {
+    listenerList.add(AdjustmentListener.class, listener);
+  }
+
+  /**
+   * This method removes an AdjustmentListener from the scroll bar. 
+   *
+   * @param listener The listener to remove.
+   */
+  public void removeAdjustmentListener(AdjustmentListener listener)
+  {
+    listenerList.remove(AdjustmentListener.class, listener);
+  }
+
+  /**
+   * This method returns an arry of all AdjustmentListeners listening to 
+   * this scroll bar.
+   *
+   * @return An array of AdjustmentListeners listening to this scroll bar.
+   */
+  public AdjustmentListener[] getAdjustmentListeners()
+  {
+    return (AdjustmentListener[]) listenerList.getListeners(AdjustmentListener.class);
+  }
+
+  /**
+   * This method is called to fired AdjustmentEvents to the listeners
+   * of this scroll bar. All AdjustmentEvents that are fired
+   * will have an ID of ADJUSTMENT_VALUE_CHANGED and a type of
+   * TRACK. 
+   *
+   * @param id The ID of the adjustment event.
+   * @param type The Type of change.
+   * @param value The new value for the property that was changed..
+   */
+  protected void fireAdjustmentValueChanged(int id, int type, int value)
+  {
+    Object[] adjustmentListeners = listenerList.getListenerList();
+    AdjustmentEvent adjustmentEvent = new AdjustmentEvent(this, 
+                                            AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+					    AdjustmentEvent.TRACK,
+					    value);
+    for (int i = adjustmentListeners.length - 2; i >= 0; i -= 2)
+      {
+	if (adjustmentListeners[i] == AdjustmentListener.class)
+	  ((AdjustmentListener) adjustmentListeners[i + 1]).adjustmentValueChanged(adjustmentEvent);
+      }
+  }
+
+  /**
+   * This method returns the minimum size for this scroll bar.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize()
+  {
+    return ui.getMinimumSize(this);
+  }
+
+  /**
+   * This method returns the maximum size for this scroll bar.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize()
+  {
+    return ui.getMaximumSize(this);
+  }
+
+  /**
+   * This method overrides the setEnabled in JComponent.
+   * When the scroll bar is disabled, the knob cannot
+   * be moved.
+   *
+   * @param x Whether the scrollbar is enabled.
+   */
+  public void setEnabled(boolean x)
+  {
+    // nothing special needs to be done here since we 
+    // just check the enabled setting before changing the value.
+    super.setEnabled(x);
+  }
+
+  /**
+   * Returns a string describing the attributes for the <code>JScrollBar</code>
+   * component, for use in debugging.  The return value is guaranteed to be 
+   * non-<code>null</code>, but the format of the string may vary between
+   * implementations.
+   *
+   * @return A string describing the attributes of the <code>JScrollBar</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",blockIncrement=").append(blockIncrement);
+    sb.append(",orientation=");
+    if (this.orientation == JScrollBar.HORIZONTAL)
+      sb.append("HORIZONTAL");
+    else 
+      sb.append("VERTICAL");
+    sb.append(",unitIncrement=").append(unitIncrement);
+    return sb.toString();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JScrollBar</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJScrollBar}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJScrollBar();
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollPane.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollPane.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollPane.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JScrollPane.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,710 @@
+/* JScrollPane.java -- 
+   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Rectangle;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.swing.border.Border;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ScrollPaneUI;
+import javax.swing.plaf.UIResource;
+
+/**
+ * A component that embeds another component and enables it to be scrolled
+ * both in horizontal and vertical direction.
+ *
+ * <table>
+ * <tr><th>Property                    </th><th>Stored in       </th><th>Bound?</th></tr>
+ * <tr><td>columnHeader                </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>columnHeaderView            </td><td>columnHeader    </td><td>no    </td></tr>
+ * <tr><td>componentOrientation        </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>horizontalScrollBar         </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>horizontalScrollBarPolicy   </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>layout                      </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>rowHeader                   </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>rowHeaderView               </td><td>rowHeader       </td><td>no    </td></tr>
+ * <tr><td>validateRoot                </td><td>scrollPane      </td><td>no    </td></tr>
+ * <tr><td>verticalScrollBar           </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>verticalScrollBarPolicy     </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>viewport                    </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>viewportBorder              </td><td>scrollPane      </td><td>yes   </td></tr>
+ * <tr><td>viewportBorderBounds        </td><td>scrollPane      </td><td>no    </td></tr>
+ * <tr><td>viewportView                </td><td>viewport        </td><td>no    </td></tr>
+ * <tr><td>wheelScrollingEnabled       </td><td>scrollPane      </td><td>yes   </td></tr>
+ * </table>
+ */
+public class JScrollPane extends JComponent
+  implements Accessible, ScrollPaneConstants
+{
+  /**
+   * Provides accessibility support for the <code>JScrollPane</code>.
+   *
+   * @author Roman Kennke (kennke at aicas.com)
+   */
+  protected class AccessibleJScrollPane extends AccessibleJComponent
+    implements ChangeListener, PropertyChangeListener
+  {
+
+    /**
+     * The viewport of the underlying scrollpane.
+     */
+    protected JViewport viewPort;
+
+    /**
+     * Creates a new <code>AccessibleJScrollPane</code> object. This
+     * initializes the <code>viewport</code> field with the current viewport
+     * from the scrollpane associated with this
+     * <code>AccessibleJScrollPane</code>.
+     */
+    public AccessibleJScrollPane()
+    {
+      viewPort = getViewport();
+      viewPort.addChangeListener(this);
+      viewPort.addPropertyChangeListener(this);
+    }
+
+    /**
+     * Receives notification when the state of the viewport changes.
+     *
+     * @param event the change event
+     */
+    public void stateChanged(ChangeEvent event)
+    {
+      // TODO: Figure out what should be done here, if anything.
+    }
+
+    /**
+     * Receives notification if any of the viewport's bound properties changes.
+     *
+     * @param e the propery change event
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      // TODO: Figure out what should be done here, if anything.
+    }
+
+    /**
+     * Resets the <code>viewPort</code> field when the scrollpane's viewport
+     * changes. This method is called by
+     * {@link JScrollPane#setViewport(JViewport)} in order to update the
+     * <code>viewPort</code> field and set up the listeners on this viewport
+     * correctly.
+     */
+    public void resetViewPort()
+    {
+      viewPort.removeChangeListener(this);
+      viewPort.removePropertyChangeListener(this);
+      viewPort = getViewport();
+      viewPort.addChangeListener(this);
+      viewPort.addPropertyChangeListener(this);
+    }
+  }
+
+  private static final long serialVersionUID = 5203525440012340014L;
+  
+  protected JViewport columnHeader;
+  protected JViewport rowHeader;
+
+  protected Component lowerLeft;
+  protected Component lowerRight;
+  protected Component upperLeft;
+  protected Component upperRight;
+
+  protected JScrollBar horizontalScrollBar;
+  protected int horizontalScrollBarPolicy;
+  protected JScrollBar verticalScrollBar;
+  protected int verticalScrollBarPolicy;
+
+  protected JViewport viewport;
+  
+  Border viewportBorder;
+  boolean wheelScrollingEnabled;
+
+  public JViewport getColumnHeader()
+  {
+    return columnHeader;
+  }
+
+  public Component getCorner(String key) 
+  {
+    if (getComponentOrientation() 
+        == ComponentOrientation.LEFT_TO_RIGHT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_LEFT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+      }
+    else if (getComponentOrientation() 
+             == ComponentOrientation.RIGHT_TO_LEFT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_LEFT_CORNER;
+      }
+
+    if (key == LOWER_RIGHT_CORNER)
+      return lowerRight;
+    else if (key == UPPER_RIGHT_CORNER)
+      return upperRight;
+    else if (key == LOWER_LEFT_CORNER)
+      return lowerLeft;
+    else if (key == UPPER_LEFT_CORNER)
+      return upperLeft;
+    return null;
+  }
+
+  public JScrollBar getHorizontalScrollBar()
+  {
+    return horizontalScrollBar;
+  }
+
+  public int getHorizontalScrollBarPolicy()
+  {
+    return horizontalScrollBarPolicy;
+  }
+
+  public JViewport getRowHeader()
+  {
+    return rowHeader;
+  }
+
+  public JScrollBar getVerticalScrollBar()
+  {
+    return verticalScrollBar;
+  }
+
+  public int getVerticalScrollBarPolicy()
+  {
+    return verticalScrollBarPolicy;
+  }
+
+  public JViewport getViewport()
+  {
+    return viewport;
+  }
+
+  public Border getViewportBorder()
+  {
+    return viewportBorder;
+  }
+
+  public Rectangle getViewportBorderBounds()
+  {
+    if (viewportBorder == null)
+      {
+        if (getViewport() == null)
+          return new Rectangle(0, 0, 0, 0);
+        else
+          return getViewport().getBounds();
+      }
+    else
+      {
+        Insets i = viewportBorder.getBorderInsets(getViewport());
+        if (getViewport() == null)
+          return new Rectangle(0, 0, i.left + i.right, i.top + i.bottom);
+        else
+          {
+            Rectangle b = getViewport().getBounds();
+            return new Rectangle(b.x - i.left, 
+                                 b.y - i.top,
+                                 b.width + i.left + i.right, 
+                                 b.height + i.top + i.bottom);
+          }
+      }
+  }
+  
+  public boolean isWheelScrollingEnabled()
+  {
+    return wheelScrollingEnabled;
+  }
+
+
+
+  private void sync()
+  {
+    LayoutManager m = super.getLayout();
+    if (m != null && m instanceof ScrollPaneLayout)
+      {
+        ScrollPaneLayout sl = (ScrollPaneLayout) m;
+        sl.syncWithScrollPane(this);
+      }
+  }
+
+  private void removeNonNull(Component c)
+  {
+    if (c != null)
+      remove(c);
+  }
+
+  private void addNonNull(Component c, Object constraints)
+  {
+    if (c != null)
+      add(c, constraints);
+  }
+
+  public void setComponentOrientation(ComponentOrientation co)
+  {
+    ComponentOrientation old = super.getComponentOrientation();
+    super.setComponentOrientation(co);
+    firePropertyChange("componentOrientation", old, co);
+    sync();
+  }
+
+  public void setColumnHeader(JViewport h)
+  {
+    if (columnHeader == h)
+      return;
+    
+    JViewport old = columnHeader;
+    removeNonNull(old);
+    columnHeader = h;
+    addNonNull(h, JScrollPane.COLUMN_HEADER);
+    firePropertyChange("columnHeader", old, h);
+    sync();
+  }
+
+  public void setColumnHeaderView(Component c)
+  {
+    if (columnHeader == null)
+      setColumnHeader(createViewport());
+    columnHeader.setView(c);
+    sync();
+  }
+
+  public void setCorner(String key, Component c)
+  {
+    if (getComponentOrientation() 
+        == ComponentOrientation.LEFT_TO_RIGHT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_LEFT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+      }
+    else if (getComponentOrientation() 
+             == ComponentOrientation.RIGHT_TO_LEFT)
+      {
+        if (key == LOWER_LEADING_CORNER)
+          key = LOWER_RIGHT_CORNER;
+        else if (key == LOWER_TRAILING_CORNER)
+          key = LOWER_LEFT_CORNER;
+        else if (key == UPPER_LEADING_CORNER)
+          key = UPPER_RIGHT_CORNER;
+        else if (key == UPPER_TRAILING_CORNER)
+          key = UPPER_LEFT_CORNER;
+      }
+
+    if (key == LOWER_RIGHT_CORNER)
+      {
+        removeNonNull(lowerRight);
+        lowerRight = c;
+        addNonNull(c, JScrollPane.LOWER_RIGHT_CORNER);
+      }
+    else if (key == UPPER_RIGHT_CORNER)
+      {
+        removeNonNull(upperRight);
+        upperRight = c;
+        addNonNull(c, JScrollPane.UPPER_RIGHT_CORNER);
+      }
+    else if (key == LOWER_LEFT_CORNER)
+      {
+        removeNonNull(lowerLeft);
+        lowerLeft = c;
+        addNonNull(c, JScrollPane.LOWER_LEFT_CORNER);
+      }
+    else if (key == UPPER_LEFT_CORNER)
+      {
+        removeNonNull(upperLeft);
+        upperLeft = c;
+        addNonNull(c, JScrollPane.UPPER_LEFT_CORNER);
+      }
+    else
+      throw new IllegalArgumentException("unknown corner " + key);
+    sync();
+  }
+
+  public void setHorizontalScrollBar(JScrollBar h)
+  {
+    if (horizontalScrollBar == h)
+      return;
+
+    JScrollBar old = horizontalScrollBar;
+    removeNonNull(old);
+    horizontalScrollBar = h;
+    addNonNull(h, JScrollPane.HORIZONTAL_SCROLLBAR);
+    firePropertyChange("horizontalScrollBar", old, h);
+    sync();
+
+  }
+
+  public void setHorizontalScrollBarPolicy(int h)
+  {
+    if (horizontalScrollBarPolicy == h)
+      return;
+    
+    if (h != HORIZONTAL_SCROLLBAR_AS_NEEDED
+        && h != HORIZONTAL_SCROLLBAR_NEVER
+        && h != HORIZONTAL_SCROLLBAR_ALWAYS)
+      throw new IllegalArgumentException("unknown horizontal scrollbar policy");    
+
+    int old = horizontalScrollBarPolicy;
+    horizontalScrollBarPolicy = h;
+    firePropertyChange("horizontalScrollBarPolicy", old, h);
+    sync();
+    revalidate();
+  }
+
+  public void setLayout(LayoutManager l)
+  {
+    LayoutManager old = super.getLayout();
+    ScrollPaneLayout tmp = (ScrollPaneLayout) l;
+    super.setLayout(l);
+    tmp.syncWithScrollPane(this);
+    firePropertyChange("layout", old, l);
+    sync();
+  }
+
+  public void setRowHeader(JViewport v)
+  {
+    if (rowHeader == v)
+      return;
+    
+    JViewport old = rowHeader;
+    removeNonNull(old);
+    rowHeader = v;
+    addNonNull(v, JScrollPane.ROW_HEADER);
+    firePropertyChange("rowHeader", old, v);
+    sync();
+  }
+
+  public void setRowHeaderView(Component c)
+  {
+    if (rowHeader == null)
+      setRowHeader(createViewport());
+    rowHeader.setView(c);
+    sync();
+  }
+
+  public void setVerticalScrollBar(JScrollBar v)
+  {
+    if (verticalScrollBar == v)
+      return;
+    
+    JScrollBar old = verticalScrollBar;
+    removeNonNull(old);
+    verticalScrollBar = v;
+    addNonNull(v, JScrollPane.VERTICAL_SCROLLBAR);
+    firePropertyChange("verticalScrollBar", old, v);
+    sync();
+  }
+
+  public void setVerticalScrollBarPolicy(int v)
+  {
+    if (verticalScrollBarPolicy == v)
+      return;
+    
+    if (v != VERTICAL_SCROLLBAR_AS_NEEDED
+        && v != VERTICAL_SCROLLBAR_NEVER
+        && v != VERTICAL_SCROLLBAR_ALWAYS)
+      throw new IllegalArgumentException("unknown vertical scrollbar policy");    
+    
+    int old = verticalScrollBarPolicy;
+    verticalScrollBarPolicy = v;
+    firePropertyChange("verticalScrollBarPolicy", old, v);
+    sync();
+    revalidate();
+  }
+
+  public void setWheelScrollingEnabled(boolean b)
+  {
+    if (wheelScrollingEnabled == b)
+      return;
+    
+    boolean old = wheelScrollingEnabled;
+    wheelScrollingEnabled = b;
+    firePropertyChange("wheelScrollingEnabled", old, b);
+    sync();
+  }
+
+  public void setViewport(JViewport v)
+  {
+    if (viewport == v)
+      return;
+    
+    JViewport old = viewport;
+    removeNonNull(old);
+    viewport = v;
+    addNonNull(v, JScrollPane.VIEWPORT);
+    revalidate();
+    repaint();
+    firePropertyChange("viewport", old, v);
+    sync();
+    if (accessibleContext != null)
+      {
+        AccessibleJScrollPane asp = (AccessibleJScrollPane) accessibleContext;
+        asp.resetViewPort();
+      }
+  }
+
+  public void setViewportBorder(Border b)
+  {
+    if (viewportBorder == b)
+      return;
+    
+    Border old = viewportBorder;
+    viewportBorder = b;
+    firePropertyChange("viewportBorder", old, b);
+    sync();
+  }
+    
+  public void setViewportView(Component view)
+  {
+    if (getViewport() == null)
+      {
+        setViewport(createViewport());
+      }
+	
+    if (view != null)
+      {
+        getViewport().setView(view);
+      }
+    sync();
+  }
+
+  public boolean isValidateRoot()
+  {
+    return true;
+  }
+
+  /**
+   * Creates a new <code>JScrollPane</code> without a view. The scrollbar
+   * policy is set to {@link #VERTICAL_SCROLLBAR_AS_NEEDED} and
+   * {@link #HORIZONTAL_SCROLLBAR_AS_NEEDED}.
+   */
+  public JScrollPane() 
+  {
+    this(null);
+  }
+
+  /**
+   * Creates a new <code>JScrollPane</code> that embeds the specified
+   * <code>view</code> component, displaying vertical and horizontal scrollbars
+   * as needed.
+   *
+   * @param view the component that is embedded inside the JScrollPane
+   */
+  public JScrollPane(Component view) 
+  {
+    this(view, 
+         VERTICAL_SCROLLBAR_AS_NEEDED, 
+         HORIZONTAL_SCROLLBAR_AS_NEEDED);
+  }
+
+  /**
+   * Creates a new <code>JScrollPane</code> without a view; The scrollbar
+   * policies are set to <code>vsbPolicy</code> and <code>hsbPolicy</code>.
+   *
+   * @param vsbPolicy the vertical scrollbar policy to set
+   * @param hsbPolicy the vertical scrollbar policy to set
+   *
+   * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS
+   * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED
+   * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER
+   * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS
+   * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED
+   * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER
+   */
+  public JScrollPane(int vsbPolicy, int hsbPolicy) 
+  {
+    this(null, vsbPolicy, hsbPolicy);
+  }
+
+  /**
+   * Creates a new <code>JScrollPane</code> that embeds the specified
+   * <code>view</code> component; The scrollbar
+   * policies are set to <code>vsbPolicy</code> and <code>hsbPolicy</code>.
+   *
+   * @param vsbPolicy the vertical scrollbar policy to set
+   * @param hsbPolicy the vertical scrollbar policy to set
+   *
+   * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS
+   * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED
+   * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER
+   * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS
+   * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED
+   * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER
+   */
+  public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) 
+  {
+    setVerticalScrollBarPolicy(vsbPolicy);
+    setVerticalScrollBar(createVerticalScrollBar());
+    setHorizontalScrollBarPolicy(hsbPolicy);
+    setHorizontalScrollBar(createHorizontalScrollBar());
+    viewport = createViewport();
+    if (view != null)
+      getViewport().setView(view);
+    add(viewport,0);
+    setLayout(new ScrollPaneLayout());
+    setOpaque(false);
+    updateUI();
+  }
+
+  
+  public JScrollBar createHorizontalScrollBar()
+  {
+    return new ScrollBar(SwingConstants.HORIZONTAL);
+  }
+
+  public JScrollBar createVerticalScrollBar()
+  {
+    return new ScrollBar(SwingConstants.VERTICAL);
+  }
+    
+  protected JViewport createViewport()
+  {
+    return new JViewport();
+  }
+
+  public String getUIClassID()
+  {
+    return "ScrollPaneUI";
+  }
+  
+  public void updateUI()
+  {
+    setUI((ScrollPaneUI) UIManager.getUI(this));
+  }  
+
+  /**
+   * This method returns the scrollpane's UI delegate.
+   *
+   * @return The scrollpane's UI delegate.
+   */
+  public ScrollPaneUI getUI()
+  {
+    return (ScrollPaneUI) ui;
+  }
+
+  /**
+   * This method sets the scrollpane's UI delegate.
+   *
+   * @param ui The scrollpane's UI delegate.
+   */
+  public void setUI(ScrollPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  protected class ScrollBar 
+    extends JScrollBar
+    implements UIResource
+  {
+    private static final long serialVersionUID = -42032395320987283L;
+
+    public ScrollBar(int orientation)
+    {
+      super(orientation);
+    }
+
+    public int getBlockIncrement(int direction)
+    {
+      Component view = JScrollPane.this.getViewport().getView();
+      if (view == null || (! (view instanceof Scrollable)))
+        return super.getBlockIncrement(direction);
+      else
+        {
+          Scrollable s = (Scrollable) view;
+          return s.getScrollableBlockIncrement(JScrollPane.this.getViewport().getViewRect(), 
+                                               this.getOrientation(),
+                                               direction);
+        }
+    }
+
+    public int getUnitIncrement(int direction)
+    {
+      Component view = JScrollPane.this.getViewport().getView();
+      if (view == null || (! (view instanceof Scrollable)))
+        return super.getUnitIncrement(direction);
+      else
+        {
+          Scrollable s = (Scrollable) view;
+          return s.getScrollableUnitIncrement(JScrollPane.this.getViewport().getViewRect(), 
+                                              this.getOrientation(),
+                                              direction);
+        }
+    }
+  }
+
+  /**
+   * Returns the accessible context associated with this
+   * <code>JScrollPane</code>.
+   *
+   * @return the accessible context associated with this
+   *         <code>JScrollPane</code>
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJScrollPane();
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSeparator.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSeparator.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSeparator.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSeparator.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,218 @@
+/* JSeparator.java --
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing;
+
+import java.beans.PropertyChangeEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.SeparatorUI;
+
+/**
+ * The JSeparator. It is mostly used to divide/space out
+ * components.
+ */
+public class JSeparator extends JComponent implements SwingConstants,
+                                                      Accessible
+{
+  /**
+   * Provides the accessibility features for the <code>JSeparator</code>
+   * component.
+   */
+  protected class AccessibleJSeparator extends AccessibleJComponent
+  {
+    private static final long serialVersionUID = 916332890553201095L;
+  
+    /**
+     * Creates a new <code>AccessibleJSeparator</code> instance.
+     */
+    protected AccessibleJSeparator()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns the accessible role for the <code>JSeparator</code> component.
+     *
+     * @return {@link AccessibleRole#SEPARATOR}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.SEPARATOR;
+    }
+  }
+
+  private static final long serialVersionUID = 125301223445282357L;
+  
+  /** The orientation of the JSeparator. */
+  private transient int orientation = HORIZONTAL;
+
+  /**
+   * Creates a new horizontal <code>JSeparator</code> object.
+   */
+  public JSeparator()
+  {
+    this(HORIZONTAL);
+  }
+
+  /**
+   * Creates a new <code>JSeparator</code> object with the given orientation.
+   *
+   * @param orientation  the orientation (either {@link #HORIZONTAL} or 
+   *     {@link #VERTICAL}).
+   *     
+   * @throws IllegalArgumentException if <code>orientation</code> is not
+   *     one of the specified values.
+   */
+  public JSeparator(int orientation)
+  {
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a valid orientation.");
+    this.orientation = orientation;
+    updateUI();
+  }
+
+  /**
+   * Returns the UI delegate being used with the <code>JSeparator</code>.
+   *
+   * @return The JSeparator's UI delegate.
+   */
+  public SeparatorUI getUI()
+  {
+    return (SeparatorUI) ui;
+  }
+
+  /**
+   * Sets the separator's UI delegate.
+   *
+   * @param ui  the UI delegate.
+   */
+  public void setUI(SeparatorUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Sets this separator's UI delegate to the default (obtained from the
+   * {@link UIManager}) for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((SeparatorUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Returns the suffix (<code>"SeparatorUI"</code> in this case) used to 
+   * determine the class name for a UI delegate that can provide the look and 
+   * feel for a <code>JSeparator</code>.
+   *
+   * @return <code>"SeparatorUI"</code>.
+   */
+  public String getUIClassID()
+  {
+    return "SeparatorUI";
+  }
+
+  /**
+   * Returns the orientation of the <code>JSeparator</code>.
+   *
+   * @return The orientation (one of {@link #HORIZONTAL} and {@link #VERTICAL}).
+   * 
+   * @see #setOrientation(int)
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * Sets the orientation for the <code>JSeparator</code> and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * <code>orientation</code>) to all registered listeners.
+   *
+   * @param orientation  the orientation (either {@link #HORIZONTAL} or 
+   *     {@link #VERTICAL}).
+   *     
+   * @throws IllegalArgumentException if <code>orientation</code> is not
+   *     one of the specified values.
+   *     
+   * @see #getOrientation()
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a valid orientation.");
+    int old = this.orientation;
+    this.orientation = orientation;
+    firePropertyChange("orientation", old, orientation);
+  }
+
+  /**
+   * Returns an implementation-dependent string describing the attributes of
+   * this <code>JSeparator</code>.
+   *
+   * @return A string describing the attributes of this <code>JSeparator</code>
+   *         (never <code>null</code>).
+   */
+  protected String paramString()
+  {
+    String superParamStr = super.paramString();
+    if (orientation == HORIZONTAL)
+      return superParamStr + ",orientation=HORIZONTAL";
+    else
+      return superParamStr + ",orientation=VERTICAL";
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JSeparator</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJSeparator}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJSeparator();
+    
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSlider.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSlider.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSlider.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSlider.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1115 @@
+/* JSlider.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Dimension;
+import java.awt.MenuContainer;
+import java.awt.image.ImageObserver;
+import java.beans.PropertyChangeEvent;
+import java.io.Serializable;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.SliderUI;
+
+/**
+ * A visual component that allows selection of a value within a
+ * range by adjusting a thumb in a track. The values for the minimum,
+ * maximum, extent and value are stored in a {@link
+ * DefaultBoundedRangeModel}.
+ * <p>
+ * A <code>JSlider</code> component has the following properties:
+ * </p>
+ * 
+ * <table>
+ * <tr><th> Property         </th><th> Stored in </th><th> Bound? </th></tr>
+ * <tr><td> extent           </td><td> model     </td><td> no     </td></tr>
+ * <tr><td> inverted         </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> labelTable       </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> majorTickSpacing </td><td> slider    </td><td> yes    </td></tr> 
+ * <tr><td> maximum          </td><td> model     </td><td> yes     </td></tr>
+ * <tr><td> minimum          </td><td> model     </td><td> yes     </td></tr>
+ * <tr><td> minorTickSpacing </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> model            </td><td> slider    </td><td> yes    </td></tr> 
+ * <tr><td> orientation      </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> paintLabels      </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> paintTicks       </td><td> slider    </td><td> yes    </td></tr>
+ * <tr><td> snapToTicks      </td><td> slider    </td><td> yes     </td></tr>
+ * <tr><td> value            </td><td> model     </td><td> no     </td></tr>
+ * <tr><td> valueIsAdjusting </td><td> model     </td><td> no     </td></tr>
+ * </table>
+ * 
+ * <p>
+ * The various behavioural aspects of these properties follows:
+ * </p>
+ * 
+ * <ul>
+ * <li>
+ * When a non-bound property stored in the slider changes, the slider fires
+ * a {@link ChangeEvent} to its change listeners.
+ * </li>
+ * <li>
+ * When a bound property stored in the slider changes, the slider fires a
+ * {@link PropertyChangeEvent} to its property change listeners.
+ * </li>
+ * <li>
+ * If any of the model's properties change, it fires a {@link ChangeEvent} to 
+ * its listeners, which include the slider.
+ * </li>
+ * <li>
+ * If the slider receives a {@link ChangeEvent} from its model, it will 
+ * propagate the event to its own change listeners, with the event's "source"
+ * property set to refer to the slider, rather than the model.
+ * </li>
+ * </ul>
+ */
+public class JSlider extends JComponent implements SwingConstants, Accessible,
+                                                   ImageObserver,
+                                                   MenuContainer, Serializable
+{
+  private static final long serialVersionUID = -1441275936141218479L;
+
+  /**
+   * Provides the accessibility features for the <code>JSlider</code>
+   * component.
+   */
+  protected class AccessibleJSlider extends JComponent.AccessibleJComponent
+    implements AccessibleValue
+  {
+    private static final long serialVersionUID = -6301740148041106789L;
+  
+    /**
+     * Creates a new <code>AccessibleJSlider</code> instance.
+     */
+    protected AccessibleJSlider()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns a set containing the current state of the {@link JSlider} 
+     * component.
+     *
+     * @return The accessible state set.
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleStateSet result = super.getAccessibleStateSet();
+      if (orientation == JSlider.HORIZONTAL)
+        result.add(AccessibleState.HORIZONTAL);
+      else if (orientation == JSlider.VERTICAL)
+        result.add(AccessibleState.VERTICAL);
+      return result;
+    }
+
+    /**
+     * Returns the accessible role for the <code>JSlider</code> component.
+     *
+     * @return {@link AccessibleRole#SLIDER}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.SLIDER;
+    }
+
+    /**
+     * Returns an object that provides access to the current, minimum and 
+     * maximum values for the {@link JSlider}.  Since this class implements 
+     * {@link AccessibleValue}, it returns itself.
+     *
+     * @return The accessible value.
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the current value of the {@link JSlider} component, as an
+     * {@link Integer}.
+     *
+     * @return The current value of the {@link JSlider} component.
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return new Integer(getValue());
+    }
+
+    /**
+     * Sets the current value of the {@link JSlider} component and sends a
+     * {@link PropertyChangeEvent} (with the property name 
+     * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
+     * listeners.  If the supplied value is <code>null</code>, this method 
+     * does nothing and returns <code>false</code>.
+     *
+     * @param value  the new slider value (<code>null</code> permitted).
+     *
+     * @return <code>true</code> if the slider value is updated, and 
+     *     <code>false</code> otherwise.
+     */
+    public boolean setCurrentAccessibleValue(Number value)
+    {
+      if (value == null)
+        return false;
+      Number oldValue = getCurrentAccessibleValue();
+      setValue(value.intValue());
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, 
+                         new Integer(getValue()));
+      return true;
+    }
+
+    /**
+     * Returns the minimum value of the {@link JSlider} component, as an
+     * {@link Integer}.
+     *
+     * @return The minimum value of the {@link JSlider} component.
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return new Integer(getMinimum());
+    }
+
+    /**
+     * Returns the maximum value of the {@link JSlider} component, as an
+     * {@link Integer}.
+     *
+     * @return The maximum value of the {@link JSlider} component.
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return new Integer(getMaximum());
+    }
+  }
+
+  /** Whether or not this slider paints its ticks. */
+  private transient boolean paintTicks;
+
+  /** Whether or not this slider paints its track. */
+  private transient boolean paintTrack = true;
+
+  /** Whether or not this slider paints its labels. */
+  private transient boolean paintLabels;
+
+  /**
+   * A dictionary of (Integer, Component) pairs where each Component is a
+   * JLabel and the Integer determines where the label will be painted.
+   */
+  private transient Dictionary labelTable;
+
+  /** The model used to store the slider's range and current value. */
+  protected BoundedRangeModel sliderModel;
+
+  /** The space/distance between major ticks. */
+  protected int majorTickSpacing;
+
+  /** The space/distance between minor ticks. */
+  protected int minorTickSpacing;
+
+  /** Whether the slider snaps its values to ticks. */
+  protected boolean snapToTicks;
+
+  /** The orientation (horizontal or vertical) of the slider. */
+  protected int orientation = HORIZONTAL;
+
+  /** Whether the slider is inverted. */
+  private transient boolean isInverted;
+
+  /** 
+   * The listener that monitors the slider's model and forwards events to the
+   * slider's listeners (see <code>createChangeListener()</code>). 
+   */
+  protected ChangeListener changeListener;
+
+  /** The change event that is passed to all listeners of this slider. */
+  protected transient ChangeEvent changeEvent;
+
+  /**
+   * Creates a new horizontal <code>JSlider</code> instance with a minimum of 
+   * 0, a maximum of 100, and a value of 50.
+   */
+  public JSlider()
+  {
+    this(HORIZONTAL, 0, 100, 50);
+  }
+
+  /**
+   * Creates a new <code>JSlider</code> instance with the given orientation 
+   * and a minimum of 0, a maximum of 100, and a value of 50.
+   *
+   * @param orientation The orientation of the slider ({@link #HORIZONTAL} or
+   *                    {@link #VERTICAL}).
+   * 
+   * @throws IllegalArgumentException if <code>orientation</code> is not one of
+   *         the specified values.
+   */
+  public JSlider(int orientation)
+  {
+    this(orientation, 0, 100, 50);
+  }
+
+  /**
+   * Creates a new horizontal <code>JSlider</code> instance with the given 
+   * maximum and minimum and a value that is halfway between the minimum and the
+   * maximum.
+   *
+   * @param minimum The minimum value.
+   * @param maximum The maximum value.
+   * 
+   * @throws IllegalArgumentException if <code>minimum</code> is greater than
+   *     <code>maximum</code>.
+   */
+  public JSlider(int minimum, int maximum)
+  {
+    this(HORIZONTAL, minimum, maximum, (maximum + minimum) / 2);
+  }
+
+  /**
+   * Creates a new horizontal <code>JSlider</code> instance with the given 
+   * minimum, maximum, and value.
+   *
+   * @param minimum The minimum value.
+   * @param maximum The maximum value.
+   * @param value The initial value.
+   * 
+   * @throws IllegalArgumentException if <code>value</code> is not in the 
+   *     specified range.
+   * @throws IllegalArgumentException if <code>minimum</code> is greater than
+   *     <code>maximum</code>.
+   */
+  public JSlider(int minimum, int maximum, int value)
+  {
+    this(HORIZONTAL, minimum, maximum, value);
+  }
+
+  /**
+   * Creates a new <code>JSlider</code> instance with the given orientation, 
+   * minimum, maximum, and value.
+   *
+   * @param orientation The orientation of the slider ({@link #HORIZONTAL} or
+   *                    {@link #VERTICAL}).
+   * @param minimum The minimum value of the JSlider.
+   * @param maximum The maximum value of the JSlider.
+   * @param value The initial value of the JSlider.
+   * 
+   * @throws IllegalArgumentException if <code>orientation</code> is not one of
+   *     the specified values.
+   * @throws IllegalArgumentException if <code>value</code> is not in the 
+   *     specified range.
+   * @throws IllegalArgumentException if <code>minimum</code> is greater than
+   *     <code>maximum</code>.
+   */
+  public JSlider(int orientation, int minimum, int maximum, int value)
+  {
+    sliderModel = new DefaultBoundedRangeModel(value, 0, minimum, maximum);
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation 
+                                         + " is not a legal orientation");
+    this.orientation = orientation;
+    changeListener = createChangeListener();
+    sliderModel.addChangeListener(changeListener);
+    updateUI();
+  }
+
+  /**
+   * Creates a new horizontal <code>JSlider</code> instance with the given 
+   * model.
+   *
+   * @param model The model (<code>null</code> not permitted).
+   * 
+   * @throws NullPointerException if <code>model</code> is <code>null</code>.
+   */
+  public JSlider(BoundedRangeModel model)
+  {
+    sliderModel = model;
+    changeListener = createChangeListener();
+    sliderModel.addChangeListener(changeListener);
+    updateUI();
+  }
+
+  /**
+   * Returns the slider's value (from the slider's model).
+   *
+   * @return The value of the slider.
+   * 
+   * @see #setValue(int)
+   */
+  public int getValue()
+  {
+    return sliderModel.getValue();
+  }
+
+  /**
+   * Sets the slider's value and sends a {@link ChangeEvent} to all 
+   * registered listeners.  Note that the model will fire a change event to all
+   * of its registered listeners first (with the model as the event source) and
+   * then the slider will fire another change event to all of its registered
+   * listeners (this time with the slider as the event source).
+   *
+   * @param value  the new value.
+   * 
+   * @see #getValue()
+   */
+  public void setValue(int value)
+  {
+    sliderModel.setValue(value);
+  }
+
+  /**
+   * Returns the slider's UI delegate.
+   *
+   * @return The slider's UI delegate.
+   */
+  public SliderUI getUI()
+  {
+    return (SliderUI) ui;
+  }
+
+  /**
+   * Sets the slider's UI delegate.
+   *
+   * @param ui  the UI delegate.
+   */
+  public void setUI(SliderUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Sets this slider's UI delegate to the default (obtained from the
+   * {@link UIManager}) for the current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((SliderUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Returns the suffix (<code>"SliderUI"</code> in this case) used to 
+   * determine the class name for a UI delegate that can provide the look and 
+   * feel for a <code>JSlider</code>.
+   *
+   * @return <code>"SliderUI"</code>.
+   */
+  public String getUIClassID()
+  {
+    return "SliderUI";
+  }
+
+  /**
+   * Creates a {@link ChangeListener} that is added to the slider's model and
+   * forwards change events generated by the model to the listeners that are
+   * registered with the <code>JSlider</code> (by calling the 
+   * {@link #fireStateChanged} method).
+   *
+   * @return A new listener.
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new ChangeListener()
+      {
+        public void stateChanged(ChangeEvent ce)
+        {
+          // No need to trigger a repaint since the UI listens to the model
+          // as well. All we need to do is pass on the stateChanged event 
+          // to our listeners.
+          fireStateChanged();
+        }
+      };
+  }
+
+  /**
+   * Registers a listener with the slider so that it will receive 
+   * {@link ChangeEvent} notifications.  Note that change events generated
+   * by the slider's model will be forwarded automatically to the slider's
+   * listeners.
+   *
+   * @param listener  the listener to register.
+   * 
+   * @see #removeChangeListener(ChangeListener)
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * Removes a listener from this slider so that it will no longer receive
+   * {@link ChangeEvent} notifications from the slider.
+   *
+   * @param listener The listener to remove.
+   * 
+   * @see #addChangeListener(ChangeListener)
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * Sends a {@link ChangeEvent} to all registered listeners, with this slider 
+   * as the source.
+   */
+  protected void fireStateChanged()
+  {
+    Object[] changeListeners = listenerList.getListenerList();
+    if (changeEvent == null)
+      changeEvent = new ChangeEvent(this);
+    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+      {
+        if (changeListeners[i] == ChangeListener.class)
+          ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+      }
+  }
+
+  /**
+   * Returns an array containing all the {@link ChangeListener} instances 
+   * registered with this slider.  If no listeners are registered, this method
+   * returns an empty array.
+   *
+   * @return An array array containing all the {@link ChangeListener} instances 
+   *     registered with this slider (possibly empty, but never 
+   *     <code>null</code>).
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * Returns the slider's model, which stores the minimum, maximum and current 
+   * values.
+   *
+   * @return The slider's model.
+   * 
+   * @see #setModel(BoundedRangeModel)
+   */
+  public BoundedRangeModel getModel()
+  {
+    return sliderModel;
+  }
+
+  /**
+   * Sets the slider's model and sends a {@link PropertyChangeEvent} (with the
+   * property name "model") to all registered listeners.   The change listener
+   * that the slider registered with the original model is removed and added
+   * to the new model (this ensures that {@link ChangeEvent} notifications 
+   * generated by the model are automatically forwarded to listeners that are
+   * registered with the slider).
+   *
+   * @param model The model to use with the slider.
+   * 
+   * @see #getModel()
+   */
+  public void setModel(BoundedRangeModel model)
+  {
+    // I didn't do the null pointer check on purpose.
+    // If you try it with Sun's, it'll go ahead and set it to null
+    // and bork the next time it tries to access the model.
+    if (model != sliderModel)
+      {
+        BoundedRangeModel oldModel = sliderModel;
+        sliderModel = model;
+        oldModel.removeChangeListener(changeListener);
+        sliderModel.addChangeListener(changeListener);
+        firePropertyChange("model", oldModel, sliderModel);
+      }
+  }
+
+  /**
+   * Returns the minimum value of the slider (from the slider's model).
+   *
+   * @return The minimum value of the slider.
+   * 
+   * @see #setMinimum(int)
+   */
+  public int getMinimum()
+  {
+    return sliderModel.getMinimum();
+  }
+
+  /**
+   * Sets the minimum value of the slider and fires a 
+   * {@link PropertyChangeEvent} (with the property name "minimum") to all
+   * registered listeners.  Note that:
+   * <p>
+   * <ul>
+   * <li>the minimum value is stored in the slider's model (see 
+   *     {@link #getModel()});</li>
+   * <li>in addition to the property change event, the slider also fires a 
+   *     {@link ChangeEvent}.</li>
+   * </ul>
+   * 
+   * @param minimum The minimum value of the slider.
+   * 
+   * @see #getMinimum()
+   */
+  public void setMinimum(int minimum)
+  {
+    int old = sliderModel.getMinimum();
+    sliderModel.setMinimum(minimum);
+    if (minimum != old)
+      firePropertyChange("minimum", old, minimum);
+  }
+
+  /**
+   * Returns the slider's maximum value (obtained from the slider's model).
+   *
+   * @return The maximum value of the slider.
+   * 
+   * @see #setMaximum(int)
+   */
+  public int getMaximum()
+  {
+    return sliderModel.getMaximum();
+  }
+
+  /**
+   * Sets the maximum value of the slider and fires a 
+   * {@link PropertyChangeEvent} (with the property name "maximum") to all
+   * registered listeners.  Note that:
+   * <p>
+   * <ul>
+   * <li>the maximum value is stored in the slider's model (see 
+   *     {@link #getModel()});</li>
+   * <li>in addition to the property change event, the slider also fires a 
+   *     {@link ChangeEvent}.</li>
+   * </ul>
+   *
+   * @param maximum The maximum value of the slider.
+   * 
+   * @see #getMaximum()
+   */
+  public void setMaximum(int maximum)
+  {
+    int old = sliderModel.getMaximum();
+    sliderModel.setMaximum(maximum);
+    if (maximum != old)
+      firePropertyChange("maximum", old, maximum);
+  }
+
+  /**
+   * Returns the <code>valueIsAdjusting</code> flag from the slider's model.
+   *
+   * @return The <code>valueIsAdjusting</code> flag from the slider's model.
+   * 
+   * @see #setValueIsAdjusting(boolean)
+   */
+  public boolean getValueIsAdjusting()
+  {
+    return sliderModel.getValueIsAdjusting();
+  }
+
+  /**
+   * Sets the <code>valueIsAdjusting</code> flag in the slider's model, and 
+   * sends a {@link ChangeEvent} to all registered listeners.
+   *
+   * @param adjusting  the new flag value.
+   * 
+   * @see #getValueIsAdjusting()
+   */
+  public void setValueIsAdjusting(boolean adjusting)
+  {
+    sliderModel.setValueIsAdjusting(adjusting);
+  }
+
+  /**
+   * Returns the slider's extent value, obtained from the slider's model.
+   *
+   * @return The extent value.
+   * 
+   * @see #setExtent(int)
+   */
+  public int getExtent()
+  {
+    return sliderModel.getExtent();
+  }
+
+  /**
+   * Sets the slider's extent value and sends a {@link ChangeEvent} to all 
+   * registered listeners.  Note that the model will fire a change event to all
+   * of its registered listeners first (with the model as the event source) and
+   * then the slider will fire another change event to all of its registered
+   * listeners (this time with the slider as the event source).
+   *
+   * @param extent The extent value for this slider.
+   * 
+   * @see #getExtent()
+   */
+  public void setExtent(int extent)
+  {
+    sliderModel.setExtent(extent);
+  }
+
+  /**
+   * Returns the orientation of the slider, either {@link JSlider#HORIZONTAL}
+   * or {@link JSlider#VERTICAL}.
+   *
+   * @return The orientation of the slider.
+   * 
+   * @see #setOrientation(int)
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * Sets the orientation for the slider and sends a 
+   * {@link PropertyChangeEvent} (with the property name "orientation") to all
+   * registered listeners.
+   *
+   * @param orientation  the orientation (one of {@link JSlider#HORIZONTAL} or
+   *     {@link JSlider#VERTICAL}).
+   *     
+   * @throws IllegalArgumentException if <code>orientation</code> is not one of
+   *     the permitted values.
+   *     
+   * @see #getOrientation()
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != VERTICAL && orientation != HORIZONTAL)
+      throw new IllegalArgumentException(
+          "orientation must be one of: VERTICAL, HORIZONTAL");
+    if (orientation != this.orientation)
+      {
+        int oldOrientation = this.orientation;
+        this.orientation = orientation;
+        firePropertyChange("orientation", oldOrientation, this.orientation);
+      }
+  }
+
+  /**
+   * Returns the label table for the slider.
+   *
+   * @return The label table for the slider (possibly <code>null</code>).
+   * 
+   * @see #setLabelTable(Dictionary)
+   */
+  public Dictionary getLabelTable()
+  {
+    return labelTable;
+  }
+
+  /**
+   * Sets the table of labels for the slider and sends a 
+   * {@link PropertyChangeEvent} (with the property name "labelTable") to all 
+   * registered listeners.
+   *
+   * @param table  the table of labels (<code>null</code> permitted).
+   * 
+   * @see #getLabelTable()
+   */
+  public void setLabelTable(Dictionary table)
+  {
+    if (table != labelTable)
+      {
+        Dictionary oldTable = labelTable;
+        labelTable = table;
+        firePropertyChange("labelTable", oldTable, labelTable);
+      }
+  }
+
+  /**
+   * Resets the UI delegates for the labels in the <code>labelTable</code> to 
+   * the default for the current look and feel.
+   */
+  protected void updateLabelUIs()
+  {
+    if (labelTable == null)
+      return;
+    for (Enumeration list = labelTable.elements(); list.hasMoreElements();)
+      {
+        JLabel label = (JLabel) list.nextElement();
+        label.updateUI();
+      }
+  }
+
+  /**
+   * Creates a hashtable of <code>(Integer, JLabel)</code> pairs that can be 
+   * used as a label table for this slider. The labels will start from the 
+   * slider's minimum and increase by the increment. Each label will have a text
+   * string indicating its integer value.
+   *
+   * @param increment The increment between labels (must be > 0).
+   *
+   * @return A hashtable containing the labels.
+   *
+   * @throws IllegalArgumentException if <code>increment</code> is not greater
+   *         than zero.
+   */
+  public Hashtable createStandardLabels(int increment)
+  {
+    return createStandardLabels(increment, sliderModel.getMinimum());
+  }
+
+  /**
+   * Creates a hashtable of <code>(Integer, JLabel)</code> pairs that can be 
+   * used as a label table for this slider. The labels will start from the 
+   * given start value and increase by the increment. Each  label will have a 
+   * text string indicating its integer value.
+   *
+   * @param increment The increment between labels (must be > 0).
+   * @param start The value to start from.
+   *
+   * @return A hashtable with the labels and their keys.
+   *
+   * @throws IllegalArgumentException if <code>increment</code> is not greater
+   *         than zero, or <code>start</code> is not within the range of the
+   *         model.
+   */
+  public Hashtable createStandardLabels(int increment, int start)
+  {
+    if (increment <= 0) 
+      throw new IllegalArgumentException("Requires 'increment' > 0.");
+    if (start < getMinimum() || start > getMaximum())
+      throw new IllegalArgumentException("The 'start' value is out of range.");
+    Hashtable table = new Hashtable();
+    JLabel label;
+    Dimension dim;
+
+    int max = sliderModel.getMaximum();
+
+    for (int i = start; i <= max; i += increment)
+      {
+        label = new JLabel(String.valueOf(i));
+        label.setVerticalAlignment(CENTER);
+        label.setHorizontalAlignment(CENTER);
+        
+        // Make sure these labels have the width and height
+        // they want.
+        dim = label.getPreferredSize();
+        label.setBounds(label.getX(), label.getY(),
+                        (int) dim.getWidth(),
+                        (int) dim.getHeight()); 
+        table.put(new Integer(i), label);
+      }
+    return table;
+  }
+
+  /**
+   * Returns the flag that controls whether or not the value scale for the
+   * slider is inverted (the default value is <code>false</code>).
+   *
+   * @return The flag that controls whether or not the value scale for the
+   *     slider is inverted.
+   *     
+   * @see #setInverted(boolean)
+   */
+  public boolean getInverted()
+  {
+    return isInverted;
+  }
+
+  /**
+   * Sets the flag that controls whether or not the value scale for the
+   * slider is inverted and, if the new flag value is different to the old flag
+   * value, sends a {@link PropertyChangeEvent} to all registered listeners.
+   * Typically, a horizontal slider will display a scale that increases from 
+   * left to right, but this is reversed if the 'inverted' flag is set to 
+   * <code>true</code>.  Similarly, a vertical slider will display a scale that
+   * increases from bottom to top, and this is reversed if the 'inverted' flag
+   * is set to <code>true</code>.
+   *
+   * @param inverted  the new flag value.
+   * 
+   * @see #getInverted()
+   */
+  public void setInverted(boolean inverted)
+  {
+    if (isInverted != inverted)
+      {
+        boolean oldInverted = isInverted;
+        isInverted = inverted;
+        firePropertyChange("inverted", oldInverted, isInverted);
+      }
+  }
+
+  /**
+   * Returns the distance between major tick marks along the slider's value 
+   * scale.
+   *
+   * @return The amount of units between each major tick mark.
+   * 
+   * @see #setMajorTickSpacing(int)
+   */
+  public int getMajorTickSpacing()
+  {
+    return majorTickSpacing;
+  }
+
+  /**
+   * Sets the distance between major tick marks along the slider's value scale, 
+   * and sends a {@link PropertyChangeEvent} (with the property name 
+   * "majorTickSpacing") to all registered listeners.
+   *
+   * @param spacing  the distance between major tick marks.
+   * 
+   * @see #getMajorTickSpacing()
+   */
+  public void setMajorTickSpacing(int spacing)
+  {
+    if (majorTickSpacing != spacing)
+      {
+        int oldSpacing = majorTickSpacing;
+        majorTickSpacing = spacing;
+        firePropertyChange("majorTickSpacing", oldSpacing, majorTickSpacing);
+      }
+  }
+
+  /**
+   * Returns the distance between minor tick marks along the slider's value 
+   * scale.
+   *
+   * @return The distance between minor tick marks along the slider's value 
+   *     scale.
+   *     
+   * @see #setMinorTickSpacing(int)
+   */
+  public int getMinorTickSpacing()
+  {
+    return minorTickSpacing;
+  }
+
+  /**
+   * Sets the distance between minor tick marks along the slider's value scale, 
+   * and sends a {@link PropertyChangeEvent} (with the property name 
+   * "minorTickSpacing") to all registered listeners.
+   *
+   * @param spacing  the distance between minor tick marks.
+   * 
+   * @see #getMinorTickSpacing()
+   */
+  public void setMinorTickSpacing(int spacing)
+  {
+    if (minorTickSpacing != spacing)
+      {
+        int oldSpacing = minorTickSpacing;
+        minorTickSpacing = spacing;
+        firePropertyChange("minorTickSpacing", oldSpacing, minorTickSpacing);
+      }
+  }
+
+  /**
+   * Returns the flag that controls whether the slider thumb will snap to ticks.
+   * Sliders that snap to ticks will automatically move the thumb to the 
+   * nearest tick mark.
+   *
+   * @return <code>true</code> if the slider thumb automatically.
+   * 
+   * @see #setSnapToTicks(boolean)
+   */
+  public boolean getSnapToTicks()
+  {
+    return snapToTicks;
+  }
+
+  /**
+   * Sets the flag that controls whether the slider thumb will snap to ticks 
+   * and sends a {@link PropertyChangeEvent} (with the property name 
+   * 'snapToTicks') to all registered listeners. Sliders that snap to ticks 
+   * will automatically move the thumb to the nearest tick mark.
+   *
+   * @param snap  the new flag value.
+   * 
+   * @see #getSnapToTicks()
+   */
+  public void setSnapToTicks(boolean snap)
+  {
+    if (snap != snapToTicks)
+      {
+        snapToTicks = snap;
+        firePropertyChange("snapToTicks", !snap, snap);
+      }
+  }
+
+  /**
+   * Returns the flag that controls whether or not tick marks are painted along
+   * the slider's value scale.
+   *
+   * @return <code>true</code> if tick marks should be painted, and 
+   *     <code>false</code> if tick marks should not be painted.
+   *     
+   * @see #setPaintTicks(boolean)
+   */
+  public boolean getPaintTicks()
+  {
+    return paintTicks;
+  }
+
+  /**
+   * Sets the flag that controls whether or not tick marks are painted along
+   * the slider's value scale, and sends a {@link PropertyChangeEvent} (with 
+   * the property name "paintTicks") to all registered listeners. In
+   * addition to setting this property to <code>true</code>, one or both of the
+   * minor tick spacing and major tick spacing attributes must be set to a 
+   * value greater than 0 in order for ticks to be painted.
+   *
+   * @param paint Whether ticks will be painted.
+   * 
+   * @see #getPaintTicks()
+   */
+  public void setPaintTicks(boolean paint)
+  {
+    if (paint != paintTicks)
+      {
+        boolean oldPaintTicks = paintTicks;
+        paintTicks = paint;
+        firePropertyChange("paintTicks", oldPaintTicks, paintTicks);
+      }
+  }
+
+  /**
+   * Returns the flag that controls whether or not the track is painted.
+   *
+   * @return Whether the track will be painted.
+   * 
+   * @see #setPaintTrack(boolean)
+   */
+  public boolean getPaintTrack()
+  {
+    return paintTrack;
+  }
+
+  /**
+   * Sets the flag that controls whether or not the track is painted, and
+   * sends a {@link PropertyChangeEvent} (for the "paintTrack" property) to all
+   * registered listeners.
+   *
+   * @param paint Whether the track will be painted.
+   * 
+   * @see #getPaintTrack()
+   */
+  public void setPaintTrack(boolean paint)
+  {
+    if (paintTrack != paint)
+    {
+      paintTrack = paint;
+      firePropertyChange("paintTrack", !paint, paint);
+    }
+  }
+
+  /**
+   * Returns the flag that controls whether or not labels are painted for the
+   * tick marks along the slider.
+   *
+   * @return Whether labels will be painted.
+   * 
+   * @see #setPaintLabels(boolean)
+   */
+  public boolean getPaintLabels()
+  {
+    return paintLabels;
+  }
+
+  /**
+   * Sets the flag that controls whether or not labels are painted for the
+   * tick marks along the slider and sends a {@link PropertyChangeEvent} (with 
+   * the property name "paintLabels") to all registered listeners.
+   *
+   * @param paint Whether labels will be painted.
+   * 
+   * @see #getPaintLabels()
+   */
+  public void setPaintLabels(boolean paint)
+  {
+    if (paint != paintLabels)
+      {
+        paintLabels = paint;
+        if (paint && majorTickSpacing > 0 && labelTable == null)
+          labelTable = createStandardLabels(majorTickSpacing);
+        firePropertyChange("paintLabels", !paint, paint);
+      }
+  }
+
+  /**
+   * Returns an implementation-dependent string describing the attributes of
+   * this <code>JSlider</code>.
+   *
+   * @return A string describing the attributes of this <code>JSlider</code>
+   *         (never <code>null</code>).
+   */
+  protected String paramString()
+  {
+    String superParamStr = super.paramString();
+    StringBuffer sb = new StringBuffer();
+    sb.append(",isInverted=").append(getInverted());
+    sb.append(",majorTickSpacing=").append(getMajorTickSpacing());
+    sb.append(",minorTickSpacing=").append(getMinorTickSpacing());
+    sb.append(",orientation=");
+    if (orientation == HORIZONTAL)
+      sb.append("HORIZONTAL");
+    else
+      sb.append("VERTICAL");
+    sb.append(",paintLabels=").append(getPaintLabels());
+    sb.append(",paintTicks=").append(getPaintTicks());
+    sb.append(",paintTrack=").append(getPaintTrack());
+    sb.append(",snapToTicks=").append(getSnapToTicks());
+    
+    // the following is output by the reference implementation.  We don't
+    // strictly need to replicate this. Perhaps it has some meaning, but
+    // I couldn't determine it yet...
+    sb.append(",snapToValue=true");
+
+    return superParamStr + sb.toString();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JSlider</code> component.
+   *
+   * @return The accessible context (an instance of {@link AccessibleJSlider}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJSlider();
+    
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSpinner.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSpinner.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSpinner.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSpinner.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,754 @@
+/* JSpinner.java --
+   Copyright (C) 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.SpinnerUI;
+import javax.swing.text.DateFormatter;
+import javax.swing.text.DefaultFormatterFactory;
+import javax.swing.text.NumberFormatter;
+
+/**
+ * A <code>JSpinner</code> is a component that displays a single value from
+ * a sequence of values, and provides a convenient means for selecting the
+ * previous and next values in the sequence.  Typically the spinner displays
+ * a numeric value, but it is possible to display dates or arbitrary items
+ * from a list.
+ *
+ * @author Ka-Hing Cheung
+ * 
+ * @since 1.4
+ */
+public class JSpinner extends JComponent
+{
+  /**
+   * The base class for the editor used by the {@link JSpinner} component.  
+   * The editor is in fact a panel containing a {@link JFormattedTextField}
+   * component.
+   */
+  public static class DefaultEditor 
+    extends JPanel 
+    implements ChangeListener, PropertyChangeListener, LayoutManager
+  {
+    /** The spinner that the editor is allocated to. */
+    private JSpinner spinner;
+
+    /** The JFormattedTextField that backs the editor. */
+    JFormattedTextField ftf;
+
+    /**
+     * For compatability with Sun's JDK 1.4.2 rev. 5
+     */
+    private static final long serialVersionUID = -5317788736173368172L;
+
+    /**
+     * Creates a new <code>DefaultEditor</code> object.  The editor is 
+     * registered with the spinner as a {@link ChangeListener} here.
+     *
+     * @param spinner the <code>JSpinner</code> associated with this editor
+     */
+    public DefaultEditor(JSpinner spinner)
+    {
+      super();
+      setLayout(this);
+      this.spinner = spinner;
+      ftf = new JFormattedTextField();
+      add(ftf);
+      ftf.setValue(spinner.getValue());
+      ftf.addPropertyChangeListener(this);
+      if (getComponentOrientation().isLeftToRight())
+	ftf.setHorizontalAlignment(JTextField.RIGHT);
+      else
+	ftf.setHorizontalAlignment(JTextField.LEFT);
+      spinner.addChangeListener(this);
+    }
+
+    /**
+     * Returns the <code>JSpinner</code> component that the editor is assigned
+     * to.
+     * 
+     * @return The spinner that the editor is assigned to.
+     */
+    public JSpinner getSpinner()
+    {
+      return spinner;
+    }
+    
+    /**
+     * DOCUMENT ME!
+     */
+    public void commitEdit() throws ParseException
+    {
+      // TODO: Implement this properly.
+    }
+
+    /**
+     * Removes the editor from the {@link ChangeListener} list maintained by
+     * the specified <code>spinner</code>.
+     *
+     * @param spinner  the spinner (<code>null</code> not permitted).
+     */
+    public void dismiss(JSpinner spinner)
+    {
+      spinner.removeChangeListener(this);
+    }
+
+    /**
+     * Returns the text field used to display and edit the current value in 
+     * the spinner.
+     *
+     * @return The text field.
+     */
+    public JFormattedTextField getTextField()
+    {
+      return ftf;
+    }
+    
+    /**
+     * Sets the bounds for the child components in this container.  In this
+     * case, the text field is the only component to be laid out.
+     *
+     * @param parent the parent container.
+     */
+    public void layoutContainer(Container parent)
+    {
+      Insets insets = getInsets();
+      Dimension size = getSize();
+      ftf.setBounds(insets.left, insets.top,
+                    size.width - insets.left - insets.right,
+                    size.height - insets.top - insets.bottom);
+    }
+    
+    /**
+     * Calculates the minimum size for this component.  In this case, the
+     * text field is the only subcomponent, so the return value is the minimum
+     * size of the text field plus the insets of this component.
+     *
+     * @param parent  the parent container.
+     *
+     * @return The minimum size.
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      Insets insets = getInsets();
+      Dimension minSize = ftf.getMinimumSize();
+      return new Dimension(minSize.width + insets.left + insets.right,
+                            minSize.height + insets.top + insets.bottom);
+    }
+    
+    /**
+     * Calculates the preferred size for this component.  In this case, the
+     * text field is the only subcomponent, so the return value is the 
+     * preferred size of the text field plus the insets of this component.
+     *
+     * @param parent  the parent container.
+     *
+     * @return The preferred size.
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      Insets insets = getInsets();
+      Dimension prefSize = ftf.getPreferredSize();
+      return new Dimension(prefSize.width + insets.left + insets.right,
+                            prefSize.height + insets.top + insets.bottom);
+    }
+    
+    /**
+     * Receives notification of property changes.  If the text field's 'value' 
+     * property changes, the spinner's model is updated accordingly.
+     *
+     * @param event the event.
+     */
+    public void propertyChange(PropertyChangeEvent event)
+    {
+      if (event.getSource() == ftf) 
+        {
+          if (event.getPropertyName().equals("value"))
+            spinner.getModel().setValue(event.getNewValue());
+        }
+    }
+    
+    /**
+     * Receives notification of changes in the state of the {@link JSpinner}
+     * that the editor belongs to - the content of the text field is updated
+     * accordingly.  
+     *
+     * @param event  the change event.
+     */
+    public void stateChanged(ChangeEvent event)
+    {
+      ftf.setValue(spinner.getValue());
+    }
+    
+    /**
+     * This method does nothing.  It is required by the {@link LayoutManager}
+     * interface, but since this component has a single child, there is no
+     * need to use this method.
+     * 
+     * @param child  the child component to remove.
+     */
+    public void removeLayoutComponent(Component child)
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * This method does nothing.  It is required by the {@link LayoutManager}
+     * interface, but since this component has a single child, there is no
+     * need to use this method.
+     * 
+     * @param name  the name.
+     * @param child  the child component to add.
+     */
+    public void addLayoutComponent(String name, Component child)
+    {
+      // Nothing to do here.
+    }
+  }
+
+  /**
+   * A panel containing a {@link JFormattedTextField} that is configured for
+   * displaying and editing numbers.  The panel is used as a subcomponent of
+   * a {@link JSpinner}.
+   * 
+   * @see JSpinner#createEditor(SpinnerModel)
+   */
+  public static class NumberEditor extends DefaultEditor
+  {
+    /**
+     * For compatability with Sun's JDK
+     */
+    private static final long serialVersionUID = 3791956183098282942L;
+
+    /**
+     * Creates a new <code>NumberEditor</code> object for the specified 
+     * <code>spinner</code>.  The editor is registered with the spinner as a 
+     * {@link ChangeListener}.
+     *
+     * @param spinner the component the editor will be used with.
+     */
+    public NumberEditor(JSpinner spinner)
+    {
+      super(spinner);
+      NumberEditorFormatter nef = new NumberEditorFormatter();
+      nef.setMinimum(getModel().getMinimum());
+      nef.setMaximum(getModel().getMaximum());
+      ftf.setFormatterFactory(new DefaultFormatterFactory(nef));
+    }
+
+    /**
+     * Creates a new <code>NumberEditor</code> object.
+     *
+     * @param spinner  the spinner.
+     * @param decimalFormatPattern  the number format pattern.
+     */
+    public NumberEditor(JSpinner spinner, String decimalFormatPattern)
+    {
+      super(spinner);
+      NumberEditorFormatter nef 
+          = new NumberEditorFormatter(decimalFormatPattern);
+      nef.setMinimum(getModel().getMinimum());
+      nef.setMaximum(getModel().getMaximum());
+      ftf.setFormatterFactory(new DefaultFormatterFactory(nef));
+    }
+
+    /**
+     * Returns the format used by the text field.
+     *
+     * @return The format used by the text field.
+     */
+    public DecimalFormat getFormat()
+    {
+      NumberFormatter formatter = (NumberFormatter) ftf.getFormatter();
+      return (DecimalFormat) formatter.getFormat();
+    }
+
+    /**
+     * Returns the model used by the editor's {@link JSpinner} component,
+     * cast to a {@link SpinnerNumberModel}.
+     * 
+     * @return The model.
+     */
+    public SpinnerNumberModel getModel()
+    {
+      return (SpinnerNumberModel) getSpinner().getModel();
+    }
+  }
+  
+  static class NumberEditorFormatter 
+    extends NumberFormatter
+  {
+    public NumberEditorFormatter() 
+    {
+      super(NumberFormat.getInstance());
+    }
+    public NumberEditorFormatter(String decimalFormatPattern)
+    {
+      super(new DecimalFormat(decimalFormatPattern));
+    }
+  }
+
+  /**
+   * A <code>JSpinner</code> editor used for the {@link SpinnerListModel}.
+   * This editor uses a <code>JFormattedTextField</code> to edit the values
+   * of the spinner.
+   *
+   * @author Roman Kennke (kennke at aicas.com)
+   */
+  public static class ListEditor extends DefaultEditor
+  {
+    /**
+     * Creates a new instance of <code>ListEditor</code>.
+     *
+     * @param spinner the spinner for which this editor is used
+     */
+    public ListEditor(JSpinner spinner)
+    {
+      super(spinner);
+    }
+
+    /**
+     * Returns the spinner's model cast as a {@link SpinnerListModel}.
+     * 
+     * @return The spinner's model.
+     */
+    public SpinnerListModel getModel()
+    {
+      return (SpinnerListModel) getSpinner().getModel();
+    }
+  }
+
+  /**
+   * An editor class for a <code>JSpinner</code> that is used
+   * for displaying and editing dates (e.g. that uses
+   * <code>SpinnerDateModel</code> as model).
+   *
+   * The editor uses a {@link JTextField} with the value
+   * displayed by a {@link DateFormatter} instance.
+   */
+  public static class DateEditor extends DefaultEditor
+  {
+
+    /** The serialVersionUID. */
+    private static final long serialVersionUID = -4279356973770397815L;
+
+    /**
+     * Creates a new instance of DateEditor for the specified
+     * <code>JSpinner</code>.
+     *
+     * @param spinner the <code>JSpinner</code> for which to
+     *     create a <code>DateEditor</code> instance
+     */
+    public DateEditor(JSpinner spinner)
+    {
+      super(spinner);
+      DateEditorFormatter nef = new DateEditorFormatter();
+      nef.setMinimum(getModel().getStart());
+      nef.setMaximum(getModel().getEnd());
+      ftf.setFormatterFactory(new DefaultFormatterFactory(nef));
+    }
+
+    /**
+     * Creates a new instance of DateEditor for the specified
+     * <code>JSpinner</code> using the specified date format
+     * pattern.
+     *
+     * @param spinner the <code>JSpinner</code> for which to
+     *     create a <code>DateEditor</code> instance
+     * @param dateFormatPattern the date format to use
+     *
+     * @see SimpleDateFormat#SimpleDateFormat(String)
+     */
+    public DateEditor(JSpinner spinner, String dateFormatPattern)
+    {
+      super(spinner);
+      DateEditorFormatter nef = new DateEditorFormatter(dateFormatPattern);
+      nef.setMinimum(getModel().getStart());
+      nef.setMaximum(getModel().getEnd());
+      ftf.setFormatterFactory(new DefaultFormatterFactory(nef));
+    }
+
+    /**
+     * Returns the <code>SimpleDateFormat</code> instance that is used to
+     * format the date value.
+     *
+     * @return the <code>SimpleDateFormat</code> instance that is used to
+     *     format the date value
+     */
+    public SimpleDateFormat getFormat()
+    {
+      DateFormatter formatter = (DateFormatter) ftf.getFormatter();
+      return (SimpleDateFormat) formatter.getFormat();
+    }
+
+    /**
+     * Returns the {@link SpinnerDateModel} that is edited by this editor.
+     *
+     * @return the <code>SpinnerDateModel</code> that is edited by this editor
+     */
+    public SpinnerDateModel getModel()
+    {
+      return (SpinnerDateModel) getSpinner().getModel();
+    }
+  }
+
+  static class DateEditorFormatter 
+    extends DateFormatter
+  {
+    public DateEditorFormatter() 
+    {
+      super(DateFormat.getInstance());
+    }
+    public DateEditorFormatter(String dateFormatPattern)
+    {
+      super(new SimpleDateFormat(dateFormatPattern));
+    }
+  }
+
+  /** 
+   * A listener that forwards {@link ChangeEvent} notifications from the model
+   * to the {@link JSpinner}'s listeners. 
+   */
+  class ModelListener implements ChangeListener
+  {
+    /**
+     * Creates a new listener.
+     */
+    public ModelListener()
+    {
+      // nothing to do here
+    }
+    
+    /**
+     * Receives notification from the model that its state has changed.
+     * 
+     * @param event  the event (ignored).
+     */
+    public void stateChanged(ChangeEvent event)
+    {
+      fireStateChanged();
+    }
+  }
+
+  /** 
+   * The model that defines the current value and permitted values for the 
+   * spinner. 
+   */
+  private SpinnerModel model;
+
+  /** The current editor. */
+  private JComponent editor;
+
+  private static final long serialVersionUID = 3412663575706551720L;
+
+  /**
+   * Creates a new <code>JSpinner</code> with default instance of 
+   * {@link SpinnerNumberModel} (that is, a model with value 0, step size 1, 
+   * and no upper or lower limit).
+   *
+   * @see javax.swing.SpinnerNumberModel
+   */
+  public JSpinner()
+  {
+    this(new SpinnerNumberModel());
+  }
+
+  /**
+   * Creates a new <code>JSpinner with the specified model.  The 
+   * {@link #createEditor(SpinnerModel)} method is used to create an editor
+   * that is suitable for the model.
+   *
+   * @param model the model (<code>null</code> not permitted).
+   * 
+   * @throws NullPointerException if <code>model</code> is <code>null</code>.
+   */
+  public JSpinner(SpinnerModel model)
+  {
+    this.model = model;
+    this.editor = createEditor(model);
+    model.addChangeListener(new ModelListener());
+    updateUI();
+  }
+
+  /**
+   * If the editor is <code>JSpinner.DefaultEditor</code>, then forwards the
+   * call to it, otherwise do nothing.
+   *
+   * @throws ParseException DOCUMENT ME!
+   */
+  public void commitEdit() throws ParseException
+  {
+    if (editor instanceof DefaultEditor)
+      ((DefaultEditor) editor).commitEdit();
+  }
+
+  /**
+   * Gets the current editor
+   *
+   * @return the current editor
+   *
+   * @see #setEditor
+   */
+  public JComponent getEditor()
+  {
+    return editor;
+  }
+
+  /**
+   * Changes the current editor to the new editor. The old editor is
+   * removed from the spinner's {@link ChangeEvent} list.
+   *
+   * @param editor the new editor (<code>null</code> not permitted.
+   *
+   * @throws IllegalArgumentException if <code>editor</code> is 
+   *                                  <code>null</code>.
+   *
+   * @see #getEditor
+   */
+  public void setEditor(JComponent editor)
+  {
+    if (editor == null)
+      throw new IllegalArgumentException("editor may not be null");
+
+    JComponent oldEditor = this.editor;
+    if (oldEditor instanceof DefaultEditor)
+      ((DefaultEditor) oldEditor).dismiss(this);
+    else if (oldEditor instanceof ChangeListener)
+      removeChangeListener((ChangeListener) oldEditor);
+    
+    this.editor = editor;
+    firePropertyChange("editor", oldEditor, editor);
+  }
+
+  /**
+   * Returns the model used by the {@link JSpinner} component.
+   *
+   * @return The model.
+   * 
+   * @see #setModel(SpinnerModel)
+   */
+  public SpinnerModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * Sets a new underlying model.
+   *
+   * @param newModel the new model to set
+   *
+   * @exception IllegalArgumentException if newModel is <code>null</code>
+   */
+  public void setModel(SpinnerModel newModel)
+  {
+    if (newModel == null)
+      throw new IllegalArgumentException();
+    
+    if (model == newModel)
+      return;
+
+    SpinnerModel oldModel = model;
+    model = newModel;
+    firePropertyChange("model", oldModel, newModel);
+    setEditor(createEditor(model));
+  }
+
+  /**
+   * Gets the next value without changing the current value.
+   *
+   * @return the next value
+   *
+   * @see javax.swing.SpinnerModel#getNextValue
+   */
+  public Object getNextValue()
+  {
+    return model.getNextValue();
+  }
+
+  /**
+   * Gets the previous value without changing the current value.
+   *
+   * @return the previous value
+   *
+   * @see javax.swing.SpinnerModel#getPreviousValue
+   */
+  public Object getPreviousValue()
+  {
+    return model.getPreviousValue();
+  }
+
+  /**
+   * Gets the <code>SpinnerUI</code> that handles this spinner
+   *
+   * @return the <code>SpinnerUI</code>
+   */
+  public SpinnerUI getUI()
+  {
+    return (SpinnerUI) ui;
+  }
+
+  /**
+   * Gets the current value of the spinner, according to the underly model,
+   * not the UI.
+   *
+   * @return the current value
+   *
+   * @see javax.swing.SpinnerModel#getValue
+   */
+  public Object getValue()
+  {
+    return model.getValue();
+  }
+
+  /**
+   * Sets the value in the model.
+   *
+   * @param value the new value.
+   */
+  public void setValue(Object value)
+  {
+    model.setValue(value);
+  }
+
+  /**
+   * Returns the ID that identifies which look and feel class will be
+   * the UI delegate for this spinner.
+   *
+   * @return <code>"SpinnerUI"</code>.
+   */
+  public String getUIClassID()
+  {
+    return "SpinnerUI";
+  }
+
+  /**
+   * This method resets the spinner's UI delegate to the default UI for the
+   * current look and feel.
+   */
+  public void updateUI()
+  {
+    setUI((SpinnerUI) UIManager.getUI(this));
+  }
+
+  /**
+   * Sets the UI delegate for the component.
+   *
+   * @param ui The spinner's UI delegate.
+   */
+  public void setUI(SpinnerUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * Adds a <code>ChangeListener</code>
+   *
+   * @param listener the listener to add
+   */
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  /**
+   * Remove a particular listener
+   *
+   * @param listener the listener to remove
+   */
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  /**
+   * Gets all the <code>ChangeListener</code>s
+   *
+   * @return all the <code>ChangeListener</code>s
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * Fires a <code>ChangeEvent</code> to all the <code>ChangeListener</code>s
+   * added to this <code>JSpinner</code>
+   */
+  protected void fireStateChanged()
+  {
+    ChangeEvent evt = new ChangeEvent(this);
+    ChangeListener[] listeners = getChangeListeners();
+
+    for (int i = 0; i < listeners.length; ++i)
+      listeners[i].stateChanged(evt);
+  }
+
+  /**
+   * Creates an editor that is appropriate for the specified <code>model</code>.
+   *
+   * @param model the model.
+   *
+   * @return The editor.
+   */
+  protected JComponent createEditor(SpinnerModel model)
+  {
+    if (model instanceof SpinnerDateModel)
+      return new DateEditor(this);
+    else if (model instanceof SpinnerNumberModel)
+      return new NumberEditor(this);
+    else if (model instanceof SpinnerListModel)
+      return new ListEditor(this);
+    else
+      return new DefaultEditor(this);
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSplitPane.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSplitPane.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSplitPane.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JSplitPane.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,946 @@
+/* JSplitPane.java -- 
+   Copyright (C) 2004, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.beans.PropertyChangeEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleValue;
+import javax.swing.plaf.SplitPaneUI;
+
+/**
+ * This class implements JSplitPane. It is used to divide two components. By
+ * dragging the SplitPane's divider, the user can resize the two components.
+ * Note that the divider cannot resize a component to smaller than it's
+ * minimum size.
+ */
+public class JSplitPane extends JComponent implements Accessible
+{
+
+  /**
+   * Provides the accessibility features for the <code>JSplitPane</code>
+   * component.
+   */
+  protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
+    implements AccessibleValue
+  {
+  private static final long serialVersionUID = -1788116871416305366L;
+  
+    /**
+     * Creates a new <code>AccessibleJSplitPane</code> instance.
+     */
+    protected AccessibleJSplitPane()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns a set containing the current state of the {@link JSplitPane} 
+     * component.
+     *
+     * @return The accessible state set.
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleStateSet result = super.getAccessibleStateSet();
+      if (getOrientation() == HORIZONTAL_SPLIT)
+        {
+          result.add(AccessibleState.HORIZONTAL);
+        }
+      else if (getOrientation() == VERTICAL_SPLIT)
+        {
+          result.add(AccessibleState.VERTICAL);
+        }
+      return result;
+    }
+
+    /**
+     * Returns the accessible role for the <code>JSplitPane</code> component.
+     *
+     * @return {@link AccessibleRole#SPLIT_PANE}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.SPLIT_PANE;
+    }
+
+    /**
+     * Returns an object that provides access to the current, minimum and 
+     * maximum values for the {@link JSplitPane}.  Since this class implements 
+     * {@link AccessibleValue}, it returns itself.
+     *
+     * @return The accessible value.
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the current divider location for the {@link JSplitPane} 
+     * component, as an {@link Integer}.
+     *
+     * @return The current divider location.
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return new Integer(getDividerLocation());
+    }
+
+    /**
+     * Sets the divider location for the {@link JSplitPane} component and sends 
+     * a {@link PropertyChangeEvent} (with the property name 
+     * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
+     * listeners.  If the supplied value is <code>null</code>, this method 
+     * does nothing and returns <code>false</code>.
+     *
+     * @param value  the new divider location (<code>null</code> permitted).
+     *
+     * @return <code>true</code> if the divider location value is updated, and 
+     *     <code>false</code> otherwise.
+     */
+    public boolean setCurrentAccessibleValue(Number value)
+    {
+      if (value == null)
+        return false;
+      Number oldValue = getCurrentAccessibleValue();
+      setDividerLocation(value.intValue());
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, 
+                         new Integer(value.intValue()));
+      return true;
+    }
+
+    /**
+     * Returns the minimum divider location for the {@link JSplitPane} 
+     * component, as an {@link Integer}.
+     *
+     * @return The minimum divider location.
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return new Integer(getMinimumDividerLocation());
+    }
+
+    /**
+     * Returns the maximum divider location for the {@link JSplitPane} 
+     * component, as an {@link Integer}.
+     *
+     * @return The maximum divider location.
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return new Integer(getMaximumDividerLocation());
+    }
+  }
+
+  private static final long serialVersionUID = -5634142046175988380L;
+  
+  /** The constraints string used to add components to the bottom. */
+  public static final String BOTTOM = "bottom";
+
+  /** The property fired when the continuousLayout property changes. */
+  public static final String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";
+
+  /** The property fired when the divider property changes. */
+  public static final String DIVIDER = "divider";
+
+  /** The property fired when the divider location property changes. */
+  public static final String DIVIDER_LOCATION_PROPERTY = "dividerLocation";
+
+  /** The property fired when the divider size property changes. */
+  public static final String DIVIDER_SIZE_PROPERTY = "dividerSize";
+
+  /**
+   * The value of the orientation when the components are split horizontally.
+   */
+  public static final int HORIZONTAL_SPLIT = 1;
+
+  /** The property fired when the last divider location property changes. */
+  public static final String LAST_DIVIDER_LOCATION_PROPERTY = 
+    "lastDividerLocation";
+
+  /** The constraints string used to add components to the left. */
+  public static final String LEFT = "left";
+
+  /** The property fired when the one touch expandable property changes. */
+  public static final String ONE_TOUCH_EXPANDABLE_PROPERTY = 
+    "oneTouchExpandable";
+
+  /** The property fired when the orientation property changes. */
+  public static final String ORIENTATION_PROPERTY = "orientation";
+
+  /** The property fired when the resize weight property changes. */
+  public static final String RESIZE_WEIGHT_PROPERTY = "resizeWeight";
+
+  /** The constraints string used to add components to the right. */
+  public static final String RIGHT = "right";
+
+  /** The constraints string used to add components to the top. */
+  public static final String TOP = "top";
+
+  /** The value of the orientation when the components are split vertically. */
+  public static final int VERTICAL_SPLIT = 0;
+
+  /** Whether the JSplitPane uses continuous layout. */
+  protected boolean continuousLayout;
+
+  /** Whether the JSplitPane uses one touch expandable buttons. */
+  protected boolean oneTouchExpandable = false;
+
+  // This is the master dividerSize variable and sets the 
+  // BasicSplitPaneDivider one accordingly
+
+  /** The size of the divider. */
+  protected int dividerSize = 10;
+
+  /** The last location of the divider given by the UI. */
+  protected int lastDividerLocation;
+
+  /** The orientation of the JSplitPane. */
+  protected int orientation;
+
+  /** The component on the top or left. */
+  protected Component leftComponent;
+
+  /** The component on the right or bottom. */
+  protected Component rightComponent;
+
+  /** Determines how extra space should be allocated. */
+  private transient double resizeWeight;
+
+  /**
+   * Indicates if the dividerSize property has been set by a client program or
+   * by the UI.
+   *
+   * @see #setUIProperty(String, Object)
+   * @see LookAndFeel#installProperty(JComponent, String, Object)
+   */
+  private boolean clientDividerSizeSet = false;
+
+  /**
+   * Indicates if the oneTouchExpandable property has been set by a client
+   * program or by the UI.
+   *
+   * @see #setUIProperty(String, Object)
+   * @see LookAndFeel#installProperty(JComponent, String, Object)
+   */
+  private boolean clientOneTouchExpandableSet = false;
+
+  /**
+   * Creates a new JSplitPane object with the given orientation, layout mode,
+   * and left and right components.
+   *
+   * @param newOrientation The orientation to use.
+   * @param newContinuousLayout The layout mode to use.
+   * @param newLeftComponent The left component.
+   * @param newRightComponent The right component.
+   *
+   * @throws IllegalArgumentException DOCUMENT ME!
+   */
+  public JSplitPane(int newOrientation, boolean newContinuousLayout,
+                    Component newLeftComponent, Component newRightComponent)
+  {
+    if (newOrientation != HORIZONTAL_SPLIT && newOrientation != VERTICAL_SPLIT)
+      throw new IllegalArgumentException("orientation is invalid.");
+    orientation = newOrientation;
+    continuousLayout = newContinuousLayout;
+    setLeftComponent(newLeftComponent);
+    setRightComponent(newRightComponent);
+
+    updateUI();
+  }
+
+  /**
+   * Creates a new JSplitPane object using nonContinuousLayout mode, the given
+   * orientation and left and right components.
+   *
+   * @param newOrientation The orientation to use.
+   * @param newLeftComponent The left component.
+   * @param newRightComponent The right component.
+   */
+  public JSplitPane(int newOrientation, Component newLeftComponent,
+                    Component newRightComponent)
+  {
+    this(newOrientation, false, newLeftComponent, newRightComponent);
+  }
+
+  /**
+   * Creates a new JSplitPane object with the given layout mode and
+   * orientation.
+   *
+   * @param newOrientation The orientation to use.
+   * @param newContinuousLayout The layout mode to use.
+   */
+  public JSplitPane(int newOrientation, boolean newContinuousLayout)
+  {
+    this(newOrientation, newContinuousLayout, null, null);
+  }
+
+  /**
+   * Creates a new JSplitPane object using a nonContinuousLayout mode and the
+   * given orientation.
+   *
+   * @param newOrientation The orientation to use.
+   */
+  public JSplitPane(int newOrientation)
+  {
+    this(newOrientation, false, null, null);
+  }
+
+  /**
+   * Creates a new JSplitPane object using HORIZONTAL_SPLIT and a
+   * nonContinuousLayout mode.
+   */
+  public JSplitPane()
+  {
+    this(HORIZONTAL_SPLIT, false, new JButton("left button"),
+         new JButton("right button"));
+  }
+
+  /**
+   * This method adds a component to the JSplitPane. The constraints object is
+   * a string that identifies where this component should go. If the
+   * constraints is not a known one, it will throw an
+   * IllegalArgumentException. The valid constraints are LEFT, TOP, RIGHT,
+   * BOTTOM and DIVIDER.
+   *
+   * @param comp The component to add.
+   * @param constraints The constraints string to use.
+   * @param index Where to place to component in the list of components.
+   *
+   * @throws IllegalArgumentException When the constraints is not a known 
+   * identifier.
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    int left = 0;
+    int right = 1;
+    int div = 2;
+    int place;
+    if (constraints == null)
+      {
+        if (leftComponent == null)
+          constraints = LEFT;
+        else if (rightComponent == null)
+          constraints = RIGHT;
+      }
+
+    if (constraints instanceof String)
+      {
+        String placement = (String) constraints;
+
+        if (placement.equals(BOTTOM) || placement.equals(RIGHT))
+          {
+            if (rightComponent != null)
+              remove(rightComponent);
+            rightComponent = comp;
+          }
+        else if (placement.equals(LEFT) || placement.equals(TOP))
+          {
+            if (leftComponent != null)
+              remove(leftComponent);
+            leftComponent = comp;
+          }
+        else if (placement.equals(DIVIDER))
+          constraints = null;
+        else
+          throw new 
+            IllegalArgumentException("Constraints is not a known identifier.");
+
+        // If no dividerLocation has been set, then we need to trigger an
+        // initial layout.
+        if (getDividerLocation() != -1)
+          resetToPreferredSizes();
+
+        super.addImpl(comp, constraints, index);
+      }
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JSplitPane</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *     {@link AccessibleJSplitPane}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJSplitPane();
+    
+    return accessibleContext;
+  }
+
+  /**
+   * This method returns the bottom component.
+   *
+   * @return The bottom component.
+   */
+  public Component getBottomComponent()
+  {
+    return rightComponent;
+  }
+
+  /**
+   * This method returns the location of the divider. This method is passed to
+   * the UI.
+   *
+   * @return The location of the divider.
+   */
+  public int getDividerLocation()
+  {
+    if (ui != null)
+      return ((SplitPaneUI) ui).getDividerLocation(this);
+    else
+      return -1;
+  }
+
+  /**
+   * This method returns the size of the divider.
+   *
+   * @return The size of the divider.
+   */
+  public int getDividerSize()
+  {
+    return dividerSize;
+  }
+
+  /**
+   * This method returns the last divider location.
+   *
+   * @return The last divider location.
+   */
+  public int getLastDividerLocation()
+  {
+    return lastDividerLocation;
+  }
+
+  /**
+   * This method returns the left component.
+   *
+   * @return The left component.
+   */
+  public Component getLeftComponent()
+  {
+    return leftComponent;
+  }
+
+  /**
+   * This method returns the maximum divider location. This method is passed
+   * to  the UI.
+   *
+   * @return DOCUMENT ME!
+   */
+  public int getMaximumDividerLocation()
+  {
+    if (ui != null)
+      return ((SplitPaneUI) ui).getMaximumDividerLocation(this);
+    else
+      return -1;
+  }
+
+  /**
+   * This method returns the minimum divider location. This method is passed
+   * to the UI.
+   *
+   * @return The minimum divider location.
+   */
+  public int getMinimumDividerLocation()
+  {
+    if (ui != null)
+      return ((SplitPaneUI) ui).getMinimumDividerLocation(this);
+    else
+      return -1;
+  }
+
+  /**
+   * This method returns the orientation that the JSplitPane is using.
+   *
+   * @return The current orientation.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  }
+
+  /**
+   * This method returns the current resize weight.
+   *
+   * @return The current resize weight.
+   */
+  public double getResizeWeight()
+  {
+    return resizeWeight;
+  }
+
+  /**
+   * This method returns the right component.
+   *
+   * @return The right component.
+   */
+  public Component getRightComponent()
+  {
+    return rightComponent;
+  }
+
+  /**
+   * This method returns the top component.
+   *
+   * @return The top component.
+   */
+  public Component getTopComponent()
+  {
+    return leftComponent;
+  }
+
+  /**
+   * This method returns the UI.
+   *
+   * @return The UI.
+   */
+  public SplitPaneUI getUI()
+  {
+    return (SplitPaneUI) ui;
+  }
+
+  /**
+   * This method returns true if the JSplitPane is using a continuousLayout.
+   *
+   * @return True if using a continuousLayout.
+   */
+  public boolean isContinuousLayout()
+  {
+    return continuousLayout;
+  }
+
+  /**
+   * This method returns true if the divider has one touch expandable buttons.
+   *
+   * @return True if one touch expandable is used.
+   */
+  public boolean isOneTouchExpandable()
+  {
+    return oneTouchExpandable;
+  }
+
+  /**
+   * This method returns true.
+   *
+   * @return true.
+   */
+  public boolean isValidateRoot()
+  {
+    return true;
+  }
+
+  /**
+   * This method overrides JComponent's paintChildren so the UI can be
+   * messaged when the children have finished painting.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  protected void paintChildren(Graphics g)
+  {
+    super.paintChildren(g);
+    if (ui != null)
+      ((SplitPaneUI) ui).finishedPaintingChildren(this, g);
+  }
+
+  /**
+   * Returns an implementation-dependent string describing the attributes of
+   * this <code>JSplitPane</code>.
+   *
+   * @return A string describing the attributes of this <code>JSplitPane</code>
+   *         (never <code>null</code>).
+   */
+  protected String paramString()
+  {
+    // FIXME: the next line can be restored once PR27208 is fixed
+    String superParamStr = ""; //super.paramString();
+    StringBuffer sb = new StringBuffer();
+    sb.append(",continuousLayout=").append(isContinuousLayout());
+    sb.append(",dividerSize=").append(getDividerSize());
+    sb.append(",lastDividerLocation=").append(getLastDividerLocation());
+    sb.append(",oneTouchExpandable=").append(isOneTouchExpandable());
+    sb.append(",orientation=");
+    if (orientation == HORIZONTAL_SPLIT)
+      sb.append("HORIZONTAL_SPLIT");
+    else
+      sb.append("VERTICAL_SPLIT");
+    return superParamStr + sb.toString();
+  }
+
+  /**
+   * This method removes the given component from the JSplitPane.
+   *
+   * @param component The Component to remove.
+   */
+  public void remove(Component component)
+  {
+    if (component == leftComponent)
+      leftComponent = null;
+    else if (component == rightComponent)
+      rightComponent = null;
+    super.remove(component);
+  }
+
+  /**
+   * This method removes the component at the given index.
+   *
+   * @param index The index of the component to remove.
+   */
+  public void remove(int index)
+  {
+    Component component = getComponent(index);
+    if (component == leftComponent)
+      leftComponent = null;
+    else if (component == rightComponent)
+      rightComponent = null;
+    super.remove(index);
+  }
+
+  /**
+   * This method removes all components from the JSplitPane.
+   */
+  public void removeAll()
+  {
+    leftComponent = null;
+    rightComponent = null;
+    super.removeAll();
+  }
+
+  /**
+   * This method resets all children of the JSplitPane to their preferred
+   * sizes.
+   */
+  public void resetToPreferredSizes()
+  {
+    if (ui != null)
+      ((SplitPaneUI) ui).resetToPreferredSizes(this);
+  }
+
+  /**
+   * This method sets the bottom component.
+   *
+   * @param comp The Component to be placed at the bottom.
+   */
+  public void setBottomComponent(Component comp)
+  {
+    if (comp != null)
+      add(comp, BOTTOM);
+    else
+      add(new JButton("right button"), BOTTOM);
+  }
+
+  /**
+   * This method sets the layout mode for the JSplitPane.
+   *
+   * @param newContinuousLayout Whether the JSplitPane is in continuousLayout
+   *        mode.
+   */
+  public void setContinuousLayout(boolean newContinuousLayout)
+  {
+    if (newContinuousLayout != continuousLayout)
+      {
+        boolean oldValue = continuousLayout;
+        continuousLayout = newContinuousLayout;
+        firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldValue,
+                           continuousLayout);
+      }
+  }
+
+  /**
+   * This method sets the location of the divider. A value of 0 sets the
+   * divider to the farthest left. A value of 1 sets the divider to the
+   * farthest right.
+   *
+   * @param proportionalLocation A double that describes the location of the
+   *        divider.
+   *
+   * @throws IllegalArgumentException if <code>proportionalLocation</code> is
+   *     not in the range from 0.0 to 1.0 inclusive.
+   */
+  public void setDividerLocation(double proportionalLocation)
+  {
+    if (proportionalLocation > 1 || proportionalLocation < 0)
+      throw new IllegalArgumentException
+        ("proportion has to be between 0 and 1.");
+
+    int max = ((orientation == HORIZONTAL_SPLIT) ? getWidth() : getHeight())
+              - getDividerSize();
+    setDividerLocation((int) (proportionalLocation * max));
+  }
+
+  /**
+   * This method sets the location of the divider.
+   * 
+   * @param location The location of the divider. The negative value forces to
+   *          compute the new location from the preferred sizes of the split
+   *          pane components.
+   */
+  public void setDividerLocation(int location)
+  {
+    if (ui != null && location != getDividerLocation())
+      {
+        int oldLocation = getDividerLocation();        
+        if (location < 0)
+          ((SplitPaneUI) ui).resetToPreferredSizes(this);
+        else
+            ((SplitPaneUI) ui).setDividerLocation(this, location);
+        
+        firePropertyChange(DIVIDER_LOCATION_PROPERTY, oldLocation, 
+                           getDividerLocation());
+      }
+  }
+
+  /**
+   * This method sets the size of the divider.
+   *
+   * @param newSize The size of the divider.
+   */
+  public void setDividerSize(int newSize)
+  {
+    clientDividerSizeSet = true;
+    if (newSize != dividerSize)
+      {
+        int oldSize = dividerSize;
+        dividerSize = newSize;
+        firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, dividerSize);
+      }
+  }
+
+  // This doesn't appear to do anything when set from user side.
+  // so it probably is only used from the UI side to change the
+  // lastDividerLocation var.
+
+  /**
+   * This method sets the last location of the divider.
+   *
+   * @param newLastLocation The last location of the divider.
+   */
+  public void setLastDividerLocation(int newLastLocation)
+  {
+    if (newLastLocation != lastDividerLocation)
+      {
+        int oldValue = lastDividerLocation;
+        lastDividerLocation = newLastLocation;
+        firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldValue,
+                           lastDividerLocation);
+      }
+  }
+
+  /**
+   * This method sets the left component.
+   *
+   * @param comp The left component.
+   */
+  public void setLeftComponent(Component comp)
+  {    
+    if (comp != null)
+      add(comp, LEFT);
+    else
+      remove (leftComponent);
+  }
+
+  /**
+   * This method sets whether the divider has one touch expandable buttons.
+   * The one touch expandable buttons can expand the size of either component
+   * to the maximum allowed size.
+   *
+   * @param newValue Whether the divider will have one touch expandable
+   *        buttons.
+   */
+  public void setOneTouchExpandable(boolean newValue)
+  {
+    clientOneTouchExpandableSet = true;
+    if (newValue != oneTouchExpandable)
+      {
+        boolean oldValue = oneTouchExpandable;
+        oneTouchExpandable = newValue;
+        firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue,
+                           oneTouchExpandable);
+      }
+  }
+
+  /**
+   * Sets the orientation for the <code>JSplitPane</code> and sends a 
+   * {@link PropertyChangeEvent} (with the property name 
+   * {@link #ORIENTATION_PROPERTY}) to all registered listeners.
+   *
+   * @param orientation  the orientation (either {@link #HORIZONTAL_SPLIT}
+   * or {@link #VERTICAL_SPLIT}).
+   *
+   * @throws IllegalArgumentException if <code>orientation</code> is not one of
+   *     the listed values.
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT)
+      throw new IllegalArgumentException
+        ("orientation must be one of VERTICAL_SPLIT, HORIZONTAL_SPLIT");
+    if (orientation != this.orientation)
+      {
+        int oldOrientation = this.orientation;
+        this.orientation = orientation;
+        firePropertyChange(ORIENTATION_PROPERTY, oldOrientation,
+                           this.orientation);
+      }
+  }
+
+  /**
+   * This method determines how extra space will be distributed among the left
+   * and right components. A value of 0 will allocate all extra space to the
+   * right component. A value of 1 indicates that all extra space will go to
+   * the left component. A value in between 1 and 0 will split the space
+   * accordingly.
+   *
+   * @param value The resize weight.
+   */
+  public void setResizeWeight(double value)
+  {
+    if (value < 0.0 || value > 1.0)
+      throw new IllegalArgumentException("Value outside permitted range.");
+    if (this.resizeWeight != value)
+      { 
+        double old = resizeWeight;
+        resizeWeight = value;
+        firePropertyChange(RESIZE_WEIGHT_PROPERTY, old, value);
+      }
+  }
+
+  /**
+   * This method sets the right component.
+   *
+   * @param comp The right component.
+   */
+  public void setRightComponent(Component comp)
+  {
+    if (comp != null)
+      add(comp, RIGHT);
+    else
+      remove (rightComponent);
+  }
+
+  /**
+   * This method sets the top component.
+   *
+   * @param comp The top component.
+   */
+  public void setTopComponent(Component comp)
+  {
+    if (comp != null)
+      add(comp, TOP);
+    else
+      add(new JButton("left button"), TOP);
+  }
+
+  /**
+   * This method sets the UI used by the JSplitPane.
+   *
+   * @param ui The UI to use.
+   */
+  public void setUI(SplitPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method resets the UI to the one specified by the current Look and
+   * Feel.
+   */
+  public void updateUI()
+  {
+    setUI((SplitPaneUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns a string identifier to determine which UI class it
+   * needs.
+   *
+   * @return A string that identifies it's UI class.
+   */
+  public String getUIClassID()
+  {
+    return "SplitPaneUI";
+  }
+
+  /**
+   * Helper method for
+   * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
+   * 
+   * @param propertyName the name of the property
+   * @param value the value of the property
+   *
+   * @throws IllegalArgumentException if the specified property cannot be set
+   *         by this method
+   * @throws ClassCastException if the property value does not match the
+   *         property type
+   * @throws NullPointerException if <code>c</code> or
+   *         <code>propertyValue</code> is <code>null</code>
+   */
+  void setUIProperty(String propertyName, Object value)
+  {
+    if (propertyName.equals("dividerSize"))
+      {
+        if (! clientDividerSizeSet)
+          {
+            setDividerSize(((Integer) value).intValue());
+            clientDividerSizeSet = false;
+          }
+      }
+    else if (propertyName.equals("oneTouchExpandable"))
+      {
+        if (! clientOneTouchExpandableSet)
+          {
+            setOneTouchExpandable(((Boolean) value).booleanValue());
+            clientOneTouchExpandableSet = false;
+          }
+      }
+    else
+      {
+        super.setUIProperty(propertyName, value);
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTabbedPane.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTabbedPane.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTabbedPane.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTabbedPane.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,1719 @@
+/* JTabbedPane.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.TabbedPaneUI;
+import javax.swing.plaf.UIResource;
+
+/**
+ * This is a container for components where only one component is displayed at
+ * a given time and the displayed component can be switched by clicking on
+ * tabs.
+ * 
+ * <p>
+ * Tabs can be oriented in several ways. They can be above, below, left and
+ * right of the component. Tabs can either wrap around (by creating multiple
+ * rows of tabs) or they can be scrolled (where only a subset of the  tabs
+ * can be seen at once). More tabs can be added by calling the
+ * add/addTab/insertTab methods.
+ * </p>
+ */
+public class JTabbedPane extends JComponent implements Serializable,
+                                                       Accessible,
+                                                       SwingConstants
+{
+  /**
+   * Accessibility support for <code>JTabbedPane</code>.
+   */
+  protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
+    implements AccessibleSelection, ChangeListener
+  {
+    /**
+     * The serialization UID.
+     */
+    private static final long serialVersionUID = 7610530885966830483L;
+
+    /**
+     * Creates a new AccessibleJTabbedPane object.
+     */
+    public AccessibleJTabbedPane()
+    {
+      super();
+    }
+
+    /**
+     * Receives notification when the selection state of the
+     * <code>JTabbedPane</code> changes and fires appropriate property change
+     * events to interested listeners.
+     *
+     * @param e the change event describing the change
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      // I couldn't figure out what else should be done here.
+      Object source = e.getSource();
+      firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
+                         null, source);
+    }
+
+    /**
+     * Returns the accessible role of the <code>JTabbedPane</code>, which is
+     * {@link AccessibleRole#PAGE_TAB_LIST}.
+     *
+     * @return the accessible role of the <code>JTabbedPane</code>
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PAGE_TAB_LIST;
+    }
+
+    /**
+     * Returns the number of accessible child components of the
+     * <code>JTabbedPane</code>.
+     *
+     * @return the number of accessible child components of the
+     *         <code>JTabbedPane</code>
+     */
+    public int getAccessibleChildrenCount()
+    {
+      return getTabCount();
+    }
+
+    /**
+     * Returns the accessible child component at the specified index.
+     *
+     * @param i the index of the child component to fetch
+     *
+     * @return the accessible child component at the specified index
+     */
+    public Accessible getAccessibleChild(int i)
+    {
+      // Testing shows that the reference implementation returns instances
+      // of page here.
+      Accessible child = null;
+      if (i >= 0 && i < tabs.size())
+        child = (Page) tabs.get(i);
+      return child;
+    }
+
+    /**
+     * Returns the current selection state of the <code>JTabbedPane</code>
+     * as AccessibleSelection object.
+     *
+     * @return the current selection state of the <code>JTabbedPane</code>
+     */
+    public AccessibleSelection getAccessibleSelection()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the accessible child component at the specified coordinates.
+     * If there is no child component at this location, then return the
+     * currently selected tab.
+     *
+     * @param p the coordinates at which to look up the child component
+     *
+     * @return the accessible child component at the specified coordinates or
+     *         the currently selected tab if there is no child component at
+     *         this location
+     */
+    public Accessible getAccessibleAt(Point p)
+    {
+      int tabIndex = indexAtLocation(p.x, p.y);
+      if (tabIndex >= 0)
+        return getAccessibleChild(tabIndex);
+      else
+        return getAccessibleSelection(0);
+    }
+
+    /**
+     * Returns the number of selected child components of the
+     * <code>JTabbedPane</code>. The reference implementation appears
+     * to return <code>1</code> always and we do the same. 
+     *
+     * @return <code>1</code>
+     */
+    public int getAccessibleSelectionCount()
+    {
+      return 1;
+    }
+
+    /**
+     * Returns the selected tab, or <code>null</code> if there is no 
+     * selection.
+     *
+     * @param i  the selection index (ignored here).
+     *
+     * @return The selected tab, or <code>null</code>.
+     */
+    public Accessible getAccessibleSelection(int i)
+    {
+      Accessible result = null;
+      int selected = getSelectedIndex();
+      if (selected >= 0)
+        result = (Page) tabs.get(selected);
+      return result;
+    }
+
+    /**
+     * Returns <code>true</code> if the specified child is selected,
+     * and <code>false</code> otherwise.
+     *
+     * @param i the child index.
+     *
+     * @return A boolean.
+     */
+    public boolean isAccessibleChildSelected(int i)
+    {
+      return i == getSelectedIndex();
+    }
+
+    /**
+     * Selects the specified tab.
+     *
+     * @param i  the index of the item to select.
+     */
+    public void addAccessibleSelection(int i)
+    {
+      setSelectedIndex(i);
+    }
+
+    /**
+     * Does nothing - it makes no sense to remove a selection for a
+     * tabbed pane, since one tab must always be selected.
+     *
+     * @param i  the item index.
+     * 
+     * @see #addAccessibleSelection(int)
+     */
+    public void removeAccessibleSelection(int i)
+    {
+      // do nothing
+    }
+
+    /**
+     * Does nothing - it makes no sense to clear the selection for
+     * a tabbed pane, since one tab must always be selected.
+     * 
+     * @see #addAccessibleSelection(int)
+     */
+    public void clearAccessibleSelection()
+    {
+      // do nothing
+    }
+
+    /**
+     * Does nothing - it makes no sense to select all for a tabbed
+     * pane, since only one tab can be selected at a time.
+     * 
+     * @see #addAccessibleSelection(int)
+     */
+    public void selectAllAccessibleSelection()
+    {
+      // do nothing
+    }
+  }
+
+  /**
+   * A helper class that listens for changes to the model.
+   */
+  protected class ModelListener implements ChangeListener, Serializable
+  {
+    private static final long serialVersionUID = 497359819958114132L;
+
+    /**
+     * Creates a new ModelListener object.
+     */
+    protected ModelListener()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * This method is called whenever the model  is changed.
+     *
+     * @param e The ChangeEvent that is passed from the model.
+     */
+    public void stateChanged(ChangeEvent e)
+    {
+      // Propagate to our listeners.
+      fireStateChanged();
+    }
+  }
+
+  /**
+   * A private class that holds all the information  for each tab.
+   */
+  private class Page
+    extends AccessibleContext
+    implements Accessible
+  {
+    /** The tooltip string. */
+    private String tip;
+
+    /** The component associated with the tab. */
+    private Component component;
+
+    /** The active icon associated with the tab. */
+    private transient Icon icon;
+
+    /** The disabled icon associated with the tab. */
+    private transient Icon disabledIcon;
+
+    /** The tab's enabled status. */
+    private transient boolean enabled = true;
+
+    /** The string painted on the tab. */
+    private transient String title;
+
+    /** The background color of the tab. */
+    private transient Color bg;
+
+    /** The foreground color of the tab. */
+    private transient Color fg;
+
+    /** The mnemonic associated with the tab. */
+    private transient int mnemonicKey;
+
+    /** The index of the underlined character in the string. */
+    private transient int underlinedChar = -1;
+
+    /**
+     * Creates a new data storage for the tab.
+     *
+     * @param title The string displayed on the tab.
+     * @param icon The active icon displayed on the tab.
+     * @param component The component associated with the tab.
+     * @param tip The tooltip associated with the tab.
+     */
+    protected Page(String title, Icon icon, Component component, String tip)
+    {
+      this.title = title;
+      this.icon = icon;
+      this.component = component;
+      this.tip = tip;
+    }
+
+    /**
+     * This method returns the component associated with the tab.
+     *
+     * @return The component associated with the tab.
+     */
+    public Component getComponent()
+    {
+      return component;
+    }
+
+    /**
+     * This method sets the component associated with the tab.
+     *
+     * @param c The component associated with the tab.
+     */
+    public void setComponent(Component c)
+    {
+      int i = indexOfComponent(component);
+      insertTab(title, icon, c, tip, i);
+      component = c;
+      removeTabAt(i);
+    }
+
+    /**
+     * This method returns the tooltip string.
+     *
+     * @return The tooltip string.
+     */
+    public String getTip()
+    {
+      return tip;
+    }
+
+    /**
+     * This method sets the tooltip string.
+     *
+     * @param tip The tooltip string.
+     */
+    public void setTip(String tip)
+    {
+      this.tip = tip;
+    }
+
+    /**
+     * This method returns the background color.
+     *
+     * @return The background color.
+     */
+    public Color getBackground()
+    {
+      Color background;
+      if (bg == null)
+        background = JTabbedPane.this.getBackground();
+      else
+        background = bg;
+      return background;
+    }
+
+    /**
+     * This method sets the background color.
+     *
+     * @param background The background color.
+     */
+    public void setBackground(Color background)
+    {
+      bg = background;
+    }
+
+    /**
+     * This method returns the foreground color.
+     *
+     * @return The foreground color.
+     */
+    public Color getForeground()
+    {
+      Color foreground;
+      if (fg == null)
+        foreground = JTabbedPane.this.getForeground();
+      else
+        foreground = fg;
+      return foreground;
+    }
+
+    /**
+     * This method sets the foreground color.
+     *
+     * @param foreground The foreground color.
+     */
+    public void setForeground(Color foreground)
+    {
+      fg = foreground;
+    }
+
+    /**
+     * This method returns the title associated with the tab.
+     *
+     * @return The title of the tab.
+     */
+    public String getTitle()
+    {
+      return title;
+    }
+
+    private static final long serialVersionUID = 1614381073220130939L;
+
+    /**
+     * This method sets the title of the tab.
+     *
+     * @param text The title of the tab.
+     */
+    public void setTitle(String text)
+    {
+      title = text;
+      if (title != null && title.length() <= underlinedChar)
+	setDisplayedMnemonicIndex(title.length() - 1);
+    }
+
+    /**
+     * This method returns the active icon.
+     *
+     * @return The active icon.
+     */
+    public Icon getIcon()
+    {
+      return icon;
+    }
+
+    /**
+     * This method sets the active icon.
+     *
+     * @param icon The active icon.
+     */
+    public void setIcon(Icon icon)
+    {
+      this.icon = icon;
+    }
+
+    /**
+     * This method returns the disabled icon.
+     *
+     * @return The disabled icon.
+     */
+    public Icon getDisabledIcon()
+    {
+      if (disabledIcon == null && icon instanceof ImageIcon)
+	setDisabledIcon(icon);
+      return disabledIcon;
+    }
+
+    /**
+     * This method sets the disabled icon.
+     *
+     * @param disabledIcon The disabled icon.
+     */
+    public void setDisabledIcon(Icon disabledIcon)
+    {
+      this.disabledIcon = disabledIcon;
+    }
+
+    /**
+     * This method returns whether the tab is enabled.
+     *
+     * @return Whether the tab is enabled.
+     */
+    public boolean isEnabled()
+    {
+      return enabled;
+    }
+
+    /**
+     * This method sets whether the tab is enabled.
+     *
+     * @param enabled Whether this tab is enabled.
+     */
+    public void setEnabled(boolean enabled)
+    {
+      this.enabled = enabled;
+    }
+
+    /**
+     * This method returns the mnemonic.
+     *
+     * @return The mnemonic.
+     */
+    public int getMnemonic()
+    {
+      return mnemonicKey;
+    }
+
+    /**
+     * This method sets the mnemonic. If the title is set, it will update the
+     * mnemonicIndex.
+     *
+     * @param key The mnemonic.
+     */
+    public void setMnemonic(int key)
+    {
+      setMnemonic((char) key);
+    }
+
+    /**
+     * This method sets the mnemonic. If the title is set, it will update the
+     * mnemonicIndex.
+     *
+     * @param aChar The mnemonic.
+     */
+    public void setMnemonic(char aChar)
+    {
+      mnemonicKey = aChar;
+      if (title != null)
+	setDisplayedMnemonicIndex(title.indexOf(mnemonicKey));
+    }
+
+    /**
+     * This method returns the mnemonicIndex.
+     *
+     * @return The mnemonicIndex.
+     */
+    public int getDisplayedMnemonicIndex()
+    {
+      return underlinedChar;
+    }
+
+    /**
+     * This method sets the mnemonicIndex.
+     *
+     * @param index The mnemonicIndex.
+     *
+     * @throws IllegalArgumentException If index less than -1 || index greater
+     *         or equal to title.length.
+     */
+    public void setDisplayedMnemonicIndex(int index)
+      throws IllegalArgumentException
+    {
+      if (index < -1 || title != null && index >= title.length())
+	throw new IllegalArgumentException();
+
+      if (title == null || mnemonicKey == 0 || (index > -1 && title.charAt(index) != mnemonicKey))
+	index = -1;
+
+      underlinedChar = index;
+    }
+
+    /**
+     * Returns the accessible context, which is this object itself.
+     *
+     * @return the accessible context, which is this object itself
+     */
+    public AccessibleContext getAccessibleContext()
+    {
+      return this;
+    }
+
+    /**
+     * Returns the accessible name for this tab.
+     * 
+     * @return The accessible name.
+     */
+    public String getAccessibleName()
+    {
+      if (accessibleName != null)
+        return accessibleName;
+      else
+        return title;
+    }
+    
+    /**
+     * Returns the accessible role of this tab, which is always
+     * {@link AccessibleRole#PAGE_TAB}.
+     *
+     * @return the accessible role of this tab
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.PAGE_TAB;
+    }
+
+    /**
+     * Returns the accessible state set of this object.
+     *
+     * @return the accessible state set of this object
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleContext parentCtx = JTabbedPane.this.getAccessibleContext(); 
+      AccessibleStateSet state = parentCtx.getAccessibleStateSet();
+      state.add(AccessibleState.SELECTABLE);
+      if (component == getSelectedComponent())
+        state.add(AccessibleState.SELECTED);
+      return state;
+    }
+
+    /**
+     * Returns the index of this tab inside its parent.
+     *
+     * @return the index of this tab inside its parent
+     */
+    public int getAccessibleIndexInParent()
+    {
+      // TODO: Not sure if the title is unambiguous, but I can't figure
+      // another way of doing this.
+      return indexOfTab(title);
+    }
+
+    /**
+     * Returns the number of accessible children, which is always one (the
+     * component of this tab).
+     *
+     * @return the number of accessible children
+     */
+    public int getAccessibleChildrenCount()
+    {
+      return 1;
+    }
+
+    /**
+     * Returns the accessible child of this tab, which is the component
+     * displayed by the tab.
+     *
+     * @return the accessible child of this tab
+     */
+    public Accessible getAccessibleChild(int i)
+    {
+      // A quick test shows that this method always returns the component
+      // displayed by the tab, regardless of the index.
+      return (Accessible) component;
+    }
+
+    /**
+     * Returns the locale of this accessible object.
+     *
+     * @return the locale of this accessible object
+     */
+    public Locale getLocale()
+    {
+      // TODO: Is this ok?
+      return Locale.getDefault();
+    }
+  }
+
+  private static final long serialVersionUID = 1614381073220130939L;
+
+  /** The changeEvent used to fire changes to listeners. */
+  protected ChangeEvent changeEvent;
+
+  /** The listener that listens to the model. */
+  protected ChangeListener changeListener;
+
+  /** The model that describes this JTabbedPane. */
+  protected SingleSelectionModel model;
+
+  /** Indicates that the TabbedPane is in scrolling mode. */
+  public static final int SCROLL_TAB_LAYOUT = 1;
+
+  /** Indicates that the TabbedPane is in wrap mode. */
+  public static final int WRAP_TAB_LAYOUT = 0;
+
+  /** The current tabPlacement of the TabbedPane. */
+  protected int tabPlacement = SwingConstants.TOP;
+
+  /** The current tabLayoutPolicy of the TabbedPane. */
+  private transient int layoutPolicy;
+
+  /** The list of tabs associated with the TabbedPane. */
+  transient Vector tabs = new Vector();
+
+  /**
+   * Creates a new JTabbedPane object with tabs on top and using wrap tab
+   * layout.
+   */
+  public JTabbedPane()
+  {
+    this(SwingConstants.TOP, WRAP_TAB_LAYOUT);
+  }
+
+  /**
+   * Creates a new JTabbedPane object using wrap tab layout  and the given
+   * <code>tabPlacement</code>, where <code>tabPlacement</code> can be one
+   * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
+   * {@link #RIGHT}.
+   *
+   * @param tabPlacement where the tabs will be placed
+   */
+  public JTabbedPane(int tabPlacement)
+  {
+    this(tabPlacement, WRAP_TAB_LAYOUT);
+  }
+
+  /**
+   * Creates a new JTabbedPane object with the given <code>tabPlacement</code>
+   * and <code>tabLayoutPolicy</code>. The <code>tabPlacement</code> can be one
+   * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
+   * {@link #RIGHT}. The <code>tabLayoutPolicy</code> can be either
+   * {@link #SCROLL_TAB_LAYOUT} or {@link #WRAP_TAB_LAYOUT}.
+   *
+   * @param tabPlacement where the tabs will be placed
+   * @param tabLayoutPolicy the way tabs will be placed
+   *
+   * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are
+   *         not valid.
+   */
+  public JTabbedPane(int tabPlacement, int tabLayoutPolicy)
+  {
+    if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
+        && tabPlacement != LEFT)
+      throw new IllegalArgumentException("tabPlacement is not valid.");
+    if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
+        && tabLayoutPolicy != WRAP_TAB_LAYOUT)
+      throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
+    this.tabPlacement = tabPlacement;
+    layoutPolicy = tabLayoutPolicy;
+    
+    changeEvent = new ChangeEvent(this);
+    changeListener = createChangeListener();
+
+    model = new DefaultSingleSelectionModel();
+    model.addChangeListener(changeListener);
+
+    updateUI();
+  }
+
+  /**
+   * This method returns the UI used to display the JTabbedPane.
+   *
+   * @return The UI used to display the JTabbedPane.
+   */
+  public TabbedPaneUI getUI()
+  {
+    return (TabbedPaneUI) ui;
+  }
+
+  /**
+   * This method sets the UI used to display the JTabbedPane.
+   *
+   * @param ui The UI used to display the JTabbedPane.
+   */
+  public void setUI(TabbedPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method restores the UI to the defaults given by the UIManager.
+   */
+  public void updateUI()
+  {
+    setUI((TabbedPaneUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns a string identifier that  is used to determine which
+   * UI will be used with  the JTabbedPane.
+   *
+   * @return A string identifier for the UI.
+   */
+  public String getUIClassID()
+  {
+    return "TabbedPaneUI";
+  }
+
+  /**
+   * This method creates a ChangeListener that is used to  listen to the model
+   * for events.
+   *
+   * @return A ChangeListener to listen to the model.
+   */
+  protected ChangeListener createChangeListener()
+  {
+    return new ModelListener();
+  }
+
+  /**
+   * This method adds a ChangeListener to the JTabbedPane.
+   *
+   * @param l The ChangeListener to add.
+   */
+  public void addChangeListener(ChangeListener l)
+  {
+    listenerList.add(ChangeListener.class, l);
+  }
+
+  /**
+   * This method removes a ChangeListener to the JTabbedPane.
+   *
+   * @param l The ChangeListener to remove.
+   */
+  public void removeChangeListener(ChangeListener l)
+  {
+    listenerList.remove(ChangeListener.class, l);
+  }
+
+  /**
+   * This method fires a ChangeEvent to all the JTabbedPane's ChangeListeners.
+   */
+  protected void fireStateChanged()
+  {
+    Object[] changeListeners = listenerList.getListenerList();
+    if (changeEvent == null)
+      changeEvent = new ChangeEvent(this);
+    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+      {
+	if (changeListeners[i] == ChangeListener.class)
+	  ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+      }
+  }
+
+  /**
+   * This method returns all ChangeListeners registered with the JTabbedPane.
+   *
+   * @return The ChangeListeners registered with the JTabbedPane.
+   */
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) super.getListeners(ChangeListener.class);
+  }
+
+  /**
+   * This method returns the model used with the JTabbedPane.
+   *
+   * @return The JTabbedPane's model.
+   */
+  public SingleSelectionModel getModel()
+  {
+    return model;
+  }
+
+  /**
+   * This method changes the model property of the JTabbedPane.
+   *
+   * @param model The new model to use with the JTabbedPane.
+   */
+  public void setModel(SingleSelectionModel model)
+  {
+    if (model != this.model)
+      {
+	SingleSelectionModel oldModel = this.model;
+	this.model.removeChangeListener(changeListener);
+	this.model = model;
+	this.model.addChangeListener(changeListener);
+	firePropertyChange("model", oldModel, this.model);
+      }
+  }
+
+  /**
+   * This method returns the tabPlacement.
+   *
+   * @return The tabPlacement used with the JTabbedPane.
+   */
+  public int getTabPlacement()
+  {
+    return tabPlacement;
+  }
+
+  /**
+   * This method changes the tabPlacement property of the JTabbedPane.
+   *
+   * @param tabPlacement The tabPlacement to use.
+   *
+   * @throws IllegalArgumentException If tabPlacement is not one of TOP,
+   *         BOTTOM, LEFT, or RIGHT.
+   */
+  public void setTabPlacement(int tabPlacement)
+  {
+    if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
+        && tabPlacement != LEFT)
+      throw new IllegalArgumentException("tabPlacement is not valid.");
+    if (tabPlacement != this.tabPlacement)
+      {
+	int oldPlacement = this.tabPlacement;
+	this.tabPlacement = tabPlacement;
+	firePropertyChange("tabPlacement", oldPlacement, this.tabPlacement);
+      }
+  }
+
+  /**
+   * This method returns the tabLayoutPolicy.
+   *
+   * @return The tabLayoutPolicy.
+   */
+  public int getTabLayoutPolicy()
+  {
+    return layoutPolicy;
+  }
+
+  /**
+   * This method changes the tabLayoutPolicy property of the JTabbedPane.
+   *
+   * @param tabLayoutPolicy The tabLayoutPolicy to use.
+   *
+   * @throws IllegalArgumentException If tabLayoutPolicy is not one of
+   *         SCROLL_TAB_LAYOUT or WRAP_TAB_LAYOUT.
+   */
+  public void setTabLayoutPolicy(int tabLayoutPolicy)
+  {
+    if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
+        && tabLayoutPolicy != WRAP_TAB_LAYOUT)
+      throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
+    if (tabLayoutPolicy != layoutPolicy)
+      {
+	int oldPolicy = layoutPolicy;
+	layoutPolicy = tabLayoutPolicy;
+	firePropertyChange("tabLayoutPolicy", oldPolicy, layoutPolicy);
+      }
+  }
+
+  /**
+   * This method returns the index of the tab that is currently selected.
+   *
+   * @return The index of the selected tab.
+   */
+  public int getSelectedIndex()
+  {
+    return model.getSelectedIndex();
+  }
+
+  /**
+   * This method checks the index.
+   *
+   * @param index The index to check.
+   * @param start DOCUMENT ME!
+   * @param end DOCUMENT ME!
+   *
+   * @throws IndexOutOfBoundsException DOCUMENT ME!
+   */
+  private void checkIndex(int index, int start, int end)
+  {
+    if (index < start || index >= end)
+      throw new IndexOutOfBoundsException("Index < " + start + " || Index >= "
+                                          + end);
+  }
+
+  /**
+   * This method sets the selected index. This method will hide the old
+   * component and show the new component.
+   *
+   * @param index The index to set it at.
+   */
+  public void setSelectedIndex(int index)
+  {
+    checkIndex(index, -1, tabs.size());
+    if (index != getSelectedIndex())
+      {
+        // Hiding and showing the involved components
+        // is done by the JTabbedPane's UI.
+	model.setSelectedIndex(index);
+      }
+  }
+
+  /**
+   * This method returns the component at the selected index.
+   *
+   * @return The component at the selected index.
+   */
+  public Component getSelectedComponent()
+  {
+    int selectedIndex = getSelectedIndex();
+    Component selected = null;
+    if (selectedIndex >= 0)
+      selected = getComponentAt(selectedIndex);
+    return selected;
+  }
+
+  /**
+   * This method sets the component at the selected index.
+   *
+   * @param c The component associated with the selected index.
+   */
+  public void setSelectedComponent(Component c)
+  {
+    if (c.getParent() == this)
+      setSelectedIndex(indexOfComponent(c));
+    else
+      setComponentAt(getSelectedIndex(), c);
+  }
+
+  /**
+   * This method inserts tabs into JTabbedPane. This includes adding the
+   * component to the JTabbedPane and hiding it.
+   *
+   * @param title the title of the tab; may be <code>null</code>
+   * @param icon the tab's icon; may be <code>null</code>
+   * @param component the component associated with the tab
+   * @param tip the tooltip for the tab
+   * @param index the index to insert the tab at
+   */
+  public void insertTab(String title, Icon icon, Component component,
+                        String tip, int index)
+  {
+    if (title == null)
+      title = "";
+    Page p = new Page(title, icon, component, tip);
+    tabs.insertElementAt(p, index);
+
+    // Hide the component so we don't see it. Do it before we parent it
+    // so we don't trigger a repaint.
+    if (component != null)
+      {
+	component.hide();
+	super.add(component);
+      }
+
+    if (getSelectedIndex() == -1)
+      setSelectedIndex(0);
+
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane.
+   *
+   * @param title the title of the tab; may be <code>null</code>
+   * @param icon the icon for the tab; may be <code>null</code>
+   * @param component the associated component
+   * @param tip the associated tooltip
+   */
+  public void addTab(String title, Icon icon, Component component, String tip)
+  {
+    insertTab(title, icon, component, tip, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane.
+   *
+   * @param title the title of the tab; may be <code>null</code>
+   * @param icon the icon for the tab; may be <code>null</code>
+   * @param component the associated component
+   */
+  public void addTab(String title, Icon icon, Component component)
+  {
+    insertTab(title, icon, component, null, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane.
+   *
+   * @param title the title of the tab; may be <code>null</code>
+   * @param component the associated component
+   */
+  public void addTab(String title, Component component)
+  {
+    insertTab(title, null, component, null, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. The title of the tab is the
+   * Component's name. If the Component is an instance of UIResource, it
+   * doesn't add the tab and instead add the component directly to the
+   * JTabbedPane.
+   *
+   * @param component The associated component.
+   *
+   * @return The Component that was added.
+   */
+  public Component add(Component component)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      insertTab(component.getName(), null, component, null, tabs.size());
+    
+    return component;
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane.
+   *
+   * @param title the title of the tab; may be <code>null</code>
+   * @param component the associated component
+   *
+   * @return The Component that was added.
+   */
+  public Component add(String title, Component component)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      insertTab(title, null, component, null, tabs.size());
+    return component;
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane.
+   *
+   * @param component The associated component.
+   * @param index The index to insert the tab at.
+   *
+   * @return The Component that was added.
+   */
+  public Component add(Component component, int index)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      insertTab(component.getName(), null, component, null, index);
+    return component;
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane. If the constraints object is an
+   * icon, it will be used as the tab's icon. If the constraints object is a
+   * string, we will use it as the title.
+   *
+   * @param component The associated component.
+   * @param constraints The constraints object.
+   */
+  public void add(Component component, Object constraints)
+  {
+    add(component, constraints, tabs.size());
+  }
+
+  /**
+   * This method adds a tab to the JTabbedPane. If the Component is an
+   * instance of UIResource, it doesn't add the tab and instead add the
+   * component directly to the JTabbedPane. If the constraints object is an
+   * icon, it will be used as the tab's icon. If the constraints object is a
+   * string, we will use it as the title.
+   *
+   * @param component The associated component.
+   * @param constraints The constraints object.
+   * @param index The index to insert the tab at.
+   */
+  public void add(Component component, Object constraints, int index)
+  {
+    if (component instanceof UIResource)
+      super.add(component);
+    else
+      {
+	if (constraints instanceof String)
+	  insertTab((String) constraints, null, component, null, index);
+	else
+	  insertTab(component.getName(),
+	            (constraints instanceof Icon) ? (Icon) constraints : null,
+	            component, null, index);
+      }
+  }
+
+  /**
+   * Removes the tab at index. After the component associated with 
+   * index is removed, its visibility is reset to true to ensure it 
+   * will be visible if added to other containers.
+   *
+   * @param index The index of the tab to remove.
+   */
+  public void removeTabAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+
+    // We need to adjust the selection if we remove a tab that comes
+    // before the selected tab or if the selected tab is removed.
+    // This decrements the selected index by 1 if any of this is the case.
+    // Note that this covers all cases:
+    // - When the selected tab comes after the removed tab, this simply
+    //   adjusts the selection so that after the removal the selected tab
+    //   is still the same.
+    // - When we remove the currently selected tab, then the tab before the
+    //   selected tab gets selected.
+    // - When the last tab is removed, then we have an index==0, which gets
+    //   decremented to -1, which means no selection, which is 100% perfect.
+    int selectedIndex = getSelectedIndex();
+    if (selectedIndex >= index)
+      setSelectedIndex(selectedIndex - 1);
+
+    Component comp = getComponentAt(index);
+
+    // Remove the tab object.
+    tabs.remove(index);
+
+    // Remove the component. I think we cannot assume that the tab order
+    // is equal to the component order, so we iterate over the children
+    // here to find the and remove the correct component.
+    if (comp != null)
+      {
+        Component[] children = getComponents();
+        for (int i = children.length - 1; i >= 0; --i)
+          {
+            if (children[i] == comp)
+              {
+                super.remove(i);
+                comp.setVisible(true);
+                break;
+              }
+          }
+      }
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Removes the specified Component from the JTabbedPane.
+   *
+   * @param component The Component to remove.
+   */
+  public void remove(Component component)
+  {
+    // Since components implementing UIResource
+    // are not added as regular tabs by the add()
+    // methods we have to take special care when
+    // removing these object. Especially 
+    // Container.remove(Component) cannot be used
+    // because it will call JTabbedPane.remove(int)
+    // later which is overridden and can only
+    // handle tab components.
+    // This implementation can even cope with a
+    // situation that someone called insertTab()
+    // with a component that implements UIResource.
+    int index = indexOfComponent(component);
+    
+    // If the component is not a tab component
+    // find out its Container-given index
+    // and call that class' implementation
+    // directly.
+    if (index == -1)
+      {
+        Component[] cs = getComponents();
+        for (int i = 0; i< cs.length; i++)
+          if (cs[i] == component)
+            super.remove(i);
+      }
+    else
+      removeTabAt(index);
+  }
+
+  /**
+   * Removes the tab and component which corresponds to the specified index.
+   *
+   * @param index The index of the tab to remove.
+   */
+  public void remove(int index)
+  {
+    removeTabAt(index);
+  }
+
+  /**
+   * This method removes all tabs and associated components from the
+   * JTabbedPane.
+   */
+  public void removeAll()
+  {
+    setSelectedIndex(-1);
+    for (int i = getTabCount() - 1; i >= 0; i--)
+      removeTabAt(i);
+  }
+
+  /**
+   * This method returns how many tabs are in the JTabbedPane.
+   *
+   * @return The number of tabs in the JTabbedPane.
+   */
+  public int getTabCount()
+  {
+    return tabs.size();
+  }
+
+  /**
+   * This method returns the number of runs used  to paint the JTabbedPane.
+   *
+   * @return The number of runs.
+   */
+  public int getTabRunCount()
+  {
+    return ((TabbedPaneUI) ui).getTabRunCount(this);
+  }
+
+  /**
+   * This method returns the tab title given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The title for the tab.
+   */
+  public String getTitleAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getTitle();
+  }
+
+  /**
+   * This method returns the active icon given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The active icon for the tab.
+   */
+  public Icon getIconAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getIcon();
+  }
+
+  /**
+   * This method returns the disabled icon given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The disabled icon for the tab.
+   */
+  public Icon getDisabledIconAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getDisabledIcon();
+  }
+
+  /**
+   * This method returns the tooltip string for the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The tooltip string for the tab.
+   */
+  public String getToolTipTextAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getTip();
+  }
+
+  /**
+   * This method returns the foreground color for the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The foreground color for the tab.
+   */
+  public Color getForegroundAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getForeground();
+  }
+
+  /**
+   * This method returns the background color for the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The background color for the tab.
+   */
+  public Color getBackgroundAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getBackground();
+  }
+
+  /**
+   * This method returns the component associated with the tab.
+   *
+   * @param index The index of the tab.
+   *
+   * @return The component associated with the tab.
+   */
+  public Component getComponentAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).getComponent();
+  }
+
+  /**
+   * This method returns whether this tab is enabled. Disabled tabs cannot be
+   * selected.
+   *
+   * @param index The index of the tab.
+   *
+   * @return Whether the tab is enabled.
+   */
+  public boolean isEnabledAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((Page) tabs.elementAt(index)).isEnabled();
+  }
+
+  /**
+   * This method returns the mnemonic for the tab.
+   *
+   * @param tabIndex The index of the tab.
+   *
+   * @return The mnemonic for the tab.
+   */
+  public int getMnemonicAt(int tabIndex)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    return ((Page) tabs.elementAt(tabIndex)).getMnemonic();
+  }
+
+  /**
+   * This method returns the mnemonic index for the tab.
+   *
+   * @param tabIndex The index of the tab.
+   *
+   * @return The mnemonic index for the tab.
+   */
+  public int getDisplayedMnemonicIndexAt(int tabIndex)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    return ((Page) tabs.elementAt(tabIndex)).getDisplayedMnemonicIndex();
+  }
+
+  /**
+   * This method returns the bounds of the tab given the index.
+   *
+   * @param index The index of the tab.
+   *
+   * @return A rectangle describing the bounds of the tab.
+   */
+  public Rectangle getBoundsAt(int index)
+  {
+    checkIndex(index, 0, tabs.size());
+    return ((TabbedPaneUI) ui).getTabBounds(this, index);
+  }
+
+  /**
+   * This method sets the title of the tab.
+   *
+   * @param index The index of the tab.
+   * @param title The new title.
+   */
+  public void setTitleAt(int index, String title)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setTitle(title);
+  }
+
+  /**
+   * This method sets the icon of the tab.
+   *
+   * @param index The index of the tab.
+   * @param icon The new icon.
+   */
+  public void setIconAt(int index, Icon icon)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setIcon(icon);
+  }
+
+  /**
+   * This method sets the disabled icon of the tab.
+   *
+   * @param index The index of the tab.
+   * @param disabledIcon The new disabled icon.
+   */
+  public void setDisabledIconAt(int index, Icon disabledIcon)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setDisabledIcon(disabledIcon);
+  }
+
+  /**
+   * This method sets the tooltip text of the tab.
+   *
+   * @param index The index of the tab.
+   * @param toolTipText The tooltip text.
+   */
+  public void setToolTipTextAt(int index, String toolTipText)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setTip(toolTipText);
+  }
+
+  /**
+   * This method sets the background color of the tab.
+   *
+   * @param index The index of the tab.
+   * @param background The background color of the tab.
+   */
+  public void setBackgroundAt(int index, Color background)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setBackground(background);
+  }
+
+  /**
+   * This method sets the foreground color of the tab.
+   *
+   * @param index The index of the tab.
+   * @param foreground The foreground color of the tab.
+   */
+  public void setForegroundAt(int index, Color foreground)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setForeground(foreground);
+  }
+
+  /**
+   * This method sets whether the tab is enabled.
+   *
+   * @param index The index of the tab.
+   * @param enabled Whether the tab is enabled.
+   */
+  public void setEnabledAt(int index, boolean enabled)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setEnabled(enabled);
+  }
+
+  /**
+   * This method sets the component associated with the tab.
+   *
+   * @param index The index of the tab.
+   * @param component The component associated with the tab.
+   */
+  public void setComponentAt(int index, Component component)
+  {
+    checkIndex(index, 0, tabs.size());
+    ((Page) tabs.elementAt(index)).setComponent(component);
+  }
+
+  /**
+   * This method sets the displayed mnemonic index of the tab.
+   *
+   * @param tabIndex The index of the tab.
+   * @param mnemonicIndex The mnemonic index.
+   */
+  public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    ((Page) tabs.elementAt(tabIndex)).setDisplayedMnemonicIndex(mnemonicIndex);
+  }
+
+  /**
+   * This method sets the mnemonic for the tab.
+   *
+   * @param tabIndex The index of the tab.
+   * @param mnemonic The mnemonic.
+   */
+  public void setMnemonicAt(int tabIndex, int mnemonic)
+  {
+    checkIndex(tabIndex, 0, tabs.size());
+    ((Page) tabs.elementAt(tabIndex)).setMnemonic(mnemonic);
+  }
+
+  /**
+   * This method finds the index of a tab given the title.
+   *
+   * @param title The title that belongs to a tab.
+   *
+   * @return The index of the tab that has the title or -1 if not found.
+   */
+  public int indexOfTab(String title)
+  {
+    int index = -1;
+    for (int i = 0; i < tabs.size(); i++)
+      {
+	if (((Page) tabs.elementAt(i)).getTitle().equals(title))
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+    return index;
+  }
+
+  /**
+   * This method finds the index of a tab given the icon.
+   *
+   * @param icon The icon that belongs to a tab.
+   *
+   * @return The index of the tab that has the icon or -1 if not found.
+   */
+  public int indexOfTab(Icon icon)
+  {
+    int index = -1;
+    for (int i = 0; i < tabs.size(); i++)
+      {
+	if (((Page) tabs.elementAt(i)).getIcon() == icon)
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+    return index;
+  }
+
+  /**
+   * This method finds the index of a tab given the component.
+   *
+   * @param component A component associated with a tab.
+   *
+   * @return The index of the tab that has this component or -1 if not found.
+   */
+  public int indexOfComponent(Component component)
+  {
+    int index = -1;
+    for (int i = 0; i < tabs.size(); i++)
+      {
+	if (((Page) tabs.elementAt(i)).getComponent() == component)
+	  {
+	    index = i;
+	    break;
+	  }
+      }
+    return index;
+  }
+
+  /**
+   * This method returns a tab index given an (x,y) location. The origin of
+   * the (x,y) pair will be the JTabbedPane's top left position. The  tab
+   * returned will be the one that contains the point. This method is
+   * delegated to the UI.
+   *
+   * @param x The x coordinate of the point.
+   * @param y The y coordinate of the point.
+   *
+   * @return The index of the tab that contains the point.
+   */
+  public int indexAtLocation(int x, int y)
+  {
+    return ((TabbedPaneUI) ui).tabForCoordinate(this, x, y);
+  }
+
+  /**
+   * This method returns the tooltip text given a mouse event.
+   *
+   * @param event The mouse event.
+   *
+   * @return The tool tip text that is associated with this mouse event.
+   */
+  public String getToolTipText(MouseEvent event)
+  {
+    int index = indexAtLocation(event.getX(), event.getY());
+    return ((Page) tabs.elementAt(index)).getTip();
+  }
+
+  /**
+   * Returns a string describing the attributes for the 
+   * <code>JTabbedPane</code> component, for use in debugging.  The return 
+   * value is guaranteed to be non-<code>null</code>, but the format of the 
+   * string may vary between implementations.
+   *
+   * @return A string describing the attributes of the 
+   *     <code>JTabbedPane</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",tabPlacement=");
+    if (tabPlacement == TOP)
+      sb.append("TOP");
+    if (tabPlacement == BOTTOM)
+      sb.append("BOTTOM");
+    if (tabPlacement == LEFT)
+      sb.append("LEFT");
+    if (tabPlacement == RIGHT)
+      sb.append("RIGHT");
+    return sb.toString();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JTabbedPane</code> component.
+   *
+   * @return The accessible context (an instance of 
+   *         {@link AccessibleJTabbedPane}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      {
+        AccessibleJTabbedPane ctx = new AccessibleJTabbedPane();
+        addChangeListener(ctx);
+        accessibleContext = ctx;
+      }
+
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTable.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTable.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTable.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTable.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,5121 @@
+/* JTable.java -- 
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.FocusListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleExtendedTable;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleTable;
+import javax.accessibility.AccessibleTableModelChange;
+import javax.swing.event.CellEditorListener;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableColumnModelEvent;
+import javax.swing.event.TableColumnModelListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.plaf.TableUI;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
+
+/**
+ * The table component, displaying information, organized in rows and columns.
+ * The table can be placed in the scroll bar and have the optional header
+ * that is always visible. Cell values may be editable after double clicking
+ * on the cell. Cell columns may have various data types, that are 
+ * displayed and edited by the different renderers and editors. It is possible
+ * to set different column width. The columns are also resizeable by 
+ * dragging the column boundary in the header.
+ */
+public class JTable
+  extends JComponent
+  implements TableModelListener, Scrollable, TableColumnModelListener,
+             ListSelectionListener, CellEditorListener, Accessible
+{
+  /**
+   * Provides accessibility support for <code>JTable</code>.
+   *
+   * @author Roman Kennke (kennke at aicas.com)
+   */
+  protected class AccessibleJTable
+    extends AccessibleJComponent
+    implements AccessibleSelection, ListSelectionListener, TableModelListener,
+    TableColumnModelListener, CellEditorListener, PropertyChangeListener,
+    AccessibleExtendedTable
+  {
+
+    /**
+     * Provides accessibility support for table cells.
+     *
+     * @author Roman Kennke (kennke at aicas.com)
+     */
+    protected class AccessibleJTableCell
+      extends AccessibleContext
+      implements Accessible, AccessibleComponent
+    {
+
+      /**
+       * The table of this cell.
+       */
+      private JTable table;
+
+      /**
+       * The row index of this cell.
+       */
+      private int row;
+
+      /**
+       * The column index of this cell.
+       */
+      private int column;
+
+      /**
+       * The index of this cell inside the AccessibleJTable parent.
+       */
+      private int index;
+
+      /**
+       * Creates a new <code>AccessibleJTableCell</code>.
+       *
+       * @param t the table
+       * @param r the row
+       * @param c the column
+       * @param i the index of this cell inside the accessible table parent
+       */
+      public AccessibleJTableCell(JTable t, int r, int c, int i)
+      {
+        table = t;
+        row = r;
+        column = c;
+        index = i;
+      }
+
+      /**
+       * Returns the accessible row for the table cell.
+       *
+       * @return the accessible row for the table cell
+       */
+      public AccessibleRole getAccessibleRole()
+      {
+        // TODO: What is the role of the table cell?
+        // Seems like the RI returns UNKNOWN here for 'normal' cells, might
+        // be different for special renderers though (not tested yet).
+        return AccessibleRole.UNKNOWN;
+      }
+
+      /**
+       * Returns the accessible state set of this accessible table cell.
+       *
+       * @return the accessible state set of this accessible table cell
+       */
+      public AccessibleStateSet getAccessibleStateSet()
+      {
+        AccessibleStateSet state = new AccessibleStateSet();
+
+        // Figure out the SHOWING state.
+        Rectangle visibleRect = getVisibleRect();
+        Rectangle cellRect = getCellRect(row, column, false);
+        if (visibleRect.intersects(cellRect))
+          state.add(AccessibleState.SHOWING);
+
+        // Figure out SELECTED state.
+        if (isCellSelected(row, column))
+          state.add(AccessibleState.SELECTED);
+
+        // Figure out ACTIVE state.
+        if (row == getSelectedRow() && column == getSelectedColumn())
+          state.add(AccessibleState.ACTIVE);
+
+        // TRANSIENT seems to be always set in the RI.
+        state.add(AccessibleState.TRANSIENT);
+
+        // TODO: Any other state to handle here?
+        return state;
+      }
+
+      /**
+       * Returns the index of this cell in the parent object.
+       *
+       * @return the index of this cell in the parent object
+       */
+      public int getAccessibleIndexInParent()
+      {
+        return index;
+      }
+
+      /**
+       * Returns the number of children of this object. Table cells cannot have
+       * children, so we return <code>0</code> here.
+       *
+       * @return <code>0</code>
+       */
+      public int getAccessibleChildrenCount()
+      {
+        return 0;
+      }
+
+      /**
+       * Returns the accessible child at index <code>i</code>. Table cells
+       * don't have children, so we return <code>null</code> here.
+       *
+       * @return <code>null</code>
+       */
+      public Accessible getAccessibleChild(int i)
+      {
+        return null;
+      }
+
+      /**
+       * Returns the locale setting for this accessible table cell.
+       *
+       * @return the locale setting for this accessible table cell
+       */
+      public Locale getLocale()
+      {
+        // TODO: For now, we return english here. This must be fixed as soon
+        // as we have a localized Swing.
+        return Locale.ENGLISH;
+      }
+
+      /**
+       * Returns the accessible context of this table cell. Since accessible
+       * table cells are their own accessible context, we return
+       * <code>this</code>.
+       *
+       * @return the accessible context of this table cell
+       */
+      public AccessibleContext getAccessibleContext()
+      {
+        return this;
+      }
+
+      /**
+       * Returns the background color of this cell.
+       *
+       * @return the background color of this cell
+       */
+      public Color getBackground()
+      {
+        return table.getBackground();
+      }
+
+      /**
+       * Sets the background of the cell. Since table cells cannot have
+       * individual background colors, this method does nothing. Set the
+       * background directly on the table instead.
+       * 
+       * @param color not used
+       */
+      public void setBackground(Color color)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns the foreground color of the table cell.
+       *
+       * @return the foreground color of the table cell
+       */
+      public Color getForeground()
+      {
+        return table.getForeground();
+      }
+
+      /**
+       * Sets the foreground of the cell. Since table cells cannot have
+       * individual foreground colors, this method does nothing. Set the
+       * foreground directly on the table instead.
+       * 
+       * @param color not used
+       */
+      public void setForeground(Color color)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns the cursor for this table cell.
+       *
+       * @return the cursor for this table cell
+       */
+      public Cursor getCursor()
+      {
+        return table.getCursor();
+      }
+
+      /**
+       * Sets the cursor of the cell. Since table cells cannot have
+       * individual cursors, this method does nothing. Set the
+       * cursor directly on the table instead.
+       * 
+       * @param cursor not used
+       */
+      public void setCursor(Cursor cursor)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns the font of the table cell.
+       *
+       * @return the font of the table cell
+       */
+      public Font getFont()
+      {
+        return table.getFont();
+      }
+
+      /**
+       * Sets the font of the cell. Since table cells cannot have
+       * individual fonts, this method does nothing. Set the
+       * font directly on the table instead.
+       * 
+       * @param font not used
+       */
+      public void setFont(Font font)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns the font metrics for a specified font.
+       *
+       * @param font the font for which we return the metrics
+       *
+       * @return the font metrics for a specified font
+       */
+      public FontMetrics getFontMetrics(Font font)
+      {
+        return table.getFontMetrics(font);
+      }
+
+      /**
+       * Returns <code>true</code> if this table cell is enabled,
+       * <code>false</code> otherwise.
+       *
+       * @return <code>true</code> if this table cell is enabled,
+       *         <code>false</code> otherwise
+       */
+      public boolean isEnabled()
+      {
+        return table.isEnabled();
+      }
+
+      /**
+       * Table cells cannot be disabled or enabled individually, so this method
+       * does nothing. Set the enabled flag on the table itself.
+       *
+       * @param b not used here
+       */
+      public void setEnabled(boolean b)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns <code>true</code> if this cell is visible, <code>false</code>
+       * otherwise.
+       *
+       * @return <code>true</code> if this cell is visible, <code>false</code>
+       *         otherwise
+       */
+      public boolean isVisible()
+      {
+        return table.isVisible();
+      }
+
+      /**
+       * The visibility cannot be set on individual table cells, so this method
+       * does nothing. Set the visibility on the table itself.
+       *
+       * @param b not used
+       */
+      public void setVisible(boolean b)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns <code>true</code> if this table cell is currently showing on
+       * screen.
+       *
+       * @return <code>true</code> if this table cell is currently showing on
+       *         screen
+       */
+      public boolean isShowing()
+      {
+        return table.isShowing();
+      }
+
+      /**
+       * Returns <code>true</code> if this table cell contains the location
+       * at <code>point</code>, <code>false</code> otherwise.
+       * <code>point</code> is interpreted as relative to the coordinate system
+       * of the table cell.
+       *
+       * @return <code>true</code> if this table cell contains the location
+       *         at <code>point</code>, <code>false</code> otherwise
+       */
+      public boolean contains(Point point)
+      {
+        Rectangle cellRect = table.getCellRect(row, column, true);
+        cellRect.x = 0;
+        cellRect.y = 0;
+        return cellRect.contains(point);
+      }
+
+      /**
+       * Returns the screen location of the table cell.
+       *
+       * @return the screen location of the table cell
+       */
+      public Point getLocationOnScreen()
+      {
+        Point tableLoc = table.getLocationOnScreen();
+        Rectangle cellRect = table.getCellRect(row, column, true);
+        tableLoc.x += cellRect.x;
+        tableLoc.y += cellRect.y;
+        return tableLoc;
+      }
+
+      /**
+       * Returns the location of this cell relative to the table's bounds.
+       *
+       * @return the location of this cell relative to the table's bounds
+       */
+      public Point getLocation()
+      {
+        Rectangle cellRect = table.getCellRect(row, column, true);
+        return new Point(cellRect.x, cellRect.y);
+      }
+
+      /**
+       * The location of the table cells cannot be manipulated directly, so
+       * this method does nothing.
+       *
+       * @param point not used
+       */
+      public void setLocation(Point point)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns the bounds of the cell relative to its table.
+       *
+       * @return the bounds of the cell relative to its table
+       */
+      public Rectangle getBounds()
+      {
+        return table.getCellRect(row, column, true);
+      }
+
+      /**
+       * The bounds of the table cells cannot be manipulated directly, so
+       * this method does nothing.
+       *
+       * @param rectangle not used
+       */
+      public void setBounds(Rectangle rectangle)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Returns the size of the table cell.
+       *
+       * @return the size of the table cell
+       */
+      public Dimension getSize()
+      {
+        Rectangle cellRect = table.getCellRect(row, column, true);
+        return new Dimension(cellRect.width, cellRect.height);
+      }
+
+      /**
+       * The size cannot be set on table cells directly, so this method does
+       * nothing.
+       *
+       * @param dimension not used
+       */
+      public void setSize(Dimension dimension)
+      {
+        // This method does nothing. See API comments.
+      }
+
+      /**
+       * Table cells have no children, so we return <code>null</code> here.
+       *
+       * @return <code>null</code>
+       */
+      public Accessible getAccessibleAt(Point point)
+      {
+        return null;
+      }
+
+      /**
+       * Returns <code>true</code> if this table cell is focus traversable,
+       * <code>false</code> otherwise.
+       *
+       * @return <code>true</code> if this table cell is focus traversable,
+       *         <code>false</code> otherwise
+       */
+      public boolean isFocusTraversable()
+      {
+        return table.isFocusable();
+      }
+
+      /**
+       * Requests that this table cell gets the keyboard focus.
+       */
+      public void requestFocus()
+      {
+        // We first set the selection models' lead selection to this cell.
+        table.getColumnModel().getSelectionModel()
+        .setLeadSelectionIndex(column);
+        table.getSelectionModel().setLeadSelectionIndex(row);
+        // Now we request that the table receives focus.
+        table.requestFocus();
+      }
+
+      /**
+       * Adds a focus listener to this cell. The focus listener is really
+       * added to the table, so there is no way to find out when an individual
+       * cell changes the focus.
+       *
+       * @param listener the focus listener to add
+       */
+      public void addFocusListener(FocusListener listener)
+      {
+        table.addFocusListener(listener);
+      }
+
+      /**
+       * Removes a focus listener from the cell. The focus listener is really
+       * removed from the table.
+       *
+       * @param listener the listener to remove
+       */
+      public void removeFocusListener(FocusListener listener)
+      {
+        table.removeFocusListener(listener);
+      }
+        
+    }
+
+    protected class AccessibleJTableModelChange
+      implements AccessibleTableModelChange
+    {
+      protected int type;
+      protected int firstRow;
+      protected int lastRow;
+      protected int firstColumn;
+      protected int lastColumn;
+
+      protected AccessibleJTableModelChange(int type, int firstRow,
+                                            int lastRow, int firstColumn,
+                                            int lastColumn)
+      {
+        this.type = type;
+        this.firstRow = firstRow;
+        this.lastRow = lastRow;
+        this.firstColumn = firstColumn;
+        this.lastColumn = lastColumn;
+      }
+
+      public int getType()
+      {
+        return type;
+      }
+
+      public int getFirstRow()
+      {
+        return firstRow;
+      }
+
+      public int getLastRow()
+      {
+        return lastRow;
+      }
+
+      public int getFirstColumn()
+      {
+        return firstColumn;
+      }
+
+      public int getLastColumn()
+      {
+        return lastColumn;
+      }
+    }
+
+    /**
+     * The RI returns an instance with this name in
+     * {@link #getAccessibleColumnHeader()}, this makes sense, so we do the
+     * same.
+     */
+    private class AccessibleTableHeader
+      implements AccessibleTable
+    {
+
+      /**
+       * The JTableHeader wrapped by this class.
+       */
+      private JTableHeader header;
+
+      /**
+       * Creates a new instance.
+       *
+       * @param h the JTableHeader to wrap
+       */
+      private AccessibleTableHeader(JTableHeader h)
+      {
+        header = h;
+      }
+
+      /**
+       * Returns the caption for the table header.
+       *
+       * @return the caption for the table header
+       */
+      public Accessible getAccessibleCaption()
+      {
+        // The RI seems to always return null here, so do we.
+        return null;
+      }
+
+      /**
+       * Sets the caption for the table header.
+       *
+       * @param caption the caption to set
+       */
+      public void setAccessibleCaption(Accessible caption)
+      {
+        // This seems to be a no-op in the RI, so we do the same.
+      }
+
+      /**
+       * Returns the caption for the table header.
+       *
+       * @return the caption for the table header
+       */
+      public Accessible getAccessibleSummary()
+      {
+        // The RI seems to always return null here, so do we.
+        return null;
+      }
+
+      /**
+       * Sets the summary for the table header.
+       *
+       * @param summary the caption to set
+       */
+      public void setAccessibleSummary(Accessible summary)
+      {
+        // This seems to be a no-op in the RI, so we do the same.
+      }
+
+      /**
+       * Returns the number of rows, which is always 1 for the table header.
+       *
+       * @return the number of rows
+       */
+      public int getAccessibleRowCount()
+      {
+        return 1;
+      }
+
+      /**
+       * Returns the number of columns in the table header.
+       *
+       * @return the number of columns in the table header
+       */
+      public int getAccessibleColumnCount()
+      {
+        return header.getColumnModel().getColumnCount();
+      }
+
+      /**
+       * Returns the accessible child at the specified row and column.
+       * The row number is ignored here, and we return an
+       * AccessibleJTableHeaderCell here with the renderer component as
+       * component.
+       *
+       * @param r the row number
+       * @param c the column number
+       *
+       * @return the accessible child at the specified row and column
+       */
+      public Accessible getAccessibleAt(int r, int c)
+      {
+        TableColumn column = header.getColumnModel().getColumn(c);
+        TableCellRenderer rend = column.getHeaderRenderer();
+        if (rend == null)
+          rend = header.getDefaultRenderer();
+        Component comp =
+          rend.getTableCellRendererComponent(header.getTable(),
+                                             column.getHeaderValue(), false,
+                                             false, -1, c);
+        return new AccessibleJTableHeaderCell(header, comp, r, c);
+      }
+
+      public int getAccessibleRowExtentAt(int r, int c)
+      {
+        // TODO Auto-generated method stub
+        return 0;
+      }
+
+      public int getAccessibleColumnExtentAt(int r, int c)
+      {
+        // TODO Auto-generated method stub
+        return 0;
+      }
+
+      public AccessibleTable getAccessibleRowHeader()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setAccessibleRowHeader(AccessibleTable header)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public AccessibleTable getAccessibleColumnHeader()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setAccessibleColumnHeader(AccessibleTable header)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Accessible getAccessibleRowDescription(int r)
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setAccessibleRowDescription(int r, Accessible description)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Accessible getAccessibleColumnDescription(int c)
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setAccessibleColumnDescription(int c, Accessible description)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public boolean isAccessibleSelected(int r, int c)
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public boolean isAccessibleRowSelected(int r)
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public boolean isAccessibleColumnSelected(int c)
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public int[] getSelectedAccessibleRows()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public int[] getSelectedAccessibleColumns()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+        
+    }
+
+    /**
+     * The RI returns an instance of such class for table header cells. This
+     * makes sense so I added this class. This still needs to be fully
+     * implemented, I just don't feel motivated enough to do so just now.
+     */
+    private class AccessibleJTableHeaderCell
+      extends AccessibleContext
+      implements Accessible, AccessibleComponent
+    {
+
+      JTableHeader header;
+      
+      int columnIndex;
+      
+      /**
+       * 
+       * @param h  the table header.
+       * @param comp
+       * @param r
+       * @param c  the column index.
+       */
+      private AccessibleJTableHeaderCell(JTableHeader h, Component comp, int r,
+                                         int c)
+      {
+        header = h;
+        columnIndex = c;
+      }
+
+      /**
+       * Returns the header renderer.
+       * 
+       * @return The header renderer.
+       */
+      Component getColumnHeaderRenderer()
+      {
+        TableColumn tc = header.getColumnModel().getColumn(columnIndex);
+        TableCellRenderer r = tc.getHeaderRenderer();
+        if (r == null)
+          r = header.getDefaultRenderer();
+        return r.getTableCellRendererComponent(header.getTable(), 
+            tc.getHeaderValue(), false, false, -1, columnIndex);
+      }
+      
+      /**
+       * Returns the accessible role for the table header cell.
+       * 
+       * @return The accessible role.
+       */
+      public AccessibleRole getAccessibleRole()
+      {
+        Component renderer = getColumnHeaderRenderer();
+        if (renderer instanceof Accessible)
+          {
+            Accessible ac = (Accessible) renderer;
+            return ac.getAccessibleContext().getAccessibleRole();
+          }
+        return null;
+      }
+
+      public AccessibleStateSet getAccessibleStateSet()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public int getAccessibleIndexInParent()
+      {
+        // TODO Auto-generated method stub
+        return 0;
+      }
+
+      public int getAccessibleChildrenCount()
+      {
+        // TODO Auto-generated method stub
+        return 0;
+      }
+
+      public Accessible getAccessibleChild(int i)
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public Locale getLocale()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      /**
+       * Returns the accessible context.
+       * 
+       * @return <code>this</code>.
+       */
+      public AccessibleContext getAccessibleContext()
+      {
+        return this;
+      }
+
+      public Color getBackground()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setBackground(Color color)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Color getForeground()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setForeground(Color color)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Cursor getCursor()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setCursor(Cursor cursor)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Font getFont()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setFont(Font font)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public FontMetrics getFontMetrics(Font font)
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public boolean isEnabled()
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public void setEnabled(boolean b)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public boolean isVisible()
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public void setVisible(boolean b)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public boolean isShowing()
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public boolean contains(Point point)
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public Point getLocationOnScreen()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public Point getLocation()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setLocation(Point point)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Rectangle getBounds()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setBounds(Rectangle rectangle)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Dimension getSize()
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public void setSize(Dimension dimension)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public Accessible getAccessibleAt(Point point)
+      {
+        // TODO Auto-generated method stub
+        return null;
+      }
+
+      public boolean isFocusTraversable()
+      {
+        // TODO Auto-generated method stub
+        return false;
+      }
+
+      public void requestFocus()
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public void addFocusListener(FocusListener listener)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+
+      public void removeFocusListener(FocusListener listener)
+      {
+        // TODO Auto-generated method stub
+        
+      }
+      
+    }
+
+    /**
+     * The last selected row. This is needed to track the selection in
+     * {@link #valueChanged(ListSelectionEvent)}.
+     */
+    private int lastSelectedRow;
+
+    /**
+     * The last selected column. This is needed to track the selection in
+     * {@link #valueChanged(ListSelectionEvent)}.
+     */
+    private int lastSelectedColumn;
+
+    /**
+     * The caption of the table.
+     */
+    private Accessible caption;
+
+    /**
+     * The summary of the table.
+     */
+    private Accessible summary;
+
+    /**
+     * Accessible descriptions for rows.
+     */
+    private Accessible[] rowDescriptions;
+
+    /**
+     * Accessible descriptions for columns.
+     */
+    private Accessible[] columnDescriptions;
+
+    /**
+     * Creates a new <code>AccessibleJTable</code>.
+     *
+     * @since JDK1.5
+     */
+    protected AccessibleJTable()
+    {
+      getModel().addTableModelListener(this);
+      getSelectionModel().addListSelectionListener(this);
+      getColumnModel().addColumnModelListener(this);
+      lastSelectedRow = getSelectedRow();
+      lastSelectedColumn = getSelectedColumn();
+      TableCellEditor editor = getCellEditor();
+      if (editor != null)
+        editor.addCellEditorListener(this);
+    }
+
+    /**
+     * Returns the accessible role for the <code>JTable</code> component.
+     *
+     * @return {@link AccessibleRole#TABLE}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.TABLE;
+    }
+    
+    /**
+     * Returns the accessible table.
+     * 
+     * @return <code>this</code>.
+     */
+    public AccessibleTable getAccessibleTable()
+    {
+      return this;
+    }
+    
+    /**
+     * Returns the number of selected items in this table.
+     */
+    public int getAccessibleSelectionCount()
+    {
+      return getSelectedColumnCount();
+    }
+
+    /**
+     * Returns the selected accessible object with the specified index
+     * <code>i</code>. This basically returns the i-th selected cell in the
+     * table when going though it row-wise, and inside the rows, column-wise.
+     *
+     * @param i the index of the selected object to find
+     *
+     * @return the selected accessible object with the specified index
+     *         <code>i</code>
+     */
+    public Accessible getAccessibleSelection(int i)
+    {
+      Accessible found = null;
+
+      int[] selectedRows = getSelectedRows();
+      int[] selectedColumns = getSelectedColumns();
+      int numCols = getColumnCount();
+      int numRows = getRowCount();
+
+      // We have to go through every selected row and column and count until we
+      // find the specified index. This is potentially inefficient, but I can't
+      // think of anything better atm.
+      if (getRowSelectionAllowed() && getColumnSelectionAllowed())
+        {
+          int current = -1;
+          int newIndex = current;
+          int lastSelectedRow = -1;
+          // Go through the selected rows array, don't forget the selected
+          // cells inside the not-selected rows' columns.
+          for (int j = 0; i < selectedRows.length; i++)
+            {
+              // Handle unselected rows between this selected and the last
+              // selected row, if any.
+              int selectedRow = selectedRows[j];
+              int r = -1;
+              int ci = -1;
+              for (r = lastSelectedRow + 1;
+                   r < selectedRow && current < i; r++)
+                {
+                  for (ci = 0; ci < selectedColumns.length && current < i;
+                       ci++)
+                    {
+                      current++;
+                    }
+                }
+              if (current == i)
+                {
+                  // We found the cell in the above loops, now get out of here.
+                  found = getAccessibleChild(r * numCols
+                                             + selectedColumns[ci]);
+                  break;
+                }
+
+              // If we're still here, handle the current selected row.
+              if (current < i && current + numCols >= i)
+                {
+                  // The cell must be in that row, which one is it?
+                  found = getAccessibleChild(r * numCols + (i - current));
+                  break;
+                }
+              current += numCols;
+            }
+          if (found == null)
+            {
+              // The cell can still be in the last couple of unselected rows.
+              int r = 0;
+              int ci = 0;
+              for (r = lastSelectedRow + 1;
+                   r < numRows && current < i; r++)
+                {
+                  for (ci = 0; ci < selectedColumns.length && current < i;
+                       ci++)
+                    {
+                      current++;
+                    }
+                }
+              if (current == i)
+                {
+                  // We found the cell in the above loops, now get out of here.
+                  found = getAccessibleChild(r * numCols
+                                             + selectedColumns[ci]);
+                }
+            }
+        }
+      // One or more rows can be completely selected.
+      else if (getRowSelectionAllowed())
+        {
+          int c = i % numCols;
+          int r = selectedRows[i / numCols];
+          found = getAccessibleChild(r * numCols + c);
+        }
+      // One or more columns can be completely selected.
+      else if (getRowSelectionAllowed())
+        {
+          int numSelectedColumns = selectedColumns.length;
+          int c = selectedColumns[i % numSelectedColumns];
+          int r = i / numSelectedColumns;
+          found = getAccessibleChild(r * numCols + c);
+        }
+
+      return found;
+    }
+
+    /**
+     * Returns <code>true</code> if the accessible child with the index
+     * <code>i</code> is selected, <code>false</code> otherwise.
+     *
+     * @param i the index of the accessible to check
+     *
+     * @return <code>true</code> if the accessible child with the index
+     *         <code>i</code> is selected, <code>false</code> otherwise
+     */
+    public boolean isAccessibleChildSelected(int i)
+    {
+      int r = getAccessibleRowAtIndex(i);
+      int c = getAccessibleColumnAtIndex(i);
+      return isCellSelected(r, c);
+    }
+
+    /**
+     * Adds the accessible child with the specified index <code>i</code> to the
+     * selection.
+     *
+     * @param i the index of the accessible child to add to the selection
+     */
+    public void addAccessibleSelection(int i)
+    {
+      int r = getAccessibleRowAtIndex(i);
+      int c = getAccessibleColumnAtIndex(i);
+      changeSelection(r, c, true, false);
+    }
+
+    /**
+     * Removes the accessible child with the specified index <code>i</code>
+     * from the current selection. This will only work on tables that have
+     * cell selection enabled (<code>rowSelectionAllowed == false &&
+     * columnSelectionAllowed == false</code>).
+     *
+     * @param i the index of the accessible to be removed from the selection
+     */
+    public void removeAccessibleSelection(int i)
+    {
+      if (! getRowSelectionAllowed() && ! getColumnSelectionAllowed())
+        {
+          int r = getAccessibleRowAtIndex(i);
+          int c = getAccessibleColumnAtIndex(i);
+          removeRowSelectionInterval(r, r);
+          removeColumnSelectionInterval(c, c);
+        }
+    }
+
+    /**
+     * Deselects all selected accessible children.
+     */
+    public void clearAccessibleSelection()
+    {
+      clearSelection();
+    }
+
+    /**
+     * Selects all accessible children that can be selected. This will only
+     * work on tables that support multiple selections and that have individual
+     * cell selection enabled.
+     */
+    public void selectAllAccessibleSelection()
+    {
+      selectAll();
+    }
+
+    /**
+     * Receives notification when the row selection changes and fires
+     * appropriate property change events.
+     *
+     * @param event the list selection event
+     */
+    public void valueChanged(ListSelectionEvent event)
+    {
+      firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
+                         Boolean.FALSE, Boolean.TRUE);
+      int r = getSelectedRow();
+      int c = getSelectedColumn();
+      if (r != lastSelectedRow || c != lastSelectedColumn)
+        {
+          Accessible o = getAccessibleAt(lastSelectedRow,
+                                         lastSelectedColumn);
+          Accessible n = getAccessibleAt(r, c);
+          firePropertyChange(AccessibleContext
+                             .ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, o, n);
+          lastSelectedRow = r;
+          lastSelectedColumn = c;
+        }
+    }
+
+    /**
+     * Receives notification when the table model changes. Depending on the
+     * type of change, this method calls {@link #tableRowsInserted} or
+     * {@link #tableRowsDeleted}.
+     *
+     * @param event the table model event
+     */
+    public void tableChanged(TableModelEvent event)
+    {
+      switch (event.getType())
+        {
+        case TableModelEvent.INSERT:
+          tableRowsInserted(event);
+          break;
+        case TableModelEvent.DELETE:
+          tableRowsDeleted(event);
+          break;
+        }
+    }
+
+    /**
+     * Receives notification when one or more rows have been inserted into the
+     * table and fires appropriate property change events.
+     *
+     * @param event the table model event
+     */
+    public void tableRowsInserted(TableModelEvent event)
+    {
+      handleRowChange(event);
+    }
+
+    /**
+     * Receives notification when one or more rows have been deleted from the
+     * table.
+     *
+     * @param event the table model event
+     */
+    public void tableRowsDeleted(TableModelEvent event)
+    {
+      handleRowChange(event);
+    }
+
+    /**
+     * Fires a PropertyChangeEvent for inserted or deleted rows.
+     *
+     * @param event the table model event
+     */
+    private void handleRowChange(TableModelEvent event)
+    {
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+                         null, null);
+      int firstColumn = event.getColumn();
+      int lastColumn = event.getColumn();
+      if (firstColumn == TableModelEvent.ALL_COLUMNS)
+        {
+          firstColumn = 0;
+          lastColumn = getColumnCount() - 1;
+        }
+      AccessibleJTableModelChange change = new AccessibleJTableModelChange
+         (event.getType(), event.getFirstRow(), event.getLastRow(),
+          firstColumn, lastColumn);
+      firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED,
+                         null, change);
+    }
+
+    public void columnAdded(TableColumnModelEvent event)
+    {
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+                         null, null);
+      handleColumnChange(AccessibleTableModelChange.INSERT,
+                         event.getFromIndex(), event.getToIndex());
+    }
+
+    public void columnRemoved(TableColumnModelEvent event)
+    {
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+                         null, null);
+      handleColumnChange(AccessibleTableModelChange.DELETE,
+                         event.getFromIndex(), event.getToIndex());
+    }
+
+    public void columnMoved(TableColumnModelEvent event)
+    {
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+                         null, null);
+      handleColumnChange(AccessibleTableModelChange.DELETE,
+                         event.getFromIndex(), event.getFromIndex());
+      handleColumnChange(AccessibleTableModelChange.INSERT,
+                         event.getFromIndex(), event.getToIndex());
+    }
+
+    /**
+     * Fires a PropertyChangeEvent for inserted or deleted columns.
+     *
+     * @param type the type of change
+     * @param from the start of the change
+     * @param to the target of the change
+     */
+    private void handleColumnChange(int type, int from, int to)
+    {
+      AccessibleJTableModelChange change =
+        new AccessibleJTableModelChange(type, 0, 0, from, to);
+      firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED,
+                         null, change);
+    }
+
+    public void columnMarginChanged(ChangeEvent event)
+    {
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+                         null, null);
+    }
+
+    public void columnSelectionChanged(ListSelectionEvent event)
+    {
+      // AFAICS, nothing is done here.
+    }
+
+    public void editingCanceled(ChangeEvent event)
+    {
+      // AFAICS, nothing is done here.
+    }
+
+    public void editingStopped(ChangeEvent event)
+    {
+      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+                         null, null);
+    }
+
+    /**
+     * Receives notification when any of the JTable's properties changes. This
+     * is used to replace the listeners on the table's model, selection model,
+     * column model and cell editor.
+     *
+     * @param e the property change event
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      String propName = e.getPropertyName(); 
+      if (propName.equals("tableModel"))
+        {
+          TableModel oldModel = (TableModel) e.getOldValue();
+          oldModel.removeTableModelListener(this);
+          TableModel newModel = (TableModel) e.getNewValue();
+          newModel.addTableModelListener(this);
+        }
+      else if (propName.equals("columnModel"))
+        {
+          TableColumnModel oldModel = (TableColumnModel) e.getOldValue();
+          oldModel.removeColumnModelListener(this);
+          TableColumnModel newModel = (TableColumnModel) e.getNewValue();
+          newModel.addColumnModelListener(this);
+        }
+      else if (propName.equals("selectionModel"))
+        {
+          ListSelectionModel oldModel = (ListSelectionModel) e.getOldValue();
+          oldModel.removeListSelectionListener(this);
+          ListSelectionModel newModel = (ListSelectionModel) e.getNewValue();
+          newModel.addListSelectionListener(this);
+        }
+      else if (propName.equals("cellEditor"))
+        {
+          CellEditor oldEd = (CellEditor) e.getOldValue();
+          oldEd.removeCellEditorListener(this);
+          CellEditor newEd = (CellEditor) e.getNewValue();
+          newEd.addCellEditorListener(this);
+        }
+    }
+
+    /**
+     * Returns the row number of an accessible child (cell) with the specified
+     * index.
+     *
+     * @param index the index of the cell of which the row number is queried
+     * 
+     * @return the row number of an accessible child (cell) with the specified
+     *         index 
+     */
+    public int getAccessibleRow(int index)
+    {
+      return getAccessibleRowAtIndex(index);
+    }
+
+    /**
+     * Returns the column number of an accessible child (cell) with the
+     * specified index.
+     *
+     * @param index the index of the cell of which the column number is queried
+     * 
+     * @return the column number of an accessible child (cell) with the
+     *         specified index 
+     */
+    public int getAccessibleColumn(int index)
+    {
+      return getAccessibleColumnAtIndex(index);
+    }
+
+    /**
+     * Returns the index of the accessible child at the specified row and
+     * column.
+     *
+     * @param r the row number
+     * @param c the column number
+     *
+     * @return the index of the accessible child at the specified row and
+     *         column
+     */
+    public int getAccessibleIndex(int r, int c)
+    {
+      return getAccessibleIndexAt(r, c);
+    }
+
+    /**
+     * Returns the caption of the table.
+     *
+     * @return the caption of the table
+     *
+     * @see #setAccessibleCaption(Accessible)
+     */
+    public Accessible getAccessibleCaption()
+    {
+      return caption;
+    }
+
+    /**
+     * Sets the caption for the table.
+     *
+     * @param c the caption to set
+     */
+    public void setAccessibleCaption(Accessible c)
+    {
+      caption = c;
+    }
+
+    /**
+     * Returns the summary for the table.
+     *
+     * @return the summary for the table
+     */
+    public Accessible getAccessibleSummary()
+    {
+      return summary;
+    }
+
+    /**
+     * Sets the summary for the table.
+     *
+     * @param s the summary to set
+     */
+    public void setAccessibleSummary(Accessible s)
+    {
+      summary = s;
+    }
+
+    /**
+     * Returns the number of rows in the table.
+     *
+     * @return the number of rows in the table
+     */
+    public int getAccessibleRowCount()
+    {
+      return getRowCount();
+    }
+
+    /**
+     * Returns the number of columns in the table.
+     *
+     * @return the number of columns in the table
+     */
+    public int getAccessibleColumnCount()
+    {
+      return getColumnCount();
+    }
+
+    /**
+     * Returns the accessible child at the given index.
+     *
+     * @param index  the child index.
+     * 
+     * @return The accessible child.
+     */
+    public Accessible getAccessibleChild(int index)
+    {
+      int r = getAccessibleRow(index);
+      int c = getAccessibleColumn(index);
+      return getAccessibleAt(r, c);  
+    }
+    
+    /**
+     * Returns the accessible child (table cell) at the specified row and
+     * column.
+     *
+     * @param r the row number
+     * @param c the column number
+     *
+     * @return the accessible child (table cell) at the specified row and
+     *         column
+     */
+    public Accessible getAccessibleAt(int r, int c)
+    {
+      TableCellRenderer cellRenderer = getCellRenderer(r, c);
+      Component renderer = cellRenderer.getTableCellRendererComponent(
+          JTable.this, getValueAt(r, c), isCellSelected(r, c), false, r, c);
+      if (renderer instanceof Accessible)
+        return (Accessible) renderer;
+      return null;
+    }
+
+    /**
+     * Returns the number of rows that the specified cell occupies. The
+     * standard table cells only occupy one row, so we return <code>1</code>
+     * here.
+     *
+     * @param r the row number
+     * @param c the column number
+     *
+     * @return the number of rows that the specified cell occupies
+     */
+    public int getAccessibleRowExtentAt(int r, int c)
+    {
+      return 1;
+    }
+
+    /**
+     * Returns the number of columns that the specified cell occupies. The
+     * standard table cells only occupy one column, so we return <code>1</code>
+     * here.
+     *
+     * @param r the row number
+     * @param c the column number
+     *
+     * @return the number of rows that the specified cell occupies
+     */
+    public int getAccessibleColumnExtentAt(int r, int c)
+    {
+      return 1;
+    }
+
+    /**
+     * Returns the accessible row header.
+     *
+     * @return the accessible row header
+     */
+    public AccessibleTable getAccessibleRowHeader()
+    {
+      // The RI seems to always return null here, so do we.
+      return null;
+    }
+
+    /**
+     * Sets the accessible row header.
+     *
+     * @param header the header to set
+     */
+    public void setAccessibleRowHeader(AccessibleTable header)
+    {
+      // In the RI this seems to be a no-op.    
+    }
+
+    /**
+     * Returns the column header.
+     *
+     * @return the column header, or <code>null</code> if there is no column
+     *         header
+     */
+    public AccessibleTable getAccessibleColumnHeader()
+    {
+      JTableHeader h = getTableHeader();
+      AccessibleTable header = null;
+      if (h != null)
+        header = new AccessibleTableHeader(h);
+      return header;
+    }
+
+    /**
+     * Sets the accessible column header. The default implementation doesn't
+     * allow changing the header this way, so this is a no-op.
+     *
+     * @param header the accessible column header to set
+     */
+    public void setAccessibleColumnHeader(AccessibleTable header)
+    {
+      // The RI doesn't seem to do anything, so we also do nothing.
+    }
+
+    /**
+     * Returns the accessible description for the row with the specified index,
+     * or <code>null</code> if no description has been set.
+     *
+     * @param r the row for which the description is queried
+     *
+     * @return the accessible description for the row with the specified index,
+     *         or <code>null</code> if no description has been set
+     */
+    public Accessible getAccessibleRowDescription(int r)
+    {
+      Accessible descr = null;
+      if (rowDescriptions != null)
+        descr = rowDescriptions[r];
+      return descr;
+    }
+
+    /**
+     * Sets the accessible description for the row with the specified index.
+     *
+     * @param r the row number for which to set the description
+     * @param description the description to set
+     */
+    public void setAccessibleRowDescription(int r, Accessible description)
+    {
+      if (rowDescriptions == null)
+        rowDescriptions = new Accessible[getAccessibleRowCount()];
+      rowDescriptions[r] = description;
+    }
+
+    /**
+     * Returns the accessible description for the column with the specified
+     * index, or <code>null</code> if no description has been set.
+     *
+     * @param c the column for which the description is queried
+     *
+     * @return the accessible description for the column with the specified
+     *         index, or <code>null</code> if no description has been set
+     */
+    public Accessible getAccessibleColumnDescription(int c)
+    {
+      Accessible descr = null;
+      if (columnDescriptions != null)
+        descr = columnDescriptions[c];
+      return descr;
+    }
+
+    /**
+     * Sets the accessible description for the column with the specified index.
+     *
+     * @param c the column number for which to set the description
+     * @param description the description to set
+     */
+    public void setAccessibleColumnDescription(int c, Accessible description)
+    {
+      if (columnDescriptions == null)
+        columnDescriptions = new Accessible[getAccessibleRowCount()];
+      columnDescriptions[c] = description;
+    }
+
+    /**
+     * Returns <code>true</code> if the accessible child at the specified
+     * row and column is selected, <code>false</code> otherwise.
+     *
+     * @param r the row number of the child
+     * @param c the column number of the child
+     *
+     * @return <code>true</code> if the accessible child at the specified
+     *         row and column is selected, <code>false</code> otherwise
+     */
+    public boolean isAccessibleSelected(int r, int c)
+    {
+      return isCellSelected(r, c);
+    }
+
+    /**
+     * Returns <code>true</code> if the row with the specified index is
+     * selected, <code>false</code> otherwise.
+     *
+     * @param r the row number
+     *
+     * @return <code>true</code> if the row with the specified index is
+     *        selected, <code>false</code> otherwise
+     */
+    public boolean isAccessibleRowSelected(int r)
+    {
+      return isRowSelected(r);
+    }
+
+    /**
+     * Returns <code>true</code> if the column with the specified index is
+     * selected, <code>false</code> otherwise.
+     *
+     * @param c the column number
+     *
+     * @return <code>true</code> if the column with the specified index is
+     *        selected, <code>false</code> otherwise
+     */
+    public boolean isAccessibleColumnSelected(int c)
+    {
+      return isColumnSelected(c);
+    }
+
+    /**
+     * Returns the indices of all selected rows.
+     *
+     * @return the indices of all selected rows
+     */
+    public int[] getSelectedAccessibleRows()
+    {
+      return getSelectedRows();
+    }
+
+    /**
+     * Returns the indices of all selected columns.
+     *
+     * @return the indices of all selected columns
+     */
+    public int[] getSelectedAccessibleColumns()
+    {
+      return getSelectedColumns();
+    }
+
+    /**
+     * Returns the accessible row at the specified index.
+     *
+     * @param index the index for which to query the row
+     *
+     * @return the row number at the specified table index
+     */
+    public int getAccessibleRowAtIndex(int index)
+    {
+      // TODO: Back this up by a Mauve test and update API docs accordingly.
+      return index / getColumnCount();
+    }
+
+    /**
+     * Returns the accessible column at the specified index.
+     *
+     * @param index the index for which to query the column
+     *
+     * @return the column number at the specified table index
+     */
+    public int getAccessibleColumnAtIndex(int index)
+    {
+      // TODO: Back this up by a Mauve test and update API docs accordingly.
+      return index % getColumnCount();
+    }
+
+    /**
+     * Returns the accessible child index at the specified column and row.
+     *
+     * @param row the row
+     * @param column the column
+     *
+     * @return the index of the accessible child at the specified row and
+     *         column
+     */
+    public int getAccessibleIndexAt(int row, int column)
+    {
+      // TODO: Back this up by a Mauve test and update API docs accordingly.
+      return row * getColumnCount() + column;
+    }
+  }
+  /**
+   * Handles property changes from the <code>TableColumn</code>s of this
+   * <code>JTable</code>.
+   *
+   * More specifically, this triggers a {@link #revalidate()} call if the
+   * preferredWidth of one of the observed columns changes.
+   */
+  class TableColumnPropertyChangeHandler implements PropertyChangeListener
+  {
+    /**
+     * Receives notification that a property of the observed TableColumns has
+     * changed.
+     * 
+     * @param ev the property change event
+     */
+    public void propertyChange(PropertyChangeEvent ev)
+    {
+      if (ev.getPropertyName().equals("preferredWidth"))
+        {
+          JTableHeader header = getTableHeader();
+          if (header != null)
+            // Do nothing if the table is in the resizing mode.
+            if (header.getResizingColumn() == null)
+              {
+                TableColumn col = (TableColumn) ev.getSource();
+                header.setResizingColumn(col);
+                doLayout();
+                header.setResizingColumn(null);
+              }
+        }
+    }
+  }
+
+  /**
+   * A cell renderer for boolean values.
+   */
+  private class BooleanCellRenderer
+    extends DefaultTableCellRenderer
+  {
+    /**
+     * The CheckBox that is used for rendering.
+     */
+    private final JCheckBox checkBox;
+    
+    /**
+     * Creates a new checkbox based boolean cell renderer. The checkbox is
+     * centered by default.
+     */
+    BooleanCellRenderer()
+    {
+       checkBox = new JCheckBox();
+       checkBox.setHorizontalAlignment(SwingConstants.CENTER);
+    }
+   
+    /**
+     * Get the check box.
+     */
+    JCheckBox getCheckBox()
+    {
+      return checkBox;
+    }
+
+    /**
+     * Returns the component that is used for rendering the value.
+     * 
+     * @param table the JTable
+     * @param value the value of the object
+     * @param isSelected is the cell selected?
+     * @param hasFocus has the cell the focus?
+     * @param row the row to render
+     * @param column the cell to render
+     * @return this component (the default table cell renderer)
+     */
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected,
+                                                   boolean hasFocus, int row,
+                                                   int column)
+    {
+      if (isSelected)
+        {
+          checkBox.setBackground(table.getSelectionBackground());
+          checkBox.setForeground(table.getSelectionForeground());
+        }
+      else
+        {
+          checkBox.setBackground(table.getBackground());
+          checkBox.setForeground(table.getForeground());
+        }
+
+      if (hasFocus)
+        {
+          checkBox.setBorder(
+            UIManager.getBorder("Table.focusCellHighlightBorder"));
+          if (table.isCellEditable(row, column))
+            {
+              checkBox.setBackground(
+                UIManager.getColor("Table.focusCellBackground"));
+              checkBox.setForeground(
+                UIManager.getColor("Table.focusCellForeground"));
+            }
+        }
+      else
+        checkBox.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
+
+      // Null is rendered as false.
+      if (value == null)
+        checkBox.setSelected(false);
+      else
+        {
+          Boolean boolValue = (Boolean) value;
+          checkBox.setSelected(boolValue.booleanValue());
+        }
+      return checkBox;
+    }
+  }
+
+  /**
+   * A cell renderer for Date values.
+   */
+  private class DateCellRenderer
+    extends DefaultTableCellRenderer
+  {
+    /**
+     * Returns the component that is used for rendering the value.
+     *
+     * @param table the JTable
+     * @param value the value of the object
+     * @param isSelected is the cell selected?
+     * @param hasFocus has the cell the focus?
+     * @param row the row to render
+     * @param column the cell to render
+     * 
+     * @return this component (the default table cell renderer)
+     */
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected,
+                                                   boolean hasFocus, int row,
+                                                   int column)
+    {
+      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
+                                          row, column);
+      if (value instanceof Date)
+        {
+          Date dateValue = (Date) value;
+          DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
+          setText(df.format(dateValue));
+        }
+      return this;
+    }
+  }
+
+  /**
+   * A cell renderer for Double values.
+   */
+  private class DoubleCellRenderer
+    extends DefaultTableCellRenderer
+  {
+    /**
+     * Creates a new instance of NumberCellRenderer.
+     */
+    public DoubleCellRenderer()
+    {
+      setHorizontalAlignment(JLabel.RIGHT);
+    }
+
+    /**
+     * Returns the component that is used for rendering the value.
+     *
+     * @param table the JTable
+     * @param value the value of the object
+     * @param isSelected is the cell selected?
+     * @param hasFocus has the cell the focus?
+     * @param row the row to render
+     * @param column the cell to render
+     * 
+     * @return this component (the default table cell renderer)
+     */
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected,
+                                                   boolean hasFocus, int row,
+                                                   int column)
+    {
+      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
+                                          row, column);
+      if (value instanceof Double)
+        {
+          Double doubleValue = (Double) value;
+          NumberFormat nf = NumberFormat.getInstance();
+          setText(nf.format(doubleValue.doubleValue()));
+        }
+      return this;
+    }
+  }
+
+  /**
+   * A cell renderer for Float values.
+   */
+  private class FloatCellRenderer
+    extends DefaultTableCellRenderer
+  {
+    /**
+     * Creates a new instance of NumberCellRenderer.
+     */
+    public FloatCellRenderer()
+    {
+      setHorizontalAlignment(JLabel.RIGHT);
+    }
+
+    /**
+     * Returns the component that is used for rendering the value.
+     *
+     * @param table the JTable
+     * @param value the value of the object
+     * @param isSelected is the cell selected?
+     * @param hasFocus has the cell the focus?
+     * @param row the row to render
+     * @param column the cell to render
+     * 
+     * @return this component (the default table cell renderer)
+     */
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected,
+                                                   boolean hasFocus, int row,
+                                                   int column)
+    {
+      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
+                                          row, column);
+      if (value instanceof Float)
+        {
+          Float floatValue = (Float) value;
+          NumberFormat nf = NumberFormat.getInstance();
+          setText(nf.format(floatValue.floatValue()));
+        }
+      return this;
+    }
+  }
+
+  /**
+   * A cell renderer for Number values.
+   */
+  private class NumberCellRenderer
+    extends DefaultTableCellRenderer
+  {
+    /**
+     * Creates a new instance of NumberCellRenderer.
+     */
+    public NumberCellRenderer()
+    {
+      setHorizontalAlignment(JLabel.RIGHT);
+    }
+  }
+
+  /**
+   * A cell renderer for Icon values.
+   */
+  private class IconCellRenderer
+    extends DefaultTableCellRenderer
+  {
+    IconCellRenderer()
+    {
+      setHorizontalAlignment(SwingConstants.CENTER);
+    }
+    
+    
+    /**
+     * Returns the component that is used for rendering the value.
+     *
+     * @param table the JTable
+     * @param value the value of the object
+     * @param isSelected is the cell selected?
+     * @param hasFocus has the cell the focus?
+     * @param row the row to render
+     * @param column the cell to render
+     * 
+     * @return this component (the default table cell renderer)
+     */
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected,
+                                                   boolean hasFocus, int row,
+                                                   int column)
+    {
+      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
+                                          row, column);
+      if (value instanceof Icon)
+        {
+          Icon iconValue = (Icon) value;
+          setIcon(iconValue);
+        }
+      else
+        {
+          setIcon(null);
+        }
+      setText("");
+      return this;
+    }
+  }
+  
+    /**
+     * The JTable text component (used in editing) always has the table
+     * as its parent. The scrollRectToVisible must be adjusted taking the
+     * relative component position.
+     *
+     * @author Audrius Meskauskas (AudriusA at Bioinformatics.org)
+     */
+    private class TableTextField extends JTextField
+    {
+      /**
+       * Create the text field without the border.
+       */
+      TableTextField()
+      {
+        setBorder(BorderFactory.createLineBorder(getGridColor(), 2));
+      }
+    }    
+  
+
+  private static final long serialVersionUID = 3876025080382781659L;
+  
+  /**
+   * This table, for referring identically name methods from inner classes.
+   */
+  final JTable this_table = this;
+
+
+  /**
+   * When resizing columns, do not automatically change any columns. In this
+   * case the table should be enclosed in a {@link JScrollPane} in order to
+   * accomodate cases in which the table size exceeds its visible area.
+   */
+  public static final int AUTO_RESIZE_OFF = 0;
+
+  /**
+   * When resizing column <code>i</code>, automatically change only the
+   * single column <code>i+1</code> to provide or absorb excess space
+   * requirements.
+   */
+  public static final int AUTO_RESIZE_NEXT_COLUMN = 1;
+
+  /**
+   * When resizing column <code>i</code> in a table of <code>n</code>
+   * columns, automatically change all columns in the range <code>[i+1,
+   * n)</code>, uniformly, to provide or absorb excess space requirements.
+   */
+  public static final int AUTO_RESIZE_SUBSEQUENT_COLUMNS = 2;
+  
+  /**
+   * When resizing column <code>i</code> in a table of <code>n</code>
+   * columns, automatically change all columns in the range <code>[0,
+   * n)</code> (with the exception of column i) uniformly, to provide or
+   * absorb excess space requirements.
+   */
+  public static final int AUTO_RESIZE_ALL_COLUMNS = 4;
+
+  /**
+   * When resizing column <code>i</code> in a table of <code>n</code>
+   * columns, automatically change column <code>n-1</code> (the last column
+   * in the table) to provide or absorb excess space requirements.
+   */
+  public static final int AUTO_RESIZE_LAST_COLUMN = 3;
+
+  /**
+   * A table mapping {@link java.lang.Class} objects to 
+   * {@link TableCellEditor} objects. This table is consulted by the 
+   * FIXME
+   */
+  protected Hashtable defaultEditorsByColumnClass = new Hashtable();
+
+  /**
+   * A table mapping {@link java.lang.Class} objects to 
+   * {@link TableCellEditor} objects. This table is consulted by the 
+   * FIXME
+   */
+  protected Hashtable defaultRenderersByColumnClass = new Hashtable();
+
+  /**
+   * The column that is edited, -1 if the table is not edited currently.
+   */
+  protected int editingColumn;
+
+  /**
+   * The row that is edited, -1 if the table is not edited currently.
+   */
+  protected int editingRow;
+
+  /**
+   * The component that is used for editing.
+   * <code>null</code> if the table is not editing currently.
+   *
+   */
+  protected transient Component editorComp;
+
+
+  /**
+   * Whether or not the table should automatically compute a matching
+   * {@link TableColumnModel} and assign it to the {@link #columnModel}
+   * property when the {@link #dataModel} property is changed. 
+   *
+   * @see #setModel(TableModel)
+   * @see #createDefaultColumnsFromModel()
+   * @see #setColumnModel(TableColumnModel)
+   * @see #setAutoCreateColumnsFromModel(boolean)
+   * @see #getAutoCreateColumnsFromModel()
+   */
+  protected boolean autoCreateColumnsFromModel;
+
+  /**
+   * A numeric code specifying the resizing behavior of the table. Must be
+   * one of {@link #AUTO_RESIZE_ALL_COLUMNS} (the default), {@link
+   * #AUTO_RESIZE_LAST_COLUMN}, {@link #AUTO_RESIZE_NEXT_COLUMN}, {@link
+   * #AUTO_RESIZE_SUBSEQUENT_COLUMNS}, or {@link #AUTO_RESIZE_OFF}.
+   * 
+   * @see #doLayout()
+   * @see #setAutoResizeMode(int)
+   * @see #getAutoResizeMode()
+   */
+  protected int autoResizeMode;
+
+  /**
+   * The height in pixels of any row of the table. All rows in a table are
+   * of uniform height. This differs from column width, which varies on a
+   * per-column basis, and is stored in the individual columns of the
+   * {@link #columnModel}.
+   * 
+   * @see #getRowHeight()
+   * @see #setRowHeight(int)
+   * @see TableColumn#getWidth()
+   * @see TableColumn#setWidth(int)
+   */
+  protected int rowHeight;
+
+  /**
+   * The height in pixels of the gap left between any two rows of the table. 
+   * 
+   * @see #setRowMargin(int)
+   * @see #getRowHeight()
+   * @see #getIntercellSpacing()
+   * @see #setIntercellSpacing(Dimension)
+   * @see TableColumnModel#getColumnMargin()
+   * @see TableColumnModel#setColumnMargin(int)
+   */
+  protected int rowMargin;
+
+  /**
+   * Whether or not the table should allow row selection. If the table
+   * allows both row <em>and</em> column selection, it is said to allow
+   * "cell selection". Previous versions of the JDK supported cell
+   * selection as an independent concept, but it is now represented solely
+   * in terms of simultaneous row and column selection.
+   *
+   * @see TableColumnModel#getColumnSelectionAllowed()
+   * @see #setRowSelectionAllowed(boolean)
+   * @see #getRowSelectionAllowed()
+   * @see #getCellSelectionEnabled()
+   * @see #setCellSelectionEnabled(boolean)
+   */
+  protected boolean rowSelectionAllowed;
+
+  /**
+   * Obsolete. Use {@link #rowSelectionAllowed}, {@link 
+   * #getColumnSelectionAllowed}, or the combined methods {@link
+   * #getCellSelectionEnabled} and {@link #setCellSelectionEnabled(boolean)}.
+   */
+  protected boolean cellSelectionEnabled;
+  
+  /**
+   * The model for data stored in the table. Confusingly, the published API
+   * requires that this field be called <code>dataModel</code>, despite its
+   * property name. The table listens to its model as a {@link
+   * TableModelListener}.
+   *
+   * @see #tableChanged(TableModelEvent)
+   * @see TableModel#addTableModelListener(TableModelListener)
+   */
+  protected TableModel dataModel;
+
+  /**
+   * <p>A model of various aspects of the columns of the table, <em>not
+   * including</em> the data stored in them. The {@link TableColumnModel}
+   * is principally concerned with holding a set of {@link TableColumn}
+   * objects, each of which describes the display parameters of a column
+   * and the numeric index of the column from the data model which the
+   * column is presenting.</p>
+   *
+   * <p>The TableColumnModel also contains a {@link ListSelectionModel} which
+   * indicates which columns are currently selected. This selection model
+   * works in combination with the {@link #selectionModel} of the table
+   * itself to specify a <em>table selection</em>: a combination of row and
+   * column selections.</p>
+   *
+   * <p>Most application programmers do not need to work with this property
+   * at all: setting {@link #autoCreateColumnsFromModel} will construct the
+   * columnModel automatically, and the table acts as a facade for most of
+   * the interesting properties of the columnModel anyways.</p>
+   * 
+   * @see #setColumnModel(TableColumnModel)
+   * @see #getColumnModel()
+   */
+  protected TableColumnModel columnModel;
+
+  /**
+   * A model of the rows of this table which are currently selected. This
+   * model is used in combination with the column selection model held as a
+   * member of the {@link #columnModel} property, to represent the rows and
+   * columns (or both: cells) of the table which are currently selected.
+   *
+   * @see #rowSelectionAllowed
+   * @see #setSelectionModel(ListSelectionModel)
+   * @see #getSelectionModel()
+   * @see TableColumnModel#getSelectionModel()
+   * @see ListSelectionModel#addListSelectionListener(ListSelectionListener)   
+   */
+  protected ListSelectionModel selectionModel;
+
+  /**
+   * The current cell editor. 
+   */
+  protected TableCellEditor cellEditor;
+
+  /**
+   * Whether or not drag-and-drop is enabled on this table.
+   *
+   * @see #setDragEnabled(boolean)
+   * @see #getDragEnabled()
+   */
+  private boolean dragEnabled;
+
+  /**
+   * The color to paint the grid lines of the table, when either {@link
+   * #showHorizontalLines} or {@link #showVerticalLines} is set.
+   *
+   * @see #setGridColor(Color)
+   * @see #getGridColor()
+   */
+  protected Color gridColor;
+
+  /**
+   * The size this table would prefer its viewport assume, if it is
+   * contained in a {@link JScrollPane}.
+   *
+   * @see #setPreferredScrollableViewportSize(Dimension)
+   * @see #getPreferredScrollableViewportSize()
+   */
+  protected Dimension preferredViewportSize;
+
+  /**
+   * The color to paint the background of selected cells. Fires a property
+   * change event with name {@link #SELECTION_BACKGROUND_CHANGED_PROPERTY}
+   * when its value changes.
+   *
+   * @see #setSelectionBackground(Color)
+   * @see #getSelectionBackground()
+   */
+  protected Color selectionBackground;
+
+  /**
+   * The name carried in property change events when the {@link
+   * #selectionBackground} property changes.
+   */
+  private static final String SELECTION_BACKGROUND_CHANGED_PROPERTY = "selectionBackground";
+
+  /**
+   * The color to paint the foreground of selected cells. Fires a property
+   * change event with name {@link #SELECTION_FOREGROUND_CHANGED_PROPERTY}
+   * when its value changes.
+   *
+   * @see #setSelectionForeground(Color)
+   * @see #getSelectionForeground()
+   */
+  protected Color selectionForeground;
+
+  /**
+   * The name carried in property change events when the
+   * {@link #selectionForeground} property changes.
+   */
+  private static final String SELECTION_FOREGROUND_CHANGED_PROPERTY = "selectionForeground";
+
+  /**
+   * The showHorizontalLines property.
+   */
+  protected boolean showHorizontalLines;
+
+  /**
+   * The showVerticalLines property.
+   */
+  protected boolean showVerticalLines;
+
+  /**
+   * The tableHeader property.
+   */
+  protected JTableHeader tableHeader;
+
+  /**
+   * The property handler for this table's columns.
+   */
+  TableColumnPropertyChangeHandler tableColumnPropertyChangeHandler =
+    new TableColumnPropertyChangeHandler();
+
+  /**
+   * Whether cell editors should receive keyboard focus when the table is
+   * activated.
+   */
+  private boolean surrendersFocusOnKeystroke = false;
+
+  /**
+   * A Rectangle object to be reused in {@link #getCellRect}. 
+   */
+  private Rectangle rectCache = new Rectangle();
+
+  /**
+   * Indicates if the rowHeight property has been set by a client program or by
+   * the UI.
+   *
+   * @see #setUIProperty(String, Object)
+   * @see LookAndFeel#installProperty(JComponent, String, Object)
+   */
+  private boolean clientRowHeightSet = false;
+
+  /**
+   * Stores the sizes and positions of each row, when using non-uniform row
+   * heights. Initially the height of all rows is equal and stored in
+   * {link #rowHeight}. However, when an application calls
+   * {@link #setRowHeight(int,int)}, the table switches to non-uniform
+   * row height mode which stores the row heights in the SizeSequence
+   * object instead.
+   *
+   * @see #setRowHeight(int)
+   * @see #getRowHeight()
+   * @see #getRowHeight(int)
+   * @see #setRowHeight(int, int)
+   */
+  private SizeSequence rowHeights;
+  
+  /**
+   * This editor serves just a marker that the value must be simply changed to
+   * the opposite one instead of starting the editing session.
+   */
+  private transient TableCellEditor booleanInvertingEditor; 
+  
+  /**
+   * Creates a new <code>JTable</code> instance.
+   */
+  public JTable ()
+  {
+    this(null, null, null);
+  }
+
+  /**
+   * Creates a new <code>JTable</code> instance with the given number
+   * of rows and columns.
+   *
+   * @param numRows an <code>int</code> value
+   * @param numColumns an <code>int</code> value
+   */
+  public JTable (int numRows, int numColumns)
+  {
+    this(new DefaultTableModel(numRows, numColumns));
+  }
+
+  /**
+   * Creates a new <code>JTable</code> instance, storing the given data 
+   * array and heaving the given column names. To see the column names,
+   * you must place the JTable into the {@link JScrollPane}.
+   *
+   * @param data an <code>Object[][]</code> the table data
+   * @param columnNames an <code>Object[]</code> the column headers
+   */
+  public JTable(Object[][] data, Object[] columnNames)
+  {
+    this(new DefaultTableModel(data, columnNames));
+  }
+
+  /**
+   * Creates a new <code>JTable</code> instance, using the given data model
+   * object that provides information about the table content. The table model
+   * object is asked for the table size, other features and also receives
+   * notifications in the case when the table has been edited by the user.
+   * 
+   * @param model
+   *          the table model.
+   */
+  public JTable (TableModel model)
+  {
+    this(model, null, null);
+  }
+
+  /**
+   * Creates a new <code>JTable</code> instance, using the given model object
+   * that provides information about the table content. The table data model
+   * object is asked for the table size, other features and also receives
+   * notifications in the case when the table has been edited by the user. The
+   * table column model provides more detailed control on the table column
+   * related features.
+   * 
+   * @param dm
+   *          the table data mode
+   * @param cm
+   *          the table column model
+   */
+  public JTable (TableModel dm, TableColumnModel cm)
+  {
+    this(dm, cm, null);
+  }
+
+  /**
+   * Creates a new <code>JTable</code> instance, providing data model,
+   * column model and list selection model. The list selection model
+   * manages the selections.
+   *
+   * @param dm data model (manages table data)
+   * @param cm column model (manages table columns)
+   * @param sm list selection model (manages table selections)
+   */
+  public JTable (TableModel dm, TableColumnModel cm, ListSelectionModel sm)
+  {
+    boolean autoCreate = false;
+    TableColumnModel columnModel;
+    if (cm != null)
+        columnModel = cm;
+    else 
+      {
+        columnModel = createDefaultColumnModel();
+        autoCreate = true;
+      }
+    
+    // Initialise the intercelar spacing before setting the column model to
+    // avoid firing unnecessary events.
+    // The initial incellar spacing is new Dimenstion(1,1). 
+    rowMargin = 1;
+    columnModel.setColumnMargin(1);
+    setColumnModel(columnModel);
+    
+    setSelectionModel(sm == null ? createDefaultSelectionModel() : sm);
+    setModel(dm == null ? createDefaultDataModel() : dm);
+    setAutoCreateColumnsFromModel(autoCreate);
+    initializeLocalVars();
+    // The following four lines properly set the lead selection indices.
+    // After this, the UI will handle the lead selection indices.
+    // FIXME: this should probably not be necessary, if the UI is installed
+    // before the TableModel is set then the UI will handle things on its
+    // own, but certain variables need to be set before the UI can be installed
+    // so we must get the correct order for all the method calls in this
+    // constructor.
+    selectionModel.setAnchorSelectionIndex(0);    
+    selectionModel.setLeadSelectionIndex(0);
+    columnModel.getSelectionModel().setAnchorSelectionIndex(0);
+    columnModel.getSelectionModel().setLeadSelectionIndex(0);
+    updateUI();
+  }
+  
+  /**
+   * Creates a new <code>JTable</code> instance that uses data and column
+   * names, stored in {@link Vector}s.
+   *
+   * @param data the table data
+   * @param columnNames the table column names.
+   */
+  public JTable(Vector data, Vector columnNames)
+  {
+    this(new DefaultTableModel(data, columnNames));
+  }  
+  
+  /**
+   * Initialize local variables to default values.
+   */
+  protected void initializeLocalVars()
+  {
+    setTableHeader(createDefaultTableHeader());
+    if (autoCreateColumnsFromModel)
+      createDefaultColumnsFromModel();
+    this.columnModel.addColumnModelListener(this);
+
+    this.autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
+    setRowHeight(16);
+    this.rowMargin = 1;
+    this.rowSelectionAllowed = true;
+    // this.accessibleContext = new AccessibleJTable();
+    this.cellEditor = null;
+    // COMPAT: Both Sun and IBM have drag enabled
+    this.dragEnabled = true;
+    this.preferredViewportSize = new Dimension(450,400);
+    this.showHorizontalLines = true;
+    this.showVerticalLines = true;
+    this.editingColumn = -1;
+    this.editingRow = -1;
+  }
+  
+  /**
+   * Add the new table column. The table column class allows to specify column
+   * features more precisely, setting the preferred width, column data type
+   * (column class) and table headers.
+   * 
+   * There is no need the add columns to the table if the default column 
+   * handling is sufficient.
+   * 
+   * @param column
+   *          the new column to add.
+   */
+  public void addColumn(TableColumn column)
+  {
+    if (column.getHeaderValue() == null)
+      {
+        String name = dataModel.getColumnName(column.getModelIndex());
+        column.setHeaderValue(name);
+      }
+    
+    columnModel.addColumn(column);
+    column.addPropertyChangeListener(tableColumnPropertyChangeHandler);
+  }
+  
+  /**
+   * Create the default editors for this table. The default method creates
+   * the editor for Booleans.
+   * 
+   * Other fields are edited as strings at the moment.
+   */
+  protected void createDefaultEditors()
+  {
+    JCheckBox box = new BooleanCellRenderer().getCheckBox();
+    box.setBorder(BorderFactory.createLineBorder(getGridColor(), 2));
+    box.setBorderPainted(true);
+    booleanInvertingEditor = new DefaultCellEditor(box);    
+    setDefaultEditor(Boolean.class, booleanInvertingEditor);
+  }
+  
+  /**
+   * Create the default renderers for this table. The default method creates
+   * renderers for Boolean, Number, Double, Date, Icon and ImageIcon.
+   *
+   */
+  protected void createDefaultRenderers()
+  {
+    setDefaultRenderer(Boolean.class, new BooleanCellRenderer());
+    setDefaultRenderer(Number.class, new NumberCellRenderer());
+    setDefaultRenderer(Double.class, new DoubleCellRenderer());
+    setDefaultRenderer(Double.class, new FloatCellRenderer());
+    setDefaultRenderer(Date.class, new DateCellRenderer());
+    setDefaultRenderer(Icon.class, new IconCellRenderer());
+    setDefaultRenderer(ImageIcon.class, new IconCellRenderer());    
+  }
+  
+  /**
+   * @deprecated 1.0.2, replaced by <code>new JScrollPane(JTable)</code>
+   */
+  public static JScrollPane createScrollPaneForTable(JTable table)
+  {
+    return new JScrollPane(table);
+  }
+  
+  /**
+   * Create the default table column model that is used if the user-defined
+   * column model is not provided. The default method creates
+   * {@link DefaultTableColumnModel}.
+   * 
+   * @return the created table column model.
+   */
+  protected TableColumnModel createDefaultColumnModel()
+  {
+    return new DefaultTableColumnModel();
+  }
+
+  /**
+   * Create the default table data model that is used if the user-defined
+   * data model is not provided. The default method creates
+   * {@link DefaultTableModel}.
+   * 
+   * @return the created table data model.
+   */
+  protected TableModel createDefaultDataModel()
+  {
+    return new DefaultTableModel();
+  }
+
+  /**
+   * Create the default table selection model that is used if the user-defined
+   * selection model is not provided. The default method creates
+   * {@link DefaultListSelectionModel}.
+   * 
+   * @return the created table data model.
+   */
+  protected ListSelectionModel createDefaultSelectionModel()
+  {
+    return new DefaultListSelectionModel();
+  }
+  
+  /**
+   * Create the default table header, if the user - defined table header is not
+   * provided.
+   * 
+   * @return the default table header.
+   */
+  protected JTableHeader createDefaultTableHeader()
+  {
+    return new JTableHeader(columnModel);
+  }
+  
+  /**
+   * Invoked when the column is added. Revalidates and repains the table.
+   */
+  public void columnAdded (TableColumnModelEvent event)
+  {
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Invoked when the column margin is changed. 
+   * Revalidates and repains the table.
+   */
+  public void columnMarginChanged (ChangeEvent event)
+  {
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Invoked when the column is moved. Revalidates and repains the table.
+   */
+  public void columnMoved (TableColumnModelEvent event)
+  {
+    if (isEditing())
+      editingCanceled(null);
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Invoked when the column is removed. Revalidates and repains the table.
+   */
+  public void columnRemoved (TableColumnModelEvent event)
+  {
+    revalidate();
+    repaint();
+  }
+  
+  /**
+   * Invoked when the the column selection changes, repaints the changed
+   * columns. It is not recommended to override this method, register the
+   * listener instead.
+   */
+  public void columnSelectionChanged (ListSelectionEvent event)
+  {
+    // We must limit the indices to the bounds of the JTable's model, because
+    // we might get values of -1 or greater then columnCount in the case
+    // when columns get removed.
+    int idx0 = Math.max(0, Math.min(getColumnCount() - 1,
+                                    event.getFirstIndex()));
+    int idxn = Math.max(0, Math.min(getColumnCount() - 1,
+                                    event.getLastIndex()));
+
+    int minRow = 0;
+    int maxRow = getRowCount() - 1;
+    if (getRowSelectionAllowed())
+      {
+        minRow = selectionModel.getMinSelectionIndex();
+        maxRow = selectionModel.getMaxSelectionIndex();
+        int leadRow = selectionModel.getLeadSelectionIndex();
+        if (minRow == -1 && maxRow == -1)
+          {
+            minRow = leadRow;
+            maxRow = leadRow;
+          }
+        else
+          {
+            // In this case we need to repaint also the range to leadRow, not
+            // only between min and max.
+            if (leadRow != -1)
+              {
+                minRow = Math.min(minRow, leadRow);
+                maxRow = Math.max(maxRow, leadRow);
+              }
+          }
+      }
+    if (minRow != -1 && maxRow != -1)
+      {
+        Rectangle first = getCellRect(minRow, idx0, false);
+        Rectangle last = getCellRect(maxRow, idxn, false);
+        Rectangle dirty = SwingUtilities.computeUnion(first.x, first.y,
+                                                      first.width,
+                                                      first.height, last);
+        repaint(dirty);
+      }
+  }
+ 
+  /**
+   * Invoked when the editing is cancelled.
+   */
+  public void editingCanceled (ChangeEvent event)
+  {
+    if (editorComp!=null)
+      {
+        remove(editorComp);
+        repaint(editorComp.getBounds());        
+        editorComp = null;
+      }
+  }
+  
+  /**
+   * Finish the current editing session and update the table with the
+   * new value by calling {@link #setValueAt}.
+   * 
+   * @param event the change event
+   */
+  public void editingStopped (ChangeEvent event)
+  {
+    if (editorComp!=null)
+      {
+        remove(editorComp);        
+        setValueAt(cellEditor.getCellEditorValue(), editingRow, editingColumn);            
+        repaint(editorComp.getBounds());
+        editorComp = null;
+      }
+    requestFocusInWindow();
+  }
+
+  /**
+   * Invoked when the table changes.
+   * <code>null</code> means everything changed.
+   */
+  public void tableChanged (TableModelEvent event)
+  {
+    // update the column model from the table model if the structure has
+    // changed and the flag autoCreateColumnsFromModel is set
+    if (event == null || (event.getFirstRow() == TableModelEvent.HEADER_ROW))
+      handleCompleteChange(event);
+    else if (event.getType() == TableModelEvent.INSERT)
+      handleInsert(event);
+    else if (event.getType() == TableModelEvent.DELETE)
+      handleDelete(event);
+    else
+      handleUpdate(event);
+  }
+
+  /**
+   * Handles a request for complete relayout. This is the case when
+   * event.getFirstRow() == TableModelEvent.HEADER_ROW.
+   *
+   * @param ev the table model event
+   */
+  private void handleCompleteChange(TableModelEvent ev)
+  {
+    clearSelection();
+    checkSelection();
+    rowHeights = null;
+    if (getAutoCreateColumnsFromModel())
+      createDefaultColumnsFromModel();
+    else
+      resizeAndRepaint();
+  }
+
+  /**
+   * Handles table model insertions.
+   *
+   * @param ev the table model event
+   */
+  private void handleInsert(TableModelEvent ev)
+  {
+    // Sync selection model with data model.
+    int first = ev.getFirstRow();
+    if (first < 0)
+      first = 0;
+    int last = ev.getLastRow();
+    if (last < 0)
+      last = getRowCount() - 1;
+    selectionModel.insertIndexInterval(first, last - first + 1, true);
+    checkSelection();
+
+    // For variable height rows we must update the SizeSequence thing.
+    if (rowHeights != null)
+      {
+        rowHeights.insertEntries(first, last - first + 1, rowHeight);
+        // TODO: We repaint the whole thing when the rows have variable
+        // heights. We might want to handle this better though.
+        repaint();
+      }
+    else
+      {
+        // Repaint the dirty region and revalidate.
+        int rowHeight = getRowHeight();
+        Rectangle dirty = new Rectangle(0, first * rowHeight,
+                                        getColumnModel().getTotalColumnWidth(),
+                                        (getRowCount() - first) * rowHeight);
+        repaint(dirty);
+      }
+    revalidate();
+  }
+
+  /**
+   * Handles table model deletions.
+   *
+   * @param ev the table model event
+   */
+  private void handleDelete(TableModelEvent ev)
+  {
+    // Sync selection model with data model.
+    int first = ev.getFirstRow();
+    if (first < 0)
+      first = 0;
+    int last = ev.getLastRow();
+    if (last < 0)
+      last = getRowCount() - 1;
+
+    selectionModel.removeIndexInterval(first, last);
+
+    checkSelection();
+
+    if (dataModel.getRowCount() == 0)
+      clearSelection();
+
+    // For variable height rows we must update the SizeSequence thing.
+    if (rowHeights != null)
+      {
+        rowHeights.removeEntries(first, last - first + 1);
+        // TODO: We repaint the whole thing when the rows have variable
+        // heights. We might want to handle this better though.
+        repaint();
+      }
+    else
+      {
+        // Repaint the dirty region and revalidate.
+        int rowHeight = getRowHeight();
+        int oldRowCount = getRowCount() + last - first + 1;
+        Rectangle dirty = new Rectangle(0, first * rowHeight,
+                                        getColumnModel().getTotalColumnWidth(),
+                                        (oldRowCount - first) * rowHeight);
+        repaint(dirty);
+      }
+    revalidate();
+  }
+
+  /**
+   * Handles table model updates without structural changes.
+   *
+   * @param ev the table model event
+   */
+  private void handleUpdate(TableModelEvent ev)
+  {
+    if (rowHeights == null)
+      {
+        // Some cells have been changed without changing the structure.
+        // Figure out the dirty rectangle and repaint.
+        int firstRow = ev.getFirstRow();
+        int lastRow = ev.getLastRow();
+        int col = ev.getColumn();
+        Rectangle dirty;
+        if (col == TableModelEvent.ALL_COLUMNS)
+          {
+            // All columns changed. 
+            dirty = new Rectangle(0, firstRow * getRowHeight(),
+                                  getColumnModel().getTotalColumnWidth(), 0);
+          }
+        else
+          {
+            // Only one cell or column of cells changed.
+            // We need to convert to view column first.
+            int column = convertColumnIndexToModel(col);
+            dirty = getCellRect(firstRow, column, false);
+          }
+
+        // Now adjust the height of the dirty region.
+        dirty.height = (lastRow + 1) * getRowHeight();
+        // .. and repaint.
+        repaint(dirty);
+      }
+    else
+      {
+        // TODO: We repaint the whole thing when the rows have variable
+        // heights. We might want to handle this better though.
+        repaint();
+      }
+  }
+
+  /**
+   * Helper method for adjusting the lead and anchor indices when the
+   * table structure changed. This sets the lead and anchor to -1 if there's
+   * no more rows, or set them to 0 when they were at -1 and there are actually
+   * some rows now.
+   */
+  private void checkSelection()
+  {
+    TableModel m = getModel();
+    ListSelectionModel sm = selectionModel;
+    if (m != null)
+      {
+        int lead = sm.getLeadSelectionIndex();
+        int c = m.getRowCount();
+        if (c == 0 && lead != -1)
+          {
+            // No rows in the model, reset lead and anchor to -1.
+            sm.setValueIsAdjusting(true);
+            sm.setAnchorSelectionIndex(-1);
+            sm.setLeadSelectionIndex(-1);
+            sm.setValueIsAdjusting(false);
+          }
+        else if (c != 0 && lead == -1)
+          {
+            // We have rows, but no lead/anchor. Set them to 0. We
+            // do a little trick here so that the actual selection is not
+            // touched.
+            if (sm.isSelectedIndex(0))
+              sm.addSelectionInterval(0, 0);
+            else
+              sm.removeSelectionInterval(0, 0);
+          }
+        // Nothing to do in the other cases.
+      }
+  }
+
+  /**
+   * Invoked when another table row is selected. It is not recommended
+   * to override thid method, register the listener instead.
+   */
+  public void valueChanged (ListSelectionEvent event)
+  {
+    // If we are in the editing process, end the editing session.
+    if (isEditing())
+      editingStopped(null);
+    
+    // Repaint the changed region.
+    int first = Math.max(0, Math.min(getRowCount() - 1, event.getFirstIndex()));
+    int last = Math.max(0, Math.min(getRowCount() - 1, event.getLastIndex()));
+    Rectangle rect1 = getCellRect(first, 0, false);
+    Rectangle rect2 = getCellRect(last, getColumnCount() - 1, false);
+    Rectangle dirty = SwingUtilities.computeUnion(rect2.x, rect2.y,
+                                                  rect2.width, rect2.height,
+                                                  rect1);
+    repaint(dirty);
+  }
+
+ /**
+   * Returns index of the column that contains specified point 
+   * or -1 if this table doesn't contain this point.
+   *
+   * @param point point to identify the column
+   * @return index of the column that contains specified point or 
+   * -1 if this table doesn't contain this point.
+   */
+  public int columnAtPoint(Point point)
+  {
+    int ncols = getColumnCount();
+    Dimension gap = getIntercellSpacing();
+    TableColumnModel cols = getColumnModel();
+    int x = point.x;
+
+    for (int i = 0; i < ncols; ++i)
+      {
+        int width = cols.getColumn(i).getWidth()
+                    + (gap == null ? 0 : gap.width);
+        if (0 <= x && x < width)
+          return i;
+        x -= width;
+      }
+    return -1;
+  }
+
+  /**
+   * Returns index of the row that contains specified point or -1 if this table
+   * doesn't contain this point.
+   * 
+   * @param point point to identify the row
+   * @return index of the row that contains specified point or -1 if this table
+   *         doesn't contain this point.
+   */
+  public int rowAtPoint(Point point)
+  {
+    if (point != null)
+      {
+        int nrows = getRowCount();
+        int r;
+        int y = point.y;
+        if (rowHeights == null)
+          {
+            int height = getRowHeight();
+            r = y / height;
+          }
+        else
+          r = rowHeights.getIndex(y);
+
+        if (r < 0 || r >= nrows)
+          return -1;
+        else
+          return r;
+      }
+    else
+      return -1;
+  }
+
+  /** 
+   * Calculate the visible rectangle for a particular row and column. The
+   * row and column are specified in visual terms; the column may not match
+   * the {@link #dataModel} column.
+   *
+   * @param row the visible row to get the cell rectangle of
+   *
+   * @param column the visible column to get the cell rectangle of, which may
+   * differ from the {@link #dataModel} column
+   *
+   * @param includeSpacing whether or not to include the cell margins in the
+   * resulting cell. If <code>false</code>, the result will only contain the
+   * inner area of the target cell, not including its margins.
+   *
+   * @return a rectangle enclosing the specified cell
+   */
+  public Rectangle getCellRect(int row,
+                               int column,
+                               boolean includeSpacing)
+  {
+    Rectangle cellRect = new Rectangle(0, 0, 0, 0);
+
+    // Check for valid range vertically.
+    if (row >= getRowCount())
+      {
+        cellRect.height = getHeight();
+      }
+    else if (row >= 0)
+      {
+        cellRect.height = getRowHeight(row);
+        if (rowHeights == null)
+          cellRect.y = row * cellRect.height;
+        else
+          cellRect.y = rowHeights.getPosition(row);
+
+        if (! includeSpacing)
+          {
+            // The rounding here is important.
+            int rMargin = getRowMargin();
+            cellRect.y += rMargin / 2;
+            cellRect.height -= rMargin;
+          }
+      }
+    // else row < 0, y = height = 0
+
+    // Check for valid range horizontally.
+    if (column < 0)
+      {
+        if (! getComponentOrientation().isLeftToRight())
+          {
+            cellRect.x = getWidth();
+          }
+      }
+    else if (column >= getColumnCount())
+      {
+        if (getComponentOrientation().isLeftToRight())
+          {
+            cellRect.x = getWidth();
+          }
+      }
+    else
+      {
+        TableColumnModel tcm = getColumnModel();
+        if (getComponentOrientation().isLeftToRight())
+          {
+            for (int i = 0; i < column; i++)
+              cellRect.x += tcm.getColumn(i).getWidth();
+          }
+        else
+          {
+            for (int i = tcm.getColumnCount() - 1; i > column; i--)
+              cellRect.x += tcm.getColumn(i).getWidth();
+          }
+        cellRect.width = tcm.getColumn(column).getWidth();
+        if (! includeSpacing)
+          {
+            // The rounding here is important.
+            int cMargin = tcm.getColumnMargin();
+            cellRect.x += cMargin / 2;
+            cellRect.width -= cMargin;
+          }
+      }
+
+    return cellRect;
+  }
+
+  public void clearSelection()
+  {
+    selectionModel.clearSelection();
+    getColumnModel().getSelectionModel().clearSelection();
+  }
+
+  /**
+   * Get the value of the selectedRow property by delegation to
+   * the {@link ListSelectionModel#getMinSelectionIndex} method of the
+   * {@link #selectionModel} field.
+   *
+   * @return The current value of the selectedRow property
+   */
+  public int getSelectedRow ()
+  {    
+    return selectionModel.getMinSelectionIndex();
+  }
+  
+  /**
+   * Get the value of the {@link #selectionModel} property.
+   *
+   * @return The current value of the property
+   */
+  public ListSelectionModel getSelectionModel()
+  {
+    //Neither Sun nor IBM returns null if rowSelection not allowed
+    return selectionModel;
+  }
+  
+  public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
+  {
+    if (orientation == SwingConstants.VERTICAL)
+      return visibleRect.height * direction;
+    else
+      return visibleRect.width * direction;
+  }
+
+  /**
+   * Get the value of the <code>scrollableTracksViewportHeight</code> property.
+   *
+   * @return The constant value <code>false</code>
+   */
+  public boolean getScrollableTracksViewportHeight()
+  {
+    return false;
+  }
+  
+  /**
+   * Get the value of the <code>scrollableTracksViewportWidth</code> property.
+   *
+   * @return <code>true</code> unless the {@link #autoResizeMode} property is
+   * <code>AUTO_RESIZE_OFF</code>
+   */
+  public boolean getScrollableTracksViewportWidth()
+  {
+    if (autoResizeMode == AUTO_RESIZE_OFF)
+      return false;
+    else
+      return true;
+  }
+  
+  /**
+   * Return the preferred scrolling amount (in pixels) for the given scrolling
+   * direction and orientation. This method handles a partially exposed row by
+   * returning the distance required to completely expose the item. When
+   * scrolling the top item is completely exposed.
+   * 
+   * @param visibleRect the currently visible part of the component.
+   * @param orientation the scrolling orientation
+   * @param direction the scrolling direction (negative - up, positive -down).
+   *          The values greater than one means that more mouse wheel or similar
+   *          events were generated, and hence it is better to scroll the longer
+   *          distance.
+   * @author Audrius Meskauskas (audriusa at bioinformatics.org)
+   */
+  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
+                                        int direction)
+  {
+    int h = (rowHeight + rowMargin);
+    int delta = h * direction;
+
+    // Round so that the top would start from the row boundary
+    if (orientation == SwingConstants.VERTICAL)
+      {
+        // Completely expose the top row
+        int near = ((visibleRect.y + delta + h / 2) / h) * h;
+        int diff = visibleRect.y + delta - near;
+        delta -= diff;
+      }
+    return delta;
+    // TODO when scrollng horizontally, scroll into the column boundary.
+  }
+
+  /**
+   * Get the cell editor, suitable for editing the given cell. The default
+   * method requests the editor from the column model. If the column model does
+   * not provide the editor, the call is forwarded to the
+   * {@link #getDefaultEditor(Class)} with the parameter, obtained from
+   * {@link TableModel#getColumnClass(int)}.
+   * 
+   * @param row the cell row
+   * @param column the cell column
+   * @return the editor to edit that cell
+   */
+  public TableCellEditor getCellEditor(int row, int column)
+  {
+    TableCellEditor editor = columnModel.getColumn(column).getCellEditor();
+
+    if (editor == null)
+      {
+        int mcolumn = convertColumnIndexToModel(column);
+        editor = getDefaultEditor(dataModel.getColumnClass(mcolumn));
+      }
+
+    return editor;
+  }
+  
+  /**
+   * Get the default editor for editing values of the given type
+   * (String, Boolean and so on).
+   * 
+   * @param columnClass the class of the value that will be edited.
+   * 
+   * @return the editor, suitable for editing this data type
+   */
+  public TableCellEditor getDefaultEditor(Class columnClass)
+  {
+    if (defaultEditorsByColumnClass.containsKey(columnClass))
+      return (TableCellEditor) defaultEditorsByColumnClass.get(columnClass);
+    else
+      {
+        JTextField t = new TableTextField();        
+        TableCellEditor r = new DefaultCellEditor(t);
+        defaultEditorsByColumnClass.put(columnClass, r);
+        return r;
+      }
+  }
+  
+  /**
+   * Get the cell renderer for rendering the given cell.
+   * 
+   * @param row the cell row
+   * @param column the cell column
+   * @return the cell renderer to render that cell.
+   */
+  public TableCellRenderer getCellRenderer(int row, int column)
+  {
+    TableCellRenderer renderer = columnModel.getColumn(column).getCellRenderer();
+    if (renderer == null)
+      {
+        int mcolumn = convertColumnIndexToModel(column);
+        renderer = getDefaultRenderer(dataModel.getColumnClass(mcolumn));
+      }
+    return renderer;
+  }
+  
+  /**
+   * Set default renderer for rendering the given data type.
+   * 
+   * @param columnClass the data type (String, Boolean and so on) that must be
+   *          rendered.
+   * @param rend the renderer that will rend this data type
+   */
+  public void setDefaultRenderer(Class columnClass, TableCellRenderer rend)
+  {
+    defaultRenderersByColumnClass.put(columnClass, rend);
+  }
+  
+  /**
+   * Get the default renderer for rendering the given data type.
+   * 
+   * @param columnClass the data that must be rendered
+   * 
+   * @return the appropriate defauld renderer for rendering that data type.
+   */
+  public TableCellRenderer getDefaultRenderer(Class columnClass)
+  {
+    if (defaultRenderersByColumnClass.containsKey(columnClass))
+      return (TableCellRenderer) defaultRenderersByColumnClass.get(columnClass);
+    else
+      {
+        TableCellRenderer r = new DefaultTableCellRenderer();
+        defaultRenderersByColumnClass.put(columnClass, r);
+        return r;
+      }
+  }
+  
+  /**
+   * Convert the table model index into the table column number.
+   * The model number need not match the real column position. The columns
+   * may be rearranged by the user with mouse at any time by dragging the
+   * column headers.
+   *
+   * @param vc the column number (0=first).
+   * 
+   * @return the table column model index of this column.
+   * 
+   * @see TableColumn#getModelIndex()
+   */
+  public int convertColumnIndexToModel(int vc)
+  {
+    if (vc < 0)
+      return vc;
+    else
+      return columnModel.getColumn(vc).getModelIndex();
+  }
+  
+  /**
+   * Convert the table column number to the table column model index.
+   * The model number need not match the real column position. The columns
+   * may be rearranged by the user with mouse at any time by dragging the
+   * column headers.
+   *  
+   * @param mc the table column index (0=first).
+   * 
+   * @return the table column number in the model
+   * 
+   * @see TableColumn#getModelIndex() 
+   */
+  public int convertColumnIndexToView(int mc)
+  {
+    if (mc < 0)
+      return mc;
+    int ncols = getColumnCount();
+    for (int vc = 0; vc < ncols; ++vc)
+      {
+        if (columnModel.getColumn(vc).getModelIndex() == mc)
+          return vc;
+      }
+    return -1;
+  }
+  
+  /**
+   * Prepare the renderer for rendering the given cell.
+   * 
+   * @param renderer the renderer being prepared
+   * @param row the row of the cell being rendered
+   * @param column the column of the cell being rendered
+   * 
+   * @return the component which .paint() method will paint the cell.
+   */
+  public Component prepareRenderer(TableCellRenderer renderer,
+                                   int row,
+                                   int column)
+  {
+    boolean rowSelAllowed = getRowSelectionAllowed();
+    boolean colSelAllowed = getColumnSelectionAllowed();
+    boolean isSel = false;
+    if (rowSelAllowed && colSelAllowed || !rowSelAllowed && !colSelAllowed)
+      isSel = isCellSelected(row, column);
+    else
+      isSel = isRowSelected(row) && getRowSelectionAllowed()
+           || isColumnSelected(column) && getColumnSelectionAllowed();
+
+    // Determine the focused cell. The focused cell is the cell at the
+    // leadSelectionIndices of the row and column selection model.
+    ListSelectionModel rowSel = getSelectionModel();
+    ListSelectionModel colSel = getColumnModel().getSelectionModel();
+    boolean hasFocus = hasFocus() && isEnabled()
+                       && rowSel.getLeadSelectionIndex() == row
+                       && colSel.getLeadSelectionIndex() == column;
+
+    return renderer.getTableCellRendererComponent(this,
+                                                  dataModel.getValueAt(row, 
+						                       convertColumnIndexToModel(column)),
+                                                  isSel,
+                                                  hasFocus,
+                                                  row, column);
+  }
+
+
+  /**
+   * Get the value of the {@link #autoCreateColumnsFromModel} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getAutoCreateColumnsFromModel()
+  {
+    return autoCreateColumnsFromModel;
+  }
+
+  /**
+   * Get the value of the {@link #autoResizeMode} property.
+   *
+   * @return The current value of the property
+   */
+  public int getAutoResizeMode()
+  {
+    return autoResizeMode;
+  }
+
+  /**
+   * Get the value of the {@link #rowHeight} property.
+   *
+   * @return The current value of the property
+   */
+  public int getRowHeight()
+  {
+    return rowHeight;
+  }
+
+  /**
+   * Get the height of the specified row.
+   *
+   * @param row the row whose height to return
+   */
+  public int getRowHeight(int row)
+  {
+    int rh = rowHeight;
+    if (rowHeights != null)
+      rh = rowHeights.getSize(row);
+    return rh;
+  }
+
+
+  /**
+   * Get the value of the {@link #rowMargin} property.
+   *
+   * @return The current value of the property
+   */
+  public int getRowMargin()
+  {
+    return rowMargin;
+  }
+
+  /**
+   * Get the value of the {@link #rowSelectionAllowed} property.
+   *
+   * @return The current value of the property
+   * 
+   * @see #setRowSelectionAllowed(boolean)
+   */
+  public boolean getRowSelectionAllowed()
+  {
+    return rowSelectionAllowed;
+  }
+
+  /**
+   * Get the value of the {@link #cellSelectionEnabled} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getCellSelectionEnabled()
+  {
+    return getColumnSelectionAllowed() && getRowSelectionAllowed();
+  }
+
+  /**
+   * Get the value of the {@link #dataModel} property.
+   *
+   * @return The current value of the property
+   */
+  public TableModel getModel()
+  {
+    return dataModel;
+  }
+
+  /**
+   * Get the value of the <code>columnCount</code> property by
+   * delegation to the {@link #columnModel} field.
+   *
+   * @return The current value of the columnCount property
+   */
+  public int getColumnCount()
+  {
+    return columnModel.getColumnCount();    
+  }
+
+  /**
+   * Get the value of the <code>rowCount</code> property by
+   * delegation to the {@link #dataModel} field.
+   *
+   * @return The current value of the rowCount property
+   */
+  public int getRowCount()
+  {
+    return dataModel.getRowCount();
+  }
+
+  /**
+   * Get the value of the {@link #columnModel} property.
+   *
+   * @return The current value of the property
+   */
+  public TableColumnModel getColumnModel()
+  {
+    return columnModel;
+  }
+
+  /**
+   * Get the value of the <code>selectedColumn</code> property by
+   * delegation to the {@link #columnModel} field.
+   *
+   * @return The current value of the selectedColumn property
+   */
+  public int getSelectedColumn()
+  {
+    return columnModel.getSelectionModel().getMinSelectionIndex();
+  }
+
+  private static int countSelections(ListSelectionModel lsm)
+  {
+    int lo = lsm.getMinSelectionIndex();
+    int hi = lsm.getMaxSelectionIndex();
+    int sum = 0;
+    if (lo != -1 && hi != -1)
+      {
+        switch (lsm.getSelectionMode())
+          {
+          case ListSelectionModel.SINGLE_SELECTION:
+            sum = 1;
+            break;
+            
+          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
+            sum = hi - lo + 1;
+            break;
+            
+          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
+            for (int i = lo; i <= hi; ++i)
+              if (lsm.isSelectedIndex(i))        
+                ++sum;
+            break;
+          }
+      }
+    return sum;
+  }
+
+  private static int[] getSelections(ListSelectionModel lsm)
+  {
+    int sz = countSelections(lsm);
+    int [] ret = new int[sz];
+
+    int lo = lsm.getMinSelectionIndex();
+    int hi = lsm.getMaxSelectionIndex();
+    int j = 0;
+    if (lo != -1 && hi != -1)
+      {
+        switch (lsm.getSelectionMode())
+          {
+          case ListSelectionModel.SINGLE_SELECTION:
+            ret[0] = lo;
+            break;      
+      
+          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:            
+            for (int i = lo; i <= hi; ++i)
+              ret[j++] = i;
+            break;
+            
+          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
+            for (int i = lo; i <= hi; ++i)
+              if (lsm.isSelectedIndex(i))        
+                ret[j++] = i;
+            break;
+          }
+      }
+    return ret;
+  }
+
+  /**
+   * Get the value of the <code>selectedColumnCount</code> property by
+   * delegation to the {@link #columnModel} field.
+   *
+   * @return The current value of the selectedColumnCount property
+   */  
+  public int getSelectedColumnCount()
+  {
+    return countSelections(columnModel.getSelectionModel());
+  }
+
+  /**
+   * Get the value of the <code>selectedColumns</code> property by
+   * delegation to the {@link #columnModel} field.
+   *
+   * @return The current value of the selectedColumns property
+   */
+  public int[] getSelectedColumns()
+  {
+    return getSelections(columnModel.getSelectionModel());
+  }
+
+  /**
+   * Get the value of the <code>columnSelectionAllowed</code> property.
+   *
+   * @return The current value of the columnSelectionAllowed property
+   * 
+   * @see #setColumnSelectionAllowed(boolean)
+   */
+  public boolean getColumnSelectionAllowed()
+  {
+    return getColumnModel().getColumnSelectionAllowed();
+  }
+
+  /**
+   * Get the value of the <code>selectedRowCount</code> property by
+   * delegation to the {@link #selectionModel} field.
+   *
+   * @return The current value of the selectedRowCount property
+   */
+  public int getSelectedRowCount()
+  {
+    return countSelections(selectionModel);
+  }
+
+  /**
+   * Get the value of the <code>selectedRows</code> property by
+   * delegation to the {@link #selectionModel} field.
+   *
+   * @return The current value of the selectedRows property
+   */
+  public int[] getSelectedRows()
+  {
+    return getSelections(selectionModel);
+  }
+
+  /**
+   * Get the value of the {@link #accessibleContext} property.
+   *
+   * @return The current value of the property
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      {
+        AccessibleJTable ctx = new AccessibleJTable();
+        addPropertyChangeListener(ctx);
+        TableColumnModel tcm = getColumnModel();
+        tcm.addColumnModelListener(ctx);
+        tcm.getSelectionModel().addListSelectionListener(ctx);
+        getSelectionModel().addListSelectionListener(ctx);
+        
+        accessibleContext = ctx;
+      }
+    return accessibleContext;
+  }
+
+  /**
+   * Get the value of the {@link #cellEditor} property.
+   *
+   * @return The current value of the property
+   */
+  public TableCellEditor getCellEditor()
+  {
+    return cellEditor;
+  }
+
+  /**
+   * Get the value of the {@link #dragEnabled} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getDragEnabled()
+  {
+    return dragEnabled;
+  }
+
+  /**
+   * Get the value of the {@link #gridColor} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getGridColor()
+  {
+    return gridColor;
+  }
+
+  /**
+   * Get the value of the <code>intercellSpacing</code> property.
+   *
+   * @return The current value of the property
+   */
+  public Dimension getIntercellSpacing()
+  {
+    return new Dimension(columnModel.getColumnMargin(), rowMargin);
+  }
+
+  /**
+   * Get the value of the {@link #preferredViewportSize} property.
+   *
+   * @return The current value of the property
+   */
+  public Dimension getPreferredScrollableViewportSize()
+  {
+    return preferredViewportSize;
+  }
+
+  /**
+   * Get the value of the {@link #selectionBackground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionBackground()
+  {
+    return selectionBackground;
+  }
+
+  /**
+   * Get the value of the {@link #selectionForeground} property.
+   *
+   * @return The current value of the property
+   */
+  public Color getSelectionForeground()
+  {
+    return selectionForeground;
+  }
+
+  /**
+   * Get the value of the {@link #showHorizontalLines} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getShowHorizontalLines()
+  {
+    return showHorizontalLines;
+  }
+
+  /**
+   * Get the value of the {@link #showVerticalLines} property.
+   *
+   * @return The current value of the property
+   */
+  public boolean getShowVerticalLines()
+  {
+    return showVerticalLines;
+  }
+
+  /**
+   * Get the value of the {@link #tableHeader} property.
+   *
+   * @return The current value of the property
+   */
+  public JTableHeader getTableHeader()
+  {
+    return tableHeader;
+  }
+
+  /**
+   * Removes specified column from displayable columns of this table.
+   *
+   * @param column column to removed
+   */
+  public void removeColumn(TableColumn column)
+  {    
+    columnModel.removeColumn(column);
+  }
+
+  /**
+   * Moves column at the specified index to new given location.
+   *
+   * @param column index of the column to move
+   * @param targetColumn index specifying new location of the column
+   */ 
+  public void moveColumn(int column,int targetColumn) 
+  {
+    columnModel.moveColumn(column, targetColumn);
+  }
+
+  /**
+   * Set the value of the {@link #autoCreateColumnsFromModel} flag.  If the
+   * flag changes from <code>false</code> to <code>true</code>, the
+   * {@link #createDefaultColumnsFromModel()} method is called.
+   *
+   * @param autoCreate  the new value of the flag.
+   */ 
+  public void setAutoCreateColumnsFromModel(boolean autoCreate)
+  {
+    if (autoCreateColumnsFromModel != autoCreate)
+    {
+      autoCreateColumnsFromModel = autoCreate;
+      if (autoCreate)
+        createDefaultColumnsFromModel();
+    }
+  }
+
+  /**
+   * Set the value of the {@link #autoResizeMode} property.
+   *
+   * @param a The new value of the autoResizeMode property
+   */ 
+  public void setAutoResizeMode(int a)
+  {
+    autoResizeMode = a;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Sets the height for all rows in the table. If you want to change the
+   * height of a single row instead, use {@link #setRowHeight(int, int)}.
+   *
+   * @param r the height to set for all rows
+   *
+   * @see #getRowHeight()
+   * @see #setRowHeight(int, int)
+   * @see #getRowHeight(int)
+   */ 
+  public void setRowHeight(int r)
+  {
+    if (r < 1)
+      throw new IllegalArgumentException();
+
+    clientRowHeightSet = true;
+
+    rowHeight = r;
+    rowHeights = null;
+    revalidate();
+    repaint();
+  }
+  
+  /**
+   * Sets the height of a single row in the table.
+   * 
+   * @param rh the new row height
+   * @param row the row to change the height of
+   */
+  public void setRowHeight(int row, int rh)
+  {
+    if (rowHeights == null)
+      {
+        rowHeights = new SizeSequence(getRowCount(), rowHeight);
+      }
+    rowHeights.setSize(row, rh);
+  }
+  
+  /**
+   * Set the value of the {@link #rowMargin} property.
+   *
+   * @param r The new value of the rowMargin property
+   */ 
+  public void setRowMargin(int r)
+  {
+    rowMargin = r;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #rowSelectionAllowed} property.
+   *
+   * @param r The new value of the rowSelectionAllowed property
+   * 
+   * @see #getRowSelectionAllowed()
+   */ 
+  public void setRowSelectionAllowed(boolean r)
+  {
+    if (rowSelectionAllowed != r) 
+      {
+        rowSelectionAllowed = r;
+        firePropertyChange("rowSelectionAllowed", !r, r);
+        repaint();
+      }
+  }
+
+  /**
+   * Set the value of the {@link #cellSelectionEnabled} property.
+   *
+   * @param c The new value of the cellSelectionEnabled property
+   */ 
+  public void setCellSelectionEnabled(boolean c)
+  {
+    setColumnSelectionAllowed(c);
+    setRowSelectionAllowed(c);
+    // for backward-compatibility sake:
+    cellSelectionEnabled = true;
+  }
+
+  /**
+   * <p>Set the value of the {@link #dataModel} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link TableModelListener} from
+   * previous {@link #dataModel} and register it with new parameter
+   * <code>m</code>.</p>
+   *
+   * @param m The new value of the model property
+   */ 
+  public void setModel(TableModel m)
+  {
+    // Throw exception is m is null.
+    if (m == null)
+      throw new IllegalArgumentException();
+   
+    // Don't do anything if setting the current model again.
+    if (dataModel == m)
+      return;
+
+    TableModel oldModel = dataModel;
+
+    // Remove table as TableModelListener from old model.
+    if (dataModel != null)
+      dataModel.removeTableModelListener(this);
+    
+    if (m != null)
+      {
+        // Set property.
+        dataModel = m;
+
+        // Add table as TableModelListener to new model.
+        dataModel.addTableModelListener(this);
+
+        // Notify the tableChanged method.
+        tableChanged(new TableModelEvent(dataModel,
+                                         TableModelEvent.HEADER_ROW));
+
+        // Automatically create columns.
+        if (autoCreateColumnsFromModel)
+          createDefaultColumnsFromModel();
+      }
+
+    // This property is bound, so we fire a property change event.
+    firePropertyChange("model", oldModel, dataModel);
+
+    // Repaint table.
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #columnModel} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link TableColumnModelListener}
+   * from previous {@link #columnModel} and register it with new parameter
+   * <code>c</code>.</p>
+   *
+   * @param c The new value of the columnModel property
+   */ 
+  public void setColumnModel(TableColumnModel c)
+  {
+    if (c == null)
+      throw new IllegalArgumentException();
+    TableColumnModel tmp = columnModel;
+    if (tmp != null)
+      tmp.removeColumnModelListener(this);
+    if (c != null)
+      c.addColumnModelListener(this);
+    columnModel = c;
+    if (dataModel != null && columnModel != null)
+      {
+        int ncols = getColumnCount();
+        TableColumn column;
+        for (int i = 0; i < ncols; ++i)
+          {
+            column = columnModel.getColumn(i); 
+            if (column.getHeaderValue()==null)
+              column.setHeaderValue(dataModel.getColumnName(i));
+          }
+      }
+
+    // according to Sun's spec we also have to set the tableHeader's
+    // column model here
+    if (tableHeader != null)
+      tableHeader.setColumnModel(c);
+
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Set the value of the <code>columnSelectionAllowed</code> property.
+   *
+   * @param c The new value of the property
+   * 
+   * @see #getColumnSelectionAllowed()
+   */ 
+  public void setColumnSelectionAllowed(boolean c)
+  {
+    if (columnModel.getColumnSelectionAllowed() != c)
+      {
+        columnModel.setColumnSelectionAllowed(c);
+        firePropertyChange("columnSelectionAllowed", !c, c);
+        repaint();
+      }
+  }
+
+  /**
+   * <p>Set the value of the {@link #selectionModel} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link ListSelectionListener}
+   * from previous {@link #selectionModel} and register it with new
+   * parameter <code>s</code>.</p>
+   *
+   * @param s The new value of the selectionModel property
+   */ 
+  public void setSelectionModel(ListSelectionModel s)
+  {
+    if (s == null)
+      throw new IllegalArgumentException();
+    ListSelectionModel tmp = selectionModel;
+    if (tmp != null)
+      tmp.removeListSelectionListener(this);
+    if (s != null)
+      s.addListSelectionListener(this);
+    selectionModel = s;
+    checkSelection();
+  }
+
+  /**
+   * Set the value of the <code>selectionMode</code> property by
+   * delegation to the {@link #selectionModel} field. The same selection
+   * mode is set for row and column selection models.
+   *
+   * @param s The new value of the property
+   */ 
+  public void setSelectionMode(int s)
+  { 
+    selectionModel.setSelectionMode(s);    
+    columnModel.getSelectionModel().setSelectionMode(s);
+    
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #cellEditor} property.</p>
+   *
+   * <p>Unregister <code>this</code> as a {@link CellEditorListener} from
+   * previous {@link #cellEditor} and register it with new parameter
+   * <code>c</code>.</p>
+   *
+   * @param c The new value of the cellEditor property
+   */ 
+  public void setCellEditor(TableCellEditor c)
+  {
+    TableCellEditor tmp = cellEditor;
+    if (tmp != null)
+      tmp.removeCellEditorListener(this);
+    if (c != null)
+      c.addCellEditorListener(this);
+    cellEditor = c;
+  }
+
+  /**
+   * Set the value of the {@link #dragEnabled} property.
+   *
+   * @param d The new value of the dragEnabled property
+   */ 
+  public void setDragEnabled(boolean d)
+  {
+    dragEnabled = d;
+  }
+
+  /**
+   * Set the value of the {@link #gridColor} property.
+   *
+   * @param g The new value of the gridColor property
+   */ 
+  public void setGridColor(Color g)
+  {
+    gridColor = g;
+    repaint();
+  }
+
+  /**
+   * Set the value of the <code>intercellSpacing</code> property.
+   *
+   * @param i The new value of the intercellSpacing property
+   */ 
+  public void setIntercellSpacing(Dimension i)
+  {
+    rowMargin = i.height;
+    columnModel.setColumnMargin(i.width);
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #preferredViewportSize} property.
+   *
+   * @param p The new value of the preferredViewportSize property
+   */ 
+  public void setPreferredScrollableViewportSize(Dimension p)
+  {
+    preferredViewportSize = p;
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #selectionBackground} property.</p>
+   *
+   * <p>Fire a PropertyChangeEvent with name {@link
+   * #SELECTION_BACKGROUND_CHANGED_PROPERTY} to registered listeners, if
+   * selectionBackground changed.</p>
+   *
+   * @param s The new value of the selectionBackground property
+   */ 
+  public void setSelectionBackground(Color s)
+  {
+    Color tmp = selectionBackground;
+    selectionBackground = s;
+    if (((tmp == null && s != null)
+         || (s == null && tmp != null)
+         || (tmp != null && s != null && !tmp.equals(s))))
+      firePropertyChange(SELECTION_BACKGROUND_CHANGED_PROPERTY, tmp, s);
+    repaint();
+  }
+
+  /**
+   * <p>Set the value of the {@link #selectionForeground} property.</p>
+   *
+   * <p>Fire a PropertyChangeEvent with name {@link
+   * #SELECTION_FOREGROUND_CHANGED_PROPERTY} to registered listeners, if
+   * selectionForeground changed.</p>
+   *
+   * @param s The new value of the selectionForeground property
+   */ 
+  public void setSelectionForeground(Color s)
+  {
+    Color tmp = selectionForeground;
+    selectionForeground = s;
+    if (((tmp == null && s != null)
+         || (s == null && tmp != null)
+         || (tmp != null && s != null && !tmp.equals(s))))
+      firePropertyChange(SELECTION_FOREGROUND_CHANGED_PROPERTY, tmp, s);
+    repaint();
+  }
+
+  /**
+   * Set the value of the <code>showGrid</code> property.
+   *
+   * @param s The new value of the showGrid property
+   */ 
+  public void setShowGrid(boolean s)
+  {
+    setShowVerticalLines(s);
+    setShowHorizontalLines(s);
+  }
+
+  /**
+   * Set the value of the {@link #showHorizontalLines} property.
+   *
+   * @param s The new value of the showHorizontalLines property
+   */ 
+  public void setShowHorizontalLines(boolean s)
+  {
+    showHorizontalLines = s;
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #showVerticalLines} property.
+   *
+   * @param s The new value of the showVerticalLines property
+   */ 
+  public void setShowVerticalLines(boolean s)
+  {
+    showVerticalLines = s;
+    repaint();
+  }
+
+  /**
+   * Set the value of the {@link #tableHeader} property.
+   *
+   * @param t The new value of the tableHeader property
+   */ 
+  public void setTableHeader(JTableHeader t)
+  {
+    if (tableHeader != null)
+      tableHeader.setTable(null);
+    tableHeader = t;
+    if (tableHeader != null)
+      tableHeader.setTable(this);
+    revalidate();
+    repaint();
+  }
+
+  protected void configureEnclosingScrollPane()
+  {
+    JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
+    if (jsp != null && tableHeader != null)
+      {
+        jsp.setColumnHeaderView(tableHeader);
+      }
+  }
+
+  protected void unconfigureEnclosingScrollPane()
+  {
+    JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
+    if (jsp != null)
+      {
+        jsp.setColumnHeaderView(null);
+      }    
+  }
+
+
+  public void addNotify()
+  {
+    super.addNotify();
+    configureEnclosingScrollPane();
+  }
+
+  public void removeNotify()
+  {
+    super.addNotify();
+    unconfigureEnclosingScrollPane();
+  }
+
+
+  /**
+   * This distributes the superfluous width in a table evenly on its columns.
+   *
+   * The implementation used here is different to that one described in
+   * the JavaDocs. It is much simpler, and seems to work very well.
+   *
+   * TODO: correctly implement the algorithm described in the JavaDoc
+   */
+  private void distributeSpill(TableColumn[] cols, int spill)
+  {
+    int average = spill / cols.length;
+    for (int i = 0; i < cols.length; i++)
+      {
+        if (cols[i] != null)
+          cols[i].setWidth(cols[i].getPreferredWidth() + average);
+      }
+  }
+  
+  /**
+   * This distributes the superfluous width in a table, setting the width of the
+   * column being resized strictly to its preferred width.
+   */
+  private void distributeSpillResizing(TableColumn[] cols, int spill,
+                                       TableColumn resizeIt)
+  {
+    int average = 0;
+    if (cols.length != 1)
+      average = spill / (cols.length-1);
+    for (int i = 0; i < cols.length; i++)
+      {
+        if (cols[i] != null && !cols[i].equals(resizeIt))
+          cols[i].setWidth(cols[i].getPreferredWidth() + average);
+      }
+    resizeIt.setWidth(resizeIt.getPreferredWidth());
+  }  
+  
+  /**
+   * Set the widths of all columns, taking they preferred widths into
+   * consideration. The excess space, if any, will be distrubuted between
+   * all columns. This method also handles special cases when one of the
+   * collumns is currently being resized.
+   * 
+   * @see TableColumn#setPreferredWidth(int)
+   */
+  public void doLayout()
+  {
+    TableColumn resizingColumn = null;
+    
+    int ncols = getColumnCount();
+    if (ncols < 1)
+      return;
+
+    int prefSum = 0;
+    int rCol = -1;
+
+    if (tableHeader != null)
+      resizingColumn = tableHeader.getResizingColumn();
+
+    for (int i = 0; i < ncols; ++i)
+      {
+        TableColumn col = columnModel.getColumn(i);
+        int p = col.getPreferredWidth();
+        prefSum += p;
+        if (resizingColumn == col)
+          rCol = i;
+      }
+
+    int spill = getWidth() - prefSum;
+
+    if (resizingColumn != null)
+      {
+        TableColumn col;
+        TableColumn [] cols;
+        
+        switch (getAutoResizeMode())
+          {
+          case AUTO_RESIZE_LAST_COLUMN:
+            col = columnModel.getColumn(ncols-1);
+            col.setWidth(col.getPreferredWidth() + spill);
+            break;
+            
+          case AUTO_RESIZE_NEXT_COLUMN:
+            col = columnModel.getColumn(ncols-1);
+            col.setWidth(col.getPreferredWidth() + spill);
+            break;
+
+          case AUTO_RESIZE_ALL_COLUMNS:
+            cols = new TableColumn[ncols];
+            for (int i = 0; i < ncols; ++i)
+              cols[i] = columnModel.getColumn(i);
+            distributeSpillResizing(cols, spill, resizingColumn);
+            break;
+
+          case AUTO_RESIZE_SUBSEQUENT_COLUMNS:
+            
+            // Subtract the width of the non-resized columns from the spill.
+            int w = 0;
+            int wp = 0;
+            TableColumn column;
+            for (int i = 0; i < rCol; i++)
+              {
+                column = columnModel.getColumn(i);
+                w += column.getWidth();
+                wp+= column.getPreferredWidth();
+              }
+
+            // The number of columns right from the column being resized.
+            int n = ncols-rCol-1;
+            if (n>0)
+              {
+                // If there are any columns on the right sied to resize.
+                spill = (getWidth()-w) - (prefSum-wp);
+                int average = spill / n;
+            
+                 // For all columns right from the column being resized:
+                for (int i = rCol+1; i < ncols; i++)
+                  {
+                    column = columnModel.getColumn(i);
+                    column.setWidth(column.getPreferredWidth() + average);
+                  }
+              }
+            resizingColumn.setWidth(resizingColumn.getPreferredWidth());
+            break;
+
+          case AUTO_RESIZE_OFF:
+          default:
+            int prefWidth = resizingColumn.getPreferredWidth();
+            resizingColumn.setWidth(prefWidth);
+          }
+      }
+    else
+      {
+        TableColumn [] cols = new TableColumn[ncols];
+        for (int i = 0; i < ncols; ++i)
+          cols[i] = columnModel.getColumn(i);
+        distributeSpill(cols, spill);
+      }
+    
+    if (editorComp!=null)
+      moveToCellBeingEdited(editorComp);
+    
+    int leftBoundary = getLeftResizingBoundary();
+    int width = getWidth() - leftBoundary;
+    repaint(leftBoundary, 0, width, getHeight());
+    if (tableHeader != null)
+      tableHeader.repaint(leftBoundary, 0, width, tableHeader.getHeight());
+  }
+  
+  /**
+   * Get the left boundary of the rectangle which changes during the column
+   * resizing.
+   */
+  int getLeftResizingBoundary()
+  {
+    if (tableHeader == null || getAutoResizeMode() == AUTO_RESIZE_ALL_COLUMNS)
+      return 0;
+    else
+      {
+        TableColumn resizingColumn = tableHeader.getResizingColumn();
+        if (resizingColumn == null)
+          return 0;
+
+        int rc = convertColumnIndexToView(resizingColumn.getModelIndex());
+        int p = 0;
+
+        for (int i = 0; i < rc; i++)
+          p += columnModel.getColumn(i).getWidth();
+        
+        return p;
+      }
+  }
+  
+  
+  /**
+   * @deprecated Replaced by <code>doLayout()</code>
+   */
+  public void sizeColumnsToFit(boolean lastColumnOnly)
+  {
+    doLayout();
+  }
+  
+  /**
+   * Obsolete since JDK 1.4. Please use <code>doLayout()</code>.
+   */
+  public void sizeColumnsToFit(int resizingColumn)
+  {
+    doLayout();
+  }
+
+  public String getUIClassID()
+  {
+    return "TableUI";
+  }
+
+  /**
+   * This method returns the table's UI delegate.
+   *
+   * @return The table's UI delegate.
+   */
+  public TableUI getUI()
+  {
+    return (TableUI) ui;
+  }
+
+  /**
+   * This method sets the table's UI delegate.
+   *
+   * @param ui The table's UI delegate.
+   */
+  public void setUI(TableUI ui)
+  {
+    super.setUI(ui);
+    // The editors and renderers must be recreated because they constructors
+    // may use the look and feel properties.
+    createDefaultEditors();
+    createDefaultRenderers();
+  }
+
+  public void updateUI()
+  {
+    setUI((TableUI) UIManager.getUI(this));
+  }
+  
+  /**
+   * Get the class (datatype) of the column. The cells are rendered and edited
+   * differently, depending from they data type.
+   * 
+   * @param column the column (not the model index).
+   * 
+   * @return the class, defining data type of that column (String.class for
+   * String, Boolean.class for boolean and so on).
+   */
+  public Class getColumnClass(int column)
+  {
+    return getModel().getColumnClass(convertColumnIndexToModel(column));
+  }
+  
+  /**
+   * Get the name of the column. If the column has the column identifier set,
+   * the return value is the result of the .toString() method call on that
+   * identifier. If the identifier is not explicitly set, the returned value
+   * is calculated by 
+   * {@link javax.swing.table.AbstractTableModel#getColumnName(int)}.
+   * 
+   * @param column the column
+   * 
+   * @return the name of that column.
+   */
+  public String getColumnName(int column)
+  {
+    int modelColumn = columnModel.getColumn(column).getModelIndex();
+    return dataModel.getColumnName(modelColumn);
+  }
+  
+  /**
+   * Get the column, currently being edited
+   * 
+   * @return the column, currently being edited.
+   */
+  public int getEditingColumn()
+  {
+    return editingColumn;
+  }
+  
+  /**
+   * Set the column, currently being edited
+   * 
+   * @param column the column, currently being edited.
+   */
+  public void setEditingColumn(int column)
+  {
+    editingColumn = column;
+  }
+  
+  /**
+   * Get the row currently being edited.
+   * 
+   * @return the row, currently being edited.
+   */
+  public int getEditingRow()
+  {
+    return editingRow;
+  }
+  
+  /**
+   * Set the row currently being edited.
+   * 
+   * @param row the row, that will be edited
+   */
+  public void setEditingRow(int row)
+  {
+    editingRow = row;
+  }
+  
+  /**
+   * Get the editor component that is currently editing one of the cells
+   * 
+   * @return the editor component or null, if none of the cells is being
+   * edited.
+   */
+  public Component getEditorComponent()
+  {
+    return editorComp;
+  }
+  
+  /**
+   * Check if one of the table cells is currently being edited.
+   * 
+   * @return true if there is a cell being edited.
+   */
+  public boolean isEditing()
+  {
+    return editorComp != null;
+  }
+  
+  /**
+   * Set the default editor for the given column class (column data type).
+   * By default, String is handled by text field and Boolean is handled by
+   * the check box.
+   *  
+   * @param columnClass the column data type
+   * @param editor the editor that will edit this data type
+   * 
+   * @see TableModel#getColumnClass(int)
+   */
+  public void setDefaultEditor(Class columnClass, TableCellEditor editor)
+  {
+    if (editor != null)
+      defaultEditorsByColumnClass.put(columnClass, editor);
+    else
+      defaultEditorsByColumnClass.remove(columnClass);
+  }
+  
+  public void addColumnSelectionInterval(int index0, int index1)
+  {
+    if ((index0 < 0 || index0 > (getColumnCount()-1)
+         || index1 < 0 || index1 > (getColumnCount()-1)))
+      throw new IllegalArgumentException("Column index out of range.");
+    
+    getColumnModel().getSelectionModel().addSelectionInterval(index0, index1);
+  }
+  
+  public void addRowSelectionInterval(int index0, int index1)
+  {            
+    if ((index0 < 0 || index0 > (getRowCount()-1)
+         || index1 < 0 || index1 > (getRowCount()-1)))
+      throw new IllegalArgumentException("Row index out of range.");
+      	
+    getSelectionModel().addSelectionInterval(index0, index1);
+  }
+  
+  public void setColumnSelectionInterval(int index0, int index1)
+  {
+    if ((index0 < 0 || index0 > (getColumnCount()-1)
+         || index1 < 0 || index1 > (getColumnCount()-1)))
+      throw new IllegalArgumentException("Column index out of range.");
+
+    getColumnModel().getSelectionModel().setSelectionInterval(index0, index1);
+  }
+  
+  public void setRowSelectionInterval(int index0, int index1)
+  {    
+    if ((index0 < 0 || index0 > (getRowCount()-1)
+         || index1 < 0 || index1 > (getRowCount()-1)))
+      throw new IllegalArgumentException("Row index out of range.");
+
+    getSelectionModel().setSelectionInterval(index0, index1);
+  }
+  
+  public void removeColumnSelectionInterval(int index0, int index1)  
+  {
+    if ((index0 < 0 || index0 > (getColumnCount()-1)
+         || index1 < 0 || index1 > (getColumnCount()-1)))
+      throw new IllegalArgumentException("Column index out of range.");
+
+    getColumnModel().getSelectionModel().removeSelectionInterval(index0, index1);
+  }
+  
+  public void removeRowSelectionInterval(int index0, int index1)
+  {
+    if ((index0 < 0 || index0 > (getRowCount()-1)
+         || index1 < 0 || index1 > (getRowCount()-1)))
+      throw new IllegalArgumentException("Row index out of range.");
+
+    getSelectionModel().removeSelectionInterval(index0, index1);
+  }
+  
+  /**
+   * Checks if the given column is selected.
+   * 
+   * @param column the column
+   * 
+   * @return true if the column is selected (as reported by the selection
+   * model, associated with the column model), false otherwise.
+   */
+  public boolean isColumnSelected(int column)
+  {
+    return getColumnModel().getSelectionModel().isSelectedIndex(column);
+  }
+  
+  /**
+   * Checks if the given row is selected.
+   * 
+   * @param row the row
+   * 
+   * @return true if the row is selected (as reported by the selection model),
+   * false otherwise.
+   */
+  public boolean isRowSelected(int row)
+  {
+    return getSelectionModel().isSelectedIndex(row);
+  }
+  
+  /**
+   * Checks if the given cell is selected. The cell is selected if both
+   * the cell row and the cell column are selected.
+   * 
+   * @param row the cell row
+   * @param column the cell column
+   * 
+   * @return true if the cell is selected, false otherwise
+   */
+  public boolean isCellSelected(int row, int column)
+  {
+    return isRowSelected(row) && isColumnSelected(column);
+  }
+  
+  /**
+   * Select all table.
+   */
+  public void selectAll()
+  {
+    // The table is empty - nothing to do!
+    if (getRowCount() == 0 || getColumnCount() == 0)
+      return;
+    
+    // rowLead and colLead store the current lead selection indices
+    int rowLead = selectionModel.getLeadSelectionIndex();
+    int colLead = getColumnModel().getSelectionModel().getLeadSelectionIndex();
+    // the following calls to setSelectionInterval change the lead selection
+    // indices
+    setColumnSelectionInterval(0, getColumnCount() - 1);
+    setRowSelectionInterval(0, getRowCount() - 1);
+    // the following addSelectionInterval calls restore the lead selection
+    // indices to their previous values
+    addColumnSelectionInterval(colLead,colLead);
+    addRowSelectionInterval(rowLead, rowLead);
+  }
+  
+  /**
+   * Get the cell value at the given position.
+   * 
+   * @param row the row to get the value
+   * @param column the actual column number (not the model index) 
+   * to get the value.
+   * 
+   * @return the cell value, as returned by model.
+   */
+  public Object getValueAt(int row, int column)
+  {
+    return dataModel.getValueAt(row, convertColumnIndexToModel(column));
+  }
+  
+  /**
+   * Set value for the cell at the given position. The modified cell is
+   * repainted.
+   * 
+   * @param value the value to set
+   * @param row the row of the cell being modified
+   * @param column the column of the cell being modified
+   */
+  public void setValueAt(Object value, int row, int column)
+  {
+    dataModel.setValueAt(value, row, convertColumnIndexToModel(column));
+    
+    repaint(getCellRect(row, column, true));
+  }
+  
+  /**
+   * Get table column with the given identified.
+   * 
+   * @param identifier the column identifier
+   * 
+   * @return the table column with this identifier
+   * 
+   * @throws IllegalArgumentException if <code>identifier</code> is 
+   *         <code>null</code> or there is no column with that identifier.
+   * 
+   * @see TableColumn#setIdentifier(Object)
+   */
+  public TableColumn getColumn(Object identifier)
+  {
+    return columnModel.getColumn(columnModel.getColumnIndex(identifier));
+  }
+
+  /**
+   * Returns <code>true</code> if the specified cell is editable, and
+   * <code>false</code> otherwise.
+   *
+   * @param row  the row index.
+   * @param column  the column index.
+   *
+   * @return true if the cell is editable, false otherwise.
+   */
+  public boolean isCellEditable(int row, int column)
+  {
+    return dataModel.isCellEditable(row, convertColumnIndexToModel(column));
+  }
+
+  /**
+   * Clears any existing columns from the <code>JTable</code>'s
+   * {@link TableColumnModel} and creates new columns to match the values in
+   * the data ({@link TableModel}) used by the table.
+   *
+   * @see #setAutoCreateColumnsFromModel(boolean)
+   */
+  public void createDefaultColumnsFromModel()
+  {
+    assert columnModel != null : "The columnModel must not be null.";
+
+    // remove existing columns
+    int columnIndex = columnModel.getColumnCount() - 1;
+    while (columnIndex >= 0)
+    {
+      columnModel.removeColumn(columnModel.getColumn(columnIndex));
+      columnIndex--;
+    }
+  
+    // add new columns to match the TableModel
+    int columnCount = dataModel.getColumnCount();
+    for (int c = 0; c < columnCount; c++)
+    {
+      TableColumn column = new TableColumn(c);
+      column.setIdentifier(dataModel.getColumnName(c));
+      column.setHeaderValue(dataModel.getColumnName(c));
+      columnModel.addColumn(column);
+      column.addPropertyChangeListener(tableColumnPropertyChangeHandler);
+    }
+  }
+
+  public void changeSelection (int rowIndex, int columnIndex, boolean toggle, boolean extend)
+  {
+    if (toggle && extend)
+      {
+        // Leave the selection state as is, but move the anchor
+        //   index to the specified location
+        selectionModel.setAnchorSelectionIndex(rowIndex);
+        getColumnModel().getSelectionModel().setAnchorSelectionIndex(columnIndex);
+      }
+    else if (toggle)
+      {
+        // Toggle the state of the specified cell
+        if (isCellSelected(rowIndex,columnIndex))
+          {
+            selectionModel.removeSelectionInterval(rowIndex,rowIndex);
+            getColumnModel().getSelectionModel().removeSelectionInterval(columnIndex,columnIndex);
+          }
+        else
+          {
+            selectionModel.addSelectionInterval(rowIndex,rowIndex);
+            getColumnModel().getSelectionModel().addSelectionInterval(columnIndex,columnIndex);
+          }
+      }
+    else if (extend)
+      {
+        // Extend the previous selection from the anchor to the 
+        // specified cell, clearing all other selections
+        selectionModel.setLeadSelectionIndex(rowIndex);
+        getColumnModel().getSelectionModel().setLeadSelectionIndex(columnIndex);
+      }
+    else
+      {
+        // Clear the previous selection and ensure the new cell
+        // is selected
+         selectionModel.clearSelection();
+        selectionModel.setSelectionInterval(rowIndex,rowIndex);
+        getColumnModel().getSelectionModel().clearSelection();
+        getColumnModel().getSelectionModel().setSelectionInterval(columnIndex, columnIndex);
+        
+        
+      }
+  }
+
+  /**
+   * Programmatically starts editing the specified cell.
+   * 
+   * @param row the row of the cell to edit.
+   * @param column the column of the cell to edit.
+   */
+  public boolean editCellAt(int row, int column)
+  {
+    // Complete the previous editing session, if still active.
+    if (isEditing())
+      editingStopped(new ChangeEvent("editingStopped"));
+
+    TableCellEditor editor = getCellEditor(row, column);
+    
+    // The boolean values are inverted by the single click without the
+    // real editing session.
+    if (editor == booleanInvertingEditor && isCellEditable(row, column))
+      {
+        if (Boolean.TRUE.equals(getValueAt(row, column)))
+          setValueAt(Boolean.FALSE, row, column);
+        else
+          setValueAt(Boolean.TRUE, row, column);
+        return false;
+      }
+    else
+      {
+        editingRow = row;
+        editingColumn = column;
+
+        setCellEditor(editor);
+        editorComp = prepareEditor(cellEditor, row, column);
+
+        // Remove the previous editor components, if present. Only one
+        // editor component at time is allowed in the table.
+        removeAll();
+        add(editorComp);
+        moveToCellBeingEdited(editorComp);
+        scrollRectToVisible(editorComp.getBounds());
+        editorComp.requestFocusInWindow();
+        
+        // Deliver the should select event.
+        return editor.shouldSelectCell(null);        
+      }
+  }
+
+  /**
+   * Move the given component under the cell being edited. 
+   * The table must be in the editing mode.
+   * 
+   * @param component the component to move.
+   */
+  private void moveToCellBeingEdited(Component component)
+  {
+     Rectangle r = getCellRect(editingRow, editingColumn, true);
+     // Adjust bounding box of the editing component, so that it lies
+     // 'above' the grid on all edges, not only right and bottom.
+     // The table grid is painted only at the right and bottom edge of a cell.
+     r.x -= 1;
+     r.y -= 1;
+     r.width += 1;
+     r.height += 1;
+     component.setBounds(r);
+  }
+
+  /**
+   * Programmatically starts editing the specified cell.
+   *
+   * @param row the row of the cell to edit.
+   * @param column the column of the cell to edit.
+   */
+  public boolean editCellAt (int row, int column, EventObject e)
+  {
+    return editCellAt(row, column);
+  }
+
+  /**
+   * Discards the editor object.
+   */
+  public void removeEditor()
+  {
+    editingStopped(new ChangeEvent(this));
+  }
+
+  /**
+   * Prepares the editor by querying for the value and selection state of the
+   * cell at (row, column).
+   *
+   * @param editor the TableCellEditor to set up
+   * @param row the row of the cell to edit
+   * @param column the column of the cell to edit
+   * @return the Component being edited
+   */
+  public Component prepareEditor (TableCellEditor editor, int row, int column)
+  {
+    return editor.getTableCellEditorComponent
+      (this, getValueAt(row, column), isCellSelected(row, column), row, column);
+  }
+
+  /**
+   * This revalidates the <code>JTable</code> and queues a repaint.
+   */
+  protected void resizeAndRepaint()
+  {
+    revalidate();
+    repaint();
+  }
+
+  /**
+   * Sets whether cell editors of this table should receive keyboard focus
+   * when the editor is activated by a keystroke. The default setting is
+   * <code>false</code> which means that the table should keep the keyboard
+   * focus until the cell is selected by a mouse click.
+   *
+   * @param value the value to set
+   *
+   * @since 1.4
+   */
+  public void setSurrendersFocusOnKeystroke(boolean value)
+  {
+    // TODO: Implement functionality of this property (in UI impl).
+    surrendersFocusOnKeystroke = value;
+  }
+  
+  /**
+   * Returns whether cell editors of this table should receive keyboard focus
+   * when the editor is activated by a keystroke. The default setting is
+   * <code>false</code> which means that the table should keep the keyboard
+   * focus until the cell is selected by a mouse click.
+   *
+   * @return whether cell editors of this table should receive keyboard focus
+   *         when the editor is activated by a keystroke
+   *
+   * @since 1.4
+   */
+  public boolean getSurrendersFocusOnKeystroke()
+  {
+    // TODO: Implement functionality of this property (in UI impl).
+    return surrendersFocusOnKeystroke;
+  }
+
+  /**
+   * Helper method for
+   * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
+   * 
+   * @param propertyName the name of the property
+   * @param value the value of the property
+   *
+   * @throws IllegalArgumentException if the specified property cannot be set
+   *         by this method
+   * @throws ClassCastException if the property value does not match the
+   *         property type
+   * @throws NullPointerException if <code>c</code> or
+   *         <code>propertyValue</code> is <code>null</code>
+   */
+  void setUIProperty(String propertyName, Object value)
+  {
+    if (propertyName.equals("rowHeight"))
+      {
+        if (! clientRowHeightSet)
+          {
+            setRowHeight(((Integer) value).intValue());
+            clientRowHeightSet = false;
+          }
+      }
+    else
+      {
+        super.setUIProperty(propertyName, value);
+      }
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextArea.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextArea.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextArea.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextArea.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,607 @@
+/* JTextArea.java -- 
+   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Dimension;
+import java.awt.FontMetrics;
+import java.awt.Rectangle;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+import javax.swing.text.View;
+
+/**
+ * The <code>JTextArea</code> component provides a multi-line area for displaying
+ * and editing plain text.  The component is designed to act as a lightweight
+ * replacement for the heavyweight <code>java.awt.TextArea</code> component,
+ * which provides similar functionality using native widgets.
+ * <p>
+ *
+ * This component has additional functionality to the AWT class.  It follows
+ * the same design pattern as seen in other text components, such as
+ * <code>JTextField</code>, <code>JTextPane</code> and <code>JEditorPane</code>,
+ * and embodied in <code>JTextComponent</code>.  These classes separate the text
+ * (the model) from its appearance within the onscreen component (the view).  The
+ * text is held within a <code>javax.swing.text.Document</code> object, which can
+ * also maintain relevant style information where necessary.  As a result, it is the
+ * document that should be monitored for textual changes, via
+ * <code>DocumentEvent</code>s delivered to registered
+ * <code>DocumentListener</code>s, rather than this component.
+ * <p>
+ *
+ * Unlike <code>java.awt.TextArea</code>, <code>JTextArea</code> does not
+ * handle scrolling.  Instead, this functionality is delegated to a
+ * <code>JScrollPane</code>, which can contain the text area and handle
+ * scrolling when required.  Likewise, the word wrapping functionality
+ * of the AWT component is converted to a property of this component
+ * and the <code>rows</code> and <code>columns</code> properties
+ * are used in calculating the preferred size of the scroll pane's
+ * view port.
+ *
+ * @author Michael Koch  (konqueror at gmx.de)
+ * @author Andrew John Hughes  (gnu_andrew at member.fsf.org)
+ * @see java.awt.TextArea
+ * @see javax.swing.text.JTextComponent
+ * @see javax.swing.JTextField
+ * @see javax.swing.JTextPane
+ * @see javax.swing.JEditorPane
+ * @see javax.swing.text.Document
+ * @see javax.swing.event.DocumentEvent
+ * @see javax.swing.event.DocumentListener
+ */
+
+public class JTextArea extends JTextComponent
+{
+  /**
+   * Provides accessibility support for <code>JTextArea</code>.
+   *
+   * @author Roman Kennke (kennke at aicas.com)
+   */
+  protected class AccessibleJTextArea extends AccessibleJTextComponent
+  {
+
+    /**
+     * Creates a new <code>AccessibleJTextArea</code> object.
+     */
+    protected AccessibleJTextArea()
+    {
+      super();
+    }
+
+    /**
+     * Returns the accessible state of this <code>AccessibleJTextArea</code>.
+     *
+     * @return  the accessible state of this <code>AccessibleJTextArea</code>
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleStateSet state = super.getAccessibleStateSet();
+      // TODO: Figure out what state must be added here to the super's state.
+      return state;
+    }
+  }
+
+  /**
+   * Compatible with Sun's JDK
+   */
+  private static final long serialVersionUID = -6141680179310439825L;
+  
+  /**
+   * The number of rows used by the component.
+   */
+  private int rows;
+
+  /**
+   * The number of columns used by the component.
+   */
+  private int columns;
+
+  /**
+   * Whether line wrapping is enabled or not.
+   */
+  private boolean lineWrap;
+
+  /**
+   * The number of characters equal to a tab within the text.
+   */
+  private int tabSize = 8;
+
+  private boolean wrapStyleWord;
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   */
+  public JTextArea()
+  {
+    this(null, null, 0, 0);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param text the initial text
+   */
+  public JTextArea(String text)
+  {
+    this(null, text, 0, 0);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param rows the number of rows
+   * @param columns the number of cols
+   *
+   * @exception IllegalArgumentException if rows or columns are negative
+   */
+  public JTextArea(int rows, int columns)
+  {
+    this(null, null, rows, columns);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param text the initial text
+   * @param rows the number of rows
+   * @param columns the number of cols
+   *
+   * @exception IllegalArgumentException if rows or columns are negative
+   */
+  public JTextArea(String text, int rows, int columns)
+  {
+    this(null, text, rows, columns);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param doc the document model to use
+   */
+  public JTextArea(Document doc)
+  {
+    this(doc, null, 0, 0);
+  }
+
+  /**
+   * Creates a new <code>JTextArea</code> object.
+   *
+   * @param doc the document model to use
+   * @param text the initial text
+   * @param rows the number of rows
+   * @param columns the number of cols
+   *
+   * @exception IllegalArgumentException if rows or columns are negative
+   */
+  public JTextArea(Document doc, String text, int rows, int columns)
+  {
+    setDocument(doc == null ? createDefaultModel() : doc);
+    // Only explicitly setText() when there is actual text since
+    // setText() might be overridden and not expected to be called
+    // from the constructor (as in JEdit).
+    if (text != null)
+      setText(text);
+    setRows(rows);
+    setColumns(columns);
+  }
+
+  /**
+   * Appends the supplied text to the current contents
+   * of the document model.
+   *
+   * @param toAppend the text to append
+   */
+  public void append(String toAppend)
+  {
+      try
+	  {
+	      getDocument().insertString(getText().length(), toAppend, null);
+	  }
+      catch (BadLocationException exception)
+	  {
+	      /* This shouldn't happen in theory -- but, if it does...  */
+	      throw new RuntimeException("Unexpected exception occurred.", exception);
+	  }
+      if (toAppend != null && toAppend.length() > 0)
+        revalidate();
+  }
+
+  /**
+   * Creates the default document model.
+   *
+   * @return a new default model
+   */
+  protected Document createDefaultModel()
+  {
+    return new PlainDocument();
+  }
+
+  /**
+   * Returns true if the width of this component should be forced
+   * to match the width of a surrounding view port.  When line wrapping
+   * is turned on, this method returns true.
+   *
+   * @return true if lines are wrapped.
+   */
+  public boolean getScrollableTracksViewportWidth()
+  {
+    return lineWrap ? true : super.getScrollableTracksViewportWidth();
+  }
+
+  /**
+   * Returns the increment that is needed to expose exactly one new line
+   * of text. This is implemented here to return the values of
+   * {@link #getRowHeight} and {@link #getColumnWidth}, depending on
+   * the value of the argument <code>direction</code>.
+   *
+   * @param visibleRect the view area that is visible in the viewport
+   * @param orientation either {@link SwingConstants#VERTICAL} or
+   *     {@link SwingConstants#HORIZONTAL}
+   * @param direction less than zero for up/left scrolling, greater
+   *     than zero for down/right scrolling
+   *
+   * @return the increment that is needed to expose exactly one new row
+   *     or column of text
+   *
+   * @throws IllegalArgumentException if <code>orientation</code> is invalid
+   */
+  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
+                                        int direction)
+  {
+    if (orientation == SwingConstants.VERTICAL)
+      return getRowHeight();
+    else if (orientation == SwingConstants.HORIZONTAL)
+      return getColumnWidth();
+    else
+      throw new IllegalArgumentException("orientation must be either "
+                                     + "javax.swing.SwingConstants.VERTICAL "
+                                     + "or "
+                                     + "javax.swing.SwingConstants.HORIZONTAL"
+                                     );
+  }
+
+  /**
+   * Returns the preferred size of that text component in the case
+   * it is embedded within a JScrollPane. This uses the column and
+   * row settings if they are explicitly set, or fall back to
+   * the superclass's behaviour.
+   *
+   * @return the preferred size of that text component in the case
+   *     it is embedded within a JScrollPane
+   */
+  public Dimension getPreferredScrollableViewportSize()
+  {
+    if ((rows > 0) && (columns > 0))
+      return new Dimension(columns * getColumnWidth(), rows * getRowHeight());
+    else
+      return super.getPreferredScrollableViewportSize();
+  }
+
+  /**
+   * Returns the UI class ID string.
+   *
+   * @return the string "TextAreaUI"
+   */
+  public String getUIClassID()
+  {
+    return "TextAreaUI";
+  }
+
+  /**
+   * Returns the current number of columns.
+   *
+   * @return number of columns
+   */
+  public int getColumns()
+  {
+    return columns;
+  }
+  
+  /**
+   * Sets the number of rows.
+   *
+   * @param columns number of columns
+   *
+   * @exception IllegalArgumentException if columns is negative
+   */
+  public void setColumns(int columns)
+  {
+    if (columns < 0)
+      throw new IllegalArgumentException();
+    
+    if (columns != this.columns)
+      {
+        this.columns = columns;
+        revalidate();
+      }
+  }
+
+  /**
+   * Returns the current number of rows.
+   *
+   * @return number of rows
+   */
+  public int getRows()
+  {
+    return rows;
+  }
+
+  /**
+   * Sets the number of rows.
+   *
+   * @param rows number of rows
+   *
+   * @exception IllegalArgumentException if rows is negative
+   */
+  public void setRows(int rows)
+  {
+    if (rows < 0)
+      throw new IllegalArgumentException();
+   
+    if (rows != this.rows)
+      {
+        this.rows = rows;
+        revalidate();
+      }
+  }
+
+  /**
+   * Checks whether line wrapping is enabled.
+   *
+   * @return <code>true</code> if line wrapping is enabled,
+   * <code>false</code> otherwise
+   */
+  public boolean getLineWrap()
+  {
+    return lineWrap;
+  }
+
+  /**
+   * Enables/disables line wrapping.
+   *
+   * @param flag <code>true</code> to enable line wrapping,
+   * <code>false</code> otherwise
+   */
+  public void setLineWrap(boolean flag)
+  {
+    if (lineWrap == flag)
+      return;
+
+    boolean oldValue = lineWrap;
+    lineWrap = flag;
+    firePropertyChange("lineWrap", oldValue, lineWrap);
+  }
+
+  /**
+   * Checks whether word style wrapping is enabled.
+   *
+   * @return <code>true</code> if word style wrapping is enabled,
+   * <code>false</code> otherwise
+   */
+  public boolean getWrapStyleWord()
+  {
+    return wrapStyleWord;
+  }
+  
+  /**
+   * Enables/Disables word style wrapping.
+   *
+   * @param flag <code>true</code> to enable word style wrapping,
+   * <code>false</code> otherwise
+   */
+  public void setWrapStyleWord(boolean flag)
+  {
+    if (wrapStyleWord == flag)
+      return;
+    
+    boolean oldValue = wrapStyleWord;
+    wrapStyleWord = flag;
+    firePropertyChange("wrapStyleWord", oldValue, wrapStyleWord);
+  }
+  
+  /**
+   * Returns the number of characters used for a tab.
+   * This defaults to 8.
+   *
+   * @return the current number of spaces used for a tab.
+   */
+  public int getTabSize()
+  {
+    return tabSize;
+  }
+
+  /**
+   * Sets the number of characters used for a tab to the
+   * supplied value.  If a change to the tab size property
+   * occurs (i.e. newSize != tabSize), a property change event
+   * is fired.
+   * 
+   * @param newSize The new number of characters to use for a tab.
+   */
+  public void setTabSize(int newSize)
+  {
+    if (tabSize == newSize)
+      return;
+    
+    int oldValue = tabSize;
+    tabSize = newSize;
+    firePropertyChange("tabSize", oldValue, tabSize);
+  }
+
+  protected int getColumnWidth()
+  {
+    FontMetrics metrics = getToolkit().getFontMetrics(getFont());
+    return metrics.charWidth('m');
+  }
+
+  public int getLineCount()
+  {
+    return getDocument().getDefaultRootElement().getElementCount();
+  }
+
+  public int getLineStartOffset(int line)
+     throws BadLocationException
+  {
+    int lineCount = getLineCount();
+    
+    if (line < 0 || line > lineCount)
+      throw new BadLocationException("Non-existing line number", line);
+
+    Element lineElem = getDocument().getDefaultRootElement().getElement(line);
+    return lineElem.getStartOffset();
+  }
+
+  public int getLineEndOffset(int line)
+     throws BadLocationException
+  {
+    int lineCount = getLineCount();
+    
+    if (line < 0 || line > lineCount)
+      throw new BadLocationException("Non-existing line number", line);
+
+    Element lineElem = getDocument().getDefaultRootElement().getElement(line);
+    return lineElem.getEndOffset();
+  }
+
+  public int getLineOfOffset(int offset)
+    throws BadLocationException
+  {
+    Document doc = getDocument();
+
+    if (offset < doc.getStartPosition().getOffset()
+	|| offset >= doc.getEndPosition().getOffset())
+      throw new BadLocationException("offset outside of document", offset);
+
+    return doc.getDefaultRootElement().getElementIndex(offset);
+  }
+
+  protected int getRowHeight()
+  {
+    FontMetrics metrics = getToolkit().getFontMetrics(getFont());
+    return metrics.getHeight();
+  }
+
+  /**
+   * Inserts the supplied text at the specified position.  Nothing
+   * happens in the case that the model or the supplied string is null
+   * or of zero length.
+   *
+   * @param string The string of text to insert.
+   * @param position The position at which to insert the supplied text.
+   * @throws IllegalArgumentException if the position is < 0 or greater
+   * than the length of the current text.
+   */
+  public void insert(String string, int position)
+  {
+    // Retrieve the document model.
+    Document doc = getDocument();
+      
+    // Check the model and string for validity.
+    if (doc == null
+	|| string == null
+	|| string.length() == 0)
+      return;
+
+    // Insert the text into the model.
+    try
+      {
+	doc.insertString(position, string, null);
+      }
+    catch (BadLocationException e)
+      {
+	throw new IllegalArgumentException("The supplied position, "
+					   + position + ", was invalid.");
+      }
+  }
+
+  public void replaceRange(String text, int start, int end)
+  {
+    Document doc = getDocument();
+    
+    if (start > end
+	|| start < doc.getStartPosition().getOffset()
+	|| end >= doc.getEndPosition().getOffset())
+      throw new IllegalArgumentException();
+
+    try
+      {
+        doc.remove(start, end - start);
+        doc.insertString(start, text, null);
+      }
+    catch (BadLocationException e)
+      {
+	// This cannot happen as we check offset above.
+      }
+  }
+
+  /**
+   * Returns the preferred size for the JTextArea. This is the maximum of
+   * the size that is needed to display the content and the requested size
+   * as per {@link #getColumns} and {@link #getRows}.
+   *
+   * @return the preferred size of the JTextArea
+   */
+  public Dimension getPreferredSize()
+  {
+    int reqWidth = getColumns() * getColumnWidth();
+    int reqHeight = getRows() * getRowHeight();
+    View view = getUI().getRootView(this);
+    int neededWidth = (int) view.getPreferredSpan(View.HORIZONTAL);
+    int neededHeight = (int) view.getPreferredSpan(View.VERTICAL);
+    return new Dimension(Math.max(reqWidth, neededWidth),
+                          Math.max(reqHeight, neededHeight));
+  }
+
+  /**
+   * Returns the accessible context associated with the <code>JTextArea</code>.
+   *
+   * @return the accessible context associated with the <code>JTextArea</code>
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJTextArea();
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextField.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextField.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextField.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextField.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,569 @@
+/* JTextField.java --
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+import javax.swing.text.TextAction;
+
+public class JTextField extends JTextComponent
+  implements SwingConstants
+{
+  /**
+   * AccessibleJTextField
+   */
+  protected class AccessibleJTextField extends AccessibleJTextComponent
+  {
+    private static final long serialVersionUID = 8255147276740453036L;
+
+    /**
+     * Constructor AccessibleJTextField
+     */
+    protected AccessibleJTextField()
+    {
+      super();
+    }
+
+    /**
+     * Returns the accessible state of this <code>AccessibleJTextField</code>.
+     *
+     * @return the accessible state of this <code>AccessibleJTextField</code>
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      AccessibleStateSet state = super.getAccessibleStateSet();
+      // TODO: Figure out what state must be added here to the super's state.
+      return state;
+    }
+  }
+
+  private static final long serialVersionUID = 353853209832607592L;
+
+  private static final Action[] actions;
+
+  /**
+   * Name of the action that gets sent when the content of the text field
+   * gets accepted.
+   */
+  public static final String notifyAction = "notify-field-accept";
+  
+  static
+    {
+      actions = new Action[1];
+      actions[0] = new TextAction(notifyAction)
+      {
+        public void actionPerformed(ActionEvent event)
+        {
+          JTextField textField = (JTextField) event.getSource();
+          textField.fireActionPerformed();
+        }
+      };
+    }
+  
+  private int columns;
+  private int align;
+  
+  /** @since 1.3 */
+  private Action action;
+
+  /** @since 1.3 */
+  private String actionCommand;
+  
+  private PropertyChangeListener actionPropertyChangeListener;
+
+  /**
+   * The horizontal visibility of the textfield.
+   */
+  private BoundedRangeModel horizontalVisibility;
+
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   */
+  public JTextField()
+  {
+    this(null, null, 0);
+  }
+
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param text the initial text
+   */
+  public JTextField(String text)
+  {
+    this(null, text, 0);
+  }
+  
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param columns the number of columns
+   *
+   * @exception IllegalArgumentException if columns %lt; 0
+   */
+  public JTextField(int columns)
+  {
+    this(null, null, columns);
+  }
+
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param text the initial text
+   * @param columns the number of columns
+   *
+   * @exception IllegalArgumentException if columns %lt; 0
+   */
+  public JTextField(String text, int columns)
+  {
+    this(null, text, columns);
+  }
+
+  /**
+   * Creates a new instance of <code>JTextField</code>.
+   *
+   * @param doc the document to use
+   * @param text the initial text
+   * @param columns the number of columns
+   *
+   * @exception IllegalArgumentException if columns %lt; 0
+   */
+  public JTextField(Document doc, String text, int columns)
+  {
+    if (columns < 0)
+      throw new IllegalArgumentException();
+
+    this.columns = columns;
+
+    // Initialize the horizontal visibility model.
+    horizontalVisibility = new DefaultBoundedRangeModel();
+
+    setDocument(doc == null ? createDefaultModel() : doc);
+
+    if (text != null)
+      setText(text);
+
+    // default value for alignment
+    align = LEADING;
+  }
+
+  /**
+   * Creates the default model for this text field.
+   * This implementation returns an instance of <code>PlainDocument</code>.
+   *
+   * @return a new instance of the default model
+   */
+  protected Document createDefaultModel()
+  {
+    return new PlainDocument();
+  }
+
+  /**
+   * Sets the document to be used for this JTextField.
+   *
+   * This sets the document property <code>filterNewlines</code> to
+   * <code>true</code> and then calls the super behaviour to setup a view and
+   * revalidate the text field.
+   *
+   * @param doc the document to set
+   */
+  public void setDocument(Document doc)
+  {
+    doc.putProperty("filterNewlines", Boolean.TRUE);
+    super.setDocument(doc);
+  }
+
+  /**
+   * Returns the class ID for the UI.
+   *
+   * @return "TextFieldUI";
+   */
+  public String getUIClassID()
+  {
+    return "TextFieldUI";
+  }
+
+  /**
+   * Adds a new listener object to this text field.
+   *
+   * @param listener the listener to add
+   */
+  public void addActionListener(ActionListener listener)
+  {
+    listenerList.add(ActionListener.class, listener);
+  }
+
+  /**
+   * Removes a listener object from this text field.
+   *
+   * @param listener the listener to remove
+   */
+  public void removeActionListener(ActionListener listener)
+  {
+    listenerList.remove(ActionListener.class, listener);
+  }
+
+  /**
+   * Returns all registered <code>ActionListener</code> objects.
+   *
+   * @return an array of listeners
+   *
+   * @since 1.4
+   */
+  public ActionListener[] getActionListeners()
+  {
+    return (ActionListener[]) getListeners(ActionListener.class);
+  }
+
+  /**
+   * Sends an action event to all registered
+   * <code>ActionListener</code> objects.
+   */
+  protected void fireActionPerformed()
+  {
+    ActionEvent event = new ActionEvent(this, 0, getText());
+    ActionListener[] listeners = getActionListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].actionPerformed(event);
+  }
+
+  /**
+   * Returns the number of columns of this text field.
+   *
+   * @return the number of columns
+   */
+  public int getColumns()
+  {
+    return columns;
+  }
+
+  /**
+   * Sets the number of columns and then invalidates the layout.
+   * @param columns the number of columns
+   * @throws IllegalArgumentException if columns < 0
+   */
+  public void setColumns(int columns)
+  {
+    if (columns < 0)
+      throw new IllegalArgumentException();
+
+    this.columns = columns;
+    invalidate();
+    //FIXME: do we need this repaint call?
+    repaint();
+  }
+
+  /**
+   * Returns the horizontal alignment, which is one of: JTextField.LEFT, 
+   * JTextField.CENTER, JTextField.RIGHT, JTextField.LEADING, 
+   * JTextField.TRAILING.
+   * @return the horizontal alignment
+   */
+  public int getHorizontalAlignment()
+  {
+    return align;
+  }
+
+  /**
+   * Sets the horizontal alignment of the text.  Calls invalidate and repaint
+   * and fires a property change event.
+   * @param newAlign must be one of: JTextField.LEFT, JTextField.CENTER,
+   * JTextField.RIGHT, JTextField.LEADING, JTextField.TRAILING.
+   * @throws IllegalArgumentException if newAlign is not one of the above.
+   */
+  public void setHorizontalAlignment(int newAlign)
+  {
+    //FIXME: should throw an IllegalArgumentException if newAlign is invalid
+    if (align == newAlign)
+      return;
+
+    int oldAlign = align;
+    align = newAlign;
+    firePropertyChange("horizontalAlignment", oldAlign, newAlign);
+    invalidate();
+    repaint();
+  }
+
+  /**
+   * Sets the current font and revalidates so the font will take effect.
+   */
+  public void setFont(Font newFont)
+  {
+    super.setFont(newFont);
+    revalidate();
+  }
+
+  /**
+   * Returns the preferred size.  If there is a non-zero number of columns, 
+   * this is the number of columns multiplied by the column width, otherwise
+   * it returns super.getPreferredSize().
+   */
+  public Dimension getPreferredSize()
+  {
+    Dimension size = super.getPreferredSize();
+
+    if (columns != 0)
+      {
+        Insets i = getInsets();
+        size.width = columns * getColumnWidth() + i.left + i.right;
+      }
+
+    return size;
+  }
+
+  /**
+   * Returns the scroll offset in pixels.
+   *
+   * @return the scroll offset
+   */
+  public int getScrollOffset()
+  {
+    return horizontalVisibility.getValue();
+  }
+
+  /**
+   * Sets the scroll offset in pixels.
+   * 
+   * @param offset the scroll offset
+   */
+  public void setScrollOffset(int offset)
+  {
+    // Automatically sets to the highest possible value if
+    // offset is bigger than that.
+    horizontalVisibility.setValue(
+                                  Math.min(horizontalVisibility.getMaximum()
+                                           - horizontalVisibility.getExtent(),
+                                           offset));
+    
+  }
+
+  /**
+   * Returns the set of Actions that are commands for the editor.
+   * This is the actions supported by this editor plus the actions
+   * of the UI (returned by JTextComponent.getActions()).
+   */
+  public Action[] getActions()
+  {
+    return TextAction.augmentList(super.getActions(), actions);
+  }
+
+  public void postActionEvent()
+  {
+    String command = actionCommand != null ? actionCommand : getText();
+    ActionEvent event = new ActionEvent(this, 0, command);
+    ActionListener[] listeners = getActionListeners();
+
+    for (int index = 0; index < listeners.length; ++index)
+      listeners[index].actionPerformed(event);
+  }
+  
+  /**
+   * @since 1.3
+   */
+  public Action getAction()
+  {
+    return action;
+  }
+
+  /**
+   * @since 1.3
+   */
+  public void setAction(Action newAction)
+  {
+    if (action == newAction)
+      return;
+
+    if (action != null)
+      {
+        removeActionListener(action);
+        action.removePropertyChangeListener(actionPropertyChangeListener);
+        actionPropertyChangeListener = null;
+      }
+
+    Action oldAction = action;
+    action = newAction;
+
+    if (action != null)
+      {
+        addActionListener(action);
+        actionPropertyChangeListener = createActionPropertyChangeListener(action);
+        action.addPropertyChangeListener(actionPropertyChangeListener);
+      }
+
+    //FIXME: is this a hack?  The horizontal alignment hasn't changed
+    firePropertyChange("horizontalAlignment", oldAction, newAction);
+  }
+
+  /**
+   * Sets the command string used in action events.
+   * @since 1.3
+   */
+  public void setActionCommand(String command)
+  {
+    actionCommand = command;
+  }
+
+  /**
+   * @since 1.3
+   */
+  protected PropertyChangeListener createActionPropertyChangeListener(Action action)
+  {
+    return new PropertyChangeListener()
+    {
+      public void propertyChange(PropertyChangeEvent event)
+      {
+        // Update properties "action" and "horizontalAlignment".
+        String name = event.getPropertyName();
+
+        if (name.equals("enabled"))
+          {
+            boolean enabled = ((Boolean) event.getNewValue()).booleanValue();
+            JTextField.this.setEnabled(enabled);
+          }
+        else if (name.equals(Action.SHORT_DESCRIPTION))
+          {
+            JTextField.this.setToolTipText((String) event.getNewValue());
+          }
+      }
+    };
+  }
+
+  /**
+   * 
+   * @since 1.3
+   */
+  protected void configurePropertiesFromAction(Action action)
+  {
+    if (action != null)
+      {
+        setEnabled(action.isEnabled());
+        setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
+      }
+    else
+      {
+        setEnabled(true);
+        setToolTipText(null);
+      }
+  }
+
+  /**
+   * Returns the column width, which is the width of the character m
+   * for the font in use.
+   * @return the width of the character m for the font in use.
+   */
+  protected int getColumnWidth()
+  {
+    FontMetrics metrics = getToolkit().getFontMetrics(getFont());
+    return metrics.charWidth('m');
+  }
+
+  /**
+   * Returns the accessible context associated with the <code>JTextField</code>.
+   *
+   * @return the accessible context associated with the <code>JTextField</code>
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJTextField();
+    return accessibleContext;
+  }
+
+  /**
+   * Returns the bounded range model that describes the horizontal visibility
+   * of the text field in the case when the text does not fit into the
+   * available space. The actual values of this model are managed by the look
+   * and feel implementation.
+   *
+   * @return the bounded range model that describes the horizontal visibility
+   */
+  public BoundedRangeModel getHorizontalVisibility()
+  {
+    return horizontalVisibility;
+  }
+
+  /**
+   * Returns <code>true</code>, unless this is embedded in a
+   * <code>JViewport</code> in which case the viewport takes responsibility of
+   * validating.
+   *
+   * @return <code>true</code>, unless this is embedded in a
+   *         <code>JViewport</code> in which case the viewport takes
+   *         responsibility of validating
+   */
+  public boolean isValidateRoot()
+  {
+    return ! (getParent() instanceof JViewport);
+  }
+  
+  public void scrollRectToVisible(Rectangle r)
+  {
+    int v = horizontalVisibility.getValue();
+    
+    // The extent value is the inner width of the text field.
+    int e = horizontalVisibility.getExtent();
+    Insets i = getInsets();
+    
+    // The x value in the rectangle (usually) denotes the new location
+    // of the caret. We check whether the location lies inside the left or
+    // right border and scroll into the appropriate direction.
+    // The calculation has to be shifted by the BoundedRangeModel's value
+    // because that value was already used to calculate r.x (this happens
+    // as part of a modelToView() call in FieldView).
+    if (r.x < i.left)
+      setScrollOffset(v + r.x - i.left);
+    else if (r.x > e + i.left)
+      setScrollOffset(r.x + v - e - i.left);
+  }
+  
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextPane.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextPane.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextPane.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JTextPane.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,433 @@
+/* JTextPane.java -- A powerful text widget supporting styled text
+   Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Caret;
+import javax.swing.text.Document;
+import javax.swing.text.EditorKit;
+import javax.swing.text.Element;
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.Style;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyledDocument;
+import javax.swing.text.StyledEditorKit;
+
+/**
+ * A powerful text component that supports styled content as well as
+ * embedding images and components. It is entirely based on a
+ * {@link StyledDocument} content model and a {@link StyledEditorKit}.
+ *
+ * @author Roman Kennke (roman at kennke.org)
+ * @author Andrew Selkirk
+ */
+public class JTextPane
+  extends JEditorPane
+{
+  /**
+   * Creates a new <code>JTextPane</code> with a <code>null</code> document.
+   */
+  public JTextPane()
+  {
+    super();
+  }
+
+  /**
+   * Creates a new <code>JTextPane</code> and sets the specified
+   * <code>document</code>.
+   *
+   * @param document the content model to use
+   */
+  public JTextPane(StyledDocument document)
+  {
+    this();
+    setStyledDocument(document);
+  }
+
+  /**
+   * Returns the UI class ID. This is <code>TextPaneUI</code>.
+   *
+   * @return <code>TextPaneUI</code>
+   */
+  public String getUIClassID()
+  {
+    return "TextPaneUI";
+  }
+
+  /**
+   * Sets the content model for this <code>JTextPane</code>.
+   * <code>JTextPane</code> can only be used with {@link StyledDocument}s,
+   * if you try to set a different type of <code>Document</code>, an
+   * <code>IllegalArgumentException</code> is thrown.
+   *
+   * @param document the content model to set
+   *
+   * @throws IllegalArgumentException if <code>document</code> is not an
+   *         instance of <code>StyledDocument</code>
+   *
+   * @see #setStyledDocument
+   */
+  public void setDocument(Document document)
+  {
+    if (document != null && !(document instanceof StyledDocument))
+      throw new IllegalArgumentException
+        ("JTextPane can only handle StyledDocuments");
+
+    setStyledDocument((StyledDocument) document);
+  }
+
+  /**
+   * Returns the {@link StyledDocument} that is the content model for
+   * this <code>JTextPane</code>. This is a typed wrapper for
+   * {@link #getDocument()}.
+   *
+   * @return the content model of this <code>JTextPane</code>
+   */
+  public StyledDocument getStyledDocument()
+  {
+    return (StyledDocument) super.getDocument();
+  }
+
+  /**
+   * Sets the content model for this <code>JTextPane</code>.
+   *
+   * @param document the content model to set
+   */
+  public void setStyledDocument(StyledDocument document)
+  {
+    super.setDocument(document);
+  }
+
+  /**
+   * Replaces the currently selected text with the specified
+   * <code>content</code>. If there is no selected text, this results
+   * in a simple insertion at the current caret position. If there is
+   * no <code>content</code> specified, this results in the selection
+   * beeing deleted.
+   *
+   * @param content the text with which the selection is replaced
+   */
+  public void replaceSelection(String content)
+  {
+    Caret caret = getCaret();
+    StyledDocument doc = getStyledDocument();
+    AttributeSet a = getInputAttributes().copyAttributes();
+    if (doc == null)
+      return;
+
+    int dot = caret.getDot();
+    int mark = caret.getMark();
+
+    int p0 = Math.min (dot, mark);
+    int p1 = Math.max (dot, mark);
+
+    try
+      {
+        if (doc instanceof AbstractDocument)
+          ((AbstractDocument)doc).replace(p0, p1 - p0, content, a);
+        else
+          {
+            // Remove selected text.
+            if (dot != mark)
+              doc.remove(p0, p1 - p0);
+            // Insert new text.
+            if (content != null && content.length() > 0)
+              doc.insertString(p0, content, a);
+          }
+      }
+    catch (BadLocationException e)
+      {
+        throw new AssertionError
+          ("No BadLocationException should be thrown here");      
+      }
+  }
+
+  /**
+   * Inserts an AWT or Swing component into the text at the current caret
+   * position.
+   *
+   * @param component the component to be inserted
+   */
+  public void insertComponent(Component component)
+  {
+    SimpleAttributeSet atts = new SimpleAttributeSet();
+    atts.addAttribute(StyleConstants.ComponentAttribute, component);
+    atts.addAttribute(StyleConstants.NameAttribute,
+                      StyleConstants.ComponentElementName);
+    try
+      {
+        getDocument().insertString(getCaret().getDot(), " ", atts);
+      }
+    catch (BadLocationException ex)
+      {
+        AssertionError err = new AssertionError("Unexpected bad location");
+        err.initCause(ex);
+        throw err;
+      }
+  }
+
+  /**
+   * Inserts an <code>Icon</code> into the text at the current caret position.
+   *
+   * @param icon the <code>Icon</code> to be inserted
+   */
+  public void insertIcon(Icon icon)
+  {
+    SimpleAttributeSet atts = new SimpleAttributeSet();
+    atts.addAttribute(StyleConstants.IconAttribute, icon);
+    atts.addAttribute(StyleConstants.NameAttribute,
+                      StyleConstants.IconElementName);
+    try
+      {
+        getDocument().insertString(getCaret().getDot(), " ", atts);
+      }
+    catch (BadLocationException ex)
+      {
+        AssertionError err = new AssertionError("Unexpected bad location");
+        err.initCause(ex);
+        throw err;
+      }
+  }
+
+  /**
+   * Adds a style into the style hierarchy. Unspecified style attributes
+   * can be resolved in the <code>parent</code> style, if one is specified.
+   *
+   * While it is legal to add nameless styles (<code>nm == null</code),
+   * you must be aware that the client application is then responsible
+   * for managing the style hierarchy, since unnamed styles cannot be
+   * looked up by their name.
+   *
+   * @param nm the name of the style or <code>null</code> if the style should
+   *           be unnamed
+   * @param parent the parent in which unspecified style attributes are
+   *           resolved, or <code>null</code> if that is not necessary
+   *
+   * @return the newly created <code>Style</code>
+   */
+  public Style addStyle(String nm, Style parent)
+  {
+    return getStyledDocument().addStyle(nm, parent);
+  }
+
+  /**
+   * Removes a named <code>Style</code> from the style hierarchy.
+   *
+   * @param nm the name of the <code>Style</code> to be removed
+   */
+  public void removeStyle(String nm)
+  {
+    getStyledDocument().removeStyle(nm);
+  }
+
+  /**
+   * Looks up and returns a named <code>Style</code>.
+   *
+   * @param nm the name of the <code>Style</code>
+   *
+   * @return the found <code>Style</code> of <code>null</code> if no such
+   *         <code>Style</code> exists
+   */
+  public Style getStyle(String nm)
+  {
+    return getStyledDocument().getStyle(nm);
+  }
+
+  /**
+   * Returns the logical style of the paragraph at the current caret position.
+   *
+   * @return the logical style of the paragraph at the current caret position
+   */
+  public Style getLogicalStyle()
+  {
+    return getStyledDocument().getLogicalStyle(getCaretPosition());
+  }
+
+  /**
+   * Sets the logical style for the paragraph at the current caret position.
+   *
+   * @param style the style to set for the current paragraph
+   */
+  public void setLogicalStyle(Style style)
+  {
+    getStyledDocument().setLogicalStyle(getCaretPosition(), style);
+  }
+
+  /**
+   * Returns the text attributes for the character at the current caret
+   * position.
+   *
+   * @return the text attributes for the character at the current caret
+   *         position
+   */
+  public AttributeSet getCharacterAttributes()
+  {
+    StyledDocument doc = getStyledDocument();
+    Element el = doc.getCharacterElement(getCaretPosition());
+    return el.getAttributes();
+  }
+
+  /**
+   * Sets text attributes for the current selection. If there is no selection
+   * the text attributes are applied to newly inserted text
+   *
+   * @param attribute the text attributes to set
+   * @param replace if <code>true</code>, the attributes of the current
+   *     selection are overridden, otherwise they are merged
+   *
+   * @see #getInputAttributes
+   */
+  public void setCharacterAttributes(AttributeSet attribute,
+                                     boolean replace)
+  {
+    int dot = getCaret().getDot();
+    int start = getSelectionStart();
+    int end = getSelectionEnd();
+    if (start == dot && end == dot)
+      // There is no selection, update insertAttributes instead
+      {
+        MutableAttributeSet inputAttributes =
+          getStyledEditorKit().getInputAttributes();
+        if (replace)
+          inputAttributes.removeAttributes(inputAttributes);
+        inputAttributes.addAttributes(attribute);
+      }
+    else
+      getStyledDocument().setCharacterAttributes(start, end - start, attribute,
+						 replace);
+  }
+
+  /**
+   * Returns the text attributes of the paragraph at the current caret
+   * position.
+   *
+   * @return the attributes of the paragraph at the current caret position
+   */
+  public AttributeSet getParagraphAttributes()
+  {
+    StyledDocument doc = getStyledDocument();
+    Element el = doc.getParagraphElement(getCaretPosition());
+    return el.getAttributes();
+  }
+
+  /**
+   * Sets text attributes for the paragraph at the current selection.
+   * If there is no selection the text attributes are applied to
+   * the paragraph at the current caret position.
+   *
+   * @param attribute the text attributes to set
+   * @param replace if <code>true</code>, the attributes of the current
+   *     selection are overridden, otherwise they are merged
+   */
+  public void setParagraphAttributes(AttributeSet attribute,
+                                     boolean replace)
+  {
+    // TODO
+  }
+
+  /**
+   * Returns the attributes that are applied to newly inserted text.
+   * This is a {@link MutableAttributeSet}, so you can easily modify these
+   * attributes.
+   *
+   * @return the attributes that are applied to newly inserted text
+   */
+  public MutableAttributeSet getInputAttributes()
+  {
+    return getStyledEditorKit().getInputAttributes();
+  }
+
+  /**
+   * Returns the {@link StyledEditorKit} that is currently used by this
+   * <code>JTextPane</code>.
+   *
+   * @return the current <code>StyledEditorKit</code> of this
+   *         <code>JTextPane</code>
+   */
+  protected final StyledEditorKit getStyledEditorKit()
+  {
+    return (StyledEditorKit) getEditorKit();
+  }
+
+  /**
+   * Creates the default {@link EditorKit} that is used in
+   * <code>JTextPane</code>s. This is an instance of {@link StyledEditorKit}.
+   *
+   * @return the default {@link EditorKit} that is used in
+   *         <code>JTextPane</code>s
+   */
+  protected EditorKit createDefaultEditorKit()
+  {
+    return new StyledEditorKit();
+  }
+
+  /**
+   * Sets the {@link EditorKit} to use for this <code>JTextPane</code>.
+   * <code>JTextPane</code>s can only handle {@link StyledEditorKit}s,
+   * if client programs try to set a different type of <code>EditorKit</code>
+   * then an IllegalArgumentException is thrown
+   *
+   * @param editor the <code>EditorKit</code> to set
+   *
+   * @throws IllegalArgumentException if <code>editor</code> is no
+   *         <code>StyledEditorKit</code>
+   */
+  public final void setEditorKit(EditorKit editor)
+  {
+    if (!(editor instanceof StyledEditorKit))
+      throw new IllegalArgumentException
+        ("JTextPanes can only handle StyledEditorKits");
+    super.setEditorKit(editor);
+  }
+
+  /**
+   * Returns a param string that can be used for debugging.
+   *
+   * @return a param string that can be used for debugging.
+   */
+  protected String paramString()
+  {
+    return super.paramString(); // TODO
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToggleButton.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToggleButton.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToggleButton.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToggleButton.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,354 @@
+/* JToggleButton.java -- 
+   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.swing.plaf.ButtonUI;
+
+/**
+ * The <code>JToggleButton</code> component provides a stateful button,
+ * which can be either selected or unselected.  This provides the basis
+ * for the implementations of radio buttons (<code>JRadioButton</code>)
+ * and check boxes (<code>JCheckBox</code>).
+ *
+ * @author Michael Koch  (konqueror at gmx.de)
+ * @author Graydon Hoare  (graydon at redhat.com)
+ * @author Andrew John Hughes  (gnu_andrew at member.fsf.org)
+ * @see JRadioButton
+ * @see JCheckBox
+ * @since 1.2
+ */
+public class JToggleButton extends AbstractButton implements Accessible
+{
+  /**
+   * This class provides accessibility support for the toggle button.
+   */
+  protected class AccessibleJToggleButton
+    extends AccessibleAbstractButton
+    implements ItemListener
+  {
+    private static final long serialVersionUID = -8652952712161229225L;
+
+    /**
+     * Constructor for the accessible toggle button.
+     */
+    public AccessibleJToggleButton()
+    {
+      super();
+      /* Register the accessible toggle button as a listener for item events */
+      addItemListener(this);
+    }
+
+    /**
+     * Returns the accessible role for the toggle button.
+     *
+     * @return An instance of <code>AccessibleRole</code>, describing
+     *         the role of the toggle button.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.TOGGLE_BUTTON;
+    }
+    
+    /**
+     * Monitors the toggle button for state changes and fires accessible
+     * property change events when they occur.
+     *
+     * @param event the event that occurred.
+     */
+    public void itemStateChanged(ItemEvent event)
+    {
+        /* Fire a state property change event as the button's state has changed */
+        if (event.getStateChange() == ItemEvent.SELECTED)
+          {
+            /* State has changed from unselected (null) to selected */
+            firePropertyChange(ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.SELECTED);
+          } 
+        else
+          {
+            /* State has changed from selected to unselected (null) */
+            firePropertyChange(ACCESSIBLE_STATE_PROPERTY, AccessibleState.ENABLED, null);
+          }
+    }
+    
+  }
+
+  /**
+   * The model handles the storage and maintenance of the state of
+   * the toggle button.  This follows the same paradigm (the MVC
+   * or Model-View-Controller design pattern) employed by
+   * other Swing components, where the data associated with a component
+   * is stored separately from the display aspects.
+   */
+  public static class ToggleButtonModel extends DefaultButtonModel
+  {
+    /**
+     * Compatible with Sun's JDK.
+     */
+    private static final long serialVersionUID = -1589950750899943974L;
+    
+    /**
+     * Sets the pressed state of the button.  The selected state
+     * of the button also changes follwing the button being pressed.
+     *
+     * @param p true if the button is pressed down.
+     */
+    public void setPressed(boolean p)  
+    {
+      // cannot change PRESSED state unless button is enabled
+      if (! isEnabled())
+        return;
+      
+      // if this call does not represent a CHANGE in state, then return
+      if ((p && isPressed()) || (!p && !isPressed()))
+        return;
+
+      // The JDK first fires events in the following order:
+      // 1. ChangeEvent for selected
+      // 2. ChangeEvent for pressed
+      // 3. ActionEvent
+      // So do we.
+
+      // setPressed(false) == mouse release on us,
+      // if we were armed, we flip the selected state.
+      if (!p && isArmed())
+        {
+          setSelected(! isSelected());
+        }
+
+      // make the change
+      if (p)
+        stateMask = stateMask | PRESSED;
+      else
+        stateMask = stateMask & (~PRESSED);
+      
+      // notify interested ChangeListeners
+      fireStateChanged();
+
+      if (!p && isArmed())
+        {
+          fireActionPerformed(new ActionEvent(this,
+                                              ActionEvent.ACTION_PERFORMED,
+                                              actionCommand));
+        }
+    }
+      
+      /**
+       * Checks if the button is selected.
+       * 
+       * @return <code>true</code> if the button is selected.
+       */
+      public boolean isSelected()
+      {
+        return super.isSelected();
+      }
+      
+      /**
+       * Sets the selected state of the button.
+       * 
+       * @param b true if button is selected
+       */
+      public void setSelected(boolean b)
+      {
+        super.setSelected(b);
+      }  
+  }
+
+  /**
+   * Compatible with Sun's JDK.
+   */
+  private static final long serialVersionUID = -3128248873429850443L;
+    
+  /**
+   * Constructs an unselected toggle button with no text or icon.
+   */ 
+  public JToggleButton()
+  {
+    this(null, null, false);
+  }
+
+  /**
+   * Constructs a toggle button using the labelling, state
+   * and icon specified by the supplied action.
+   *
+   * @param a the action to use to define the properties of the button.
+   */
+  public JToggleButton(Action a)
+  {
+    this();
+    setAction(a);
+  }
+
+  /**
+   * Constructs an unselected toggle button with the supplied icon
+   * and no text.
+   *
+   * @param icon the icon to use.
+   */
+  public JToggleButton(Icon icon)
+  { 
+    this(null, icon, false);
+  }    
+  
+  /**
+   * Constructs a toggle button with the supplied icon and state.
+   *
+   * @param icon the icon to use.
+   * @param selected if true, the toggle button is initially in the
+   *        selected state.  Otherwise, the button is unselected.
+   */
+  public JToggleButton(Icon icon, boolean selected) 
+  {
+    this(null, icon, selected);
+  }
+  
+  /**
+   * Constructs an unselected toggle button using the supplied text
+   * and no icon.
+   *
+   * @param text the text to use.
+   */ 
+  public JToggleButton(String text)
+  {
+    this(text, null, false);
+  }
+      
+  /**
+   * Constructs a toggle button with the supplied text and state.
+   *
+   * @param text the text to use.
+   * @param selected if true, the toggle button is initially in the
+   *        selected state.  Otherwise, the button is unselected.
+   */
+  public JToggleButton(String text, boolean selected)
+  {
+    this(text, null, selected);
+  }
+
+  /**
+   * Constructs an unselected toggle button with the supplied text
+   * and icon.
+   *
+   * @param text the text to use.
+   * @param icon the icon to use.
+   */
+  public JToggleButton(String text, Icon icon)
+  {
+    this(text, icon, false);
+  }
+
+  /**
+   * Constructs a toggle button with the supplied text, icon and state.
+   *
+   * @param text the text to use.
+   * @param icon the icon to use.
+   * @param selected if true, the toggle button is initially in the
+   *        selected state.  Otherwise, the button is unselected.
+   */
+  public JToggleButton (String text, Icon icon, boolean selected) 
+  {
+    super();
+    init(text, icon);
+
+    setModel(new ToggleButtonModel());	
+    model.setSelected(selected);
+    setAlignmentX(LEFT_ALIGNMENT);
+  }
+
+  /**
+   * Gets the AccessibleContext associated with this <code>JToggleButton</code>.
+   * The context is created, if necessary.
+   *
+   * @return the associated context
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    /* Create the context if this is the first request */
+    if (accessibleContext == null)
+      {
+        /* Create the context */
+	accessibleContext = new AccessibleJToggleButton();
+      }
+    return accessibleContext;
+  }
+  
+  /**
+   * Returns a string that specifies the name of the Look and Feel
+   * class that renders this component.
+   *
+   * @return The Look and Feel UI class in <code>String</code> form.
+   */
+  public String getUIClassID()
+  {
+    return "ToggleButtonUI";
+  }
+  
+  /**
+   * Returns a textual representation of this component for debugging.
+   * Users should not depend on anything as regards the content or formatting
+   * of this string, except for the fact that the returned string may never be
+   * null (only empty).
+   *
+   * @return the component in <code>String</code> form for debugging.
+   */
+  protected  String paramString()
+  {
+    return super.paramString();
+  }
+  
+  /**
+   * This method resets the toggle button's UI delegate to the default UI for
+   * the current look and feel.
+   */
+  public void updateUI()
+  {	
+    setUI((ButtonUI)UIManager.getUI(this));
+  }
+
+}
+
+
+

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolBar.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolBar.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolBar.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolBar.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,796 @@
+/* JToolBar.java --
+   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.beans.PropertyChangeListener;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.plaf.ToolBarUI;
+
+/**
+ * JToolBar is a component that provides a toolbar to Swing programs. Users
+ * can add buttons (or actions that will be represented by JButtons) as well
+ * as other components to the JToolBar. JToolBars can be dragged in and out
+ * of their parent components. If the JToolBar is dragged out of the parent,
+ * then it will be displayed in its own RootPaneContainer. For dragging to
+ * work properly, JToolBars need to be placed in a Container that has a
+ * BorderLayout. That parent Container cannot have components in the NORTH,
+ * EAST, SOUTH,  or WEST components (that is not the JToolBar).
+ */
+public class JToolBar extends JComponent implements SwingConstants, Accessible
+{
+  /**
+   * Provides the accessibility features for the <code>JToolBar</code>
+   * component.
+   */
+  protected class AccessibleJToolBar extends AccessibleJComponent
+  {
+    private static final long serialVersionUID = -5516888265903814215L;
+
+    /**
+     * Creates a new <code>AccessibleJToolBar</code> instance.
+     */
+    protected AccessibleJToolBar()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns a set containing the current state of the {@link JToolBar} 
+     * component.  The current implementation simply calls the superclass.
+     *
+     * @return The accessible state set.
+     */
+    public AccessibleStateSet getAccessibleStateSet()
+    {
+      // running tests against the reference implementation, I was unable
+      // to find any state information that is set specifically by the
+      // tool bar...
+      return super.getAccessibleStateSet();
+    }
+
+    /**
+     * Returns the accessible role for the <code>JToolBar</code> component.
+     *
+     * @return {@link AccessibleRole#TOOL_BAR}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.TOOL_BAR;
+    }
+  }
+
+  /**
+   * This is the private JToolBar layout manager.
+   */
+  private class DefaultToolBarLayout implements LayoutManager
+  {
+    /**
+     * This method is called when a new component is added to the container.
+     *
+     * @param name The name of the component added.
+     * @param comp The component that was added.
+     */
+    public void addLayoutComponent(String name, Component comp)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called to lay out the given container  to position and
+     * size the child components.
+     *
+     * @param c The container to lay out.
+     *
+     * @throws Error DOCUMENT ME!
+     */
+    public void layoutContainer(Container c)
+    {
+      if (! (c instanceof JToolBar))
+	throw new Error("DefaultToolBarLayout can only be used on JToolBars.");
+      Insets insets = getInsets();
+      Insets margin = getMargin();
+      int middle;
+      if (margin != null)
+        {
+	  insets.left += margin.left;
+	  insets.top += margin.top;
+	  insets.bottom += margin.bottom;
+	  insets.right += margin.right;
+        }
+      Component[] components = c.getComponents();
+      Dimension tdims = c.getSize();
+      int start = 0;
+      Dimension pref;
+
+      if (getOrientation() == SwingUtilities.HORIZONTAL)
+        {
+	  start += insets.left;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] != null && components[i].isVisible())
+	        {
+		  pref = components[i].getPreferredSize();
+		  if (pref != null)
+		    {
+		      middle = (tdims.height - pref.height) / 2;
+		      components[i].setBounds(start, middle, pref.width,
+		                              pref.height);
+		      start += pref.width;
+		    }
+	        }
+	    }
+        }
+      else
+        {
+	  start += insets.top;
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      if (components[i] != null && components[i].isVisible())
+	        {
+		  pref = components[i].getPreferredSize();
+		  if (pref != null)
+		    {
+		      middle = (tdims.width - pref.width) / 2;
+		      components[i].setBounds(middle, start, pref.width,
+		                              pref.height);
+		      start += pref.height;
+		    }
+	        }
+	    }
+        }
+    }
+
+    /**
+     * This method returns the minimum size of the given container given the
+     * child components.
+     *
+     * @param parent The container to measure.
+     *
+     * @return The minimum size of the given container.
+     */
+    public Dimension minimumLayoutSize(Container parent)
+    {
+      return preferredLayoutSize(parent);
+    }
+
+    /**
+     * This method returns the preferred size of the given container given the
+     * child components.
+     *
+     * @param parent The container to measure.
+     *
+     * @return The preferred size of the given container.
+     */
+    public Dimension preferredLayoutSize(Container parent)
+    {
+      int orientation = getOrientation();
+      Component[] components = getComponents();
+
+      int limit = 0;
+      int total = 0;
+      Dimension dims;
+
+      int w = 0;
+      int h = 0;
+
+      if (orientation == SwingConstants.HORIZONTAL)
+        {
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      dims = components[i].getPreferredSize();
+	      if (dims != null)
+	        {
+		  if (dims.height > limit)
+		    limit = dims.height;
+		  total += dims.width;
+	        }
+	    }
+	  w = total;
+	  h = limit;
+        }
+      else
+        {
+	  for (int i = 0; i < components.length; i++)
+	    {
+	      dims = components[i].getPreferredSize();
+	      if (dims != null)
+	        {
+		  if (dims.width > limit)
+		    limit = dims.width;
+		  total += dims.height;
+	        }
+	    }
+	  w = limit;
+	  h = total;
+        }
+
+      Insets insets = getInsets();
+      w += insets.left + insets.right;
+      h += insets.top + insets.bottom;
+
+      Insets margin = getMargin();
+      if (margin != null)
+        {
+	  w += margin.left + margin.right;
+	  h += margin.top + margin.bottom;
+        }
+
+      return new Dimension(w, h);
+    }
+
+    /**
+     * This method is called when the given component  is removed from the
+     * container.
+     *
+     * @param comp The component removed.
+     */
+    public void removeLayoutComponent(Component comp)
+    {
+      // Do nothing.
+    }
+  }
+
+  /**
+   * This is an extension of JSeparator used in toolbars. Unlike JSeparator,
+   * nothing is painted for this Separator, it is only blank space that
+   * separates components.
+   */
+  public static class Separator extends JSeparator
+  {
+    /** DOCUMENT ME! */
+    private static final long serialVersionUID = -1656745644823105219L;
+
+    /**
+     * Creates a new Separator object.
+     */
+    public Separator()
+    {
+      super();
+    } // Separator()
+
+    /**
+     * Creates a new Separator object with the given size.
+     *
+     * @param size The size of the separator.
+     */
+    public Separator(Dimension size)
+    {
+      setPreferredSize(size);
+    } // Separator()
+
+    /**
+     * This method returns the String ID of the UI class of  Separator.
+     *
+     * @return The UI class' String ID.
+     */
+    public String getUIClassID()
+    {
+      return "ToolBarSeparatorUI";
+    } // getUIClassID()
+
+    /**
+     * This method returns the preferred size of the Separator.
+     *
+     * @return The preferred size of the Separator.
+     */
+    public Dimension getPreferredSize()
+    {
+      return super.getPreferredSize();
+    } // getPreferredSize()
+
+    /**
+     * This method returns the maximum size of the Separator.
+     *
+     * @return The maximum size of the Separator.
+     */
+    public Dimension getMaximumSize()
+    {
+      return super.getPreferredSize();
+    } // getMaximumSize()
+
+    /**
+     * This method returns the minimum size of the Separator.
+     *
+     * @return The minimum size of the Separator.
+     */
+    public Dimension getMinimumSize()
+    {
+      return super.getPreferredSize();
+    } // getMinimumSize()
+
+    /**
+     * This method returns the size of the Separator.
+     *
+     * @return The size of the Separator.
+     */
+    public Dimension getSeparatorSize()
+    {
+      return super.getPreferredSize();
+    } // getSeparatorSize()
+
+    /**
+     * This method sets the size of the Separator.
+     *
+     * @param size The new size of the Separator.
+     */
+    public void setSeparatorSize(Dimension size)
+    {
+      setPreferredSize(size);
+    } // setSeparatorSize()
+  } // Separator
+
+  /** DOCUMENT ME! */
+  private static final long serialVersionUID = -1269915519555129643L;
+
+  /** Whether the JToolBar paints its border. */
+  private transient boolean paintBorder = true;
+
+  /** The extra insets around the JToolBar. */
+  private transient Insets margin;
+
+  /** Whether the JToolBar can float (and be dragged around). */
+  private transient boolean floatable = true;
+
+  /** Whether the buttons will have rollover borders. */
+  private transient boolean rollover;
+
+  /** The orientation of the JToolBar. */
+  private int orientation = HORIZONTAL;
+
+  /**
+   * This method creates a new JToolBar object with horizontal orientation
+   * and no name.
+   */
+  public JToolBar()
+  {
+    this(null, HORIZONTAL);
+  } // JToolBar()
+
+  /**
+   * This method creates a new JToolBar with the given orientation and  no
+   * name.
+   *
+   * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
+   */
+  public JToolBar(int orientation)
+  {
+    this(null, orientation);
+  } // JToolBar()
+
+  /**
+   * This method creates a new JToolBar object with the given name and
+   * horizontal orientation.
+   *
+   * @param name Name assigned to undocked tool bar.
+   */
+  public JToolBar(String name)
+  {
+    this(name, HORIZONTAL);
+  } // JToolBar()
+
+  /**
+   * This method creates a new JToolBar object with the given name and
+   * orientation.
+   *
+   * @param name Name assigned to undocked tool bar.
+   * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
+   */
+  public JToolBar(String name, int orientation)
+  {
+    setName(name);
+    setOrientation(orientation);
+    setLayout(new DefaultToolBarLayout());
+    revalidate();
+    setOpaque(true);
+    updateUI();
+  }
+
+  /**
+   * This method adds a new JButton that performs the given Action to the
+   * JToolBar.
+   *
+   * @param action The Action to add to the JToolBar.
+   *
+   * @return The JButton that wraps the Action.
+   */
+  public JButton add(Action action)
+  {
+    JButton b = createActionComponent(action);
+    add(b);
+    return b;
+  } // add()
+
+  /**
+   * This method paints the border if the borderPainted property is true.
+   *
+   * @param graphics The graphics object to paint with.
+   */
+  protected void paintBorder(Graphics graphics)
+  {
+    if (paintBorder && isFloatable())
+      super.paintBorder(graphics);
+  } // paintBorder()
+
+  /**
+   * This method returns the UI class used to paint this JToolBar.
+   *
+   * @return The UI class for this JToolBar.
+   */
+  public ToolBarUI getUI()
+  {
+    return (ToolBarUI) ui;
+  } // getUI()
+
+  /**
+   * This method sets the UI used with the JToolBar.
+   *
+   * @param ui The UI used with the JToolBar.
+   */
+  public void setUI(ToolBarUI ui)
+  {
+    super.setUI(ui);
+  } // setUI()
+
+  /**
+   * This method resets the UI used to the Look and Feel defaults.
+   */
+  public void updateUI()
+  {
+    setUI((ToolBarUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This method returns the String identifier for the UI class to the used
+   * with the JToolBar.
+   *
+   * @return The String identifier for the UI class.
+   */
+  public String getUIClassID()
+  {
+    return "ToolBarUI";
+  } // getUIClassID()
+
+  /**
+   * This method sets the rollover property for the JToolBar. In rollover
+   * mode, JButtons inside the JToolBar will only display their borders when
+   * the mouse is moving over them.
+   *
+   * @param b The new rollover property.
+   */
+  public void setRollover(boolean b)
+  {
+    if (b != rollover)
+      {
+	rollover = b;
+	firePropertyChange("rollover", ! rollover, rollover);
+	revalidate();
+	repaint();
+      }
+  }
+
+  /**
+   * This method returns the rollover property.
+   *
+   * @return The rollover property.
+   */
+  public boolean isRollover()
+  {
+    return rollover;
+  }
+
+  /**
+   * This method returns the index of the given component.
+   *
+   * @param component The component to find.
+   *
+   * @return The index of the given component.
+   */
+  public int getComponentIndex(Component component)
+  {
+    Component[] components = getComponents();
+    if (components == null)
+      return -1;
+
+    for (int i = 0; i < components.length; i++)
+      if (components[i] == component)
+	return i;
+
+    return -1;
+  } // getComponentIndex()
+
+  /**
+   * This method returns the component at the given index.
+   *
+   * @param index The index of the component.
+   *
+   * @return The component at the given index.
+   */
+  public Component getComponentAtIndex(int index)
+  {
+    return getComponent(index);
+  } // getComponentAtIndex()
+
+  /**
+   * This method returns the margin property.
+   *
+   * @return The margin property.
+   */
+  public Insets getMargin()
+  {
+    return margin;
+  } // getMargin()
+
+  /**
+   * This method sets the margin property. The margin property determines the
+   * extra space between the children components of the JToolBar and the
+   * border.
+   *
+   * @param margin The margin property.
+   */
+  public void setMargin(Insets margin)
+  {
+    if ((this.margin != null && margin == null)
+        || (this.margin == null && margin != null)
+        || (margin != null && this.margin != null
+        && (margin.left != this.margin.left
+        || margin.right != this.margin.right || margin.top != this.margin.top
+        || margin.bottom != this.margin.bottom)))
+      {
+	Insets oldMargin = this.margin;
+	this.margin = margin;
+	firePropertyChange("margin", oldMargin, this.margin);
+	revalidate();
+	repaint();
+      }
+  } // setMargin()
+
+  /**
+   * This method returns the borderPainted property.
+   *
+   * @return The borderPainted property.
+   */
+  public boolean isBorderPainted()
+  {
+    return paintBorder;
+  } // isBorderPainted()
+
+  /**
+   * This method sets the borderPainted property. If set to false, the border
+   * will not be painted.
+   *
+   * @param painted Whether the border will be painted.
+   */
+  public void setBorderPainted(boolean painted)
+  {
+    if (painted != paintBorder)
+      {
+	paintBorder = painted;
+	firePropertyChange("borderPainted", ! paintBorder,
+	                   paintBorder);
+	repaint();
+      }
+  } // setBorderPainted()
+
+  /**
+   * This method returns the floatable property.
+   *
+   * @return The floatable property.
+   */
+  public boolean isFloatable()
+  {
+    return floatable;
+  } // isFloatable()
+
+  /**
+   * This method sets the floatable property. If set to false, the JToolBar
+   * cannot be dragged.
+   *
+   * @param floatable Whether the JToolBar can be dragged.
+   */
+  public void setFloatable(boolean floatable)
+  {
+    if (floatable != this.floatable)
+      {
+	this.floatable = floatable;
+	firePropertyChange("floatable", ! floatable, floatable);
+      }
+  } // setFloatable()
+
+  /**
+   * This method returns the orientation of the JToolBar.
+   *
+   * @return The orientation of the JToolBar.
+   */
+  public int getOrientation()
+  {
+    return orientation;
+  } // getOrientation()
+
+  /**
+   * This method sets the layout manager to be used with the JToolBar.
+   *
+   * @param mgr The Layout Manager used with the JToolBar.
+   */
+  public void setLayout(LayoutManager mgr)
+  {
+    super.setLayout(mgr);
+    revalidate();
+    repaint();
+  } // setLayout()
+
+  /**
+   * This method sets the orientation property for JToolBar.
+   *
+   * @param orientation The new orientation for JToolBar.
+   *
+   * @throws IllegalArgumentException If the orientation is not HORIZONTAL or
+   *         VERTICAL.
+   */
+  public void setOrientation(int orientation)
+  {
+    if (orientation != HORIZONTAL && orientation != VERTICAL)
+      throw new IllegalArgumentException(orientation
+                                         + " is not a legal orientation");
+    if (orientation != this.orientation)
+      {
+	int oldOrientation = this.orientation;
+	this.orientation = orientation;
+	firePropertyChange("orientation", oldOrientation, this.orientation);
+	revalidate();
+	repaint();
+      }
+  } // setOrientation()
+
+  /**
+   * This method adds a Separator of default size to the JToolBar.
+   */
+  public void addSeparator()
+  {
+    add(new Separator());
+  } // addSeparator()
+
+  /**
+   * This method adds a Separator with the given size to the JToolBar.
+   *
+   * @param size The size of the Separator.
+   */
+  public void addSeparator(Dimension size)
+  {
+    add(new Separator(size));
+  } // addSeparator()
+
+  /**
+   * This method is used to create JButtons which can be added to the JToolBar
+   * for the given action.
+   *
+   * @param action The action to create a JButton for.
+   *
+   * @return The JButton created from the action.
+   */
+  protected JButton createActionComponent(Action action)
+  {
+    return new JButton(action);
+  } // createActionComponent()
+
+  /**
+   * This method creates a pre-configured PropertyChangeListener which updates
+   * the control as changes are made to the Action. However, this is no
+   * longer the recommended way of adding Actions to Containers. As such,
+   * this method returns null.
+   *
+   * @param button The JButton to configure a PropertyChangeListener for.
+   *
+   * @return null.
+   */
+  protected PropertyChangeListener createActionChangeListener(JButton button)
+  {
+    // XXX: As specified, this returns null. But seems kind of strange, usually deprecated methods don't just return null, verify!
+    return null;
+  } // createActionChangeListener()
+
+  /**
+   * This method overrides Container's addImpl method. If a JButton is added,
+   * it is disabled.
+   *
+   * @param component The Component to add.
+   * @param constraints The Constraints placed on the component.
+   * @param index The index to place the Component at.
+   */
+  protected void addImpl(Component component, Object constraints, int index)
+  {
+    // XXX: Sun says disable button but test cases show otherwise.
+    super.addImpl(component, constraints, index);
+
+    // if we added a Swing Button then adjust this a little
+    if (component instanceof AbstractButton)
+      {
+        AbstractButton b = (AbstractButton) component;
+        b.setRolloverEnabled(rollover);
+      }
+
+  } // addImpl()
+
+  /**
+   * Returns a string describing the attributes for the <code>JToolBar</code>
+   * component, for use in debugging.  The return value is guaranteed to be 
+   * non-<code>null</code>, but the format of the string may vary between
+   * implementations.
+   *
+   * @return A string describing the attributes of the <code>JToolBar</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",floatable=").append(floatable);
+    sb.append(",margin=");
+    if (margin != null)
+      sb.append(margin);
+    sb.append(",orientation=");
+    if (orientation == HORIZONTAL)
+      sb.append("HORIZONTAL");
+    else
+      sb.append(VERTICAL);
+    sb.append(",paintBorder=").append(paintBorder);
+    return sb.toString();
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JToolBar</code> component.
+   *
+   * @return The accessible context (an instance of {@link AccessibleJToolBar}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJToolBar();
+
+    return accessibleContext;
+  }
+}

Added: llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolTip.java
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolTip.java?rev=43913&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolTip.java (added)
+++ llvm-gcc-4.2/trunk/libjava/classpath/javax/swing/JToolTip.java Thu Nov  8 16:56:19 2007
@@ -0,0 +1,228 @@
+/* JToolTip.java --
+   Copyright (C) 2002, 2004  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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, or (at your option)
+any later version.
+
+GNU Classpath 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.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.AWTEvent;
+import java.beans.PropertyChangeEvent;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.swing.plaf.ToolTipUI;
+
+/**
+ * This class is used to display ToolTips. ToolTips are small floating windows
+ * that display text when the mouse comes to rest over a Component. ToolTips
+ * are set for JComponents using JComponent.setToolTipText(String).
+ */
+public class JToolTip extends JComponent implements Accessible
+{
+
+  private static final long serialVersionUID = -1138929898906751643L;
+
+  /**
+   * Provides the accessibility features for the <code>JToolTip</code>
+   * component.
+   */
+  protected class AccessibleJToolTip extends AccessibleJComponent
+  {
+    private static final long serialVersionUID = -6222548177795408476L;
+
+    /**
+     * Creates a new AccessibleJToolTip object.
+     */
+    protected AccessibleJToolTip()
+    {
+      // Nothing to do here.
+    }
+
+    /**
+     * Returns a description for the accessible component.
+     *
+     * @return A description for the accessible component.
+     */
+    public String getAccessibleDescription()
+    {
+      String result = super.getAccessibleDescription();
+      if (result == null)
+        result = text;
+      return result;
+    }
+
+    /**
+     * Returns the accessible role for the <code>JToolTip</code> component.
+     *
+     * @return {@link AccessibleRole#TOOL_TIP}.
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return AccessibleRole.TOOL_TIP;
+    }
+  }
+
+  /** The text to display in the JToolTip. */
+  String text;
+
+  /** The component that the tool tip is associated with. */
+  JComponent component;
+
+  /**
+   * Creates a new <code>JToolTip</code> instance.
+   */
+  public JToolTip()
+  {
+    disableEvents(AWTEvent.MOUSE_EVENT_MASK);
+    updateUI();
+  }
+
+  /**
+   * Returns the text displayed by the tool tip.
+   *
+   * @return The text (possibly <code>null</code>).
+   * 
+   * @see #setTipText(String)
+   */
+  public String getTipText()
+  {
+    return text;
+  }
+
+  /**
+   * Returns the object that provides accessibility features for this
+   * <code>JToolTip</code> component.
+   *
+   * @return The accessible context (an instance of {@link AccessibleJToolTip}).
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJToolTip();
+    return accessibleContext;
+  }
+
+  /**
+   * Returns the component that the tool tip is associated with.
+   *
+   * @return The component (possibly <code>null</code>).
+   * 
+   * @see #setComponent(JComponent)
+   */
+  public JComponent getComponent()
+  {
+    return component;
+  }
+
+  /**
+   * Returns the current UI delegate for this component.
+   *
+   * @return The UI delegate.
+   */
+  public ToolTipUI getUI()
+  {
+    return (ToolTipUI) ui;
+  }
+
+  /**
+   * Returns the string suffix used to identify the UI class, in this case
+   * <code>"ToolTipUI"</code>.
+   *
+   * @return <code>"ToolTipUI"</code>.
+   */
+  public String getUIClassID()
+  {
+    return "ToolTipUI";
+  }
+
+  /**
+   * Returns a string describing the attributes for the <code>JToolTip</code>
+   * component, for use in debugging.  The return value is guaranteed to be 
+   * non-<code>null</code>, but the format of the string may vary between
+   * implementations.
+   *
+   * @return A string describing the attributes of the <code>JToolTip</code>.
+   */
+  protected String paramString()
+  {
+    StringBuffer sb = new StringBuffer(super.paramString());
+    sb.append(",tiptext=");
+    if (text != null);
+      sb.append(text);
+    return sb.toString();
+  }
+
+  /**
+   * Sets the component that the tool tip is associated with and sends a 
+   * {@link PropertyChangeEvent} (with the property name 'component') to all 
+   * registered listeners.
+   *
+   * @param c  the component (<code>null</code> permitted).
+   * 
+   * @see #getComponent()
+   */
+  public void setComponent(JComponent c)
+  {
+    JComponent oldValue = component;
+    component = c;
+    firePropertyChange("component", oldValue, c);
+  }
+
+  /**
+   * Sets the text to be displayed by the tool tip and sends a 
+   * {@link PropertyChangeEvent} (with the property name 'tiptext') to all 
+   * registered listeners.
+   *
+   * @param tipText the text (<code>null</code> permitted).
+   * 
+   * @see #getTipText()
+   */
+  public void setTipText(String tipText)
+  {
+    String oldValue = text;
+    text = tipText;
+    firePropertyChange("tiptext", oldValue, tipText);
+  }
+
+  /**
+   * This method resets the UI used to the Look and Feel default.
+   */
+  public void updateUI()
+  {
+    setUI((ToolTipUI) UIManager.getUI(this));
+  }
+}





More information about the llvm-commits mailing list