summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/plaf/basic
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-09 19:58:05 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-09 19:58:05 +0000
commit65bf3316cf384588453604be6b4f0ed3751a8b0f (patch)
tree996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/classpath/javax/swing/plaf/basic
parent8fc56618a84446beccd45b80381cdfe0e94050df (diff)
downloadppe42-gcc-65bf3316cf384588453604be6b4f0ed3751a8b0f.tar.gz
ppe42-gcc-65bf3316cf384588453604be6b4f0ed3751a8b0f.zip
Merged gcj-eclipse branch to trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120621 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic')
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicButtonListener.java136
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java330
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java6
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java10
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java55
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicHTML.java26
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java10
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java64
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java57
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicListUI.java2
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java24
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java144
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java207
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java160
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java79
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java237
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java566
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java412
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java372
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java417
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java8
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java9
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java538
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java6
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicToolTipUI.java123
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java529
26 files changed, 2734 insertions, 1793 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicButtonListener.java b/libjava/classpath/javax/swing/plaf/basic/BasicButtonListener.java
index 84895821518..c99de2c708c 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicButtonListener.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicButtonListener.java
@@ -54,15 +54,79 @@ import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
+import javax.swing.Action;
+import javax.swing.ActionMap;
import javax.swing.ButtonModel;
+import javax.swing.InputMap;
import javax.swing.JComponent;
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.ButtonUI;
-public class BasicButtonListener implements MouseListener, MouseMotionListener,
- FocusListener, ChangeListener, PropertyChangeListener
+public class BasicButtonListener
+ implements MouseListener, MouseMotionListener, FocusListener, ChangeListener,
+ PropertyChangeListener
{
+ /**
+ * Implements the keyboard action for Swing buttons.
+ */
+ private class ButtonAction
+ extends AbstractAction
+ {
+ /**
+ * The key for pressed action.
+ */
+ static final String PRESSED = "pressed";
+
+ /**
+ * The key for released action.
+ */
+ static final String RELEASED = "released";
+
+ /**
+ * Performs the action.
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ Object cmd = getValue("__command__");
+ AbstractButton b = (AbstractButton) event.getSource();
+ ButtonModel m = b.getModel();
+ if (PRESSED.equals(cmd))
+ {
+ m.setArmed(true);
+ m.setPressed(true);
+ if (! b.isFocusOwner())
+ b.requestFocus();
+ }
+ else if (RELEASED.equals(cmd))
+ {
+ m.setPressed(false);
+ m.setArmed(false);
+ }
+ }
+
+ /**
+ * Indicates if this action is enabled.
+ *
+ * @param source the source of the action
+ *
+ * @return <code>true</code> when enabled, <code>false</code> otherwise
+ */
+ public boolean isEnabled(Object source)
+ {
+ boolean enabled = true;
+ if (source instanceof AbstractButton)
+ {
+ AbstractButton b = (AbstractButton) source;
+ enabled = b.isEnabled();
+ }
+ return enabled;
+ }
+ }
+
public BasicButtonListener(AbstractButton b)
{
// Do nothing here.
@@ -73,12 +137,12 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener,
// Store the TextLayout for this in a client property for speed-up
// painting of the label.
String property = e.getPropertyName();
+ AbstractButton b = (AbstractButton) e.getSource();
if ((property.equals(AbstractButton.TEXT_CHANGED_PROPERTY)
|| property.equals("font"))
&& SystemProperties.getProperty("gnu.javax.swing.noGraphics2D")
== null)
{
- AbstractButton b = (AbstractButton) e.getSource();
String text = b.getText();
if (text == null)
text = "";
@@ -86,12 +150,25 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener,
false, false);
TextLayout layout = new TextLayout(text, b.getFont(), frc);
b.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, layout);
+
+ // Update HTML renderer.
+ BasicHTML.updateRenderer(b, b.getText());
+ }
+ else if (property.equals(AbstractButton.CONTENT_AREA_FILLED_CHANGED_PROPERTY))
+ {
+ checkOpacity(b);
}
}
-
+
+ /**
+ * Checks the <code>contentAreaFilled</code> property and updates the
+ * opaque property of the button.
+ *
+ * @param b the button to check
+ */
protected void checkOpacity(AbstractButton b)
{
- // TODO: What should be done here?
+ b.setOpaque(b.isContentAreaFilled());
}
public void focusGained(FocusEvent e)
@@ -116,6 +193,26 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener,
public void installKeyboardActions(JComponent c)
{
+ ButtonUI ui = ((AbstractButton) c).getUI();
+ if (ui instanceof BasicButtonUI)
+ {
+ // Install InputMap.
+ BasicButtonUI basicUI = (BasicButtonUI) ui;
+ String prefix = basicUI.getPropertyPrefix();
+ InputMap focusInputMap =
+ (InputMap) UIManager.get(prefix + "focusInputMap");
+ SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED,
+ focusInputMap);
+
+ ActionMap am = (ActionMap) UIManager.get(prefix + "actionMap");
+ if (am == null)
+ {
+ am = createDefaultActionMap();
+ UIManager.put(prefix + "actionMap", am);
+ }
+ SwingUtilities.replaceUIActionMap(c, am);
+ }
+
c.getActionMap().put("pressed",
new AbstractAction()
{
@@ -142,31 +239,46 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener,
}
});
}
-
+
+ /**
+ * Creates and returns the default action map for Swing buttons.
+ *
+ * @return the default action map for Swing buttons
+ */
+ private ActionMap createDefaultActionMap()
+ {
+ Action action = new ButtonAction();
+ ActionMapUIResource am = new ActionMapUIResource();
+ am.put(ButtonAction.PRESSED, action);
+ am.put(ButtonAction.RELEASED, action);
+ return am;
+ }
+
public void uninstallKeyboardActions(JComponent c)
{
- c.getActionMap().put("pressed", null);
- c.getActionMap().put("released", null);
+ SwingUtilities.replaceUIActionMap(c, null);
+ SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, null);
}
public void stateChanged(ChangeEvent e)
{
- // TODO: What should be done here, if anything?
+ // Need to repaint when the button state changes.
+ ((AbstractButton) e.getSource()).repaint();
}
public void mouseMoved(MouseEvent e)
{
- // TODO: What should be done here, if anything?
+ // Nothing to do here.
}
public void mouseDragged(MouseEvent e)
{
- // TODO: What should be done here, if anything?
+ // Nothing to do here.
}
public void mouseClicked(MouseEvent e)
{
- // TODO: What should be done here, if anything?
+ // Nothing to do here.
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java
index d531133ba26..9f685bb7bfd 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicButtonUI.java
@@ -42,12 +42,14 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Insets;
import java.awt.Rectangle;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
-import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
@@ -56,6 +58,7 @@ import javax.swing.UIManager;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
+import javax.swing.text.View;
/**
* A UI delegate for the {@link JButton} component.
@@ -63,6 +66,39 @@ import javax.swing.plaf.UIResource;
public class BasicButtonUI extends ButtonUI
{
/**
+ * Cached rectangle for layouting the label. Used in paint() and
+ * BasicGraphicsUtils.getPreferredButtonSize().
+ */
+ static Rectangle viewR = new Rectangle();
+
+ /**
+ * Cached rectangle for layouting the label. Used in paint() and
+ * BasicGraphicsUtils.getPreferredButtonSize().
+ */
+ static Rectangle iconR = new Rectangle();
+
+ /**
+ * Cached rectangle for layouting the label. Used in paint() and
+ * BasicGraphicsUtils.getPreferredButtonSize().
+ */
+ static Rectangle textR = new Rectangle();
+
+ /**
+ * Cached Insets instance, used in paint().
+ */
+ static Insets cachedInsets;
+
+ /**
+ * The shared button UI.
+ */
+ private static BasicButtonUI sharedUI;
+
+ /**
+ * The shared BasicButtonListener.
+ */
+ private static BasicButtonListener sharedListener;
+
+ /**
* A constant used to pad out elements in the button's layout and
* preferred size calculations.
*/
@@ -86,7 +122,9 @@ public class BasicButtonUI extends ButtonUI
*/
public static ComponentUI createUI(final JComponent c)
{
- return new BasicButtonUI();
+ if (sharedUI == null)
+ sharedUI = new BasicButtonUI();
+ return sharedUI;
}
/**
@@ -153,14 +191,29 @@ public class BasicButtonUI extends ButtonUI
protected void installDefaults(AbstractButton b)
{
String prefix = getPropertyPrefix();
+ // Install colors and font.
LookAndFeel.installColorsAndFont(b, prefix + "background",
prefix + "foreground", prefix + "font");
+ // Install border.
LookAndFeel.installBorder(b, prefix + "border");
+
+ // Install margin property.
if (b.getMargin() == null || b.getMargin() instanceof UIResource)
b.setMargin(UIManager.getInsets(prefix + "margin"));
- b.setIconTextGap(UIManager.getInt(prefix + "textIconGap"));
- b.setInputMap(JComponent.WHEN_FOCUSED,
- (InputMap) UIManager.get(prefix + "focusInputMap"));
+
+ // Install rollover property.
+ Object rollover = UIManager.get(prefix + "rollover");
+ if (rollover != null)
+ LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
+
+ // Fetch default textShiftOffset.
+ defaultTextShiftOffset = UIManager.getInt(prefix + "textShiftOffset");
+
+ // Make button opaque if needed.
+ if (b.isContentAreaFilled())
+ LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
+ else
+ LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
}
/**
@@ -170,21 +223,10 @@ public class BasicButtonUI extends ButtonUI
*/
protected void uninstallDefaults(AbstractButton b)
{
- if (b.getFont() instanceof UIResource)
- b.setFont(null);
- if (b.getForeground() instanceof UIResource)
- b.setForeground(null);
- if (b.getBackground() instanceof UIResource)
- b.setBackground(null);
- if (b.getBorder() instanceof UIResource)
- b.setBorder(null);
- b.setIconTextGap(defaultTextIconGap);
- if (b.getMargin() instanceof UIResource)
- b.setMargin(null);
+ // The other properties aren't uninstallable.
+ LookAndFeel.uninstallBorder(b);
}
- protected BasicButtonListener listener;
-
/**
* Creates and returns a new instance of {@link BasicButtonListener}. This
* method provides a hook to make it easy for subclasses to install a
@@ -196,7 +238,13 @@ public class BasicButtonUI extends ButtonUI
*/
protected BasicButtonListener createButtonListener(AbstractButton b)
{
- return new BasicButtonListener(b);
+ // Note: The RI always returns a new instance here. However,
+ // the BasicButtonListener class is perfectly suitable to be shared
+ // between multiple buttons, so we return a shared instance here
+ // for efficiency.
+ if (sharedListener == null)
+ sharedListener = new BasicButtonListener(b);
+ return sharedListener;
}
/**
@@ -206,12 +254,19 @@ public class BasicButtonUI extends ButtonUI
*/
protected void installListeners(AbstractButton b)
{
- listener = createButtonListener(b);
- b.addChangeListener(listener);
- b.addPropertyChangeListener(listener);
- b.addFocusListener(listener);
- b.addMouseListener(listener);
- b.addMouseMotionListener(listener);
+ BasicButtonListener listener = createButtonListener(b);
+ if (listener != null)
+ {
+ b.addChangeListener(listener);
+ b.addPropertyChangeListener(listener);
+ b.addFocusListener(listener);
+ b.addMouseListener(listener);
+ b.addMouseMotionListener(listener);
+ }
+ // Fire synthetic property change event to let the listener update
+ // the TextLayout cache.
+ listener.propertyChange(new PropertyChangeEvent(b, "font", null,
+ b.getFont()));
}
/**
@@ -221,21 +276,29 @@ public class BasicButtonUI extends ButtonUI
*/
protected void uninstallListeners(AbstractButton b)
{
- b.removeChangeListener(listener);
- b.removePropertyChangeListener(listener);
- b.removeFocusListener(listener);
- b.removeMouseListener(listener);
- b.removeMouseMotionListener(listener);
+ BasicButtonListener listener = getButtonListener(b);
+ if (listener != null)
+ {
+ b.removeChangeListener(listener);
+ b.removePropertyChangeListener(listener);
+ b.removeFocusListener(listener);
+ b.removeMouseListener(listener);
+ b.removeMouseMotionListener(listener);
+ }
}
protected void installKeyboardActions(AbstractButton b)
{
- listener.installKeyboardActions(b);
+ BasicButtonListener listener = getButtonListener(b);
+ if (listener != null)
+ listener.installKeyboardActions(b);
}
protected void uninstallKeyboardActions(AbstractButton b)
{
- listener.uninstallKeyboardActions(b);
+ BasicButtonListener listener = getButtonListener(b);
+ if (listener != null)
+ listener.uninstallKeyboardActions(b);
}
/**
@@ -253,9 +316,75 @@ public class BasicButtonUI extends ButtonUI
{
AbstractButton b = (AbstractButton) c;
installDefaults(b);
+ // It is important to install the listeners before installing
+ // the keyboard actions, because the keyboard actions
+ // are actually installed on the listener instance.
installListeners(b);
installKeyboardActions(b);
+ BasicHTML.updateRenderer(b, b.getText());
+ }
+ }
+
+ /**
+ * Uninstalls the UI from the component.
+ *
+ * @param c the component from which to uninstall the UI
+ */
+ public void uninstallUI(JComponent c)
+ {
+ if (c instanceof AbstractButton)
+ {
+ AbstractButton b = (AbstractButton) c;
+ uninstallKeyboardActions(b);
+ uninstallListeners(b);
+ uninstallDefaults(b);
+ BasicHTML.updateRenderer(b, "");
+ b.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, null);
+ }
+ }
+
+ /**
+ * Calculates the minimum size for the specified component.
+ *
+ * @param c the component for which to compute the minimum size
+ *
+ * @return the minimum size for the specified component
+ */
+ public Dimension getMinimumSize(JComponent c)
+ {
+ Dimension size = getPreferredSize(c);
+ // When the HTML view has a minimum width different from the preferred
+ // width, then substract this here accordingly. The height is not
+ // affected by that.
+ View html = (View) c.getClientProperty(BasicHTML.propertyKey);
+ if (html != null)
+ {
+ size.width -= html.getPreferredSpan(View.X_AXIS)
+ - html.getPreferredSpan(View.X_AXIS);
}
+ return size;
+ }
+
+ /**
+ * Calculates the maximum size for the specified component.
+ *
+ * @param c the component for which to compute the maximum size
+ *
+ * @return the maximum size for the specified component
+ */
+ public Dimension getMaximumSize(JComponent c)
+ {
+ Dimension size = getPreferredSize(c);
+ // When the HTML view has a maximum width different from the preferred
+ // width, then add this here accordingly. The height is not
+ // affected by that.
+ View html = (View) c.getClientProperty(BasicHTML.propertyKey);
+ if (html != null)
+ {
+ size.width += html.getMaximumSpan(View.X_AXIS)
+ - html.getPreferredSpan(View.X_AXIS);
+ }
+ return size;
}
/**
@@ -269,8 +398,8 @@ public class BasicButtonUI extends ButtonUI
public Dimension getPreferredSize(JComponent c)
{
AbstractButton b = (AbstractButton) c;
- Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b,
- defaultTextIconGap + defaultTextShiftOffset);
+ Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b,
+ b.getIconTextGap());
return d;
}
@@ -315,38 +444,50 @@ public class BasicButtonUI extends ButtonUI
{
AbstractButton b = (AbstractButton) c;
- Rectangle tr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle vr = new Rectangle();
+ Insets i = c.getInsets(cachedInsets);
+ viewR.x = i.left;
+ viewR.y = i.top;
+ viewR.width = c.getWidth() - i.left - i.right;
+ viewR.height = c.getHeight() - i.top - i.bottom;
+ textR.x = 0;
+ textR.y = 0;
+ textR.width = 0;
+ textR.height = 0;
+ iconR.x = 0;
+ iconR.y = 0;
+ iconR.width = 0;
+ iconR.height = 0;
Font f = c.getFont();
-
g.setFont(f);
+ Icon icon = b.getIcon();
+ String text = b.getText();
+ text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f),
+ text, icon,
+ b.getVerticalAlignment(),
+ b.getHorizontalAlignment(),
+ b.getVerticalTextPosition(),
+ b.getHorizontalTextPosition(),
+ viewR, iconR, textR,
+ text == null ? 0
+ : b.getIconTextGap());
- if (b.isBorderPainted())
- SwingUtilities.calculateInnerArea(b, vr);
- 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);
-
- if ((b.getModel().isArmed() && b.getModel().isPressed())
- || b.isSelected())
+ ButtonModel model = b.getModel();
+ if (model.isArmed() && model.isPressed())
paintButtonPressed(g, b);
-
- paintIcon(g, c, ir);
+
+ if (icon != null)
+ paintIcon(g, c, iconR);
if (text != null)
- paintText(g, b, tr, text);
+ {
+ View html = (View) b.getClientProperty(BasicHTML.propertyKey);
+ if (html != null)
+ html.paint(g, textR);
+ else
+ paintText(g, b, textR, text);
+ }
if (b.isFocusOwner() && b.isFocusPainted())
- paintFocus(g, b, vr, tr, ir);
+ paintFocus(g, b, viewR, textR, iconR);
}
/**
@@ -386,7 +527,16 @@ public class BasicButtonUI extends ButtonUI
Icon i = currentIcon(b);
if (i != null)
- i.paintIcon(c, g, iconRect.x, iconRect.y);
+ {
+ ButtonModel m = b.getModel();
+ if (m.isPressed() && m.isArmed())
+ {
+ int offs = getTextShiftOffset();
+ i.paintIcon(c, g, iconRect.x + offs, iconRect.y + offs);
+ }
+ else
+ i.paintIcon(c, g, iconRect.x, iconRect.y);
+ }
}
/**
@@ -419,22 +569,7 @@ public class BasicButtonUI extends ButtonUI
protected void paintText(Graphics g, JComponent c, Rectangle textRect,
String text)
{
- paintText(g, (AbstractButton) c, textRect, text);
- }
-
- /**
- * Paints the "text" property of an {@link AbstractButton}.
- *
- * @param g The graphics context to paint with
- * @param b The button to paint the state of
- * @param textRect The area in which to paint the text
- * @param text The text to paint
- *
- * @since 1.4
- */
- protected void paintText(Graphics g, AbstractButton b, Rectangle textRect,
- String text)
- {
+ AbstractButton b = (AbstractButton) c;
Font f = b.getFont();
g.setFont(f);
FontMetrics fm = g.getFontMetrics(f);
@@ -454,5 +589,48 @@ public class BasicButtonUI extends ButtonUI
BasicGraphicsUtils.drawString(b, g, text, -1, textRect.x,
textRect.y + fm.getAscent());
}
+ }
+
+ /**
+ * Paints the "text" property of an {@link AbstractButton}.
+ *
+ * @param g The graphics context to paint with
+ * @param b The button to paint the state of
+ * @param textRect The area in which to paint the text
+ * @param text The text to paint
+ *
+ * @since 1.4
+ */
+ protected void paintText(Graphics g, AbstractButton b, Rectangle textRect,
+ String text)
+ {
+ paintText(g, (JComponent) b, textRect, text);
}
+
+ /**
+ * A helper method that finds the BasicButtonListener for the specified
+ * button. This is there because this UI class is stateless and
+ * shared for all buttons, and thus can't store the listener
+ * as instance field. (We store our shared instance in sharedListener,
+ * however, subclasses may override createButtonListener() and we would
+ * be lost in this case).
+ *
+ * @param b the button
+ *
+ * @return the UI event listener
+ */
+ private BasicButtonListener getButtonListener(AbstractButton b)
+ {
+ // The listener gets installed as PropertyChangeListener,
+ // so look for it in the list of property change listeners.
+ PropertyChangeListener[] listeners = b.getPropertyChangeListeners();
+ BasicButtonListener l = null;
+ for (int i = 0; listeners != null && l == null && i < listeners.length;
+ i++)
+ {
+ if (listeners[i] instanceof BasicButtonListener)
+ l = (BasicButtonListener) listeners[i];
+ }
+ return l;
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java b/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java
index ed916cb5f1a..de82bd47bb6 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicDirectoryModel.java
@@ -381,7 +381,7 @@ public class BasicDirectoryModel extends AbstractListModel
*
* @return a Vector
*/
- public Vector getDirectories()
+ public Vector<File> getDirectories()
{
// Synchronize this with the UpdateSwingRequest for the case when
// contents is modified.
@@ -418,7 +418,7 @@ public class BasicDirectoryModel extends AbstractListModel
*
* @return a Vector
*/
- public Vector getFiles()
+ public Vector<File> getFiles()
{
synchronized (contents)
{
@@ -562,7 +562,7 @@ public class BasicDirectoryModel extends AbstractListModel
*
* @param v The Vector to sort.
*/
- protected void sort(Vector v)
+ protected void sort(Vector<? extends File> v)
{
Collections.sort(v, comparator);
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java
index dc1c051225c..e1f8e4b28ba 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java
@@ -183,7 +183,7 @@ public class BasicFileChooserUI extends FileChooserUI
protected class BasicFileView extends FileView
{
/** Storage for cached icons. */
- protected Hashtable iconCache = new Hashtable();
+ protected Hashtable<File, Icon> iconCache = new Hashtable<File, Icon>();
/**
* Creates a new instance.
@@ -444,10 +444,10 @@ public class BasicFileChooserUI extends FileChooserUI
setDirectory(null);
}
lastSelected = path;
- parentPath = path.substring(0, path.lastIndexOf("/") + 1);
+ parentPath = f.getParent();
if (f.isFile())
- setFileName(path.substring(path.lastIndexOf("/") + 1));
+ setFileName(f.getName());
else if (filechooser.getFileSelectionMode() !=
JFileChooser.FILES_ONLY)
setFileName(path);
@@ -827,9 +827,9 @@ public class BasicFileChooserUI extends FileChooserUI
installComponents(fc);
installListeners(fc);
- Object path = filechooser.getCurrentDirectory();
+ File path = filechooser.getCurrentDirectory();
if (path != null)
- parentPath = path.toString().substring(path.toString().lastIndexOf("/"));
+ parentPath = path.getParent();
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java b/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java
index 1e84be93282..4c270682d88 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicGraphicsUtils.java
@@ -748,7 +748,6 @@ public class BasicGraphicsUtils
}
}
-
/**
* Determines the preferred width and height of an AbstractButton,
* given the gap between the button&#x2019;s text and icon.
@@ -769,24 +768,31 @@ public class BasicGraphicsUtils
public static Dimension getPreferredButtonSize(AbstractButton b,
int textIconGap)
{
- Rectangle contentRect;
- Rectangle viewRect;
- Rectangle iconRect = new Rectangle();
- Rectangle textRect = new Rectangle();
- Insets insets = b.getInsets();
-
- viewRect = new Rectangle();
-
- /* java.awt.Toolkit.getFontMetrics is deprecated. However, it
- * seems not obvious how to get to the correct FontMetrics object
- * otherwise. The real problem probably is that the method
- * javax.swing.SwingUtilities.layoutCompundLabel should take a
- * LineMetrics, not a FontMetrics argument. But fixing this that
- * would change the public API.
- */
+ // These cached rectangles are use here and in BasicButtonUI.paint(),
+ // so these two methods must never be executed concurrently. Maybe
+ // we must use other Rectangle instances here. OTOH, Swing is
+ // designed to be not thread safe, and every layout and paint operation
+ // should be performed from the EventDispatchThread, so it _should_ be
+ // OK to do this optimization.
+ Rectangle viewRect = BasicButtonUI.viewR;
+ viewRect.x = 0;
+ viewRect.y = 0;
+ viewRect.width = Short.MAX_VALUE;
+ viewRect.height = Short.MAX_VALUE;
+ Rectangle iconRect = BasicButtonUI.iconR;
+ iconRect.x = 0;
+ iconRect.y = 0;
+ iconRect.width = 0;
+ iconRect.height = 0;
+ Rectangle textRect = BasicButtonUI.textR;
+ textRect.x = 0;
+ textRect.y = 0;
+ textRect.width = 0;
+ textRect.height = 0;
+
SwingUtilities.layoutCompoundLabel(
b, // for the component orientation
- b.getToolkit().getFontMetrics(b.getFont()), // see comment above
+ b.getFontMetrics(b.getFont()), // see comment above
b.getText(),
b.getIcon(),
b.getVerticalAlignment(),
@@ -804,13 +810,12 @@ public class BasicGraphicsUtils
* +------------------------+ +------------------------+
*/
- contentRect = textRect.union(iconRect);
-
- return new Dimension(insets.left
- + contentRect.width
- + insets.right + b.getHorizontalAlignment(),
- insets.top
- + contentRect.height
- + insets.bottom);
+ Rectangle contentRect =
+ SwingUtilities.computeUnion(textRect.x, textRect.y, textRect.width,
+ textRect.height, iconRect);
+
+ Insets insets = b.getInsets();
+ return new Dimension(insets.left + contentRect.width + insets.right,
+ insets.top + contentRect.height + insets.bottom);
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java
index 98c9cb277f4..6e26d5355a2 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java
@@ -48,6 +48,7 @@ import java.io.StringReader;
import javax.swing.JComponent;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
+import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
@@ -107,6 +108,7 @@ public class BasicHTML
editorKit = kit;
document = doc;
setView(view);
+ setSize(view.getPreferredSpan(X_AXIS), view.getPreferredSpan(Y_AXIS));
}
/**
@@ -151,6 +153,14 @@ public class BasicHTML
}
/**
+ * Overridden to forward to real view.
+ */
+ public void setSize(float w, float h)
+ {
+ view.setSize(w, h);
+ }
+
+ /**
* Returns the real root view, regardless of the index.
*
* @param index not used here
@@ -346,6 +356,22 @@ public class BasicHTML
{
return document;
}
+
+ /**
+ * Overridden to return null, as a RootView has no attributes on its own.
+ */
+ public AttributeSet getAttributes()
+ {
+ return null;
+ }
+
+ /**
+ * Overridden to provide an element for the view.
+ */
+ public Element getElement()
+ {
+ return view.getElement();
+ }
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
index 11980f6ca2e..ea8b4603691 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
@@ -177,9 +177,15 @@ public class BasicInternalFrameTitlePane extends JComponent
try
{
if (frame.isMaximizable() && ! frame.isMaximum())
- frame.setMaximum(true);
+ {
+ frame.setMaximum(true);
+ maxButton.setIcon(minIcon);
+ }
else if (frame.isMaximum())
- frame.setMaximum(false);
+ {
+ frame.setMaximum(false);
+ maxButton.setIcon(maxIcon);
+ }
}
catch (PropertyVetoException pve)
{
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
index 8f2181336cb..87c5268c8c7 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -459,18 +459,12 @@ public class BasicInternalFrameUI extends InternalFrameUI
{
if (frame.isMaximum())
{
- JDesktopPane pane = (JDesktopPane) e.getSource();
- Insets insets = pane.getInsets();
- Rectangle bounds = pane.getBounds();
-
- frame.setBounds(bounds.x + insets.left, bounds.y + insets.top,
- bounds.width - insets.left - insets.right,
- bounds.height - insets.top - insets.bottom);
- frame.revalidate();
- frame.repaint();
+ Container parent = frame.getParent();
+ Insets i = parent.getInsets();
+ int width = parent.getWidth() - i.left - i.right;
+ int height = parent.getHeight() - i.top - i.bottom;
+ frame.setBounds(0, 0, width, height);
}
-
- // Sun also resizes the icons. but it doesn't seem to do anything.
}
/**
@@ -949,17 +943,25 @@ public class BasicInternalFrameUI extends InternalFrameUI
{
if (evt.getNewValue() == Boolean.TRUE)
{
+ Container parent = frame.getParent();
+ if (parent != null)
+ parent.removeComponentListener(componentListener);
closeFrame(frame);
}
}
- /*
- * FIXME: need to add ancestor properties to JComponents. else if
- * (evt.getPropertyName().equals(JComponent.ANCESTOR_PROPERTY)) { if
- * (desktopPane != null)
- * desktopPane.removeComponentListener(componentListener); desktopPane =
- * frame.getDesktopPane(); if (desktopPane != null)
- * desktopPane.addComponentListener(componentListener); }
- */
+ else if (property.equals("ancestor"))
+ {
+ Container newParent = (Container) evt.getNewValue();
+ Container oldParent = (Container) evt.getOldValue();
+ if (newParent != null)
+ {
+ newParent.addComponentListener(componentListener);
+ }
+ else if (oldParent != null)
+ {
+ oldParent.removeComponentListener(componentListener);
+ }
+ }
}
}
@@ -1258,6 +1260,12 @@ public class BasicInternalFrameUI extends InternalFrameUI
frame.addPropertyChangeListener(propertyChangeListener);
frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
+
+ Container parent = frame.getParent();
+ if (parent != null)
+ {
+ parent.addComponentListener(componentListener);
+ }
}
/**
@@ -1286,8 +1294,13 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
protected void uninstallListeners()
{
- if (desktopPane != null)
- desktopPane.removeComponentListener(componentListener);
+
+ Container parent = frame.getParent();
+ if (parent != null)
+ {
+ parent.removeComponentListener(componentListener);
+ }
+ componentListener = null;
frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher);
@@ -1298,7 +1311,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
frame.removeMouseListener(borderListener);
propertyChangeListener = null;
- componentListener = null;
+
borderListener = null;
internalFrameListener = null;
glassPaneDispatcher = null;
@@ -1581,6 +1594,13 @@ public class BasicInternalFrameUI extends InternalFrameUI
{
replacePane(northPane, c);
northPane = c;
+ // the following is needed to make internal frames draggable when using
+ // the JGoodies PlasticLookAndFeel, because it overrides the
+ // createNorthPane() method and doesn't assign anything to the titlePane
+ // field. It is possible there is another way to make this work, but
+ // I didn't find it...
+ if (c instanceof BasicInternalFrameTitlePane)
+ titlePane = (BasicInternalFrameTitlePane) c;
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
index 304e13ad735..1ec020b1c0b 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
@@ -119,13 +119,37 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
{
JLabel lab = (JLabel) c;
Insets insets = lab.getInsets();
- FontMetrics fm = lab.getFontMetrics(lab.getFont());
- layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr);
- Rectangle cr = SwingUtilities.computeUnion(tr.x, tr.y, tr.width, tr.height,
- ir);
- return new Dimension(insets.left + cr.width + insets.right, insets.top
- + cr.height + insets.bottom);
-
+ int insetsX = insets.left + insets.right;
+ int insetsY = insets.top + insets.bottom;
+ Icon icon = lab.getIcon();
+ String text = lab.getText();
+ Dimension ret;
+ if (icon == null && text == null)
+ ret = new Dimension(insetsX, insetsY);
+ else if (icon != null && text == null)
+ ret = new Dimension(icon.getIconWidth() + insetsX,
+ icon.getIconHeight() + insetsY);
+ else
+ {
+ FontMetrics fm = lab.getFontMetrics(lab.getFont());
+ ir.x = 0;
+ ir.y = 0;
+ ir.width = 0;
+ ir.height = 0;
+ tr.x = 0;
+ tr.y = 0;
+ tr.width = 0;
+ tr.height = 0;
+ vr.x = 0;
+ vr.y = 0;
+ vr.width = Short.MAX_VALUE;
+ vr.height = Short.MAX_VALUE;
+ layoutCL(lab, fm, text, icon, vr, ir, tr);
+ Rectangle cr = SwingUtilities.computeUnion(tr.x, tr.y, tr.width,
+ tr.height, ir);
+ ret = new Dimension(cr.width + insetsX, cr.height + insetsY);
+ }
+ return ret;
}
/**
@@ -166,13 +190,20 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
{
JLabel b = (JLabel) c;
FontMetrics fm = g.getFontMetrics();
- vr = SwingUtilities.calculateInnerArea(c, vr);
-
- if (vr.width < 0)
- vr.width = 0;
- if (vr.height < 0)
- vr.height = 0;
+ Insets i = c.getInsets();
+ vr.x = i.left;
+ vr.y = i.right;
+ vr.width = c.getWidth() - i.left + i.right;
+ vr.height = c.getHeight() - i.top + i.bottom;
+ ir.x = 0;
+ ir.y = 0;
+ ir.width = 0;
+ ir.height = 0;
+ tr.x = 0;
+ tr.y = 0;
+ tr.width = 0;
+ tr.height = 0;
Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon();
String text = layoutCL(b, fm, b.getText(), icon, vr, ir, tr);
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
index 493fc0578e3..befc227364a 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
@@ -921,7 +921,7 @@ public class BasicListUI extends ListUI
*/
protected void maybeUpdateLayoutState()
{
- if (updateLayoutStateNeeded != 0)
+ if (updateLayoutStateNeeded != 0 || !list.isValid())
{
updateLayoutState();
updateLayoutStateNeeded = 0;
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
index c056a2403f9..15430945468 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
@@ -1062,8 +1062,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"ProgressBar.repaintInterval", new Integer(50),
"ProgressBar.cycleTime", new Integer(3000),
"RadioButton.background", new ColorUIResource(light),
- "RadioButton.border", new BorderUIResource.CompoundBorderUIResource(null,
- null),
+ "RadioButton.border", BasicBorders.getRadioButtonBorder(),
"RadioButton.darkShadow", new ColorUIResource(shadow),
"RadioButton.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
KeyStroke.getKeyStroke("SPACE"), "pressed",
@@ -1183,6 +1182,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"Slider.thumbHeight", new Integer(20),
"Slider.thumbWidth", new Integer(11),
"Slider.tickHeight", new Integer(12),
+ "Slider.horizontalSize", new Dimension(200, 21),
+ "Slider.verticalSize", new Dimension(21, 200),
+ "Slider.minimumHorizontalSize", new Dimension(36, 21),
+ "Slider.minimumVerticalSize", new Dimension(21, 36),
"Spinner.background", new ColorUIResource(light),
"Spinner.foreground", new ColorUIResource(light),
"Spinner.arrowButtonSize", new DimensionUIResource(16, 5),
@@ -1218,10 +1221,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"ctrl UP", "requestFocus",
"ctrl KP_UP", "requestFocus"
}),
- "TabbedPane.background", new ColorUIResource(light),
+ "TabbedPane.background", new ColorUIResource(192, 192, 192),
"TabbedPane.contentBorderInsets", new InsetsUIResource(2, 2, 3, 3),
- "TabbedPane.darkShadow", new ColorUIResource(shadow),
- "TabbedPane.focus", new ColorUIResource(darkShadow),
+ "TabbedPane.darkShadow", new ColorUIResource(Color.black),
+ "TabbedPane.focus", new ColorUIResource(Color.black),
"TabbedPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
KeyStroke.getKeyStroke("ctrl DOWN"), "requestFocusForVisibleComponent",
KeyStroke.getKeyStroke("KP_UP"), "navigateUp",
@@ -1235,17 +1238,16 @@ public abstract class BasicLookAndFeel extends LookAndFeel
KeyStroke.getKeyStroke("DOWN"), "navigateDown"
}),
"TabbedPane.font", new FontUIResource("Dialog", Font.PLAIN, 12),
- "TabbedPane.foreground", new ColorUIResource(darkShadow),
- "TabbedPane.highlight", new ColorUIResource(highLight),
- "TabbedPane.light", new ColorUIResource(highLight),
+ "TabbedPane.foreground", new ColorUIResource(Color.black),
+ "TabbedPane.highlight", new ColorUIResource(Color.white),
+ "TabbedPane.light", new ColorUIResource(192, 192, 192),
"TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 2, 1),
- "TabbedPane.shadow", new ColorUIResource(shadow),
- "TabbedPane.tabbedPaneContentBorderInsets", new InsetsUIResource(3, 2, 1, 2),
- "TabbedPane.tabbedPaneTabPadInsets", new InsetsUIResource(1, 1, 1, 1),
+ "TabbedPane.shadow", new ColorUIResource(128, 128, 128),
"TabbedPane.tabsOpaque", Boolean.TRUE,
"TabbedPane.tabAreaInsets", new InsetsUIResource(3, 2, 0, 2),
"TabbedPane.tabInsets", new InsetsUIResource(0, 4, 1, 4),
"TabbedPane.tabRunOverlay", new Integer(2),
+ "TabbedPane.tabsOverlapBorder", Boolean.FALSE,
"TabbedPane.textIconGap", new Integer(4),
"Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
"ctrl DOWN", "selectNextRowChangeLead",
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
index bbc08535cdc..5fafb4108b2 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
@@ -180,17 +180,9 @@ public class BasicMenuItemUI extends MenuItemUI
private ItemListener itemListener;
/**
- * Number of spaces between accelerator and menu item's label.
+ * A PropertyChangeListener to make UI updates after property changes.
*/
- private int defaultAcceleratorLabelGap = 10;
-
- /**
- * The gap between different menus on the MenuBar.
- */
- private int MenuGap = 10;
-
- /** A PropertyChangeListener to make UI updates after property changes **/
- PropertyChangeHandler propertyChangeListener;
+ private PropertyChangeHandler propertyChangeListener;
/**
* The view rectangle used for layout of the menu item.
@@ -262,7 +254,6 @@ public class BasicMenuItemUI extends MenuItemUI
|| property.equals("font"))
&& SystemProperties.getProperty("gnu.javax.swing.noGraphics2D")
== null)
-
{
AbstractButton b = (AbstractButton) e.getSource();
String text = b.getText();
@@ -373,7 +364,7 @@ public class BasicMenuItemUI extends MenuItemUI
*/
protected void doClick(MenuSelectionManager msm)
{
- menuItem.doClick();
+ menuItem.doClick(0);
msm.clearSelectedPath();
}
@@ -411,14 +402,10 @@ public class BasicMenuItemUI extends MenuItemUI
{
ArrayList path = new ArrayList();
- // Path to menu should also include its popup menu.
- if (menuItem instanceof JMenu)
- path.add(((JMenu) menuItem).getPopupMenu());
-
Component c = menuItem;
while (c instanceof MenuElement)
{
- path.add(0, (MenuElement) c);
+ path.add(0, c);
if (c instanceof JPopupMenu)
c = ((JPopupMenu) c).getInvoker();
@@ -453,6 +440,7 @@ public class BasicMenuItemUI extends MenuItemUI
// Layout the menu item. The result gets stored in the rectangle
// fields of this class.
+ resetRectangles(null);
layoutMenuItem(m, accelText);
// The union of the text and icon areas is the label area.
@@ -606,6 +594,11 @@ public class BasicMenuItemUI extends MenuItemUI
menuItem.addMenuKeyListener(menuKeyListener);
menuItem.addItemListener(itemListener);
menuItem.addPropertyChangeListener(propertyChangeListener);
+ // Fire synthetic property change event to let the listener update
+ // the TextLayout cache.
+ propertyChangeListener.propertyChange(new PropertyChangeEvent(menuItem,
+ "font", null,
+ menuItem.getFont()));
}
/**
@@ -704,6 +697,8 @@ public class BasicMenuItemUI extends MenuItemUI
// Layout menu item. The result gets stored in the rectangle fields
// of this class.
+ resetRectangles(m);
+
layoutMenuItem(m, accelText);
// Paint the background.
@@ -936,6 +931,7 @@ public class BasicMenuItemUI extends MenuItemUI
uninstallListeners();
uninstallDefaults();
uninstallComponents(menuItem);
+ c.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, null);
menuItem = null;
}
@@ -953,47 +949,6 @@ public class BasicMenuItemUI extends MenuItemUI
}
/**
- * Return text representation of the specified accelerator
- *
- * @param accelerator
- * Accelerator for which to return string representation
- * @return $String$ Text representation of the given accelerator
- */
- private String getAcceleratorText(KeyStroke accelerator)
- {
- // convert keystroke into string format
- String modifiersText = "";
- int modifiers = accelerator.getModifiers();
- char keyChar = accelerator.getKeyChar();
- int keyCode = accelerator.getKeyCode();
-
- if (modifiers != 0)
- modifiersText = KeyEvent.getKeyModifiersText(modifiers)
- + acceleratorDelimiter;
-
- if (keyCode == KeyEvent.VK_UNDEFINED)
- return modifiersText + keyChar;
- else
- return modifiersText + KeyEvent.getKeyText(keyCode);
- }
-
- /**
- * Calculates and return rectange in which accelerator should be displayed
- *
- * @param accelerator
- * accelerator for which to return the display rectangle
- * @param fm
- * The font metrics used to measure the text
- * @return $Rectangle$ reactangle which will be used to display accelerator
- */
- private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm)
- {
- int width = fm.stringWidth(getAcceleratorText(accelerator));
- int height = fm.getHeight();
- return new Rectangle(0, 0, width, height);
- }
-
- /**
* This class handles mouse events occuring inside the menu item. Most of the
* events are forwarded for processing to MenuSelectionManager of the current
* menu hierarchy.
@@ -1103,15 +1058,14 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void mouseReleased(MouseEvent e)
{
- Rectangle size = menuItem.getBounds();
MenuSelectionManager manager = MenuSelectionManager.defaultManager();
- if (e.getX() > 0 && e.getX() < size.width && e.getY() > 0
- && e.getY() < size.height)
+ int x = e.getX();
+ int y = e.getY();
+ if (x > 0 && x < menuItem.getWidth() && y > 0
+ && y < menuItem.getHeight())
{
- manager.clearSelectedPath();
- menuItem.doClick();
+ doClick(manager);
}
-
else
manager.processMouseEvent(e);
}
@@ -1130,7 +1084,7 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void menuDragMouseDragged(MenuDragMouseEvent e)
{
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+ MenuSelectionManager manager = e.getMenuSelectionManager();
manager.setSelectedPath(e.getPath());
}
@@ -1143,7 +1097,7 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void menuDragMouseEntered(MenuDragMouseEvent e)
{
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
+ MenuSelectionManager manager = e.getMenuSelectionManager();
manager.setSelectedPath(e.getPath());
}
@@ -1155,7 +1109,7 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void menuDragMouseExited(MenuDragMouseEvent e)
{
- // TODO: What should be done here, if anything?
+ // Nothing to do here yet.
}
/**
@@ -1167,13 +1121,14 @@ public class BasicMenuItemUI extends MenuItemUI
*/
public void menuDragMouseReleased(MenuDragMouseEvent e)
{
- MenuElement[] path = e.getPath();
-
- if (path[path.length - 1] instanceof JMenuItem)
- ((JMenuItem) path[path.length - 1]).doClick();
-
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
- manager.clearSelectedPath();
+ MenuSelectionManager manager = e.getMenuSelectionManager();
+ int x = e.getX();
+ int y = e.getY();
+ if (x >= 0 && x < menuItem.getWidth() && y >= 0
+ && y < menuItem.getHeight())
+ doClick(manager);
+ else
+ manager.clearSelectedPath();
}
}
@@ -1275,32 +1230,41 @@ public class BasicMenuItemUI extends MenuItemUI
}
/**
- * A helper method that lays out the menu item. The layout is stored
- * in the fields of this class.
+ * Resets the cached layout rectangles. If <code>i</code> is not null, then
+ * the view rectangle is set to the inner area of the component, otherwise
+ * it is set to (0, 0, Short.MAX_VALUE, Short.MAX_VALUE), this is needed
+ * for layouting.
*
- * @param m the menu item to layout
- * @param accelText the accelerator text
+ * @param i the component for which to initialize the rectangles
*/
- private void layoutMenuItem(JMenuItem m, String accelText)
+ private void resetRectangles(JMenuItem i)
{
- int width = m.getWidth();
- int height = m.getHeight();
-
// Reset rectangles.
iconRect.setBounds(0, 0, 0, 0);
textRect.setBounds(0, 0, 0, 0);
accelRect.setBounds(0, 0, 0, 0);
checkIconRect.setBounds(0, 0, 0, 0);
arrowIconRect.setBounds(0, 0, 0, 0);
- viewRect.setBounds(0, 0, width, height);
-
- // Substract insets to the view rect.
- Insets insets = m.getInsets();
- viewRect.x += insets.left;
- viewRect.y += insets.top;
- viewRect.width -= insets.left + insets.right;
- viewRect.height -= insets.top + insets.bottom;
+ if (i == null)
+ viewRect.setBounds(0, 0, Short.MAX_VALUE, Short.MAX_VALUE);
+ else
+ {
+ Insets insets = i.getInsets();
+ viewRect.setBounds(insets.left, insets.top,
+ i.getWidth() - insets.left - insets.right,
+ i.getHeight() - insets.top - insets.bottom);
+ }
+ }
+ /**
+ * A helper method that lays out the menu item. The layout is stored
+ * in the fields of this class.
+ *
+ * @param m the menu item to layout
+ * @param accelText the accelerator text
+ */
+ private void layoutMenuItem(JMenuItem m, String accelText)
+ {
// Fetch the fonts.
Font font = m.getFont();
FontMetrics fm = m.getFontMetrics(font);
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java
index 7d8784fd15a..355e0435ec8 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicMenuUI.java
@@ -41,16 +41,22 @@ package javax.swing.plaf.basic;
import gnu.classpath.NotImplementedException;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;
+import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPopupMenu;
import javax.swing.LookAndFeel;
+import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
+import javax.swing.Timer;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
@@ -69,6 +75,32 @@ import javax.swing.plaf.ComponentUI;
*/
public class BasicMenuUI extends BasicMenuItemUI
{
+ /**
+ * Selects a menu. This is used to delay menu selection.
+ */
+ class SelectMenuAction
+ extends AbstractAction
+ {
+ /**
+ * Performs the action.
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+ JMenu menu = (JMenu) menuItem;
+ MenuSelectionManager defaultManager =
+ MenuSelectionManager.defaultManager();
+ MenuElement path[] = defaultManager.getSelectedPath();
+ if(path.length > 0 && path[path.length - 1] == menu)
+ {
+ MenuElement newPath[] = new MenuElement[path.length + 1];
+ System.arraycopy(path, 0, newPath, 0, path.length);
+ newPath[path.length] = menu.getPopupMenu();
+ defaultManager.setSelectedPath(newPath);
+ }
+ }
+
+ }
+
protected ChangeListener changeListener;
/* MenuListener listens to MenuEvents fired by JMenu */
@@ -201,6 +233,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
protected void installDefaults()
{
+
LookAndFeel.installBorder(menuItem, "Menu.border");
LookAndFeel.installColorsAndFont(menuItem, "Menu.background",
"Menu.foreground", "Menu.font");
@@ -212,6 +245,7 @@ public class BasicMenuUI extends BasicMenuItemUI
selectionForeground = UIManager.getColor("Menu.selectionForeground");
arrowIcon = UIManager.getIcon("Menu.arrowIcon");
oldBorderPainted = UIManager.getBoolean("Menu.borderPainted");
+ ((JMenu) menuItem).setDelay(200);
}
/**
@@ -234,9 +268,10 @@ public class BasicMenuUI extends BasicMenuItemUI
}
protected void setupPostTimer(JMenu menu)
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ Timer timer = new Timer(menu.getDelay(), new SelectMenuAction());
+ timer.setRepeats(false);
+ timer.start();
}
/**
@@ -285,8 +320,7 @@ public class BasicMenuUI extends BasicMenuItemUI
{
public void mouseClicked(MouseEvent e)
{
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
- manager.processMouseEvent(e);
+ // Nothing to do here.
}
public void mouseDragged(MouseEvent e)
@@ -313,29 +347,46 @@ public class BasicMenuUI extends BasicMenuItemUI
public void mouseEntered(MouseEvent e)
{
- /* When mouse enters menu item, it should be considered selected
-
- if (i) if this menu is a submenu in some other menu
- (ii) or if this menu is in a menu bar and some other menu in a
- menu bar was just selected and has its popup menu visible.
- (If nothing was selected, menu should be pressed before
- it will be selected)
- */
JMenu menu = (JMenu) menuItem;
-
- // NOTE: the following if used to require !menu.isArmed but I could find
- // no reason for this and it was preventing some JDK-compatible behaviour.
- // Specifically, if a menu is selected but its popup menu not visible,
- // and then another menu is selected whose popup menu IS visible, when
- // the mouse is moved over the first menu, its popup menu should become
- // visible.
-
- if (! menu.isTopLevelMenu() || popupVisible())
+ if (menu.isEnabled())
{
- // set new selection and forward this event to MenuSelectionManager
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
- manager.setSelectedPath(getPath());
- manager.processMouseEvent(e);
+ MenuSelectionManager manager =
+ MenuSelectionManager.defaultManager();
+ MenuElement[] selectedPath = manager.getSelectedPath();
+ if (! menu.isTopLevelMenu())
+ {
+ // Open the menu immediately or delayed, depending on the
+ // delay value.
+ if(! (selectedPath.length > 0
+ && selectedPath[selectedPath.length - 1] == menu.getPopupMenu()))
+ {
+ if(menu.getDelay() == 0)
+ {
+ MenuElement[] path = getPath();
+ MenuElement[] newPath = new MenuElement[path.length + 1];
+ System.arraycopy(path, 0, newPath, 0, path.length);
+ newPath[path.length] = menu.getPopupMenu();
+ manager.setSelectedPath(newPath);
+ }
+ else
+ {
+ manager.setSelectedPath(getPath());
+ setupPostTimer(menu);
+ }
+ }
+ }
+ else
+ {
+ if(selectedPath.length > 0
+ && selectedPath[0] == menu.getParent())
+ {
+ MenuElement[] newPath = new MenuElement[3];
+ newPath[0] = (MenuElement) menu.getParent();
+ newPath[1] = menu;
+ newPath[2] = menu.getPopupMenu();
+ manager.setSelectedPath(newPath);
+ }
+ }
}
}
@@ -354,29 +405,48 @@ public class BasicMenuUI extends BasicMenuItemUI
{
MenuSelectionManager manager = MenuSelectionManager.defaultManager();
JMenu menu = (JMenu) menuItem;
- manager.processMouseEvent(e);
-
- // Menu should be displayed when the menu is pressed only if
- // it is top-level menu
- if (menu.isTopLevelMenu())
+ if (menu.isEnabled())
{
- if (menu.getPopupMenu().isVisible())
- // If menu is visible and menu button was pressed..
- // then need to cancel the menu
- manager.clearSelectedPath();
- else
- {
- // Display the menu
- int x = 0;
- int y = menu.getHeight();
-
- manager.setSelectedPath(getPath());
-
- JMenuBar mb = (JMenuBar) menu.getParent();
-
- // set selectedIndex of the selectionModel of a menuBar
- mb.getSelectionModel().setSelectedIndex(mb.getComponentIndex(menu));
- }
+ // Open up the menu immediately if it's a toplevel menu.
+ // But not yet the popup, which might be opened delayed, see below.
+ if (menu.isTopLevelMenu())
+ {
+ if (menu.isSelected())
+ manager.clearSelectedPath();
+ else
+ {
+ Container cnt = menu.getParent();
+ if (cnt != null && cnt instanceof JMenuBar)
+ {
+ MenuElement[] me = new MenuElement[2];
+ me[0] = (MenuElement) cnt;
+ me[1] = menu;
+ manager.setSelectedPath(me);
+ }
+ }
+ }
+
+ // Open the menu's popup. Either do that immediately if delay == 0,
+ // or delayed when delay > 0.
+ MenuElement[] selectedPath = manager.getSelectedPath();
+ if (selectedPath.length > 0
+ && selectedPath[selectedPath.length - 1] != menu.getPopupMenu())
+ {
+ if(menu.isTopLevelMenu() || menu.getDelay() == 0)
+ {
+ MenuElement[] newPath =
+ new MenuElement[selectedPath.length + 1];
+ System.arraycopy(selectedPath, 0, newPath, 0,
+ selectedPath.length);
+ newPath[selectedPath.length] = menu.getPopupMenu();
+ manager.setSelectedPath(newPath);
+ }
+ else
+ {
+ setupPostTimer(menu);
+ }
+ }
+
}
}
@@ -493,8 +563,44 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void menuDragMouseDragged(MenuDragMouseEvent e)
{
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
- manager.setSelectedPath(e.getPath());
+ if (menuItem.isEnabled())
+ {
+ MenuSelectionManager manager = e.getMenuSelectionManager();
+ MenuElement path[] = e.getPath();
+
+ Point p = e.getPoint();
+ if(p.x >= 0 && p.x < menuItem.getWidth()
+ && p.y >= 0 && p.y < menuItem.getHeight())
+ {
+ JMenu menu = (JMenu) menuItem;
+ MenuElement[] selectedPath = manager.getSelectedPath();
+ if(! (selectedPath.length > 0
+ && selectedPath[selectedPath.length-1]
+ == menu.getPopupMenu()))
+ {
+ if(menu.isTopLevelMenu() || menu.getDelay() == 0
+ || e.getID() == MouseEvent.MOUSE_DRAGGED)
+ {
+ MenuElement[] newPath = new MenuElement[path.length + 1];
+ System.arraycopy(path, 0, newPath, 0, path.length);
+ newPath[path.length] = menu.getPopupMenu();
+ manager.setSelectedPath(newPath);
+ }
+ else
+ {
+ manager.setSelectedPath(path);
+ setupPostTimer(menu);
+ }
+ }
+ }
+ else if (e.getID() == MouseEvent.MOUSE_RELEASED)
+ {
+ Component comp = manager.componentForPoint(e.getComponent(),
+ e.getPoint());
+ if (comp == null)
+ manager.clearSelectedPath();
+ }
+ }
}
/**
@@ -505,8 +611,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*/
public void menuDragMouseEntered(MenuDragMouseEvent e)
{
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
- manager.setSelectedPath(e.getPath());
+ // Nothing to do here.
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java
index aed4d69d6d5..bfb9e98dbc9 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java
@@ -52,6 +52,7 @@ import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
+import javax.swing.text.View;
/**
* The BasicLookAndFeel UI implementation for
@@ -81,7 +82,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
*/
public BasicRadioButtonUI()
{
- icon = getDefaultIcon();
+ // nothing to do
}
/**
@@ -93,6 +94,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
protected void installDefaults(AbstractButton b)
{
super.installDefaults(b);
+ icon = UIManager.getIcon(getPropertyPrefix() + "icon");
}
/**
@@ -116,7 +118,7 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
*/
public Icon getDefaultIcon()
{
- return UIManager.getIcon(getPropertyPrefix() + "icon");
+ return icon;
}
/**
@@ -128,40 +130,92 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
public void paint(Graphics g, JComponent c)
{
AbstractButton b = (AbstractButton) c;
-
- Rectangle tr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle vr = new Rectangle();
+ Dimension size = c.getSize();
+ Insets i = b.getInsets();
+ textR.x = 0;
+ textR.y = 0;
+ textR.width = 0;
+ textR.height = 0;
+ iconR.x = 0;
+ iconR.y = 0;
+ iconR.width = 0;
+ iconR.height = 0;
+ viewR.x = i.left;
+ viewR.y = i.right;
+ viewR.width = size.width - i.left - i.right;
+ viewR.height = size.height - i.top - i.bottom;
Font f = c.getFont();
g.setFont(f);
ButtonModel m = b.getModel();
- // FIXME: Do a filtering on any customized icon if the following property
- // is set.
- boolean enabled = b.isEnabled();
-
- Icon currentIcon = b.getIcon();
- if (currentIcon == null)
- {
- currentIcon = getDefaultIcon();
- }
-
- SwingUtilities.calculateInnerArea(b, vr);
+ // This is the icon that we use for layout.
+ Icon icon = b.getIcon();
+ if (icon == null)
+ icon = getDefaultIcon();
+
+ // Do the layout.
String text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f),
- b.getText(), currentIcon,
+ b.getText(), icon,
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
- vr, ir, tr, b.getIconTextGap() + defaultTextShiftOffset);
-
- currentIcon.paintIcon(c, g, ir.x, ir.y);
-
+ viewR, iconR, textR, b.getIconTextGap());
+
+ // Figure out the correct icon.
+ icon = b.getIcon();
+ if (icon == null)
+ icon = getDefaultIcon();
+ else
+ {
+ if (! m.isEnabled())
+ {
+ if (m.isSelected())
+ icon = b.getDisabledSelectedIcon();
+ else
+ icon = b.getDisabledIcon();
+ }
+ else if (m.isArmed() && m.isPressed())
+ {
+ icon = b.getPressedIcon();
+ if (icon == null)
+ icon = b.getSelectedIcon();
+ }
+ else if (m.isSelected())
+ {
+ if (b.isRolloverEnabled() && m.isRollover())
+ {
+ icon = b.getRolloverSelectedIcon();
+ if (icon == null)
+ icon = b.getSelectedIcon();
+ }
+ else
+ icon = b.getSelectedIcon();
+ }
+ else if (b.isRolloverEnabled() && m.isRollover())
+ icon = b.getRolloverIcon();
+ if (icon == null)
+ icon = b.getIcon();
+ }
+ // .. and paint it.
+ icon.paintIcon(c, g, iconR.x, iconR.y);
+
+ // Paint text and focus indicator.
if (text != null)
- paintText(g, b, tr, text);
- if (b.hasFocus() && b.isFocusPainted() && m.isEnabled())
- paintFocus(g, tr, c.getSize());
+ {
+ // Maybe render HTML in the radio button.
+ View v = (View) c.getClientProperty(BasicHTML.propertyKey);
+ if (v != null)
+ v.paint(g, textR);
+ else
+ paintText(g, b, textR, text);
+
+ // Paint focus indicator if necessary.
+ if (b.hasFocus() && b.isFocusPainted()
+ && textR.width > 0 && textR.height > 0)
+ paintFocus(g, textR, size);
+ }
}
public Dimension getPreferredSize(JComponent c)
@@ -174,38 +228,40 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
// The other icon properties are ignored.
AbstractButton b = (AbstractButton) c;
- Rectangle contentRect;
- Rectangle viewRect;
- Rectangle iconRect = new Rectangle();
- Rectangle textRect = new Rectangle();
Insets insets = b.getInsets();
-
+
+ String text = b.getText();
Icon i = b.getIcon();
if (i == null)
i = getDefaultIcon();
- viewRect = new Rectangle();
-
- SwingUtilities.layoutCompoundLabel(
- b, // for the component orientation
- b.getFontMetrics(b.getFont()),
- b.getText(),
- i,
- b.getVerticalAlignment(),
- b.getHorizontalAlignment(),
- b.getVerticalTextPosition(),
- b.getHorizontalTextPosition(),
- viewRect, iconRect, textRect,
- defaultTextIconGap + defaultTextShiftOffset);
-
- contentRect = textRect.union(iconRect);
-
- return new Dimension(insets.left
- + contentRect.width
- + insets.right + b.getHorizontalAlignment(),
- insets.top
- + contentRect.height
- + insets.bottom);
+ textR.x = 0;
+ textR.y = 0;
+ textR.width = 0;
+ textR.height = 0;
+ iconR.x = 0;
+ iconR.y = 0;
+ iconR.width = 0;
+ iconR.height = 0;
+ viewR.x = 0;
+ viewR.y = 0;
+ viewR.width = Short.MAX_VALUE;
+ viewR.height = Short.MAX_VALUE;
+
+ SwingUtilities.layoutCompoundLabel(b, // for the component orientation
+ b.getFontMetrics(b.getFont()),
+ text, i, b.getVerticalAlignment(),
+ b.getHorizontalAlignment(),
+ b.getVerticalTextPosition(),
+ b.getHorizontalTextPosition(),
+ viewR, iconR, textR,
+ text == null ? 0 : b.getIconTextGap());
+
+ Rectangle r = SwingUtilities.computeUnion(textR.x, textR.y, textR.width,
+ textR.height, iconR);
+
+ return new Dimension(insets.left + r.width + insets.right,
+ insets.top + r.height + insets.bottom);
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
index 78e5168fc80..400ede03ce9 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -760,10 +760,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
scrollbar.setOpaque(true);
scrollbar.setLayout(this);
- thumbColor = UIManager.getColor("ScrollBar.thumb");
- thumbDarkShadowColor = UIManager.getColor("ScrollBar.thumbDarkShadow");
- thumbHighlightColor = UIManager.getColor("ScrollBar.thumbHighlight");
- thumbLightShadowColor = UIManager.getColor("ScrollBar.thumbShadow");
+ configureScrollBarColors();
maximumThumbSize = UIManager.getDimension("ScrollBar.maximumThumbSize");
minimumThumbSize = UIManager.getDimension("ScrollBar.minimumThumbSize");
@@ -1228,8 +1225,36 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected void scrollByBlock(int direction)
{
- scrollbar.setValue(scrollbar.getValue()
- + scrollbar.getBlockIncrement(direction));
+ scrollByBlock(scrollbar, direction);
+ }
+
+ /**
+ * Scrolls the specified <code>scrollBar</code> by one block (according
+ * to the scrollable protocol) in the specified <code>direction</code>.
+ *
+ * This method is here statically to support wheel scrolling from the
+ * BasicScrollPaneUI without code duplication.
+ *
+ * @param scrollBar the scrollbar to scroll
+ * @param direction the scroll direction
+ */
+ static final void scrollByBlock(JScrollBar scrollBar, int direction)
+ {
+ int delta;
+ if (direction > 0)
+ delta = scrollBar.getBlockIncrement(direction);
+ else
+ delta = - scrollBar.getBlockIncrement(direction);
+ int oldValue = scrollBar.getValue();
+ int newValue = oldValue + delta;
+
+ // Overflow check.
+ if (delta > 0 && newValue < oldValue)
+ newValue = scrollBar.getMaximum();
+ else if (delta < 0 && newValue > oldValue)
+ newValue = scrollBar.getMinimum();
+
+ scrollBar.setValue(newValue);
}
/**
@@ -1239,8 +1264,46 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected void scrollByUnit(int direction)
{
- scrollbar.setValue(scrollbar.getValue()
- + scrollbar.getUnitIncrement(direction));
+ scrollByUnits(scrollbar, direction, 1);
+ }
+
+ /**
+ * Scrolls the specified <code>scrollbac/code> by <code>units</code> units
+ * in the specified <code>direction</code>.
+ *
+ * This method is here statically to support wheel scrolling from the
+ * BasicScrollPaneUI without code duplication.
+ *
+ * @param scrollBar the scrollbar to scroll
+ * @param direction the direction
+ * @param units the number of units to scroll
+ */
+ static final void scrollByUnits(JScrollBar scrollBar, int direction,
+ int units)
+ {
+ // Do this inside a loop so that we don't clash with the scrollable
+ // interface, which can return different units at times. For instance,
+ // a Scrollable could return a unit of 2 pixels only to adjust the
+ // visibility of an item. If we would simply multiply this by units,
+ // then we would only get 6 pixels, which is complete crap.
+ for (int i = 0; i < units; i++)
+ {
+ int delta;
+ if (direction > 0)
+ delta = scrollBar.getUnitIncrement(direction);
+ else
+ delta = - scrollBar.getUnitIncrement(direction);
+ int oldValue = scrollBar.getValue();
+ int newValue = oldValue + delta;
+
+ // Overflow check.
+ if (delta > 0 && newValue < oldValue)
+ newValue = scrollBar.getMaximum();
+ else if (delta < 0 && newValue > oldValue)
+ newValue = scrollBar.getMinimum();
+
+ scrollBar.setValue(newValue);
+ }
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java
index a0616a8c1cf..a7194284050 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -38,9 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import gnu.classpath.NotImplementedException;
-
-import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
@@ -54,7 +51,6 @@ 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;
@@ -65,15 +61,15 @@ 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.border.Border;
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;
+import javax.swing.plaf.UIResource;
/**
* A UI delegate for the {@link JScrollPane} component.
@@ -102,19 +98,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI
JScrollBar hsb = scrollpane.getHorizontalScrollBar();
JViewport vp = scrollpane.getViewport();
Point viewPosition = vp.getViewPosition();
- int xpos = hsb.getValue();
-
- if (xpos != viewPosition.x)
- {
- viewPosition.x = xpos;
- vp.setViewPosition(viewPosition);
- }
-
- viewPosition.y = 0;
- JViewport columnHeader = scrollpane.getColumnHeader();
- if (columnHeader != null
- && !columnHeader.getViewPosition().equals(viewPosition))
- columnHeader.setViewPosition(viewPosition);
+ viewPosition.x = hsb.getValue();
+ vp.setViewPosition(viewPosition);
}
}
@@ -139,18 +124,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI
JScrollBar vsb = scrollpane.getVerticalScrollBar();
JViewport vp = scrollpane.getViewport();
Point viewPosition = vp.getViewPosition();
- int ypos = vsb.getValue();
- if (ypos != viewPosition.y)
- {
- viewPosition.y = ypos;
- vp.setViewPosition(viewPosition);
- }
-
- viewPosition.x = 0;
- JViewport rowHeader = scrollpane.getRowHeader();
- if (rowHeader != null
- && !rowHeader.getViewPosition().equals(viewPosition))
- rowHeader.setViewPosition(viewPosition);
+ viewPosition.y = vsb.getValue();
+ vp.setViewPosition(viewPosition);
}
}
@@ -174,9 +149,6 @@ public class BasicScrollPaneUI extends ScrollPaneUI
*/
public void stateChanged(ChangeEvent event)
{
- JViewport vp = scrollpane.getViewport();
- JScrollBar hsb = scrollpane.getHorizontalScrollBar();
- JScrollBar vsb = scrollpane.getVerticalScrollBar();
syncScrollPaneWithViewport();
}
@@ -254,103 +226,24 @@ public class BasicScrollPaneUI extends ScrollPaneUI
*/
public void mouseWheelMoved(MouseWheelEvent e)
{
- if (scrollpane.getViewport().getComponentCount() == 0)
- return;
-
- Component target = scrollpane.getViewport().getComponent(0);
- JScrollBar bar = scrollpane.getVerticalScrollBar();
- Scrollable scrollable = (target instanceof Scrollable) ? (Scrollable) target
- : null;
-
- boolean tracksHeight = scrollable != null
- && scrollable.getScrollableTracksViewportHeight();
- int wheel = e.getWheelRotation() * ROWS_PER_WHEEL_CLICK;
- int delta;
-
- // If possible, scroll vertically.
- if (bar != null && ! tracksHeight)
+ if (scrollpane.isWheelScrollingEnabled() && e.getScrollAmount() != 0)
{
- if (scrollable != null)
+ // Try to scroll vertically first.
+ JScrollBar scrollBar = scrollpane.getVerticalScrollBar();
+ if (scrollBar == null || ! scrollBar.isVisible())
+ scrollBar = scrollpane.getHorizontalScrollBar();
+ if (scrollBar != null && scrollBar.isVisible())
{
- bounds(target);
- delta = scrollable.getScrollableUnitIncrement(
- rect, SwingConstants.VERTICAL, wheel);
- }
- else
- {
- // Scroll non scrollables.
- delta = wheel * SCROLL_NON_SCROLLABLES;
- }
- scroll(bar, delta);
- }
- // If not, try to scroll horizontally
- else
- {
- bar = scrollpane.getHorizontalScrollBar();
- boolean tracksWidth = scrollable != null
- && scrollable.getScrollableTracksViewportWidth();
-
- if (bar != null && ! tracksWidth)
- {
- if (scrollable != null)
- {
- bounds(target);
- delta = scrollable.getScrollableUnitIncrement(
- rect, SwingConstants.HORIZONTAL, wheel);
- }
- else
- {
- // Scroll non scrollables.
- delta = wheel * SCROLL_NON_SCROLLABLES;
- }
- scroll(bar, delta);
+ int direction = e.getWheelRotation() < 0 ? -1 : 1;
+ int scrollType = e.getScrollType();
+ if (scrollType == MouseWheelEvent.WHEEL_UNIT_SCROLL)
+ BasicScrollBarUI.scrollByUnits(scrollBar, direction,
+ e.getScrollAmount());
+ else if (scrollType == MouseWheelEvent.WHEEL_BLOCK_SCROLL)
+ BasicScrollBarUI.scrollByBlock(scrollBar, direction);
}
}
}
-
- /**
- * Place the component bounds into rect. The x and y values
- * need to be reversed.
- *
- * @param target the target being scrolled
- */
- final void bounds(Component target)
- {
- // Viewport bounds, translated by the scroll bar positions.
- target.getParent().getBounds(rect);
- rect.x = getValue(scrollpane.getHorizontalScrollBar());
- rect.y = getValue(scrollpane.getVerticalScrollBar());
- }
-
- /**
- * 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)
- {
- return bar != null ? bar.getValue() : 0;
- }
-
- /**
- * Scroll the given distance.
- *
- * @param bar the scrollbar to scroll
- * @param delta the distance
- */
- final void scroll(JScrollBar bar, int delta)
- {
- int y = bar.getValue() + delta;
-
- if (y < bar.getMinimum())
- y = bar.getMinimum();
- if (y > bar.getMaximum())
- y = bar.getMaximum();
-
- bar.setValue(y);
- }
}
/**
@@ -436,16 +329,24 @@ public class BasicScrollPaneUI extends ScrollPaneUI
"ScrollPane.foreground",
"ScrollPane.font");
LookAndFeel.installBorder(p, "ScrollPane.border");
+
+ // Install Viewport border.
+ Border vpBorder = p.getViewportBorder();
+ if (vpBorder == null || vpBorder instanceof UIResource)
+ {
+ vpBorder = UIManager.getBorder("ScrollPane.viewportBorder");
+ p.setViewportBorder(vpBorder);
+ }
+
p.setOpaque(true);
}
protected void uninstallDefaults(JScrollPane p)
{
- p.setForeground(null);
- p.setBackground(null);
- p.setFont(null);
- p.setBorder(null);
- scrollpane = null;
+ LookAndFeel.uninstallBorder(p);
+ Border vpBorder = p.getViewportBorder();
+ if (vpBorder != null && vpBorder instanceof UIResource)
+ p.setViewportBorder(null);
}
public void installUI(final JComponent c)
@@ -770,9 +671,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI
public void uninstallUI(final JComponent c)
{
- super.uninstallUI(c);
- this.uninstallDefaults((JScrollPane) c);
- uninstallListeners((JScrollPane) c);
+ uninstallDefaults((JScrollPane) c);
+ uninstallListeners(c);
installKeyboardActions((JScrollPane) c);
}
@@ -808,29 +708,65 @@ public class BasicScrollPaneUI extends ScrollPaneUI
}
public void paint(Graphics g, JComponent c)
- {
- // do nothing; the normal painting-of-children algorithm, along with
- // ScrollPaneLayout, does all the relevant work.
+ {
+ Border vpBorder = scrollpane.getViewportBorder();
+ if (vpBorder != null)
+ {
+ Rectangle r = scrollpane.getViewportBorderBounds();
+ vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
+ }
}
/**
- * Synchronizes the scrollbars with the viewport's extents.
+ * Synchronizes the scrollbar and header settings positions and extent
+ * with the viewport's view position and extent.
*/
protected void syncScrollPaneWithViewport()
{
JViewport vp = scrollpane.getViewport();
- // Update the horizontal scrollbar.
- JScrollBar hsb = scrollpane.getHorizontalScrollBar();
- hsb.setMaximum(vp.getViewSize().width);
- hsb.setValue(vp.getViewPosition().x);
- hsb.setVisibleAmount(vp.getExtentSize().width);
-
- // Update the vertical scrollbar.
- JScrollBar vsb = scrollpane.getVerticalScrollBar();
- vsb.setMaximum(vp.getViewSize().height);
- vsb.setValue(vp.getViewPosition().y);
- vsb.setVisibleAmount(vp.getExtentSize().height);
+ if (vp != null)
+ {
+ Dimension extentSize = vp.getExtentSize();
+ Point viewPos = vp.getViewPosition();
+ Dimension viewSize = vp.getViewSize();
+
+ // Update the vertical scrollbar.
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ if (vsb != null)
+ {
+ int extent = extentSize.height;
+ int max = viewSize.height;
+ int val = Math.max(0, Math.min(viewPos.y, max - extent));
+ vsb.setValues(val, extent, 0, max);
+ }
+
+ // Update the horizontal scrollbar.
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ if (hsb != null)
+ {
+ int extent = extentSize.width;
+ int max = viewSize.width;
+ int val = Math.max(0, Math.min(viewPos.x, max - extent));
+ hsb.setValues(val, extent, 0, max);
+ }
+
+ // Update the row header.
+ JViewport rowHeader = scrollpane.getRowHeader();
+ if (rowHeader != null)
+ {
+ Point p = new Point(0, viewPos.y);
+ rowHeader.setViewPosition(p);
+ }
+
+ // Update the column header.
+ JViewport colHeader = scrollpane.getColumnHeader();
+ if (colHeader != null)
+ {
+ Point p = new Point(viewPos.x, 0);
+ colHeader.setViewPosition(p);
+ }
+ }
}
/**
@@ -863,7 +799,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI
*/
protected void updateScrollBarDisplayPolicy(PropertyChangeEvent ev)
{
- // TODO: Find out what should be done here. Or is this only a hook?
+ scrollpane.revalidate();
+ scrollpane.repaint();
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java
index 3811eebdfd6..474a4225640 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSliderUI.java
@@ -40,7 +40,6 @@ package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
-import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
@@ -65,7 +64,6 @@ import javax.swing.ActionMap;
import javax.swing.BoundedRangeModel;
import javax.swing.InputMap;
import javax.swing.JComponent;
-import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
@@ -185,8 +183,6 @@ public class BasicSliderUI extends SliderUI
public void componentResized(ComponentEvent e)
{
calculateGeometry();
-
- slider.revalidate();
slider.repaint();
}
}
@@ -209,7 +205,6 @@ public class BasicSliderUI extends SliderUI
public void focusGained(FocusEvent e)
{
slider.repaint();
- hasFocus = true;
}
/**
@@ -221,7 +216,6 @@ public class BasicSliderUI extends SliderUI
public void focusLost(FocusEvent e)
{
slider.repaint();
- hasFocus = false;
}
}
@@ -240,25 +234,27 @@ public class BasicSliderUI extends SliderUI
public void propertyChange(PropertyChangeEvent e)
{
// Check for orientation changes.
- if (e.getPropertyName().equals("orientation"))
- recalculateIfOrientationChanged();
+ String prop = e.getPropertyName();
+ if (prop.equals("orientation")
+ || prop.equals("inverted")
+ || prop.equals("labelTable")
+ || prop.equals("majorTickSpacing")
+ || prop.equals("minorTickSpacing")
+ || prop.equals("paintTicks")
+ || prop.equals("paintTrack")
+ || prop.equals("paintLabels"))
+ {
+ calculateGeometry();
+ slider.repaint();
+ }
else if (e.getPropertyName().equals("model"))
{
BoundedRangeModel oldModel = (BoundedRangeModel) e.getOldValue();
oldModel.removeChangeListener(changeListener);
slider.getModel().addChangeListener(changeListener);
calculateThumbLocation();
+ slider.repaint();
}
- else if (e.getPropertyName().equals("paintTicks"))
- calculateGeometry();
-
- // elif the componentOrientation changes (this is a bound property,
- // just undocumented) we change leftToRightCache. In Sun's
- // implementation, the LTR cache changes on a repaint. This is strange
- // since there is no need to do so. We could events here and
- // update the cache.
- // elif the border/insets change, we recalculateInsets.
- slider.repaint();
}
}
@@ -466,6 +462,7 @@ public class BasicSliderUI extends SliderUI
if (scrollTimer != null)
scrollTimer.stop();
}
+ slider.repaint();
}
/**
@@ -592,10 +589,7 @@ public class BasicSliderUI extends SliderUI
/** The focus color. */
private transient Color focusColor;
-
- /** True if the slider has focus. */
- private transient boolean hasFocus;
-
+
/** True if the user is dragging the slider. */
boolean dragging;
@@ -935,36 +929,10 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getPreferredHorizontalSize()
{
- Insets insets = slider.getInsets();
-
- // The width should cover all the labels (which are usually the
- // deciding factor of the width)
- int width = getWidthOfWidestLabel() * (slider.getLabelTable() == null ? 0
- : slider.getLabelTable().size());
-
- // If there are not enough labels.
- // This number is pretty much arbitrary, but it looks nice.
- if (width < 200)
- width = 200;
-
- // We can only draw inside of the focusRectangle, so we have to
- // pad it with insets.
- width += insets.left + insets.right + focusInsets.left + focusInsets.right;
-
- // Height is determined by the thumb, the ticks and the labels.
- int height = getThumbSize().height;
-
- if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0)
- height += getTickLength();
-
- if (slider.getPaintLabels())
- height += getHeightOfTallestLabel();
-
- height += insets.top + insets.bottom + focusInsets.top
- + focusInsets.bottom;
-
- return new Dimension(width, height);
+ Dimension dim = UIManager.getDimension("Slider.horizontalSize");
+ if (dim == null) // Just to be sure we mirror the default.
+ dim = new Dimension(200, 21);
+ return dim;
}
/**
@@ -975,30 +943,10 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getPreferredVerticalSize()
{
- Insets insets = slider.getInsets();
-
- int height = getHeightOfTallestLabel() * (slider.getLabelTable() == null
- ? 0 : slider.getLabelTable()
- .size());
-
- if (height < 200)
- height = 200;
-
- height += insets.top + insets.bottom + focusInsets.top
- + focusInsets.bottom;
-
- int width = getThumbSize().width;
-
- if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0)
- width += getTickLength();
-
- if (slider.getPaintLabels())
- width += getWidthOfWidestLabel();
-
- width += insets.left + insets.right + focusInsets.left + focusInsets.right;
-
- return new Dimension(width, height);
+ Dimension dim = UIManager.getDimension("Slider.verticalSize");
+ if (dim == null) // Just to be sure we mirror the default.
+ dim = new Dimension(21, 200);
+ return dim;
}
/**
@@ -1009,21 +957,10 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getMinimumHorizontalSize()
{
- Insets insets = slider.getInsets();
- // Height is determined by the thumb, the ticks and the labels.
- int height = getThumbSize().height;
-
- if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0)
- height += getTickLength();
-
- if (slider.getPaintLabels())
- height += getHeightOfTallestLabel();
-
- height += insets.top + insets.bottom + focusInsets.top
- + focusInsets.bottom;
-
- return new Dimension(36, height);
+ Dimension dim = UIManager.getDimension("Slider.minimumHorizontalSize");
+ if (dim == null) // Just to be sure we mirror the default.
+ dim = new Dimension(36, 21);
+ return dim;
}
/**
@@ -1034,19 +971,10 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getMinimumVerticalSize()
{
- Insets insets = slider.getInsets();
- int width = getThumbSize().width;
-
- if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0)
- width += getTickLength();
-
- if (slider.getPaintLabels())
- width += getWidthOfWidestLabel();
-
- width += insets.left + insets.right + focusInsets.left + focusInsets.right;
-
- return new Dimension(width, 36);
+ Dimension dim = UIManager.getDimension("Slider.minimumVerticalSize");
+ if (dim == null) // Just to be sure we mirror the default.
+ dim = new Dimension(21, 36);
+ return dim;
}
/**
@@ -1060,10 +988,25 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getPreferredSize(JComponent c)
{
+ recalculateIfInsetsChanged();
+ Dimension dim;
if (slider.getOrientation() == JSlider.HORIZONTAL)
- return getPreferredHorizontalSize();
+ {
+ // Create copy here to protect the UIManager value.
+ dim = new Dimension(getPreferredHorizontalSize());
+ dim.height = insetCache.top + insetCache.bottom;
+ dim.height += focusInsets.top + focusInsets.bottom;
+ dim.height += trackRect.height + tickRect.height + labelRect.height;
+ }
else
- return getPreferredVerticalSize();
+ {
+ // Create copy here to protect the UIManager value.
+ dim = new Dimension(getPreferredVerticalSize());
+ dim.width = insetCache.left + insetCache.right;
+ dim.width += focusInsets.left + focusInsets.right;
+ dim.width += trackRect.width + tickRect.width + labelRect.width;
+ }
+ return dim;
}
/**
@@ -1077,10 +1020,25 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getMinimumSize(JComponent c)
{
+ recalculateIfInsetsChanged();
+ Dimension dim;
if (slider.getOrientation() == JSlider.HORIZONTAL)
- return getMinimumHorizontalSize();
+ {
+ // Create copy here to protect the UIManager value.
+ dim = new Dimension(getMinimumHorizontalSize());
+ dim.height = insetCache.top + insetCache.bottom;
+ dim.height += focusInsets.top + focusInsets.bottom;
+ dim.height += trackRect.height + tickRect.height + labelRect.height;
+ }
else
- return getMinimumVerticalSize();
+ {
+ // Create copy here to protect the UIManager value.
+ dim = new Dimension(getMinimumVerticalSize());
+ dim.width = insetCache.left + insetCache.right;
+ dim.width += focusInsets.left + focusInsets.right;
+ dim.width += trackRect.width + tickRect.width + labelRect.width;
+ }
+ return dim;
}
/**
@@ -1093,40 +1051,12 @@ public class BasicSliderUI extends SliderUI
*/
public Dimension getMaximumSize(JComponent c)
{
- Insets insets = slider.getInsets();
+ Dimension dim = getPreferredSize(c);
if (slider.getOrientation() == JSlider.HORIZONTAL)
- {
- // Height is determined by the thumb, the ticks and the labels.
- int height = getThumbSize().height;
-
- if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0)
- height += getTickLength();
-
- if (slider.getPaintLabels())
- height += getHeightOfTallestLabel();
-
- height += insets.top + insets.bottom + focusInsets.top
- + focusInsets.bottom;
-
- return new Dimension(32767, height);
- }
+ dim.width = Short.MAX_VALUE;
else
- {
- int width = getThumbSize().width;
-
- if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0)
- width += getTickLength();
-
- if (slider.getPaintLabels())
- width += getWidthOfWidestLabel();
-
- width += insets.left + insets.right + focusInsets.left
- + focusInsets.right;
-
- return new Dimension(width, 32767);
- }
+ dim.height = Short.MAX_VALUE;
+ return dim;
}
/**
@@ -1151,12 +1081,10 @@ public class BasicSliderUI extends SliderUI
*/
protected void calculateFocusRect()
{
- insetCache = slider.getInsets();
- focusRect = SwingUtilities.calculateInnerArea(slider, focusRect);
- if (focusRect.width < 0)
- focusRect.width = 0;
- if (focusRect.height < 0)
- focusRect.height = 0;
+ focusRect.x = insetCache.left;
+ focusRect.y = insetCache.top;
+ focusRect.width = slider.getWidth() - insetCache.left - insetCache.right;
+ focusRect.height = slider.getHeight() - insetCache.top - insetCache.bottom;
}
/**
@@ -1181,13 +1109,8 @@ public class BasicSliderUI extends SliderUI
contentRect.y = focusRect.y + focusInsets.top;
contentRect.width = focusRect.width - focusInsets.left - focusInsets.right;
- contentRect.height = focusRect.height - focusInsets.top
- - focusInsets.bottom;
-
- if (contentRect.width < 0)
- contentRect.width = 0;
- if (contentRect.height < 0)
- contentRect.height = 0;
+ contentRect.height = focusRect.height - focusInsets.top
+ - focusInsets.bottom;
}
/**
@@ -1258,26 +1181,24 @@ public class BasicSliderUI extends SliderUI
{
if (slider.getOrientation() == JSlider.HORIZONTAL)
{
- trackRect.x = contentRect.x + trackBuffer;
- int h = getThumbSize().height;
- if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0))
- h += getTickLength();
+ int center = thumbRect.height;
+ if (slider.getPaintTicks())
+ center += getTickLength();
if (slider.getPaintLabels())
- h += getHeightOfTallestLabel();
- trackRect.y = contentRect.y + (contentRect.height - h) / 2 - 1;
+ center += getHeightOfTallestLabel();
+ trackRect.x = contentRect.x + trackBuffer;
+ trackRect.y = contentRect.y + (contentRect.height - center - 1) / 2;
trackRect.width = contentRect.width - 2 * trackBuffer;
trackRect.height = thumbRect.height;
}
else
{
- int w = getThumbSize().width;
- if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
- || slider.getMinorTickSpacing() > 0))
- w += getTickLength();
+ int center = thumbRect.width;
+ if (slider.getPaintTicks())
+ center += getTickLength();
if (slider.getPaintLabels())
- w += getWidthOfWidestLabel();
- trackRect.x = contentRect.x + (contentRect.width - w) / 2 - 1;
+ center += getWidthOfWidestLabel();
+ trackRect.x = contentRect.x + (contentRect.width - center - 1) / 2;
trackRect.y = contentRect.y + trackBuffer;
trackRect.width = thumbRect.width;
trackRect.height = contentRect.height - 2 * trackBuffer;
@@ -1310,28 +1231,28 @@ public class BasicSliderUI extends SliderUI
tickRect.x = trackRect.x;
tickRect.y = trackRect.y + trackRect.height;
tickRect.width = trackRect.width;
- tickRect.height = slider.getPaintTicks() ? getTickLength() : 0;
+ tickRect.height = getTickLength();
// this makes our Mauve tests pass...can't explain it!
if (!slider.getPaintTicks())
- tickRect.y--;
-
- if (tickRect.y + tickRect.height > contentRect.y + contentRect.height)
- tickRect.height = contentRect.y + contentRect.height - tickRect.y;
+ {
+ tickRect.y--;
+ tickRect.height = 0;
+ }
}
else
{
tickRect.x = trackRect.x + trackRect.width;
tickRect.y = trackRect.y;
- tickRect.width = slider.getPaintTicks() ? getTickLength() : 0;
+ tickRect.width = getTickLength();
tickRect.height = trackRect.height;
// this makes our Mauve tests pass...can't explain it!
if (!slider.getPaintTicks())
- tickRect.x--;
-
- if (tickRect.x + tickRect.width > contentRect.x + contentRect.width)
- tickRect.width = contentRect.x + contentRect.width - tickRect.x;
+ {
+ tickRect.x--;
+ tickRect.width = 0;
+ }
}
}
@@ -1345,33 +1266,35 @@ public class BasicSliderUI extends SliderUI
{
if (slider.getPaintLabels())
{
- labelRect.x = contentRect.x;
- labelRect.y = tickRect.y + tickRect.height - 1;
- labelRect.width = contentRect.width;
+ labelRect.x = tickRect.x - trackBuffer;
+ labelRect.y = tickRect.y + tickRect.height;
+ labelRect.width = tickRect.width + trackBuffer * 2;
+ labelRect.height = getHeightOfTallestLabel();
}
else
{
- labelRect.x = trackRect.x;
+ labelRect.x = tickRect.x;
labelRect.y = tickRect.y + tickRect.height;
- labelRect.width = trackRect.width;
+ labelRect.width = tickRect.width;
+ labelRect.height = 0;
}
- labelRect.height = getHeightOfTallestLabel();
}
else
{
if (slider.getPaintLabels())
{
- labelRect.x = tickRect.x + tickRect.width - 1;
- labelRect.y = contentRect.y;
- labelRect.height = contentRect.height;
+ labelRect.x = tickRect.x + tickRect.width;
+ labelRect.y = tickRect.y - trackBuffer;
+ labelRect.width = getWidthOfWidestLabel();
+ labelRect.height = tickRect.height + trackBuffer * 2;
}
else
{
labelRect.x = tickRect.x + tickRect.width;
- labelRect.y = trackRect.y;
- labelRect.height = trackRect.height;
+ labelRect.y = tickRect.y;
+ labelRect.width = 0;
+ labelRect.height = tickRect.height;
}
- labelRect.width = getWidthOfWidestLabel();
}
}
@@ -1384,22 +1307,15 @@ public class BasicSliderUI extends SliderUI
protected int getWidthOfWidestLabel()
{
int widest = 0;
- Component label;
-
- if (slider.getLabelTable() == null)
- return 0;
-
- Dimension pref;
- for (Enumeration list = slider.getLabelTable().elements();
- list.hasMoreElements();)
+ Dictionary table = slider.getLabelTable();
+ if (table != null)
{
- Object comp = list.nextElement();
- if (! (comp instanceof Component))
- continue;
- label = (Component) comp;
- pref = label.getPreferredSize();
- if (pref != null && pref.width > widest)
- widest = pref.width;
+ for (Enumeration list = slider.getLabelTable().elements();
+ list.hasMoreElements();)
+ {
+ Component label = (Component) list.nextElement();
+ widest = Math.max(label.getPreferredSize().width, widest);
+ }
}
return widest;
}
@@ -1576,23 +1492,18 @@ public class BasicSliderUI extends SliderUI
*/
public void paint(Graphics g, JComponent c)
{
- // FIXME: Move this to propertyChangeEvent handler, when we get those.
- leftToRightCache = slider.getComponentOrientation()
- != ComponentOrientation.RIGHT_TO_LEFT;
- // FIXME: This next line is only here because the above line is here.
- calculateGeometry();
-
- if (slider.getPaintTrack())
+ recalculateIfInsetsChanged();
+ recalculateIfOrientationChanged();
+ if (slider.getPaintTrack() && hitClip(g, trackRect))
paintTrack(g);
- if (slider.getPaintTicks())
+ if (slider.getPaintTicks() && hitClip(g, tickRect))
paintTicks(g);
- if (slider.getPaintLabels())
+ if (slider.getPaintLabels() && hitClip(g, labelRect))
paintLabels(g);
-
- paintThumb(g);
-
- if (hasFocus)
+ if (slider.hasFocus() && hitClip(g, focusRect))
paintFocus(g);
+ if (hitClip(g, thumbRect))
+ paintThumb(g);
}
/**
@@ -1601,18 +1512,12 @@ public class BasicSliderUI extends SliderUI
*/
protected void recalculateIfInsetsChanged()
{
- // Examining a test program shows that either Sun calls private
- // methods that we don't know about, or these don't do anything.
- calculateFocusRect();
-
- calculateContentRect();
- calculateThumbSize();
- calculateTrackBuffer();
- calculateTrackRect();
- calculateThumbLocation();
-
- calculateTickRect();
- calculateLabelRect();
+ Insets insets = slider.getInsets();
+ if (! insets.equals(insetCache))
+ {
+ insetCache = insets;
+ calculateGeometry();
+ }
}
/**
@@ -1863,45 +1768,30 @@ public class BasicSliderUI extends SliderUI
*/
public void paintLabels(Graphics g)
{
- if (slider.getLabelTable() != null)
+ Dictionary table = slider.getLabelTable();
+ if (table != null)
{
- Dictionary table = slider.getLabelTable();
- Integer tmpKey;
- Object key;
- Object element;
- Component label;
- if (slider.getOrientation() == JSlider.HORIZONTAL)
- {
- for (Enumeration list = table.keys(); list.hasMoreElements();)
- {
- key = list.nextElement();
- if (! (key instanceof Integer))
- continue;
- tmpKey = (Integer) key;
- element = table.get(tmpKey);
- // We won't paint them if they're not
- // JLabels so continue anyway
- if (! (element instanceof JLabel))
- continue;
- label = (Component) element;
- paintHorizontalLabel(g, tmpKey.intValue(), label);
- }
- }
- else
+ int min = slider.getMinimum();
+ int max = slider.getMaximum();
+ for (Enumeration list = table.keys(); list.hasMoreElements();)
{
- for (Enumeration list = table.keys(); list.hasMoreElements();)
+ Integer key = (Integer) list.nextElement();
+ int value = key.intValue();
+ if (value >= min && value <= max)
{
- key = list.nextElement();
- if (! (key instanceof Integer))
- continue;
- tmpKey = (Integer) key;
- element = table.get(tmpKey);
- // We won't paint them if they're not
- // JLabels so continue anyway
- if (! (element instanceof JLabel))
- continue;
- label = (Component) element;
- paintVerticalLabel(g, tmpKey.intValue(), label);
+ Component label = (Component) table.get(key);
+ if (slider.getOrientation() == JSlider.HORIZONTAL)
+ {
+ g.translate(0, labelRect.y);
+ paintHorizontalLabel(g, value, label);
+ g.translate(0, -labelRect.y);
+ }
+ else
+ {
+ g.translate(labelRect.x, 0);
+ paintVerticalLabel(g, value, label);
+ g.translate(-labelRect.x, 0);
+ }
}
}
}
@@ -1920,51 +1810,11 @@ public class BasicSliderUI extends SliderUI
*/
protected void paintHorizontalLabel(Graphics g, int value, Component label)
{
- // This relies on clipping working properly or we'll end up
- // painting all over the place. If our preferred size is ignored, then
- // the labels may not fit inside the slider's bounds. Rather than mucking
- // with font sizes and possible icon sizes, we'll set the bounds for
- // the label and let it get clipped.
- Dimension dim = label.getPreferredSize();
- int w = (int) dim.getWidth();
- int h = (int) dim.getHeight();
-
- int max = slider.getMaximum();
- int min = slider.getMinimum();
-
- if (value > max || value < min)
- return;
-
- // value
- // |
- // ------------
- // | |
- // | |
- // | |
- // The label must move w/2 to the right to fit directly under the value.
- int xpos = xPositionForValue(value) - w / 2;
- int ypos = labelRect.y;
-
- // We want to center the label around the xPositionForValue
- // So we use xpos - w / 2. However, if value is min and the label
- // is large, we run the risk of going out of bounds. So we bring it back
- // to 0 if it becomes negative.
- if (xpos < 0)
- xpos = 0;
-
- // If the label + starting x position is greater than
- // the x space in the label rectangle, we reset it to the largest
- // amount possible in the rectangle. This means ugliness.
- if (xpos + w > labelRect.x + labelRect.width)
- w = labelRect.x + labelRect.width - xpos;
-
- // If the label is too tall. We reset it to the height of the label
- // rectangle.
- if (h > labelRect.height)
- h = labelRect.height;
-
- label.setBounds(xpos, ypos, w, h);
- SwingUtilities.paintComponent(g, label, null, label.getBounds());
+ int center = xPositionForValue(value);
+ int left = center - label.getPreferredSize().width / 2;
+ g.translate(left, 0);
+ label.paint(g);
+ g.translate(-left, 0);
}
/**
@@ -1980,30 +1830,11 @@ public class BasicSliderUI extends SliderUI
*/
protected void paintVerticalLabel(Graphics g, int value, Component label)
{
- Dimension dim = label.getPreferredSize();
- int w = (int) dim.getWidth();
- int h = (int) dim.getHeight();
-
- int max = slider.getMaximum();
- int min = slider.getMinimum();
-
- if (value > max || value < min)
- return;
-
- int xpos = labelRect.x;
- int ypos = yPositionForValue(value) - h / 2;
-
- if (ypos < 0)
- ypos = 0;
-
- if (ypos + h > labelRect.y + labelRect.height)
- h = labelRect.y + labelRect.height - ypos;
-
- if (w > labelRect.width)
- w = labelRect.width;
-
- label.setBounds(xpos, ypos, w, h);
- SwingUtilities.paintComponent(g, label, null, label.getBounds());
+ int center = yPositionForValue(value);
+ int top = center - label.getPreferredSize().height / 2;
+ g.translate(0, top);
+ label.paint(g);
+ g.translate(0, -top);
}
/**
@@ -2118,8 +1949,11 @@ public class BasicSliderUI extends SliderUI
*/
public void setThumbLocation(int x, int y)
{
- thumbRect.x = x;
- thumbRect.y = y;
+ Rectangle union = new Rectangle(thumbRect);
+ thumbRect.setLocation(x, y);
+ SwingUtilities.computeUnion(thumbRect.x, thumbRect.y, thumbRect.width,
+ thumbRect.height, union);
+ slider.repaint(union);
}
/**
@@ -2197,21 +2031,21 @@ public class BasicSliderUI extends SliderUI
*/
protected int xPositionForValue(int value)
{
- double min = slider.getMinimum();
- if (value < min)
- value = (int) min;
- double max = slider.getMaximum();
- if (value > max)
- value = (int) max;
- double len = trackRect.width;
- if ((max - min) <= 0.0)
- return 0;
- int xPos = (int) ((value - min) / (max - min) * len + 0.5);
-
- if (drawInverted())
- return trackRect.x + Math.max(trackRect.width - xPos - 1, 0);
+ int min = slider.getMinimum();
+ int max = slider.getMaximum();
+ int len = trackRect.width;
+ double range = max - min;
+ double pixPerVal = len / range;
+ int left = trackRect.x;
+ int right = left + trackRect.width - 1;
+ int xpos;
+ if (! drawInverted())
+ xpos = left + (int) Math.round(pixPerVal * ((double) value - min));
else
- return trackRect.x + Math.min(xPos, trackRect.width - 1);
+ xpos = right - (int) Math.round(pixPerVal * ((double) value - min));
+ xpos = Math.max(left, xpos);
+ xpos = Math.min(right, xpos);
+ return xpos;
}
/**
@@ -2225,22 +2059,21 @@ public class BasicSliderUI extends SliderUI
*/
protected int yPositionForValue(int value)
{
- double min = slider.getMinimum();
- if (value < min)
- value = (int) min;
- double max = slider.getMaximum();
- if (value > max)
- value = (int) max;
+ int min = slider.getMinimum();
+ int max = slider.getMaximum();
int len = trackRect.height;
- if ((max - min) <= 0.0)
- return 0;
-
- int yPos = (int) ((value - min) / (max - min) * len + 0.5);
-
+ double range = max - min;
+ double pixPerVal = len / range;
+ int top = trackRect.y;
+ int bottom = top + trackRect.height - 1;
+ int ypos;
if (! drawInverted())
- return trackRect.y + trackRect.height - Math.max(yPos, 1);
+ ypos = top + (int) Math.round(pixPerVal * ((double) max - value));
else
- return trackRect.y + Math.min(yPos, trackRect.height - 1);
+ ypos = top + (int) Math.round(pixPerVal * ((double) value - min));
+ ypos = Math.max(top, ypos);
+ ypos = Math.min(bottom, ypos);
+ return ypos;
}
/**
@@ -2494,4 +2327,13 @@ public class BasicSliderUI extends SliderUI
);
return map;
}
+
+ /**
+ * Small utility method to save me from typing the hell out of myself in
+ * paint().
+ */
+ private boolean hitClip(Graphics g, Rectangle r)
+ {
+ return g.hitClip(r.x, r.y, r.width, r.height);
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java
index 06d32984efb..95468caa972 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java
@@ -38,12 +38,15 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
@@ -52,7 +55,7 @@ import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JSplitPane;
-import javax.swing.SwingConstants;
+import javax.swing.UIManager;
import javax.swing.border.Border;
/**
@@ -72,6 +75,207 @@ public class BasicSplitPaneDivider extends Container
implements PropertyChangeListener
{
/**
+ * The buttons used as one touch buttons.
+ */
+ private class BasicOneTouchButton
+ extends JButton
+ {
+ /**
+ * Denotes a left button.
+ */
+ static final int LEFT = 0;
+
+ /**
+ * Denotes a right button.
+ */
+ static final int RIGHT = 1;
+
+ /**
+ * The x points for the arrow.
+ */
+ private int[] xpoints;
+
+ /**
+ * The y points for the arrow.
+ */
+ private int[] ypoints;
+
+ /**
+ * Either LEFT or RIGHT.
+ */
+ private int direction;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param dir either LEFT or RIGHT
+ */
+ BasicOneTouchButton(int dir)
+ {
+ direction = dir;
+ xpoints = new int[3];
+ ypoints = new int[3];
+ }
+
+ /**
+ * Never allow borders.
+ */
+ public void setBorder(Border b)
+ {
+ }
+
+ /**
+ * Never allow focus traversal.
+ */
+ public boolean isFocusTraversable()
+ {
+ return false;
+ }
+
+ /**
+ * Paints the one touch button.
+ */
+ public void paint(Graphics g)
+ {
+ if (splitPane != null)
+ {
+ // Fill background.
+ g.setColor(splitPane.getBackground());
+ g.fillRect(0, 0, getWidth(), getHeight());
+
+ // Draw arrow.
+ int size;
+ if (direction == LEFT)
+ {
+ if (orientation == JSplitPane.VERTICAL_SPLIT)
+ {
+ size = Math.min(getHeight(), ONE_TOUCH_SIZE);
+ xpoints[0] = 0;
+ xpoints[1] = size / 2;
+ xpoints[2] = size;
+ ypoints[0] = size;
+ ypoints[1] = 0;
+ ypoints[2] = size;
+ }
+ else
+ {
+ size = Math.min(getWidth(), ONE_TOUCH_SIZE);
+ xpoints[0] = size;
+ xpoints[1] = 0;
+ xpoints[2] = size;
+ ypoints[0] = 0;
+ ypoints[1] = size / 2;
+ ypoints[2] = size;
+ }
+ }
+ else
+ {
+ if (orientation == JSplitPane.VERTICAL_SPLIT)
+ {
+ size = Math.min(getHeight(), ONE_TOUCH_SIZE);
+ xpoints[0] = 0;
+ xpoints[1] = size / 2;
+ xpoints[2] = size;
+ ypoints[0] = 0;
+ ypoints[1] = size;
+ ypoints[2] = 0;
+ }
+ else
+ {
+ size = Math.min(getWidth(), ONE_TOUCH_SIZE);
+ xpoints[0] = 0;
+ xpoints[1] = size;
+ xpoints[2] = 0;
+ ypoints[0] = 0;
+ ypoints[1] = size / 2;
+ ypoints[2] = size;
+ }
+ }
+ g.setColor(Color.BLACK);
+ g.fillPolygon(xpoints, ypoints, 3);
+ }
+ }
+ }
+
+ /**
+ * Listens for actions on the one touch buttons.
+ */
+ private class OneTouchAction
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent ev)
+ {
+ Insets insets = splitPane.getInsets();
+ int lastLoc = splitPane.getLastDividerLocation();
+ int currentLoc = splitPaneUI.getDividerLocation(splitPane);
+ int newLoc;
+
+ if (ev.getSource() == leftButton)
+ {
+ if (orientation == JSplitPane.VERTICAL_SPLIT)
+ {
+ if (currentLoc
+ >= splitPane.getHeight() - insets.bottom - getHeight())
+ {
+ newLoc = Math.min(splitPane.getMaximumDividerLocation(),
+ lastLoc);
+ }
+ else
+ {
+ newLoc = insets.top;
+ }
+ }
+ else
+ {
+ if (currentLoc
+ >= splitPane.getWidth() - insets.right - getWidth())
+ {
+ newLoc = Math.min(splitPane.getMaximumDividerLocation(),
+ lastLoc);
+ }
+ else
+ {
+ newLoc = insets.left;
+ }
+ }
+ }
+ else
+ {
+ if (orientation == JSplitPane.VERTICAL_SPLIT)
+ {
+ if (currentLoc == insets.top)
+ {
+ newLoc = Math.min(splitPane.getMaximumDividerLocation(),
+ lastLoc);
+ }
+ else
+ {
+ newLoc = splitPane.getHeight() - insets.top - getHeight();
+ }
+ }
+ else
+ {
+ if (currentLoc == insets.left)
+ {
+ newLoc = Math.min(splitPane.getMaximumDividerLocation(),
+ lastLoc);
+ }
+ else
+ {
+ newLoc = splitPane.getWidth() - insets.left - getWidth();
+ }
+ }
+ }
+ if (currentLoc != newLoc)
+ {
+ splitPane.setDividerLocation(newLoc);
+ splitPane.setLastDividerLocation(currentLoc);
+ }
+ }
+ }
+
+ /**
* Determined using the <code>serialver</code> tool of Apple/Sun JDK 1.3.1
* on MacOS X 10.1.5.
*/
@@ -161,6 +365,14 @@ public class BasicSplitPaneDivider extends Container
transient int currentDividerLocation = 1;
/**
+ * Indicates if the ont touch buttons are laid out centered or at the
+ * top/left.
+ *
+ * Package private to avoid accessor method.
+ */
+ boolean centerOneTouchButtons;
+
+ /**
* Constructs a new divider.
*
* @param ui the UI delegate of the enclosing <code>JSplitPane</code>.
@@ -170,6 +382,8 @@ public class BasicSplitPaneDivider extends Container
setLayout(new DividerLayout());
setBasicSplitPaneUI(ui);
setDividerSize(splitPane.getDividerSize());
+ centerOneTouchButtons =
+ UIManager.getBoolean("SplitPane.centerOneTouchButtons");
}
/**
@@ -202,7 +416,8 @@ public class BasicSplitPaneDivider extends Container
addMouseMotionListener(mouseHandler);
hiddenDivider = splitPaneUI.getNonContinuousLayoutDivider();
orientation = splitPane.getOrientation();
- oneTouchExpandableChanged();
+ if (splitPane.isOneTouchExpandable())
+ oneTouchExpandableChanged();
}
}
@@ -293,7 +508,12 @@ public class BasicSplitPaneDivider extends Container
*/
public Dimension getPreferredSize()
{
- return getLayout().preferredLayoutSize(this);
+ Dimension d;
+ if (orientation == JSplitPane.HORIZONTAL_SPLIT)
+ d = new Dimension(getDividerSize(), 1);
+ else
+ d = new Dimension(1, getDividerSize());
+ return d;
}
/**
@@ -320,11 +540,9 @@ public class BasicSplitPaneDivider extends Container
else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY))
{
orientation = splitPane.getOrientation();
- if (splitPane.isOneTouchExpandable())
- {
- layout();
- repaint();
- }
+ invalidate();
+ if (splitPane != null)
+ splitPane.revalidate();
}
else if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY))
dividerSize = splitPane.getDividerSize();
@@ -345,11 +563,6 @@ public class BasicSplitPaneDivider extends Container
dividerSize = getSize();
border.paintBorder(this, g, 0, 0, dividerSize.width, dividerSize.height);
}
- if (splitPane.isOneTouchExpandable())
- {
- ((BasicArrowButton) rightButton).paint(g);
- ((BasicArrowButton) leftButton).paint(g);
- }
}
/**
@@ -361,31 +574,23 @@ public class BasicSplitPaneDivider extends Container
if (splitPane.isOneTouchExpandable())
{
leftButton = createLeftOneTouchButton();
- rightButton = createRightOneTouchButton();
- add(leftButton);
- add(rightButton);
+ if (leftButton != null)
+ leftButton.addActionListener(new OneTouchAction());
- leftButton.addMouseListener(mouseHandler);
- rightButton.addMouseListener(mouseHandler);
+ rightButton = createRightOneTouchButton();
+ if (rightButton != null)
+ rightButton.addActionListener(new OneTouchAction());
- // Set it to 1.
- currentDividerLocation = 1;
- }
- else
- {
+ // Only add them when both are non-null.
if (leftButton != null && rightButton != null)
- {
- leftButton.removeMouseListener(mouseHandler);
- rightButton.removeMouseListener(mouseHandler);
-
- remove(leftButton);
- remove(rightButton);
- leftButton = null;
- rightButton = null;
+ {
+ add(leftButton);
+ add(rightButton);
}
}
- layout();
- repaint();
+ invalidate();
+ if (splitPane != null)
+ splitPane.revalidate();
}
/**
@@ -396,12 +601,9 @@ public class BasicSplitPaneDivider extends Container
*/
protected JButton createLeftOneTouchButton()
{
- int dir = SwingConstants.WEST;
- if (orientation == JSplitPane.VERTICAL_SPLIT)
- dir = SwingConstants.NORTH;
- JButton button = new BasicArrowButton(dir);
- button.setBorder(null);
-
+ JButton button = new BasicOneTouchButton(BasicOneTouchButton.LEFT);
+ button.setMinimumSize(new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE));
+ button.setRequestFocusEnabled(false);
return button;
}
@@ -413,11 +615,9 @@ public class BasicSplitPaneDivider extends Container
*/
protected JButton createRightOneTouchButton()
{
- int dir = SwingConstants.EAST;
- if (orientation == JSplitPane.VERTICAL_SPLIT)
- dir = SwingConstants.SOUTH;
- JButton button = new BasicArrowButton(dir);
- button.setBorder(null);
+ JButton button = new BasicOneTouchButton(BasicOneTouchButton.RIGHT);
+ button.setMinimumSize(new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE));
+ button.setRequestFocusEnabled(false);
return button;
}
@@ -521,25 +721,6 @@ public class BasicSplitPaneDivider extends Container
*/
public void mousePressed(MouseEvent e)
{
- if (splitPane.isOneTouchExpandable())
- {
- if (e.getSource() == leftButton)
- {
- currentDividerLocation--;
- if (currentDividerLocation < 0)
- currentDividerLocation = 0;
- moveDividerTo(currentDividerLocation);
- return;
- }
- else if (e.getSource() == rightButton)
- {
- currentDividerLocation++;
- if (currentDividerLocation > 2)
- currentDividerLocation = 2;
- moveDividerTo(currentDividerLocation);
- return;
- }
- }
isDragging = true;
currentDividerLocation = 1;
if (orientation == JSplitPane.HORIZONTAL_SPLIT)
@@ -797,10 +978,64 @@ public class BasicSplitPaneDivider extends Container
*/
public void layoutContainer(Container c)
{
- if (splitPane.isOneTouchExpandable())
+ if (leftButton != null && rightButton != null
+ && c == BasicSplitPaneDivider.this)
{
- changeButtonOrientation();
- positionButtons();
+ if (splitPane.isOneTouchExpandable())
+ {
+ Insets insets = getInsets();
+ if (orientation == JSplitPane.HORIZONTAL_SPLIT)
+ {
+ int size = getWidth() - insets.left - insets.right;
+ size = Math.max(size, 0);
+ size = Math.min(size, ONE_TOUCH_SIZE);
+ int x, y;
+ if (centerOneTouchButtons)
+ {
+ y = insets.top;
+ x = (getWidth() - size) / 2;
+ }
+ else
+ {
+ x = insets.left;
+ y = 0;
+ }
+
+ leftButton.setBounds(x, y + ONE_TOUCH_OFFSET, size,
+ size * 2);
+ rightButton.setBounds(x, y + ONE_TOUCH_OFFSET
+ + ONE_TOUCH_SIZE * 2, size, size * 2);
+ }
+ else
+ {
+ int size = getHeight() - insets.top - insets.bottom;
+ size = Math.max(size, 0);
+ size = Math.min(size, ONE_TOUCH_SIZE);
+ int x, y;
+ if (centerOneTouchButtons)
+ {
+ x = insets.left;
+ y = (getHeight() - size) / 2;
+ }
+ else
+ {
+ x = 0;
+ y = insets.top;
+ }
+ leftButton.setBounds(x + ONE_TOUCH_OFFSET, y, size * 2,
+ size);
+ rightButton.setBounds(x + ONE_TOUCH_OFFSET
+ + ONE_TOUCH_SIZE * 2, y, size * 2,
+ size);
+ }
+ }
+ else
+ {
+ // The JDK sets this bounds for disabled one touch buttons, so
+ // do we.
+ leftButton.setBounds(-5, -5, 1, 1);
+ rightButton.setBounds(-5, -5, 1, 1);
+ }
}
}
@@ -838,50 +1073,5 @@ public class BasicSplitPaneDivider extends Container
// Do nothing.
}
- /**
- * This method changes the button orientation when the orientation of the
- * SplitPane changes.
- */
- private void changeButtonOrientation()
- {
- if (orientation == JSplitPane.HORIZONTAL_SPLIT)
- {
- ((BasicArrowButton) rightButton).setDirection(SwingConstants.EAST);
- ((BasicArrowButton) leftButton).setDirection(SwingConstants.WEST);
- }
- else
- {
- ((BasicArrowButton) rightButton).setDirection(SwingConstants.SOUTH);
- ((BasicArrowButton) leftButton).setDirection(SwingConstants.NORTH);
- }
- }
-
- /**
- * This method sizes and positions the buttons.
- */
- private void positionButtons()
- {
- int w = 0;
- int h = 0;
- if (orientation == JSplitPane.HORIZONTAL_SPLIT)
- {
- rightButton.setLocation(ONE_TOUCH_OFFSET, ONE_TOUCH_OFFSET);
- leftButton.setLocation(ONE_TOUCH_OFFSET,
- ONE_TOUCH_OFFSET + 2 * ONE_TOUCH_SIZE);
- w = dividerSize - 2 * ONE_TOUCH_OFFSET;
- h = 2 * ONE_TOUCH_SIZE;
- }
- else
- {
- leftButton.setLocation(ONE_TOUCH_OFFSET, ONE_TOUCH_OFFSET);
- rightButton.setLocation(ONE_TOUCH_OFFSET + 2 * ONE_TOUCH_SIZE,
- ONE_TOUCH_OFFSET);
- h = dividerSize - 2 * ONE_TOUCH_OFFSET;
- w = 2 * ONE_TOUCH_SIZE;
- }
- Dimension dims = new Dimension(w, h);
- leftButton.setSize(dims);
- rightButton.setSize(dims);
- }
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
index 2d595597424..b7cc425482d 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
@@ -63,6 +63,7 @@ import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
+import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ActionMapUIResource;
@@ -107,13 +108,34 @@ public class BasicSplitPaneUI extends SplitPaneUI
protected int[] sizes = new int[3];
/**
+ * This is used to determine if we are vertical or horizontal layout.
+ * In the JDK, the BasicVerticalLayoutManager seems to have no more
+ * methods implemented (as of JDK5), so we keep this state here.
+ */
+ private int axis;
+
+ /**
* Creates a new instance. This is package private because the reference
* implementation has no public constructor either. Still, we need to
* call it from BasicVerticalLayoutManager.
*/
BasicHorizontalLayoutManager()
{
- // Nothing to do here.
+ this(SwingConstants.HORIZONTAL);
+ }
+
+ /**
+ * Creates a new instance for a specified axis. This is provided for
+ * compatibility, since the BasicVerticalLayoutManager seems to have
+ * no more implementation in the RI, according to the specs. So
+ * we handle all the axis specific stuff here.
+ *
+ * @param a the axis, either SwingConstants#HORIZONTAL,
+ * or SwingConstants#VERTICAL
+ */
+ BasicHorizontalLayoutManager(int a)
+ {
+ axis = a;
}
/**
@@ -167,7 +189,12 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
protected int getAvailableSize(Dimension containerSize, Insets insets)
{
- return containerSize.width - insets.left - insets.right;
+ int size;
+ if (axis == SwingConstants.HORIZONTAL)
+ size = containerSize.width - insets.left - insets.right;
+ else
+ size = containerSize.height - insets.top - insets.bottom;
+ return size;
}
/**
@@ -180,9 +207,15 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
protected int getInitialLocation(Insets insets)
{
+ int loc = 0;
if (insets != null)
- return insets.left;
- return 0;
+ {
+ if (axis == SwingConstants.HORIZONTAL)
+ loc = insets.left;
+ else
+ loc = insets.top;
+ }
+ return loc;
}
/**
@@ -195,7 +228,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public float getLayoutAlignmentX(Container target)
{
- return target.getAlignmentX();
+ return 0.0f;
}
/**
@@ -208,7 +241,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public float getLayoutAlignmentY(Container target)
{
- return target.getAlignmentY();
+ return 0.0f;
}
/**
@@ -220,10 +253,19 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
protected int getPreferredSizeOfComponent(Component c)
{
+ int size = 0;
Dimension dims = c.getPreferredSize();
- if (dims != null)
- return dims.width;
- return 0;
+ if (axis == SwingConstants.HORIZONTAL)
+ {
+ if (dims != null)
+ size = dims.width;
+ }
+ else
+ {
+ if (dims != null)
+ size = dims.height;
+ }
+ return size;
}
/**
@@ -235,7 +277,12 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
protected int getSizeOfComponent(Component c)
{
- return c.getWidth();
+ int size;
+ if (axis == SwingConstants.HORIZONTAL)
+ size = c.getHeight();
+ else
+ size = c.getWidth();
+ return size;
}
/**
@@ -273,8 +320,17 @@ public class BasicSplitPaneUI extends SplitPaneUI
Dimension dims = split.getSize();
int loc = getInitialLocation(insets);
int available = getAvailableSize(dims, insets);
- sizes[0] = getDividerLocation(split) - loc;
+ sizes[0] = split.getDividerLocation();
sizes[1] = available - sizes[0] - sizes[2];
+
+ // According to a Mauve test we only honour the minimum
+ // size of the components, when the dividerLocation hasn't
+ // been excplicitly set.
+ if (! dividerLocationSet)
+ {
+ sizes[0] = Math.max(sizes[0], minimumSizeOfComponent(0));
+ sizes[1] = Math.max(sizes[1], minimumSizeOfComponent(1));
+ }
// The size of the divider won't change.
// Layout component#1.
@@ -313,27 +369,30 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public Dimension minimumLayoutSize(Container target)
{
+ Dimension dim = new Dimension();
if (target instanceof JSplitPane)
{
- JSplitPane split = (JSplitPane) target;
- Insets insets = target.getInsets();
-
- int height = 0;
- int width = 0;
+ int primary = 0;
+ int secondary = 0;
for (int i = 0; i < components.length; i++)
{
- if (components[i] == null)
- continue;
- Dimension dims = components[i].getMinimumSize();
- if (dims != null)
+ if (components[i] != null)
{
- width += dims.width;
- height = Math.max(height, dims.height);
+ Dimension dims = components[i].getMinimumSize();
+ primary += axis == SwingConstants.HORIZONTAL ? dims.width
+ : dims.height;
+ int sec = axis == SwingConstants.HORIZONTAL ? dims.height
+ : dims.width;
+ secondary = Math.max(sec, secondary);
}
}
- return new Dimension(width, height);
+ int width = axis == SwingConstants.HORIZONTAL ? primary : secondary;
+ int height = axis == SwingConstants.VERTICAL ? secondary : primary;
+
+ Insets i = splitPane.getInsets();
+ dim.setSize(width + i.left + i.right, height + i.top + i.bottom);
}
- return null;
+ return dim;
}
/**
@@ -347,28 +406,30 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public Dimension preferredLayoutSize(Container target)
{
+ Dimension dim = new Dimension();
if (target instanceof JSplitPane)
{
- JSplitPane split = (JSplitPane) target;
- Insets insets = target.getInsets();
-
- int height = 0;
- int width = 0;
+ int primary = 0;
+ int secondary = 0;
for (int i = 0; i < components.length; i++)
{
- if (components[i] == null)
- continue;
- Dimension dims = components[i].getPreferredSize();
- if (dims != null)
+ if (components[i] != null)
{
- width += dims.width;
- if (!(components[i] instanceof BasicSplitPaneDivider))
- height = Math.max(height, dims.height);
+ Dimension dims = components[i].getPreferredSize();
+ primary += axis == SwingConstants.HORIZONTAL ? dims.width
+ : dims.height;
+ int sec = axis == SwingConstants.HORIZONTAL ? dims.height
+ : dims.width;
+ secondary = Math.max(sec, secondary);
}
}
- return new Dimension(width, height);
+ int width = axis == SwingConstants.HORIZONTAL ? primary : secondary;
+ int height = axis == SwingConstants.VERTICAL ? secondary : primary;
+
+ Insets i = splitPane.getInsets();
+ dim.setSize(width + i.left + i.right, height + i.top + i.bottom);
}
- return null;
+ return dim;
}
/**
@@ -406,8 +467,6 @@ public class BasicSplitPaneUI extends SplitPaneUI
{
for (int i = 0; i < components.length; i++)
resetSizeAt(i);
- setDividerLocation(splitPane,
- getInitialLocation(splitPane.getInsets()) + sizes[0]);
}
/**
@@ -425,11 +484,23 @@ public class BasicSplitPaneUI extends SplitPaneUI
protected void setComponentToSize(Component c, int size, int location,
Insets insets, Dimension containerSize)
{
- int w = size;
- int h = containerSize.height - insets.top - insets.bottom;
- int x = location;
- int y = insets.top;
- c.setBounds(x, y, w, h);
+ if (insets != null)
+ {
+ if (axis == SwingConstants.HORIZONTAL)
+ c.setBounds(location, insets.top, size,
+ containerSize.height - insets.top - insets.bottom);
+ else
+ c.setBounds(insets.left, location,
+ containerSize.width - insets.left - insets.right,
+ size);
+ }
+ else
+ {
+ if (axis == SwingConstants.HORIZONTAL)
+ c.setBounds(location, 0, size, containerSize.height);
+ else
+ c.setBounds(0, location, containerSize.width, size);
+ }
}
/**
@@ -462,7 +533,6 @@ public class BasicSplitPaneUI extends SplitPaneUI
resetSizeAt(1);
}
components[2] = divider;
- resetSizeAt(2);
}
/**
@@ -485,10 +555,13 @@ public class BasicSplitPaneUI extends SplitPaneUI
int minimumSizeOfComponent(int index)
{
Dimension dims = components[index].getMinimumSize();
+ int size = 0;
if (dims != null)
- return dims.width;
- else
- return 0;
+ if (axis == SwingConstants.HORIZONTAL)
+ size = dims.width;
+ else
+ size = dims.height;
+ return size;
}
} //end BasicHorizontalLayoutManager
@@ -504,163 +577,11 @@ public class BasicSplitPaneUI extends SplitPaneUI
extends BasicHorizontalLayoutManager
{
/**
- * This method returns the height of the container minus the top and
- * bottom inset.
- *
- * @param containerSize The size of the container.
- * @param insets The insets of the container.
- *
- * @return The height minus top and bottom inset.
- */
- protected int getAvailableSize(Dimension containerSize, Insets insets)
- {
- return containerSize.height - insets.top - insets.bottom;
- }
-
- /**
- * This method returns the top inset.
- *
- * @param insets The Insets to use.
- *
- * @return The top inset.
- */
- protected int getInitialLocation(Insets insets)
- {
- return insets.top;
- }
-
- /**
- * This method returns the preferred height of the component.
- *
- * @param c The component to measure.
- *
- * @return The preferred height of the component.
- */
- protected int getPreferredSizeOfComponent(Component c)
- {
- Dimension dims = c.getPreferredSize();
- if (dims != null)
- return dims.height;
- return 0;
- }
-
- /**
- * This method returns the current height of the component.
- *
- * @param c The component to measure.
- *
- * @return The current height of the component.
- */
- protected int getSizeOfComponent(Component c)
- {
- return c.getHeight();
- }
-
- /**
- * This method returns the minimum layout size. The minimum height is the
- * sum of all the components' minimum heights. The minimum width is the
- * maximum of all the components' minimum widths.
- *
- * @param container The container to measure.
- *
- * @return The minimum size.
+ * Creates a new instance.
*/
- public Dimension minimumLayoutSize(Container container)
+ public BasicVerticalLayoutManager()
{
- if (container instanceof JSplitPane)
- {
- JSplitPane split = (JSplitPane) container;
- Insets insets = container.getInsets();
-
- int height = 0;
- int width = 0;
- for (int i = 0; i < components.length; i++)
- {
- if (components[i] == null)
- continue;
- Dimension dims = components[i].getMinimumSize();
- if (dims != null)
- {
- height += dims.height;
- width = Math.max(width, dims.width);
- }
- }
- return new Dimension(width, height);
- }
- return null;
- }
-
- /**
- * This method returns the preferred layout size. The preferred height is
- * the sum of all the components' preferred heights. The preferred width
- * is the maximum of all the components' preferred widths.
- *
- * @param container The container to measure.
- *
- * @return The preferred size.
- */
- public Dimension preferredLayoutSize(Container container)
- {
- if (container instanceof JSplitPane)
- {
- JSplitPane split = (JSplitPane) container;
- Insets insets = container.getInsets();
-
- int height = 0;
- int width = 0;
- for (int i = 0; i < components.length; i++)
- {
- if (components[i] == null)
- continue;
- Dimension dims = components[i].getPreferredSize();
- if (dims != null)
- {
- height += dims.height;
- width = Math.max(width, dims.width);
- }
- }
- return new Dimension(width, height);
- }
- return null;
- }
-
- /**
- * This method sets the bounds of the given component. The y coordinate is
- * the location given. The x coordinate is the left inset. The height is
- * the size given. The width is the container size minus the left and
- * right inset.
- *
- * @param c The component to set bounds for.
- * @param size The height.
- * @param location The y coordinate.
- * @param insets The insets to use.
- * @param containerSize The container's size.
- */
- protected void setComponentToSize(Component c, int size, int location,
- Insets insets, Dimension containerSize)
- {
- int y = location;
- int x = insets.left;
- int h = size;
- int w = containerSize.width - insets.left - insets.right;
- c.setBounds(x, y, w, h);
- }
-
- /**
- * This method returns the minimum height of the component at the given
- * index.
- *
- * @param index The index of the component to check.
- *
- * @return The minimum height of the given component.
- */
- int minimumSizeOfComponent(int index)
- {
- Dimension dims = components[index].getMinimumSize();
- if (dims != null)
- return dims.height;
- else
- return 0;
+ super(SwingConstants.VERTICAL);
}
}
@@ -941,7 +862,13 @@ public class BasicSplitPaneUI extends SplitPaneUI
/** The JSplitPane that this UI draws. */
protected JSplitPane splitPane;
- private int dividerLocation;
+ /**
+ * True, when setDividerLocation() has been called at least
+ * once on the JSplitPane, false otherwise.
+ *
+ * This is package private to avoid a synthetic accessor method.
+ */
+ boolean dividerLocationSet;
/**
* Creates a new BasicSplitPaneUI object.
@@ -973,6 +900,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
if (c instanceof JSplitPane)
{
splitPane = (JSplitPane) c;
+ dividerLocationSet = false;
installDefaults();
installListeners();
installKeyboardActions();
@@ -990,6 +918,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
uninstallListeners();
uninstallDefaults();
+ dividerLocationSet = false;
splitPane = null;
}
@@ -1007,8 +936,10 @@ public class BasicSplitPaneUI extends SplitPaneUI
nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider();
splitPane.add(divider, JSplitPane.DIVIDER);
- // There is no need to add the nonContinuousLayoutDivider
- splitPane.setDividerSize(UIManager.getInt("SplitPane.dividerSize"));
+ // There is no need to add the nonContinuousLayoutDivider.
+ dividerSize = UIManager.getInt("SplitPane.dividerSize");
+ splitPane.setDividerSize(dividerSize);
+ divider.setDividerSize(dividerSize);
splitPane.setOpaque(true);
}
@@ -1136,8 +1067,10 @@ public class BasicSplitPaneUI extends SplitPaneUI
new AbstractAction("negativeIncrement") {
public void actionPerformed(ActionEvent event)
{
- setDividerLocation(splitPane, Math.max(dividerLocation
- - KEYBOARD_DIVIDER_MOVE_OFFSET, 0));
+ int oldLoc = splitPane.getDividerLocation();
+ int newLoc =
+ Math.max(oldLoc - KEYBOARD_DIVIDER_MOVE_OFFSET, 0);
+ splitPane.setDividerLocation(newLoc);
}
}
);
@@ -1145,8 +1078,10 @@ public class BasicSplitPaneUI extends SplitPaneUI
new AbstractAction("positiveIncrement") {
public void actionPerformed(ActionEvent event)
{
- setDividerLocation(splitPane, dividerLocation
- + KEYBOARD_DIVIDER_MOVE_OFFSET);
+ int oldLoc = splitPane.getDividerLocation();
+ int newLoc =
+ Math.max(oldLoc + KEYBOARD_DIVIDER_MOVE_OFFSET, 0);
+ splitPane.setDividerLocation(newLoc);
}
}
);
@@ -1436,7 +1371,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public void setDividerLocation(JSplitPane jc, int location)
{
- dividerLocation = location;
+ dividerLocationSet = true;
splitPane.revalidate();
splitPane.repaint();
}
@@ -1450,7 +1385,12 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public int getDividerLocation(JSplitPane jc)
{
- return dividerLocation;
+ int loc;
+ if (jc.getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
+ loc = divider.getX();
+ else
+ loc = divider.getY();
+ return loc;
}
/**
@@ -1523,7 +1463,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public Dimension getPreferredSize(JComponent jc)
{
- return layoutManager.preferredLayoutSize((Container) jc);
+ return layoutManager.preferredLayoutSize(jc);
}
/**
@@ -1535,7 +1475,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public Dimension getMinimumSize(JComponent jc)
{
- return layoutManager.minimumLayoutSize((Container) jc);
+ return layoutManager.minimumLayoutSize(jc);
}
/**
@@ -1547,7 +1487,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public Dimension getMaximumSize(JComponent jc)
{
- return layoutManager.maximumLayoutSize((Container) jc);
+ return layoutManager.maximumLayoutSize(jc);
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index 11f25167d21..0d1fa1eed9b 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -76,7 +76,6 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
-import javax.swing.plaf.PanelUI;
import javax.swing.plaf.TabbedPaneUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.View;
@@ -252,7 +251,16 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
public void mouseReleased(MouseEvent e)
{
- // Nothing to do here.
+ Object s = e.getSource();
+
+ // Event may originate from the viewport in
+ // SCROLL_TAB_LAYOUT mode. It is redisptached
+ // through the tabbed pane then.
+ if (tabPane != e.getSource())
+ {
+ redispatchEvent(e);
+ e.setSource(s);
+ }
}
/**
@@ -264,6 +272,16 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
public void mousePressed(MouseEvent e)
{
Object s = e.getSource();
+
+ // Event may originate from the viewport in
+ // SCROLL_TAB_LAYOUT mode. It is redisptached
+ // through the tabbed pane then.
+ if (tabPane != e.getSource())
+ {
+ redispatchEvent(e);
+ e.setSource(s);
+ }
+
int placement = tabPane.getTabPlacement();
if (s == incrButton)
@@ -298,47 +316,61 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
if(!decrButton.isEnabled())
return;
- // The scroll location may be zero but the offset
- // greater than zero because of an adjustement to
- // make a partially visible tab completely visible.
- if (currentScrollLocation > 0)
- currentScrollLocation--;
-
- // Set the offset back to 0 and recompute it.
- currentScrollOffset = 0;
-
- switch (placement)
- {
- case JTabbedPane.TOP:
- case JTabbedPane.BOTTOM:
- // Take the tab area inset into account.
- if (currentScrollLocation > 0)
- currentScrollOffset = getTabAreaInsets(placement).left;
- // Recompute scroll offset.
- for (int i = 0; i < currentScrollLocation; i++)
- currentScrollOffset += rects[i].width;
- break;
- default:
- // Take the tab area inset into account.
- if (currentScrollLocation > 0)
- currentScrollOffset = getTabAreaInsets(placement).top;
+ // The scroll location may be zero but the offset
+ // greater than zero because of an adjustement to
+ // make a partially visible tab completely visible.
+ if (currentScrollLocation > 0)
+ currentScrollLocation--;
- for (int i = 0; i < currentScrollLocation; i++)
- currentScrollOffset += rects[i].height;
- }
+ // Set the offset back to 0 and recompute it.
+ currentScrollOffset = 0;
+
+ switch (placement)
+ {
+ case JTabbedPane.TOP:
+ case JTabbedPane.BOTTOM:
+ // Take the tab area inset into account.
+ if (currentScrollLocation > 0)
+ currentScrollOffset = getTabAreaInsets(placement).left;
+ // Recompute scroll offset.
+ for (int i = 0; i < currentScrollLocation; i++)
+ currentScrollOffset += rects[i].width;
+ break;
+ default:
+ // Take the tab area inset into account.
+ if (currentScrollLocation > 0)
+ currentScrollOffset = getTabAreaInsets(placement).top;
+
+ for (int i = 0; i < currentScrollLocation; i++)
+ currentScrollOffset += rects[i].height;
+ }
- updateViewPosition();
- updateButtons();
+ updateViewPosition();
+ updateButtons();
- tabPane.repaint();
- } else if (tabPane.isEnabled())
+ tabPane.repaint();
+ }
+ else if (tabPane.isEnabled())
{
int index = tabForCoordinate(tabPane, e.getX(), e.getY());
+ if (!tabPane.isEnabledAt(index))
+ return;
+
if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT
&& s == panel)
+ {
scrollTab(index, placement);
+
+ tabPane.setSelectedIndex(index);
+ tabPane.repaint();
+ }
+ else
+ {
+ tabPane.setSelectedIndex(index);
+ tabPane.revalidate();
+ tabPane.repaint();
+ }
- tabPane.setSelectedIndex(index);
}
}
@@ -347,11 +379,22 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* Receives notification when the mouse pointer has entered the tabbed
* pane.
*
- * @param ev the mouse event
+ * @param e the mouse event
*/
- public void mouseEntered(MouseEvent ev)
+ public void mouseEntered(MouseEvent e)
{
- int tabIndex = tabForCoordinate(tabPane, ev.getX(), ev.getY());
+ Object s = e.getSource();
+
+ // Event may originate from the viewport in
+ // SCROLL_TAB_LAYOUT mode. It is redisptached
+ // through the tabbed pane then.
+ if (tabPane != e.getSource())
+ {
+ redispatchEvent(e);
+ e.setSource(s);
+ }
+
+ int tabIndex = tabForCoordinate(tabPane, e.getX(), e.getY());
setRolloverTab(tabIndex);
}
@@ -359,10 +402,21 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* Receives notification when the mouse pointer has exited the tabbed
* pane.
*
- * @param ev the mouse event
+ * @param e the mouse event
*/
- public void mouseExited(MouseEvent ev)
+ public void mouseExited(MouseEvent e)
{
+ Object s = e.getSource();
+
+ // Event may originate from the viewport in
+ // SCROLL_TAB_LAYOUT mode. It is redisptached
+ // through the tabbed pane then.
+ if (tabPane != e.getSource())
+ {
+ redispatchEvent(e);
+ e.setSource(s);
+ }
+
setRolloverTab(-1);
}
@@ -374,9 +428,37 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void mouseMoved(MouseEvent ev)
{
+ Object s = ev.getSource();
+
+ if (tabPane != ev.getSource())
+ {
+ ev.setSource(tabPane);
+ tabPane.dispatchEvent(ev);
+
+ ev.setSource(s);
+ }
+
int tabIndex = tabForCoordinate(tabPane, ev.getX(), ev.getY());
setRolloverTab(tabIndex);
}
+
+ /** Modifies the mouse event to originate from
+ * the tabbed pane and redispatches it.
+ *
+ * @param me
+ */
+ void redispatchEvent(MouseEvent me)
+ {
+ me.setSource(tabPane);
+ Point viewPos = viewport.getViewPosition();
+ viewPos.x -= viewport.getX();
+ viewPos.y -= viewport.getY();
+ me.translatePoint(-viewPos.x, -viewPos.y);
+ tabPane.dispatchEvent(me);
+
+ me.translatePoint(viewPos.x, viewPos.y);
+ }
+
}
/**
@@ -396,20 +478,56 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void propertyChange(PropertyChangeEvent e)
{
- if (e.getPropertyName().equals("tabLayoutPolicy"))
+ out:
{
- currentScrollLocation = currentScrollOffset = 0;
-
- layoutManager = createLayoutManager();
-
- tabPane.setLayout(layoutManager);
- }
- else if (e.getPropertyName().equals("tabPlacement")
- && tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
- {
- incrButton = createIncreaseButton();
- decrButton = createDecreaseButton();
+ if (e.getPropertyName().equals("tabLayoutPolicy"))
+ {
+ currentScrollLocation = currentScrollOffset = 0;
+
+ layoutManager = createLayoutManager();
+
+ tabPane.setLayout(layoutManager);
+ }
+ else if (e.getPropertyName().equals("tabPlacement")
+ && tabPane.getTabLayoutPolicy()
+ == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ incrButton = createIncreaseButton();
+ decrButton = createDecreaseButton();
+
+ // If the tab placement value was changed of a tabbed pane
+ // in SCROLL_TAB_LAYOUT mode we investigate the change to
+ // implement the following behavior which was observed in
+ // the RI:
+ // The scrolling offset will be reset if we change to
+ // a direction which is orthogonal to the current
+ // direction and stays the same if it is parallel.
+
+ int oldPlacement = ((Integer) e.getOldValue()).intValue();
+ int newPlacement = ((Integer) e.getNewValue()).intValue();
+ switch (newPlacement)
+ {
+ case JTabbedPane.TOP:
+ case JTabbedPane.BOTTOM:
+ if (oldPlacement == JTabbedPane.TOP
+ || oldPlacement == JTabbedPane.BOTTOM)
+ break out;
+
+ currentScrollOffset = getTabAreaInsets(newPlacement).left;
+ break;
+ default:
+ if (oldPlacement == JTabbedPane.LEFT
+ || oldPlacement == JTabbedPane.RIGHT)
+ break out;
+
+ currentScrollOffset = getTabAreaInsets(newPlacement).top;
+ }
+
+ updateViewPosition();
+ updateButtons();
+ }
}
+
tabPane.revalidate();
tabPane.repaint();
}
@@ -784,6 +902,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
default:
tabAreaHeight = calculateTabAreaHeight(tabPlacement, runCount,
maxTabHeight);
+
compX = insets.left + contentBorderInsets.left;
compY = tabAreaHeight + insets.top + contentBorderInsets.top;
}
@@ -838,83 +957,51 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected void normalizeTabRuns(int tabPlacement, int tabCount, int start,
int max)
{
- Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
- if (tabPlacement == SwingUtilities.TOP
- || tabPlacement == SwingUtilities.BOTTOM)
+ boolean horizontal = tabPlacement == TOP || tabPlacement == BOTTOM;
+ int currentRun = runCount - 1;
+ double weight = 1.25;
+ for (boolean adjust = true; adjust == true;)
{
- // We should only do this for runCount - 1, cause we can
- // only shift that many times between runs.
- for (int i = 1; i < runCount; i++)
+ int last = lastTabInRun(tabCount, currentRun);
+ int prevLast = lastTabInRun(tabCount, currentRun - 1);
+ int end;
+ int prevLength;
+ if (horizontal)
{
- Rectangle currRun = rects[lastTabInRun(tabCount, i)];
- Rectangle nextRun = rects[lastTabInRun(tabCount,
- getNextTabRun(i))];
- int spaceInCurr = currRun.x + currRun.width;
- int spaceInNext = nextRun.x + nextRun.width;
-
- int diffNow = spaceInCurr - spaceInNext;
- int diffLater = (spaceInCurr - currRun.width)
- - (spaceInNext + currRun.width);
-
- while (Math.abs(diffLater) < Math.abs(diffNow)
- && spaceInNext + currRun.width < max)
- {
- tabRuns[i]--;
- spaceInNext += currRun.width;
- spaceInCurr -= currRun.width;
- currRun = rects[lastTabInRun(tabCount, i)];
- diffNow = spaceInCurr - spaceInNext;
- diffLater = (spaceInCurr - currRun.width)
- - (spaceInNext + currRun.width);
- }
-
- // Fixes the bounds of all tabs in the current
- // run.
- int first = tabRuns[i];
- int last = lastTabInRun(tabCount, i);
- int currX = start;
- for (int j = first; j <= last; j++)
- {
- rects[j].x = currX;
- currX += rects[j].width;
- }
+ end = rects[last].x + rects[last].width;
+ prevLength = (int) (maxTabWidth * weight);
}
- }
- else
- {
- for (int i = 1; i < runCount; i++)
+ else
{
- Rectangle currRun = rects[lastTabInRun(tabCount, i)];
- Rectangle nextRun = rects[lastTabInRun(tabCount,
- getNextTabRun(i))];
- int spaceInCurr = currRun.y + currRun.height;
- int spaceInNext = nextRun.y + nextRun.height;
-
- int diffNow = spaceInCurr - spaceInNext;
- int diffLater = (spaceInCurr - currRun.height)
- - (spaceInNext + currRun.height);
- while (Math.abs(diffLater) < Math.abs(diffNow)
- && spaceInNext + currRun.height < max)
- {
- tabRuns[i]--;
- spaceInNext += currRun.height;
- spaceInCurr -= currRun.height;
- currRun = rects[lastTabInRun(tabCount, i)];
- diffNow = spaceInCurr - spaceInNext;
- diffLater = (spaceInCurr - currRun.height)
- - (spaceInNext + currRun.height);
- }
-
- // Fixes the bounds of tabs in the current run.
- int first = tabRuns[i];
- int last = lastTabInRun(tabCount, i);
- int currY = start;
- for (int j = first; j <= last; j++)
+ end = rects[last].y + rects[last].height;
+ prevLength = (int) (maxTabWidth * weight * 2);
+ }
+ if (max - end > prevLength)
+ {
+ tabRuns[currentRun] = prevLast;
+ if (horizontal)
+ rects[prevLast].x = start;
+ else
+ rects[prevLast].y = start;
+ for (int i = prevLast + 1; i <= last; i++)
{
- rects[j].y = currY;
- currY += rects[j].height;
+ if (horizontal)
+ rects[i].x = rects[i - 1].x + rects[i - 1].width;
+ else
+ rects[i].y = rects[i - 1].y + rects[i - 1].height;
}
}
+ else if (currentRun == runCount - 1)
+ adjust = false;
+ if (currentRun - 1 > 0)
+ currentRun -= 1;
+ else
+ {
+ // Check again, but with higher ratio to avoid
+ // clogging up the last run.
+ currentRun = runCount - 1;
+ weight += 0.25;
+ }
}
}
@@ -1325,7 +1412,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
super.layoutContainer(pane);
int tabCount = tabPane.getTabCount();
- Point p = null;
if (tabCount == 0)
return;
int tabPlacement = tabPane.getTabPlacement();
@@ -1512,7 +1598,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void updateUI()
{
- setUI((PanelUI) new ScrollingPanelUI());
+ setUI(new ScrollingPanelUI());
}
}
@@ -1892,15 +1978,19 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
final void updateViewPosition()
{
Point p = viewport.getViewPosition();
-
+
+ // The unneeded coordinate must be set to zero
+ // in order to correctly handle placement changes.
switch (tabPane.getTabPlacement())
{
case JTabbedPane.LEFT:
case JTabbedPane.RIGHT:
+ p.x = 0;
p.y = currentScrollOffset;
break;
default:
p.x = currentScrollOffset;
+ p.y = 0;
}
viewport.setViewPosition(p);
@@ -2331,7 +2421,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
paintTabBorder(g, tabPlacement, tabIndex, rect.x, rect.y, rect.width,
rect.height, isSelected);
-
// Layout label.
FontMetrics fm = getFontMetrics();
Icon icon = getIconForTab(tabIndex);
@@ -2369,7 +2458,17 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Rectangle tabRect, Rectangle iconRect,
Rectangle textRect, boolean isSelected)
{
- SwingUtilities.layoutCompoundLabel(metrics, title, icon,
+ // Reset the icon and text rectangles, as the result is not specified
+ // when the locations are not (0,0).
+ textRect.x = 0;
+ textRect.y = 0;
+ textRect.width = 0;
+ textRect.height = 0;
+ iconRect.x = 0;
+ iconRect.y = 0;
+ iconRect.width = 0;
+ iconRect.height = 0;
+ SwingUtilities.layoutCompoundLabel(tabPane, metrics, title, icon,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
@@ -2764,7 +2863,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int width = tabPane.getWidth();
int height = tabPane.getHeight();
Insets insets = tabPane.getInsets();
- Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
// Calculate coordinates of content area.
int x = insets.left;
@@ -2869,8 +2967,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int endgap = rects[selectedIndex].y + rects[selectedIndex].height
- currentScrollOffset;
- int diff = 0;
-
if (tabPlacement == SwingConstants.LEFT && startgap >= 0)
{
g.drawLine(x, y, x, startgap);
@@ -2957,8 +3053,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int endgap = rects[selectedIndex].y + rects[selectedIndex].height
- currentScrollOffset;
- int diff = 0;
-
if (tabPlacement == SwingConstants.RIGHT && startgap >= 0)
{
g.setColor(shadow);
@@ -2988,8 +3082,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
}
/**
- * This method returns the tab bounds for the given index.
- *
+ * <p>This method returns the bounds of a tab for the given index
+ * and shifts it by the current scrolling offset if the tabbed
+ * pane is in scrolling tab layout mode.</p>
+ *
+ * <p>Subclassses should retrievs a tab's bounds by this method
+ * if they want to find out whether the tab is currently visible.</p>
+ *
* @param pane The JTabbedPane.
* @param i The index to look for.
*
@@ -3000,6 +3099,26 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// Need to re-layout container if tab does not exist.
if (i >= rects.length)
layoutManager.layoutContainer(pane);
+
+ // Properly shift coordinates if scrolling has taken
+ // place.
+ if (pane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ Rectangle r = new Rectangle(rects[i]);
+
+ switch(pane.getTabPlacement())
+ {
+ case SwingConstants.TOP:
+ case SwingConstants.BOTTOM:
+ r.x -= currentScrollOffset;
+ break;
+ default:
+ r.y -= currentScrollOffset;
+ }
+
+ return r;
+ }
+
return rects[i];
}
@@ -3048,7 +3167,10 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
}
/**
- * This method returns the tab bounds in the given rectangle.
+ * <p>This method returns the tab bounds in the given rectangle.</p>
+ *
+ * <p>The returned rectangle will be shifted by the current scroll
+ * offset if the tabbed pane is in scrolling tab layout mode.</p>.
*
* @param tabIndex The index to get bounds for.
* @param dest The rectangle to store bounds in.
@@ -3324,21 +3446,20 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Icon icon = getIconForTab(tabIndex);
Insets insets = getTabInsets(tabPlacement, tabIndex);
- int width = 0;
+ int width = insets.bottom + insets.right + 3;
if (icon != null)
{
- Rectangle vr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
- layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
- tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
- tabIndex == tabPane.getSelectedIndex());
- width = tr.union(ir).width;
+ width += icon.getIconWidth() + textIconGap;
}
- else
- width = metrics.stringWidth(tabPane.getTitleAt(tabIndex));
- width += insets.left + insets.right;
+ View v = getTextViewForTab(tabIndex);
+ if (v != null)
+ width += v.getPreferredSpan(View.X_AXIS);
+ else
+ {
+ String label = tabPane.getTitleAt(tabIndex);
+ width += metrics.stringWidth(label);
+ }
return width;
}
@@ -3377,7 +3498,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
Insets insets = getTabAreaInsets(tabPlacement);
int tabAreaHeight = horizRunCount * maxTabHeight
- - (horizRunCount - 1) * tabRunOverlay;
+ - (horizRunCount - 1)
+ * getTabRunOverlay(tabPlacement);
tabAreaHeight += insets.top + insets.bottom;
@@ -3399,7 +3521,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
Insets insets = getTabAreaInsets(tabPlacement);
int tabAreaWidth = vertRunCount * maxTabWidth
- - (vertRunCount - 1) * tabRunOverlay;
+ - (vertRunCount - 1)
+ * getTabRunOverlay(tabPlacement);
tabAreaWidth += insets.left + insets.right;
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java
index abe7cab43b3..8a8eeb837fe 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
@@ -415,9 +413,8 @@ public class BasicTableHeaderUI extends TableHeaderUI
}
protected void installKeyboardActions()
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ // AFAICS, the RI does nothing here.
}
/**
@@ -448,9 +445,8 @@ public class BasicTableHeaderUI extends TableHeaderUI
}
protected void uninstallKeyboardActions()
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ // AFAICS, the RI does nothing here.
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
index 15be4d57e62..a672173c725 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
@@ -443,11 +443,14 @@ public class BasicTableUI extends TableUI
public Dimension getPreferredSize(JComponent comp)
{
int prefTotalColumnWidth = 0;
- for (int i = 0; i < table.getColumnCount(); i++)
+ TableColumnModel tcm = table.getColumnModel();
+
+ for (int i = 0; i < tcm.getColumnCount(); i++)
{
- TableColumn col = table.getColumnModel().getColumn(i);
+ TableColumn col = tcm.getColumn(i);
prefTotalColumnWidth += col.getPreferredWidth();
}
+
return new Dimension(prefTotalColumnWidth, getHeight());
}
@@ -455,7 +458,7 @@ public class BasicTableUI extends TableUI
* 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()
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
index 8e9c8c949f3..e152a3034d5 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.SystemProperties;
+
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
@@ -71,6 +73,7 @@ import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TextUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.AbstractDocument;
+import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
@@ -120,6 +123,140 @@ public abstract class BasicTextUI extends TextUI
}
}
+ private static class FocusHandler
+ implements FocusListener
+ {
+ public void focusGained(FocusEvent e)
+ {
+ // Nothing to do here.
+ }
+ public void focusLost(FocusEvent e)
+ {
+ JTextComponent textComponent = (JTextComponent) e.getComponent();
+ // Integrates Swing text components with the system clipboard:
+ // The idea is that if one wants to copy text around X11-style
+ // (select text and middle-click in the target component) the focus
+ // will move to the new component which gives the old focus owner the
+ // possibility to paste its selection into the clipboard.
+ if (!e.isTemporary()
+ && textComponent.getSelectionStart()
+ != textComponent.getSelectionEnd())
+ {
+ SecurityManager sm = System.getSecurityManager();
+ try
+ {
+ if (sm != null)
+ sm.checkSystemClipboardAccess();
+
+ Clipboard cb = Toolkit.getDefaultToolkit().getSystemSelection();
+ if (cb != null)
+ {
+ StringSelection selection = new StringSelection(
+ textComponent.getSelectedText());
+ cb.setContents(selection, selection);
+ }
+ }
+ catch (SecurityException se)
+ {
+ // Not allowed to access the clipboard: Ignore and
+ // do not access it.
+ }
+ catch (HeadlessException he)
+ {
+ // There is no AWT: Ignore and do not access the
+ // clipboard.
+ }
+ catch (IllegalStateException ise)
+ {
+ // Clipboard is currently unavaible.
+ }
+ }
+ }
+ }
+
+ /**
+ * This FocusListener triggers repaints on focus shift.
+ */
+ private static FocusListener focusListener;
+
+ /**
+ * Receives notifications when properties of the text component change.
+ */
+ private class Handler
+ implements PropertyChangeListener, DocumentListener
+ {
+ /**
+ * Notifies when a property of the text component changes.
+ *
+ * @param event the PropertyChangeEvent describing the change
+ */
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ if (event.getPropertyName().equals("document"))
+ {
+ // Document changed.
+ Object oldValue = event.getOldValue();
+ if (oldValue != null)
+ {
+ Document oldDoc = (Document) oldValue;
+ oldDoc.removeDocumentListener(handler);
+ }
+ Object newValue = event.getNewValue();
+ if (newValue != null)
+ {
+ Document newDoc = (Document) newValue;
+ newDoc.addDocumentListener(handler);
+ }
+ modelChanged();
+ }
+
+ BasicTextUI.this.propertyChange(event);
+ }
+
+ /**
+ * Notification about a document change event.
+ *
+ * @param ev the DocumentEvent describing the change
+ */
+ public void changedUpdate(DocumentEvent ev)
+ {
+ // Updates are forwarded to the View even if 'getVisibleEditorRect'
+ // method returns null. This means the View classes have to be
+ // aware of that possibility.
+ rootView.changedUpdate(ev, getVisibleEditorRect(),
+ rootView.getViewFactory());
+ }
+
+ /**
+ * Notification about a document insert event.
+ *
+ * @param ev the DocumentEvent describing the insertion
+ */
+ public void insertUpdate(DocumentEvent ev)
+ {
+ // Updates are forwarded to the View even if 'getVisibleEditorRect'
+ // method returns null. This means the View classes have to be
+ // aware of that possibility.
+ rootView.insertUpdate(ev, getVisibleEditorRect(),
+ rootView.getViewFactory());
+ }
+
+ /**
+ * Notification about a document removal event.
+ *
+ * @param ev the DocumentEvent describing the removal
+ */
+ public void removeUpdate(DocumentEvent ev)
+ {
+ // Updates are forwarded to the View even if 'getVisibleEditorRect'
+ // method returns null. This means the View classes have to be
+ // aware of that possibility.
+ rootView.removeUpdate(ev, getVisibleEditorRect(),
+ rootView.getViewFactory());
+ }
+
+ }
+
/**
* This view forms the root of the View hierarchy. However, it delegates
* most calls to another View which is the real root of the hierarchy.
@@ -226,19 +363,14 @@ public abstract class BasicTextUI extends TextUI
}
/**
- * Returns the preferred span along the specified <code>axis</code>.
- * This is delegated to the real root view.
- *
- * @param axis the axis for which the preferred span is queried
- *
- * @return the preferred span along the axis
+ * Sets the size of the renderer. This is synchronized because that
+ * potentially triggers layout and we don't want more than one thread
+ * playing with the layout information.
*/
- public float getPreferredSpan(int axis)
+ public synchronized void setSize(float w, float h)
{
if (view != null)
- return view.getPreferredSpan(axis);
-
- return Integer.MAX_VALUE;
+ view.setSize(w, h);
}
/**
@@ -251,8 +383,8 @@ public abstract class BasicTextUI extends TextUI
{
if (view != null)
{
- Rectangle b = s.getBounds();
- view.setSize(b.width, b.height);
+ Rectangle b = s instanceof Rectangle ? (Rectangle) s : s.getBounds();
+ setSize(b.width, b.height);
view.paint(g, s);
}
}
@@ -312,7 +444,8 @@ public abstract class BasicTextUI extends TextUI
*/
public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
- view.insertUpdate(ev, shape, vf);
+ if (view != null)
+ view.insertUpdate(ev, shape, vf);
}
/**
@@ -325,7 +458,8 @@ public abstract class BasicTextUI extends TextUI
*/
public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
- view.removeUpdate(ev, shape, vf);
+ if (view != null)
+ view.removeUpdate(ev, shape, vf);
}
/**
@@ -338,7 +472,8 @@ public abstract class BasicTextUI extends TextUI
*/
public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
{
- view.changedUpdate(ev, shape, vf);
+ if (view != null)
+ view.changedUpdate(ev, shape, vf);
}
/**
@@ -400,116 +535,73 @@ public abstract class BasicTextUI extends TextUI
{
return textComponent.getDocument();
}
- }
- /**
- * Receives notifications when properties of the text component change.
- */
- private class PropertyChangeHandler implements PropertyChangeListener
- {
/**
- * Notifies when a property of the text component changes.
- *
- * @param event the PropertyChangeEvent describing the change
+ * Returns the attributes, which is null for the RootView.
*/
- public void propertyChange(PropertyChangeEvent event)
+ public AttributeSet getAttributes()
{
- if (event.getPropertyName().equals("document"))
- {
- // Document changed.
- Object oldValue = event.getOldValue();
- if (oldValue != null)
- {
- Document oldDoc = (Document) oldValue;
- oldDoc.removeDocumentListener(documentHandler);
- }
- Object newValue = event.getNewValue();
- if (newValue != null)
- {
- Document newDoc = (Document) newValue;
- newDoc.addDocumentListener(documentHandler);
- }
- modelChanged();
- }
-
- BasicTextUI.this.propertyChange(event);
+ return null;
}
- }
- /**
- * Listens for changes on the underlying model and forwards notifications
- * to the View. This also updates the caret position of the text component.
- *
- * TODO: Maybe this should somehow be handled through EditorKits
- */
- class DocumentHandler implements DocumentListener
- {
/**
- * Notification about a document change event.
- *
- * @param ev the DocumentEvent describing the change
+ * Overridden to forward to the view.
*/
- public void changedUpdate(DocumentEvent ev)
+ public float getPreferredSpan(int axis)
{
- // Updates are forwarded to the View even if 'getVisibleEditorRect'
- // method returns null. This means the View classes have to be
- // aware of that possibility.
- rootView.changedUpdate(ev, getVisibleEditorRect(),
- rootView.getViewFactory());
+ // The RI returns 10 in the degenerate case.
+ float span = 10;
+ if (view != null)
+ span = view.getPreferredSpan(axis);
+ return span;
}
/**
- * Notification about a document insert event.
- *
- * @param ev the DocumentEvent describing the insertion
+ * Overridden to forward to the real view.
*/
- public void insertUpdate(DocumentEvent ev)
+ public float getMinimumSpan(int axis)
{
- // Updates are forwarded to the View even if 'getVisibleEditorRect'
- // method returns null. This means the View classes have to be
- // aware of that possibility.
- rootView.insertUpdate(ev, getVisibleEditorRect(),
- rootView.getViewFactory());
+ // The RI returns 10 in the degenerate case.
+ float span = 10;
+ if (view != null)
+ span = view.getMinimumSpan(axis);
+ return span;
}
/**
- * Notification about a document removal event.
- *
- * @param ev the DocumentEvent describing the removal
+ * Overridden to return Integer.MAX_VALUE.
*/
- public void removeUpdate(DocumentEvent ev)
+ public float getMaximumSpan(int axis)
{
- // Updates are forwarded to the View even if 'getVisibleEditorRect'
- // method returns null. This means the View classes have to be
- // aware of that possibility.
- rootView.removeUpdate(ev, getVisibleEditorRect(),
- rootView.getViewFactory());
+ // The RI returns Integer.MAX_VALUE here, regardless of the real view's
+ // maximum size.
+ return Integer.MAX_VALUE;
}
}
/**
* The EditorKit used by this TextUI.
*/
- // FIXME: should probably be non-static.
- static EditorKit kit = new DefaultEditorKit();
+ private static EditorKit kit;
/**
- * The root view.
+ * The combined event handler for text components.
+ *
+ * This is package private to avoid accessor methods.
*/
- RootView rootView = new RootView();
+ Handler handler;
/**
- * The text component that we handle.
+ * The root view.
+ *
+ * This is package private to avoid accessor methods.
*/
- JTextComponent textComponent;
+ RootView rootView;
/**
- * Receives notification when the model changes.
+ * The text component that we handle.
*/
- private PropertyChangeHandler updateHandler = new PropertyChangeHandler();
-
- /** The DocumentEvent handler. */
- DocumentHandler documentHandler = new DocumentHandler();
+ JTextComponent textComponent;
/**
* Creates a new <code>BasicTextUI</code> instance.
@@ -558,17 +650,31 @@ public abstract class BasicTextUI extends TextUI
public void installUI(final JComponent c)
{
textComponent = (JTextComponent) c;
+
+ if (rootView == null)
+ rootView = new RootView();
+
installDefaults();
- textComponent.addPropertyChangeListener(updateHandler);
+ installFixedDefaults();
+
+ // These listeners must be installed outside of installListeners(),
+ // because overriding installListeners() doesn't prevent installing
+ // these in the RI, but overriding isntallUI() does.
+ if (handler == null)
+ handler = new Handler();
+ textComponent.addPropertyChangeListener(handler);
Document doc = textComponent.getDocument();
if (doc == null)
{
+ // The Handler takes care of installing the necessary listeners
+ // on the document here.
doc = getEditorKit(textComponent).createDefaultDocument();
textComponent.setDocument(doc);
}
else
{
- doc.addDocumentListener(documentHandler);
+ // Must install the document listener.
+ doc.addDocumentListener(handler);
modelChanged();
}
@@ -586,7 +692,6 @@ public abstract class BasicTextUI extends TextUI
LookAndFeel.installColorsAndFont(textComponent, prefix + ".background",
prefix + ".foreground", prefix + ".font");
LookAndFeel.installBorder(textComponent, prefix + ".border");
- textComponent.setMargin(UIManager.getInsets(prefix + ".margin"));
// Some additional text component only properties.
Color color = textComponent.getCaretColor();
@@ -600,7 +705,7 @@ public abstract class BasicTextUI extends TextUI
color = textComponent.getDisabledTextColor();
if (color == null || color instanceof UIResource)
{
- color = UIManager.getColor(prefix + ".inactiveBackground");
+ color = UIManager.getColor(prefix + ".inactiveForeground");
textComponent.setDisabledTextColor(color);
}
color = textComponent.getSelectedTextColor();
@@ -623,6 +728,15 @@ public abstract class BasicTextUI extends TextUI
textComponent.setMargin(margin);
}
+ }
+
+ /**
+ * Installs defaults that can't be overridden by overriding
+ * installDefaults().
+ */
+ private void installFixedDefaults()
+ {
+ String prefix = getPropertyPrefix();
Caret caret = textComponent.getCaret();
if (caret == null || caret instanceof UIResource)
{
@@ -638,64 +752,18 @@ public abstract class BasicTextUI extends TextUI
}
/**
- * This FocusListener triggers repaints on focus shift.
- */
- private FocusListener focuslistener = new FocusListener() {
- public void focusGained(FocusEvent e)
- {
- textComponent.repaint();
- }
- public void focusLost(FocusEvent e)
- {
- textComponent.repaint();
-
- // Integrates Swing text components with the system clipboard:
- // The idea is that if one wants to copy text around X11-style
- // (select text and middle-click in the target component) the focus
- // will move to the new component which gives the old focus owner the
- // possibility to paste its selection into the clipboard.
- if (!e.isTemporary()
- && textComponent.getSelectionStart()
- != textComponent.getSelectionEnd())
- {
- SecurityManager sm = System.getSecurityManager();
- try
- {
- if (sm != null)
- sm.checkSystemClipboardAccess();
-
- Clipboard cb = Toolkit.getDefaultToolkit().getSystemSelection();
- if (cb != null)
- {
- StringSelection selection = new StringSelection(
- textComponent.getSelectedText());
- cb.setContents(selection, selection);
- }
- }
- catch (SecurityException se)
- {
- // Not allowed to access the clipboard: Ignore and
- // do not access it.
- }
- catch (HeadlessException he)
- {
- // There is no AWT: Ignore and do not access the
- // clipboard.
- }
- catch (IllegalStateException ise)
- {
- // Clipboard is currently unavaible.
- }
- }
- }
- };
-
- /**
* Install all listeners on the text component.
*/
protected void installListeners()
{
- textComponent.addFocusListener(focuslistener);
+ //
+ if (SystemProperties.getProperty("gnu.swing.text.no-xlike-clipboard")
+ == null)
+ {
+ if (focusListener == null)
+ focusListener = new FocusHandler();
+ textComponent.addFocusListener(focusListener);
+ }
}
/**
@@ -834,10 +902,12 @@ public abstract class BasicTextUI extends TextUI
*/
public void uninstallUI(final JComponent component)
{
- super.uninstallUI(component);
+ textComponent.removePropertyChangeListener(handler);
+ textComponent.getDocument().removeDocumentListener(handler);
rootView.setView(null);
uninstallDefaults();
+ uninstallFixedDefaults();
uninstallListeners();
uninstallKeyboardActions();
@@ -850,7 +920,29 @@ public abstract class BasicTextUI extends TextUI
*/
protected void uninstallDefaults()
{
- // Do nothing here.
+ if (textComponent.getCaretColor() instanceof UIResource)
+ textComponent.setCaretColor(null);
+ if (textComponent.getSelectionColor() instanceof UIResource)
+ textComponent.setSelectionColor(null);
+ if (textComponent.getDisabledTextColor() instanceof UIResource)
+ textComponent.setDisabledTextColor(null);
+ if (textComponent.getSelectedTextColor() instanceof UIResource)
+ textComponent.setSelectedTextColor(null);
+ LookAndFeel.uninstallBorder(textComponent);
+ if (textComponent.getMargin() instanceof UIResource)
+ textComponent.setMargin(null);
+ }
+
+ /**
+ * Uninstalls additional fixed defaults that were installed
+ * by installFixedDefaults().
+ */
+ private void uninstallFixedDefaults()
+ {
+ if (textComponent.getCaret() instanceof UIResource)
+ textComponent.setCaret(null);
+ if (textComponent.getHighlighter() instanceof UIResource)
+ textComponent.setHighlighter(null);
}
/**
@@ -859,7 +951,10 @@ public abstract class BasicTextUI extends TextUI
*/
protected void uninstallListeners()
{
- textComponent.removeFocusListener(focuslistener);
+ // Don't nullify the focusListener field, as it is static and shared
+ // between components.
+ if (focusListener != null)
+ textComponent.removeFocusListener(focusListener);
}
/**
@@ -891,14 +986,38 @@ public abstract class BasicTextUI extends TextUI
*/
public Dimension getPreferredSize(JComponent c)
{
- View v = getRootView(textComponent);
-
- float w = v.getPreferredSpan(View.X_AXIS);
- float h = v.getPreferredSpan(View.Y_AXIS);
-
+ Dimension d = c.getSize();
Insets i = c.getInsets();
- return new Dimension((int) w + i.left + i.right,
+ // We need to lock here, since we require the view hierarchy to _not_
+ // change in between.
+ float w;
+ float h;
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readLock();
+ try
+ {
+ if (d.width > (i.left + i.right) && d.height > (i.top + i.bottom))
+ {
+ rootView.setSize(d.width - i.left - i.right,
+ d.height - i.top - i.bottom);
+ }
+ else
+ {
+ // Not laid out yet. Force some pseudo size.
+ rootView.setSize(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+ w = rootView.getPreferredSpan(View.X_AXIS);
+ h = rootView.getPreferredSpan(View.Y_AXIS);
+ }
+ finally
+ {
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readUnlock();
+ }
+ Dimension size = new Dimension((int) w + i.left + i.right,
(int) h + i.top + i.bottom);
+ return size;
}
/**
@@ -912,8 +1031,27 @@ public abstract class BasicTextUI extends TextUI
*/
public Dimension getMaximumSize(JComponent c)
{
- // Sun's implementation returns Integer.MAX_VALUE here, so do we.
- return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ Dimension d = new Dimension();
+ Insets i = c.getInsets();
+ Document doc = textComponent.getDocument();
+ // We need to lock here, since we require the view hierarchy to _not_
+ // change in between.
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readLock();
+ try
+ {
+ // Check for overflow here.
+ d.width = (int) Math.min((long) rootView.getMaximumSpan(View.X_AXIS)
+ + i.left + i.right, Integer.MAX_VALUE);
+ d.height = (int) Math.min((long) rootView.getMaximumSpan(View.Y_AXIS)
+ + i.top + i.bottom, Integer.MAX_VALUE);
+ }
+ finally
+ {
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readUnlock();
+ }
+ return d;
}
/**
@@ -924,8 +1062,26 @@ public abstract class BasicTextUI extends TextUI
*/
public Dimension getMinimumSize(JComponent c)
{
+ Dimension d = new Dimension();
+ Document doc = textComponent.getDocument();
+ // We need to lock here, since we require the view hierarchy to _not_
+ // change in between.
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readLock();
+ try
+ {
+ d.width = (int) rootView.getMinimumSpan(View.X_AXIS);
+ d.height = (int) rootView.getMinimumSpan(View.Y_AXIS);
+ }
+ finally
+ {
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readUnlock();
+ }
Insets i = c.getInsets();
- return new Dimension(i.left + i.right, i.top + i.bottom);
+ d.width += i.left + i.right;
+ d.height += i.top + i.bottom;
+ return d;
}
/**
@@ -946,7 +1102,6 @@ public abstract class BasicTextUI extends TextUI
AbstractDocument aDoc = (AbstractDocument) doc;
aDoc.readLock();
}
-
paintSafely(g);
}
finally
@@ -996,7 +1151,6 @@ public abstract class BasicTextUI extends TextUI
g.setColor(oldColor);
}
-
rootView.paint(g, getVisibleEditorRect());
if (caret != null && textComponent.hasFocus())
@@ -1104,6 +1258,8 @@ public abstract class BasicTextUI extends TextUI
*/
public EditorKit getEditorKit(JTextComponent t)
{
+ if (kit == null)
+ kit = new DefaultEditorKit();
return kit;
}
@@ -1126,12 +1282,26 @@ public abstract class BasicTextUI extends TextUI
Position.Bias[] biasRet)
throws BadLocationException
{
- // A comment in the spec of NavigationFilter.getNextVisualPositionFrom()
- // suggests that this method should be implemented by forwarding the call
- // the root view.
- return rootView.getNextVisualPositionFrom(pos, b,
- getVisibleEditorRect(),
- direction, biasRet);
+ int offset = -1;
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readLock();
+ try
+ {
+ Rectangle alloc = getVisibleEditorRect();
+ if (alloc != null)
+ {
+ rootView.setSize(alloc.width, alloc.height);
+ offset = rootView.getNextVisualPositionFrom(pos, b, alloc,
+ direction, biasRet);
+ }
+ }
+ finally
+ {
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readUnlock();
+ }
+ return offset;
}
/**
@@ -1224,7 +1394,7 @@ public abstract class BasicTextUI extends TextUI
*/
public int viewToModel(JTextComponent t, Point pt)
{
- return viewToModel(t, pt, null);
+ return viewToModel(t, pt, new Position.Bias[1]);
}
/**
@@ -1241,7 +1411,25 @@ public abstract class BasicTextUI extends TextUI
*/
public int viewToModel(JTextComponent t, Point pt, Position.Bias[] biasReturn)
{
- return rootView.viewToModel(pt.x, pt.y, getVisibleEditorRect(), biasReturn);
+ int offset = -1;
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readLock();
+ try
+ {
+ Rectangle alloc = getVisibleEditorRect();
+ if (alloc != null)
+ {
+ rootView.setSize(alloc.width, alloc.height);
+ offset = rootView.viewToModel(pt.x, pt.y, alloc, biasReturn);
+ }
+ }
+ finally
+ {
+ if (doc instanceof AbstractDocument)
+ ((AbstractDocument) doc).readUnlock();
+ }
+ return offset;
}
/**
@@ -1273,6 +1461,11 @@ public abstract class BasicTextUI extends TextUI
}
/**
+ * A cached Insets instance to be reused below.
+ */
+ private Insets cachedInsets;
+
+ /**
* Returns the allocation to give the root view.
*
* @return the allocation to give the root view
@@ -1290,7 +1483,7 @@ public abstract class BasicTextUI extends TextUI
if (width <= 0 || height <= 0)
return null;
- Insets insets = textComponent.getInsets();
+ Insets insets = textComponent.getInsets(cachedInsets);
return new Rectangle(insets.left, insets.top,
width - insets.left - insets.right,
height - insets.top - insets.bottom);
@@ -1341,4 +1534,5 @@ public abstract class BasicTextUI extends TextUI
{
// The default implementation does nothing.
}
+
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java
index 1c36b408d5a..7be69ec2576 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java
@@ -898,7 +898,8 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
b.setRolloverEnabled(false);
// Save old border in hashtable.
- borders.put(b, b.getBorder());
+ if (b.getBorder() != null)
+ borders.put(b, b.getBorder());
b.setBorder(nonRolloverBorder);
}
@@ -932,7 +933,8 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
b.setRolloverEnabled(false);
// Save old border in hashtable.
- borders.put(b, b.getBorder());
+ if (b.getBorder() != null)
+ borders.put(b, b.getBorder());
b.setBorder(rolloverBorder);
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToolTipUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToolTipUI.java
index 5cec2e33365..94e7bc322f6 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicToolTipUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicToolTipUI.java
@@ -40,19 +40,20 @@ package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Dimension;
+import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
-import java.awt.Toolkit;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.LookAndFeel;
-import javax.swing.SwingConstants;
-import javax.swing.SwingUtilities;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ToolTipUI;
+import javax.swing.text.View;
/**
* This is the Basic Look and Feel UI class for JToolTip.
@@ -60,6 +61,28 @@ import javax.swing.plaf.ToolTipUI;
public class BasicToolTipUI extends ToolTipUI
{
+ /**
+ * Receives notification when a property of the JToolTip changes.
+ * This updates the HTML renderer if appropriate.
+ */
+ private class PropertyChangeHandler
+ implements PropertyChangeListener
+ {
+
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ String prop = e.getPropertyName();
+ if (prop.equals("tiptext") || prop.equals("font")
+ || prop.equals("foreground"))
+ {
+ JToolTip tip = (JToolTip) e.getSource();
+ String text = tip.getTipText();
+ BasicHTML.updateRenderer(tip, text);
+ }
+ }
+
+ }
+
/** The shared instance of BasicToolTipUI used for all ToolTips. */
private static BasicToolTipUI shared;
@@ -67,6 +90,11 @@ public class BasicToolTipUI extends ToolTipUI
private String text;
/**
+ * Handles property changes.
+ */
+ private PropertyChangeListener propertyChangeHandler;
+
+ /**
* Creates a new BasicToolTipUI object.
*/
public BasicToolTipUI()
@@ -98,7 +126,12 @@ public class BasicToolTipUI extends ToolTipUI
*/
public Dimension getMaximumSize(JComponent c)
{
- return getPreferredSize(c);
+ Dimension d = getPreferredSize(c);
+ View view = (View) c.getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ d.width += view.getMaximumSpan(View.X_AXIS)
+ - view.getPreferredSpan(View.X_AXIS);
+ return d;
}
/**
@@ -110,7 +143,12 @@ public class BasicToolTipUI extends ToolTipUI
*/
public Dimension getMinimumSize(JComponent c)
{
- return getPreferredSize(c);
+ Dimension d = getPreferredSize(c);
+ View view = (View) c.getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ d.width -= view.getPreferredSpan(View.X_AXIS)
+ - view.getMinimumSpan(View.X_AXIS);
+ return d;
}
/**
@@ -123,22 +161,25 @@ public class BasicToolTipUI extends ToolTipUI
public Dimension getPreferredSize(JComponent c)
{
JToolTip tip = (JToolTip) c;
- FontMetrics fm;
- Toolkit g = tip.getToolkit();
- text = tip.getTipText();
-
- Rectangle vr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
- Insets insets = tip.getInsets();
- fm = g.getFontMetrics(tip.getFont());
- SwingUtilities.layoutCompoundLabel(tip, fm, text, null,
- SwingConstants.CENTER,
- SwingConstants.CENTER,
- SwingConstants.CENTER,
- SwingConstants.CENTER, vr, ir, tr, 0);
- return new Dimension(insets.left + tr.width + insets.right,
- insets.top + tr.height + insets.bottom);
+ String str = tip.getTipText();
+ FontMetrics fm = c.getFontMetrics(c.getFont());
+ Insets i = c.getInsets();
+ Dimension d = new Dimension(i.left + i.right, i.top + i.bottom);
+ if (str != null && ! str.equals(""))
+ {
+ View view = (View) c.getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ {
+ d.width += (int) view.getPreferredSpan(View.X_AXIS);
+ d.height += (int) view.getPreferredSpan(View.Y_AXIS);
+ }
+ else
+ {
+ d.width += fm.stringWidth(str) + 6;
+ d.height += fm.getHeight();
+ }
+ }
+ return d;
}
/**
@@ -160,7 +201,8 @@ public class BasicToolTipUI extends ToolTipUI
*/
protected void installListeners(JComponent c)
{
- // TODO: Implement this properly.
+ propertyChangeHandler = new PropertyChangeHandler();
+ c.addPropertyChangeListener(propertyChangeHandler);
}
/**
@@ -172,6 +214,7 @@ public class BasicToolTipUI extends ToolTipUI
{
c.setOpaque(true);
installDefaults(c);
+ BasicHTML.updateRenderer(c, ((JToolTip) c).getTipText());
installListeners(c);
}
@@ -186,26 +229,25 @@ public class BasicToolTipUI extends ToolTipUI
JToolTip tip = (JToolTip) c;
String text = tip.getTipText();
- Toolkit t = tip.getToolkit();
- if (text == null)
- return;
-
- Rectangle vr = new Rectangle();
- vr = SwingUtilities.calculateInnerArea(tip, vr);
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
- FontMetrics fm = t.getFontMetrics(tip.getFont());
+ Font font = c.getFont();
+ FontMetrics fm = c.getFontMetrics(font);
int ascent = fm.getAscent();
- SwingUtilities.layoutCompoundLabel(tip, fm, text, null,
- SwingConstants.CENTER,
- SwingConstants.CENTER,
- SwingConstants.CENTER,
- SwingConstants.CENTER, vr, ir, tr, 0);
+ Insets i = c.getInsets();
+ Dimension size = c.getSize();
+ Rectangle paintR = new Rectangle(i.left, i.top,
+ size.width - i.left - i.right,
+ size.height - i.top - i.bottom);
Color saved = g.getColor();
+ Font oldFont = g.getFont();
g.setColor(Color.BLACK);
- g.drawString(text, vr.x, vr.y + ascent);
+ View view = (View) c.getClientProperty(BasicHTML.propertyKey);
+ if (view != null)
+ view.paint(g, paintR);
+ else
+ g.drawString(text, paintR.x + 3, paintR.y + ascent);
+ g.setFont(oldFont);
g.setColor(saved);
}
@@ -229,7 +271,11 @@ public class BasicToolTipUI extends ToolTipUI
*/
protected void uninstallListeners(JComponent c)
{
- // TODO: Implement this properly.
+ if (propertyChangeHandler != null)
+ {
+ c.removePropertyChangeListener(propertyChangeHandler);
+ propertyChangeHandler = null;
+ }
}
/**
@@ -240,6 +286,7 @@ public class BasicToolTipUI extends ToolTipUI
public void uninstallUI(JComponent c)
{
uninstallDefaults(c);
+ BasicHTML.updateRenderer(c, "");
uninstallListeners(c);
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
index 9a193986ac5..5b0ffce09b6 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
@@ -38,17 +38,16 @@
package javax.swing.plaf.basic;
-import gnu.classpath.NotImplementedException;
import gnu.javax.swing.tree.GnuPath;
import java.awt.Color;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Dimension;
-import java.awt.Font;
-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;
@@ -196,7 +195,7 @@ public class BasicTreeUI
protected AbstractLayoutCache treeState;
/** Used for minimizing the drawing of vertical lines. */
- protected Hashtable drawingCache;
+ protected Hashtable<TreePath, Boolean> drawingCache;
/**
* True if doing optimizations for a largeModel. Subclasses that don't support
@@ -275,13 +274,6 @@ public class BasicTreeUI
TreeModelListener treeModelListener;
/**
- * This timer fires the editing action after about 1200 ms if not reset during
- * that time. It handles the editing start with the single mouse click (and
- * 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;
@@ -428,6 +420,7 @@ public class BasicTreeUI
{
if (largeModel != this.largeModel)
{
+ completeEditing();
tree.removeComponentListener(componentListener);
this.largeModel = largeModel;
tree.addComponentListener(componentListener);
@@ -451,6 +444,7 @@ public class BasicTreeUI
*/
protected void setRowHeight(int rowHeight)
{
+ completeEditing();
if (rowHeight == 0)
rowHeight = getMaxHeight(tree);
treeState.setRowHeight(rowHeight);
@@ -544,6 +538,7 @@ public class BasicTreeUI
*/
protected void setRootVisible(boolean newValue)
{
+ completeEditing();
tree.setRootVisible(newValue);
}
@@ -590,8 +585,7 @@ public class BasicTreeUI
*/
protected void setCellEditor(TreeCellEditor editor)
{
- cellEditor = editor;
- createdCellEditor = true;
+ updateCellEditor();
}
/**
@@ -611,7 +605,7 @@ public class BasicTreeUI
*/
protected void setEditable(boolean newValue)
{
- tree.setEditable(newValue);
+ updateCellEditor();
}
/**
@@ -632,6 +626,7 @@ public class BasicTreeUI
*/
protected void setSelectionModel(TreeSelectionModel newLSM)
{
+ completeEditing();
if (newLSM != null)
{
treeSelectionModel = newLSM;
@@ -787,12 +782,13 @@ public class BasicTreeUI
*/
public boolean stopEditing(JTree tree)
{
- if (isEditing(tree))
+ boolean ret = false;
+ if (editingComponent != null && cellEditor.stopCellEditing())
{
completeEditing(false, false, true);
- finish();
+ ret = true;
}
- return ! isEditing(tree);
+ return ret;
}
/**
@@ -805,8 +801,8 @@ public class BasicTreeUI
// There is no need to send the cancel message to the editor,
// as the cancellation event itself arrives from it. This would
// only be necessary when cancelling the editing programatically.
- completeEditing(false, false, false);
- finish();
+ if (editingComponent != null)
+ completeEditing(false, true, false);
}
/**
@@ -818,7 +814,9 @@ public class BasicTreeUI
*/
public void startEditingAtPath(JTree tree, TreePath path)
{
- startEditing(path, null);
+ tree.scrollPathToVisible(path);
+ if (path != null && tree.isVisible(path))
+ startEditing(path, null);
}
/**
@@ -842,6 +840,7 @@ public class BasicTreeUI
preferredSize = new Dimension();
largeModel = tree.isLargeModel();
preferredSize = new Dimension();
+ stopEditingInCompleteEditing = true;
setModel(tree.getModel());
}
@@ -1136,6 +1135,7 @@ public class BasicTreeUI
*/
protected void updateExpandedDescendants(TreePath path)
{
+ completeEditing();
Enumeration expanded = tree.getExpandedDescendants(path);
while (expanded.hasMoreElements())
treeState.setExpandedState((TreePath) expanded.nextElement(), true);
@@ -1167,9 +1167,33 @@ public class BasicTreeUI
*/
protected void updateCellEditor()
{
- if (tree.isEditable() && cellEditor == null)
- setCellEditor(createDefaultCellEditor());
- createdCellEditor = true;
+ completeEditing();
+ TreeCellEditor newEd = null;
+ if (tree != null && tree.isEditable())
+ {
+ newEd = tree.getCellEditor();
+ if (newEd == null)
+ {
+ newEd = createDefaultCellEditor();
+ if (newEd != null)
+ {
+ tree.setCellEditor(newEd);
+ createdCellEditor = true;
+ }
+ }
+ }
+ // Update listeners.
+ if (newEd != cellEditor)
+ {
+ if (cellEditor != null && cellEditorListener != null)
+ cellEditor.removeCellEditorListener(cellEditorListener);
+ cellEditor = newEd;
+ if (cellEditorListener == null)
+ cellEditorListener = createCellEditorListener();
+ if (cellEditor != null && cellEditorListener != null)
+ cellEditor.addCellEditorListener(cellEditorListener);
+ createdCellEditor = false;
+ }
}
/**
@@ -1563,12 +1587,15 @@ public class BasicTreeUI
for (int i = startIndex; i <= endIndex; i++, k++)
{
path[k] = treeState.getPathForRow(i);
- isLeaf[k] = treeModel.isLeaf(path[k].getLastPathComponent());
- isExpanded[k] = tree.isExpanded(path[k]);
- bounds[k] = getPathBounds(tree, path[k]);
-
- paintHorizontalPartOfLeg(g, clip, insets, bounds[k], path[k], i,
- isExpanded[k], false, isLeaf[k]);
+ if (path[k] != null)
+ {
+ isLeaf[k] = treeModel.isLeaf(path[k].getLastPathComponent());
+ isExpanded[k] = tree.isExpanded(path[k]);
+ bounds[k] = getPathBounds(tree, path[k]);
+
+ paintHorizontalPartOfLeg(g, clip, insets, bounds[k], path[k],
+ i, isExpanded[k], false, isLeaf[k]);
+ }
if (isLastChild(path[k]))
paintVerticalPartOfLeg(g, clip, insets, path[k]);
}
@@ -1576,8 +1603,9 @@ public class BasicTreeUI
k = 0;
for (int i = startIndex; i <= endIndex; i++, k++)
{
- paintRow(g, clip, insets, bounds[k], path[k], i, isExpanded[k],
- false, isLeaf[k]);
+ if (path[k] != null)
+ paintRow(g, clip, insets, bounds[k], path[k], i, isExpanded[k],
+ false, isLeaf[k]);
}
}
}
@@ -1587,7 +1615,9 @@ public class BasicTreeUI
*/
private boolean isLastChild(TreePath path)
{
- if (path instanceof GnuPath)
+ if (path == null)
+ return false;
+ else if (path instanceof GnuPath)
{
// Except the seldom case when the layout cache is changed, this
// optimized code will be executed.
@@ -1719,6 +1749,10 @@ public class BasicTreeUI
*/
protected void completeEditing()
{
+ if (tree.getInvokesStopCellEditing() && stopEditingInCompleteEditing
+ && editingComponent != null)
+ cellEditor.stopCellEditing();
+
completeEditing(false, true, false);
}
@@ -1736,28 +1770,35 @@ public class BasicTreeUI
boolean messageTree)
{
// Make no attempt to complete the non existing editing session.
- if (!isEditing(tree))
- return;
-
- if (messageStop)
+ if (stopEditingInCompleteEditing && editingComponent != null)
{
- getCellEditor().stopCellEditing();
- stopEditingInCompleteEditing = true;
- }
-
- if (messageCancel)
- {
- getCellEditor().cancelCellEditing();
- stopEditingInCompleteEditing = true;
- }
+ Component comp = editingComponent;
+ TreePath p = editingPath;
+ editingComponent = null;
+ editingPath = null;
+ if (messageStop)
+ cellEditor.stopCellEditing();
+ else if (messageCancel)
+ cellEditor.cancelCellEditing();
+
+ tree.remove(comp);
+
+ if (editorHasDifferentSize)
+ {
+ treeState.invalidatePathBounds(p);
+ updateSize();
+ }
+ else
+ {
+ // Need to refresh the tree.
+ Rectangle b = getPathBounds(tree, p);
+ tree.repaint(0, b.y, tree.getWidth(), b.height);
+ }
- if (messageTree)
- {
- TreeCellEditor editor = getCellEditor();
- if (editor != null)
+ if (messageTree)
{
- Object value = editor.getCellEditorValue();
- treeModel.valueForPathChanged(tree.getLeadSelectionPath(), value);
+ Object value = cellEditor.getCellEditorValue();
+ treeModel.valueForPathChanged(p, value);
}
}
}
@@ -1772,47 +1813,105 @@ public class BasicTreeUI
*/
protected boolean startEditing(TreePath path, MouseEvent event)
{
- updateCellEditor();
- TreeCellEditor ed = getCellEditor();
+ // Maybe cancel editing.
+ if (isEditing(tree) && tree.getInvokesStopCellEditing()
+ && ! stopEditing(tree))
+ return false;
- if (ed != null && (event == EDIT || ed.shouldSelectCell(event))
- && ed.isCellEditable(event))
+ completeEditing();
+ TreeCellEditor ed = cellEditor;
+ if (ed != null && tree.isPathEditable(path))
{
- Rectangle bounds = getPathBounds(tree, path);
-
- // Extend the right boundary till the tree width.
- bounds.width = tree.getWidth() - bounds.x;
-
- editingPath = path;
- editingRow = tree.getRowForPath(editingPath);
-
- Object value = editingPath.getLastPathComponent();
-
- stopEditingInCompleteEditing = false;
- boolean expanded = tree.isExpanded(editingPath);
- isEditing = true;
- editingComponent = ed.getTreeCellEditorComponent(tree, value, true,
- expanded,
- isLeaf(editingRow),
- editingRow);
-
- // Remove all previous components (if still present). Only one
- // container with the editing component inside is allowed in the tree.
- tree.removeAll();
-
- // The editing component must be added to its container. We add the
- // container, not the editing component itself.
- Component container = editingComponent.getParent();
- container.setBounds(bounds);
- tree.add(container);
- editingComponent.requestFocus();
+ if (ed.isCellEditable(event))
+ {
+ editingRow = getRowForPath(tree, path);
+ Object value = path.getLastPathComponent();
+ boolean isSelected = tree.isPathSelected(path);
+ boolean isExpanded = tree.isExpanded(editingPath);
+ boolean isLeaf = treeModel.isLeaf(value);
+ editingComponent = ed.getTreeCellEditorComponent(tree, value,
+ isSelected,
+ isExpanded,
+ isLeaf,
+ editingRow);
+
+ Rectangle bounds = getPathBounds(tree, path);
+
+ Dimension size = editingComponent.getPreferredSize();
+ int rowHeight = getRowHeight();
+ if (size.height != bounds.height && rowHeight > 0)
+ size.height = rowHeight;
+
+ if (size.width != bounds.width || size.height != bounds.height)
+ {
+ editorHasDifferentSize = true;
+ treeState.invalidatePathBounds(path);
+ updateSize();
+ }
+ else
+ editorHasDifferentSize = false;
+
+ // The editing component must be added to its container. We add the
+ // container, not the editing component itself.
+ tree.add(editingComponent);
+ editingComponent.setBounds(bounds.x, bounds.y, size.width,
+ size.height);
+ editingComponent.validate();
+ editingPath = path;
+
+ if (ed.shouldSelectCell(event))
+ {
+ stopEditingInCompleteEditing = false;
+ tree.setSelectionRow(editingRow);
+ stopEditingInCompleteEditing = true;
+ }
+
+ editorRequestFocus(editingComponent);
+ // Register MouseInputHandler to redispatch initial mouse events
+ // correctly.
+ if (event instanceof MouseEvent)
+ {
+ Point p = SwingUtilities.convertPoint(tree, event.getX(), event.getY(),
+ editingComponent);
+ Component active =
+ SwingUtilities.getDeepestComponentAt(editingComponent, p.x, p.y);
+ if (active != null)
+ {
+ MouseInputHandler ih = new MouseInputHandler(tree, active, event);
+
+ }
+ }
- return true;
+ return true;
+ }
+ else
+ editingComponent = null;
}
return false;
}
/**
+ * Requests focus on the editor. The method is necessary since the
+ * DefaultTreeCellEditor returns a container that contains the
+ * actual editor, and we want to request focus on the editor, not the
+ * container.
+ */
+ private void editorRequestFocus(Component c)
+ {
+ if (c instanceof Container)
+ {
+ // TODO: Maybe do something more reasonable here, like queriying the
+ // FocusTraversalPolicy.
+ Container cont = (Container) c;
+ if (cont.getComponentCount() > 0)
+ cont.getComponent(0).requestFocus();
+ }
+ else if (c.isFocusable())
+ c.requestFocus();
+
+ }
+
+ /**
* If the <code>mouseX</code> and <code>mouseY</code> are in the expand or
* collapse region of the row, this will toggle the row.
*
@@ -2180,7 +2279,7 @@ public class BasicTreeUI
*/
public void editingStopped(ChangeEvent e)
{
- stopEditing(tree);
+ completeEditing(false, false, true);
}
/**
@@ -2191,7 +2290,7 @@ public class BasicTreeUI
*/
public void editingCanceled(ChangeEvent e)
{
- cancelEditing(tree);
+ completeEditing(false, false, false);
}
} // CellEditorHandler
@@ -2347,9 +2446,15 @@ public class BasicTreeUI
* events.
*/
public class MouseHandler
- extends MouseAdapter
- implements MouseMotionListener
+ extends MouseAdapter
+ implements MouseMotionListener
{
+
+ /**
+ * If the cell has been selected on mouse press.
+ */
+ private boolean selectedOnPress;
+
/**
* Constructor
*/
@@ -2365,76 +2470,15 @@ 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)
+ if (! e.isConsumed())
{
- startEditTimer.stop();
- startEditTimer = null;
+ handleEvent(e);
+ selectedOnPress = true;
}
-
- if (tree != null && tree.isEnabled())
+ else
{
- // Always end the current editing session if clicked on the
- // tree and outside the bounds of the editing component.
- if (isEditing(tree))
- if (!stopEditing(tree))
- // Return if we have failed to cancel the editing session.
- return;
-
- int x = e.getX();
- int y = e.getY();
- TreePath path = getClosestPathForLocation(tree, x, y);
-
- if (path != null)
- {
- Rectangle bounds = getPathBounds(tree, path);
- if (SwingUtilities.isLeftMouseButton(e))
- checkForClickInExpandControl(path, x, y);
-
- if (x > bounds.x && x <= (bounds.x + bounds.width))
- {
- TreePath currentLead = tree.getLeadSelectionPath();
- if (currentLead != null && currentLead.equals(path)
- && e.getClickCount() == 1 && tree.isEditable())
- {
- // Schedule the editing session.
- final TreePath editPath = path;
-
- // The code below handles the required click-pause-click
- // functionality which must be present in the tree UI.
- // If the next click comes after the
- // time longer than the double click interval AND
- // the same node stays focused for the WAIT_TILL_EDITING
- // duration, the timer starts the editing session.
- 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)
- toggleExpandState(path);
- else
- selectPathForEvent(path, e);
- }
- }
- }
+ selectedOnPress = false;
}
-
- // We need to request the focus.
- tree.requestFocusInWindow();
}
/**
@@ -2446,9 +2490,8 @@ 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?
+ // Nothing to do here.
}
/**
@@ -2458,9 +2501,8 @@ 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?
+ // Nothing to do here.
}
/**
@@ -2469,9 +2511,46 @@ 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?
+ if (! e.isConsumed() && ! selectedOnPress)
+ handleEvent(e);
+ }
+
+ /**
+ * Handles press and release events.
+ *
+ * @param e the mouse event
+ */
+ private void handleEvent(MouseEvent e)
+ {
+ if (tree != null && tree.isEnabled())
+ {
+ // Maybe stop editing.
+ if (isEditing(tree) && tree.getInvokesStopCellEditing()
+ && ! stopEditing(tree))
+ return;
+
+ // Explicitly request focus.
+ tree.requestFocusInWindow();
+
+ int x = e.getX();
+ int y = e.getY();
+ TreePath path = getClosestPathForLocation(tree, x, y);
+ if (path != null)
+ {
+ Rectangle b = getPathBounds(tree, path);
+ if (y <= b.y + b.height)
+ {
+ if (SwingUtilities.isLeftMouseButton(e))
+ checkForClickInExpandControl(path, x, y);
+ if (x > b.x && x <= b.x + b.width)
+ {
+ if (! startEditing(path, e))
+ selectPathForEvent(path, e);
+ }
+ }
+ }
+ }
}
}
@@ -2501,6 +2580,9 @@ public class BasicTreeUI
{
this.source = source;
this.destination = destination;
+ source.addMouseListener(this);
+ source.addMouseMotionListener(this);
+ dispatch(e);
}
/**
@@ -2510,9 +2592,8 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseClicked(MouseEvent e)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ dispatch(e);
}
/**
@@ -2521,9 +2602,8 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mousePressed(MouseEvent e)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ // Nothing to do here.
}
/**
@@ -2532,9 +2612,9 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseReleased(MouseEvent e)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ dispatch(e);
+ removeFromSource();
}
/**
@@ -2543,9 +2623,9 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseEntered(MouseEvent e)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ if (! SwingUtilities.isLeftMouseButton(e))
+ removeFromSource();
}
/**
@@ -2554,9 +2634,9 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseExited(MouseEvent e)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ if (! SwingUtilities.isLeftMouseButton(e))
+ removeFromSource();
}
/**
@@ -2568,9 +2648,8 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseDragged(MouseEvent e)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ dispatch(e);
}
/**
@@ -2580,18 +2659,37 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseMoved(MouseEvent e)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ removeFromSource();
}
/**
* Removes event from the source
*/
protected void removeFromSource()
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ if (source != null)
+ {
+ source.removeMouseListener(this);
+ source.removeMouseMotionListener(this);
+ }
+ source = null;
+ destination = null;
+ }
+
+ /**
+ * Redispatches mouse events to the destination.
+ *
+ * @param e the mouse event to redispatch
+ */
+ private void dispatch(MouseEvent e)
+ {
+ if (destination != null)
+ {
+ MouseEvent e2 = SwingUtilities.convertMouseEvent(source, e,
+ destination);
+ destination.dispatchEvent(e2);
+ }
}
}
@@ -2627,24 +2725,42 @@ public class BasicTreeUI
public Rectangle getNodeDimensions(Object cell, int row, int depth,
boolean expanded, Rectangle size)
{
- if (size == null || cell == null)
- return null;
-
- String s = cell.toString();
- Font f = tree.getFont();
- FontMetrics fm = tree.getToolkit().getFontMetrics(f);
-
- if (s != null)
+ Dimension prefSize;
+ if (editingComponent != null && editingRow == row)
+ {
+ // Editing, ask editor for preferred size.
+ prefSize = editingComponent.getPreferredSize();
+ int rowHeight = getRowHeight();
+ if (rowHeight > 0 && rowHeight != prefSize.height)
+ prefSize.height = rowHeight;
+ }
+ else
+ {
+ // Not editing, ask renderer for preferred size.
+ Component rend =
+ currentCellRenderer.getTreeCellRendererComponent(tree, cell,
+ tree.isRowSelected(row),
+ expanded,
+ treeModel.isLeaf(cell),
+ row, false);
+ // Make sure the layout is valid.
+ rendererPane.add(rend);
+ rend.validate();
+ prefSize = rend.getPreferredSize();
+ }
+ if (size != null)
{
- TreePath path = treeState.getPathForRow(row);
size.x = getRowX(row, depth);
- size.width = SwingUtilities.computeStringWidth(fm, s);
- size.width = size.width + getCurrentControlIcon(path).getIconWidth()
- + gap + getNodeIcon(path).getIconWidth();
- size.height = getMaxHeight(tree);
- size.y = size.height * row;
+ // FIXME: This should be handled by the layout cache.
+ size.y = prefSize.height * row;
+ size.width = prefSize.width;
+ size.height = prefSize.height;
}
-
+ else
+ // FIXME: The y should be handled by the layout cache.
+ size = new Rectangle(getRowX(row, depth), prefSize.height * row, prefSize.width,
+ prefSize.height);
+
return size;
}
@@ -2706,6 +2822,9 @@ public class BasicTreeUI
if (treeState != null)
treeState.invalidateSizes();
}
+ else if (property.equals(JTree.EDITABLE_PROPERTY))
+ setEditable(((Boolean) event.getNewValue()).booleanValue());
+
}
}
@@ -2714,7 +2833,7 @@ public class BasicTreeUI
* properties of the model change.
*/
public class SelectionModelPropertyChangeHandler
- implements PropertyChangeListener
+ implements PropertyChangeListener
{
/**
@@ -2732,9 +2851,8 @@ public class BasicTreeUI
* the property that has changed.
*/
public void propertyChange(PropertyChangeEvent event)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ treeSelectionModel.resetRowSelection();
}
}
@@ -2804,6 +2922,7 @@ public class BasicTreeUI
*/
public void treeCollapsed(TreeExpansionEvent event)
{
+ completeEditing();
validCachedPreferredSize = false;
treeState.setExpandedState(event.getPath(), false);
// The maximal cell height may change
@@ -3269,8 +3388,7 @@ public class BasicTreeUI
*/
public void valueChanged(TreeSelectionEvent event)
{
- if (tree.isEditing())
- tree.cancelEditing();
+ completeEditing();
TreePath op = event.getOldLeadSelectionPath();
TreePath np = event.getNewLeadSelectionPath();
@@ -3808,25 +3926,6 @@ public class BasicTreeUI
}
/**
- * Finish the editing session.
- */
- void finish()
- {
- treeState.invalidatePathBounds(treeState.getPathForRow(editingRow));
- editingPath = null;
- editingRow = - 1;
- stopEditingInCompleteEditing = false;
- isEditing = false;
- Rectangle bounds = editingComponent.getParent().getBounds();
- tree.removeAll();
- validCachedPreferredSize = false;
- // Repaint the region, where was the editing component.
- tree.repaint(bounds);
- editingComponent = null;
- tree.requestFocus();
- }
-
- /**
* Returns the amount to indent the given row
*
* @return amount to indent the given row.
OpenPOWER on IntegriCloud