diff options
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic')
28 files changed, 1573 insertions, 692 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java index 7dbcb91467e..0a537c4bdd8 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java @@ -72,7 +72,7 @@ public class BasicButtonUI extends ButtonUI * A constant added to the defaultTextIconGap to adjust the text * within this particular button. */ - protected int defaultTextShiftOffset = 0; + protected int defaultTextShiftOffset; private int textShiftOffset; @@ -268,10 +268,9 @@ public class BasicButtonUI extends ButtonUI */ public Dimension getPreferredSize(JComponent c) { - AbstractButton b = (AbstractButton)c; - Dimension d = - BasicGraphicsUtils.getPreferredButtonSize - (b, defaultTextIconGap + defaultTextShiftOffset); + AbstractButton b = (AbstractButton) c; + Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b, + defaultTextIconGap + defaultTextShiftOffset); return d; } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java index 14dadb85cf9..1010139b8fc 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java @@ -1,5 +1,5 @@ /* BasicCheckBoxUI.java - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,25 +38,32 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import javax.swing.Icon; +import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +/** + * A UI delegate for the {@link JCheckBox} component. + */ public class BasicCheckBoxUI extends BasicRadioButtonUI { - public static ComponentUI createUI(final JComponent c) { + /** + * Returns a UI delegate (that is, an instance of this class) for the + * specified component. + * + * @param c the component (this should be a {@link JCheckBox}). + * + * @return A new instance of <code>BasicCheckBoxUI</code>. + */ + public static ComponentUI createUI(JComponent c) { return new BasicCheckBoxUI(); } - public Icon getDefaultIcon() - { - return UIManager.getIcon("CheckBox.icon"); - } - /** - * Returns the prefix for entries in the {@link UIManager} defaults table. + * Returns the prefix for entries in the {@link UIManager} defaults table + * (<code>"CheckBox."</code> in this case). * * @return "CheckBox." */ diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java index 557eea93f07..ea6f9850435 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -1,5 +1,5 @@ /* BasicComboBoxUI.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -66,12 +66,14 @@ import javax.swing.CellRendererPane; import javax.swing.ComboBoxEditor; import javax.swing.ComboBoxModel; import javax.swing.DefaultListCellRenderer; +import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.ListCellRenderer; import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; @@ -546,7 +548,7 @@ public class BasicComboBoxUI extends ComboBoxUI } /** - * Unconfigures the editor for this combo nox. This method is not implemented. + * Unconfigures the editor for this combo box. */ protected void unconfigureEditor() { @@ -711,12 +713,14 @@ public class BasicComboBoxUI extends ComboBoxUI } public int getAccessibleChildrenCount(JComponent c) + throws NotImplementedException { // FIXME: Need to implement return 0; } public Accessible getAccessibleChild(JComponent c, int i) + throws NotImplementedException { // FIXME: Need to implement return null; @@ -731,7 +735,9 @@ public class BasicComboBoxUI extends ComboBoxUI * @return true if the specified key is a navigation key and false otherwis */ protected boolean isNavigationKey(int keyCode) + throws NotImplementedException { + // FIXME: Need to implement return false; } @@ -780,9 +786,7 @@ public class BasicComboBoxUI extends ComboBoxUI Insets i = comboBox.getInsets(); int arrowSize = h - (i.top + i.bottom); if (arrowButton != null) - { - arrowSize = arrowButton.getWidth(); - } + arrowSize = arrowButton.getWidth(); return new Rectangle(i.left, i.top, w - (i.left + i.right + arrowSize), h - (i.top + i.left)); } @@ -822,14 +826,12 @@ public class BasicComboBoxUI extends ComboBoxUI if (hasFocus && ! isPopupVisible(comboBox)) { comp = renderer.getListCellRendererComponent(listBox, - comboBox.getSelectedItem(), - -1, true, false); + comboBox.getSelectedItem(), -1, true, false); } else { comp = renderer.getListCellRendererComponent(listBox, - comboBox.getSelectedItem(), - -1, false, false); + comboBox.getSelectedItem(), -1, false, false); Color bg = UIManager.getColor("ComboBox.disabledForeground"); comp.setBackground(bg); } @@ -871,13 +873,9 @@ public class BasicComboBoxUI extends ComboBoxUI { Color saved = g.getColor(); if (comboBox.isEnabled()) - { - g.setColor(UIManager.getColor("UIManager.background")); - } + g.setColor(UIManager.getColor("UIManager.background")); else - { - g.setColor(UIManager.getColor("UIManager.disabledBackground")); - } + g.setColor(UIManager.getColor("UIManager.disabledBackground")); g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); g.setColor(saved); } @@ -897,9 +895,7 @@ public class BasicComboBoxUI extends ComboBoxUI protected Dimension getDefaultSize() { Component comp = DEFAULT_RENDERER.getListCellRendererComponent(listBox, - " ", -1, - false, - false); + " ", -1, false, false); currentValuePane.add(comp); comp.setFont(comboBox.getFont()); Dimension d = comp.getPreferredSize(); @@ -974,19 +970,22 @@ public class BasicComboBoxUI extends ComboBoxUI * by the look and feel. */ protected void installKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement. + SwingUtilities.replaceUIInputMap(comboBox, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, + (InputMap) UIManager.get("ComboBox.ancestorInputMap")); + // Install any action maps here. } - + /** * Uninstalls the keyboard actions for the {@link JComboBox} there were * installed by in {@link #installListeners}. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement. + SwingUtilities.replaceUIInputMap(comboBox, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); + // Uninstall any action maps here. } /** @@ -1145,9 +1144,7 @@ public class BasicComboBoxUI extends ComboBoxUI ComboBoxModel model = comboBox.getModel(); Object v = model.getSelectedItem(); if (editor != null) - { - comboBox.configureEditor(comboBox.getEditor(), v); - } + comboBox.configureEditor(comboBox.getEditor(), v); comboBox.repaint(); } } @@ -1166,9 +1163,10 @@ public class BasicComboBoxUI extends ComboBoxUI * Invoked whenever key is pressed while JComboBox is in focus. */ public void keyPressed(KeyEvent e) + throws NotImplementedException { - // FIXME: This method calls JComboBox.selectWithKeyChar if the key that was - // pressed is not a navigation key. + // FIXME: This method calls JComboBox.selectWithKeyChar if the key that + // was pressed is not a navigation key. } } @@ -1198,10 +1196,8 @@ public class BasicComboBoxUI extends ComboBoxUI comboBox.revalidate(); } if (editor != null) - { - comboBox.configureEditor(comboBox.getEditor(), - comboBox.getSelectedItem()); - } + comboBox.configureEditor(comboBox.getEditor(), + comboBox.getSelectedItem()); comboBox.repaint(); } @@ -1215,9 +1211,7 @@ public class BasicComboBoxUI extends ComboBoxUI int start = e.getIndex0(); int end = e.getIndex1(); if (start == 0 && comboBox.getItemCount() - (end - start + 1) == 0) - { - contentsChanged(e); - } + contentsChanged(e); else if (start != -1 || end != -1) { ListCellRenderer renderer = comboBox.getRenderer(); @@ -1227,10 +1221,8 @@ public class BasicComboBoxUI extends ComboBoxUI // TODO: Optimize using prototype here. for (int i = start; i <= end; ++i) { - Component comp = - renderer.getListCellRendererComponent(listBox, - model.getElementAt(i), - -1, false, false); + Component comp = renderer.getListCellRendererComponent(listBox, + model.getElementAt(i), -1, false, false); currentValuePane.add(comp); comp.setFont(comboBox.getFont()); Dimension dim = comp.getPreferredSize(); @@ -1241,13 +1233,9 @@ public class BasicComboBoxUI extends ComboBoxUI if (displaySize.width < w || displaySize.height < h) { if (displaySize.width < w) - { - displaySize.width = w; - } + displaySize.width = w; if (displaySize.height < h) - { - displaySize.height = h; - } + displaySize.height = h; comboBox.revalidate(); if (editor != null) { @@ -1297,37 +1285,37 @@ public class BasicComboBoxUI extends ComboBoxUI if (e.getPropertyName().equals("enabled")) { - arrowButton.setEnabled(comboBox.isEnabled()); + arrowButton.setEnabled(comboBox.isEnabled()); - if (comboBox.isEditable()) - comboBox.getEditor().getEditorComponent().setEnabled(comboBox - .isEnabled()); + if (comboBox.isEditable()) + comboBox.getEditor().getEditorComponent().setEnabled( + comboBox.isEnabled()); } else if (e.getPropertyName().equals("editable")) { - if (comboBox.isEditable()) - { - configureEditor(); - addEditor(); - } - else - { - unconfigureEditor(); - removeEditor(); - } - - comboBox.revalidate(); - comboBox.repaint(); + if (comboBox.isEditable()) + { + configureEditor(); + addEditor(); + } + else + { + unconfigureEditor(); + removeEditor(); + } + + comboBox.revalidate(); + comboBox.repaint(); } else if (e.getPropertyName().equals("dataModel")) { - // remove ListDataListener from old model and add it to new model - ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue(); - if (oldModel != null) - oldModel.removeListDataListener(listDataListener); + // remove ListDataListener from old model and add it to new model + ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue(); + if (oldModel != null) + oldModel.removeListDataListener(listDataListener); - if ((ComboBoxModel) e.getNewValue() != null) - comboBox.getModel().addListDataListener(listDataListener); + if ((ComboBoxModel) e.getNewValue() != null) + comboBox.getModel().addListDataListener(listDataListener); } else if (e.getPropertyName().equals("font")) { @@ -1339,7 +1327,7 @@ public class BasicComboBoxUI extends ComboBoxUI comboBox.repaint(); } - // FIXME: Need to handle changes in other bound properties. + // FIXME: Need to handle changes in other bound properties. } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java index d4eabc60264..0d822955bbc 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Component; import java.awt.Dimension; @@ -294,9 +292,8 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup * This method uninstalls keyboard actions installed by the UI. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement + // Nothing to do here. } /** @@ -559,12 +556,11 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup } /** - * DOCUMENT ME! + * Installs the keyboard actions. */ protected void installKeyboardActions() - throws NotImplementedException { - // FIXME: Need to implement + // Nothing to do here } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java b/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java index a694f328049..ef7a880c2ac 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java @@ -227,16 +227,16 @@ public class BasicDirectoryModel extends AbstractListModel if (aTrav == bTrav) { - String aname = a.getName().toLowerCase(); - String bname = b.getName().toLowerCase(); - return ((aname.compareTo(bname) < 0) ? true : false); + String aname = a.getName().toLowerCase(); + String bname = b.getName().toLowerCase(); + return (aname.compareTo(bname) < 0) ? true : false; } else { - if (aTrav) - return true; - else - return false; + if (aTrav) + return true; + else + return false; } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java index daa97708390..9adb0c642ba 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -365,10 +365,10 @@ public class BasicFileChooserUI extends FileChooserUI { /** DOCUMENT ME! */ - private Object lastSelected = null; + private Object lastSelected; /** DOCUMENT ME! */ - private JList list = null; + private JList list; /** * Creates a new DoubleClickListener object. diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java b/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java index 6debd649509..cad0d0e8abe 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicIconFactory.java @@ -56,8 +56,14 @@ public class BasicIconFactory implements Serializable private static class DummyIcon implements Icon { - public int getIconHeight() { return 10; } - public int getIconWidth() { return 10; } + public int getIconHeight() + { + return 10; + } + public int getIconWidth() + { + return 10; + } public void paintIcon(Component c, Graphics g, int x, int y) { Color save = g.getColor(); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java index 7ec3aa074bd..6beac6c971b 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -1,5 +1,5 @@ /* BasicInternalFrameUI.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.AWTEvent; import java.awt.Color; import java.awt.Component; @@ -52,12 +50,16 @@ import java.awt.LayoutManager; import java.awt.LayoutManager2; import java.awt.Point; import java.awt.Rectangle; +import java.awt.event.ActionEvent; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.beans.PropertyVetoException; +import javax.swing.AbstractAction; +import javax.swing.ActionMap; import javax.swing.DefaultDesktopManager; import javax.swing.DesktopManager; import javax.swing.JComponent; @@ -73,6 +75,7 @@ import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameListener; import javax.swing.event.MouseInputAdapter; import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.InternalFrameUI; import javax.swing.plaf.UIResource; @@ -168,10 +171,9 @@ public class BasicInternalFrameUI extends InternalFrameUI implements SwingConstants { /** - * If true, the cursor is being already shown in the alternative "resize" - * shape. + * The current shape of the cursor. */ - transient boolean showingResizeCursor; + transient int showingCursor; /** FIXME: Use for something. */ protected final int RESIZE_NONE = 0; @@ -187,7 +189,7 @@ public class BasicInternalFrameUI extends InternalFrameUI /** Cache rectangle that can be reused. */ private transient Rectangle cacheRect = new Rectangle(); - + /** * This method is called when the mouse is clicked. * @@ -195,6 +197,20 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public void mouseClicked(MouseEvent e) { + // Do minimization/maximization when double-clicking in the title pane. + if (e.getSource() == titlePane && e.getClickCount() == 2) + try + { + if (frame.isMaximizable() && ! frame.isMaximum()) + frame.setMaximum(true); + else if (frame.isMaximum()) + frame.setMaximum(false); + } + catch (PropertyVetoException pve) + { + // We do nothing if the attempt has been vetoed. + } + // There is nothing to do when the mouse is clicked // on the border. } @@ -223,34 +239,34 @@ public class BasicInternalFrameUI extends InternalFrameUI { switch (direction) { - case NORTH: + case Cursor.N_RESIZE_CURSOR: cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height - min.height), b.width, b.height - y); break; - case NORTH_EAST: + case Cursor.NE_RESIZE_CURSOR: cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height - - min.height), x, + - min.height), x + 1, b.height - y); break; - case EAST: - cacheRect.setBounds(b.x, b.y, x, b.height); + case Cursor.E_RESIZE_CURSOR: + cacheRect.setBounds(b.x, b.y, x + 1, b.height); break; - case SOUTH_EAST: - cacheRect.setBounds(b.x, b.y, x, y); + case Cursor.SE_RESIZE_CURSOR: + cacheRect.setBounds(b.x, b.y, x + 1, y + 1); break; - case SOUTH: - cacheRect.setBounds(b.x, b.y, b.width, y); + case Cursor.S_RESIZE_CURSOR: + cacheRect.setBounds(b.x, b.y, b.width, y + 1); break; - case SOUTH_WEST: + case Cursor.SW_RESIZE_CURSOR: cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width), - b.y, b.width - x, y); + b.y, b.width - x, y + 1); break; - case WEST: + case Cursor.W_RESIZE_CURSOR: cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width), b.y, b.width - x, b.height); break; - case NORTH_WEST: + case Cursor.NW_RESIZE_CURSOR: cacheRect.setBounds( Math.min(b.x + x, b.x + b.width - min.width), Math.min(b.y + y, b.y + b.height - min.height), @@ -260,6 +276,7 @@ public class BasicInternalFrameUI extends InternalFrameUI dm.resizeFrame(frame, cacheRect.x, cacheRect.y, Math.max(min.width, cacheRect.width), Math.max(min.height, cacheRect.height)); + setCursor(e); } else if (e.getSource() == titlePane) { @@ -277,11 +294,10 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public void mouseExited(MouseEvent e) { - // Reset the cursor shape. - if (showingResizeCursor) + if (showingCursor != Cursor.DEFAULT_CURSOR) { frame.setCursor(Cursor.getDefaultCursor()); - showingResizeCursor = false; + showingCursor = Cursor.DEFAULT_CURSOR; } } @@ -293,53 +309,36 @@ public class BasicInternalFrameUI extends InternalFrameUI public void mouseMoved(MouseEvent e) { // Turn off the resize cursor if we are in the frame header. - if (showingResizeCursor && e.getSource() != frame) + if (showingCursor != Cursor.DEFAULT_CURSOR && e.getSource() != frame) { frame.setCursor(Cursor.getDefaultCursor()); - showingResizeCursor = false; + showingCursor = Cursor.DEFAULT_CURSOR; } else if (e.getSource()==frame && frame.isResizable()) { - int cursor; - switch (sectionOfClick(e.getX(), e.getY())) - { - case NORTH: - cursor = Cursor.N_RESIZE_CURSOR; - break; - case NORTH_EAST: - cursor = Cursor.NE_RESIZE_CURSOR; - break; - case EAST: - cursor = Cursor.E_RESIZE_CURSOR; - break; - case SOUTH_EAST: - cursor = Cursor.SE_RESIZE_CURSOR; - break; - case SOUTH: - cursor = Cursor.S_RESIZE_CURSOR; - break; - case SOUTH_WEST: - cursor = Cursor.SW_RESIZE_CURSOR; - break; - case WEST: - cursor = Cursor.W_RESIZE_CURSOR; - break; - case NORTH_WEST: - cursor = Cursor.NW_RESIZE_CURSOR; - break; - default: - cursor = Cursor.DEFAULT_CURSOR; - } - + setCursor(e); + } + } + + /** + * Set the mouse cursor, how applicable. + * + * @param e the current mouse event. + */ + void setCursor(MouseEvent e) + { + int cursor = sectionOfClick(e.getX(), e.getY()); + if (cursor != showingCursor) + { Cursor resize = Cursor.getPredefinedCursor(cursor); frame.setCursor(resize); - showingResizeCursor = true; + showingCursor = cursor; } } /** * This method is called when the mouse is pressed. - * + * * @param e The MouseEvent. */ public void mousePressed(MouseEvent e) @@ -383,6 +382,8 @@ public class BasicInternalFrameUI extends InternalFrameUI dm.endDraggingFrame(frame); frame.putClientProperty("bufferedDragging", null); } + + setCursor(e); } /** @@ -392,30 +393,31 @@ public class BasicInternalFrameUI extends InternalFrameUI * @param x The x coordinate of the MouseEvent. * @param y The y coordinate of the MouseEvent. * - * @return The direction of the resize (a SwingConstant direction). + * @return The cursor constant, determining the resizing direction. */ private int sectionOfClick(int x, int y) { - Insets insets = frame.getInsets(); Rectangle b = frame.getBounds(); - if (x < insets.left && y < insets.top) - return NORTH_WEST; - else if (x > b.width - insets.right && y < insets.top) - return NORTH_EAST; - else if (x > b.width - insets.right && y > b.height - insets.bottom) - return SOUTH_EAST; - else if (x < insets.left && y > b.height - insets.bottom) - return SOUTH_WEST; - else if (y < insets.top) - return NORTH; - else if (x < insets.left) - return WEST; - else if (y > b.height - insets.bottom) - return SOUTH; - else if (x > b.width - insets.right) - return EAST; - - return -1; + int corner = InternalFrameBorder.cornerSize; + + if (x < corner && y < corner) + return Cursor.NW_RESIZE_CURSOR; + else if (x > b.width - corner && y < corner) + return Cursor.NE_RESIZE_CURSOR; + else if (x > b.width - corner && y > b.height - corner) + return Cursor.SE_RESIZE_CURSOR; + else if (x < corner && y > b.height - corner) + return Cursor.SW_RESIZE_CURSOR; + else if (y < corner) + return Cursor.N_RESIZE_CURSOR; + else if (x < corner) + return Cursor.W_RESIZE_CURSOR; + else if (y > b.height - corner) + return Cursor.S_RESIZE_CURSOR; + else if (x > b.width - corner) + return Cursor.E_RESIZE_CURSOR; + + return Cursor.DEFAULT_CURSOR; } } @@ -992,14 +994,18 @@ public class BasicInternalFrameUI extends InternalFrameUI /** * This helper class is the border for the JInternalFrame. */ - private class InternalFrameBorder extends AbstractBorder implements + class InternalFrameBorder extends AbstractBorder implements UIResource { - /** The width of the border. */ - private static final int bSize = 5; + /** + * The width of the border. + */ + static final int bSize = 5; - /** The size of the corners. */ - private static final int offset = 10; + /** + * The size of the corners (also used by the mouse listener). + */ + static final int cornerSize = 10; /** * This method returns whether the border is opaque. @@ -1069,10 +1075,12 @@ public class BasicInternalFrameUI extends InternalFrameUI g.fillRect(0, y3, b.width, bSize); g.fillRect(x3, 0, bSize, b.height); - g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false); - g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false); - g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false); - g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false); + g.fill3DRect(0, cornerSize, bSize, b.height - 2 * cornerSize, false); + g.fill3DRect(cornerSize, 0, b.width - 2 * cornerSize, bSize, false); + g.fill3DRect(cornerSize, b.height - bSize, b.width - 2 * cornerSize, + bSize, false); + g.fill3DRect(b.width - bSize, cornerSize, bSize, + b.height - 2 * cornerSize, false); g.translate(-x, -y); g.setColor(saved); @@ -1080,6 +1088,23 @@ public class BasicInternalFrameUI extends InternalFrameUI } /** + * This action triggers the system menu. + * + * @author Roman Kennke (kennke@aicas.com) + */ + private class ShowSystemMenuAction + extends AbstractAction + { + public void actionPerformed(ActionEvent e) + { + if (titlePane != null) + { + titlePane.showSystemMenu(); + } + } + } + + /** * The MouseListener that is responsible for dragging and resizing the * JInternalFrame in response to MouseEvents. */ @@ -1220,9 +1245,17 @@ public class BasicInternalFrameUI extends InternalFrameUI * This method installs the keyboard actions for the JInternalFrame. */ protected void installKeyboardActions() - throws NotImplementedException { - // FIXME: Implement. + ActionMapUIResource am = new ActionMapUIResource(); + am.put("showSystemMenu", new ShowSystemMenuAction()); + + // The RI impl installs the audio actions as parent of the UI action map, + // so do we. + BasicLookAndFeel blaf = (BasicLookAndFeel) UIManager.getLookAndFeel(); + ActionMap audioActionMap = blaf.getAudioActionMap(); + am.setParent(audioActionMap); + + SwingUtilities.replaceUIActionMap(frame, am); } /** @@ -1303,9 +1336,10 @@ public class BasicInternalFrameUI extends InternalFrameUI * This method uninstalls the keyboard actions for the JInternalFrame. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Implement. + SwingUtilities.replaceUIActionMap(frame, null); + SwingUtilities.replaceUIInputMap(frame, JComponent.WHEN_IN_FOCUSED_WINDOW, + null); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java index d9bc0676dd9..44f6a408984 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java @@ -218,11 +218,12 @@ public class BasicListUI extends ListUI class ListAction extends AbstractAction { - public void actionPerformed (ActionEvent e) + public void actionPerformed(ActionEvent e) { int lead = list.getLeadSelectionIndex(); int max = list.getModel().getSize() - 1; - DefaultListSelectionModel selModel = (DefaultListSelectionModel)list.getSelectionModel(); + DefaultListSelectionModel selModel + = (DefaultListSelectionModel) list.getSelectionModel(); String command = e.getActionCommand(); // Do nothing if list is empty if (max == -1) @@ -260,9 +261,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getLastVisibleIndex()) { - target = Math.min - (max, lead + (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.min(max, lead + (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getLastVisibleIndex(); @@ -273,9 +273,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getLastVisibleIndex()) { - target = Math.min - (max, lead + (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.min(max, lead + (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getLastVisibleIndex(); @@ -286,9 +285,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getFirstVisibleIndex()) { - target = Math.max - (0, lead - (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.max(0, lead - (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getFirstVisibleIndex(); @@ -299,9 +297,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getFirstVisibleIndex()) { - target = Math.max - (0, lead - (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.max(0, lead - (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getFirstVisibleIndex(); @@ -309,32 +306,31 @@ public class BasicListUI extends ListUI } else if (command.equals("selectNextRowExtendSelection")) { - selModel.setLeadSelectionIndex(Math.min(lead + 1,max)); + selModel.setLeadSelectionIndex(Math.min(lead + 1, max)); } else if (command.equals("selectFirstRow")) { list.setSelectedIndex(0); } else if (command.equals("selectFirstRowChangeLead")) - { - selModel.moveLeadSelectionIndex(0); - } + { + selModel.moveLeadSelectionIndex(0); + } else if (command.equals("selectFirstRowExtendSelection")) { selModel.setLeadSelectionIndex(0); } else if (command.equals("selectPreviousRowExtendSelection")) { - selModel.setLeadSelectionIndex(Math.max(0,lead - 1)); + selModel.setLeadSelectionIndex(Math.max(0, lead - 1)); } else if (command.equals("scrollUp")) { int target; if (lead == list.getFirstVisibleIndex()) { - target = Math.max - (0, lead - (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.max(0, lead - (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getFirstVisibleIndex(); @@ -349,9 +345,8 @@ public class BasicListUI extends ListUI int target; if (lead == list.getLastVisibleIndex()) { - target = Math.min - (max, lead + (list.getLastVisibleIndex() - - list.getFirstVisibleIndex() + 1)); + target = Math.min(max, lead + (list.getLastVisibleIndex() + - list.getFirstVisibleIndex() + 1)); } else target = list.getLastVisibleIndex(); @@ -451,9 +446,9 @@ public class BasicListUI extends ListUI if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) list.setSelectedIndex(index); else if (list.isSelectedIndex(index)) - list.removeSelectionInterval(index,index); + list.removeSelectionInterval(index, index); else - list.addSelectionInterval(index,index); + list.addSelectionInterval(index, index); } else list.setSelectedIndex(index); @@ -1006,14 +1001,14 @@ public class BasicListUI extends ListUI // Register key bindings in the UI InputMap-ActionMap pair for (int i = 0; i < keys.length; i++) { - KeyStroke stroke = (KeyStroke)keys[i]; + KeyStroke stroke = (KeyStroke) keys[i]; String actionString = (String) focusInputMap.get(stroke); parentInputMap.put(KeyStroke.getKeyStroke(stroke.getKeyCode(), stroke.getModifiers()), actionString); - parentActionMap.put (actionString, - new ActionListenerProxy(action, actionString)); + parentActionMap.put(actionString, + new ActionListenerProxy(action, actionString)); } // Register the new InputMap-ActionMap as the parents of the list's // InputMap and ActionMap diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java index 78c16ef08ae..5a08b2a3982 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -1,5 +1,5 @@ /* BasicLookAndFeel.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -1147,14 +1147,16 @@ public abstract class BasicLookAndFeel extends LookAndFeel "F8", "startResize", "END", "selectMax", "HOME", "selectMin", - "LEFT", "negativeIncremnent", + "LEFT", "negativeIncrement", "KP_UP", "negativeIncrement", "KP_DOWN", "positiveIncrement", "UP", "negativeIncrement", "RIGHT", "positiveIncrement", "KP_LEFT", "negativeIncrement", "DOWN", "positiveIncrement", - "KP_RIGHT", "positiveIncrement" + "KP_RIGHT", "positiveIncrement", + "shift ctrl pressed TAB", "focusOutBackward", + "ctrl pressed TAB", "focusOutForward" }), "SplitPane.background", new ColorUIResource(light), "SplitPane.border", new BasicBorders.SplitPaneBorder(null, null), diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java index 88bca3b53ce..91bf614340d 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -977,7 +977,7 @@ public class BasicOptionPaneUI extends OptionPaneUI case JOptionPane.OK_CANCEL_OPTION: return new Object[] { OK_STRING, CANCEL_STRING }; case JOptionPane.DEFAULT_OPTION: - return (optionPane.getWantsInput() ) ? + return (optionPane.getWantsInput()) ? new Object[] { OK_STRING, CANCEL_STRING } : ( optionPane.getMessageType() == JOptionPane.QUESTION_MESSAGE ) ? new Object[] { YES_STRING, NO_STRING, CANCEL_STRING } : diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java index 4f535f653cc..458f10204f0 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicPanelUI.java @@ -1,5 +1,5 @@ /* BasicPanelUI.java - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,33 +44,68 @@ import javax.swing.LookAndFeel; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.PanelUI; +/** + * A UI delegate for the {@link JPanel} component. + */ public class BasicPanelUI extends PanelUI { - public static ComponentUI createUI(JComponent x) + /** + * A UI delegate that can be shared by all panels (because the delegate is + * stateless). + */ + static BasicPanelUI sharedUI; + + /** + * Returns a UI delegate for the specified component. + * + * @param panel the panel. + */ + public static ComponentUI createUI(JComponent panel) { - return new BasicPanelUI(); + if (sharedUI == null) + sharedUI = new BasicPanelUI(); + return sharedUI; } + /** + * Installs this UI delegate in the specified component. + * + * @param c the component (should be a {@link JPanel}, <code>null</code> not + * permitted). + */ public void installUI(JComponent c) { super.installUI(c); if (c instanceof JPanel) { - JPanel p = (JPanel) c; - installDefaults(p); + JPanel p = (JPanel) c; + installDefaults(p); } } + /** + * Installs the defaults for this UI delegate in the specified panel. + * + * @param p the panel (<code>null</code> not permitted). + */ protected void installDefaults(JPanel p) { LookAndFeel.installColorsAndFont(p, "Panel.background", "Panel.foreground", "Panel.font"); + + // A test against the reference implementation shows that this method will + // install a border if one is defined in the UIDefaults table (even though + // the BasicLookAndFeel doesn't actually define a "Panel.border"). This + // test was written after discovering that a null argument to + // uninstallDefaults throws a NullPointerException in + // LookAndFeel.uninstallBorder()... + LookAndFeel.installBorder(p, "Panel.border"); } /** - * Uninstalls this UI from the JPanel. + * Uninstalls this UI delegate from the specified component. * - * @param c the JPanel from which to uninstall this UI + * @param c the component (<code>null</code> not permitted). */ public void uninstallUI(JComponent c) { @@ -78,13 +113,20 @@ public class BasicPanelUI extends PanelUI } /** - * Uninstalls the UI defaults that have been install through - * {@link #installDefaults}. + * Uninstalls the UI defaults for the specified panel. * - * @param p the panel from which to uninstall the UI defaults + * @param p the panel (<code>null</code> not permitted). */ protected void uninstallDefaults(JPanel p) { - // Nothing to do here. + // Tests on the reference implementation showed this method: + // (1) doesn't actually remove the installed colors and font installed + // by installDefaults(), it isn't necessary; + // (2) throws a NullPointerException in LookAndFeel.uninstallBorder() if + // p is null. Strangely, no border is installed by the + // BasicLookAndFeel - perhaps this is needed by another LAF? + + LookAndFeel.uninstallBorder(p); } + } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java index d3674664d4c..2518a91997a 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicProgressBarUI.java @@ -52,6 +52,7 @@ import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; +import java.awt.geom.AffineTransform; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -725,26 +726,22 @@ public class BasicProgressBarUI extends ProgressBarUI protected void paintString(Graphics g, int x, int y, int width, int height, int amountFull, Insets b) { - // FIXME: We do not support vertical text painting because Java2D is needed - // for this. - if (progressBar.getOrientation() == JProgressBar.VERTICAL) - return; - - // We want to place in the exact center of the bar. + String str = progressBar.getString(); + int full = getAmountFull(b, width, height); Point placement = getStringPlacement(g, progressBar.getString(), - x + b.left, y + b.top, + x + b.left, y + b.top, width - b.left - b.right, height - b.top - b.bottom); - Color savedColor = g.getColor(); Shape savedClip = g.getClip(); FontMetrics fm = g.getFontMetrics(progressBar.getFont()); - int full = getAmountFull(b, width, height); - String str = progressBar.getString(); - - // We draw this string two times with different clips so that the text - // over the filled area is painted with selectionForeground and over - // the clear area with selectionBackground. + + if (progressBar.getOrientation() == JProgressBar.VERTICAL) + { + AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2); + g.setFont(progressBar.getFont().deriveFont(rotate)); + } + g.setColor(getSelectionForeground()); g.setClip(0, 0, full + b.left, height); g.drawString(str, placement.x, placement.y + fm.getAscent()); @@ -756,9 +753,9 @@ public class BasicProgressBarUI extends ProgressBarUI } /** - * This method sets the current animation index. If the index - * is greater than the number of frames, it resets to 0. - * + * This method sets the current animation index. If the index is greater than + * the number of frames, it resets to 0. + * * @param newValue The new animation index. */ protected void setAnimationIndex(int newValue) diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java index a66fa28e610..64a1deca572 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java @@ -1,5 +1,5 @@ /* BasicRadioButtonUI.java - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -167,9 +167,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI } if (text != null) paintText(g, b, tr, text); - // TODO: Figure out what is the size parameter? if (b.hasFocus() && b.isFocusPainted() && m.isEnabled()) - paintFocus(g, tr, null); + paintFocus(g, tr, c.getSize()); } /** @@ -177,9 +176,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI * * @param g the graphics context * @param tr the rectangle for the text label - * @param size the size (??) + * @param size the size of the <code>JRadioButton</code> component. */ - // TODO: Figure out what for is the size parameter. protected void paintFocus(Graphics g, Rectangle tr, Dimension size) { Color focusColor = UIManager.getColor(getPropertyPrefix() + ".focus"); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java index 933db4c6bc2..e20bc2bb3db 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java @@ -215,9 +215,8 @@ public class BasicRootPaneUI extends RootPaneUI JComponent.WHEN_IN_FOCUSED_WINDOW); if (newValue != null) { - Object[] keybindings = - (Object[]) UIManager.get - ("RootPane.defaultButtonWindowKeyBindings"); + Object[] keybindings = (Object[]) UIManager.get( + "RootPane.defaultButtonWindowKeyBindings"); LookAndFeel.loadKeyBindings(im, keybindings); } else diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java index e6a4eaf4fc1..03fb2255e88 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java @@ -1,5 +1,5 @@ /* BasicScrollPaneUI.java - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,6 +45,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; +import java.awt.event.ActionEvent; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.MouseWheelEvent; @@ -52,20 +53,31 @@ import java.awt.event.MouseWheelListener; 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.JScrollBar; import javax.swing.JScrollPane; +import javax.swing.JSlider; import javax.swing.JViewport; import javax.swing.LookAndFeel; import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneLayout; import javax.swing.Scrollable; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ScrollPaneUI; +/** + * A UI delegate for the {@link JScrollPane} component. + */ public class BasicScrollPaneUI extends ScrollPaneUI implements ScrollPaneConstants { @@ -236,7 +248,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI final Rectangle rect = new Rectangle(); /** - * Scroll with the mouse whell. + * Scroll with the mouse wheel. * * @author Audrius Meskauskas (audriusa@Bioinformatics.org) */ @@ -311,7 +323,11 @@ public class BasicScrollPaneUI extends ScrollPaneUI } /** - * Get the scroll bar value or null if there is no such scroll bar. + * Get the scroll bar value or 0 if there is no such scroll bar. + * + * @param bar the scroll bar (<code>null</code> permitted). + * + * @return The scroll bar value, or 0. */ final int getValue(JScrollBar bar) { @@ -478,6 +494,197 @@ public class BasicScrollPaneUI extends ScrollPaneUI v.getComponent(i).addMouseWheelListener(mouseWheelListener); } + InputMap getInputMap(int condition) + { + if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + return (InputMap) UIManager.get("ScrollPane.ancestorInputMap"); + return null; + } + + /** + * Returns the action map for the {@link JScrollPane}. All scroll panes + * share a single action map which is created the first time this method is + * called, then stored in the UIDefaults table for subsequent access. + * + * @return The shared action map. + */ + ActionMap getActionMap() + { + ActionMap map = (ActionMap) UIManager.get("ScrollPane.actionMap"); + + if (map == null) // first time here + { + map = createActionMap(); + if (map != null) + UIManager.put("Slider.actionMap", map); + } + return map; + } + + /** + * Creates the action map shared by all {@link JSlider} instances. + * This method is called once by {@link #getActionMap()} when it + * finds no action map in the UIDefaults table...after the map is + * created, it gets added to the defaults table so that subsequent + * calls to {@link #getActionMap()} will return the same shared + * instance. + * + * @return The action map. + */ + ActionMap createActionMap() + { + ActionMap map = new ActionMapUIResource(); + map.put("scrollLeft", + new AbstractAction("scrollLeft") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollEnd", + new AbstractAction("scrollEnd") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb1 = sp.getHorizontalScrollBar(); + if (sb1.isVisible()) + { + sb1.setValue(sb1.getMaximum()); + } + JScrollBar sb2 = sp.getVerticalScrollBar(); + if (sb2.isVisible()) + { + sb2.setValue(sb2.getMaximum()); + } + } + } + ); + map.put("unitScrollUp", + new AbstractAction("unitScrollUp") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("unitScrollLeft", + new AbstractAction("unitScrollLeft") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollUp", + new AbstractAction("scrollUp") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(-1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollRight", + new AbstractAction("scrollRight") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("scrollHome", + new AbstractAction("scrollHome") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb1 = sp.getHorizontalScrollBar(); + if (sb1.isVisible()) + { + sb1.setValue(sb1.getMinimum()); + } + JScrollBar sb2 = sp.getVerticalScrollBar(); + if (sb2.isVisible()) + { + sb2.setValue(sb2.getMinimum()); + } + } + } + ); + map.put("scrollDown", + new AbstractAction("scrollDown") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getBlockIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("unitScrollDown", + new AbstractAction("unitScrollDown") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getVerticalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + map.put("unitScrollRight", + new AbstractAction("unitScrollRight") { + public void actionPerformed(ActionEvent event) + { + JScrollPane sp = (JScrollPane) event.getSource(); + JScrollBar sb = sp.getHorizontalScrollBar(); + if (sb.isVisible()) + { + int delta = sb.getUnitIncrement(1); + sb.setValue(sb.getValue() + delta); + } + } + } + ); + return map; + } + /** * Installs additional keyboard actions on the scrollpane. This is a hook * method provided to subclasses in order to install their own keyboard @@ -486,13 +693,30 @@ public class BasicScrollPaneUI extends ScrollPaneUI * @param sp the scrollpane to install keyboard actions on */ protected void installKeyboardActions(JScrollPane sp) - throws NotImplementedException { - // TODO: Is this only a hook method or should we actually do something - // here? If the latter, than figure out what and implement this. + InputMap keyMap = getInputMap( + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + SwingUtilities.replaceUIInputMap(sp, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap); + ActionMap map = getActionMap(); + SwingUtilities.replaceUIActionMap(sp, map); } /** + * Uninstalls all keyboard actions from the JScrollPane that have been + * installed by {@link #installKeyboardActions}. This is a hook method + * provided to subclasses to add their own keyboard actions. + * + * @param sp the scrollpane to uninstall keyboard actions from + */ + protected void uninstallKeyboardActions(JScrollPane sp) + { + SwingUtilities.replaceUIActionMap(sp, null); + SwingUtilities.replaceUIInputMap(sp, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); + } + + /** * Creates and returns the change listener for the horizontal scrollbar. * * @return the change listener for the horizontal scrollbar @@ -536,6 +760,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI * Creates and returns the mouse wheel listener for the scrollpane. * * @return the mouse wheel listener for the scrollpane + * + * @since 1.4 */ protected MouseWheelListener createMouseWheelListener() { @@ -545,7 +771,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI public void uninstallUI(final JComponent c) { super.uninstallUI(c); - this.uninstallDefaults((JScrollPane)c); + this.uninstallDefaults((JScrollPane) c); uninstallListeners((JScrollPane) c); installKeyboardActions((JScrollPane) c); } @@ -574,23 +800,9 @@ public class BasicScrollPaneUI extends ScrollPaneUI } - /** - * Uninstalls all keyboard actions from the JScrollPane that have been - * installed by {@link #installKeyboardActions}. This is a hook method - * provided to subclasses to add their own keyboard actions. - * - * @param sp the scrollpane to uninstall keyboard actions from - */ - protected void uninstallKeyboardActions(JScrollPane sp) - throws NotImplementedException - { - // TODO: Is this only a hook method or should we actually do something - // here? If the latter, than figure out what and implement this. - } - public Dimension getMinimumSize(JComponent c) { - JScrollPane p = (JScrollPane ) c; + JScrollPane p = (JScrollPane) c; ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout(); return sl.minimumLayoutSize(c); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java index 137ab55a607..0569768a627 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Component; import java.awt.ComponentOrientation; @@ -70,6 +68,7 @@ import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JSlider; import javax.swing.LookAndFeel; +import javax.swing.RepaintManager; import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.UIManager; @@ -209,9 +208,9 @@ public class BasicSliderUI extends SliderUI * @param e A {@link FocusEvent}. */ public void focusGained(FocusEvent e) - throws NotImplementedException { - // FIXME: implement. + slider.repaint(); + hasFocus = true; } /** @@ -221,9 +220,9 @@ public class BasicSliderUI extends SliderUI * @param e A {@link FocusEvent}. */ public void focusLost(FocusEvent e) - throws NotImplementedException { - // FIXME: implement. + slider.repaint(); + hasFocus = false; } } @@ -592,6 +591,9 @@ public class BasicSliderUI extends SliderUI /** The focus color. */ private transient Color focusColor; + + /** True if the slider has focus. */ + private transient boolean hasFocus; /** * Creates a new Basic look and feel Slider UI. @@ -1548,9 +1550,11 @@ public class BasicSliderUI extends SliderUI paintTicks(g); if (slider.getPaintLabels()) paintLabels(g); - - //FIXME: Paint focus. + paintThumb(g); + + if (hasFocus) + paintFocus(g); } /** @@ -1602,7 +1606,7 @@ public class BasicSliderUI extends SliderUI Color saved_color = g.getColor(); g.setColor(getFocusColor()); - + g.drawRect(focusRect.x, focusRect.y, focusRect.width, focusRect.height); g.setColor(saved_color); @@ -1989,7 +1993,7 @@ public class BasicSliderUI extends SliderUI public void paintThumb(Graphics g) { Color saved_color = g.getColor(); - + Point a = new Point(thumbRect.x, thumbRect.y); Point b = new Point(a); Point c = new Point(a); @@ -1997,11 +2001,11 @@ public class BasicSliderUI extends SliderUI Point e = new Point(a); Polygon bright; - Polygon light; // light shadow - Polygon dark; // dark shadow + Polygon light; // light shadow + Polygon dark; // dark shadow Polygon all; - // This will be in X-dimension if the slider is inverted and y if it isn't. + // This will be in X-dimension if the slider is inverted and y if it isn't. int turnPoint; if (slider.getOrientation() == JSlider.HORIZONTAL) @@ -2016,13 +2020,15 @@ public class BasicSliderUI extends SliderUI bright = new Polygon(new int[] { b.x - 1, a.x, e.x, d.x }, new int[] { b.y, a.y, e.y, d.y }, 4); - dark = new Polygon(new int[] { b.x, c.x, d.x + 1 }, - new int[] { b.y, c.y - 1, d.y }, 3); - - light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 }, - new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3); - - all = new Polygon(new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 }, + dark = new Polygon(new int[] { b.x, c.x, d.x + 1 }, new int[] { b.y, + c.y - 1, + d.y }, 3); + + light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 }, + new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3); + + all = new Polygon( + new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 }, new int[] { a.y + 1, b.y + 1, c.y - 1, d.y - 1, e.y }, 5); } @@ -2038,15 +2044,16 @@ public class BasicSliderUI extends SliderUI bright = new Polygon(new int[] { c.x - 1, b.x, a.x, e.x }, new int[] { c.y - 1, b.y, a.y, e.y - 1 }, 4); - dark = new Polygon(new int[] { c.x, d.x, e.x }, - new int[] { c.y, d.y, e.y }, 3); + dark = new Polygon(new int[] { c.x, d.x, e.x }, new int[] { c.y, d.y, + e.y }, 3); - light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1}, - new int[] { c.y, d.y - 1, e.y - 1}, 3); - all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x, - e.x + 1 }, - new int[] { a.y + 1, b.y + 1, c.y - 1, c.y, d.y - 2, - e.y - 2 }, 6); + light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1 }, + new int[] { c.y, d.y - 1, e.y - 1 }, 3); + all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x, + e.x + 1 }, new int[] { a.y + 1, b.y + 1, + c.y - 1, c.y, + d.y - 2, e.y - 2 }, + 6); } g.setColor(Color.WHITE); @@ -2057,7 +2064,7 @@ public class BasicSliderUI extends SliderUI g.setColor(Color.GRAY); g.drawPolyline(light.xpoints, light.ypoints, light.npoints); - + g.setColor(Color.LIGHT_GRAY); g.drawPolyline(all.xpoints, all.ypoints, all.npoints); g.fillPolygon(all); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java index 465374bfda9..254a9a4fa2b 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java @@ -220,7 +220,7 @@ public class BasicSpinnerUI extends SpinnerUI BasicSpinnerUI.this.spinner.getModel().setValue(next); } - volatile boolean mouseDown = false; + volatile boolean mouseDown; Timer timer = new Timer(50, new ActionListener() { @@ -260,7 +260,7 @@ public class BasicSpinnerUI extends SpinnerUI BasicSpinnerUI.this.spinner.getModel().setValue(prev); } - volatile boolean mouseDown = false; + volatile boolean mouseDown; Timer timer = new Timer(50, new ActionListener() { diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java index 694baaddade..2d595597424 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java @@ -1,5 +1,5 @@ /* BasicSplitPaneUI.java -- - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Canvas; import java.awt.Color; import java.awt.Component; @@ -57,11 +55,17 @@ import java.awt.event.FocusListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.AbstractAction; +import javax.swing.ActionMap; +import javax.swing.InputMap; import javax.swing.JComponent; +import javax.swing.JSlider; import javax.swing.JSplitPane; import javax.swing.KeyStroke; import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; import javax.swing.UIManager; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.SplitPaneUI; import javax.swing.plaf.UIResource; @@ -676,7 +680,9 @@ public class BasicSplitPaneUI extends SplitPaneUI */ public void focusGained(FocusEvent ev) { - // FIXME: implement. + // repaint the divider because its background color may change due to + // the focus state... + divider.repaint(); } /** @@ -686,7 +692,9 @@ public class BasicSplitPaneUI extends SplitPaneUI */ public void focusLost(FocusEvent ev) { - // FIXME: implement. + // repaint the divider because its background color may change due to + // the focus state... + divider.repaint(); } } @@ -1046,21 +1054,143 @@ public class BasicSplitPaneUI extends SplitPaneUI } /** - * This method installs the keyboard actions for the JSplitPane. + * Returns the input map for the specified condition. + * + * @param condition the condition. + * + * @return The input map. + */ + InputMap getInputMap(int condition) + { + if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + return (InputMap) UIManager.get("SplitPane.ancestorInputMap"); + return null; + } + + /** + * Returns the action map for the {@link JSplitPane}. All sliders share + * a single action map which is created the first time this method is + * called, then stored in the UIDefaults table for subsequent access. + * + * @return The shared action map. + */ + ActionMap getActionMap() + { + ActionMap map = (ActionMap) UIManager.get("SplitPane.actionMap"); + + if (map == null) // first time here + { + map = createActionMap(); + if (map != null) + UIManager.put("SplitPane.actionMap", map); + } + return map; + } + + /** + * Creates the action map shared by all {@link JSlider} instances. + * This method is called once by {@link #getActionMap()} when it + * finds no action map in the UIDefaults table...after the map is + * created, it gets added to the defaults table so that subsequent + * calls to {@link #getActionMap()} will return the same shared + * instance. + * + * @return The action map. + */ + ActionMap createActionMap() + { + ActionMap map = new ActionMapUIResource(); + map.put("toggleFocus", + new AbstractAction("toggleFocus") { + public void actionPerformed(ActionEvent event) + { + // FIXME: What to do here? + } + } + ); + map.put("startResize", + new AbstractAction("startResize") { + public void actionPerformed(ActionEvent event) + { + splitPane.requestFocus(); + } + } + ); + map.put("selectMax", + new AbstractAction("selectMax") { + public void actionPerformed(ActionEvent event) + { + splitPane.setDividerLocation(1.0); + } + } + ); + map.put("selectMin", + new AbstractAction("selectMin") { + public void actionPerformed(ActionEvent event) + { + splitPane.setDividerLocation(0.0); + } + } + ); + map.put("negativeIncrement", + new AbstractAction("negativeIncrement") { + public void actionPerformed(ActionEvent event) + { + setDividerLocation(splitPane, Math.max(dividerLocation + - KEYBOARD_DIVIDER_MOVE_OFFSET, 0)); + } + } + ); + map.put("positiveIncrement", + new AbstractAction("positiveIncrement") { + public void actionPerformed(ActionEvent event) + { + setDividerLocation(splitPane, dividerLocation + + KEYBOARD_DIVIDER_MOVE_OFFSET); + } + } + ); + map.put("focusOutBackward", + new AbstractAction("focusOutBackward") { + public void actionPerformed(ActionEvent event) + { + // FIXME: implement this + } + } + ); + map.put("focusOutForward", + new AbstractAction("focusOutForward") { + public void actionPerformed(ActionEvent event) + { + // FIXME: implement this + } + } + ); + return map; + } + + /** + * Installs any keyboard actions. The list of keys that need to be bound are + * listed in Basic look and feel's defaults. */ protected void installKeyboardActions() - throws NotImplementedException { - // FIXME: implement. + InputMap keyMap = getInputMap( + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + SwingUtilities.replaceUIInputMap(splitPane, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap); + ActionMap map = getActionMap(); + SwingUtilities.replaceUIActionMap(splitPane, map); } /** * This method reverses the work done in installKeyboardActions. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: implement. + SwingUtilities.replaceUIActionMap(splitPane, null); + SwingUtilities.replaceUIInputMap(splitPane, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 6d9bed331cb..1b5249770ec 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -286,7 +286,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants width = Math.max(min, width); int tabAreaHeight = preferredTabAreaHeight(tabPlacement, width - tabAreaInsets.left - -tabAreaInsets.right); + - tabAreaInsets.right); height += tabAreaHeight; } else @@ -476,7 +476,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants else nextIndex = i + 1; int next = tabRuns[nextIndex]; - int end = (next != 0 ? next - 1 : tabCount - 1); + int end = next != 0 ? next - 1 : tabCount - 1; if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) { @@ -491,9 +491,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants padTabRun(tabPlacement, start, end, breakAt); } if (tabPlacement == BOTTOM) - y -= (maxTabHeight - tabRunOverlay); + y -= maxTabHeight - tabRunOverlay; else - y += (maxTabHeight - tabRunOverlay); + y += maxTabHeight - tabRunOverlay; } else { @@ -508,9 +508,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants padTabRun(tabPlacement, start, end, breakAt); } if (tabPlacement == RIGHT) - x -= (maxTabWidth - tabRunOverlay); + x -= maxTabWidth - tabRunOverlay; else - x += (maxTabWidth - tabRunOverlay); + x += maxTabWidth - tabRunOverlay; } } @@ -1818,7 +1818,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants next = tabRuns[0]; else next = tabRuns[i + 1]; - int end = (next != 0 ? next - 1 : tabCount - 1); + int end = next != 0 ? next - 1 : tabCount - 1; for (int j = start; j <= end; ++j) { if (j != selectedIndex) @@ -2194,7 +2194,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { case LEFT: x += calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); - w -= (x - insets.left); + w -= x - insets.left; break; case RIGHT: w -= calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); @@ -2205,7 +2205,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants case TOP: default: y += calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); - h -= (y - insets.top); + h -= y - insets.top; } // Fill background if necessary. @@ -2410,6 +2410,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ public Rectangle getTabBounds(JTabbedPane pane, int i) { + // Need to re-layout container if tab does not exist. + if (i >= rects.length) + layoutManager.layoutContainer(pane); return rects[i]; } @@ -3015,7 +3018,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { int currRun = getRunForTab(tabCount, tabIndex); int offset; - int nextRun = (forward) ? getNextTabRun(currRun) : getPreviousTabRun(currRun); + int nextRun = forward ? getNextTabRun(currRun) : getPreviousTabRun(currRun); if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) offset = rects[lastTabInRun(tabCount, nextRun)].y diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java index cfbebda2149..ce8846ff8af 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java @@ -199,10 +199,7 @@ public class BasicTableHeaderUI extends TableHeaderUI */ public void mouseExited(MouseEvent e) { - if (header.getResizingColumn() != null && header.getResizingAllowed()) - endResizing(); - if (header.getDraggedColumn() != null && header.getReorderingAllowed()) - endDragging(null); + // Nothing to do. } /** @@ -363,25 +360,20 @@ public class BasicTableHeaderUI extends TableHeaderUI void endDragging(MouseEvent e) { header.setDraggedColumn(null); - - // Return if the mouse have left the header area while pressed. - if (e == null) - { - header.repaint(draggingHeaderRect); - draggingHeaderRect = null; - return; - } - else - draggingHeaderRect = null; + draggingHeaderRect = null; TableColumnModel model = header.getColumnModel(); // Find where have we dragged the column. int x = e.getX(); int p = 0; - int col = - 1; + + int col = model.getColumnCount()-1; int n = model.getColumnCount(); + // This loop does not find the column if the mouse if out of the + // right boundary of the table header. Then we make this column the + // rightmost column. Scan: for (int i = 0; i < n; i++) { p += model.getColumn(i).getWidth(); @@ -391,8 +383,8 @@ public class BasicTableHeaderUI extends TableHeaderUI break Scan; } } - if (col >= 0) - header.getTable().moveColumn(draggingColumnNumber, col); + + header.getTable().moveColumn(draggingColumnNumber, col); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java index ef491cbf1c6..d3abba217cd 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java @@ -78,6 +78,7 @@ import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TableUI; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; @@ -228,8 +229,6 @@ public class BasicTableUI extends TableUI if (e.getClickCount() < ce.getClickCountToStart()) return; } - else if (e.getClickCount() < 2) - return; table.editCellAt(row, col); } } @@ -387,10 +386,8 @@ public class BasicTableUI extends TableUI int maxTotalColumnWidth = 0; for (int i = 0; i < table.getColumnCount(); i++) maxTotalColumnWidth += table.getColumnModel().getColumn(i).getMaxWidth(); - if (maxTotalColumnWidth == 0 || table.getRowCount() == 0) - return null; - return new Dimension(maxTotalColumnWidth, table.getRowCount()* - (table.getRowHeight()+table.getRowMargin())); + + return new Dimension(maxTotalColumnWidth, getHeight()); } /** @@ -408,16 +405,45 @@ public class BasicTableUI extends TableUI int minTotalColumnWidth = 0; for (int i = 0; i < table.getColumnCount(); i++) minTotalColumnWidth += table.getColumnModel().getColumn(i).getMinWidth(); - if (minTotalColumnWidth == 0 || table.getRowCount() == 0) - return null; - return new Dimension(minTotalColumnWidth, table.getRowCount()*table.getRowHeight()); + + return new Dimension(minTotalColumnWidth, getHeight()); } + /** + * Returns the preferred size for the table of that UI. + * + * @param comp ignored, the <code>table</code> field is used instead + * + * @return the preferred size for the table of that UI + */ public Dimension getPreferredSize(JComponent comp) { - int width = table.getColumnModel().getTotalColumnWidth(); - int height = table.getRowCount() * (table.getRowHeight()+table.getRowMargin()); - return new Dimension(width, height); + int prefTotalColumnWidth = 0; + for (int i = 0; i < table.getColumnCount(); i++) + { + TableColumn col = table.getColumnModel().getColumn(i); + prefTotalColumnWidth += col.getPreferredWidth(); + } + return new Dimension(prefTotalColumnWidth, getHeight()); + } + + /** + * Returns the table height. This helper method is used by + * {@link #getMinimumSize(JComponent)}, {@link #getPreferredSize(JComponent)} + * and {@link #getMaximumSize(JComponent)} to determine the table height. + * + * @return the table height + */ + private int getHeight() + { + int height = 0; + int rowCount = table.getRowCount(); + if (rowCount > 0 && table.getColumnCount() > 0) + { + Rectangle r = table.getCellRect(rowCount - 1, 0, true); + height = r.y + r.height; + } + return height; } protected void installDefaults() @@ -428,7 +454,6 @@ public class BasicTableUI extends TableUI table.setSelectionForeground(UIManager.getColor("Table.selectionForeground")); table.setSelectionBackground(UIManager.getColor("Table.selectionBackground")); table.setOpaque(true); - rendererPane = new CellRendererPane(); } protected void installKeyboardActions() @@ -1188,6 +1213,9 @@ public class BasicTableUI extends TableUI public void installUI(JComponent comp) { table = (JTable)comp; + rendererPane = new CellRendererPane(); + table.add(rendererPane); + installDefaults(); installKeyboardActions(); installListeners(); @@ -1197,7 +1225,11 @@ public class BasicTableUI extends TableUI { uninstallListeners(); uninstallKeyboardActions(); - uninstallDefaults(); + uninstallDefaults(); + + table.remove(rendererPane); + rendererPane = null; + table = null; } /** @@ -1257,7 +1289,6 @@ public class BasicTableUI extends TableUI } Rectangle bounds = table.getCellRect(r0, c0, false); - // The left boundary of the area being repainted. int left = bounds.x; @@ -1278,9 +1309,9 @@ public class BasicTableUI extends TableUI bounds.x += widths[c] + columnMargin; } bounds.x = left; - bounds.y += table.getRowHeight(r) + rowMargin; + bounds.y += table.getRowHeight(r); // Update row height for tables with custom heights. - bounds.height = table.getRowHeight(r + 1); + bounds.height = table.getRowHeight(r + 1) - rowMargin; } bottom = bounds.y - rowMargin; @@ -1311,7 +1342,7 @@ public class BasicTableUI extends TableUI { // The horizontal grid is draw below the cells, so we // add before drawing. - y += table.getRowHeight(r) + rowMargin; + y += table.getRowHeight(r); gfx.drawLine(left, y, p2.x, y); } gfx.setColor(save); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java index 93e119b31fa..3f5aa27cf40 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextAreaUI.java @@ -73,7 +73,7 @@ public class BasicTextAreaUI extends BasicTextUI */ public View create(Element elem) { - JTextArea comp = (JTextArea)getComponent(); + JTextArea comp = (JTextArea) getComponent(); if (comp.getLineWrap()) { if (comp.getWrapStyleWord()) @@ -105,7 +105,7 @@ public class BasicTextAreaUI extends BasicTextUI */ protected void propertyChange(PropertyChangeEvent ev) { - JTextArea comp = (JTextArea)getComponent(); + JTextArea comp = (JTextArea) getComponent(); if (ev.getPropertyName() == "lineWrap" || ev.getPropertyName() == "wrapStyleWord") { diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java index 3b620f04989..b058175a454 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java @@ -38,8 +38,6 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import gnu.classpath.NotImplementedException; - import java.awt.Color; import java.awt.Container; import java.awt.Dimension; @@ -64,10 +62,12 @@ import javax.swing.JComponent; import javax.swing.LookAndFeel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; +import javax.swing.TransferHandler; 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.AbstractDocument; @@ -734,18 +734,8 @@ public abstract class BasicTextUI extends TextUI // load any bindings for the newer InputMap / ActionMap interface SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED, - getInputMap(JComponent.WHEN_FOCUSED)); - 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); + getInputMap()); + SwingUtilities.replaceUIActionMap(textComponent, getActionMap()); } /** @@ -753,40 +743,71 @@ public abstract class BasicTextUI extends TextUI * * @return an ActionMap to be installed on the text component */ - ActionMap createActionMap() + private ActionMap getActionMap() + { + // Note: There are no .actionMap entries in the standard L&Fs. However, + // with the RI it is possible to install action maps via such keys, so + // we must load them too. It can be observed that when there is no + // .actionMap entry in the UIManager, one gets installed after a text + // component of that type has been loaded. + String prefix = getPropertyPrefix(); + String amName = prefix + ".actionMap"; + ActionMap am = (ActionMap) UIManager.get(amName); + if (am == null) + { + am = createActionMap(); + UIManager.put(amName, am); + } + + ActionMap map = new ActionMapUIResource(); + map.setParent(am); + + return map; + } + + /** + * Creates a default ActionMap for text components that have no UI default + * for this (the standard for the built-in L&Fs). The ActionMap is copied + * from the text component's getActions() method. + * + * @returna default ActionMap + */ + private ActionMap createActionMap() { - Action[] actions = textComponent.getActions(); ActionMap am = new ActionMapUIResource(); - for (int i = 0; i < actions.length; ++i) + Action[] actions = textComponent.getActions(); + for (int i = actions.length - 1; i >= 0; i--) { - String name = (String) actions[i].getValue(Action.NAME); - if (name != null) - am.put(name, actions[i]); + Action action = actions[i]; + am.put(action.getValue(Action.NAME), action); } + // Add TransferHandler's actions here. They don't seem to be in the + // JTextComponent's default actions, and I can't make up a better place + // to add them. + Action copyAction = TransferHandler.getCopyAction(); + am.put(copyAction.getValue(Action.NAME), copyAction); + Action cutAction = TransferHandler.getCutAction(); + am.put(cutAction.getValue(Action.NAME), cutAction); + Action pasteAction = TransferHandler.getPasteAction(); + am.put(pasteAction.getValue(Action.NAME), pasteAction); + return am; } /** * Gets the input map for the specified <code>condition</code>. * - * @param condition the condition for the InputMap - * * @return the InputMap for the specified condition */ - InputMap getInputMap(int condition) + private InputMap getInputMap() { + InputMap im = new InputMapUIResource(); String prefix = getPropertyPrefix(); - switch (condition) - { - case JComponent.WHEN_IN_FOCUSED_WINDOW: - // FIXME: is this the right string? nobody seems to use it. - return (InputMap) UIManager.get(prefix + ".windowInputMap"); - case JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT: - return (InputMap) UIManager.get(prefix + ".ancestorInputMap"); - default: - case JComponent.WHEN_FOCUSED: - return (InputMap) UIManager.get(prefix + ".focusInputMap"); - } + InputMap shared = + (InputMap) SharedUIDefaults.get(prefix + ".focusInputMap"); + if (shared != null) + im.setParent(shared); + return im; } /** @@ -831,9 +852,9 @@ public abstract class BasicTextUI extends TextUI * this UI. */ protected void uninstallKeyboardActions() - throws NotImplementedException { - // FIXME: Uninstall keyboard actions here. + SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED, null); + SwingUtilities.replaceUIActionMap(textComponent, null); } /** @@ -1041,7 +1062,12 @@ public abstract class BasicTextUI extends TextUI Rectangle l1 = modelToView(t, p0, firstBias); Rectangle l2 = modelToView(t, p1, secondBias); - if (l1.y == l2.y) + if (l1 == null || l2 == null) + { + // Unable to determine the start or end of the selection. + t.repaint(); + } + else if (l1.y == l2.y) { SwingUtilities.computeUnion(l2.x, l2.y, l2.width, l2.height, l1); t.repaint(l1); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java index 896ea0c89dc..921648670df 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java @@ -1,5 +1,5 @@ /* BasicToggleButtonUI.java - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,21 +44,35 @@ import java.awt.Rectangle; import javax.swing.AbstractButton; import javax.swing.JComponent; +import javax.swing.JToggleButton; import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +/** + * A UI delegate for the {@link JToggleButton} component. + */ public class BasicToggleButtonUI extends BasicButtonUI { - public static ComponentUI createUI(final JComponent component) + + /** + * Returns a UI delegate for the specified component. + * + * @param component the component (should be an instance of + * {@link JToggleButton}). + * + * @return An instance of <code>BasicToggleButtonUI</code>. + */ + public static ComponentUI createUI(JComponent component) { return new BasicToggleButtonUI(); } /** - * Returns the prefix for the UI defaults property for this UI class. - * This is 'ToggleButton' for this class. + * Returns the prefix for entries in the {@link UIManager} defaults table + * (<code>"ToggleButton."</code> in this case). * - * @return the prefix for the UI defaults property + * @return <code>"ToggleButton."</code> */ protected String getPropertyPrefix() { @@ -89,15 +103,10 @@ public class BasicToggleButtonUI extends BasicButtonUI else vr = SwingUtilities.getLocalBounds(b); String text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f), - b.getText(), - currentIcon(b), - b.getVerticalAlignment(), - b.getHorizontalAlignment(), - b.getVerticalTextPosition(), - b.getHorizontalTextPosition(), - vr, ir, tr, - b.getIconTextGap() - + defaultTextShiftOffset); + b.getText(), currentIcon(b), b.getVerticalAlignment(), + b.getHorizontalAlignment(), b.getVerticalTextPosition(), + b.getHorizontalTextPosition(), vr, ir, tr, b.getIconTextGap() + + defaultTextShiftOffset); if ((b.getModel().isArmed() && b.getModel().isPressed()) || b.isSelected()) diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java index 80fec6a775a..eabac157036 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java @@ -1,5 +1,5 @@ /* BasicToolBarUI.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -75,11 +75,12 @@ import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; -import javax.swing.border.EtchedBorder; +import javax.swing.border.CompoundBorder; import javax.swing.event.MouseInputListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ToolBarUI; import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicBorders.ButtonBorder; /** * This is the Basic Look and Feel UI class for JToolBar. @@ -310,8 +311,19 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected Border createNonRolloverBorder() { - return new EtchedBorder(); - } + Border b = UIManager.getBorder("ToolBar.nonrolloverBorder"); + + if (b == null) + { + b = new CompoundBorder( + new ButtonBorder(UIManager.getColor("Button.shadow"), + UIManager.getColor("Button.darkShadow"), + UIManager.getColor("Button.light"), + UIManager.getColor("Button.highlight")), + BasicBorders.getMarginBorder()); + } + + return b; } /** * This method creates a new PropertyChangeListener for the JToolBar. @@ -331,18 +343,19 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected Border createRolloverBorder() { - return new EtchedBorder() + Border b = UIManager.getBorder("ToolBar.rolloverBorder"); + + if (b == null) { - public void paintBorder(Component c, Graphics g, int x, int y, - int width, int height) - { - if (c instanceof JButton) - { - if (((JButton) c).getModel().isRollover()) - super.paintBorder(c, g, x, y, width, height); - } - } - }; + b = new CompoundBorder( + new ButtonBorder(UIManager.getColor("Button.shadow"), + UIManager.getColor("Button.darkShadow"), + UIManager.getColor("Button.light"), + UIManager.getColor("Button.highlight")), + BasicBorders.getMarginBorder()); + } + + return b; } /** @@ -745,6 +758,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants * @param direction The direction to give focus to. */ protected void navigateFocusedComp(int direction) + throws NotImplementedException { // FIXME: Implement. } @@ -761,6 +775,10 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants { AbstractButton b = (AbstractButton) c; b.setRolloverEnabled(false); + + // Save old border in hashtable. + borders.put(b, b.getBorder()); + b.setBorder(nonRolloverBorder); } } @@ -772,11 +790,11 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected void setBorderToNormal(Component c) { - if (c instanceof JButton) + if (c instanceof AbstractButton) { - JButton b = (JButton) c; - Border border = (Border) borders.get(b); - b.setBorder(border); + AbstractButton b = (AbstractButton) c; + b.setRolloverEnabled(true); + b.setBorder((Border) borders.remove(b)); } } @@ -787,11 +805,15 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants */ protected void setBorderToRollover(Component c) { - if (c instanceof JButton) + if (c instanceof AbstractButton) { - JButton b = (JButton) c; - b.setRolloverEnabled(true); - b.setBorder(rolloverBorder); + AbstractButton b = (AbstractButton) c; + b.setRolloverEnabled(false); + + // Save old border in hashtable. + borders.put(b, b.getBorder()); + + b.setBorder(rolloverBorder); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java index be61ccaec22..8cbea7f592d 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java @@ -38,6 +38,7 @@ package javax.swing.plaf.basic; +import gnu.classpath.NotImplementedException; import gnu.javax.swing.tree.GnuPath; import java.awt.Color; @@ -48,7 +49,6 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Insets; import java.awt.Label; -import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -80,7 +80,6 @@ import javax.swing.JComponent; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTree; -import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.Timer; @@ -96,7 +95,6 @@ import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TreeUI; import javax.swing.tree.AbstractLayoutCache; import javax.swing.tree.DefaultTreeCellEditor; @@ -251,6 +249,9 @@ public class BasicTreeUI /** The max height of the nodes in the tree. */ int maxHeight = 0; + + /** The hash color. */ + Color hashColor; /** Listeners */ PropertyChangeListener propertyChangeListener; @@ -279,6 +280,11 @@ public class BasicTreeUI * not the double mouse click) on the selected tree node. */ Timer startEditTimer; + + /** + * The zero size icon, used for expand controls, if they are not visible. + */ + static Icon nullIcon; /** * The special value of the mouse event is sent indicating that this is not @@ -298,17 +304,6 @@ public class BasicTreeUI nodeDimensions = createNodeDimensions(); configureLayoutCache(); - propertyChangeListener = createPropertyChangeListener(); - focusListener = createFocusListener(); - treeSelectionListener = createTreeSelectionListener(); - mouseListener = createMouseListener(); - keyListener = createKeyListener(); - selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener(); - componentListener = createComponentListener(); - cellEditorListener = createCellEditorListener(); - treeExpansionListener = createTreeExpansionListener(); - treeModelListener = createTreeModelListener(); - editingRow = - 1; lastSelectedRow = - 1; } @@ -331,7 +326,7 @@ public class BasicTreeUI */ protected Color getHashColor() { - return UIManager.getColor("Tree.hash"); + return hashColor; } /** @@ -341,8 +336,7 @@ public class BasicTreeUI */ protected void setHashColor(Color color) { - // FIXME: Putting something in the UIDefaults map is certainly wrong. - UIManager.put("Tree.hash", color); + hashColor = color; } /** @@ -505,9 +499,22 @@ public class BasicTreeUI */ protected void setModel(TreeModel model) { - tree.setModel(model); + completeEditing(); + + if (treeModel != null && treeModelListener != null) + treeModel.removeTreeModelListener(treeModelListener); + treeModel = tree.getModel(); - treeState.setModel(treeModel); + + if (treeModel != null && treeModelListener != null) + treeModel.addTreeModelListener(treeModelListener); + + if (treeState != null) + { + treeState.setModel(treeModel); + updateLayoutCacheExpandedNodes(); + updateSize(); + } } /** @@ -547,7 +554,13 @@ public class BasicTreeUI */ protected void setShowsRootHandles(boolean newValue) { - tree.setShowsRootHandles(newValue); + completeEditing(); + updateDepthOffset(); + if (treeState != null) + { + treeState.invalidateSizes(); + updateSize(); + } } /** @@ -673,6 +686,20 @@ public class BasicTreeUI treeState.setRowHeight(maxHeight); return maxHeight; } + + /** + * Get the tree node icon. + */ + Icon getNodeIcon(TreePath path) + { + Object node = path.getLastPathComponent(); + if (treeModel.isLeaf(node)) + return UIManager.getIcon("Tree.leafIcon"); + else if (treeState.getExpandedState(path)) + return UIManager.getIcon("Tree.openIcon"); + else + return UIManager.getIcon("Tree.closedIcon"); + } /** * Returns the path for passed in row. If row is not visible null is returned. @@ -801,7 +828,11 @@ public class BasicTreeUI */ protected void prepareForUIInstall() { - // TODO: Implement this properly. + lastSelectedRow = -1; + preferredSize = new Dimension(); + largeModel = tree.isLargeModel(); + preferredSize = new Dimension(); + setModel(tree.getModel()); } /** @@ -810,7 +841,14 @@ public class BasicTreeUI */ protected void completeUIInstall() { - // TODO: Implement this properly. + setShowsRootHandles(tree.getShowsRootHandles()); + updateRenderer(); + updateDepthOffset(); + setSelectionModel(tree.getSelectionModel()); + treeState = createLayoutCache(); + treeSelectionModel.setRowMapper(treeState); + configureLayoutCache(); + updateSize(); } /** @@ -819,7 +857,7 @@ public class BasicTreeUI */ protected void completeUIUninstall() { - // TODO: Implement this properly. + tree = null; } /** @@ -972,15 +1010,14 @@ public class BasicTreeUI */ protected TreeCellEditor createDefaultCellEditor() { - if (currentCellRenderer != null) - return new DefaultTreeCellEditor( - tree, - (DefaultTreeCellRenderer) currentCellRenderer, - cellEditor); - return new DefaultTreeCellEditor( - tree, - (DefaultTreeCellRenderer) createDefaultCellRenderer(), - cellEditor); + DefaultTreeCellEditor ed; + if (currentCellRenderer != null + && currentCellRenderer instanceof DefaultTreeCellRenderer) + ed = new DefaultTreeCellEditor(tree, + (DefaultTreeCellRenderer) currentCellRenderer); + else + ed = new DefaultTreeCellEditor(tree, null); + return ed; } /** @@ -1077,7 +1114,7 @@ public class BasicTreeUI */ protected void updateLayoutCacheExpandedNodes() { - if (treeModel != null) + if (treeModel != null && treeModel.getRoot() != null) updateExpandedDescendants(new TreePath(treeModel.getRoot())); } @@ -1132,14 +1169,12 @@ public class BasicTreeUI protected void updateRenderer() { if (tree != null) - { - if (tree.getCellRenderer() == null) - { - if (currentCellRenderer == null) - currentCellRenderer = createDefaultCellRenderer(); - tree.setCellRenderer(currentCellRenderer); - } - } + currentCellRenderer = tree.getCellRenderer(); + + if (currentCellRenderer == null) + currentCellRenderer = createDefaultCellRenderer(); + + updateCellEditor(); } /** @@ -1206,6 +1241,7 @@ public class BasicTreeUI rightChildIndent = UIManager.getInt("Tree.rightChildIndent"); leftChildIndent = UIManager.getInt("Tree.leftChildIndent"); + totalChildIndent = rightChildIndent + leftChildIndent; setRowHeight(UIManager.getInt("Tree.rowHeight")); tree.setRowHeight(getRowHeight()); tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand")); @@ -1218,40 +1254,103 @@ public class BasicTreeUI */ protected void installKeyboardActions() { - InputMap focusInputMap = (InputMap) UIManager.get("Tree.focusInputMap"); - InputMapUIResource parentInputMap = new InputMapUIResource(); - ActionMap parentActionMap = new ActionMapUIResource(); + InputMap focusInputMap = + (InputMap) SharedUIDefaults.get("Tree.focusInputMap"); + SwingUtilities.replaceUIInputMap(tree, JComponent.WHEN_FOCUSED, + focusInputMap); + InputMap ancestorInputMap = + (InputMap) SharedUIDefaults.get("Tree.ancestorInputMap"); + SwingUtilities.replaceUIInputMap(tree, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, + ancestorInputMap); + action = new TreeAction(); - Object keys[] = focusInputMap.allKeys(); - for (int i = 0; i < keys.length; i++) - { - parentInputMap.put( - KeyStroke.getKeyStroke( - ((KeyStroke) keys[i]).getKeyCode(), - convertModifiers(((KeyStroke) keys[i]).getModifiers())), - (String) focusInputMap.get((KeyStroke) keys[i])); - - parentInputMap.put( - KeyStroke.getKeyStroke( - ((KeyStroke) keys[i]).getKeyCode(), - ((KeyStroke) keys[i]).getModifiers()), - (String) focusInputMap.get((KeyStroke) keys[i])); - - parentActionMap.put( - (String) focusInputMap.get((KeyStroke) keys[i]), - new ActionListenerProxy( - action, - (String) focusInputMap.get((KeyStroke) keys[i]))); + SwingUtilities.replaceUIActionMap(tree, getActionMap()); + } + /** + * Creates and returns the shared action map for JTrees. + * + * @return the shared action map for JTrees + */ + private ActionMap getActionMap() + { + ActionMap am = (ActionMap) UIManager.get("Tree.actionMap"); + if (am == null) + { + am = createDefaultActions(); + UIManager.getLookAndFeelDefaults().put("Tree.actionMap", am); } + return am; + } + + /** + * Creates the default actions when there are none specified by the L&F. + * + * @return the default actions + */ + private ActionMap createDefaultActions() + { + ActionMapUIResource am = new ActionMapUIResource(); + Action action; + + action= new TreeAction(); + am.put(action.getValue(Action.NAME), action); + + // TreeHomeAction. + action= new TreeHomeAction(-1, "selectFirst"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(-1, "selectFirstChangeLead"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(-1, "selectFirstExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(1, "selectLast"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(1, "selectLastChangeLead"); + am.put(action.getValue(Action.NAME), action); + action= new TreeHomeAction(1, "selectLastExtendSelection"); + am.put(action.getValue(Action.NAME), action); + + // TreeIncrementAction. + action = new TreeIncrementAction(-1, "selectPrevious"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(-1, "selectPreviousExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(-1, "selectPreviousChangeLead"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(1, "selectNext"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(1, "selectNextExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreeIncrementAction(1, "selectNextChangeLead"); + am.put(action.getValue(Action.NAME), action); + + // TreeTraverseAction. + action = new TreeTraverseAction(-1, "selectParent"); + am.put(action.getValue(Action.NAME), action); + action = new TreeTraverseAction(1, "selectChild"); + am.put(action.getValue(Action.NAME), action); + + // TreeToggleAction. + action = new TreeToggleAction("toggleAndAnchor"); + am.put(action.getValue(Action.NAME), action); - parentInputMap.setParent(tree.getInputMap( - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent()); - parentActionMap.setParent(tree.getActionMap().getParent()); - tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent( - parentInputMap); - tree.getActionMap().setParent(parentActionMap); + // TreePageAction. + action = new TreePageAction(-1, "scrollUpChangeSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(-1, "scrollUpExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(-1, "scrollUpChangeLead"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(1, "scrollDownChangeSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(1, "scrollDownExtendSelection"); + am.put(action.getValue(Action.NAME), action); + action = new TreePageAction(1, "scrollDownChangeLead"); + am.put(action.getValue(Action.NAME), action); + + return am; } /** @@ -1295,16 +1394,41 @@ public class BasicTreeUI */ protected void installListeners() { + propertyChangeListener = createPropertyChangeListener(); tree.addPropertyChangeListener(propertyChangeListener); + + focusListener = createFocusListener(); tree.addFocusListener(focusListener); + + treeSelectionListener = createTreeSelectionListener(); tree.addTreeSelectionListener(treeSelectionListener); + + mouseListener = createMouseListener(); tree.addMouseListener(mouseListener); + + keyListener = createKeyListener(); tree.addKeyListener(keyListener); - tree.addPropertyChangeListener(selectionModelPropertyChangeListener); + + selectionModelPropertyChangeListener = + createSelectionModelPropertyChangeListener(); + if (treeSelectionModel != null + && selectionModelPropertyChangeListener != null) + { + treeSelectionModel.addPropertyChangeListener + (selectionModelPropertyChangeListener); + } + + componentListener = createComponentListener(); tree.addComponentListener(componentListener); + + treeExpansionListener = createTreeExpansionListener(); tree.addTreeExpansionListener(treeExpansionListener); + + treeModelListener = createTreeModelListener(); if (treeModel != null) treeModel.addTreeModelListener(treeModelListener); + + cellEditorListener = createCellEditorListener(); } /** @@ -1315,27 +1439,15 @@ public class BasicTreeUI public void installUI(JComponent c) { tree = (JTree) c; - treeModel = tree.getModel(); prepareForUIInstall(); - super.installUI(c); installDefaults(); installComponents(); installKeyboardActions(); installListeners(); - - setCellEditor(createDefaultCellEditor()); - createdCellEditor = true; - isEditing = false; - - setModel(tree.getModel()); - treeSelectionModel = tree.getSelectionModel(); - setRootVisible(tree.isRootVisible()); - treeState.setRootVisible(tree.isRootVisible()); - completeUIInstall(); } - + /** * Uninstall the defaults for the tree */ @@ -1353,11 +1465,12 @@ public class BasicTreeUI */ public void uninstallUI(JComponent c) { + completeEditing(); + prepareForUIUninstall(); uninstallDefaults(); uninstallKeyboardActions(); uninstallListeners(); - tree = null; uninstallComponents(); completeUIUninstall(); } @@ -1590,6 +1703,9 @@ public class BasicTreeUI protected void completeEditing(boolean messageStop, boolean messageCancel, boolean messageTree) { + if (! stopEditingInCompleteEditing || editingComponent == null) + return; + if (messageStop) { getCellEditor().stopCellEditing(); @@ -1675,7 +1791,7 @@ public class BasicTreeUI int mouseY) { if (isLocationInExpandControl(path, mouseX, mouseY)) - toggleExpandState(path); + handleExpandControlClick(path, mouseX, mouseY); } /** @@ -1694,16 +1810,17 @@ public class BasicTreeUI int mouseY) { boolean cntlClick = false; - int row = getRowForPath(tree, path); - - if (! isLeaf(row)) + if (! treeModel.isLeaf(path.getLastPathComponent())) { - Rectangle bounds = getPathBounds(tree, path); - - if (hasControlIcons() - && (mouseX < bounds.x) - && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap))) - cntlClick = true; + int width = 8; // Only guessing. + Icon expandedIcon = getExpandedIcon(); + if (expandedIcon != null) + width = expandedIcon.getIconWidth(); + + Insets i = tree.getInsets(); + int left = getRowX(tree.getRowForPath(path), path.getPathCount() - 1) + -getRightChildIndent() - width / 2 + i.left; + cntlClick = mouseX >= left && mouseX <= left + width; } return cntlClick; } @@ -1786,7 +1903,14 @@ public class BasicTreeUI */ protected boolean isToggleEvent(MouseEvent event) { - return true; + boolean toggle = false; + if (SwingUtilities.isLeftMouseButton(event)) + { + int clickCount = tree.getToggleClickCount(); + if (clickCount > 0 && event.getClickCount() == clickCount) + toggle = true; + } + return toggle; } /** @@ -1831,7 +1955,8 @@ public class BasicTreeUI { // This is an ordinary event that just selects the clicked row. tree.setSelectionPath(path); - tree.setAnchorSelectionPath(path); + if (isToggleEvent(event)) + toggleExpandState(path); } } @@ -1969,7 +2094,32 @@ public class BasicTreeUI */ public void componentMoved(ComponentEvent e) { - // TODO: What should be done here, if anything? + if (timer == null) + { + JScrollPane scrollPane = getScrollPane(); + if (scrollPane == null) + updateSize(); + else + { + // Determine the scrollbar that is adjusting, if any, and + // start the timer for that. If no scrollbar is adjusting, + // we simply call updateSize(). + scrollBar = scrollPane.getVerticalScrollBar(); + if (scrollBar == null || !scrollBar.getValueIsAdjusting()) + { + // It's not the vertical scrollbar, try the horizontal one. + scrollBar = scrollPane.getHorizontalScrollBar(); + if (scrollBar != null && scrollBar.getValueIsAdjusting()) + startTimer(); + else + updateSize(); + } + else + { + startTimer(); + } + } + } } /** @@ -1978,7 +2128,12 @@ public class BasicTreeUI */ protected void startTimer() { - // TODO: Implement this properly. + if (timer == null) + { + timer = new Timer(200, this); + timer.setRepeats(true); + } + timer.start(); } /** @@ -1988,7 +2143,13 @@ public class BasicTreeUI */ protected JScrollPane getScrollPane() { - return null; + JScrollPane found = null; + Component p = tree.getParent(); + while (p != null && !(p instanceof JScrollPane)) + p = p.getParent(); + if (p instanceof JScrollPane) + found = (JScrollPane) p; + return found; } /** @@ -1999,7 +2160,14 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent ae) { - // TODO: Implement this properly. + if (scrollBar == null || !scrollBar.getValueIsAdjusting()) + { + if (timer != null) + timer.stop(); + updateSize(); + timer = null; + scrollBar = null; + } } } @@ -2080,7 +2248,7 @@ public class BasicTreeUI { repaintLeadRow(); } - + /** * Repaint the lead row. */ @@ -2122,6 +2290,7 @@ public class BasicTreeUI * @param e the key typed */ public void keyTyped(KeyEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2132,6 +2301,7 @@ public class BasicTreeUI * @param e the key pressed */ public void keyPressed(KeyEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2142,6 +2312,7 @@ public class BasicTreeUI * @param e the key released */ public void keyReleased(KeyEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2170,94 +2341,29 @@ public class BasicTreeUI */ public void mousePressed(MouseEvent e) { - // Any mouse click cancels the previous waiting edit action, initiated - // by the single click on the selected node. - if (startEditTimer != null) - { - startEditTimer.stop(); - startEditTimer = null; - } - - Point click = e.getPoint(); - TreePath path = getClosestPathForLocation(tree, click.x, click.y); - if (path != null) + if (tree != null && tree.isEnabled()) { - Rectangle bounds = getPathBounds(tree, path); - int row = getRowForPath(tree, path); - - // Cancel the editing session if clicked on the different row. - if (tree.isEditing() && row != editingRow) - cancelEditing(tree); - - boolean cntlClick = isLocationInExpandControl(path, click.x, click.y); - - boolean isLeaf = isLeaf(row); - - TreeCellRenderer tcr = getCellRenderer(); - Icon icon; - if (isLeaf) - icon = UIManager.getIcon("Tree.leafIcon"); - else if (tree.isExpanded(path)) - 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; - } + // Maybe stop editing and return. + if (isEditing(tree) && tree.getInvokesStopCellEditing() + && !stopEditing(tree)) + return; - // add gap*2 for the space before and after the text - if (icon != null) - bounds.width += icon.getIconWidth() + gap * 2; + int x = e.getX(); + int y = e.getY(); + TreePath path = getClosestPathForLocation(tree, x, y); - boolean inBounds = bounds.contains(click.x, click.y); - if ((inBounds || cntlClick) && tree.isVisible(path)) + if (path != null) { - if (inBounds) - { - TreePath currentLead = tree.getLeadSelectionPath(); - if (currentLead != null && currentLead.equals(path) - && e.getClickCount() == 1 && tree.isEditable()) - { - // Schedule the editing session. - final TreePath editPath = path; - - if (startEditTimer != null) - startEditTimer.stop(); - - startEditTimer = new Timer(WAIT_TILL_EDITING, - new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - startEditing(editPath, EDIT); - } - }); - startEditTimer.setRepeats(false); - startEditTimer.start(); - } - else - { - if (e.getClickCount() == 2 && ! isLeaf(row)) - toggleExpandState(path); - else - selectPathForEvent(path, e); - } - } + Rectangle bounds = getPathBounds(tree, path); + if (SwingUtilities.isLeftMouseButton(e)) + checkForClickInExpandControl(path, x, y); - if (cntlClick) + if (x > bounds.x && x <= (bounds.x + bounds.width)) { - handleExpandControlClick(path, click.x, click.y); - if (cellEditor != null) - cellEditor.cancelCellEditing(); - tree.scrollPathToVisible(path); + if (! startEditing(path, e)) + selectPathForEvent(path, e); } - else if (tree.isEditable()) - startEditing(path, e); } } } @@ -2271,6 +2377,7 @@ public class BasicTreeUI * @param e is the mouse event that occured */ public void mouseDragged(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2282,6 +2389,7 @@ public class BasicTreeUI * @param e the mouse event that occured */ public void mouseMoved(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2292,6 +2400,7 @@ public class BasicTreeUI * @param e is the mouse event that occured */ public void mouseReleased(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2332,6 +2441,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseClicked(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2342,6 +2452,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mousePressed(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2352,6 +2463,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseReleased(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2362,6 +2474,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseEntered(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2372,6 +2485,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseExited(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2385,6 +2499,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseDragged(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2396,6 +2511,7 @@ public class BasicTreeUI * @param e mouse event that occured */ public void mouseMoved(MouseEvent e) + throws NotImplementedException { // TODO: What should be done here, if anything? } @@ -2404,6 +2520,7 @@ public class BasicTreeUI * Removes event from the source */ protected void removeFromSource() + throws NotImplementedException { // TODO: Implement this properly. } @@ -2450,10 +2567,11 @@ public class BasicTreeUI if (s != null) { + TreePath path = treeState.getPathForRow(row); size.x = getRowX(row, depth); size.width = SwingUtilities.computeStringWidth(fm, s); - size.width = size.width + getCurrentControlIcon(null).getIconWidth() - + gap; + size.width = size.width + getCurrentControlIcon(path).getIconWidth() + + gap + getNodeIcon(path).getIconWidth(); size.height = getMaxHeight(tree); size.y = size.height * row; } @@ -2468,8 +2586,7 @@ public class BasicTreeUI */ protected int getRowX(int row, int depth) { - int iw = getCurrentControlIcon(null).getIconWidth(); - return depth * (rightChildIndent + iw/2); + return BasicTreeUI.this.getRowX(row, depth); } }// NodeDimensionsHandler @@ -2511,8 +2628,14 @@ public class BasicTreeUI } else if (property.equals(JTree.TREE_MODEL_PROPERTY)) { - treeModel = tree.getModel(); - treeModel.addTreeModelListener(treeModelListener); + setModel(tree.getModel()); + } + else if (property.equals(JTree.CELL_RENDERER_PROPERTY)) + { + setCellRenderer(tree.getCellRenderer()); + // Update layout. + if (treeState != null) + treeState.invalidateSizes(); } } } @@ -2540,45 +2663,38 @@ public class BasicTreeUI * the property that has changed. */ public void propertyChange(PropertyChangeEvent event) + throws NotImplementedException { // TODO: What should be done here, if anything? } } /** - * ActionListener that invokes cancelEditing when action performed. + * The action to cancel editing on this tree. */ public class TreeCancelEditingAction extends AbstractAction { - /** - * Constructor + * Creates the new tree cancel editing action. + * + * @param name the name of the action (used in toString). */ public TreeCancelEditingAction(String name) { - // TODO: Implement this properly. + super(name); } /** - * Invoked when an action occurs. + * Invoked when an action occurs, cancels the cell editing (if the + * tree cell is being edited). * * @param e event that occured */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly. - } - - /** - * Returns true if the action is enabled. - * - * @return true if the action is enabled, false otherwise - */ - public boolean isEnabled() - { - // TODO: Implement this properly. - return false; + if (isEnabled() && tree.isEditing()) + tree.cancelEditing(); } } @@ -2606,6 +2722,8 @@ public class BasicTreeUI { validCachedPreferredSize = false; treeState.setExpandedState(event.getPath(), true); + // The maximal cell height may change + maxHeight = 0; tree.revalidate(); tree.repaint(); } @@ -2619,6 +2737,8 @@ public class BasicTreeUI { validCachedPreferredSize = false; treeState.setExpandedState(event.getPath(), false); + // The maximal cell height may change + maxHeight = 0; tree.revalidate(); tree.repaint(); } @@ -2636,14 +2756,16 @@ public class BasicTreeUI protected int direction; /** - * Constructor + * Creates a new TreeHomeAction instance. * - * @param direction - it is home or end - * @param name is the name of the direction + * @param dir the direction to go to, <code>-1</code> for home, + * <code>1</code> for end + * @param name the name of the action */ - public TreeHomeAction(int direction, String name) + public TreeHomeAction(int dir, String name) { - // TODO: Implement this properly + direction = dir; + putValue(Action.NAME, name); } /** @@ -2653,7 +2775,61 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly + if (tree != null) + { + String command = (String) getValue(Action.NAME); + if (command.equals("selectFirst")) + { + ensureRowsAreVisible(0, 0); + tree.setSelectionInterval(0, 0); + } + if (command.equals("selectFirstChangeLead")) + { + ensureRowsAreVisible(0, 0); + tree.setLeadSelectionPath(getPathForRow(tree, 0)); + } + if (command.equals("selectFirstExtendSelection")) + { + ensureRowsAreVisible(0, 0); + TreePath anchorPath = tree.getAnchorSelectionPath(); + if (anchorPath == null) + tree.setSelectionInterval(0, 0); + else + { + int anchorRow = getRowForPath(tree, anchorPath); + tree.setSelectionInterval(0, anchorRow); + tree.setAnchorSelectionPath(anchorPath); + tree.setLeadSelectionPath(getPathForRow(tree, 0)); + } + } + else if (command.equals("selectLast")) + { + int end = getRowCount(tree) - 1; + ensureRowsAreVisible(end, end); + tree.setSelectionInterval(end, end); + } + else if (command.equals("selectLastChangeLead")) + { + int end = getRowCount(tree) - 1; + ensureRowsAreVisible(end, end); + tree.setLeadSelectionPath(getPathForRow(tree, end)); + } + else if (command.equals("selectLastExtendSelection")) + { + int end = getRowCount(tree) - 1; + ensureRowsAreVisible(end, end); + TreePath anchorPath = tree.getAnchorSelectionPath(); + if (anchorPath == null) + tree.setSelectionInterval(end, end); + else + { + int anchorRow = getRowForPath(tree, anchorPath); + tree.setSelectionInterval(end, anchorRow); + tree.setAnchorSelectionPath(anchorPath); + tree.setLeadSelectionPath(getPathForRow(tree, end)); + } + } + } } /** @@ -2663,8 +2839,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - // TODO: Implement this properly - return false; + return (tree != null) && tree.isEnabled(); } } @@ -2673,21 +2848,24 @@ public class BasicTreeUI * up or down based on direction. */ public class TreeIncrementAction - extends AbstractAction + extends AbstractAction { - /** Specifies the direction to adjust the selection by. */ + /** + * Specifies the direction to adjust the selection by. + */ protected int direction; /** - * Constructor + * Creates a new TreeIncrementAction. * - * @param direction up or down + * @param dir up or down, <code>-1</code> for up, <code>1</code> for down * @param name is the name of the direction */ - public TreeIncrementAction(int direction, String name) + public TreeIncrementAction(int dir, String name) { - // TODO: Implement this properly + direction = dir; + putValue(Action.NAME, name); } /** @@ -2712,7 +2890,7 @@ public class BasicTreeUI boolean hasNext = nextRow < rows; boolean hasPrev = prevRow >= 0 && rows > 0; TreePath newPath; - String command = e.getActionCommand(); + String command = (String) getValue(Action.NAME); if (command.equals("selectPreviousChangeLead") && hasPrev) { @@ -2776,8 +2954,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - // TODO: Implement this properly - return false; + return (tree != null) && tree.isEnabled(); } } @@ -2883,6 +3060,7 @@ public class BasicTreeUI public TreePageAction(int direction, String name) { this.direction = direction; + putValue(Action.NAME, name); } /** @@ -2892,7 +3070,94 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly. + String command = (String) getValue(Action.NAME); + boolean extendSelection = command.equals("scrollUpExtendSelection") + || command.equals("scrollDownExtendSelection"); + boolean changeSelection = command.equals("scrollUpChangeSelection") + || command.equals("scrollDownChangeSelection"); + + // Disable change lead, unless we are in discontinuous mode. + if (!extendSelection && !changeSelection + && tree.getSelectionModel().getSelectionMode() != + TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION) + { + changeSelection = true; + } + + int rowCount = getRowCount(tree); + if (rowCount > 0 && treeSelectionModel != null) + { + Dimension maxSize = tree.getSize(); + TreePath lead = tree.getLeadSelectionPath(); + TreePath newPath = null; + Rectangle visible = tree.getVisibleRect(); + if (direction == -1) // The RI handles -1 as up. + { + newPath = getClosestPathForLocation(tree, visible.x, visible.y); + if (newPath.equals(lead)) // Corner case, adjust one page up. + { + visible.y = Math.max(0, visible.y - visible.height); + newPath = getClosestPathForLocation(tree, visible.x, + visible.y); + } + } + else // +1 is down. + { + visible.y = Math.min(maxSize.height, + visible.y + visible.height - 1); + newPath = getClosestPathForLocation(tree, visible.x, visible.y); + if (newPath.equals(lead)) // Corner case, adjust one page down. + { + visible.y = Math.min(maxSize.height, + visible.y + visible.height - 1); + newPath = getClosestPathForLocation(tree, visible.x, + visible.y); + } + } + + // Determine new visible rect. + Rectangle newVisible = getPathBounds(tree, newPath); + newVisible.x = visible.x; + newVisible.width = visible.width; + if (direction == -1) + { + newVisible.height = visible.height; + } + else + { + newVisible.y -= (visible.height - newVisible.height); + newVisible.height = visible.height; + } + + if (extendSelection) + { + // Extend selection. + TreePath anchorPath = tree.getAnchorSelectionPath(); + if (anchorPath == null) + { + tree.setSelectionPath(newPath); + } + else + { + int newIndex = getRowForPath(tree, newPath); + int anchorIndex = getRowForPath(tree, anchorPath); + tree.setSelectionInterval(Math.min(anchorIndex, newIndex), + Math.max(anchorIndex, newIndex)); + tree.setAnchorSelectionPath(anchorPath); + tree.setLeadSelectionPath(newPath); + } + } + else if (changeSelection) + { + tree.setSelectionPath(newPath); + } + else // Change lead. + { + tree.setLeadSelectionPath(newPath); + } + + tree.scrollRectToVisible(newVisible); + } } /** @@ -2902,7 +3167,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - return false; + return (tree != null) && tree.isEnabled(); } }// TreePageAction @@ -2958,13 +3223,13 @@ public class BasicTreeUI extends AbstractAction { /** - * Constructor + * Creates a new TreeToggleAction. * * @param name is the name of <code>Action</code> field */ public TreeToggleAction(String name) { - // Nothing to do here. + putValue(Action.NAME, name); } /** @@ -2974,7 +3239,17 @@ public class BasicTreeUI */ public void actionPerformed(ActionEvent e) { - // TODO: Implement this properly. + int selected = tree.getLeadSelectionRow(); + if (selected != -1 && isLeaf(selected)) + { + TreePath anchorPath = tree.getAnchorSelectionPath(); + TreePath leadPath = tree.getLeadSelectionPath(); + toggleExpandState(getPathForRow(tree, selected)); + // Need to do this, so that the toggling doesn't mess up the lead + // and anchor. + tree.setLeadSelectionPath(leadPath); + tree.setAnchorSelectionPath(anchorPath); + } } /** @@ -2984,7 +3259,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - return false; + return (tree != null) && tree.isEnabled(); } } // TreeToggleAction @@ -3009,6 +3284,7 @@ public class BasicTreeUI public TreeTraverseAction(int direction, String name) { this.direction = direction; + putValue(Action.NAME, name); } /** @@ -3022,7 +3298,8 @@ public class BasicTreeUI if (current == null) return; - if (e.getActionCommand().equals("selectParent")) + String command = (String) getValue(Action.NAME); + if (command.equals("selectParent")) { if (current == null) return; @@ -3042,7 +3319,7 @@ public class BasicTreeUI tree.setSelectionPath(parent); } } - else if (e.getActionCommand().equals("selectChild")) + else if (command.equals("selectChild")) { Object node = current.getLastPathComponent(); int nc = treeModel.getChildCount(node); @@ -3068,8 +3345,7 @@ public class BasicTreeUI */ public boolean isEnabled() { - // TODO: Implement this properly - return false; + return (tree != null) && tree.isEnabled(); } } @@ -3094,9 +3370,35 @@ public class BasicTreeUI */ Icon getCurrentControlIcon(TreePath path) { - if (tree.isExpanded(path)) - return expandedIcon; - return collapsedIcon; + if (hasControlIcons()) + { + if (tree.isExpanded(path)) + return expandedIcon; + else + return collapsedIcon; + } + else + { + if (nullIcon == null) + nullIcon = new Icon() + { + public int getIconHeight() + { + return 0; + } + + public int getIconWidth() + { + return 0; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + // No action here. + } + }; + return nullIcon; + } } /** @@ -3323,10 +3625,8 @@ public class BasicTreeUI { if (row != 0) { - Icon icon = getCurrentControlIcon(path); - int iconW = icon.getIconWidth(); paintHorizontalLine(g, tree, bounds.y + bounds.height / 2, - bounds.x - iconW/2 - gap, bounds.x - gap); + bounds.x - leftChildIndent - gap, bounds.x - gap); } } @@ -3379,15 +3679,13 @@ public class BasicTreeUI paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf); - TreeCellRenderer dtcr = tree.getCellRenderer(); - if (dtcr == null) - dtcr = createDefaultCellRenderer(); + TreeCellRenderer dtcr = currentCellRenderer; boolean focused = false; - if (treeSelectionModel!= null) - focused = treeSelectionModel.getLeadSelectionRow() == row - && tree.isFocusOwner(); - + if (treeSelectionModel != null) + focused = treeSelectionModel.getLeadSelectionRow() == row + && tree.isFocusOwner(); + Component c = dtcr.getTreeCellRendererComponent(tree, node, selected, isExpanded, isLeaf, row, focused); @@ -3400,7 +3698,7 @@ public class BasicTreeUI */ protected void prepareForUIUninstall() { - // TODO: Implement this properly. + // Nothing to do here yet. } /** @@ -3440,4 +3738,14 @@ public class BasicTreeUI editingComponent = null; tree.requestFocus(); } + + /** + * Returns the amount to indent the given row + * + * @return amount to indent the given row. + */ + protected int getRowX(int row, int depth) + { + return depth * totalChildIndent; + } } // BasicTreeUI diff --git a/libjava/classpath/javax/swing/plaf/basic/SharedUIDefaults.java b/libjava/classpath/javax/swing/plaf/basic/SharedUIDefaults.java new file mode 100644 index 00000000000..47876491160 --- /dev/null +++ b/libjava/classpath/javax/swing/plaf/basic/SharedUIDefaults.java @@ -0,0 +1,78 @@ +/* SharedUIDefaults.java -- Manages shared instances for UIDefaults + 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.util.HashMap; + +import javax.swing.UIManager; + +/** + * Manages shared instances for UI defaults. For example, all Swing components + * of one type usually share one InputMap/ActionMap pair. In order to avoid + * duplication of such objects we store them in a Map here. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class SharedUIDefaults +{ + + /** + * Stores the shared instances, indexed by their UI names + * (i.e. "TextField.InputMap"). + */ + private static HashMap sharedDefaults = new HashMap(); + + /** + * Returns a shared UI defaults object. + * + * @param key the key for the shared object + * + * @return a shared UI defaults object for the specified key + */ + static Object get(String key) + { + Object o = sharedDefaults.get(key); + if (o == null) + { + o = UIManager.get(key); + sharedDefaults.put(key, o); + } + return o; + } +} |