diff options
author | Mark Wielaard <mark@gcc.gnu.org> | 2006-01-17 18:09:40 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2006-01-17 18:09:40 +0000 |
commit | 2127637945ea6b763966398130e0770fa993c860 (patch) | |
tree | c976ca91e3ef0bda3b34b37c0195145638d8d08e /libjava/classpath/javax/swing/plaf | |
parent | bcb36c3e02e3bd2843aad1b9888513dfb5d6e337 (diff) | |
download | gcc-2127637945ea6b763966398130e0770fa993c860.zip gcc-2127637945ea6b763966398130e0770fa993c860.tar.gz gcc-2127637945ea6b763966398130e0770fa993c860.tar.bz2 |
Imported GNU Classpath 0.20
Imported GNU Classpath 0.20
* Makefile.am (AM_CPPFLAGS): Add classpath/include.
* java/nio/charset/spi/CharsetProvider.java: New override file.
* java/security/Security.java: Likewise.
* sources.am: Regenerated.
* Makefile.in: Likewise.
From-SVN: r109831
Diffstat (limited to 'libjava/classpath/javax/swing/plaf')
31 files changed, 4042 insertions, 1669 deletions
diff --git a/libjava/classpath/javax/swing/plaf/ComponentUI.java b/libjava/classpath/javax/swing/plaf/ComponentUI.java index 6a736f2..be7b68a 100644 --- a/libjava/classpath/javax/swing/plaf/ComponentUI.java +++ b/libjava/classpath/javax/swing/plaf/ComponentUI.java @@ -41,7 +41,6 @@ package javax.swing.plaf; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; -import java.awt.Rectangle; import javax.accessibility.Accessible; import javax.swing.JComponent; @@ -185,12 +184,12 @@ public abstract class ComponentUI public void update(Graphics g, JComponent c) { if (c.isOpaque()) - { - Color oldColor = g.getColor(); - g.setColor(c.getBackground()); - g.fillRect(0, 0, c.getWidth(), c.getHeight()); - g.setColor(oldColor); - } + { + Color oldColor = g.getColor(); + g.setColor(c.getBackground()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + g.setColor(oldColor); + } paint(g, c); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java b/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java index 69d4415..56e4e70 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java @@ -162,8 +162,8 @@ public class BasicArrowButton extends JButton implements SwingConstants super.paint(g); Rectangle bounds = getBounds(); int size = bounds.height / 4; - int x = (bounds.width - size) / 2; - int y = (bounds.height - size) / 2; + int x = bounds.x + (bounds.width - size) / 2; + int y = (bounds.height - size) / 4; ButtonModel m = getModel(); if (m.isArmed()) { diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java index b22aa15..288a8d8 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -190,10 +190,19 @@ public class BasicComboBoxUI extends ComboBoxUI */ Dimension displaySize; - // FIXME: This fields aren't used anywhere at this moment. - protected Dimension cachedMinimumSize; + // FIXME: This field isn't used anywhere at this moment. protected CellRendererPane currentValuePane; - protected boolean isMinimumSizeDirty; + + /** + * The current minimum size if isMinimumSizeDirty is false. + * Setup by getMinimumSize() and invalidated by the various listeners. + */ + protected Dimension cachedMinimumSize; + + /** + * Indicates whether or not the cachedMinimumSize field is valid or not. + */ + protected boolean isMinimumSizeDirty = true; /** * Creates a new <code>BasicComboBoxUI</code> object. @@ -285,8 +294,7 @@ public class BasicComboBoxUI extends ComboBoxUI comboBox.addPropertyChangeListener(propertyChangeListener); focusListener = createFocusListener(); - comboBox.addFocusListener(focusListener); - listBox.addFocusListener(focusListener); + editor.addFocusListener(focusListener); itemListener = createItemListener(); comboBox.addItemListener(itemListener); @@ -563,6 +571,7 @@ public class BasicComboBoxUI extends ComboBoxUI { arrowButton.setEnabled(comboBox.isEnabled()); arrowButton.setFont(comboBox.getFont()); + arrowButton.setFocusable(false); } /** @@ -615,12 +624,14 @@ public class BasicComboBoxUI extends ComboBoxUI public void setPopupVisible(JComboBox c, boolean v) { if (v) - { - popup.show(); - popup.getList().requestFocus(); - } + popup.show(); else popup.hide(); + + if (comboBox.isEditable()) + editor.requestFocus(); + else + comboBox.requestFocus(); } /** @@ -668,7 +679,7 @@ public class BasicComboBoxUI extends ComboBoxUI /** * Returns the minimum size for this {@link JComboBox} for this - * look and feel. + * look and feel. Also makes sure cachedMinimimSize is setup correctly. * * @param c The {@link JComponent} to find the minimum size for. * @@ -676,10 +687,15 @@ public class BasicComboBoxUI extends ComboBoxUI */ public Dimension getMinimumSize(JComponent c) { - Dimension d = getDisplaySize(); - int arrowButtonWidth = d.height; - Dimension result = new Dimension(d.width + arrowButtonWidth, d.height); - return result; + if (isMinimumSizeDirty) + { + Dimension d = getDisplaySize(); + int arrowButtonWidth = d.height; + cachedMinimumSize = new Dimension(d.width + arrowButtonWidth, + d.height); + isMinimumSizeDirty = false; + } + return new Dimension(cachedMinimumSize); } /** The value returned by the getMaximumSize() method. */ @@ -1062,6 +1078,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void focusGained(FocusEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + hasFocus = true; comboBox.repaint(); } @@ -1074,6 +1093,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void focusLost(FocusEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + hasFocus = false; setPopupVisible(comboBox, false); comboBox.repaint(); @@ -1102,6 +1124,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void itemStateChanged(ItemEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + if (e.getStateChange() == ItemEvent.SELECTED && comboBox.isEditable()) comboBox.getEditor().setItem(e.getItem()); comboBox.repaint(); @@ -1149,6 +1174,9 @@ public class BasicComboBoxUI extends ComboBoxUI public void contentsChanged(ListDataEvent e) { // if the item is selected or deselected + + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; } /** @@ -1158,6 +1186,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void intervalAdded(ListDataEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + ComboBoxModel model = comboBox.getModel(); ListCellRenderer renderer = comboBox.getRenderer(); @@ -1179,6 +1210,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void intervalRemoved(ListDataEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + // recalculate display size of the JComboBox. displaySize = getDisplaySize(); comboBox.repaint(); @@ -1206,6 +1240,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void propertyChange(PropertyChangeEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + if (e.getPropertyName().equals("enabled")) { arrowButton.setEnabled(comboBox.isEnabled()); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java index 73979bb..08dab7f 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java @@ -442,6 +442,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup { list.setModel(comboBox.getModel()); list.setVisibleRowCount(comboBox.getMaximumRowCount()); + list.setFocusable(false); installListListeners(); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java index 60179dc..30e3156 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -37,19 +37,8 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Point; -import java.awt.Polygon; import java.awt.Window; import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; @@ -62,23 +51,16 @@ import java.util.Hashtable; import javax.swing.AbstractAction; import javax.swing.Action; -import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.JButton; -import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; -import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; -import javax.swing.JScrollPane; import javax.swing.JTextField; -import javax.swing.JToggleButton; -import javax.swing.ListCellRenderer; -import javax.swing.SwingConstants; import javax.swing.SwingUtilities; -import javax.swing.Timer; +import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @@ -87,6 +69,7 @@ import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.FileChooserUI; +import javax.swing.plaf.metal.MetalIconFactory; /** @@ -144,7 +127,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected ApproveSelectionAction() { - // Nothing to do here. + super("approveSelection"); } /** @@ -154,17 +137,22 @@ public class BasicFileChooserUI extends FileChooserUI */ public void actionPerformed(ActionEvent e) { - Object obj = new String(parentPath + entry.getText()); + Object obj = null; + if (parentPath != null) + obj = new String(parentPath + getFileName()); + else + obj = filechooser.getSelectedFile(); if (obj != null) { - File f = filechooser.getFileSystemView().createFileObject( - obj.toString()); - if (filechooser.isTraversable(f) - && filechooser.isDirectorySelectionEnabled()) - filechooser.setCurrentDirectory(f); + File f = filechooser.getFileSystemView().createFileObject(obj.toString()); + File currSelected = filechooser.getSelectedFile(); + if (filechooser.isTraversable(f)) + { + filechooser.setCurrentDirectory(currSelected); + filechooser.rescanCurrentDirectory(); + } else { - filechooser.setSelectedFile(f); filechooser.approveSelection(); closeDialog(); } @@ -307,7 +295,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected CancelSelectionAction() { - // Nothing to do here. + super(null); } /** @@ -317,6 +305,8 @@ public class BasicFileChooserUI extends FileChooserUI */ public void actionPerformed(ActionEvent e) { + filechooser.setSelectedFile(null); + filechooser.setSelectedFiles(null); filechooser.cancelSelection(); closeDialog(); } @@ -335,7 +325,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected ChangeToParentDirectoryAction() { - // Nothing to do here. + super("Go Up"); } /** @@ -358,8 +348,6 @@ public class BasicFileChooserUI extends FileChooserUI */ protected class DoubleClickListener extends MouseAdapter { - /** A timer. */ - private Timer timer = null; /** DOCUMENT ME! */ private Object lastSelected = null; @@ -375,8 +363,6 @@ public class BasicFileChooserUI extends FileChooserUI public DoubleClickListener(JList list) { this.list = list; - timer = new Timer(1000, null); - timer.setRepeats(false); lastSelected = list.getSelectedValue(); setDirectorySelected(false); } @@ -388,14 +374,14 @@ public class BasicFileChooserUI extends FileChooserUI */ public void mouseClicked(MouseEvent e) { - if (list.getSelectedValue() == null) + Object p = list.getSelectedValue(); + if (p == null) return; FileSystemView fsv = filechooser.getFileSystemView(); - if (timer.isRunning() - && list.getSelectedValue().toString().equals(lastSelected.toString())) + if (e.getClickCount() >= 2 && lastSelected != null && + p.toString().equals(lastSelected.toString())) { File f = fsv.createFileObject(lastSelected.toString()); - timer.stop(); if (filechooser.isTraversable(f)) { filechooser.setCurrentDirectory(f); @@ -410,8 +396,19 @@ public class BasicFileChooserUI extends FileChooserUI } else { - String path = list.getSelectedValue().toString(); + String path = p.toString(); File f = fsv.createFileObject(path); + filechooser.setSelectedFile(f); + + if (filechooser.isMultiSelectionEnabled()) + { + int[] inds = list.getSelectedIndices(); + File[] allFiles = new File[inds.length]; + for (int i = 0; i < inds.length; i++) + allFiles[i] = (File) list.getModel().getElementAt(inds[i]); + filechooser.setSelectedFiles(allFiles); + } + if (filechooser.isTraversable(f)) { setDirectorySelected(true); @@ -424,8 +421,11 @@ public class BasicFileChooserUI extends FileChooserUI } lastSelected = path; parentPath = path.substring(0, path.lastIndexOf("/") + 1); - entry.setText(path.substring(path.lastIndexOf("/") + 1)); - timer.restart(); + if (f.isFile()) + setFileName(path.substring(path.lastIndexOf("/") + 1)); + else if (filechooser.getFileSelectionMode() == + JFileChooser.DIRECTORIES_ONLY) + setFileName(path); } } @@ -453,7 +453,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected GoHomeAction() { - // Nothing to do here. + super("Go Home"); } /** @@ -483,7 +483,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected NewFolderAction() { - // Nothing to do here. + super("New Folder"); } /** @@ -529,7 +529,8 @@ public class BasicFileChooserUI extends FileChooserUI */ public void valueChanged(ListSelectionEvent e) { - Object f = filelist.getSelectedValue(); + JList list = (JList) e.getSource(); + Object f = list.getSelectedValue(); if (f == null) return; File file = filechooser.getFileSystemView().createFileObject(f.toString()); @@ -552,7 +553,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected UpdateAction() { - // Nothing to do here. + super(null); } /** @@ -576,91 +577,13 @@ public class BasicFileChooserUI extends FileChooserUI protected String cancelButtonToolTipText; /** An icon representing a computer. */ - protected Icon computerIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - // FIXME: is this not implemented, or is the icon intentionally blank? - } - }; + protected Icon computerIcon; /** An icon for the "details view" button. */ - protected Icon detailsViewIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - g.setColor(Color.GRAY); - g.drawRect(1, 1, 15, 20); - g.drawLine(17, 6, 23, 6); - g.drawLine(17, 12, 23, 12); - g.drawLine(17, 18, 23, 18); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon detailsViewIcon; /** An icon representing a directory. */ - protected Icon directoryIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point ap = new Point(3, 7); - Point bp = new Point(3, 21); - Point cp = new Point(21, 21); - Point dp = new Point(21, 12); - Point ep = new Point(16, 12); - Point fp = new Point(13, 7); - - Polygon dir = new Polygon(new int[] { ap.x, bp.x, cp.x, dp.x, ep.x, fp.x }, - new int[] { ap.y, bp.y, cp.y, dp.y, ep.y, fp.y }, - 6); - - g.setColor(new Color(153, 204, 255)); - g.fillPolygon(dir); - g.setColor(Color.BLACK); - g.drawPolygon(dir); - - g.translate(-x, -y); - g.setColor(saved); - } - }; + protected Icon directoryIcon; /** The localised Mnemonic for the open button. */ protected int directoryOpenButtonMnemonic; @@ -672,82 +595,13 @@ public class BasicFileChooserUI extends FileChooserUI protected String directoryOpenButtonToolTipText; /** An icon representing a file. */ - protected Icon fileIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point a = new Point(5, 4); - Point b = new Point(5, 20); - Point d = new Point(19, 20); - Point e = new Point(19, 7); - Point f = new Point(16, 4); - - Polygon p = new Polygon(new int[] { a.x, b.x, d.x, e.x, f.x, }, - new int[] { a.y, b.y, d.y, e.y, f.y }, 5); - - g.setColor(Color.WHITE); - g.fillPolygon(p); - g.setColor(Color.BLACK); - g.drawPolygon(p); - - g.drawLine(16, 4, 14, 6); - g.drawLine(14, 6, 19, 7); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon fileIcon; /** An icon representing a floppy drive. */ - protected Icon floppyDriveIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - // FIXME: is this not implemented, or is the icon intentionally blank? - } - }; + protected Icon floppyDriveIcon; /** An icon representing a hard drive. */ - protected Icon hardDriveIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - // FIXME: is this not implemented, or is the icon intentionally blank? - } - }; + protected Icon hardDriveIcon; /** The localised mnemonic for the "help" button. */ protected int helpButtonMnemonic; @@ -759,86 +613,10 @@ public class BasicFileChooserUI extends FileChooserUI protected String helpButtonToolTipText; /** An icon representing the user's home folder. */ - protected Icon homeFolderIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point a = new Point(12, 3); - Point b = new Point(4, 10); - Point d = new Point(20, 10); - - Polygon p = new Polygon(new int[] { a.x, b.x, d.x }, - new int[] { a.y, b.y, d.y }, 3); - - g.setColor(new Color(104, 51, 0)); - g.fillPolygon(p); - g.setColor(Color.BLACK); - g.drawPolygon(p); - - g.setColor(Color.WHITE); - g.fillRect(8, 10, 8, 10); - g.setColor(Color.BLACK); - g.drawRect(8, 10, 8, 10); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon homeFolderIcon; /** An icon for the "list view" button. */ - protected Icon listViewIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - // Not needed. Only simplifies things until we get real icons. - private void paintPartial(Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - g.setColor(Color.GRAY); - g.drawRect(1, 1, 7, 10); - g.drawLine(8, 6, 11, 6); - - g.setColor(saved); - g.translate(-x, -y); - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - paintPartial(g, 0, 0); - paintPartial(g, 12, 0); - paintPartial(g, 0, 12); - paintPartial(g, 12, 12); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon listViewIcon; /** An icon for the "new folder" button. */ protected Icon newFolderIcon = directoryIcon; @@ -871,65 +649,13 @@ public class BasicFileChooserUI extends FileChooserUI protected String updateButtonToolTipText; /** An icon for the "up folder" button. */ - protected Icon upFolderIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component comp, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point a = new Point(3, 7); - Point b = new Point(3, 21); - Point c = new Point(21, 21); - Point d = new Point(21, 12); - Point e = new Point(16, 12); - Point f = new Point(13, 7); - - Polygon dir = new Polygon(new int[] { a.x, b.x, c.x, d.x, e.x, f.x }, - new int[] { a.y, b.y, c.y, d.y, e.y, f.y }, 6); - - g.setColor(new Color(153, 204, 255)); - g.fillPolygon(dir); - g.setColor(Color.BLACK); - g.drawPolygon(dir); - - a = new Point(12, 15); - b = new Point(9, 18); - c = new Point(15, 18); - - Polygon arrow = new Polygon(new int[] { a.x, b.x, c.x }, - new int[] { a.y, b.y, c.y }, 3); - - g.fillPolygon(arrow); - - g.drawLine(12, 15, 12, 22); - - g.translate(-x, -y); - g.setColor(saved); - } - }; + protected Icon upFolderIcon; // -- begin private, but package local since used in inner classes -- /** The file chooser component represented by this UI delegate. */ JFileChooser filechooser; - /** The file list. */ - JList filelist; - - /** The combo box used to display/select file filters. */ - JComboBox filters; - /** The model for the directory list. */ BasicDirectoryModel model; @@ -939,32 +665,11 @@ public class BasicFileChooserUI extends FileChooserUI /** The default file view. */ FileView fv = new BasicFileView(); - /** The icon size. */ - static final int ICON_SIZE = 24; - - /** A combo box for display/selection of parent directories. */ - JComboBox parents; - - /** The current file name. */ - String filename; - /** The accept (open/save) button. */ JButton accept; - /** The cancel button. */ - JButton cancel; - - /** The button to move up to the parent directory. */ - JButton upFolderButton; - - /** The button to create a new directory. */ - JButton newFolderButton; - - /** The button to move to the user's home directory. */ - JButton homeFolderButton; - /** An optional accessory panel. */ - JPanel accessoryPanel; + JPanel accessoryPanel = new JPanel(); /** A property change listener. */ PropertyChangeListener propertyChangeListener; @@ -997,47 +702,43 @@ public class BasicFileChooserUI extends FileChooserUI /** Current parent path */ String parentPath; + /** + * The action for the 'approve' button. + * @see #getApproveSelectionAction() + */ + private ApproveSelectionAction approveSelectionAction; + + /** + * The action for the 'cancel' button. + * @see #getCancelSelectionAction() + */ + private CancelSelectionAction cancelSelectionAction; + + /** + * The action for the 'go home' control button. + * @see #getGoHomeAction() + */ + private GoHomeAction goHomeAction; + + /** + * The action for the 'up folder' control button. + * @see #getChangeToParentDirectoryAction() + */ + private ChangeToParentDirectoryAction changeToParentDirectoryAction; + + /** + * The action for the 'new folder' control button. + * @see #getNewFolderAction() + */ + private NewFolderAction newFolderAction; + + /** + * The action for ???. // FIXME: what is this? + * @see #getUpdateAction() + */ + private UpdateAction updateAction; + // -- end private -- - private class ListLabelRenderer extends JLabel implements ListCellRenderer - { - /** DOCUMENT ME! */ - final Color selected = new Color(153, 204, 255); - - /** - * Creates a new ListLabelRenderer object. - */ - public ListLabelRenderer() - { - super(); - setOpaque(true); - } - - /** - * DOCUMENT ME! - * - * @param list DOCUMENT ME! - * @param value DOCUMENT ME! - * @param index DOCUMENT ME! - * @param isSelected DOCUMENT ME! - * @param cellHasFocus DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public Component getListCellRendererComponent(JList list, Object value, - int index, - boolean isSelected, - boolean cellHasFocus) - { - setHorizontalAlignment(SwingConstants.LEFT); - File file = (File) value; - setText(filechooser.getName(file)); - setIcon(filechooser.getIcon(file)); - setBackground(isSelected ? selected : Color.WHITE); - setForeground(Color.BLACK); - - return this; - } - } /** * Closes the dialog. @@ -1056,7 +757,6 @@ public class BasicFileChooserUI extends FileChooserUI */ public BasicFileChooserUI(JFileChooser b) { - this.filechooser = b; } /** @@ -1081,6 +781,7 @@ public class BasicFileChooserUI extends FileChooserUI if (c instanceof JFileChooser) { JFileChooser fc = (JFileChooser) c; + this.filechooser = fc; fc.resetChoosableFileFilters(); createModel(); clearIconCache(); @@ -1130,78 +831,7 @@ public class BasicFileChooserUI extends FileChooserUI if (parentFiles.size() == 0) return; - if (parents.getItemCount() > 0) - parents.removeAllItems(); - for (int i = parentFiles.size() - 1; i >= 0; i--) - parents.addItem(parentFiles.get(i)); - parents.setSelectedIndex(parentFiles.size() - 1); - parents.revalidate(); - parents.repaint(); - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - private ItemListener createBoxListener() - { - return new ItemListener() - { - public void itemStateChanged(ItemEvent e) - { - if (parents.getItemCount() - 1 == parents.getSelectedIndex()) - return; - StringBuffer dir = new StringBuffer(); - for (int i = 0; i <= parents.getSelectedIndex(); i++) - { - dir.append(parents.getItemAt(i)); - dir.append(File.separatorChar); - } - filechooser.setCurrentDirectory(filechooser.getFileSystemView() - .createFileObject(dir - .toString())); - } - }; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - private ItemListener createFilterListener() - { - return new ItemListener() - { - public void itemStateChanged(ItemEvent e) - { - int index = filters.getSelectedIndex(); - if (index == -1) - return; - filechooser.setFileFilter(filechooser.getChoosableFileFilters()[index]); - } - }; - } - - void filterEntries() - { - FileFilter[] list = filechooser.getChoosableFileFilters(); - if (filters.getItemCount() > 0) - filters.removeAllItems(); - - int index = -1; - String selected = filechooser.getFileFilter().getDescription(); - for (int i = 0; i < list.length; i++) - { - if (selected.equals(list[i].getDescription())) - index = i; - filters.addItem(list[i].getDescription()); - } - filters.setSelectedIndex(index); - filters.revalidate(); - filters.repaint(); - } + } /** * Creates and install the subcomponents for the file chooser. @@ -1210,121 +840,6 @@ public class BasicFileChooserUI extends FileChooserUI */ public void installComponents(JFileChooser fc) { - JLabel look = new JLabel("Look In:"); - - parents = new JComboBox(); - parents.setRenderer(new BasicComboBoxRenderer()); - boxEntries(); - look.setLabelFor(parents); - JPanel parentsPanel = new JPanel(); - parentsPanel.add(look); - parentsPanel.add(parents); - JPanel buttonPanel = new JPanel(); - - upFolderButton = new JButton(); - upFolderButton.setIcon(upFolderIcon); - buttonPanel.add(upFolderButton); - - homeFolderButton = new JButton(); - homeFolderButton = new JButton(homeFolderIcon); - buttonPanel.add(homeFolderButton); - - newFolderButton = new JButton(); - newFolderButton.setIcon(newFolderIcon); - buttonPanel.add(newFolderButton); - - ButtonGroup toggles = new ButtonGroup(); - JToggleButton listViewButton = new JToggleButton(); - listViewButton.setIcon(listViewIcon); - toggles.add(listViewButton); - buttonPanel.add(listViewButton); - - JToggleButton detailsViewButton = new JToggleButton(); - detailsViewButton.setIcon(detailsViewIcon); - toggles.add(detailsViewButton); - buttonPanel.add(detailsViewButton); - - JPanel topPanel = new JPanel(); - parentsPanel.add(buttonPanel); - topPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); - topPanel.add(parentsPanel); - - accessoryPanel = new JPanel(); - if (filechooser.getAccessory() != null) - accessoryPanel.add(filechooser.getAccessory(), BorderLayout.CENTER); - - filelist = new JList(model); - filelist.setVisibleRowCount(6); - JScrollPane scrollp = new JScrollPane(filelist); - scrollp.setPreferredSize(new Dimension(400, 175)); - filelist.setBackground(Color.WHITE); - - filelist.setLayoutOrientation(JList.VERTICAL_WRAP); - filelist.setCellRenderer(new ListLabelRenderer()); - - GridBagConstraints c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 0; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - c.weighty = 1; - - JPanel centrePanel = new JPanel(); - centrePanel.setLayout(new GridBagLayout()); - centrePanel.add(scrollp, c); - - c.gridx = 1; - centrePanel.add(accessoryPanel, c); - - JLabel fileNameLabel = new JLabel("File Name:"); - JLabel fileTypesLabel = new JLabel("Files of Type:"); - - entry = new JTextField(); - filters = new JComboBox(); - filterEntries(); - - fileNameLabel.setLabelFor(entry); - fileNameLabel.setHorizontalTextPosition(SwingConstants.LEFT); - fileTypesLabel.setLabelFor(filters); - fileTypesLabel.setHorizontalTextPosition(SwingConstants.LEFT); - - closePanel = new JPanel(); - accept = getApproveButton(filechooser); - cancel = new JButton(cancelButtonText); - cancel.setMnemonic(cancelButtonMnemonic); - cancel.setToolTipText(cancelButtonToolTipText); - closePanel.add(accept); - closePanel.add(cancel); - - c.anchor = GridBagConstraints.WEST; - c.weighty = 0; - c.weightx = 0; - c.gridx = 0; - - bottomPanel = new JPanel(); - bottomPanel.setLayout(new GridBagLayout()); - bottomPanel.add(fileNameLabel, c); - - c.gridy = 1; - bottomPanel.add(fileTypesLabel, c); - c.gridx = 1; - c.gridy = 0; - c.weightx = 1; - c.weighty = 1; - bottomPanel.add(entry, c); - - c.gridy = 1; - bottomPanel.add(filters, c); - - c.fill = GridBagConstraints.NONE; - c.gridy = 2; - c.anchor = GridBagConstraints.EAST; - bottomPanel.add(closePanel, c); - - filechooser.setLayout(new BorderLayout()); - filechooser.add(topPanel, BorderLayout.NORTH); - filechooser.add(centrePanel, BorderLayout.CENTER); - filechooser.add(bottomPanel, BorderLayout.SOUTH); } /** @@ -1334,15 +849,6 @@ public class BasicFileChooserUI extends FileChooserUI */ public void uninstallComponents(JFileChooser fc) { - parents = null; - - accept = null; - cancel = null; - upFolderButton = null; - homeFolderButton = null; - newFolderButton = null; - - filelist = null; } /** @@ -1354,17 +860,6 @@ public class BasicFileChooserUI extends FileChooserUI { propertyChangeListener = createPropertyChangeListener(filechooser); filechooser.addPropertyChangeListener(propertyChangeListener); - - //parents.addItemListener(createBoxListener()); - accept.addActionListener(getApproveSelectionAction()); - cancel.addActionListener(getCancelSelectionAction()); - upFolderButton.addActionListener(getChangeToParentDirectoryAction()); - homeFolderButton.addActionListener(getGoHomeAction()); - newFolderButton.addActionListener(getNewFolderAction()); - filters.addItemListener(createFilterListener()); - - filelist.addMouseListener(createDoubleClickListener(filechooser, filelist)); - filelist.addListSelectionListener(createListSelectionListener(filechooser)); } /** @@ -1401,24 +896,42 @@ public class BasicFileChooserUI extends FileChooserUI } /** - * Installs the icons for this UI delegate (NOT YET IMPLEMENTED). + * Installs the icons for this UI delegate. * - * @param fc the file chooser. + * @param fc the file chooser (ignored). */ protected void installIcons(JFileChooser fc) { - // FIXME: Implement. + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + computerIcon = MetalIconFactory.getTreeComputerIcon(); + detailsViewIcon = defaults.getIcon("FileChooser.detailsViewIcon"); + directoryIcon = new MetalIconFactory.TreeFolderIcon(); + fileIcon = new MetalIconFactory.TreeLeafIcon(); + floppyDriveIcon = MetalIconFactory.getTreeFloppyDriveIcon(); + hardDriveIcon = MetalIconFactory.getTreeHardDriveIcon(); + homeFolderIcon = defaults.getIcon("FileChooser.homeFolderIcon"); + listViewIcon = defaults.getIcon("FileChooser.listViewIcon"); + newFolderIcon = defaults.getIcon("FileChooser.newFolderIcon"); + upFolderIcon = defaults.getIcon("FileChooser.upFolderIcon"); } /** - * Uninstalls the icons previously added by this UI delegate (NOT YET - * IMPLEMENTED). + * Uninstalls the icons previously added by this UI delegate. * * @param fc the file chooser. */ protected void uninstallIcons(JFileChooser fc) { - // FIXME: Implement. + computerIcon = null; + detailsViewIcon = null; + directoryIcon = null; + fileIcon = null; + floppyDriveIcon = null; + hardDriveIcon = null; + homeFolderIcon = null; + listViewIcon = null; + newFolderIcon = null; + upFolderIcon = null; } /** @@ -1428,25 +941,36 @@ public class BasicFileChooserUI extends FileChooserUI */ protected void installStrings(JFileChooser fc) { - acceptAllFileFilterText = UIManager.getString("FileChooser.acceptAllFileFilterText"); - cancelButtonMnemonic = UIManager.getInt("FileChooser.cancelButtonMnemonic"); - cancelButtonText = UIManager.getString("FileChooser.cancelButtonText"); - cancelButtonToolTipText = UIManager.getString("FileChooser.cancelButtonToolTipText"); + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + + dirDescText = defaults.getString("FileChooser.directoryDescriptionText"); + fileDescText = defaults.getString("FileChooser.fileDescriptionText"); - dirDescText = UIManager.getString("FileChooser.directoryDescriptionText"); - fileDescText = UIManager.getString("FileChooser.fileDescriptionText"); + acceptAllFileFilterText = defaults.getString("FileChooser.acceptAllFileFilterText"); + cancelButtonText = "Cancel"; + cancelButtonToolTipText = "Abort file chooser dialog"; + cancelButtonMnemonic = new Integer((String) UIManager.get("FileChooser.cancelButtonMnemonic")).intValue(); - helpButtonMnemonic = UIManager.getInt("FileChooser.helpButtonMnemonic"); - helpButtonText = UIManager.getString("FileChooser.helpButtonText"); - helpButtonToolTipText = UIManager.getString("FileChooser.helpButtonToolTipText"); + directoryOpenButtonText = "Open"; + directoryOpenButtonToolTipText = "Open selected directory"; + directoryOpenButtonMnemonic + = new Integer((String) UIManager.get("FileChooser.directoryOpenButtonMnemonic")).intValue(); + + helpButtonText = "Help"; + helpButtonToolTipText = "FileChooser help"; + helpButtonMnemonic = new Integer((String) UIManager.get("FileChooser.helpButtonMnemonic")).intValue(); - openButtonMnemonic = UIManager.getInt("FileChooser.openButtonMnemonic"); - openButtonText = UIManager.getString("FileChooser.openButtonText"); - openButtonToolTipText = UIManager.getString("FileChooser.openButtonToolTipText"); + openButtonText = "Open"; + openButtonToolTipText = "Open selected file"; + openButtonMnemonic = new Integer((String) UIManager.get("FileChooser.openButtonMnemonic")).intValue(); - saveButtonMnemonic = UIManager.getInt("FileChooser.saveButtonMnemonic"); - saveButtonText = UIManager.getString("FileChooser.saveButtonText"); - saveButtonToolTipText = UIManager.getString("FileChooser.saveButtonToolTipText"); + saveButtonText = "Save"; + saveButtonToolTipText = "Save selected file"; + saveButtonMnemonic = new Integer((String) UIManager.get("FileChooser.saveButtonMnemonic")).intValue(); + + updateButtonText = "Update"; + updateButtonToolTipText = "Update directory listing"; + updateButtonMnemonic = new Integer((String) UIManager.get("FileChooser.updateButtonMnemonic")).intValue(); } /** @@ -1457,24 +981,26 @@ public class BasicFileChooserUI extends FileChooserUI protected void uninstallStrings(JFileChooser fc) { acceptAllFileFilterText = null; - cancelButtonMnemonic = 0; + dirDescText = null; + fileDescText = null; + cancelButtonText = null; cancelButtonToolTipText = null; - dirDescText = null; - fileDescText = null; + directoryOpenButtonText = null; + directoryOpenButtonToolTipText = null; - helpButtonMnemonic = 0; helpButtonText = null; helpButtonToolTipText = null; - openButtonMnemonic = 0; openButtonText = null; openButtonToolTipText = null; - saveButtonMnemonic = 0; saveButtonText = null; saveButtonToolTipText = null; + + updateButtonText = null; + updateButtonToolTipText = null; } /** @@ -1509,110 +1035,6 @@ public class BasicFileChooserUI extends FileChooserUI { public void propertyChange(PropertyChangeEvent e) { - // FIXME: Multiple file selection waiting on JList multiple selection - // bug. - if (e.getPropertyName().equals( - JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) - { - if (filechooser.getSelectedFile() == null) - setFileName(null); - else - setFileName(filechooser.getSelectedFile().toString()); - int index = -1; - File file = filechooser.getSelectedFile(); - for (index = 0; index < model.getSize(); index++) - if (((File) model.getElementAt(index)).equals(file)) - break; - if (index == -1) - return; - filelist.setSelectedIndex(index); - filelist.ensureIndexIsVisible(index); - filelist.revalidate(); - filelist.repaint(); - } - else if (e.getPropertyName().equals( - JFileChooser.DIRECTORY_CHANGED_PROPERTY)) - { - filelist.clearSelection(); - filelist.revalidate(); - filelist.repaint(); - setDirectorySelected(false); - setDirectory(filechooser.getCurrentDirectory()); - boxEntries(); - } - else if (e.getPropertyName().equals( - JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) - filterEntries(); - else if (e.getPropertyName().equals( - JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY)) - { - Window owner = SwingUtilities.windowForComponent(filechooser); - if (owner instanceof JDialog) - ((JDialog) owner).setTitle(getDialogTitle(filechooser)); - accept.setText(getApproveButtonText(filechooser)); - accept.setToolTipText(getApproveButtonToolTipText(filechooser)); - accept.setMnemonic(getApproveButtonMnemonic(filechooser)); - } - else if (e.getPropertyName().equals( - JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY)) - accept.setText(getApproveButtonText(filechooser)); - else if (e.getPropertyName().equals( - JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) - accept.setToolTipText(getApproveButtonToolTipText(filechooser)); - else if (e.getPropertyName().equals( - JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) - accept.setMnemonic(getApproveButtonMnemonic(filechooser)); - else if (e.getPropertyName().equals( - JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) - { - if (filechooser.getControlButtonsAreShown()) - { - GridBagConstraints c = new GridBagConstraints(); - c.gridy = 1; - bottomPanel.add(filters, c); - - c.fill = GridBagConstraints.BOTH; - c.gridy = 2; - c.anchor = GridBagConstraints.EAST; - bottomPanel.add(closePanel, c); - bottomPanel.revalidate(); - bottomPanel.repaint(); - bottomPanel.doLayout(); - } - else - bottomPanel.remove(closePanel); - } - else if (e.getPropertyName().equals( - JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY)) - { - if (filechooser.isAcceptAllFileFilterUsed()) - filechooser.addChoosableFileFilter(getAcceptAllFileFilter(filechooser)); - else - filechooser.removeChoosableFileFilter(getAcceptAllFileFilter(filechooser)); - } - else if (e.getPropertyName().equals( - JFileChooser.ACCESSORY_CHANGED_PROPERTY)) - { - JComponent old = (JComponent) e.getOldValue(); - if (old != null) - getAccessoryPanel().remove(old); - JComponent newval = (JComponent) e.getNewValue(); - if (newval != null) - getAccessoryPanel().add(newval); - } - if (e.getPropertyName().equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.FILE_FILTER_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.FILE_HIDING_CHANGED_PROPERTY)) - rescanCurrentDirectory(filechooser); - - filechooser.revalidate(); - filechooser.repaint(); } }; } @@ -1624,7 +1046,9 @@ public class BasicFileChooserUI extends FileChooserUI */ public String getFileName() { - return filename; + // FIXME: I'm thinking that this method just provides access to the + // text value in the JTextField component...but not sure yet + return null; //filename; } /** @@ -1649,7 +1073,9 @@ public class BasicFileChooserUI extends FileChooserUI */ public void setFileName(String filename) { - this.filename = filename; + // FIXME: it might be the case that this method provides an access + // point for the JTextField (or whatever) a subclass is using... + //this.filename = filename; } /** @@ -1672,7 +1098,6 @@ public class BasicFileChooserUI extends FileChooserUI public void rescanCurrentDirectory(JFileChooser fc) { getModel().validateFileCache(); - filelist.revalidate(); } /** @@ -1708,17 +1133,14 @@ public class BasicFileChooserUI extends FileChooserUI } /** - * Creates and returns an approve (open or save) button for the dialog. + * Returns the approve (open or save) button for the dialog. * * @param fc the file chooser. * * @return The button. */ - public JButton getApproveButton(JFileChooser fc) + protected JButton getApproveButton(JFileChooser fc) { - accept = new JButton(getApproveButtonText(fc)); - accept.setMnemonic(getApproveButtonMnemonic(fc)); - accept.setToolTipText(getApproveButtonToolTipText(fc)); return accept; } @@ -1830,9 +1252,8 @@ public class BasicFileChooserUI extends FileChooserUI } /** - * Returns the file view for the file chooser. This returns either the - * file view that has been explicitly set for the {@link JFileChooser}, or - * a default file view. + * Returns the default file view (NOT the file view from the file chooser, + * if there is one). * * @param fc the file chooser component. * @@ -1856,24 +1277,10 @@ public class BasicFileChooserUI extends FileChooserUI */ public String getDialogTitle(JFileChooser fc) { - String ret = fc.getDialogTitle(); - if (ret != null) - return ret; - switch (fc.getDialogType()) - { - case JFileChooser.OPEN_DIALOG: - ret = openButtonText; - break; - case JFileChooser.SAVE_DIALOG: - ret = saveButtonText; - break; - default: - ret = fc.getApproveButtonText(); - break; - } - if (ret == null) - ret = openButtonText; - return ret; + String result = fc.getDialogTitle(); + if (result == null) + result = getApproveButtonText(fc); + return result; } /** @@ -1906,23 +1313,28 @@ public class BasicFileChooserUI extends FileChooserUI */ public String getApproveButtonText(JFileChooser fc) { - if (fc.getApproveButtonText() != null) - return fc.getApproveButtonText(); - else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) - return saveButtonText; - else - return openButtonText; + String result = fc.getApproveButtonText(); + if (result == null) + { + if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) + result = saveButtonText; + else + result = openButtonText; + } + return result; } /** * Creates and returns a new action that will be used with the "new folder" * button. * - * @return A new instance of {@link GoHomeAction}. + * @return A new instance of {@link NewFolderAction}. */ public Action getNewFolderAction() { - return new NewFolderAction(); + if (newFolderAction == null) + newFolderAction = new NewFolderAction(); + return newFolderAction; } /** @@ -1933,49 +1345,56 @@ public class BasicFileChooserUI extends FileChooserUI */ public Action getGoHomeAction() { - return new GoHomeAction(); + if (goHomeAction == null) + goHomeAction = new GoHomeAction(); + return goHomeAction; } /** - * Creates and returns a new action that will be used with the "up folder" - * button. + * Returns the action that handles events for the "up folder" control button. * - * @return A new instance of {@link ChangeToParentDirectoryAction}. + * @return An instance of {@link ChangeToParentDirectoryAction}. */ public Action getChangeToParentDirectoryAction() { - return new ChangeToParentDirectoryAction(); + if (changeToParentDirectoryAction == null) + changeToParentDirectoryAction = new ChangeToParentDirectoryAction(); + return changeToParentDirectoryAction; } /** - * Creates and returns a new action that will be used with the "approve" - * button. + * Returns the action that handles events for the "approve" button. * - * @return A new instance of {@link ApproveSelectionAction}. + * @return An instance of {@link ApproveSelectionAction}. */ public Action getApproveSelectionAction() { - return new ApproveSelectionAction(); + if (approveSelectionAction == null) + approveSelectionAction = new ApproveSelectionAction(); + return approveSelectionAction; } /** - * Creates and returns a new action that will be used with the "cancel" - * button. + * Returns the action that handles events for the "cancel" button. * - * @return A new instance of {@link CancelSelectionAction}. + * @return An instance of {@link CancelSelectionAction}. */ public Action getCancelSelectionAction() { - return new CancelSelectionAction(); + if (cancelSelectionAction == null) + cancelSelectionAction = new CancelSelectionAction(); + return cancelSelectionAction; } /** - * Creates and returns a new instance of {@link UpdateAction}. + * Returns the update action (an instance of {@link UpdateAction}). * * @return An action. */ public Action getUpdateAction() { - return new UpdateAction(); + if (updateAction == null) + updateAction = new UpdateAction(); + return updateAction; } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java new file mode 100644 index 0000000..b9891e1 --- /dev/null +++ b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java @@ -0,0 +1,154 @@ +/* BasicHTML.java -- Provides HTML support to ComponentUI implementations + Copyright (C) 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.plaf.basic; + +import java.io.IOException; +import java.io.StringReader; + +import javax.swing.JComponent; +import javax.swing.text.BadLocationException; +import javax.swing.text.Element; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; + +/** + * Provides support for HTML rendering to {@link javax.swing.plaf.ComponentUI} + * implementations. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class BasicHTML +{ + + /** + * The key that is used to store a HTML view in a JComponent's client + * properties. + */ + public static final String propertyKey = "html"; + + /** + * The key that is used to store the document base in a JComponent's client + * properties. The document base is used to resolve relative references + * in HTML. + */ + public static final String documentBaseKey = "html.base"; + + /** + * Creates a new instance of BasicHTML. This should not be necessary since + * all methods in this class are static. + */ + public BasicHTML() + { + // Nothing to do here. + } + + /** + * Creates a {@link View} instance that can be used by the component + * <code>c</code> to render the HTML string <code>html</code>. + * + * @param c the component that needs to render the HTML string + * @param html the HTML string to be rendered + * + * @return a view that can render the HTML string + */ + public static View createHTMLView(JComponent c, String html) + { + // TODO: This might be wrong. Lets see if it turns out good when + // the javax.swing.text.html package is in a good shape. + HTMLDocument doc = new HTMLDocument(); + HTMLEditorKit kit = new HTMLEditorKit(); + StringReader reader = new StringReader(html); + try + { + kit.read(reader, doc, 0); + } + catch (IOException ex) + { + AssertionError err = new AssertionError("unexpected IOException"); + err.initCause(ex); + throw err; + } + catch (BadLocationException ex) + { + AssertionError err = + new AssertionError("unexpected BadLocationException"); + err.initCause(ex); + throw err; + } + ViewFactory vf = kit.getViewFactory(); + Element root = doc.getDefaultRootElement(); + View view = vf.create(root); + return view; + } + + /** + * Returns <code>true</code> if <code>s</code> is HTML, <code>false</code> + * otherwise. + * + * @param s the string to test + * + * @return <code>true</code> if <code>s</code> is HTML, <code>false</code> + * otherwise + */ + public static boolean isHTMLString(String s) + { + // We consider a string to be HTML if it contains both the '<' and '>' + // character at least once. + return s.contains("<") && s.contains(">"); + } + + /** + * Stores a HTML renderer in <code>c</code>'s client property if + * <code>text</code> is HTML, otherwise it clears the corresponding client + * property. This is useful for {@link java.swing.plaf.ComponentUI} + * implementations that are shared between it's components. + * + * @param c the component to update the renderer for + * @param text the string to be rendered + */ + public static void updateRenderer(JComponent c, String text) + { + if (isHTMLString(text)) + c.putClientProperty(propertyKey, createHTMLView(c, text)); + else + c.putClientProperty(propertyKey, null); + } +} diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java index d9dadda..f9653bd 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -46,6 +46,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.LayoutManager; +import java.awt.LayoutManager2; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ComponentEvent; @@ -1164,9 +1165,6 @@ public class BasicInternalFrameUI extends InternalFrameUI { frame = (JInternalFrame) c; - internalFrameLayout = createLayoutManager(); - frame.setLayout(internalFrameLayout); - ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false); frame.getRootPane().getGlassPane().setVisible(true); @@ -1192,7 +1190,6 @@ public class BasicInternalFrameUI extends InternalFrameUI uninstallListeners(); uninstallDefaults(); - frame.setLayout(null); ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true); frame.getRootPane().getGlassPane().setVisible(false); @@ -1204,6 +1201,8 @@ public class BasicInternalFrameUI extends InternalFrameUI */ protected void installDefaults() { + internalFrameLayout = createLayoutManager(); + frame.setLayout(internalFrameLayout); LookAndFeel.installBorder(frame, "InternalFrame.border"); frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon")); // InternalFrames are invisible by default. @@ -1256,6 +1255,8 @@ public class BasicInternalFrameUI extends InternalFrameUI protected void uninstallDefaults() { frame.setBorder(null); + frame.setLayout(null); + internalFrameLayout = null; } /** @@ -1329,7 +1330,13 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public Dimension getPreferredSize(JComponent x) { - return internalFrameLayout.preferredLayoutSize(x); + Dimension pref = null; + LayoutManager layout = frame.getLayout(); + if (frame == x && layout != null) + pref = layout.preferredLayoutSize(frame); + else + pref = new Dimension(100, 100); + return pref; } /** @@ -1341,7 +1348,13 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public Dimension getMinimumSize(JComponent x) { - return internalFrameLayout.minimumLayoutSize(x); + Dimension min = null; + LayoutManager layout = frame.getLayout(); + if (frame == x && layout != null) + min = layout.minimumLayoutSize(frame); + else + min = new Dimension(0, 0); + return min; } /** @@ -1353,7 +1366,13 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public Dimension getMaximumSize(JComponent x) { - return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + Dimension max = null; + LayoutManager layout = frame.getLayout(); + if (frame == x && layout != null && layout instanceof LayoutManager2) + max = ((LayoutManager2) layout).maximumLayoutSize(frame); + else + max = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + return max; } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java index c8f677f..fd4cff5 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java @@ -39,7 +39,6 @@ package javax.swing.plaf.basic; import java.awt.Color; import java.awt.Dimension; -import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Insets; @@ -104,7 +103,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener Rectangle ir = new Rectangle(); Rectangle tr = new Rectangle(); Insets insets = lab.getInsets(); - FontMetrics fm = lab.getToolkit().getFontMetrics(lab.getFont()); + FontMetrics fm = lab.getFontMetrics(lab.getFont()); layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr); Rectangle cr = tr.union(ir); return new Dimension(insets.left + cr.width + insets.right, insets.top @@ -150,17 +149,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener { JLabel b = (JLabel) c; - Font saved_font = g.getFont(); - Rectangle tr = new Rectangle(); Rectangle ir = new Rectangle(); Rectangle vr = new Rectangle(); - Font f = c.getFont(); - - g.setFont(f); - FontMetrics fm = g.getFontMetrics(f); - + FontMetrics fm = g.getFontMetrics(); vr = SwingUtilities.calculateInnerArea(c, vr); if (vr.width < 0) @@ -182,8 +175,6 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener else paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent()); } - - g.setFont(saved_font); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java index 2d66645..00d157a 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java @@ -41,13 +41,11 @@ package javax.swing.plaf.basic; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; +import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseEvent; @@ -61,7 +59,6 @@ import javax.swing.DefaultListSelectionModel; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JList; -import javax.swing.JViewport; import javax.swing.KeyStroke; import javax.swing.ListCellRenderer; import javax.swing.ListModel; @@ -87,21 +84,6 @@ public class BasicListUI extends ListUI { /** - * A helper class which listens for {@link ComponentEvent}s from - * the JList. - */ - private class ComponentHandler extends ComponentAdapter { - - /** - * Called when the component is hidden. Invalidates the internal - * layout. - */ - public void componentResized(ComponentEvent ev) { - BasicListUI.this.damageLayout(); - } - } - - /** * A helper class which listens for {@link FocusEvent}s * from the JList. */ @@ -153,7 +135,7 @@ public class BasicListUI extends ListUI */ public void contentsChanged(ListDataEvent e) { - BasicListUI.this.damageLayout(); + list.revalidate(); } /** @@ -163,7 +145,7 @@ public class BasicListUI extends ListUI */ public void intervalAdded(ListDataEvent e) { - BasicListUI.this.damageLayout(); + list.revalidate(); } /** @@ -173,7 +155,7 @@ public class BasicListUI extends ListUI */ public void intervalRemoved(ListDataEvent e) { - BasicListUI.this.damageLayout(); + list.revalidate(); } } @@ -524,7 +506,14 @@ public class BasicListUI extends ListUI */ public void mouseDragged(MouseEvent event) { - // TODO: What should be done here, if anything? + Point click = event.getPoint(); + int index = locationToIndex(list, click); + if (index == -1) + return; + if (!event.isShiftDown() && !event.isControlDown()) + list.setSelectedIndex(index); + + list.ensureIndexIsVisible(list.getLeadSelectionIndex()); } /** @@ -562,20 +551,19 @@ public class BasicListUI extends ListUI } // Update the updateLayoutStateNeeded flag. if (e.getPropertyName().equals("model")) - updateLayoutStateNeeded += modelChanged; + updateLayoutStateNeeded |= modelChanged; else if (e.getPropertyName().equals("selectionModel")) - updateLayoutStateNeeded += selectionModelChanged; + updateLayoutStateNeeded |= selectionModelChanged; else if (e.getPropertyName().equals("font")) - updateLayoutStateNeeded += fontChanged; + updateLayoutStateNeeded |= fontChanged; else if (e.getPropertyName().equals("fixedCellWidth")) - updateLayoutStateNeeded += fixedCellWidthChanged; + updateLayoutStateNeeded |= fixedCellWidthChanged; else if (e.getPropertyName().equals("fixedCellHeight")) - updateLayoutStateNeeded += fixedCellHeightChanged; + updateLayoutStateNeeded |= fixedCellHeightChanged; else if (e.getPropertyName().equals("prototypeCellValue")) - updateLayoutStateNeeded += prototypeCellValueChanged; + updateLayoutStateNeeded |= prototypeCellValueChanged; else if (e.getPropertyName().equals("cellRenderer")) - updateLayoutStateNeeded += cellRendererChanged; - BasicListUI.this.damageLayout(); + updateLayoutStateNeeded |= cellRendererChanged; } } @@ -641,11 +629,6 @@ public class BasicListUI extends ListUI /** The property change listener listening to the list. */ protected PropertyChangeListener propertyChangeListener; - - /** The component listener that receives notification for resizing the - * JList component.*/ - private ComponentListener componentListener; - /** Saved reference to the list this UI was created for. */ protected JList list; @@ -738,13 +721,12 @@ public class BasicListUI extends ListUI int maxIndex = Math.max(index1, index2); Point loc = indexToLocation(list, minIndex); Rectangle bounds = new Rectangle(loc.x, loc.y, cellWidth, - getRowHeight(minIndex)); - + getCellHeight(minIndex)); for (int i = minIndex + 1; i <= maxIndex; i++) { Point hiLoc = indexToLocation(list, i); Rectangle hibounds = new Rectangle(hiLoc.x, hiLoc.y, cellWidth, - getRowHeight(i)); + getCellHeight(i)); bounds = bounds.union(hibounds); } @@ -752,6 +734,29 @@ public class BasicListUI extends ListUI } /** + * Calculates the maximum cell height. + * + * @param index the index of the cell + * + * @return the maximum cell height + */ + private int getCellHeight(int index) + { + int height = cellHeight; + if (height <= 0) + { + if (list.getLayoutOrientation() == JList.VERTICAL) + height = getRowHeight(index); + else + { + for (int j = 0; j < cellHeights.length; j++) + height = Math.max(height, cellHeights[j]); + } + } + return height; + } + + /** * Calculate the Y coordinate of the upper edge of a particular row, * considering the Y coordinate <code>0</code> to occur at the top of the * list. @@ -804,7 +809,7 @@ public class BasicListUI extends ListUI // Update the layout if necessary. maybeUpdateLayoutState(); - int index = list.getModel().getSize() - 1;; + int index = list.getModel().getSize() - 1; // If a fixed cell height is set, then we can work more efficient. if (cellHeight > 0) @@ -884,24 +889,12 @@ public class BasicListUI extends ListUI } /** - * Marks the current layout as damaged and requests revalidation from the - * JList. - * This is package-private to avoid an accessor method. - * - * @see #updateLayoutStateNeeded - */ - void damageLayout() - { - updateLayoutStateNeeded = 1; - } - - /** * Calls {@link #updateLayoutState} if {@link #updateLayoutStateNeeded} * is nonzero, then resets {@link #updateLayoutStateNeeded} to zero. */ protected void maybeUpdateLayoutState() { - if (updateLayoutStateNeeded != 0) + if (updateLayoutStateNeeded != 0 || !list.isValid()) { updateLayoutState(); updateLayoutStateNeeded = 0; @@ -968,12 +961,6 @@ public class BasicListUI extends ListUI if (propertyChangeListener == null) propertyChangeListener = createPropertyChangeListener(); list.addPropertyChangeListener(propertyChangeListener); - - // FIXME: Are these two really needed? At least they are not documented. - //keyListener = new KeyHandler(); - componentListener = new ComponentHandler(); - list.addComponentListener(componentListener); - //list.addKeyListener(keyListener); } /** @@ -985,7 +972,6 @@ public class BasicListUI extends ListUI list.getModel().removeListDataListener(listDataListener); list.removeListSelectionListener(listSelectionListener); list.removeMouseListener(mouseInputListener); - //list.removeKeyListener(keyListener); list.removeMouseMotionListener(mouseInputListener); list.removePropertyChangeListener(propertyChangeListener); } @@ -1073,33 +1059,62 @@ public class BasicListUI extends ListUI */ public Dimension getPreferredSize(JComponent c) { + maybeUpdateLayoutState(); int size = list.getModel().getSize(); - if (size == 0) - return new Dimension(0, 0); int visibleRows = list.getVisibleRowCount(); int layoutOrientation = list.getLayoutOrientation(); - Rectangle bounds = getCellBounds(list, 0, list.getModel().getSize() - 1); - Dimension retVal = bounds.getSize(); - Component parent = list.getParent(); - if ((visibleRows == -1) && (parent instanceof JViewport)) - { - JViewport viewport = (JViewport) parent; - if (layoutOrientation == JList.HORIZONTAL_WRAP) + int h; + int w; + int maxCellHeight = cellHeight; + if (maxCellHeight <= 0) + { + for (int i = 0; i < cellHeights.length; i++) + maxCellHeight = Math.max(maxCellHeight, cellHeights[i]); + } + if (layoutOrientation == JList.HORIZONTAL_WRAP) + { + if (visibleRows > 0) { - int h = viewport.getSize().height; - int cellsPerCol = h / cellHeight; - int w = size / cellsPerCol * cellWidth; - retVal = new Dimension(w, h); + // We cast to double here to force double divisions. + double modelSize = size; + int neededColumns = (int) Math.ceil(modelSize / visibleRows); + int adjustedRows = (int) Math.ceil(modelSize / neededColumns); + h = maxCellHeight * adjustedRows; + w = cellWidth * neededColumns; } - else if (layoutOrientation == JList.VERTICAL_WRAP) + else { - int w = viewport.getSize().width; - int cellsPerRow = Math.max(w / cellWidth, 1); - int h = size / cellsPerRow * cellHeight; - retVal = new Dimension(w, h); + int neededColumns = Math.min(1, list.getWidth() / cellWidth); + h = size / neededColumns * maxCellHeight; + w = neededColumns * cellWidth; } } + else if (layoutOrientation == JList.VERTICAL_WRAP) + { + if (visibleRows > 0) + h = visibleRows * maxCellHeight; + else + h = Math.max(list.getHeight(), maxCellHeight); + int neededColumns = h / maxCellHeight; + w = cellWidth * neededColumns; + } + else + { + if (list.getFixedCellWidth() > 0) + w = list.getFixedCellWidth(); + else + w = cellWidth; + if (list.getFixedCellHeight() > 0) + // FIXME: We need to add some cellVerticalMargins here, according + // to the specs. + h = list.getFixedCellHeight() * size; + else + h = maxCellHeight * size; + } + Insets insets = list.getInsets(); + Dimension retVal = new Dimension(w + insets.left + insets.right, + h + insets.top + insets.bottom); return retVal; } @@ -1148,9 +1163,9 @@ public class BasicListUI extends ListUI int lead = sel.getLeadSelectionIndex(); Rectangle clip = g.getClipBounds(); - int startIndex = list.locationToIndex(new Point(clip.x, clip.y)); - int endIndex = list.locationToIndex(new Point(clip.x + clip.width, - clip.y + clip.height)); + int startIndex = locationToIndex(list, new Point(clip.x, clip.y)); + int endIndex = locationToIndex(list, new Point(clip.x + clip.width, + clip.y + clip.height)); for (int row = startIndex; row <= endIndex; ++row) { @@ -1165,13 +1180,13 @@ public class BasicListUI extends ListUI * location lies outside the bounds of the list, the greatest index in the * list model is returned. * - * @param list the list which on which the computation is based on + * @param l the list which on which the computation is based on * @param location the coordinates * * @return the index of the list item that is located at the given * coordinates or <code>-1</code> if the list model is empty */ - public int locationToIndex(JList list, Point location) + public int locationToIndex(JList l, Point location) { int layoutOrientation = list.getLayoutOrientation(); int index = -1; @@ -1182,52 +1197,34 @@ public class BasicListUI extends ListUI break; case JList.HORIZONTAL_WRAP: // determine visible rows and cells per row - int visibleRows = list.getVisibleRowCount(); + int maxCellHeight = getCellHeight(0); + int visibleRows = list.getHeight() / maxCellHeight; int cellsPerRow = -1; int numberOfItems = list.getModel().getSize(); - Dimension listDim = list.getSize(); - if (visibleRows <= 0) - { - try - { - cellsPerRow = listDim.width / cellWidth; - } - catch (ArithmeticException ex) - { - cellsPerRow = 1; - } - } - else - { - cellsPerRow = numberOfItems / visibleRows + 1; - } + cellsPerRow = numberOfItems / visibleRows + 1; // determine index for the given location int cellsPerColumn = numberOfItems / cellsPerRow + 1; int gridX = Math.min(location.x / cellWidth, cellsPerRow - 1); - int gridY = Math.min(location.y / cellHeight, cellsPerColumn); + int gridY = Math.min(location.y / maxCellHeight, cellsPerColumn); index = gridX + gridY * cellsPerRow; break; case JList.VERTICAL_WRAP: // determine visible rows and cells per column - int visibleRows2 = list.getVisibleRowCount(); - if (visibleRows2 <= 0) - { - Dimension listDim2 = list.getSize(); - visibleRows2 = listDim2.height / cellHeight; - } + int maxCellHeight2 = getCellHeight(0); + int visibleRows2 = list.getHeight() / maxCellHeight2; int numberOfItems2 = list.getModel().getSize(); int cellsPerRow2 = numberOfItems2 / visibleRows2 + 1; int gridX2 = Math.min(location.x / cellWidth, cellsPerRow2 - 1); - int gridY2 = Math.min(location.y / cellHeight, visibleRows2); + int gridY2 = Math.min(location.y / maxCellHeight2, visibleRows2); index = gridY2 + gridX2 * visibleRows2; break; } return index; } - public Point indexToLocation(JList list, int index) + public Point indexToLocation(JList l, int index) { int layoutOrientation = list.getLayoutOrientation(); Point loc = null; @@ -1238,40 +1235,31 @@ public class BasicListUI extends ListUI break; case JList.HORIZONTAL_WRAP: // determine visible rows and cells per row - int visibleRows = list.getVisibleRowCount(); + int maxCellHeight = getCellHeight(0); + int visibleRows = list.getHeight() / maxCellHeight; int numberOfCellsPerRow = -1; - if (visibleRows <= 0) - { - Dimension listDim = list.getSize(); - numberOfCellsPerRow = Math.max(listDim.width / cellWidth, 1); - } - else - { - int numberOfItems = list.getModel().getSize(); - numberOfCellsPerRow = numberOfItems / visibleRows + 1; - } + int numberOfItems = list.getModel().getSize(); + numberOfCellsPerRow = numberOfItems / visibleRows + 1; + // compute coordinates inside the grid int gridX = index % numberOfCellsPerRow; int gridY = index / numberOfCellsPerRow; int locX = gridX * cellWidth; - int locY = gridY * cellHeight; + int locY; + locY = gridY * maxCellHeight; loc = new Point(locX, locY); break; case JList.VERTICAL_WRAP: // determine visible rows and cells per column - int visibleRows2 = list.getVisibleRowCount(); - if (visibleRows2 <= 0) - { - Dimension listDim2 = list.getSize(); - visibleRows2 = listDim2.height / cellHeight; - } + int maxCellHeight2 = getCellHeight(0); + int visibleRows2 = list.getHeight() / maxCellHeight2; // compute coordinates inside the grid if (visibleRows2 > 0) { int gridY2 = index % visibleRows2; int gridX2 = index / visibleRows2; int locX2 = gridX2 * cellWidth; - int locY2 = gridY2 * cellHeight; + int locY2 = gridY2 * maxCellHeight2; loc = new Point(locX2, locY2); } else diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java index 13c78ad..f5217be 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -41,16 +41,26 @@ package javax.swing.plaf.basic; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.ResourceBundle; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; +import javax.swing.UIManager; import javax.swing.border.BevelBorder; import javax.swing.border.Border; import javax.swing.plaf.BorderUIResource; @@ -59,7 +69,6 @@ import javax.swing.plaf.DimensionUIResource; import javax.swing.plaf.FontUIResource; import javax.swing.plaf.IconUIResource; import javax.swing.plaf.InsetsUIResource; -import javax.swing.text.JTextComponent; /** * BasicLookAndFeel @@ -68,8 +77,68 @@ import javax.swing.text.JTextComponent; public abstract class BasicLookAndFeel extends LookAndFeel implements Serializable { + /** + * An action that can play an audio file. + * + * @author Roman Kennke (kennke@aicas.com) + */ + private class AudioAction extends AbstractAction + { + /** + * The UIDefaults key that specifies the sound. + */ + Object key; + + /** + * Creates a new AudioAction. + * + * @param key the key that describes the audio action, normally a filename + * of an audio file relative to the current package + */ + AudioAction(Object key) + { + this.key = key; + } + + /** + * Plays the sound represented by this action. + * + * @param event the action event that triggers this audio action + */ + public void actionPerformed(ActionEvent event) + { + // We only can handle strings for now. + if (key instanceof String) + { + String name = UIManager.getString(key); + InputStream stream = getClass().getResourceAsStream(name); + try + { + Clip clip = AudioSystem.getClip(); + AudioInputStream audioStream = + AudioSystem.getAudioInputStream(stream); + clip.open(audioStream); + } + catch (LineUnavailableException ex) + { + // Nothing we can do about it. + } + catch (IOException ex) + { + // Nothing we can do about it. + } + catch (UnsupportedAudioFileException e) + { + // Nothing we can do about it. + } + } + } + } + static final long serialVersionUID = -6096995660290287879L; + private ActionMap audioActionMap; + /** * Creates a new instance of the Basic look and feel. */ @@ -148,7 +217,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TextPaneUI", "javax.swing.plaf.basic.BasicTextPaneUI", "TextAreaUI", "javax.swing.plaf.basic.BasicTextAreaUI", "TextFieldUI", "javax.swing.plaf.basic.BasicTextFieldUI", - "TextPaneUI", "javax.swing.plaf.basic.BasicTextPaneUI", "ToggleButtonUI", "javax.swing.plaf.basic.BasicToggleButtonUI", "ToolBarSeparatorUI", "javax.swing.plaf.basic.BasicToolBarSeparatorUI", "ToolBarUI", "javax.swing.plaf.basic.BasicToolBarUI", @@ -265,12 +333,12 @@ public abstract class BasicLookAndFeel extends LookAndFeel } }, "Button.darkShadow", new ColorUIResource(Color.BLACK), - "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" - }), "Button.font", new FontUIResource("Dialog", Font.PLAIN, 12), "Button.foreground", new ColorUIResource(Color.BLACK), + "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" + }), "Button.highlight", new ColorUIResource(Color.WHITE), "Button.light", new ColorUIResource(Color.LIGHT_GRAY), "Button.margin", new InsetsUIResource(2, 14, 2, 14), @@ -281,8 +349,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel "CheckBox.border", new BorderUIResource.CompoundBorderUIResource(null, null), "CheckBox.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" }), "CheckBox.font", new FontUIResource("Dialog", Font.PLAIN, 12), "CheckBox.foreground", new ColorUIResource(darkShadow), @@ -342,12 +410,12 @@ public abstract class BasicLookAndFeel extends LookAndFeel "ColorChooser.okText", "OK", "ColorChooser.previewText", "Preview", "ColorChooser.resetText", "Reset", - "ColorChooser.rgbBlueMnemonic", new Integer(66), + "ColorChooser.rgbBlueMnemonic", "66", "ColorChooser.rgbBlueText", "Blue", - "ColorChooser.rgbGreenMnemonic", new Integer(71), + "ColorChooser.rgbGreenMnemonic", "78", "ColorChooser.rgbGreenText", "Green", "ColorChooser.rgbNameText", "RGB", - "ColorChooser.rgbRedMnemonic", new Integer(82), + "ColorChooser.rgbRedMnemonic", "68", "ColorChooser.rgbRedText", "Red", "ColorChooser.sampleText", "Sample Text Sample Text", "ColorChooser.swatchesDefaultRecentColor", new ColorUIResource(light), @@ -403,20 +471,63 @@ public abstract class BasicLookAndFeel extends LookAndFeel "EditorPane.font", new FontUIResource("Serif", Font.PLAIN, 12), "EditorPane.foreground", new ColorUIResource(Color.black), "EditorPane.inactiveForeground", new ColorUIResource(Color.gray), - "EditorPane.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, - 0), "caret-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, - 0), "caret-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, - 0), "page-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, - 0), "page-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), "insert-break"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, - 0), "insert-tab") - }, + "EditorPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("shift UP"), "selection-up", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift KP_UP"), "selection-up", + KeyStroke.getKeyStroke("DOWN"), "caret-down", + KeyStroke.getKeyStroke("shift ctrl T"), "previous-link-action", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift PAGE_UP"), "selection-page-up", + KeyStroke.getKeyStroke("KP_UP"), "caret-up", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ctrl HOME"), "caret-begin", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl END"), "caret-end", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("ctrl SPACE"), "activate-link-action", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ENTER"), "insert-break", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "selection-page-left", + KeyStroke.getKeyStroke("shift DOWN"), "selection-down", + KeyStroke.getKeyStroke("PAGE_DOWN"), "page-down", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "selection-page-right", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("KP_DOWN"), "caret-down", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("shift ctrl END"), "selection-end", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl T"), "next-link-action", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selection-down", + KeyStroke.getKeyStroke("TAB"), "insert-tab", + KeyStroke.getKeyStroke("UP"), "caret-up", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selection-begin", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "selection-page-down", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("PAGE_UP"), "page-up", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard" + }), "EditorPane.margin", new InsetsUIResource(3, 3, 3, 3), "EditorPane.selectionBackground", new ColorUIResource(Color.black), "EditorPane.selectionForeground", new ColorUIResource(Color.white), @@ -424,51 +535,74 @@ public abstract class BasicLookAndFeel extends LookAndFeel "FileChooser.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { "ESCAPE", "cancelSelection" }), - "FileChooser.cancelButtonMnemonic", new Integer(67), + "FileChooser.cancelButtonMnemonic", "67", "FileChooser.cancelButtonText", "Cancel", "FileChooser.cancelButtonToolTipText", "Abort file chooser dialog", - // XXX Don't use gif -// "FileChooser.detailsViewIcon", new IconUIResource(new ImageIcon("icons/DetailsView.gif")), "FileChooser.directoryDescriptionText", "Directory", "FileChooser.fileDescriptionText", "Generic File", - "FileChooser.helpButtonMnemonic", new Integer(72), + "FileChooser.directoryOpenButtonMnemonic", "79", + "FileChooser.helpButtonMnemonic", "72", "FileChooser.helpButtonText", "Help", "FileChooser.helpButtonToolTipText", "FileChooser help", - // XXX Don't use gif -// "FileChooser.homeFolderIcon", new IconUIResource(new ImageIcon("icons/HomeFolder.gif")), - // XXX Don't use gif -// "FileChooser.listViewIcon", new IconUIResource(new ImageIcon("icons/ListView.gif")), "FileChooser.newFolderErrorSeparator", ":", "FileChooser.newFolderErrorText", "Error creating new folder", - // XXX Don't use gif -// "FileChooser.newFolderIcon", new IconUIResource(new ImageIcon("icons/NewFolder.gif")), - "FileChooser.openButtonMnemonic", new Integer(79), + "FileChooser.openButtonMnemonic", "79", "FileChooser.openButtonText", "Open", "FileChooser.openButtonToolTipText", "Open selected file", - "FileChooser.saveButtonMnemonic", new Integer(83), + "FileChooser.saveButtonMnemonic", "83", "FileChooser.saveButtonText", "Save", "FileChooser.saveButtonToolTipText", "Save selected file", - // XXX Don't use gif -// "FileChooser.upFolderIcon", new IconUIResource(new ImageIcon("icons/UpFolder.gif")), - "FileChooser.updateButtonMnemonic", new Integer(85), + "FileChooser.updateButtonMnemonic", "85", "FileChooser.updateButtonText", "Update", "FileChooser.updateButtonToolTipText", "Update directory listing", - // XXX Don't use gif -// "FileView.computerIcon", new IconUIResource(new ImageIcon("icons/Computer.gif")), - // XXX Don't use gif -// "FileView.directoryIcon", new IconUIResource(new ImageIcon("icons/Directory.gif")), - // XXX Don't use gif -// "FileView.fileIcon", new IconUIResource(new ImageIcon("icons/File.gif")), - // XXX Don't use gif -// "FileView.floppyDriveIcon", new IconUIResource(new ImageIcon("icons/Floppy.gif")), - // XXX Don't use gif -// "FileView.hardDriveIcon", new IconUIResource(new ImageIcon("icons/HardDrive.gif")), "FocusManagerClassName", "TODO", "FormattedTextField.background", new ColorUIResource(light), "FormattedTextField.caretForeground", new ColorUIResource(Color.black), + "FormattedTextField.margin", new InsetsUIResource(0, 0, 0, 0), + "FormattedTextField.caretBlinkRate", new Integer(500), "FormattedTextField.font", new FontUIResource("SansSerif", Font.PLAIN, 12), "FormattedTextField.foreground", new ColorUIResource(Color.black), + "FormattedTextField.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("KP_UP"), "increment", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("KP_DOWN"), "decrement", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("UP"), "increment", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("ESCAPE"), "reset-field-edit", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("DOWN"), "decrement", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ENTER"), "notify-field-accept", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward" + }), "FormattedTextField.inactiveBackground", new ColorUIResource(light), "FormattedTextField.inactiveForeground", new ColorUIResource(Color.gray), "FormattedTextField.selectionBackground", @@ -504,7 +638,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel "InternalFrame.borderLight", new ColorUIResource(Color.LIGHT_GRAY), "InternalFrame.borderShadow", new ColorUIResource(Color.GRAY), "InternalFrame.closeIcon", BasicIconFactory.createEmptyFrameIcon(), - // FIXME: Set a nice icon for InternalFrames here. "InternalFrame.icon", new UIDefaults.LazyValue() { @@ -533,67 +666,67 @@ public abstract class BasicLookAndFeel extends LookAndFeel "List.background", new ColorUIResource(Color.white), "List.border", new BasicBorders.MarginBorder(), "List.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "ctrl DOWN", "selectNextRowChangeLead", - "shift UP", "selectPreviousRowExtendSelection", - "ctrl RIGHT", "selectNextColumnChangeLead", - "shift ctrl LEFT", "selectPreviousColumnExtendSelection", - "shift KP_UP", "selectPreviousRowChangeLead", - "DOWN", "selectNextRow", - "ctrl UP", "selectPreviousRowChangeLead", - "ctrl LEFT", "selectPreviousColumnChangeLead", - "CUT", "cut", - "END", "selectLastRow", - "shift PAGE_UP","scrollUpExtendSelection", - "KP_UP", "selectPreviousRow", - "shift ctrl UP", "selectPreviousRowExtendSelection", - "ctrl HOME", "selectFirstRowChangeLead", - "shift LEFT", "selectPreviousColumnExtendSelection", - "ctrl END", "selectLastRowChangeLead", - "ctrl PAGE_DOWN", "scrollDownChangeLead", - "shift ctrl RIGHT", "selectNextColumnExtendSelection", - "LEFT", "selectPreviousColumn", - "ctrl PAGE_UP", "scrollUpChangeLead", - "KP_LEFT", "selectPreviousColumn", - "shift KP_RIGHT", "selectNextColumnExtendSelection", - "SPACE", "addToSelection", - "ctrl SPACE", "toggleAndAnchor", - "shift SPACE", "extendTo", - "shift ctrl SPACE", "moveSelectionTo", - "shift ctrl DOWN", "selectNextRowExtendSelection", - "ctrl BACK_SLASH", "clearSelection", - "shift HOME", "selectFirstRowExtendSelection", - "RIGHT", "selectNextColumn", - "shift ctrl PAGE_UP", "scrollUpExtendSelection", - "shift DOWN", "selectNextRowExtendSelection", - "PAGE_DOWN", "scrollDown", - "shift ctrl KP_UP", "selectPreviousRowExtendSelection", - "shift KP_LEFT", "selectPreviousColumnExtendSelection", - "ctrl X", "cut", - "shift ctrl PAGE_DOWN", "scrollDownExtendSelection", - "ctrl SLASH", "selectAll", - "ctrl C", "copy", - "ctrl KP_RIGHT", "selectNextColumnChangeLead", - "shift END", "selectLastRowExtendSelection", - "shift ctrl KP_DOWN", "selectNextRowExtendSelection", - "ctrl KP_LEFT", "selectPreviousColumnChangeLead", - "HOME", "selectFirstRow", - "ctrl V", "paste", - "KP_DOWN", "selectNextRow", - "ctrl KP_DOWN", "selectNextRowChangeLead", - "shift RIGHT", "selectNextColumnExtendSelection", - "ctrl A", "selectAll", - "shift ctrl END", "selectLastRowExtendSelection", - "COPY", "copy", - "ctrl KP_UP", "selectPreviousRowChangeLead", - "shift ctrl KP_LEFT", "selectPreviousColumnExtendSelection", - "shift KP_DOWN", "selectNextRowExtendSelection", - "UP", "selectPreviousRow", - "shift ctrl HOME", "selectFirstRowExtendSelection", - "shift PAGE_DOWN", "scrollDownExtendSelection", - "KP_RIGHT", "selectNextColumn", - "shift ctrl KP_RIGHT", "selectNextColumnExtendSelection", - "PAGE_UP", "scrollUp", - "PASTE", "paste" + KeyStroke.getKeyStroke("ctrl DOWN"), "selectNextRowChangeLead", + KeyStroke.getKeyStroke("shift UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("ctrl RIGHT"), "selectNextColumnChangeLead", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("shift KP_UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("DOWN"), "selectNextRow", + KeyStroke.getKeyStroke("ctrl UP"), "selectPreviousRowChangeLead", + KeyStroke.getKeyStroke("ctrl LEFT"), "selectPreviousColumnChangeLead", + KeyStroke.getKeyStroke("CUT"), "cut", + KeyStroke.getKeyStroke("END"), "selectLastRow", + KeyStroke.getKeyStroke("shift PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("KP_UP"), "selectPreviousRow", + KeyStroke.getKeyStroke("shift ctrl UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("ctrl HOME"), "selectFirstRowChangeLead", + KeyStroke.getKeyStroke("shift LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("ctrl END"), "selectLastRowChangeLead", + KeyStroke.getKeyStroke("ctrl PAGE_DOWN"), "scrollDownChangeLead", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("LEFT"), "selectPreviousColumn", + KeyStroke.getKeyStroke("ctrl PAGE_UP"), "scrollUpChangeLead", + KeyStroke.getKeyStroke("KP_LEFT"), "selectPreviousColumn", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("SPACE"), "addToSelection", + KeyStroke.getKeyStroke("ctrl SPACE"), "toggleAndAnchor", + KeyStroke.getKeyStroke("shift SPACE"), "extendTo", + KeyStroke.getKeyStroke("shift ctrl SPACE"), "moveSelectionTo", + KeyStroke.getKeyStroke("shift ctrl DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "clearSelection", + KeyStroke.getKeyStroke("shift HOME"), "selectFirstRowExtendSelection", + KeyStroke.getKeyStroke("RIGHT"), "selectNextColumn", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("shift DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("PAGE_DOWN"), "scrollDown", + KeyStroke.getKeyStroke("shift ctrl KP_UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("ctrl X"), "cut", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("ctrl SLASH"), "selectAll", + KeyStroke.getKeyStroke("ctrl C"), "copy", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "selectNextColumnChangeLead", + KeyStroke.getKeyStroke("shift END"), "selectLastRowExtendSelection", + KeyStroke.getKeyStroke("shift ctrl KP_DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "selectPreviousColumnChangeLead", + KeyStroke.getKeyStroke("HOME"), "selectFirstRow", + KeyStroke.getKeyStroke("ctrl V"), "paste", + KeyStroke.getKeyStroke("KP_DOWN"), "selectNextRow", + KeyStroke.getKeyStroke("ctrl KP_DOWN"), "selectNextRowChangeLead", + KeyStroke.getKeyStroke("shift RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("ctrl A"), "selectAll", + KeyStroke.getKeyStroke("shift ctrl END"), "selectLastRowExtendSelection", + KeyStroke.getKeyStroke("COPY"), "copy", + KeyStroke.getKeyStroke("ctrl KP_UP"), "selectPreviousRowChangeLead", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("UP"), "selectPreviousRow", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selectFirstRowExtendSelection", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("KP_RIGHT"), "selectNextColumn", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("PAGE_UP"), "scrollUp", + KeyStroke.getKeyStroke("PASTE"), "paste" }), "List.font", new FontUIResource("Dialog", Font.PLAIN, 12), "List.foreground", new ColorUIResource(Color.black), @@ -603,6 +736,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel new BorderUIResource. LineBorderUIResource(new ColorUIResource(Color.yellow)), "Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12), + "Menu.crossMenuMnemonic", Boolean.TRUE, "Menu.acceleratorForeground", new ColorUIResource(darkShadow), "Menu.acceleratorSelectionForeground", new ColorUIResource(Color.white), "Menu.arrowIcon", BasicIconFactory.getMenuArrowIcon(), @@ -627,6 +761,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel "ENTER", "return", "SPACE", "return" }, + "Menu.menuPopupOffsetX", new Integer(0), + "Menu.menuPopupOffsetY", new Integer(0), + "Menu.submenuPopupOffsetX", new Integer(0), + "Menu.submenuPopupOffsetY", new Integer(0), "Menu.selectionBackground", new ColorUIResource(Color.black), "Menu.selectionForeground", new ColorUIResource(Color.white), "MenuBar.background", new ColorUIResource(light), @@ -638,7 +776,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel "MenuBar.windowBindings", new Object[] { "F10", "takeFocus" }, - "MenuItem.acceleratorDelimiter", "-", + "MenuItem.acceleratorDelimiter", "+", "MenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12), "MenuItem.acceleratorForeground", new ColorUIResource(darkShadow), "MenuItem.acceleratorSelectionForeground", @@ -657,15 +795,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0), "OptionPane.buttonAreaBorder", new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0), + "OptionPane.buttonClickThreshhold", new Integer(500), "OptionPane.cancelButtonText", "Cancel", - // XXX Don't use gif -// "OptionPane.errorIcon", -// new IconUIResource(new ImageIcon("icons/Error.gif")), "OptionPane.font", new FontUIResource("Dialog", Font.PLAIN, 12), "OptionPane.foreground", new ColorUIResource(darkShadow), - // XXX Don't use gif -// "OptionPane.informationIcon", -// new IconUIResource(new ImageIcon("icons/Inform.gif")), "OptionPane.messageAreaBorder", new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0), "OptionPane.messageForeground", new ColorUIResource(darkShadow), @@ -674,12 +807,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel BasicOptionPaneUI.MinimumHeight), "OptionPane.noButtonText", "No", "OptionPane.okButtonText", "OK", - // XXX Don't use gif -// "OptionPane.questionIcon", -// new IconUIResource(new ImageIcon("icons/Question.gif")), - // XXX Don't use gif -// "OptionPane.warningIcon", -// new IconUIResource(new ImageIcon("icons/Warn.gif")), "OptionPane.windowBindings", new Object[] { "ESCAPE", "close" }, @@ -692,14 +819,45 @@ public abstract class BasicLookAndFeel extends LookAndFeel null, null), "PasswordField.caretBlinkRate", new Integer(500), "PasswordField.caretForeground", new ColorUIResource(Color.black), - "PasswordField.font", new FontUIResource("Dialog", Font.PLAIN, 12), + "PasswordField.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12), "PasswordField.foreground", new ColorUIResource(Color.black), "PasswordField.inactiveBackground", new ColorUIResource(light), "PasswordField.inactiveForeground", new ColorUIResource(Color.gray), - "PasswordField.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), - "notify-field-accept")}, + "PasswordField.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-end-line", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-begin-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-end-line", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-begin-line", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-begin-line", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-end-line", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ENTER"), "notify-field-accept", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward" + }), "PasswordField.margin", new InsetsUIResource(0, 0, 0, 0), "PasswordField.selectionBackground", new ColorUIResource(Color.black), "PasswordField.selectionForeground", new ColorUIResource(Color.white), @@ -723,8 +881,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel null), "RadioButton.darkShadow", new ColorUIResource(shadow), "RadioButton.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" }), "RadioButton.font", new FontUIResource("Dialog", Font.PLAIN, 12), "RadioButton.foreground", new ColorUIResource(darkShadow), @@ -818,18 +976,20 @@ public abstract class BasicLookAndFeel extends LookAndFeel "Slider.background", new ColorUIResource(light), "Slider.focus", new ColorUIResource(shadow), "Slider.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "PAGE_UP", "positiveBlockIncrement", - "PAGE_DOWN", "negativeBlockIncrement", - "END", "maxScroll", - "HOME", "minScroll", - "LEFT", "negativeUnitIncrement", - "KP_UP", "positiveUnitIncrement", - "KP_DOWN", "negativeUnitIncrement", - "UP", "positiveUnitIncrement", - "RIGHT", "positiveUnitIncrement", - "KP_LEFT", "negativeUnitIncrement", - "DOWN", "negativeUnitIncrement", - "KP_RIGHT", "positiveUnitIncrement" + "ctrl PAGE_DOWN", "negativeBlockIncrement", + "PAGE_DOWN", "negativeBlockIncrement", + "PAGE_UP", "positiveBlockIncrement", + "ctrl PAGE_UP", "positiveBlockIncrement", + "KP_RIGHT", "positiveUnitIncrement", + "DOWN", "negativeUnitIncrement", + "KP_LEFT", "negativeUnitIncrement", + "RIGHT", "positiveUnitIncrement", + "KP_DOWN", "negativeUnitIncrement", + "UP", "positiveUnitIncrement", + "KP_UP", "positiveUnitIncrement", + "LEFT", "negativeUnitIncrement", + "HOME", "minScroll", + "END", "maxScroll" }), "Slider.focusInsets", new InsetsUIResource(2, 2, 2, 2), "Slider.foreground", new ColorUIResource(light), @@ -840,6 +1000,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel "Slider.tickHeight", new Integer(12), "Spinner.background", new ColorUIResource(light), "Spinner.foreground", new ColorUIResource(light), + "Spinner.arrowButtonSize", new DimensionUIResource(16, 5), + "Spinner.editorBorderPainted", Boolean.FALSE, + "Spinner.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12), "SplitPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { "F6", "toggleFocus", "F8", "startResize", @@ -857,7 +1020,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel "SplitPane.background", new ColorUIResource(light), "SplitPane.border", new BasicBorders.SplitPaneBorder(null, null), "SplitPane.darkShadow", new ColorUIResource(shadow), - "SplitPane.dividerSize", new Integer(10), + "SplitPane.dividerSize", new Integer(7), "SplitPane.highlight", new ColorUIResource(highLight), "SplitPane.shadow", new ColorUIResource(shadow), "TabbedPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { @@ -871,16 +1034,16 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TabbedPane.darkShadow", new ColorUIResource(shadow), "TabbedPane.focus", new ColorUIResource(darkShadow), "TabbedPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "LEFT", "navigateLeft", - "KP_UP", "navigateUp", - "ctrl DOWN", "requestFocusForVisibleComponent", - "UP", "navigateUp", - "KP_DOWN", "navigateDown", - "RIGHT", "navigateRight", - "KP_LEFT", "navigateLeft", - "ctrl KP_DOWN", "requestFocusForVisibleComponent", - "KP_RIGHT", "navigateRight", - "DOWN", "navigateDown" + KeyStroke.getKeyStroke("ctrl DOWN"), "requestFocusForVisibleComponent", + KeyStroke.getKeyStroke("KP_UP"), "navigateUp", + KeyStroke.getKeyStroke("LEFT"), "navigateLeft", + KeyStroke.getKeyStroke("ctrl KP_DOWN"), "requestFocusForVisibleComponent", + KeyStroke.getKeyStroke("UP"), "navigateUp", + KeyStroke.getKeyStroke("KP_DOWN"), "navigateDown", + KeyStroke.getKeyStroke("KP_LEFT"), "navigateLeft", + KeyStroke.getKeyStroke("RIGHT"), "navigateRight", + KeyStroke.getKeyStroke("KP_RIGHT"), "navigateRight", + KeyStroke.getKeyStroke("DOWN"), "navigateDown" }), "TabbedPane.font", new FontUIResource("Dialog", Font.PLAIN, 12), "TabbedPane.foreground", new ColorUIResource(darkShadow), @@ -888,10 +1051,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TabbedPane.light", new ColorUIResource(highLight), "TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 2, 1), "TabbedPane.shadow", new ColorUIResource(shadow), - "TabbedPane.tabbedPaneTabAreaInsets", new InsetsUIResource(3, 2, 1, 2), - "TabbedPane.tabbedPaneTabInsets", new InsetsUIResource(1, 4, 1, 4), "TabbedPane.tabbedPaneContentBorderInsets", new InsetsUIResource(3, 2, 1, 2), "TabbedPane.tabbedPaneTabPadInsets", new InsetsUIResource(1, 1, 1, 1), + "TabbedPane.tabAreaInsets", new InsetsUIResource(3, 2, 0, 2), + "TabbedPane.tabInsets", new InsetsUIResource(0, 4, 1, 4), "TabbedPane.tabRunOverlay", new Integer(2), "TabbedPane.textIconGap", new Integer(4), "Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { @@ -976,32 +1139,73 @@ public abstract class BasicLookAndFeel extends LookAndFeel "Table.selectionBackground", new ColorUIResource(new ColorUIResource(0, 0, 128)), "Table.selectionForeground", new ColorUIResource(new ColorUIResource(255, 255, 255)), "TableHeader.background", new ColorUIResource(new ColorUIResource(192, 192, 192)), - "TableHeader.cellBorder", new BorderUIResource.BevelBorderUIResource(0), "TableHeader.font", new FontUIResource("Dialog", Font.PLAIN, 12), "TableHeader.foreground", new ColorUIResource(new ColorUIResource(0, 0, 0)), - "TextArea.background", new ColorUIResource(light), - "TextArea.border", - new BorderUIResource(BasicBorders.getMarginBorder()), + "TextArea.background", new ColorUIResource(light), + "TextArea.border", new BorderUIResource(BasicBorders.getMarginBorder()), "TextArea.caretBlinkRate", new Integer(500), "TextArea.caretForeground", new ColorUIResource(Color.black), "TextArea.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12), "TextArea.foreground", new ColorUIResource(Color.black), "TextArea.inactiveForeground", new ColorUIResource(Color.gray), - "TextArea.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, - 0), "caret-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, - 0), "caret-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, - 0), "page-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, - 0), "page-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), "insert-break"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, - 0), "insert-tab") - }, + "TextArea.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("shift UP"), "selection-up", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift KP_UP"), "selection-up", + KeyStroke.getKeyStroke("DOWN"), "caret-down", + KeyStroke.getKeyStroke("shift ctrl T"), "previous-link-action", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift PAGE_UP"), "selection-page-up", + KeyStroke.getKeyStroke("KP_UP"), "caret-up", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ctrl HOME"), "caret-begin", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl END"), "caret-end", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("ctrl SPACE"), "activate-link-action", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ENTER"), "insert-break", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "selection-page-left", + KeyStroke.getKeyStroke("shift DOWN"), "selection-down", + KeyStroke.getKeyStroke("PAGE_DOWN"), "page-down", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "selection-page-right", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("KP_DOWN"), "caret-down", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("shift ctrl END"), "selection-end", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl T"), "next-link-action", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selection-down", + KeyStroke.getKeyStroke("TAB"), "insert-tab", + KeyStroke.getKeyStroke("UP"), "caret-up", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selection-begin", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "selection-page-down", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("PAGE_UP"), "page-up", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard" + }), "TextArea.margin", new InsetsUIResource(0, 0, 0, 0), "TextArea.selectionBackground", new ColorUIResource(Color.black), "TextArea.selectionForeground", new ColorUIResource(Color.white), @@ -1017,17 +1221,41 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TextField.inactiveForeground", new ColorUIResource(Color.GRAY), "TextField.light", new ColorUIResource(highLight), "TextField.highlight", new ColorUIResource(light), - "TextField.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), - "notify-field-accept"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, - InputEvent.SHIFT_DOWN_MASK), - "selection-backward"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, - InputEvent.SHIFT_DOWN_MASK), - "selection-forward"), - }, + "TextField.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("ENTER"), "notify-field-accept", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word" + }), "TextField.margin", new InsetsUIResource(0, 0, 0, 0), "TextField.selectionBackground", new ColorUIResource(Color.black), "TextField.selectionForeground", new ColorUIResource(Color.white), @@ -1038,20 +1266,63 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TextPane.font", new FontUIResource("Serif", Font.PLAIN, 12), "TextPane.foreground", new ColorUIResource(Color.black), "TextPane.inactiveForeground", new ColorUIResource(Color.gray), - "TextPane.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, - 0), "caret-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, - 0), "caret-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, - 0), "page-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, - 0), "page-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), "insert-break"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, - 0), "insert-tab") - }, + "TextPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("shift UP"), "selection-up", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift KP_UP"), "selection-up", + KeyStroke.getKeyStroke("DOWN"), "caret-down", + KeyStroke.getKeyStroke("shift ctrl T"), "previous-link-action", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift PAGE_UP"), "selection-page-up", + KeyStroke.getKeyStroke("KP_UP"), "caret-up", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ctrl HOME"), "caret-begin", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl END"), "caret-end", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("ctrl SPACE"), "activate-link-action", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ENTER"), "insert-break", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "selection-page-left", + KeyStroke.getKeyStroke("shift DOWN"), "selection-down", + KeyStroke.getKeyStroke("PAGE_DOWN"), "page-down", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "selection-page-right", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("KP_DOWN"), "caret-down", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("shift ctrl END"), "selection-end", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl T"), "next-link-action", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selection-down", + KeyStroke.getKeyStroke("TAB"), "insert-tab", + KeyStroke.getKeyStroke("UP"), "caret-up", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selection-begin", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "selection-page-down", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("PAGE_UP"), "page-up", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard" + }), "TextPane.margin", new InsetsUIResource(3, 3, 3, 3), "TextPane.selectionBackground", new ColorUIResource(Color.black), "TextPane.selectionForeground", new ColorUIResource(Color.white), @@ -1063,8 +1334,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel new BorderUIResource.CompoundBorderUIResource(null, null), "ToggleButton.darkShadow", new ColorUIResource(shadow), "ToggleButton.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" }), "ToggleButton.font", new FontUIResource("Dialog", Font.PLAIN, 12), "ToggleButton.foreground", new ColorUIResource(darkShadow), @@ -1095,7 +1366,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel "ToolBar.foreground", new ColorUIResource(darkShadow), "ToolBar.highlight", new ColorUIResource(highLight), "ToolBar.light", new ColorUIResource(highLight), - "ToolBar.separatorSize", new DimensionUIResource(20, 20), + "ToolBar.separatorSize", new DimensionUIResource(10, 10), "ToolBar.shadow", new ColorUIResource(shadow), "ToolTip.background", new ColorUIResource(light), "ToolTip.border", new BorderUIResource.LineBorderUIResource(Color.lightGray), @@ -1106,72 +1377,147 @@ public abstract class BasicLookAndFeel extends LookAndFeel }), "Tree.background", new ColorUIResource(new Color(255, 255, 255)), "Tree.changeSelectionWithFocus", Boolean.TRUE, -// "Tree.closedIcon", new IconUIResource(new ImageIcon("icons/TreeClosed.png")), -// "Tree.collapsedIcon", new IconUIResource(new ImageIcon("icons/TreeCollapsed.png")), "Tree.drawsFocusBorderAroundIcon", Boolean.FALSE, "Tree.editorBorder", new BorderUIResource.LineBorderUIResource(Color.lightGray), "Tree.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "shift PAGE_DOWN", "scrollDownExtendSelection", - "PAGE_DOWN", "scrollDownChangeSelection", - "END", "selectLast", - "ctrl KP_UP", "selectPreviousChangeLead", - "shift END", "selectLastExtendSelection", - "HOME", "selectFirst", - "ctrl END", "selectLastChangeLead", - "ctrl SLASH", "selectAll", - "LEFT", "selectParent", - "shift HOME", "selectFirstExtendSelection", - "UP", "selectPrevious", - "ctrl KP_DOWN", "selectNextChangeLead", - "RIGHT", "selectChild", - "ctrl HOME", "selectFirstChangeLead", - "DOWN", "selectNext", - "ctrl KP_LEFT", "scrollLeft", - "shift UP", "selectPreviousExtendSelection", - "F2", "startEditing", - "ctrl LEFT", "scrollLeft", - "ctrl KP_RIGHT","scrollRight", - "ctrl UP", "selectPreviousChangeLead", - "shift DOWN", "selectNextExtendSelection", - "ENTER", "toggle", - "KP_UP", "selectPrevious", - "KP_DOWN", "selectNext", - "ctrl RIGHT", "scrollRight", - "KP_LEFT", "selectParent", - "KP_RIGHT", "selectChild", - "ctrl DOWN", "selectNextChangeLead", - "ctrl A", "selectAll", - "shift KP_UP", "selectPreviousExtendSelection", - "shift KP_DOWN","selectNextExtendSelection", - "ctrl SPACE", "toggleSelectionPreserveAnchor", - "ctrl shift PAGE_UP", "scrollUpExtendSelection", - "ctrl BACK_SLASH", "clearSelection", - "shift SPACE", "extendSelection", - "ctrl PAGE_UP", "scrollUpChangeLead", - "shift PAGE_UP","scrollUpExtendSelection", - "SPACE", "toggleSelectionPreserveAnchor", - "ctrl shift PAGE_DOWN", "scrollDownExtendSelection", - "PAGE_UP", "scrollUpChangeSelection", - "ctrl PAGE_DOWN", "scrollDownChangeLead" + KeyStroke.getKeyStroke("ctrl DOWN"), "selectNextChangeLead", + KeyStroke.getKeyStroke("shift UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("ctrl RIGHT"), "scrollRight", + KeyStroke.getKeyStroke("shift KP_UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("DOWN"), "selectNext", + KeyStroke.getKeyStroke("ctrl UP"), "selectPreviousChangeLead", + KeyStroke.getKeyStroke("ctrl LEFT"), "scrollLeft", + KeyStroke.getKeyStroke("CUT"), "cut", + KeyStroke.getKeyStroke("END"), "selectLast", + KeyStroke.getKeyStroke("shift PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("KP_UP"), "selectPrevious", + KeyStroke.getKeyStroke("shift ctrl UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("ctrl HOME"), "selectFirstChangeLead", + KeyStroke.getKeyStroke("ctrl END"), "selectLastChangeLead", + KeyStroke.getKeyStroke("ctrl PAGE_DOWN"), "scrollDownChangeLead", + KeyStroke.getKeyStroke("LEFT"), "selectParent", + KeyStroke.getKeyStroke("ctrl PAGE_UP"), "scrollUpChangeLead", + KeyStroke.getKeyStroke("KP_LEFT"), "selectParent", + KeyStroke.getKeyStroke("SPACE"), "addToSelection", + KeyStroke.getKeyStroke("ctrl SPACE"), "toggleAndAnchor", + KeyStroke.getKeyStroke("shift SPACE"), "extendTo", + KeyStroke.getKeyStroke("shift ctrl SPACE"), "moveSelectionTo", + KeyStroke.getKeyStroke("ADD"), "expand", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "clearSelection", + KeyStroke.getKeyStroke("shift ctrl DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("shift HOME"), "selectFirstExtendSelection", + KeyStroke.getKeyStroke("RIGHT"), "selectChild", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("shift DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("PAGE_DOWN"), "scrollDownChangeSelection", + KeyStroke.getKeyStroke("shift ctrl KP_UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("SUBTRACT"), "collapse", + KeyStroke.getKeyStroke("ctrl X"), "cut", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("ctrl SLASH"), "selectAll", + KeyStroke.getKeyStroke("ctrl C"), "copy", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "scrollRight", + KeyStroke.getKeyStroke("shift END"), "selectLastExtendSelection", + KeyStroke.getKeyStroke("shift ctrl KP_DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "scrollLeft", + KeyStroke.getKeyStroke("HOME"), "selectFirst", + KeyStroke.getKeyStroke("ctrl V"), "paste", + KeyStroke.getKeyStroke("KP_DOWN"), "selectNext", + KeyStroke.getKeyStroke("ctrl A"), "selectAll", + KeyStroke.getKeyStroke("ctrl KP_DOWN"), "selectNextChangeLead", + KeyStroke.getKeyStroke("shift ctrl END"), "selectLastExtendSelection", + KeyStroke.getKeyStroke("COPY"), "copy", + KeyStroke.getKeyStroke("ctrl KP_UP"), "selectPreviousChangeLead", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("UP"), "selectPrevious", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selectFirstExtendSelection", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("KP_RIGHT"), "selectChild", + KeyStroke.getKeyStroke("F2"), "startEditing", + KeyStroke.getKeyStroke("PAGE_UP"), "scrollUpChangeSelection", + KeyStroke.getKeyStroke("PASTE"), "paste" }), "Tree.font", new FontUIResource("Dialog", Font.PLAIN, 12), "Tree.foreground", new ColorUIResource(Color.black), "Tree.hash", new ColorUIResource(new Color(128, 128, 128)), "Tree.leftChildIndent", new Integer(7), "Tree.rightChildIndent", new Integer(13), - "Tree.rowHeight", new Integer(0), + "Tree.rowHeight", new Integer(16), "Tree.scrollsOnExpand", Boolean.TRUE, "Tree.selectionBackground", new ColorUIResource(Color.black), "Tree.nonSelectionBackground", new ColorUIResource(new Color(255, 255, 255)), "Tree.selectionBorderColor", new ColorUIResource(Color.black), "Tree.selectionBorder", new BorderUIResource.LineBorderUIResource(Color.black), "Tree.selectionForeground", new ColorUIResource(new Color(255, 255, 255)), - "Tree.textBackground", new ColorUIResource(new Color(192, 192, 192)), - "Tree.textForeground", new ColorUIResource(new Color(0, 0, 0)), "Viewport.background", new ColorUIResource(light), "Viewport.foreground", new ColorUIResource(Color.black), "Viewport.font", new FontUIResource("Dialog", Font.PLAIN, 12) }; defaults.putDefaults(uiDefaults); } -} // class BasicLookAndFeel + + /** + * Returns the <code>ActionMap</code> that stores all the actions that are + * responsibly for rendering auditory cues. + * + * @return the action map that stores all the actions that are + * responsibly for rendering auditory cues + * + * @see #createAudioAction + * @see #playSound + * + * @since 1.4 + */ + protected ActionMap getAudioActionMap() + { + if (audioActionMap != null) + audioActionMap = new ActionMap(); + return audioActionMap; + } + + /** + * Creates an <code>Action</code> that can play an auditory cue specified by + * the key. The UIDefaults value for the key is normally a String that points + * to an audio file relative to the current package. + * + * @param key a UIDefaults key that specifies the sound + * + * @return an action that can play the sound + * + * @see #playSound + * + * @since 1.4 + */ + protected Action createAudioAction(Object key) + { + return new AudioAction(key); + } + + /** + * Plays the sound of the action if it is listed in + * <code>AuditoryCues.playList</code>. + * + * @param audioAction the audio action to play + * + * @since 1.4 + */ + protected void playSound(Action audioAction) + { + if (audioAction instanceof AudioAction) + { + Object[] playList = (Object[]) UIManager.get("AuditoryCues.playList"); + for (int i = 0; i < playList.length; ++i) + { + if (playList[i].equals(((AudioAction) audioAction).key)) + { + ActionEvent ev = new ActionEvent(this, + ActionEvent.ACTION_PERFORMED, + (String) playList[i]); + audioAction.actionPerformed(ev); + break; + } + } + } + } + +} diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java index c8754a3..63f0ce2 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -206,7 +206,10 @@ public class BasicMenuItemUI extends MenuItemUI map.remove((KeyStroke)e.getOldValue()); else map = new ComponentInputMapUIResource(menuItem); - map.put((KeyStroke)e.getNewValue(), "doClick"); + + KeyStroke accelerator = (KeyStroke) e.getNewValue(); + if (accelerator != null) + map.put(accelerator, "doClick"); } } } @@ -485,7 +488,9 @@ public class BasicMenuItemUI extends MenuItemUI InputMap focusedWindowMap = SwingUtilities.getUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW); if (focusedWindowMap == null) focusedWindowMap = new ComponentInputMapUIResource(menuItem); - focusedWindowMap.put(menuItem.getAccelerator(), "doClick"); + KeyStroke accelerator = menuItem.getAccelerator(); + if (accelerator != null) + focusedWindowMap.put(accelerator, "doClick"); SwingUtilities.replaceUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW, focusedWindowMap); ActionMap UIActionMap = SwingUtilities.getUIActionMap(menuItem); @@ -555,17 +560,16 @@ public class BasicMenuItemUI extends MenuItemUI // Menu item is considered to be highlighted when it is selected. // But we don't want to paint the background of JCheckBoxMenuItems ButtonModel mod = menuItem.getModel(); - if ((menuItem.isSelected() && checkIcon == null) || (mod != null && - mod.isArmed()) - && (menuItem.getParent() instanceof MenuElement)) + if (menuItem.isContentAreaFilled()) { - if (menuItem.isContentAreaFilled()) - { - g.setColor(selectionBackground); - g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight()); - } - } - + if ((menuItem.isSelected() && checkIcon == null) || (mod != null && + mod.isArmed()) + && (menuItem.getParent() instanceof MenuElement)) + g.setColor(selectionBackground); + else + g.setColor(bgColor); + g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight()); + } } /** @@ -608,7 +612,7 @@ public class BasicMenuItemUI extends MenuItemUI FontMetrics fm = g.getFontMetrics(f); SwingUtilities.calculateInnerArea(m, br); SwingUtilities.calculateInsetArea(br, m.getInsets(), vr); - paintBackground(g, m, m.getBackground()); + paintBackground(g, m, background); /* * MenuItems insets are equal to menuItems margin, space between text and diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java index 6b37d31..005a3b3 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -774,7 +774,7 @@ public class BasicOptionPaneUI extends OptionPaneUI // it will create a box and burst the string. // otherwise, it will just create a label and re-call // this method with the label o.O - if (msg.toString().length() > maxll) + if (msg.toString().length() > maxll || msg.toString().contains("\n")) { Box tmp = new Box(BoxLayout.Y_AXIS); burstStringInto(tmp, msg.toString(), maxll); @@ -796,17 +796,35 @@ public class BasicOptionPaneUI extends OptionPaneUI */ protected void burstStringInto(Container c, String d, int maxll) { - // FIXME: Verify that this is the correct behaviour. - // One interpretation of the spec is that this method - // should recursively call itself to create (and add) - // JLabels to the container if the length of the String d - // is greater than maxll. - // but in practice, even with a really long string, this is - // all that happens. if (d == null || c == null) return; - JLabel label = new JLabel(d); + + int newlineIndex = d.indexOf('\n'); + String line; + String remainder; + if (newlineIndex >= 0 && newlineIndex < maxll) + { + line = d.substring(0, newlineIndex); + remainder = d.substring(newlineIndex + 1); + } + else + { + line = d.substring(0, maxll); + remainder = d.substring(maxll); + } + JLabel label = new JLabel(line); c.add(label); + + // If there is nothing left to burst, then we can stop. + if (remainder.length() == 0) + return; + + // Recursivly call ourselves to burst the remainder of the string, + if ((remainder.length() > maxll || remainder.contains("\n"))) + burstStringInto(c, remainder, maxll); + else + // Add the remainder to the container and be done. + c.add(new JLabel(remainder)); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java index 808ed27..71671b7 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java @@ -505,7 +505,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI JViewport oldViewport = (JViewport) ev.getOldValue(); oldViewport.removeChangeListener(viewportChangeListener); JViewport newViewport = (JViewport) ev.getNewValue(); - oldViewport.addChangeListener(viewportChangeListener); + newViewport.addChangeListener(viewportChangeListener); + syncScrollPaneWithViewport(); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java index 69ed2be..ff17ff0 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java @@ -376,6 +376,11 @@ public class BasicSplitPaneDivider extends Container dividerSize = getSize(); border.paintBorder(this, g, 0, 0, dividerSize.width, dividerSize.height); } + if (splitPane.isOneTouchExpandable()) + { + ((BasicArrowButton) rightButton).paint(g); + ((BasicArrowButton) leftButton).paint(g); + } } /** @@ -583,7 +588,7 @@ public class BasicSplitPaneDivider extends Container public void mouseReleased(MouseEvent e) { if (isDragging) - dragger.completeDrag(e); + dragger.completeDrag(e); isDragging = false; } @@ -596,7 +601,7 @@ public class BasicSplitPaneDivider extends Container public void mouseDragged(MouseEvent e) { if (dragger != null) - dragger.continueDrag(e); + dragger.continueDrag(e); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java index ce9ea3e..a8f52ce 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -208,7 +208,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants incrButton = createIncreaseButton(); decrButton = createDecreaseButton(); } - tabPane.layout(); + tabPane.revalidate(); tabPane.repaint(); } } @@ -241,6 +241,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ public void calculateLayoutInfo() { + assureRectsCreated(tabPane.getTabCount()); + contentRect = SwingUtilities.calculateInnerArea(tabPane, contentRect); + calculateTabRects(tabPane.getTabPlacement(), tabPane.getTabCount()); if (tabPane.getSelectedIndex() != -1) @@ -286,8 +289,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants componentWidth = Math.max(componentWidth, dims.width); } } - Insets insets = tabPane.getInsets(); - if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) { @@ -331,7 +332,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { if (tabCount == 0) return; - assureRectsCreated(tabCount); FontMetrics fm = getFontMetrics(); SwingUtilities.calculateInnerArea(tabPane, calcRect); @@ -944,13 +944,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { if (tabCount == 0) return; - assureRectsCreated(tabCount); FontMetrics fm = getFontMetrics(); SwingUtilities.calculateInnerArea(tabPane, calcRect); Insets tabAreaInsets = getTabAreaInsets(tabPlacement); Insets insets = tabPane.getInsets(); - int max = 0; int runs = 1; int start = 0; int top = 0; @@ -959,7 +957,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { int maxHeight = calculateMaxTabHeight(tabPlacement); calcRect.width -= tabAreaInsets.left + tabAreaInsets.right; - max = calcRect.width + tabAreaInsets.left + insets.left; start = tabAreaInsets.left + insets.left; int width = 0; int runWidth = start; @@ -996,7 +993,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants int maxWidth = calculateMaxTabWidth(tabPlacement); calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom; - max = calcRect.height + tabAreaInsets.top; int height = 0; start = tabAreaInsets.top + insets.top; int runHeight = start; @@ -1048,8 +1044,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants if (tabCount == 0) return; int tabPlacement = tabPane.getTabPlacement(); - incrButton.hide(); - decrButton.hide(); + incrButton.setVisible(false); + decrButton.setVisible(false); if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) { @@ -1068,8 +1064,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants decrDims.width, tabAreaRect.height); tabAreaRect.width -= decrDims.width + incrDims.width; - incrButton.show(); - decrButton.show(); + incrButton.setVisible(true); + decrButton.setVisible(true); } } @@ -1092,8 +1088,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants incrDims.height); tabAreaRect.height -= decrDims.height + incrDims.height; - incrButton.show(); - decrButton.show(); + incrButton.setVisible(true); + decrButton.setVisible(true); } } viewport.setBounds(tabAreaRect.x, tabAreaRect.y, tabAreaRect.width, @@ -1348,6 +1344,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants public BasicTabbedPaneUI() { super(); + rects = new Rectangle[0]; + tabRuns = new int[10]; } /** @@ -1460,7 +1458,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants layoutManager = createLayoutManager(); tabPane.setLayout(layoutManager); - tabPane.layout(); } } @@ -1552,9 +1549,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants textIconGap = UIManager.getInt("TabbedPane.textIconGap"); tabRunOverlay = UIManager.getInt("TabbedPane.tabRunOverlay"); - tabInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabInsets"); + tabInsets = UIManager.getInsets("TabbedPane.tabInsets"); selectedTabPadInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabPadInsets"); - tabAreaInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabAreaInsets"); + tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets"); contentBorderInsets = UIManager.getInsets("TabbedPane.tabbedPaneContentBorderInsets"); calcRect = new Rectangle(); @@ -1884,7 +1881,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants protected void paintIcon(Graphics g, int tabPlacement, int tabIndex, Icon icon, Rectangle iconRect, boolean isSelected) { - icon.paintIcon(tabPane, g, iconRect.x, iconRect.y); + if (icon != null) + icon.paintIcon(tabPane, g, iconRect.x, iconRect.y); } /** @@ -2110,7 +2108,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) { - Insets insets = getContentBorderInsets(tabPlacement); int x = contentRect.x; int y = contentRect.y; int w = contentRect.width; @@ -2396,16 +2393,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ protected void assureRectsCreated(int tabCount) { - if (rects == null) - rects = new Rectangle[tabCount]; - if (tabCount == rects.length) - return; - else + if (rects.length < tabCount) { - int numToCopy = Math.min(tabCount, rects.length); - Rectangle[] tmp = new Rectangle[tabCount]; - System.arraycopy(rects, 0, tmp, 0, numToCopy); - rects = tmp; + Rectangle[] old = rects; + rects = new Rectangle[tabCount]; + System.arraycopy(old, 0, rects, 0, old.length); + for (int i = old.length; i < rects.length; i++) + rects[i] = new Rectangle(); } } @@ -2763,7 +2757,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ protected FontMetrics getFontMetrics() { - FontMetrics fm = tabPane.getToolkit().getFontMetrics(tabPane.getFont()); + FontMetrics fm = tabPane.getFontMetrics(tabPane.getFont()); return fm; } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java index ec0467a..9c8a5ef 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java @@ -139,6 +139,7 @@ public class BasicTableHeaderUI extends TableHeaderUI public void installUI(JComponent c) { header = (JTableHeader) c; + rendererPane = new CellRendererPane(); installDefaults(); installKeyboardActions(); installListeners(); @@ -194,18 +195,15 @@ public class BasicTableHeaderUI extends TableHeaderUI false, // isSelected false, // isFocused -1, i); + // FIXME: The following settings should be performed in + // rend.getTableCellRendererComponent(). comp.setFont(header.getFont()); comp.setBackground(header.getBackground()); comp.setForeground(header.getForeground()); if (comp instanceof JComponent) ((JComponent)comp).setBorder(cellBorder); - gfx.translate(bounds.x, bounds.y); - gfx.setClip(0, 0, bounds.width, bounds.height); - comp.setSize(bounds.width, bounds.height); - comp.setLocation(0,0); - comp.paint(gfx); - gfx.translate(-bounds.x, -bounds.y); - gfx.setClip(oldClip); + rendererPane.paintComponent(gfx, comp, header, bounds.x, bounds.y, + bounds.width, bounds.height); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java index 0154439..18b6912 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java @@ -1193,29 +1193,9 @@ public class BasicTableUI extends TableUI TableCellRenderer rend, TableModel data, int rowLead, int colLead) { - boolean rowSelAllowed = table.getRowSelectionAllowed(); - boolean colSelAllowed = table.getColumnSelectionAllowed(); - boolean isSel = false; - if (rowSelAllowed && colSelAllowed || !rowSelAllowed && !colSelAllowed) - isSel = table.isCellSelected(row, col); - else - isSel = table.isRowSelected(row) && table.getRowSelectionAllowed() - || table.isColumnSelected(col) && table.getColumnSelectionAllowed(); - - // Determine the focused cell. The focused cell is the cell at the - // leadSelectionIndices of the row and column selection model. - ListSelectionModel rowSel = table.getSelectionModel(); - ListSelectionModel colSel = table.getColumnModel().getSelectionModel(); - boolean hasFocus = table.hasFocus() && table.isEnabled() - && rowSel.getLeadSelectionIndex() == row - && colSel.getLeadSelectionIndex() == col; - - Component comp = rend.getTableCellRendererComponent(table, - data.getValueAt(row, col), - isSel, hasFocus, row, col); - + Component comp = table.prepareRenderer(rend, row, col); rendererPane.paintComponent(g, comp, table, bounds); - + // FIXME: this is manual painting of the Caret, why doesn't the // JTextField take care of this itself? if (comp instanceof JTextField) @@ -1263,7 +1243,7 @@ public class BasicTableUI extends TableUI width - gap.width + 1, height - gap.height); if (bounds.intersects(clip)) - { + { paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c), table.getModel(), table.getSelectionModel().getLeadSelectionIndex(), @@ -1286,12 +1266,10 @@ public class BasicTableUI extends TableUI x = x0; Color save = gfx.getColor(); gfx.setColor(grid); - boolean paintedLine = false; for (int c = 0; c < ncols && x < xmax; ++c) { x += cols.getColumn(c).getWidth(); gfx.drawLine(x, y0, x, ymax); - paintedLine = true; } gfx.setColor(save); } @@ -1302,12 +1280,10 @@ public class BasicTableUI extends TableUI y = y0; Color save = gfx.getColor(); gfx.setColor(grid); - boolean paintedLine = false; for (int r = 0; r < nrows && y < ymax; ++r) { y += height; gfx.drawLine(x0, y, xmax, y); - paintedLine = true; } gfx.setColor(save); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java index e8eeece..fc38894 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java @@ -46,15 +46,20 @@ import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; +import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; @@ -62,6 +67,7 @@ import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.plaf.ActionMapUIResource; +import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TextUI; import javax.swing.plaf.UIResource; import javax.swing.text.BadLocationException; @@ -334,9 +340,9 @@ public abstract class BasicTextUI extends TextUI * Returns the document position that is (visually) nearest to the given * document position <code>pos</code> in the given direction <code>d</code>. * - * @param c the text component * @param pos the document position * @param b the bias for <code>pos</code> + * @param a the allocation for the view * @param d the direction, must be either {@link SwingConstants#NORTH}, * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or * {@link SwingConstants#EAST} @@ -351,12 +357,11 @@ public abstract class BasicTextUI extends TextUI * @throws BadLocationException if <code>pos</code> is not a valid offset in * the document model */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) + public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, + int d, Position.Bias[] biasRet) throws BadLocationException { - return view.getNextVisualPositionFrom(c, pos, b, d, biasRet); + return view.getNextVisualPositionFrom(pos, b, a, d, biasRet); } } @@ -616,15 +621,25 @@ public abstract class BasicTextUI extends TextUI */ protected Keymap createKeymap() { + JTextComponent.KeyBinding[] bindings = null; String prefix = getPropertyPrefix(); - JTextComponent.KeyBinding[] bindings = - (JTextComponent.KeyBinding[]) UIManager.get(prefix + ".keyBindings"); + InputMapUIResource m = (InputMapUIResource) UIManager.get(prefix + ".focusInputMap"); + if (m != null) + { + KeyStroke[] keys = m.keys(); + int len = keys.length; + bindings = new JTextComponent.KeyBinding[len]; + for (int i = 0; i < len; i++) + { + KeyStroke curr = keys[i]; + bindings[i] = new JTextComponent.KeyBinding(curr, + (String) m.get(curr)); + } + } if (bindings == null) { bindings = new JTextComponent.KeyBinding[0]; - // FIXME: Putting something into the defaults map is certainly wrong. - // Must be fixed somehow. - UIManager.put(prefix + ".keyBindings", bindings); + UIManager.put(prefix + ".focusInputMap", bindings); } Keymap km = JTextComponent.addKeymap(getKeymapName(), @@ -637,18 +652,45 @@ public abstract class BasicTextUI extends TextUI * Installs the keyboard actions on the text components. */ protected void installKeyboardActions() - { - // load any bindings for the older Keymap interface + { + // load key bindings for the older interface Keymap km = JTextComponent.getKeymap(getKeymapName()); if (km == null) km = createKeymap(); textComponent.setKeymap(km); // load any bindings for the newer InputMap / ActionMap interface - SwingUtilities.replaceUIInputMap(textComponent, - JComponent.WHEN_FOCUSED, + SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED, getInputMap(JComponent.WHEN_FOCUSED)); - SwingUtilities.replaceUIActionMap(textComponent, getActionMap()); + SwingUtilities.replaceUIActionMap(textComponent, createActionMap()); + + ActionMap parentActionMap = new ActionMapUIResource(); + Action[] actions = textComponent.getActions(); + for (int j = 0; j < actions.length; j++) + { + Action currAction = actions[j]; + parentActionMap.put(currAction.getValue(Action.NAME), currAction); + } + + SwingUtilities.replaceUIActionMap(textComponent, parentActionMap); + } + + /** + * Creates an ActionMap to be installed on the text component. + * + * @return an ActionMap to be installed on the text component + */ + ActionMap createActionMap() + { + Action[] actions = textComponent.getActions(); + ActionMap am = new ActionMapUIResource(); + for (int i = 0; i < actions.length; ++i) + { + String name = (String) actions[i].getValue(Action.NAME); + if (name != null) + am.put(name, actions[i]); + } + return am; } /** @@ -675,46 +717,6 @@ public abstract class BasicTextUI extends TextUI } /** - * Returns the ActionMap to be installed on the text component. - * - * @return the ActionMap to be installed on the text component - */ - // FIXME: The UIDefaults have no entries for .actionMap, so this should - // be handled somehow different. - ActionMap getActionMap() - { - String prefix = getPropertyPrefix(); - ActionMap am = (ActionMap) UIManager.get(prefix + ".actionMap"); - if (am == null) - { - am = createActionMap(); - // FIXME: Putting something in the UIDefaults map is certainly wrong. - // However, the whole method seems wrong and must be replaced by - // something that is less wrong. - UIManager.put(prefix + ".actionMap", am); - } - return am; - } - - /** - * Creates an ActionMap to be installed on the text component. - * - * @return an ActionMap to be installed on the text component - */ - ActionMap createActionMap() - { - Action[] actions = textComponent.getActions(); - ActionMap am = new ActionMapUIResource(); - for (int i = 0; i < actions.length; ++i) - { - String name = (String) actions[i].getValue(Action.NAME); - if (name != null) - am.put(name, actions[i]); - } - return am; - } - - /** * Uninstalls this TextUI from the text component. * * @param component the text component to uninstall the UI from diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java index 7bf2a4a..261db68 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java @@ -1060,7 +1060,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants isDragging = true; if (dragWindow != null) - dragWindow.setOffset(new Point(e.getX(), e.getY())); + dragWindow.setOffset(new Point(cachedBounds.width/2, cachedBounds.height/2)); dragTo(e.getPoint(), origin); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java index 2d54983..f2ebcfc 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java @@ -112,7 +112,6 @@ import javax.swing.tree.TreeSelectionModel; * the Basic look and feel. * * @see javax.swing.JTree - * * @author Lillian Angel (langel@redhat.com) * @author Sascha Brawer (brawer@dandelis.ch) */ @@ -173,7 +172,7 @@ public class BasicTreeUI extends TreeUI /** Size needed to completely display all the nodes. */ protected Dimension preferredSize; - + /** Minimum size needed to completely display all the nodes. */ protected Dimension preferredMinSize; @@ -225,7 +224,7 @@ public class BasicTreeUI extends TreeUI /** Set to true if the editor has a different size than the renderer. */ protected boolean editorHasDifferentSize; - + /** The action listener for the editor's Timer. */ Timer editorTimer = new EditorUpdateTimer(); @@ -234,29 +233,38 @@ public class BasicTreeUI extends TreeUI /** The action bound to KeyStrokes. */ TreeAction action; - + /** Boolean to keep track of editing. */ boolean isEditing; - + /** The current path of the visible nodes in the tree. */ TreePath currentVisiblePath; - + /** The gap between the icon and text. */ int gap = 4; - - /** Default row height, if none was set. */ - int rowHeight = 20; + + /** The max height of the nodes in the tree. */ + int maxHeight = 0; /** Listeners */ private PropertyChangeListener propertyChangeListener; + private FocusListener focusListener; + private TreeSelectionListener treeSelectionListener; + private MouseListener mouseListener; + private KeyListener keyListener; + private PropertyChangeListener selectionModelPropertyChangeListener; + private ComponentListener componentListener; + CellEditorListener cellEditorListener; + private TreeExpansionListener treeExpansionListener; + private TreeModelListener treeModelListener; /** @@ -437,7 +445,7 @@ public class BasicTreeUI extends TreeUI protected void setRowHeight(int rowHeight) { if (rowHeight == 0) - rowHeight = this.rowHeight; + rowHeight = Math.max(getMaxHeight(tree), 20); treeState.setRowHeight(rowHeight); } @@ -625,19 +633,49 @@ public class BasicTreeUI extends TreeUI */ public Rectangle getPathBounds(JTree tree, TreePath path) { - Rectangle bounds = null; int row = -1; Object cell = null; if (path != null) { row = getRowForPath(tree, path); cell = path.getLastPathComponent(); - bounds = new Rectangle(0, row * getRowHeight(), 0, 0); } - return nodeDimensions.getNodeDimensions(cell, row, - getLevel(cell), + return nodeDimensions.getNodeDimensions(cell, row, getLevel(cell), tree.isExpanded(path), - bounds); + new Rectangle()); + } + + /** + * Returns the max height of all the nodes in the tree. + * + * @param tree - + * the current tree + * @return the max height. + */ + private int getMaxHeight(JTree tree) + { + if (maxHeight != 0) + return maxHeight; + + Icon e = UIManager.getIcon("Tree.openIcon"); + Icon c = UIManager.getIcon("Tree.closedIcon"); + Icon l = UIManager.getIcon("Tree.leafIcon"); + int rc = getRowCount(tree); + int iconHeight = 0; + + for (int row = 0; row < rc; row++) + { + if (isLeaf(row)) + iconHeight = l.getIconHeight(); + else if (tree.isExpanded(row)) + iconHeight = e.getIconHeight(); + else + iconHeight = c.getIconHeight(); + + maxHeight = Math.max(maxHeight, iconHeight + gap); + } + + return maxHeight; } /** @@ -684,7 +722,7 @@ public class BasicTreeUI extends TreeUI { if (dest.equals(nodes[row])) return row; - row++; + row++; } } return -1; @@ -720,7 +758,7 @@ public class BasicTreeUI extends TreeUI */ public TreePath getClosestPathForLocation(JTree tree, int x, int y) { - int row = Math.round(y / getRowHeight()); + int row = Math.round(y / getMaxHeight(tree)); TreePath path = getPathForRow(tree, row); // no row is visible at this node @@ -977,10 +1015,12 @@ public class BasicTreeUI extends TreeUI protected TreeCellEditor createDefaultCellEditor() { if (currentCellRenderer != null) - return new DefaultTreeCellEditor(tree, + return new DefaultTreeCellEditor( + tree, (DefaultTreeCellRenderer) currentCellRenderer, cellEditor); - return new DefaultTreeCellEditor(tree, + return new DefaultTreeCellEditor( + tree, (DefaultTreeCellRenderer) createDefaultCellRenderer(), cellEditor); } @@ -1034,7 +1074,8 @@ public class BasicTreeUI extends TreeUI protected void uninstallKeyboardActions() { action = null; - tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent(null); + tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent( + null); tree.getActionMap().setParent(null); } @@ -1094,7 +1135,7 @@ public class BasicTreeUI extends TreeUI { Enumeration expanded = tree.getExpandedDescendants(path); while (expanded.hasMoreElements()) - treeState.setExpandedState(((TreePath) expanded.nextElement()), true); + treeState.setExpandedState(((TreePath) expanded.nextElement()), true); } /** @@ -1125,7 +1166,7 @@ public class BasicTreeUI extends TreeUI protected void updateCellEditor() { if (tree.isEditable() && cellEditor == null) - setCellEditor(createDefaultCellEditor()); + setCellEditor(createDefaultCellEditor()); createdCellEditor = true; } @@ -1136,10 +1177,10 @@ public class BasicTreeUI extends TreeUI { if (tree != null) { - if(tree.getCellRenderer() == null) - { - if(currentCellRenderer == null) - currentCellRenderer = createDefaultCellRenderer(); + if (tree.getCellRenderer() == null) + { + if (currentCellRenderer == null) + currentCellRenderer = createDefaultCellRenderer(); tree.setCellRenderer(currentCellRenderer); } } @@ -1186,9 +1227,13 @@ public class BasicTreeUI extends TreeUI bounds.width += getCurrentControlIcon(curr).getIconWidth(); maxWidth = Math.max(maxWidth, bounds.x + bounds.width); } - preferredSize = new Dimension(maxWidth, (getRowHeight() * path.length)); + + maxHeight = 0; + maxHeight = getMaxHeight(tree); + preferredSize = new Dimension(maxWidth, (maxHeight * path.length)); } - else preferredSize = new Dimension(0, 0); + else + preferredSize = new Dimension(0, 0); validCachedPreferredSize = true; } @@ -1201,7 +1246,6 @@ public class BasicTreeUI extends TreeUI protected void pathWasExpanded(TreePath path) { validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } @@ -1211,7 +1255,6 @@ public class BasicTreeUI extends TreeUI protected void pathWasCollapsed(TreePath path) { validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } @@ -1345,19 +1388,12 @@ public class BasicTreeUI extends TreeUI installComponents(); installKeyboardActions(); installListeners(); - + setCellEditor(createDefaultCellEditor()); createdCellEditor = true; isEditing = false; - TreeModel mod = tree.getModel(); - setModel(mod); - if (mod != null) - { - TreePath path = new TreePath(mod.getRoot()); - if (!tree.isExpanded(path)) - toggleExpandState(path); - } + setModel(tree.getModel()); treeSelectionModel = tree.getSelectionModel(); completeUIInstall(); @@ -1406,8 +1442,7 @@ public class BasicTreeUI extends TreeUI public void paint(Graphics g, JComponent c) { JTree tree = (JTree) c; - if (currentVisiblePath == null) - updateCurrentVisiblePath(); + updateCurrentVisiblePath(); Rectangle clip = g.getClipBounds(); Insets insets = tree.getInsets(); @@ -1451,7 +1486,7 @@ public class BasicTreeUI extends TreeUI endRow = beginRow; beginRow = temp; } - + for (int i = beginRow; i < endRow; i++) { TreePath path = getPathForRow(tree, i); @@ -1508,8 +1543,8 @@ public class BasicTreeUI extends TreeUI */ public Dimension getPreferredSize(JComponent c, boolean checkConsistancy) { - // FIXME: checkConsistancy not implemented, c not used - if(!validCachedPreferredSize) + // FIXME: checkConsistancy not implemented, c not used + if (!validCachedPreferredSize) updateCachedPreferredSize(); return preferredSize; } @@ -1524,7 +1559,7 @@ public class BasicTreeUI extends TreeUI */ public Dimension getMinimumSize(JComponent c) { - Dimension min = getPreferredMinSize(); + Dimension min = getPreferredMinSize(); if (min == null) return new Dimension(); return min; @@ -1636,7 +1671,7 @@ public class BasicTreeUI extends TreeUI tree.add(editingComponent.getParent()); editingComponent.getParent().validate(); validCachedPreferredSize = false; - tree.revalidate(); + ((JTextField) editingComponent).requestFocusInWindow(false); editorTimer.start(); return true; @@ -1682,12 +1717,13 @@ public class BasicTreeUI extends TreeUI { boolean cntlClick = false; int row = getRowForPath(tree, path); - + if (!isLeaf(row)) { Rectangle bounds = getPathBounds(tree, path); - if (hasControlIcons() && (mouseX < bounds.x) + if (hasControlIcons() + && (mouseX < bounds.x) && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap))) cntlClick = true; } @@ -1725,7 +1761,6 @@ public class BasicTreeUI extends TreeUI tree.collapsePath(path); else tree.expandPath(path); - updateCurrentVisiblePath(); } /** @@ -1739,8 +1774,7 @@ public class BasicTreeUI extends TreeUI */ protected boolean isToggleSelectionEvent(MouseEvent event) { - return (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.SINGLE_TREE_SELECTION); + return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION); } /** @@ -1754,8 +1788,7 @@ public class BasicTreeUI extends TreeUI */ protected boolean isMultiSelectEvent(MouseEvent event) { - return (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); + return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); } /** @@ -1834,8 +1867,7 @@ public class BasicTreeUI extends TreeUI * are pressed for the JTree. The actionPerformed method is called when a key * that has been registered for the JTree is received. */ - class TreeAction - extends AbstractAction + class TreeAction extends AbstractAction { /** @@ -1877,7 +1909,7 @@ public class BasicTreeUI extends TreeUI else if (e.getActionCommand().equals("toggle")) { if (tree.isEditing()) - tree.stopEditing(); + tree.stopEditing(); else { Object last = lead.getLastPathComponent(); @@ -1903,8 +1935,7 @@ public class BasicTreeUI extends TreeUI * to the true receiver after altering the actionCommand property of the * event. */ - private static class ActionListenerProxy - extends AbstractAction + private static class ActionListenerProxy extends AbstractAction { ActionListener target; @@ -1929,9 +1960,7 @@ public class BasicTreeUI extends TreeUI /** * The timer that updates the editor component. */ - private class EditorUpdateTimer - extends Timer - implements ActionListener + private class EditorUpdateTimer extends Timer implements ActionListener { /** * Creates a new EditorUpdateTimer object with a default delay of 0.3 @@ -1975,8 +2004,8 @@ public class BasicTreeUI extends TreeUI /** * Updates the preferred size when scrolling, if necessary. */ - public class ComponentHandler extends ComponentAdapter - implements ActionListener + public class ComponentHandler extends ComponentAdapter implements + ActionListener { /** * Timer used when inside a scrollpane and the scrollbar is adjusting @@ -2006,8 +2035,8 @@ public class BasicTreeUI extends TreeUI } /** - * Creates, if necessary, and starts a Timer to check if needed to resize the - * bounds + * Creates, if necessary, and starts a Timer to check if needed to resize + * the bounds */ protected void startTimer() { @@ -2082,7 +2111,6 @@ public class BasicTreeUI extends TreeUI tree.requestFocusInWindow(false); editorTimer.stop(); validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } @@ -2113,7 +2141,6 @@ public class BasicTreeUI extends TreeUI editorTimer.stop(); isEditing = false; validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } }// CellEditorHandler @@ -2121,8 +2148,7 @@ public class BasicTreeUI extends TreeUI /** * Repaints the lead selection row when focus is lost/grained. */ - public class FocusHandler - implements FocusListener + public class FocusHandler implements FocusListener { /** * Constructor @@ -2161,8 +2187,7 @@ public class BasicTreeUI extends TreeUI * This is used to get multiple key down events to appropriately genereate * events. */ - public class KeyHandler - extends KeyAdapter + public class KeyHandler extends KeyAdapter { /** Key code that is being generated for. */ protected Action repeatKeyAction; @@ -2247,7 +2272,7 @@ public class BasicTreeUI extends TreeUI boolean cntlClick = isLocationInExpandControl(path, click.x, click.y); boolean isLeaf = isLeaf(row); - + TreeCellRenderer tcr = getCellRenderer(); Icon icon; if (isLeaf) @@ -2256,17 +2281,17 @@ public class BasicTreeUI extends TreeUI icon = UIManager.getIcon("Tree.openIcon"); else icon = UIManager.getIcon("Tree.closedIcon"); - + if (tcr instanceof DefaultTreeCellRenderer) { - Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon(); - if (tmp != null) - icon = tmp; + Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon(); + if (tmp != null) + icon = tmp; } - + // add gap*2 for the space before and after the text if (icon != null) - bounds.width += icon.getIconWidth() + gap*2; + bounds.width += icon.getIconWidth() + gap * 2; boolean inBounds = bounds.contains(click.x, click.y); if ((inBounds || cntlClick) && tree.isVisible(path)) @@ -2275,9 +2300,9 @@ public class BasicTreeUI extends TreeUI { selectPath(tree, path); if (e.getClickCount() == 2 && !isLeaf(row)) - toggleExpandState(path); + toggleExpandState(path); } - + if (cntlClick) { handleExpandControlClick(path, click.x, click.y); @@ -2455,8 +2480,7 @@ public class BasicTreeUI extends TreeUI * BasicTreeUI method. X location does not include insets, that is handled in * getPathBounds. */ - public class NodeDimensionsHandler - extends AbstractLayoutCache.NodeDimensions + public class NodeDimensionsHandler extends AbstractLayoutCache.NodeDimensions { /** * Constructor @@ -2467,10 +2491,10 @@ public class BasicTreeUI extends TreeUI } /** - * Returns, by reference in bounds, the size and x origin to place value at. - * The calling method is responsible for determining the Y location. - * If bounds is null, a newly created Rectangle should be returned, - * otherwise the value should be placed in bounds and returned. + * Returns, by reference in bounds, the size and x origin to place value at. + * The calling method is responsible for determining the Y location. If + * bounds is null, a newly created Rectangle should be returned, otherwise + * the value should be placed in bounds and returned. * * @param cell * the value to be represented @@ -2498,8 +2522,10 @@ public class BasicTreeUI extends TreeUI { size.x = getRowX(row, depth); size.width = SwingUtilities.computeStringWidth(fm, s); - size.height = fm.getHeight(); + size.height = getMaxHeight(tree); + size.y = size.height * row; } + return size; } @@ -2520,8 +2546,7 @@ public class BasicTreeUI extends TreeUI * PropertyChangeListener for the tree. Updates the appropriate varaible, or * TreeState, based on what changes. */ - public class PropertyChangeHandler - implements PropertyChangeListener + public class PropertyChangeHandler implements PropertyChangeListener { /** @@ -2544,8 +2569,6 @@ public class BasicTreeUI extends TreeUI if ((event.getPropertyName()).equals("rootVisible")) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } } @@ -2555,8 +2578,8 @@ public class BasicTreeUI extends TreeUI * Listener on the TreeSelectionModel, resets the row selection if any of the * properties of the model change. */ - public class SelectionModelPropertyChangeHandler - implements PropertyChangeListener + public class SelectionModelPropertyChangeHandler implements + PropertyChangeListener { /** @@ -2583,8 +2606,7 @@ public class BasicTreeUI extends TreeUI /** * ActionListener that invokes cancelEditing when action performed. */ - public class TreeCancelEditingAction - extends AbstractAction + public class TreeCancelEditingAction extends AbstractAction { /** @@ -2621,8 +2643,7 @@ public class BasicTreeUI extends TreeUI /** * Updates the TreeState in response to nodes expanding/collapsing. */ - public class TreeExpansionHandler - implements TreeExpansionListener + public class TreeExpansionHandler implements TreeExpansionListener { /** @@ -2642,8 +2663,6 @@ public class BasicTreeUI extends TreeUI public void treeExpanded(TreeExpansionEvent event) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2656,8 +2675,6 @@ public class BasicTreeUI extends TreeUI public void treeCollapsed(TreeExpansionEvent event) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } }// TreeExpansionHandler @@ -2666,8 +2683,7 @@ public class BasicTreeUI extends TreeUI * TreeHomeAction is used to handle end/home actions. Scrolls either the first * or last cell to be visible based on direction. */ - public class TreeHomeAction - extends AbstractAction + public class TreeHomeAction extends AbstractAction { /** direction is either home or end */ @@ -2713,8 +2729,7 @@ public class BasicTreeUI extends TreeUI * TreeIncrementAction is used to handle up/down actions. Selection is moved * up or down based on direction. */ - public class TreeIncrementAction - extends AbstractAction + public class TreeIncrementAction extends AbstractAction { /** Specifies the direction to adjust the selection by. */ @@ -2746,7 +2761,7 @@ public class BasicTreeUI extends TreeUI if (e.getActionCommand().equals("selectPreviousChangeLead")) { Object prev = getPreviousVisibleNode(last); - + if (prev != null) { TreePath newPath = new TreePath(getPathToRoot(prev, 0)); @@ -2767,7 +2782,7 @@ public class BasicTreeUI extends TreeUI else if (e.getActionCommand().equals("selectPrevious")) { Object prev = getPreviousVisibleNode(last); - + if (prev != null) { TreePath newPath = new TreePath(getPathToRoot(prev, 0)); @@ -2777,7 +2792,7 @@ public class BasicTreeUI extends TreeUI else if (e.getActionCommand().equals("selectNext")) { Object next = getNextVisibleNode(last); - + if (next != null) { TreePath newPath = new TreePath(getPathToRoot(next, 0)); @@ -2847,8 +2862,6 @@ public class BasicTreeUI extends TreeUI public void treeNodesChanged(TreeModelEvent e) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2863,8 +2876,6 @@ public class BasicTreeUI extends TreeUI public void treeNodesInserted(TreeModelEvent e) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2882,8 +2893,6 @@ public class BasicTreeUI extends TreeUI public void treeNodesRemoved(TreeModelEvent e) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2902,9 +2911,7 @@ public class BasicTreeUI extends TreeUI if (e.getPath().length == 1 && !e.getPath()[0].equals(treeModel.getRoot())) tree.expandPath(new TreePath(treeModel.getRoot())); - updateCurrentVisiblePath(); validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } }// TreeModelHandler @@ -3102,7 +3109,7 @@ public class BasicTreeUI extends TreeUI return true; return false; } - + /** * Returns control icon. It is null if the LookAndFeel does not implements the * control icons. Package private for use in inner classes. @@ -3127,10 +3134,9 @@ public class BasicTreeUI extends TreeUI */ Object getParent(Object root, Object node) { - if (root == null || node == null || - root.equals(node)) + if (root == null || node == null || root.equals(node)) return null; - + if (node instanceof TreeNode) return ((TreeNode) node).getParent(); return findNode(root, node); @@ -3163,7 +3169,7 @@ public class BasicTreeUI extends TreeUI } return null; } - + /** * Get previous visible node in the tree. Package private for use in inner * classes. @@ -3182,8 +3188,8 @@ public class BasicTreeUI extends TreeUI while (i < nodes.length && !node.equals(nodes[i])) i++; // return the next node - if (i-1 >= 0) - return nodes[i-1]; + if (i - 1 >= 0) + return nodes[i - 1]; } return null; } @@ -3191,7 +3197,7 @@ public class BasicTreeUI extends TreeUI /** * Returns the next node in the tree Package private for use in inner classes. * - * @param curr - + * @param curr - * current node * @return the next node in the tree */ @@ -3208,7 +3214,7 @@ public class BasicTreeUI extends TreeUI node = getParent(treeModel.getRoot(), node); } while (sibling == null && node != null); - + return sibling; } @@ -3250,7 +3256,7 @@ public class BasicTreeUI extends TreeUI * Returns the next sibling in the tree Package private for use in inner * classes. * - * @param node - + * @param node - * current node * @return the next sibling in the tree */ @@ -3270,7 +3276,7 @@ public class BasicTreeUI extends TreeUI return treeModel.getChild(parent, index); } - + /** * Returns the previous sibling in the tree Package private for use in inner * classes. @@ -3309,15 +3315,13 @@ public class BasicTreeUI extends TreeUI { if (path != null) { - if (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.SINGLE_TREE_SELECTION) + if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION) { tree.getSelectionModel().clearSelection(); tree.addSelectionPath(path); tree.setLeadSelectionPath(path); } - else if (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.CONTIGUOUS_TREE_SELECTION) + else if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION) { // TODO } @@ -3325,8 +3329,8 @@ public class BasicTreeUI extends TreeUI { tree.addSelectionPath(path); tree.setLeadSelectionPath(path); - tree.getSelectionModel().setSelectionMode - (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + tree.getSelectionModel().setSelectionMode( + TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); } } } @@ -3351,7 +3355,8 @@ public class BasicTreeUI extends TreeUI return new Object[depth]; } - Object[] path = getPathToRoot(getParent(treeModel.getRoot(), node), depth + 1); + Object[] path = getPathToRoot(getParent(treeModel.getRoot(), node), + depth + 1); path[path.length - depth - 1] = node; return path; } @@ -3374,7 +3379,7 @@ public class BasicTreeUI extends TreeUI Object root = treeModel.getRoot(); if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root))) count--; - + do { current = getParent(root, current); @@ -3441,28 +3446,32 @@ public class BasicTreeUI extends TreeUI * @param x * is the center position in x-direction * @param y - * is the center position in y-direction + * is the center position in y-direction */ protected void drawCentered(Component c, Graphics g, Icon icon, int x, int y) { x -= icon.getIconWidth() / 2; y -= icon.getIconHeight() / 2; - + if (x < 0) x = 0; if (y < 0) y = 0; - + icon.paintIcon(c, g, x, y); } - + /** * Draws a dashed horizontal line. * - * @param g - the graphics configuration. - * @param y - the y location to start drawing at - * @param x1 - the x location to start drawing at - * @param x2 - the x location to finish drawing at + * @param g - + * the graphics configuration. + * @param y - + * the y location to start drawing at + * @param x1 - + * the x location to start drawing at + * @param x2 - + * the x location to finish drawing at */ protected void drawDashedHorizontalLine(Graphics g, int y, int x1, int x2) { @@ -3470,14 +3479,18 @@ public class BasicTreeUI extends TreeUI for (int i = x1; i < x2; i += 2) g.drawLine(i, y, i + 1, y); } - + /** * Draws a dashed vertical line. * - * @param g - the graphics configuration. - * @param x - the x location to start drawing at - * @param y1 - the y location to start drawing at - * @param y2 - the y location to finish drawing at + * @param g - + * the graphics configuration. + * @param x - + * the x location to start drawing at + * @param y1 - + * the y location to start drawing at + * @param y2 - + * the y location to finish drawing at */ protected void drawDashedVerticalLine(Graphics g, int x, int y1, int y2) { @@ -3485,72 +3498,89 @@ public class BasicTreeUI extends TreeUI for (int i = y1; i < y2; i += 2) g.drawLine(x, i, x, i + 1); } - + /** - * Paints the expand (toggle) part of a row. The receiver should NOT modify + * Paints the expand (toggle) part of a row. The receiver should NOT modify * clipBounds, or insets. * - * @param g - the graphics configuration - * @param clipBounds - - * @param insets - - * @param bounds - bounds of expand control - * @param path - path to draw control for - * @param row - row to draw control for - * @param isExpanded - is the row expanded - * @param hasBeenExpanded - has the row already been expanded - * @param isLeaf - is the path a leaf + * @param g - + * the graphics configuration + * @param clipBounds - + * @param insets - + * @param bounds - + * bounds of expand control + * @param path - + * path to draw control for + * @param row - + * row to draw control for + * @param isExpanded - + * is the row expanded + * @param hasBeenExpanded - + * has the row already been expanded + * @param isLeaf - + * is the path a leaf */ protected void paintExpandControl(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, - TreePath path, int row, - boolean isExpanded, boolean hasBeenExpanded, - boolean isLeaf) + TreePath path, int row, boolean isExpanded, + boolean hasBeenExpanded, boolean isLeaf) { if (shouldPaintExpandControl(path, row, isExpanded, hasBeenExpanded, isLeaf)) { Icon icon = getCurrentControlIcon(path); int iconW = icon.getIconWidth(); - int x = bounds.x - rightChildIndent + iconW/2; + int x = bounds.x - rightChildIndent + iconW / 2; if (x + iconW > bounds.x) x = bounds.x - rightChildIndent - gap; - icon.paintIcon(tree, g, x, bounds.y + bounds.height/2 - icon.getIconHeight()/2); + icon.paintIcon(tree, g, x, bounds.y + bounds.height / 2 + - icon.getIconHeight() / 2); } } /** - * Paints the horizontal part of the leg. The receiver should NOT modify - * clipBounds, or insets. - * NOTE: parentRow can be -1 if the root is not visible. - * - * @param g - the graphics configuration - * @param clipBounds - - * @param insets - - * @param bounds - bounds of the cell - * @param path - path to draw leg for - * @param row - row to start drawing at - * @param isExpanded - is the row expanded - * @param hasBeenExpanded - has the row already been expanded - * @param isLeaf - is the path a leaf + * Paints the horizontal part of the leg. The receiver should NOT modify + * clipBounds, or insets. NOTE: parentRow can be -1 if the root is not + * visible. + * + * @param g - + * the graphics configuration + * @param clipBounds - + * @param insets - + * @param bounds - + * bounds of the cell + * @param path - + * path to draw leg for + * @param row - + * row to start drawing at + * @param isExpanded - + * is the row expanded + * @param hasBeenExpanded - + * has the row already been expanded + * @param isLeaf - + * is the path a leaf */ protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row, - boolean isExpanded, boolean hasBeenExpanded, + boolean isExpanded, + boolean hasBeenExpanded, boolean isLeaf) { if (row != 0) - paintHorizontalLine(g, tree, bounds.y + bounds.height/2, bounds.x - gap - 2, - bounds.x); + paintHorizontalLine(g, tree, bounds.y + bounds.height / 2, bounds.x - gap + - 2, bounds.x); } - + /** - * Paints the vertical part of the leg. The receiver should NOT modify + * Paints the vertical part of the leg. The receiver should NOT modify * clipBounds, insets. * - * @param g - the graphics configuration. - * @param clipBounds - - * @param insets - - * @param path - the path to draw the vertical part for. + * @param g - + * the graphics configuration. + * @param clipBounds - + * @param insets - + * @param path - + * the path to draw the vertical part for. */ protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, TreePath path) @@ -3564,56 +3594,65 @@ public class BasicTreeUI extends TreeUI if (numChild > 0 && tree.isExpanded(currPath)) { Rectangle bounds = getPathBounds(tree, currPath); - Rectangle lastChildBounds = getPathBounds(tree, - new TreePath(getPathToRoot( - treeModel.getChild(curr, numChild - 1), - 0))); - paintVerticalLine(g, tree, bounds.x + gap + 2, bounds.y + - bounds.height - 2, lastChildBounds.y + - lastChildBounds.height/2); + Rectangle lastChildBounds = getPathBounds( + tree, + new TreePath( + getPathToRoot( + treeModel.getChild( + curr, + numChild - 1), + 0))); + paintVerticalLine(g, tree, bounds.x + gap + 2, bounds.y + + bounds.height - 2, + lastChildBounds.y + lastChildBounds.height / 2); } } } /** - * Paints the renderer part of a row. The receiver should NOT modify clipBounds, - * or insets. + * Paints the renderer part of a row. The receiver should NOT modify + * clipBounds, or insets. * - * @param g - the graphics configuration - * @param clipBounds - - * @param insets - - * @param bounds - bounds of expand control - * @param path - path to draw control for - * @param row - row to draw control for - * @param isExpanded - is the row expanded - * @param hasBeenExpanded - has the row already been expanded - * @param isLeaf - is the path a leaf - */ - protected void paintRow(Graphics g, Rectangle clipBounds, - Insets insets, Rectangle bounds, - TreePath path, int row, + * @param g - + * the graphics configuration + * @param clipBounds - + * @param insets - + * @param bounds - + * bounds of expand control + * @param path - + * path to draw control for + * @param row - + * row to draw control for + * @param isExpanded - + * is the row expanded + * @param hasBeenExpanded - + * has the row already been expanded + * @param isLeaf - + * is the path a leaf + */ + protected void paintRow(Graphics g, Rectangle clipBounds, Insets insets, + Rectangle bounds, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) { boolean selected = tree.isPathSelected(path); boolean hasIcons = false; Object node = path.getLastPathComponent(); - + if (tree.isVisible(path)) { if (!validCachedPreferredSize) updateCachedPreferredSize(); - - - paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf); - + + paintExpandControl(g, clipBounds, insets, bounds, path, row, + isExpanded, hasBeenExpanded, isLeaf); + if (row != 0) bounds.x += gap; bounds.width = preferredSize.width + bounds.x; - if (editingComponent != null && editingPath != null && isEditing(tree) && node.equals(editingPath.getLastPathComponent())) - { + { rendererPane.paintComponent(g, editingComponent.getParent(), null, bounds); } @@ -3622,9 +3661,12 @@ public class BasicTreeUI extends TreeUI TreeCellRenderer dtcr = tree.getCellRenderer(); if (dtcr == null) dtcr = createDefaultCellRenderer(); - + Component c = dtcr.getTreeCellRendererComponent(tree, node, - selected, isExpanded, isLeaf, row, tree.hasFocus()); + selected, + isExpanded, isLeaf, + row, + tree.hasFocus()); rendererPane.paintComponent(g, c, c.getParent(), bounds); } } @@ -3637,16 +3679,21 @@ public class BasicTreeUI extends TreeUI { // TODO: Implement this properly. } - + /** * Returns true if the expand (toggle) control should be drawn for the * specified row. * - * @param path - current path to check for. - * @param row - current row to check for. - * @param isExpanded - true if the path is expanded - * @param hasBeenExpanded - true if the path has been expanded already - * @param isLeaf - true if the row is a lead + * @param path - + * current path to check for. + * @param row - + * current row to check for. + * @param isExpanded - + * true if the path is expanded + * @param hasBeenExpanded - + * true if the path has been expanded already + * @param isLeaf - + * true if the row is a lead */ protected boolean shouldPaintExpandControl(TreePath path, int row, boolean isExpanded, @@ -3656,10 +3703,9 @@ public class BasicTreeUI extends TreeUI Object node = path.getLastPathComponent(); return (!isLeaf && getLevel(node) != 0 && hasControlIcons()); } - + /** - * Updates the cached current TreePath of all visible - * nodes in the tree. + * Updates the cached current TreePath of all visible nodes in the tree. */ void updateCurrentVisiblePath() { @@ -3667,19 +3713,22 @@ public class BasicTreeUI extends TreeUI return; Object next = treeModel.getRoot(); + if (next == null) + return; + TreePath rootPath = new TreePath(next); Rectangle bounds = getPathBounds(tree, rootPath); - + // If root is not a valid size to be visible, or is // not visible and the tree is expanded, then the next node acts // as the root - if ((bounds.width == 0 && bounds.height == 0) || (!isRootVisible() - && tree.isExpanded(new TreePath(next)))) + if ((bounds.width == 0 && bounds.height == 0) + || (!isRootVisible() && tree.isExpanded(new TreePath(next)))) { next = getNextNode(next); rootPath = new TreePath(next); } - + Object root = next; TreePath current = null; while (next != null) @@ -3688,7 +3737,7 @@ public class BasicTreeUI extends TreeUI current = rootPath; else current = current.pathByAddingChild(next); - + do { TreePath path = new TreePath(getPathToRoot(next, 0)); @@ -3712,19 +3761,23 @@ public class BasicTreeUI extends TreeUI } } } - while (next != null && - !tree.isVisible(new TreePath(getPathToRoot(next, 0)))); + while (next != null + && !tree.isVisible(new TreePath(getPathToRoot(next, 0)))); } currentVisiblePath = current; tree.setVisibleRowCount(getRowCount(tree)); - if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0 && - currentVisiblePath != null) - selectPath(tree, new TreePath(getPathToRoot(currentVisiblePath. - getPathComponent(0), 0))); + if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0 + && currentVisiblePath != null) + selectPath( + tree, + new TreePath( + getPathToRoot( + currentVisiblePath.getPathComponent(0), + 0))); } - + /** * Get next visible node in the currentVisiblePath. Package private for use in * inner classes. @@ -3743,8 +3796,8 @@ public class BasicTreeUI extends TreeUI while (i < nodes.length && !node.equals(nodes[i])) i++; // return the next node - if (i+1 < nodes.length) - return nodes[i+1]; + if (i + 1 < nodes.length) + return nodes[i + 1]; } return null; } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java index a43ee3c..0006b78 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java @@ -313,4 +313,40 @@ public class MetalComboBoxUI extends BasicComboBoxUI d.height + insetsH + 1); } + /** + * Configures the editor for this combo box. + */ + public void configureEditor() + { + ComboBoxEditor cbe = comboBox.getEditor(); + if (cbe != null) + { + cbe.getEditorComponent().setFont(comboBox.getFont()); + cbe.setItem(comboBox.getSelectedItem()); + cbe.addActionListener(comboBox); + } + } + + /** + * Unconfigures the editor for this combo box. + */ + public void unconfigureEditor() + { + ComboBoxEditor cbe = comboBox.getEditor(); + if (cbe != null) + { + cbe.getEditorComponent().setFont(null); + cbe.setItem(null); + cbe.removeActionListener(comboBox); + } + } + + /** + * Lays out the ComboBox + */ + public void layoutComboBox(Container parent, + MetalComboBoxUI.MetalComboBoxLayoutManager manager) + { + manager.layoutContainer(parent); + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java index 3a2e1c1..967c40d 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -38,39 +38,421 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.awt.BorderLayout; import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Rectangle; +import java.awt.Window; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.text.NumberFormat; + import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; + import java.io.File; -import java.util.List; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; +import javax.swing.ActionMap; +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; import javax.swing.ComboBoxModel; import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JComponent; +import javax.swing.JDialog; import javax.swing.JFileChooser; +import javax.swing.JLabel; import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.JViewport; +import javax.swing.ListModel; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; import javax.swing.UIManager; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicFileChooserUI; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; + +import java.sql.Date; + +import java.text.DateFormat; + +import java.util.List; /** * A UI delegate for the {@link JFileChooser} component. This class is only * partially implemented and is not usable yet. */ -public class MetalFileChooserUI extends BasicFileChooserUI +public class MetalFileChooserUI + extends BasicFileChooserUI { + + /** + * A renderer for the files and directories in the file chooser table. + */ + class TableFileRenderer + extends DefaultTableCellRenderer + { + + /** + * Creates a new renderer. + */ + public TableFileRenderer() + { + super(); + } + + /** + * Returns a component that can render the specified value. + * + * @param table the table + * @param value the string value of the cell + * @param isSelected is the item selected? + * @param hasFocus does the item have the focus? + * @param row the row + * @param column the column + * + * @return The renderer. + */ + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) + { + if (column == 0) + { + FileView v = getFileView(getFileChooser()); + ListModel lm = fileList.getModel(); + if (row < lm.getSize()) + setIcon(v.getIcon((File) lm.getElementAt(row))); + } + else + setIcon(null); + + setText(value.toString()); + setOpaque(true); + setEnabled(table.isEnabled()); + setFont(fileList.getFont()); + + if (startEditing && column == 0 || !isSelected) + { + setBackground(table.getBackground()); + setForeground(table.getForeground()); + } + else + { + setBackground(table.getSelectionBackground()); + setForeground(table.getSelectionForeground()); + } + + if (hasFocus) + setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); + else + setBorder(noFocusBorder); + + return this; + } + } + + /** + * ActionListener for the list view. + */ + class ListViewActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (!listView) + { + int[] index = fileTable.getSelectedRows(); + listView = true; + JFileChooser fc = getFileChooser(); + fc.remove(fileTablePanel); + createList(fc); + + fileList.getSelectionModel().clearSelection(); + if (index.length > 0) + for (int i = 0; i < index.length; i++) + fileList.getSelectionModel().addSelectionInterval(index[i], index[i]); + + fc.add(fileListPanel, BorderLayout.CENTER); + fc.revalidate(); + fc.repaint(); + } + } + } + + /** + * ActionListener for the details view. + */ + class DetailViewActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (listView) + { + int[] index = fileList.getSelectedIndices(); + JFileChooser fc = getFileChooser(); + listView = false; + fc.remove(fileListPanel); + + if (fileTable == null) + createDetailsView(fc); + else + updateTable(); + + fileTable.getSelectionModel().clearSelection(); + if (index.length > 0) + { + for (int i = 0; i < index.length; i++) + fileTable.getSelectionModel().addSelectionInterval(index[i], index[i]); + } + + fc.add(fileTablePanel, BorderLayout.CENTER); + fc.revalidate(); + fc.repaint(); + } + } + } + + /** + * A property change listener. + */ + class MetalFileChooserPropertyChangeListener + implements PropertyChangeListener + { + /** + * Default constructor. + */ + public MetalFileChooserPropertyChangeListener() + { + } + + /** + * Handles a property change event. + * + * @param e the event. + */ + public void propertyChange(PropertyChangeEvent e) + { + JFileChooser filechooser = getFileChooser(); + + String n = e.getPropertyName(); + if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY)) + { + int mode = -1; + if (filechooser.isMultiSelectionEnabled()) + mode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION; + else + mode = ListSelectionModel.SINGLE_SELECTION; + + if (listView) + fileList.setSelectionMode(mode); + else + fileTable.setSelectionMode(mode); + } + else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) + { + File file = filechooser.getSelectedFile(); + + if (file != null + && filechooser.getDialogType() == JFileChooser.SAVE_DIALOG) + { + if (file.isDirectory() && filechooser.isTraversable(file)) + { + directoryLabel = look; + dirLabel.setText(directoryLabel); + filechooser.setApproveButtonText(openButtonText); + filechooser.setApproveButtonToolTipText(openButtonToolTipText); + } + else if (file.isFile()) + { + directoryLabel = save; + dirLabel.setText(directoryLabel); + filechooser.setApproveButtonText(saveButtonText); + filechooser.setApproveButtonToolTipText(saveButtonToolTipText); + } + } + + if (file == null) + setFileName(null); + else + setFileName(file.getName()); + int index = -1; + index = getModel().indexOf(file); + if (index >= 0) + { + if (listView) + { + fileList.setSelectedIndex(index); + fileList.ensureIndexIsVisible(index); + fileList.revalidate(); + fileList.repaint(); + } + else + { + fileTable.getSelectionModel().addSelectionInterval(index, index); + fileTable.scrollRectToVisible(fileTable.getCellRect(index, 0, true)); + fileTable.revalidate(); + fileTable.repaint(); + } + } + } + + else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) + { + if (listView) + { + fileList.clearSelection(); + fileList.revalidate(); + fileList.repaint(); + } + else + { + fileTable.clearSelection(); + fileTable.revalidate(); + fileTable.repaint(); + } + + setDirectorySelected(false); + File currentDirectory = filechooser.getCurrentDirectory(); + setDirectory(currentDirectory); + boolean hasParent = (currentDirectory.getParentFile() != null); + getChangeToParentDirectoryAction().setEnabled(hasParent); + } + + else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY)) + { + filterModel.propertyChange(e); + } + else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) + { + filterModel.propertyChange(e); + } + else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY) + || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY)) + { + Window owner = SwingUtilities.windowForComponent(filechooser); + if (owner instanceof JDialog) + ((JDialog) owner).setTitle(getDialogTitle(filechooser)); + approveButton.setText(getApproveButtonText(filechooser)); + approveButton.setToolTipText( + getApproveButtonToolTipText(filechooser)); + approveButton.setMnemonic(getApproveButtonMnemonic(filechooser)); + } + + else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY)) + approveButton.setText(getApproveButtonText(filechooser)); + + else if (n.equals( + JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) + approveButton.setToolTipText(getApproveButtonToolTipText(filechooser)); + + else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) + approveButton.setMnemonic(getApproveButtonMnemonic(filechooser)); + + else if (n.equals( + JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) + { + if (filechooser.getControlButtonsAreShown()) + { + topPanel.add(controls, BorderLayout.EAST); + } + else + topPanel.remove(controls); + topPanel.revalidate(); + topPanel.repaint(); + topPanel.doLayout(); + } + + else if (n.equals( + JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY)) + { + if (filechooser.isAcceptAllFileFilterUsed()) + filechooser.addChoosableFileFilter( + getAcceptAllFileFilter(filechooser)); + else + filechooser.removeChoosableFileFilter( + getAcceptAllFileFilter(filechooser)); + } + + else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) + { + JComponent old = (JComponent) e.getOldValue(); + if (old != null) + getAccessoryPanel().remove(old); + JComponent newval = (JComponent) e.getNewValue(); + if (newval != null) + getAccessoryPanel().add(newval); + } + + if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY) + || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY) + || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY)) + { + // Remove editing component + if (fileTable != null) + fileTable.removeAll(); + if (fileList != null) + fileList.removeAll(); + startEditing = false; + + // Set text on button back to original. + if (filechooser.getDialogType() == JFileChooser.SAVE_DIALOG) + { + directoryLabel = save; + dirLabel.setText(directoryLabel); + filechooser.setApproveButtonText(saveButtonText); + filechooser.setApproveButtonToolTipText(saveButtonToolTipText); + } + + rescanCurrentDirectory(filechooser); + } + + filechooser.revalidate(); + filechooser.repaint(); + } + }; + /** * A combo box model containing the selected directory and all its parent * directories. */ - protected class DirectoryComboBoxModel extends AbstractListModel + protected class DirectoryComboBoxModel + extends AbstractListModel implements ComboBoxModel { /** Storage for the items in the model. */ @@ -161,7 +543,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI /** * Handles changes to the selection in the directory combo box. */ - protected class DirectoryComboBoxAction extends AbstractAction + protected class DirectoryComboBoxAction + extends AbstractAction { /** * Creates a new action. @@ -184,9 +567,60 @@ public class MetalFileChooserUI extends BasicFileChooserUI } /** + * A renderer for the items in the directory combo box. + */ + class DirectoryComboBoxRenderer + extends DefaultListCellRenderer + { + /** + * Creates a new renderer. + */ + public DirectoryComboBoxRenderer(JFileChooser fc) + { + } + + /** + * Returns a component that can be used to paint the given value within + * the list. + * + * @param list the list. + * @param value the value (a {@link File}). + * @param index the item index. + * @param isSelected is the item selected? + * @param cellHasFocus does the list cell have focus? + * + * @return The list cell renderer. + */ + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) + { + FileView fileView = getFileView(getFileChooser()); + File file = (File) value; + setIcon(fileView.getIcon(file)); + setText(fileView.getName(file)); + + if (isSelected) + { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } + else + { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + + setEnabled(list.isEnabled()); + setFont(list.getFont()); + return this; + } + } + + /** * A renderer for the files and directories in the file chooser. */ - protected class FileRenderer extends DefaultListCellRenderer + protected class FileRenderer + extends DefaultListCellRenderer { /** @@ -213,8 +647,17 @@ public class MetalFileChooserUI extends BasicFileChooserUI { FileView v = getFileView(getFileChooser()); File f = (File) value; - setText(v.getName(f)); - setIcon(v.getIcon(f)); + if (f != null) + { + setText(v.getName(f)); + setIcon(v.getIcon(f)); + } + else + { + setText(""); + setIcon(null); + } + setOpaque(true); if (isSelected) { setBackground(list.getSelectionBackground()); @@ -249,7 +692,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI protected FileFilter[] filters; /** The index of the selected file filter. */ - private int selectedIndex; + private Object selected; /** * Creates a new model. @@ -258,7 +701,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { filters = new FileFilter[1]; filters[0] = getAcceptAllFileFilter(getFileChooser()); - selectedIndex = 0; + selected = filters[0]; } /** @@ -270,11 +713,11 @@ public class MetalFileChooserUI extends BasicFileChooserUI { if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) { - selectedIndex = -1; - FileFilter selected = (FileFilter) e.getNewValue(); - for (int i = 0; i < filters.length; i++) - if (filters[i].equals(selected)) - selectedIndex = i; + JFileChooser fc = getFileChooser(); + FileFilter[] choosableFilters = fc.getChoosableFileFilters(); + filters = choosableFilters; + fireContentsChanged(this, 0, filters.length); + selected = e.getNewValue(); fireContentsChanged(this, -1, -1); } else if (e.getPropertyName().equals( @@ -291,13 +734,15 @@ public class MetalFileChooserUI extends BasicFileChooserUI /** * Sets the selected filter. * - * @param filter the filter. + * @param filter the filter (<code>null</code> ignored). */ public void setSelectedItem(Object filter) { - // change the filter in the file chooser and let the property change - // event trigger the change to the selected item - getFileChooser().setFileFilter((FileFilter) filter); + if (filter != null) + { + selected = filter; + fireContentsChanged(this, -1, -1); + } } /** @@ -307,9 +752,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI */ public Object getSelectedItem() { - if (selectedIndex >= 0) - return filters[selectedIndex]; - return null; + return selected; } /** @@ -339,7 +782,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI /** * A renderer for the items in the file filter combo box. */ - public class FilterComboBoxRenderer extends DefaultListCellRenderer + public class FilterComboBoxRenderer + extends DefaultListCellRenderer { /** * Creates a new renderer. @@ -359,20 +803,488 @@ public class MetalFileChooserUI extends BasicFileChooserUI * @param isSelected is the item selected? * @param cellHasFocus does the list cell have focus? * - * @return A component. + * @return This component as the renderer. */ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, + cellHasFocus); FileFilter filter = (FileFilter) value; - return super.getListCellRendererComponent(list, filter.getDescription(), - index, isSelected, cellHasFocus); + setText(filter.getDescription()); + return this; + } + } + + /** + * A listener for selection events in the file list. + * + * @see #createListSelectionListener(JFileChooser) + */ + class MetalFileChooserSelectionListener + implements ListSelectionListener + { + /** + * Creates a new <code>SelectionListener</code> object. + */ + protected MetalFileChooserSelectionListener() + { + // Do nothing here. + } + + /** + * Makes changes to different properties when + * a value has changed in the filechooser's selection. + * + * @param e - the list selection event that occured. + */ + public void valueChanged(ListSelectionEvent e) + { + File f = (File) fileList.getSelectedValue(); + if (f == null) + return; + JFileChooser filechooser = getFileChooser(); + if (! filechooser.isTraversable(f)) + filechooser.setSelectedFile(f); + else + filechooser.setSelectedFile(null); + } + } + + /** + * A mouse listener for the {@link JFileChooser}. + * This listener is used for editing filenames. + */ + protected class SingleClickListener + extends MouseAdapter + { + + /** Stores instance of the list */ + JList list; + + /** + * Stores the current file that is being edited. + * It is null if nothing is currently being edited. + */ + File editFile; + + /** The current file chooser. */ + JFileChooser fc; + + /** The last file selected. */ + Object lastSelected; + + /** The textfield used for editing. */ + JTextField editField; + + /** + * Creates a new listener. + * + * @param list the directory/file list. + */ + public SingleClickListener(JList list) + { + this.list = list; + editFile = null; + fc = getFileChooser(); + lastSelected = null; + startEditing = false; + } + + /** + * Receives notification of a mouse click event. + * + * @param e the event. + */ + public void mouseClicked(MouseEvent e) + { + if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) + { + int index = list.locationToIndex(e.getPoint()); + File[] sf = fc.getSelectedFiles(); + if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1)) + && index >= 0 && !startEditing && list.isSelectedIndex(index)) + { + Object tmp = list.getModel().getElementAt(index); + if (lastSelected != null && lastSelected.equals(tmp)) + editFile(index); + lastSelected = tmp; + } + else + completeEditing(); + } + else + completeEditing(); + } + + /** + * Sets up the text editor for the current file. + * + * @param index - + * the current index of the item in the list to be edited. + */ + void editFile(int index) + { + Rectangle bounds = list.getCellBounds(index, index); + list.scrollRectToVisible(bounds); + editFile = (File) list.getModel().getElementAt(index); + if (editFile.canWrite()) + { + startEditing = true; + editField = new JTextField(editFile.getName()); + editField.addActionListener(new EditingActionListener()); + + Icon icon = getFileView(fc).getIcon(editFile); + if (icon != null) + { + int padding = icon.getIconWidth() + 4; + bounds.x += padding; + bounds.width -= padding; + } + editField.setBounds(bounds); + + list.add(editField); + + editField.requestFocus(); + editField.selectAll(); + } + else + completeEditing(); + list.repaint(); + } + + /** + * Completes the editing. + */ + void completeEditing() + { + if (editField != null && editFile != null) + { + String text = editField.getText(); + if (text != null && text != "" && !text.equals(fc.getName(editFile))) + if (editFile.renameTo + (fc.getFileSystemView().createFileObject + (fc.getCurrentDirectory(), text))) + rescanCurrentDirectory(fc); + list.remove(editField); + } + startEditing = false; + editFile = null; + lastSelected = null; + editField = null; + list.repaint(); + } + + /** + * ActionListener for the editing text field. + */ + class EditingActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (e.getActionCommand().equals("notify-field-accept")) + completeEditing(); + else if (editField != null) + { + list.remove(editField); + startEditing = false; + editFile = null; + lastSelected = null; + editField = null; + list.repaint(); + } + } } } + /** + * A mouse listener for the {@link JFileChooser}. + * This listener is used for the table + */ + private class TableClickListener extends MouseAdapter + { + + /** Stores instance of the table */ + JTable table; + + /** Stores instance of the file chooser */ + JFileChooser fc; + + /** The last selected file. */ + Object lastSelected = null; + + /** + * Stores the current file that is being edited. + * It is null if nothing is currently being edited. + */ + File editFile; + + /** The textfield used for editing. */ + JTextField editField; + + /** + * Creates a new listener. + * + * @param table + * the directory/file table + * @param fc + * the JFileChooser + */ + public TableClickListener(JTable table, JFileChooser fc) + { + this.table = table; + this.fc = fc; + lastSelected = fileList.getSelectedValue(); + setDirectorySelected(false); + startEditing = false; + editFile = null; + editField = null; + } + + /** + * Receives notification of a mouse click event. + * + * @param e + * the event. + */ + public void mouseClicked(MouseEvent e) + { + int row = table.getSelectedRow(); + Object selVal = fileList.getModel().getElementAt(row); + if (selVal == null) + return; + FileSystemView fsv = fc.getFileSystemView(); + if (e.getClickCount() == 1 && + selVal.equals(lastSelected) && + e.getButton() == MouseEvent.BUTTON1) + { + File[] sf = fc.getSelectedFiles(); + if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1)) + && !startEditing) + { + editFile = (File) selVal; + editFile(row); + } + } + else if (e.getClickCount() >= 2 && + selVal.equals(lastSelected)) + { + if (startEditing) + completeEditing(); + File f = fsv.createFileObject(lastSelected.toString()); + if (fc.isTraversable(f)) + { + fc.setCurrentDirectory(f); + fc.rescanCurrentDirectory(); + } + else + { + fc.setSelectedFile(f); + fc.approveSelection(); + closeDialog(); + } + } + else + { + if (startEditing) + completeEditing(); + String path = selVal.toString(); + File f = fsv.createFileObject(path); + fc.setSelectedFile(f); + if (fc.isTraversable(f)) + { + setDirectorySelected(true); + setDirectory(f); + } + else + { + setDirectorySelected(false); + setDirectory(null); + } + lastSelected = selVal; + if (f.isFile()) + setFileName(path.substring(path.lastIndexOf("/") + 1)); + else if (fc.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) + setFileName(path); + } + fileTable.repaint(); + } + + /** + * Sets up the text editor for the current file. + * + * @param row - + * the current row of the item in the list to be edited. + */ + void editFile(int row) + { + Rectangle bounds = table.getCellRect(row, 0, true); + table.scrollRectToVisible(bounds); + if (editFile.canWrite()) + { + startEditing = true; + editField = new JTextField(editFile.getName()); + editField.addActionListener(new EditingActionListener()); + + // Need to adjust y pos + bounds.y = row * table.getRowHeight(); + editField.setBounds(bounds); + + table.add(editField); + + editField.requestFocus(); + editField.selectAll(); + } + else + completeEditing(); + table.repaint(); + } + + /** + * Completes the editing. + */ + void completeEditing() + { + if (editField != null && editFile != null) + { + String text = editField.getText(); + if (text != null && text != "" && !text.equals(fc.getName(editFile))) + if (editFile.renameTo + (fc.getFileSystemView().createFileObject + (fc.getCurrentDirectory(), text))) + rescanCurrentDirectory(fc); + table.remove(editField); + } + startEditing = false; + editFile = null; + editField = null; + table.repaint(); + } + + /** + * ActionListener for the editing text field. + */ + class EditingActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (e.getActionCommand().equals("notify-field-accept")) + completeEditing(); + else if (editField != null) + { + table.remove(editField); + startEditing = false; + editFile = null; + editField = null; + table.repaint(); + } + } + } + + /** + * Closes the dialog. + */ + public void closeDialog() + { + Window owner = SwingUtilities.windowForComponent(fc); + if (owner instanceof JDialog) + ((JDialog) owner).dispose(); + } + } + + /** The text for a label describing the directory combo box. */ + private String directoryLabel; + + private JComboBox directoryComboBox; + /** The model for the directory combo box. */ DirectoryComboBoxModel directoryModel; + /** The text for a label describing the file text field. */ + private String fileLabel; + + /** The file name text field. */ + private JTextField fileTextField; + + /** The text for a label describing the filter combo box. */ + private String filterLabel; + + /** + * The top panel (contains the directory combo box and the control buttons). + */ + private JPanel topPanel; + + /** A panel containing the control buttons ('up', 'home' etc.). */ + private JPanel controls; + + /** + * The panel that contains the filename field and the filter combobox. + */ + private JPanel bottomPanel; + + /** + * The panel that contains the 'Open' (or 'Save') and 'Cancel' buttons. + */ + private JPanel buttonPanel; + + private JButton approveButton; + + /** The file list. */ + JList fileList; + + /** The file table. */ + JTable fileTable; + + /** The panel containing the file list. */ + JPanel fileListPanel; + + /** The panel containing the file table. */ + JPanel fileTablePanel; + + /** The filter combo box model. */ + private FilterComboBoxModel filterModel; + + /** The action map. */ + private ActionMap actionMap; + + /** True if currently in list view. */ + boolean listView; + + /** True if we can or have started editing a cell. */ + boolean startEditing; + + /** The scrollpane used for the table and list. */ + JScrollPane scrollPane; + + /** The text for the label when saving. */ + String save; + + /** The text for the label when opening a directory. */ + String look; + + /** The label for the file combo box. */ + JLabel dirLabel; + + /** Listeners. */ + ListSelectionListener listSelList; + MouseListener doubleClickList; + SingleClickListener singleClickList; + TableClickListener tableClickList; + /** * A factory method that returns a UI delegate for the specified * component. @@ -393,9 +1305,439 @@ public class MetalFileChooserUI extends BasicFileChooserUI public MetalFileChooserUI(JFileChooser filechooser) { super(filechooser); + bottomPanel = new JPanel(new GridLayout(3, 2)); + buttonPanel = new JPanel(); + } + + public void installUI(JComponent c) + { + super.installUI(c); + actionMap = createActionMap(); + } + + public void uninstallUI(JComponent c) + { + super.uninstallUI(c); + actionMap = null; + } + + /** + * Installs the sub-components of the file chooser. + * + * @param fc the file chooser component. + */ + public void installComponents(JFileChooser fc) + { + fc.setLayout(new BorderLayout()); + topPanel = new JPanel(new BorderLayout()); + dirLabel = new JLabel(directoryLabel); + topPanel.add(dirLabel, BorderLayout.WEST); + this.controls = new JPanel(); + addControlButtons(); + + JPanel dirPanel = new JPanel(new VerticalMidLayout()); + directoryModel = createDirectoryComboBoxModel(fc); + directoryComboBox = new JComboBox(directoryModel); + directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc)); + dirPanel.add(directoryComboBox); + topPanel.add(dirPanel); + topPanel.add(controls, BorderLayout.EAST); + topPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8)); + fc.add(topPanel, BorderLayout.NORTH); + + JPanel list = createList(fc); + list.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); + fc.add(list, BorderLayout.CENTER); + + JPanel bottomPanel = getBottomPanel(); + filterModel = createFilterComboBoxModel(); + JComboBox fileFilterCombo = new JComboBox(filterModel); + fileFilterCombo.setRenderer(createFilterComboBoxRenderer()); + + fileTextField = new JTextField(); + JPanel fileNamePanel = new JPanel(new VerticalMidLayout()); + fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 5)); + fileNamePanel.add(fileTextField); + JPanel row1 = new JPanel(new BorderLayout()); + row1.add(new JLabel(this.fileLabel), BorderLayout.WEST); + row1.add(fileNamePanel); + bottomPanel.add(row1); + + JPanel row2 = new JPanel(new BorderLayout()); + row2.add(new JLabel(this.filterLabel), BorderLayout.WEST); + row2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + row2.add(fileFilterCombo); + bottomPanel.add(row2); + JPanel buttonPanel = new JPanel(new ButtonLayout()); + + approveButton = new JButton(getApproveSelectionAction()); + approveButton.setText(getApproveButtonText(fc)); + approveButton.setToolTipText(getApproveButtonToolTipText(fc)); + approveButton.setMnemonic(getApproveButtonMnemonic(fc)); + buttonPanel.add(approveButton); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0)); + + JButton cancelButton = new JButton(getCancelSelectionAction()); + cancelButton.setText(cancelButtonText); + cancelButton.setToolTipText(cancelButtonToolTipText); + cancelButton.setMnemonic(cancelButtonMnemonic); + buttonPanel.add(cancelButton); + bottomPanel.add(buttonPanel, BorderLayout.SOUTH); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8)); + fc.add(bottomPanel, BorderLayout.SOUTH); + + fc.add(getAccessoryPanel(), BorderLayout.EAST); + } + + /** + * Uninstalls the components added by + * {@link #installComponents(JFileChooser)}. + * + * @param fc the file chooser. + */ + public void uninstallComponents(JFileChooser fc) + { + fc.remove(bottomPanel); + bottomPanel = null; + fc.remove(fileListPanel); + fc.remove(fileTablePanel); + fileTablePanel = null; + fileListPanel = null; + fc.remove(topPanel); + topPanel = null; + + directoryModel = null; + fileTextField = null; + directoryComboBox = null; + } + + /** + * Returns the panel that contains the 'Open' (or 'Save') and 'Cancel' + * buttons. + * + * @return The panel. + */ + protected JPanel getButtonPanel() + { + return buttonPanel; + } + + /** + * Creates and returns a new panel that will be used for the controls at + * the bottom of the file chooser. + * + * @return A new panel. + */ + protected JPanel getBottomPanel() + { + if (bottomPanel == null) + bottomPanel = new JPanel(new GridLayout(3, 2)); + return bottomPanel; + } + + /** + * Fetches localised strings for use by the labels and buttons on the + * file chooser. + * + * @param fc the file chooser. + */ + protected void installStrings(JFileChooser fc) + { + super.installStrings(fc); + look = "Look In: "; + save = "Save In: "; + if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) + directoryLabel = save; + else + directoryLabel = look; + + fileLabel = "File Name: "; + filterLabel = "Files of Type: "; + + this.cancelButtonMnemonic = 0; + this.cancelButtonText = "Cancel"; + this.cancelButtonToolTipText = "Abort file chooser dialog"; + + this.directoryOpenButtonMnemonic = 0; + this.directoryOpenButtonText = "Open"; + this.directoryOpenButtonToolTipText = "Open selected directory"; + + this.helpButtonMnemonic = 0; + this.helpButtonText = "Help"; + this.helpButtonToolTipText = "Filechooser help"; + + this.openButtonMnemonic = 0; + this.openButtonText = "Open"; + this.openButtonToolTipText = "Open selected file"; + + this.saveButtonMnemonic = 0; + this.saveButtonText = "Save"; + this.saveButtonToolTipText = "Save selected file"; + + this.updateButtonMnemonic = 0; + this.updateButtonText = "Update"; + this.updateButtonToolTipText = "Update directory listing"; + } + + /** + * Installs the listeners required. + * + * @param fc the file chooser. + */ + protected void installListeners(JFileChooser fc) + { + directoryComboBox.setAction(new DirectoryComboBoxAction()); + fc.addPropertyChangeListener(filterModel); + listSelList = createListSelectionListener(fc); + doubleClickList = this.createDoubleClickListener(fc, fileList); + singleClickList = new SingleClickListener(fileList); + fileList.addListSelectionListener(listSelList); + fileList.addMouseListener(doubleClickList); + fileList.addMouseListener(singleClickList); + super.installListeners(fc); + } + + protected void uninstallListeners(JFileChooser fc) + { + super.uninstallListeners(fc); + fc.removePropertyChangeListener(filterModel); + directoryComboBox.setAction(null); + fileList.removeListSelectionListener(listSelList); + fileList.removeMouseListener(doubleClickList); + fileList.removeMouseListener(singleClickList); + + if (fileTable != null) + fileTable.removeMouseListener(tableClickList); + } + + protected ActionMap getActionMap() + { + if (actionMap == null) + actionMap = createActionMap(); + return actionMap; + } + + /** + * Creates and returns an action map. + * + * @return The action map. + */ + protected ActionMap createActionMap() + { + ActionMap map = new ActionMap(); + map.put("approveSelection", getApproveSelectionAction()); + map.put("cancelSelection", getCancelSelectionAction()); + map.put("Go Up", getChangeToParentDirectoryAction()); + return map; + } + + /** + * Creates a panel containing a list of files. + * + * @param fc the file chooser. + * + * @return A panel. + */ + protected JPanel createList(JFileChooser fc) + { + if (fileList == null) + { + fileListPanel = new JPanel(new BorderLayout()); + fileList = new JList(getModel()); + scrollPane = new JScrollPane(fileList); + scrollPane.setVerticalScrollBarPolicy + (JScrollPane.VERTICAL_SCROLLBAR_NEVER); + fileList.setLayoutOrientation(JList.VERTICAL_WRAP); + fileList.setCellRenderer(new FileRenderer()); + } + else + { + fileList.setModel(getModel()); + fileListPanel.removeAll(); + scrollPane.getViewport().setView(fileList); + } + fileListPanel.add(scrollPane); + + return fileListPanel; + } + + /** + * Creates a panel containing a table within a scroll pane. + * + * @param fc the file chooser. + * + * @return The details view. + */ + protected JPanel createDetailsView(JFileChooser fc) + { + fileTablePanel = new JPanel(new BorderLayout()); + + Object[] cols = new Object[] {"Name", "Size", "Modified"}; + Object[][] rows = new Object[fileList.getModel().getSize()][3]; + + fileTable = new JTable(new DefaultTableModel(rows, cols)); + + if (fc.isMultiSelectionEnabled()) + fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + else + fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + fileTable.setShowGrid(false); + fileTable.setColumnSelectionAllowed(false); + fileTable.setDefaultRenderer(Object.class, new TableFileRenderer()); + + tableClickList = new TableClickListener(fileTable, fc); + fileTable.addMouseListener(tableClickList); + + return updateTable(); + } + + /** + * Sets the values in the table, and puts it in the panel. + * + * @return the panel containing the table. + */ + JPanel updateTable() + { + DefaultTableModel mod = (DefaultTableModel) fileTable.getModel(); + ListModel lm = fileList.getModel(); + DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT, + DateFormat.SHORT); + File curr = null; + int size = lm.getSize(); + int rc = mod.getRowCount(); + + // If there are not enough rows + for (int x = rc; x < size; x++) + mod.addRow(new Object[3]); + + for (int i = 0; i < size; i++) + { + curr = (File) lm.getElementAt(i); + fileTable.setValueAt(curr.getName(), i, 0); + fileTable.setValueAt(formatSize(curr.length()), i, 1); + fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2); + } + + // If there are too many rows + while (rc > size) + mod.removeRow(--rc); + + scrollPane.getViewport().setView(fileTable); + scrollPane.setColumnHeaderView(fileTable.getTableHeader()); + + fileTablePanel.removeAll(); + fileTablePanel.add(scrollPane); + + return fileTablePanel; + } + + /** + * Formats bytes into the appropriate size. + * + * @param bytes - + * the number of bytes to convert + * @return a string representation of the size + */ + private String formatSize(long bytes) + { + NumberFormat nf = NumberFormat.getNumberInstance(); + long mb = (long) Math.pow(2, 20); + long kb = (long) Math.pow(2, 10); + long gb = (long) Math.pow(2, 30); + double size = 0; + String id = ""; + + if ((bytes / gb) >= 1) + { + size = (double) bytes / (double) gb; + id = "GB"; + } + else if ((bytes / mb) >= 1) + { + size = (double) bytes / (double) mb; + id = "MB"; + } + else if ((bytes / kb) >= 1) + { + size = (double) bytes / (double) kb; + id = "KB"; + } + else + { + size = bytes; + id = "Bytes"; + } + + return nf.format(size) + " " + id; + } + /** + * Creates a listener that monitors selections in the directory/file list + * and keeps the {@link JFileChooser} component up to date. + * + * @param fc the file chooser. + * + * @return The listener. + * + * @see #installListeners(JFileChooser) + */ + public ListSelectionListener createListSelectionListener(JFileChooser fc) + { + return new MetalFileChooserSelectionListener(); + } + + /** + * Returns the preferred size for the file chooser component. + * + * @return The preferred size. + */ + public Dimension getPreferredSize(JComponent c) + { + Dimension tp = topPanel.getPreferredSize(); + Dimension bp = bottomPanel.getPreferredSize(); + Dimension fl = fileListPanel.getPreferredSize(); + return new Dimension(fl.width, tp.height + bp.height + fl.height); + } + + /** + * Returns the minimum size for the file chooser component. + * + * @return The minimum size. + */ + public Dimension getMinimumSize(JComponent c) + { + Dimension tp = topPanel.getMinimumSize(); + Dimension bp = bottomPanel.getMinimumSize(); + Dimension fl = fileListPanel.getMinimumSize(); + return new Dimension(fl.width, tp.height + bp.height + fl.height); } /** + * Returns the maximum size for the file chooser component. + * + * @return The maximum size. + */ + public Dimension getMaximumSize(JComponent c) + { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + /** + * Creates a property change listener that monitors the {@link JFileChooser} + * for property change events and updates the component display accordingly. + * + * @param fc the file chooser. + * + * @return The property change listener. + * + * @see #installListeners(JFileChooser) + */ + public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) + { + return new MetalFileChooserPropertyChangeListener(); + } + + /** * Creates and returns a new instance of {@link DirectoryComboBoxModel}. * * @return A new instance of {@link DirectoryComboBoxModel}. @@ -407,6 +1749,20 @@ public class MetalFileChooserUI extends BasicFileChooserUI } /** + * Creates a new instance of the renderer used in the directory + * combo box. + * + * @param fc the file chooser. + * + * @return The renderer. + */ + protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer( + JFileChooser fc) + { + return new DirectoryComboBoxRenderer(fc); + } + + /** * Creates and returns a new instance of {@link FilterComboBoxModel}. * * @return A new instance of {@link FilterComboBoxModel}. @@ -427,4 +1783,297 @@ public class MetalFileChooserUI extends BasicFileChooserUI return new FilterComboBoxRenderer(); } + /** + * Adds the control buttons ('up', 'home' etc.) to the panel. + */ + protected void addControlButtons() + { + JButton upButton = new JButton(getChangeToParentDirectoryAction()); + upButton.setText(null); + upButton.setIcon(this.upFolderIcon); + upButton.setMargin(new Insets(0, 0, 0, 0)); + controls.add(upButton); + + JButton homeButton = new JButton(getGoHomeAction()); + homeButton.setText(null); + homeButton.setIcon(this.homeFolderIcon); + homeButton.setMargin(new Insets(0, 0, 0, 0)); + controls.add(homeButton); + + JButton newFolderButton = new JButton(getNewFolderAction()); + newFolderButton.setText(null); + newFolderButton.setIcon(this.newFolderIcon); + newFolderButton.setMargin(new Insets(0, 0, 0, 0)); + controls.add(newFolderButton); + + JToggleButton listButton = new JToggleButton(this.listViewIcon); + listButton.setMargin(new Insets(0, 0, 0, 0)); + listButton.addActionListener(new ListViewActionListener()); + listButton.setSelected(true); + listView = true; + controls.add(listButton); + + JToggleButton detailButton = new JToggleButton(this.detailsViewIcon); + detailButton.setMargin(new Insets(0, 0, 0, 0)); + detailButton.addActionListener(new DetailViewActionListener()); + detailButton.setSelected(false); + controls.add(detailButton); + + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(listButton); + buttonGroup.add(detailButton); + } + + /** + * Removes all the buttons from the control panel. + */ + protected void removeControlButtons() + { + controls.removeAll(); + controls.revalidate(); + controls.repaint(); + } + + /** + * Updates the current directory. + * + * @param the file chooser to update. + */ + public void rescanCurrentDirectory(JFileChooser fc) + { + directoryModel.setSelectedItem(fc.getCurrentDirectory()); + getModel().validateFileCache(); + if (!listView) + updateTable(); + else + createList(fc); + } + + /** + * Returns the file name in the text field. + * + * @return The file name. + */ + public String getFileName() + { + String result = null; + if (fileTextField != null) + result = fileTextField.getText(); + return result; + } + + /** + * Sets the file name in the text field. + * + * @param filename the file name. + */ + public void setFileName(String filename) + { + fileTextField.setText(filename); + } + + /** + * DOCUMENT ME!! + * + * @param e - DOCUMENT ME! + */ + public void valueChanged(ListSelectionEvent e) + { + // FIXME: Not sure what we should be doing here, if anything. + } + + /** + * Returns the approve button. + * + * @return The approve button. + */ + protected JButton getApproveButton(JFileChooser fc) + { + return approveButton; + } + + /** + * A layout manager that is used to arrange the subcomponents of the + * {@link JFileChooser}. + */ + class VerticalMidLayout implements LayoutManager + { + /** + * Performs the layout. + * + * @param parent the container. + */ + public void layoutContainer(Container parent) + { + int count = parent.getComponentCount(); + if (count > 0) + { + Insets insets = parent.getInsets(); + Component c = parent.getComponent(0); + Dimension prefSize = c.getPreferredSize(); + int h = parent.getHeight() - insets.top - insets.bottom; + int adj = Math.max(0, (h - prefSize.height) / 2); + c.setBounds(insets.left, insets.top + adj, parent.getWidth() + - insets.left - insets.right, + (int) Math.min(prefSize.getHeight(), h)); + } + } + + /** + * Returns the minimum layout size. + * + * @param parent the container. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container parent) + { + return preferredLayoutSize(parent); + } + + /** + * Returns the preferred layout size. + * + * @param parent the container. + * + * @return The preferred layout size. + */ + public Dimension preferredLayoutSize(Container parent) + { + if (parent.getComponentCount() > 0) + { + return parent.getComponent(0).getPreferredSize(); + } + else return null; + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param name the name the component is associated with. + * @param component the component. + */ + public void addLayoutComponent(String name, Component component) + { + // do nothing + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param component the component. + */ + public void removeLayoutComponent(Component component) { + // do nothing + } + } + + /** + * A layout manager that is used to arrange buttons for the + * {@link JFileChooser}. + */ + class ButtonLayout implements LayoutManager + { + static final int GAP = 4; + + /** + * Performs the layout. + * + * @param parent the container. + */ + public void layoutContainer(Container parent) + { + int count = parent.getComponentCount(); + if (count > 0) + { + // first find the widest button + int maxW = 0; + for (int i = 0; i < count; i++) + { + Component c = parent.getComponent(i); + Dimension prefSize = c.getPreferredSize(); + maxW = Math.max(prefSize.width, maxW); + } + + // then position the buttons + Insets insets = parent.getInsets(); + int availableH = parent.getHeight() - insets.top - insets.bottom; + int currentX = parent.getWidth() - insets.right; + for (int i = count - 1; i >= 0; i--) + { + Component c = parent.getComponent(i); + Dimension prefSize = c.getPreferredSize(); + int adj = Math.max(0, (availableH - prefSize.height) / 2); + currentX = currentX - prefSize.width; + c.setBounds(currentX, insets.top + adj, prefSize.width, + (int) Math.min(prefSize.getHeight(), availableH)); + currentX = currentX - GAP; + } + } + } + + /** + * Returns the minimum layout size. + * + * @param parent the container. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container parent) + { + return preferredLayoutSize(parent); + } + + /** + * Returns the preferred layout size. + * + * @param parent the container. + * + * @return The preferred layout size. + */ + public Dimension preferredLayoutSize(Container parent) + { + Insets insets = parent.getInsets(); + int maxW = 0; + int maxH = 0; + int count = parent.getComponentCount(); + if (count > 0) + { + for (int i = 0; i < count; i++) + { + Component c = parent.getComponent(i); + Dimension d = c.getPreferredSize(); + maxW = Math.max(d.width, maxW); + maxH = Math.max(d.height, maxH); + } + } + return new Dimension(maxW * count + GAP * (count - 1) + insets.left + + insets.right, maxH + insets.top + insets.bottom); + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param name the name the component is associated with. + * @param component the component. + */ + public void addLayoutComponent(String name, Component component) + { + // do nothing + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param component the component. + */ + public void removeLayoutComponent(Component component) { + // do nothing + } + } + } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java index bcb86e6..0b644f3 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java @@ -68,6 +68,12 @@ public class MetalIconFactory implements Serializable /** A constant representing "light". */ public static final boolean LIGHT = true; + + /** A shared instance of the MenuArrowIcon. */ + private static Icon menuArrow; + + /** A shared instance of the MenuItemArrowIcon. */ + private static Icon menuItemArrow; /** * An icon displayed for {@link JCheckBoxMenuItem} components. @@ -2467,4 +2473,102 @@ public class MetalIconFactory implements Serializable return treeHardDriveIcon; } + /** + * Returns a new instance of a 4 x 8 icon showing a small black triangle that + * points to the right. This is displayed in menu items that have a + * sub menu. + * + * @return The icon. + */ + public static Icon getMenuArrowIcon() + { + if (menuArrow == null) + menuArrow = new Icon() + { + public int getIconHeight() + { + return 8; + } + + public int getIconWidth() + { + return 4; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + Color saved = g.getColor(); + g.setColor(Color.BLACK); + for (int i = 0; i < 4; i++) + g.drawLine(x + i, y + i, x + i, y + 7 - i); + g.setColor(saved); + } + }; + return menuArrow; + } + + /** + * Returns a new instance of a 4 x 8 icon showing a small black triangle that + * points to the right. This is displayed in menu items that have a sub menu. + * + * @return The icon. + */ + public static Icon getMenuItemArrowIcon() + { + if (menuItemArrow == null) + menuItemArrow = new Icon() + { + public int getIconHeight() + { + return 8; + } + + public int getIconWidth() + { + return 4; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + Color saved = g.getColor(); + g.setColor(Color.BLACK); + for (int i = 0; i < 4; i++) + g.drawLine(x + i, y + i, x + i, y + 7 - i); + g.setColor(saved); + } + }; + return menuItemArrow; + } + + /** + * Returns a new instance of a 13 x 13 icon showing a small black check mark. + * + * @return The icon. + */ + public static Icon getMenuItemCheckIcon() + { + return new Icon() + { + public int getIconHeight() + { + return 13; + } + + public int getIconWidth() + { + return 13; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + Color saved = g.getColor(); + g.setColor(Color.BLACK); + g.drawLine(3 + x, 5 + y, 3 + x, 9 + y); + g.drawLine(4 + x, 5 + y, 4 + x, 9 + y); + g.drawLine(5 + x, 7 + y, 9 + x, 3 + y); + g.drawLine(5 + x, 8 + y, 9 + x, 4 + y); + g.setColor(saved); + } + }; + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java index da01937..c60b55c 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -40,7 +40,6 @@ package javax.swing.plaf.metal; import java.awt.Color; import java.awt.Font; -import java.awt.Insets; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; @@ -55,7 +54,17 @@ import javax.swing.plaf.basic.BasicLookAndFeel; /** * A custom look and feel that is designed to look similar across different - * operating systems. + * operating systems. To install this look and feel, add the following code + * (or something similar) near the start of your application:</p> + * <pre> + * try + * { + * UIManager.setLookAndFeel(new MetalLookAndFeel()); + * } + * catch (UnsupportedLookAndFeelException e) + * { + * e.printStackTrace(); + * }</pre> */ public class MetalLookAndFeel extends BasicLookAndFeel { @@ -72,8 +81,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public MetalLookAndFeel() { - if (theme == null) - createDefaultTheme(); + createDefaultTheme(); } /** @@ -81,7 +89,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ protected void createDefaultTheme() { - setCurrentTheme(new DefaultMetalTheme()); + if (theme == null) + setCurrentTheme(new DefaultMetalTheme()); } /** @@ -115,7 +124,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public String getDescription() { - return "Metal look and feel"; + return "The Java(tm) Look and Feel"; } /** @@ -125,7 +134,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public String getID() { - return "MetalLookAndFeel"; + return "Metal"; } /** @@ -135,7 +144,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public String getName() { - return "MetalLookAndFeel"; + return "Metal"; } public UIDefaults getDefaults() @@ -145,7 +154,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel LAF_defaults = super.getDefaults(); // add custom theme entries to the table - theme.addCustomEntriesToTable(LAF_defaults); + if (theme != null) + theme.addCustomEntriesToTable(LAF_defaults); } // Returns the default values for this look and feel. @@ -159,7 +169,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getAcceleratorForeground() { - return theme.getAcceleratorForeground(); + if (theme != null) + return theme.getAcceleratorForeground(); + return null; } /** @@ -170,7 +182,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getAcceleratorSelectedForeground() { - return theme.getAcceleratorSelectedForeground(); + if (theme != null) + return theme.getAcceleratorSelectedForeground(); + return null; } /** @@ -180,7 +194,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getBlack() { - return theme.getBlack(); + if (theme != null) + return theme.getBlack(); + return null; } /** @@ -190,7 +206,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControl() { - return theme.getControl(); + if (theme != null) + return theme.getControl(); + return null; } /** @@ -201,7 +219,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlDarkShadow() { - return theme.getControlDarkShadow(); + if (theme != null) + return theme.getControlDarkShadow(); + return null; } /** @@ -211,7 +231,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlDisabled() { - return theme.getControlDisabled(); + if (theme != null) + return theme.getControlDisabled(); + return null; } /** @@ -222,7 +244,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlHighlight() { - return theme.getControlHighlight(); + if (theme != null) + return theme.getControlHighlight(); + return null; } /** @@ -233,7 +257,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlInfo() { - return theme.getControlInfo(); + if (theme != null) + return theme.getControlInfo(); + return null; } /** @@ -244,7 +270,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlShadow() { - return theme.getControlShadow(); + if (theme != null) + return theme.getControlShadow(); + return null; } /** @@ -254,7 +282,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlTextColor() { - return theme.getControlTextColor(); + if (theme != null) + return theme.getControlTextColor(); + return null; } /** @@ -264,7 +294,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getControlTextFont() { - return theme.getControlTextFont(); + if (theme != null) + return theme.getControlTextFont(); + return null; } /** @@ -275,7 +307,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getDesktopColor() { - return theme.getDesktopColor(); + if (theme != null) + return theme.getDesktopColor(); + return null; } /** @@ -286,7 +320,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getFocusColor() { - return theme.getFocusColor(); + if (theme != null) + return theme.getFocusColor(); + return null; } /** @@ -297,7 +333,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getHighlightedTextColor() { - return theme.getHighlightedTextColor(); + if (theme != null) + return theme.getHighlightedTextColor(); + return null; } /** @@ -308,7 +346,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getInactiveControlTextColor() { - return theme.getInactiveControlTextColor(); + if (theme != null) + return theme.getInactiveControlTextColor(); + return null; } /** @@ -319,7 +359,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getInactiveSystemTextColor() { - return theme.getInactiveSystemTextColor(); + if (theme != null) + return theme.getInactiveSystemTextColor(); + return null; } /** @@ -331,7 +373,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuBackground() { - return theme.getMenuBackground(); + if (theme != null) + return theme.getMenuBackground(); + return null; } /** @@ -344,7 +388,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuDisabledForeground() { - return theme.getMenuDisabledForeground(); + if (theme != null) + return theme.getMenuDisabledForeground(); + return null; } /** @@ -357,7 +403,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuForeground() { - return theme.getMenuForeground(); + if (theme != null) + return theme.getMenuForeground(); + return null; } /** @@ -370,7 +418,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuSelectedBackground() { - return theme.getMenuSelectedBackground(); + if (theme != null) + return theme.getMenuSelectedBackground(); + return null; } /** @@ -383,7 +433,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuSelectedForeground() { - return theme.getMenuSelectedForeground(); + if (theme != null) + return theme.getMenuSelectedForeground(); + return null; } /** @@ -393,7 +445,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getMenuTextFont() { - return theme.getMenuTextFont(); + if (theme != null) + return theme.getMenuTextFont(); + return null; } /** @@ -403,7 +457,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControl() { - return theme.getPrimaryControl(); + if (theme != null) + return theme.getPrimaryControl(); + return null; } /** @@ -414,7 +470,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlDarkShadow() { - return theme.getPrimaryControlDarkShadow(); + if (theme != null) + return theme.getPrimaryControlDarkShadow(); + return null; } /** @@ -425,7 +483,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlHighlight() { - return theme.getPrimaryControlHighlight(); + if (theme != null) + return theme.getPrimaryControlHighlight(); + return null; } /** @@ -436,7 +496,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlInfo() { - return theme.getPrimaryControlInfo(); + if (theme != null) + return theme.getPrimaryControlInfo(); + return null; } /** @@ -447,7 +509,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlShadow() { - return theme.getPrimaryControlShadow(); + if (theme != null) + return theme.getPrimaryControlShadow(); + return null; } /** @@ -457,7 +521,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getSeparatorBackground() { - return theme.getSeparatorBackground(); + if (theme != null) + return theme.getSeparatorBackground(); + return null; } /** @@ -467,7 +533,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getSeparatorForeground() { - return theme.getSeparatorForeground(); + if (theme != null) + return theme.getSeparatorForeground(); + return null; } /** @@ -477,7 +545,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getSubTextFont() { - return theme.getSubTextFont(); + if (theme != null) + return theme.getSubTextFont(); + return null; } /** @@ -487,7 +557,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getSystemTextColor() { - return theme.getSystemTextColor(); + if (theme != null) + return theme.getSystemTextColor(); + return null; } /** @@ -497,7 +569,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getSystemTextFont() { - return theme.getSystemTextFont(); + if (theme != null) + return theme.getSystemTextFont(); + return null; } /** @@ -507,7 +581,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getTextHighlightColor() { - return theme.getTextHighlightColor(); + if (theme != null) + return theme.getTextHighlightColor(); + return null; } /** @@ -517,7 +593,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getUserTextColor() { - return theme.getUserTextColor(); + if (theme != null) + return theme.getUserTextColor(); + return null; } /** @@ -527,7 +605,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getUserTextFont() { - return theme.getUserTextFont(); + if (theme != null) + return theme.getUserTextFont(); + return null; } /** @@ -537,7 +617,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWhite() { - return theme.getWhite(); + if (theme != null) + return theme.getWhite(); + return null; } /** @@ -547,7 +629,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowBackground() { - return theme.getWindowBackground(); + if (theme != null) + return theme.getWindowBackground(); + return null; } /** @@ -557,7 +641,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleBackground() { - return theme.getWindowTitleBackground(); + if (theme != null) + return theme.getWindowTitleBackground(); + return null; } /** @@ -569,7 +655,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getWindowTitleFont() { - return theme.getWindowTitleFont(); + if (theme != null) + return theme.getWindowTitleFont(); + return null; } /** @@ -579,7 +667,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleForeground() { - return theme.getWindowTitleForeground(); + if (theme != null) + return theme.getWindowTitleForeground(); + return null; } /** @@ -590,7 +680,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleInactiveBackground() { - return theme.getWindowTitleInactiveBackground(); + if (theme != null) + return theme.getWindowTitleInactiveBackground(); + return null; } /** @@ -601,7 +693,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleInactiveForeground() { - return theme.getWindowTitleInactiveForeground(); + if (theme != null) + return theme.getWindowTitleInactiveForeground(); + return null; } /** @@ -691,6 +785,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "CheckBoxUI", "javax.swing.plaf.metal.MetalCheckBoxUI", "ComboBoxUI", "javax.swing.plaf.metal.MetalComboBoxUI", "DesktopIconUI", "javax.swing.plaf.metal.MetalDesktopIconUI", + "FileChooserUI", "javax.swing.plaf.metal.MetalFileChooserUI", "InternalFrameUI", "javax.swing.plaf.metal.MetalInternalFrameUI", "LabelUI", "javax.swing.plaf.metal.MetalLabelUI", "MenuBarUI", "javax.swing.plaf.metal.MetalMenuBarUI", @@ -841,7 +936,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "EditorPane.background", getWindowBackground(), "EditorPane.caretForeground", getUserTextColor(), - "EditorPane.font", new FontUIResource("Dialog", Font.PLAIN, 12), + "EditorPane.font", new FontUIResource("Dialog", Font.BOLD, 12), "EditorPane.foreground", getUserTextColor(), "EditorPane.inactiveForeground", getInactiveSystemTextColor(), "EditorPane.selectionBackground", getTextHighlightColor(), @@ -858,6 +953,19 @@ public class MetalLookAndFeel extends BasicLookAndFeel "FormattedTextField.selectionBackground", getTextHighlightColor(), "FormattedTextField.selectionForeground", getHighlightedTextColor(), + "FileChooser.upFolderIcon", + MetalIconFactory.getFileChooserUpFolderIcon(), + "FileChooser.listViewIcon", + MetalIconFactory.getFileChooserListViewIcon(), + "FileChooser.newFolderIcon", + MetalIconFactory.getFileChooserNewFolderIcon(), + "FileChooser.homeFolderIcon", + MetalIconFactory.getFileChooserHomeFolderIcon(), + "FileChooser.detailsViewIcon", + MetalIconFactory.getFileChooserDetailViewIcon(), + "FileChooser.fileNameLabelMnemonic", new Integer(78), + "FileChooser.filesOfTypeLabelMnemonic",new Integer(84), + "FileChooser.lookInLabelMnemonic", new Integer(73), "FileView.computerIcon", MetalIconFactory.getTreeComputerIcon(), "FileView.directoryIcon", MetalIconFactory.getTreeFolderIcon(), "FileView.fileIcon", MetalIconFactory.getTreeLeafIcon(), @@ -875,15 +983,20 @@ public class MetalLookAndFeel extends BasicLookAndFeel "InternalFrame.icon", MetalIconFactory.getInternalFrameDefaultMenuIcon(), "InternalFrame.closeIcon", MetalIconFactory.getInternalFrameCloseIcon(16), + "InternalFrame.closeSound", "sounds/FrameClose.wav", "InternalFrame.inactiveTitleBackground", getWindowTitleInactiveBackground(), "InternalFrame.inactiveTitleForeground", getWindowTitleInactiveForeground(), "InternalFrame.maximizeIcon", MetalIconFactory.getInternalFrameMaximizeIcon(16), + "InternalFrame.maximizeSound", "sounds/FrameMaximize.wav", "InternalFrame.iconifyIcon", MetalIconFactory.getInternalFrameMinimizeIcon(16), + "InternalFrame.minimizeSound", "sounds/FrameMinimize.wav", "InternalFrame.paletteBorder", new MetalBorders.PaletteBorder(), "InternalFrame.paletteCloseIcon", new MetalIconFactory.PaletteCloseIcon(), "InternalFrame.paletteTitleHeight", new Integer(11), + "InternalFrame.restoreDownSound", "sounds/FrameRestoreDown.wav", + "InternalFrame.restoreUpSound", "sounds/FrameRestoreUp.wav", "Label.background", getControl(), "Label.disabledForeground", getInactiveSystemTextColor(), @@ -902,14 +1015,18 @@ public class MetalLookAndFeel extends BasicLookAndFeel "Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10), "Menu.acceleratorForeground", getAcceleratorForeground(), "Menu.acceleratorSelectionForeground", getAcceleratorSelectedForeground(), + "Menu.arrowIcon", MetalIconFactory.getMenuArrowIcon(), "Menu.background", getMenuBackground(), "Menu.border", new MetalBorders.MenuItemBorder(), "Menu.borderPainted", Boolean.TRUE, + "MenuItem.commandSound", "sounds/MenuItemCommand.wav", "Menu.disabledForeground", getMenuDisabledForeground(), "Menu.font", getControlTextFont(), "Menu.foreground", getMenuForeground(), "Menu.selectionBackground", getMenuSelectedBackground(), "Menu.selectionForeground", getMenuSelectedForeground(), + "Menu.submenuPopupOffsetX", new Integer(-4), + "Menu.submenuPopupOffsetY", new Integer(-3), "MenuBar.background", getMenuBackground(), "MenuBar.border", new MetalBorders.MenuBarBorder(), @@ -918,11 +1035,14 @@ public class MetalLookAndFeel extends BasicLookAndFeel "MenuBar.highlight", getControlHighlight(), "MenuBar.shadow", getControlShadow(), + "MenuItem.acceleratorDelimiter", "-", "MenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10), "MenuItem.acceleratorForeground", getAcceleratorForeground(), "MenuItem.acceleratorSelectionForeground", getAcceleratorSelectedForeground(), + "MenuItem.arrowIcon", MetalIconFactory.getMenuItemArrowIcon(), "MenuItem.background", getMenuBackground(), "MenuItem.border", new MetalBorders.MenuItemBorder(), + "MenuItem.borderPainted", Boolean.TRUE, "MenuItem.disabledForeground", getMenuDisabledForeground(), "MenuItem.font", getControlTextFont(), "MenuItem.foreground", getMenuForeground(), @@ -930,6 +1050,10 @@ public class MetalLookAndFeel extends BasicLookAndFeel "MenuItem.selectionForeground", getMenuSelectedForeground(), "OptionPane.background", getControl(), + "OptionPane.errorSound", "sounds/OptionPaneError.wav", + "OptionPane.informationSound", "sounds/OptionPaneInformation.wav", + "OptionPane.questionSound", "sounds/OptionPaneQuestion.wav", + "OptionPane.warningSound", "sounds/OptionPaneWarning.wav", "OptionPane.errorDialog.border.background", new ColorUIResource(153, 51, 51), "OptionPane.errorDialog.titlePane.background", new ColorUIResource(255, 153, 153), "OptionPane.errorDialog.titlePane.foreground", new ColorUIResource(51, 0, 0), @@ -953,6 +1077,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel new BorderUIResource(MetalBorders.getTextFieldBorder()), "PasswordField.caretForeground", getUserTextColor(), "PasswordField.foreground", getUserTextColor(), + "PasswordField.font", new FontUIResource("Dialog", Font.PLAIN, 12), "PasswordField.inactiveBackground", getControl(), "PasswordField.inactiveForeground", getInactiveSystemTextColor(), "PasswordField.selectionBackground", getTextHighlightColor(), @@ -962,6 +1087,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "PopupMenu.border", new MetalBorders.PopupMenuBorder(), "PopupMenu.font", new FontUIResource("Dialog", Font.BOLD, 12), "PopupMenu.foreground", getMenuForeground(), + "PopupMenu.popupSound", "sounds/PopupMenuPopup.wav", "ProgressBar.background", getControl(), "ProgressBar.border", new BorderUIResource.LineBorderUIResource(getControlDarkShadow(), 1), @@ -997,6 +1123,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "RadioButtonMenuItem.borderPainted", Boolean.TRUE, "RadioButtonMenuItem.checkIcon", MetalIconFactory.getRadioButtonMenuItemIcon(), + "RadioButtonMenuItem.commandSound", "sounds/MenuItemCommand.wav", "RadioButtonMenuItem.disabledForeground", getMenuDisabledForeground(), "RadioButtonMenuItem.font", MetalLookAndFeel.getControlTextFont(), "RadioButtonMenuItem.foreground", getMenuForeground(), @@ -1006,6 +1133,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "RadioButtonMenuItem.selectionForeground", MetalLookAndFeel.getMenuSelectedForeground(), + "ScrollBar.allowsAbsolutePositioning", Boolean.TRUE, "ScrollBar.background", getControl(), "ScrollBar.darkShadow", getControlDarkShadow(), "ScrollBar.foreground", getControl(), @@ -1041,6 +1169,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "Slider.verticalThumbIcon", MetalIconFactory.getVerticalSliderThumbIcon(), + "Spinner.arrowButtonInsets", new InsetsUIResource(0, 0, 0, 0), "Spinner.background", getControl(), "Spinner.font", new FontUIResource("Dialog", Font.BOLD, 12), "Spinner.foreground", getControl(), @@ -1048,6 +1177,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "SplitPane.background", getControl(), "SplitPane.darkShadow", getControlDarkShadow(), "SplitPane.dividerFocusColor", getPrimaryControl(), + "SplitPane.dividerSize", new Integer(10), "SplitPane.highlight", getControlHighlight(), "SplitPane.shadow", getControlShadow(), @@ -1150,6 +1280,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "ToolTip.font", new FontUIResource("Dialog", Font.PLAIN, 12), "ToolTip.foreground", getPrimaryControlInfo(), "ToolTip.foregroundInactive", getControlDarkShadow(), + "ToolTip.hideAccelerator", Boolean.FALSE, "Tree.background", getWindowBackground(), "Tree.closedIcon", MetalIconFactory.getTreeFolderIcon(), diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java index de71fe8..9fb960f 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java @@ -176,7 +176,7 @@ public class MetalRadioButtonUI protected void paintFocus(Graphics g, Rectangle t, Dimension d) { g.setColor(focusColor); - g.drawRect(t.x - 1, t.y + 2, t.width + 2, t.height - 4); + g.drawRect(t.x - 1, t.y - 1, t.width + 2, t.height + 2); } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java index d5bf175..ae14af3 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java @@ -38,7 +38,10 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.beans.PropertyChangeListener; + import javax.swing.JComponent; +import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicScrollPaneUI; @@ -68,4 +71,89 @@ public class MetalScrollPaneUI { return new MetalScrollPaneUI(); } + + /** + * Configures the specified component appropriate for the look and feel. + * This method is invoked when the ComponentUI instance is being installed + * as the UI delegate on the specified component. This method should + * completely configure the component for the look and feel, + * including the following: + * 1. Install any default property values for color, fonts, borders, + * icons, opacity, etc. on the component. Whenever possible, property + * values initialized by the client program should not be overridden. + * 2. Install a LayoutManager on the component if necessary. + * 3. Create/add any required sub-components to the component. + * 4. Create/install event listeners on the component. + * 5. Create/install a PropertyChangeListener on the component in order + * to detect and respond to component property changes appropriately. + * 6. Install keyboard UI (mnemonics, traversal, etc.) on the component. + * 7. Initialize any appropriate instance data. + * + * @param c - the component to install the ui on + */ + public void installUI(JComponent c) + { + super.installUI(c); + JScrollBar hsb = scrollpane.getHorizontalScrollBar(); + hsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, Boolean.FALSE); + JScrollBar vsb = scrollpane.getVerticalScrollBar(); + vsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, Boolean.FALSE); + } + + /** + * Reverses configuration which was done on the specified component + * during installUI. This method is invoked when this UIComponent + * instance is being removed as the UI delegate for the specified + * component. This method should undo the configuration performed in + * installUI, being careful to leave the JComponent instance in a + * clean state (no extraneous listeners, look-and-feel-specific property + * objects, etc.). This should include the following: + * 1. Remove any UI-set borders from the component. + * 2. Remove any UI-set layout managers on the component. + * 3. Remove any UI-added sub-components from the component. + * 4. Remove any UI-added event/property listeners from the component. + * 5. Remove any UI-installed keyboard UI from the component. + * 6. Nullify any allocated instance data objects to allow for GC. + * + * @param c - the component to uninstall the ui on + */ + public void uninstallUI(JComponent c) + { + JScrollBar hsb = scrollpane.getHorizontalScrollBar(); + hsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, null); + JScrollBar vsb = scrollpane.getVerticalScrollBar(); + vsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, null); + super.uninstallUI(c); + } + + /** + * Installs listeners on scrollPane + * + * @param scrollPane - the component to install the listeners on + */ + public void installListeners(JScrollPane scrollPane) + { + super.installListeners(scrollPane); + } + + /** + * Uninstalls listeners on scrollPane + * + * @param scrollPane - the component to uninstall the listeners on + */ + public void uninstallListeners(JScrollPane scrollPane) + { + super.uninstallListeners(scrollPane); + } + + /** + * TODO + * + * @return TODO + */ + protected PropertyChangeListener createScrollBarSwapListener() + { + // FIXME: Anything else to do here? + return super.createPropertyChangeListener(); + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java index 016e095..34a964c 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java @@ -38,9 +38,16 @@ exception statement from your version. */ package javax.swing.plaf.metal; import java.awt.Color; +import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; +import java.awt.LayoutManager; +import java.awt.Point; +import javax.swing.JSplitPane; +import javax.swing.SwingConstants; +import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.plaf.basic.BasicSplitPaneDivider; /** @@ -56,7 +63,13 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider /** The light color in the pattern. */ Color light; + + /** The JSplitPane the divider is on. */ + JSplitPane splitPane; + /** The split pane orientation. */ + int orientation; + /** * Creates a new instance of MetalSplitPaneDivider. * @@ -65,6 +78,9 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider public MetalSplitPaneDivider(MetalSplitPaneUI ui, Color light, Color dark) { super(ui); + setLayout(new MetalDividerLayout()); + this.splitPane = super.splitPane; + this.orientation = super.orientation; this.light = light; this.dark = dark; } @@ -76,9 +92,127 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider */ public void paint(Graphics g) { - //super.paint(g); Dimension s = getSize(); MetalUtils.fillMetalPattern(splitPane, g, 2, 2, s.width - 4, s.height - 4, light, dark); + if (splitPane.isOneTouchExpandable()) + { + ((BasicArrowButton) rightButton).paint(g); + ((BasicArrowButton) leftButton).paint(g); + } + } + + /** + * This helper class acts as the Layout Manager for the divider. + */ + public class MetalDividerLayout implements LayoutManager + { + /** The right button. */ + BasicArrowButton rb; + + /** The left button. */ + BasicArrowButton lb; + + /** + * Creates a new DividerLayout object. + */ + public MetalDividerLayout() + { + // Nothing to do here + } + + /** + * This method is called when a Component is added. + * + * @param string The constraints string. + * @param c The Component to add. + */ + public void addLayoutComponent(String string, Component c) + { + // Nothing to do here, constraints are set depending on + // orientation in layoutContainer + } + + /** + * This method is called to lay out the container. + * + * @param c The container to lay out. + */ + public void layoutContainer(Container c) + { + // The only components we care about setting up are the + // one touch buttons. + if (splitPane.isOneTouchExpandable()) + { + if (c.getComponentCount() == 2) + { + Component c1 = c.getComponent(0); + Component c2 = c.getComponent(1); + if ((c1 instanceof BasicArrowButton) + && (c2 instanceof BasicArrowButton)) + { + lb = ((BasicArrowButton) c1); + rb = ((BasicArrowButton) c2); + } + } + if (rb != null && lb != null) + { + Point p = getLocation(); + lb.setSize(lb.getPreferredSize()); + rb.setSize(rb.getPreferredSize()); + lb.setLocation(p.x, p.y); + + if (orientation == JSplitPane.HORIZONTAL_SPLIT) + { + rb.setDirection(SwingConstants.EAST); + lb.setDirection(SwingConstants.WEST); + rb.setLocation(p.x, p.y + lb.getHeight()); + } + else + { + rb.setDirection(SwingConstants.SOUTH); + lb.setDirection(SwingConstants.NORTH); + rb.setLocation(p.x + lb.getWidth(), p.y); + } + } + } + } + + /** + * This method returns the minimum layout size. + * + * @param c The container to calculate for. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container c) + { + return preferredLayoutSize(c); + } + + /** + * This method returns the preferred layout size. + * + * @param c The container to calculate for. + * + * @return The preferred layout size. + */ + public Dimension preferredLayoutSize(Container c) + { + int dividerSize = getDividerSize(); + return new Dimension(dividerSize, dividerSize); + } + + /** + * This method is called when a component is removed. + * + * @param c The component to remove. + */ + public void removeLayoutComponent(Component c) + { + // Nothing to do here. If buttons are removed + // they will not be layed out when layoutContainer is + // called. + } } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java index b1e02c7..c6c46ff 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java @@ -38,11 +38,14 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.awt.Color; import java.awt.Graphics; import java.awt.LayoutManager; +import java.awt.Rectangle; import javax.swing.JComponent; import javax.swing.JTabbedPane; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicTabbedPaneUI; @@ -101,6 +104,29 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI } /** + * The minimum tab width. + */ + protected int minTabWidth; + + /** + * The color for the selected tab. + */ + protected Color selectColor; + + /** + * The color for a highlighted selected tab. + */ + protected Color selectHighlight; + + /** + * The background color used for the tab area. + */ + protected Color tabAreaBackground; + + /** The graphics to draw the highlight below the tab. */ + private Graphics hg; + + /** * Constructs a new instance of MetalTabbedPaneUI. */ public MetalTabbedPaneUI() @@ -175,6 +201,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI protected void paintTopTabBorder(int tabIndex, Graphics g, int x, int y, int w, int h, int btm, int rght, boolean isSelected) { + int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex); + if (shouldFillGap(currentRun, tabIndex, x, y)) + { + g.translate(x, y); + g.setColor(getColorForGap(currentRun, x, y)); + g.fillRect(1, 0, 5, 3); + g.fillRect(1, 3, 2, 2); + g.translate(-x, -y); + } + if (isSelected) { g.setColor(MetalLookAndFeel.getControlHighlight()); @@ -267,6 +303,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI protected void paintBottomTabBorder(int tabIndex, Graphics g, int x, int y, int w, int h, int btm, int rght, boolean isSelected) { + int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex); + if (shouldFillGap(currentRun, tabIndex, x, y)) + { + g.translate(x, y); + g.setColor(getColorForGap(currentRun, x, y)); + g.fillRect(1, h - 5, 3, 5); + g.fillRect(4, h - 2, 2, 2); + g.translate(-x, -y); + } + if (isSelected) { g.setColor(MetalLookAndFeel.getControlHighlight()); @@ -297,9 +343,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI int tabIndex, int x, int y, int w, int h, boolean isSelected) { if (isSelected) - g.setColor(MetalLookAndFeel.getControl()); + g.setColor(UIManager.getColor("TabbedPane.selected")); else - g.setColor(MetalLookAndFeel.getControlShadow()); + { + // This is only present in the OceanTheme, so we must check if it + // is actually there + Color background = UIManager.getColor("TabbedPane.unselectedBackground"); + if (background == null) + background = UIManager.getColor("TabbedPane.background"); + g.setColor(background); + } int[] px, py; if (tabPlacement == TOP) { @@ -324,6 +377,8 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI else throw new AssertionError("Unrecognised 'tabPlacement' argument."); g.fillPolygon(px, py, 5); + hg = g; + paintHighlightBelowTab(); } /** @@ -342,5 +397,94 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI // (which is drawn at the very top for tabPlacement == TOP) return run < this.runCount - 1; } + + /** + * Installs the defaults for this UI. This method calls super.installDefaults + * and then loads the Metal specific defaults for TabbedPane. + */ + protected void installDefaults() + { + super.installDefaults(); + selectColor = UIManager.getColor("TabbedPane.selected"); + selectHighlight = UIManager.getColor("TabbedPane.selectHighlight"); + tabAreaBackground = UIManager.getColor("TabbedPane.tabAreaBackground"); + minTabWidth = 0; + } + /** + * Returns the color for the gap. + * + * @param currentRun - The current run to return the color for + * @param x - The x position of the current run + * @param y - The y position of the current run + * + * @return the color for the gap in the current run. + */ + protected Color getColorForGap(int currentRun, int x, int y) + { + int index = tabForCoordinate(tabPane, x, y); + int selected = tabPane.getSelectedIndex(); + if (selected == index) + return selectColor; + return tabAreaBackground; + } + + /** + * Returns true if the gap should be filled in. + * + * @param currentRun - The current run + * @param tabIndex - The current tab + * @param x - The x position of the tab + * @param y - The y position of the tab + * + * @return true if the gap at the current run should be filled + */ + protected boolean shouldFillGap(int currentRun, int tabIndex, int x, int y) + { + // As far as I can tell, the gap is never filled in. + return false; + } + + /** + * Paints the highlight below the tab, if there is one. + */ + protected void paintHighlightBelowTab() + { + int selected = tabPane.getSelectedIndex(); + int tabPlacement = tabPane.getTabPlacement(); + Rectangle bounds = getTabBounds(tabPane, selected); + + hg.setColor(selectColor); + int x = bounds.x; + int y = bounds.y; + int w = bounds.width; + int h = bounds.height; + + if (tabPlacement == TOP) + hg.fillRect(x, y + h - 2, w, 30); + else if (tabPlacement == LEFT) + hg.fillRect(x + w - 1, y, 20, h); + else if (tabPlacement == BOTTOM) + hg.fillRect(x, y - h + 2, w, 30); + else if (tabPlacement == RIGHT) + hg.fillRect(x - 18, y, 20, h); + else + throw new AssertionError("Unrecognised 'tabPlacement' argument."); + hg = null; + } + + /** + * Returns true if we should rotate the tab runs. + * + * @param tabPlacement - The current tab placement. + * @param selectedRun - The selected run. + * + * @return true if the tab runs should be rotated. + */ + protected boolean shouldRotateTabRuns(int tabPlacement, + int selectedRun) + { + // false because tab runs are not rotated in the MetalLookAndFeel + return false; + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java index 6984dae..30738b3 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java @@ -38,6 +38,8 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.beans.PropertyChangeEvent; + import javax.swing.JComponent; import javax.swing.JTextField; import javax.swing.plaf.ComponentUI; @@ -67,4 +69,14 @@ public class MetalTextFieldUI extends BasicTextFieldUI { return new MetalTextFieldUI(); } + + /** + * This method gets called when a bound property is changed on the associated + * JTextComponent. This is a hook which UI implementations may change to + * reflect how the UI displays bound properties of JTextComponent subclasses. + */ + public void propertyChange(PropertyChangeEvent evt) + { + super.propertyChange(evt); + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java index c5ca913..16e22ac 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java @@ -38,12 +38,16 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.awt.Point; import java.awt.event.ContainerListener; +import java.awt.event.MouseEvent; + import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.JToolBar; import javax.swing.border.Border; +import javax.swing.event.MouseInputListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicToolBarUI; @@ -158,5 +162,67 @@ public class MetalToolBarUI extends BasicToolBarUI { return MetalBorders.getToolbarButtonBorder(); } - + + /** + * Sets the offset for the window used for dragging the toolbar. + * It is set as long as the window is not null (it has been installed). + */ + protected void setDragOffset(Point p) + { + if (dragWindow != null) + dragWindow.setOffset(p); + } + + /** + * Creates and returns an instance of MetalDockingListener. + * + * @return an instance of MetalDockingListener. + */ + protected MouseInputListener createDockingListener() + { + return new MetalDockingListener(toolBar); + } + + /** + * This is the MouseHandler class that allows the user to drag the JToolBar + * in and out of the parent and dock it if it can. + */ + protected class MetalDockingListener extends BasicToolBarUI.DockingListener + { + /** + * Creates a new DockingListener object. + * + * @param t The JToolBar this DockingListener is being used for. + */ + public MetalDockingListener(JToolBar t) + { + super(t); + } + + /** + * This method is called when the mouse is pressed in the JToolBar. If the + * press doesn't occur in a place where it causes the JToolBar to be + * dragged, it returns. Otherwise, it starts a drag session. + * + * @param e The MouseEvent. + */ + public void mousePressed(MouseEvent e) + { + super.mousePressed(e); + setDragOffset(new Point(e.getX(), e.getY())); + } + + /** + * This method is called when the mouse is dragged. It delegates the drag + * painting to the dragTo method. + * + * @param e The MouseEvent. + */ + public void mouseDragged(MouseEvent e) + { + // Does not do anything differently than dragging + // BasicToolBarUI.DockingListener + super.mouseDragged(e); + } + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java b/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java index f1886b1..d1fc4cf 100644 --- a/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java +++ b/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java @@ -238,6 +238,10 @@ public class OceanTheme extends DefaultMetalTheme {new Double(0.3), new Double(0.0), new ColorUIResource(221, 232, 243), new ColorUIResource(Color.WHITE), new ColorUIResource(184, 207, 229)})); + defaults.put("Button.rollover", Boolean.TRUE); + + defaults.put("TabbedPane.selected", new ColorUIResource(200, 221, 242)); + defaults.put("TabbedPane.unselectedBackground", SECONDARY3); } } |