summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/plaf/basic
diff options
context:
space:
mode:
authorMark Wielaard <mark@gcc.gnu.org>2006-03-10 21:46:48 +0000
committerMark Wielaard <mark@gcc.gnu.org>2006-03-10 21:46:48 +0000
commit8aa540d2f783474d1d2e06f16744bf67b9c1facc (patch)
treeea38c56431c5d4528fb54254c3f8e50f517bede3 /libjava/classpath/javax/swing/plaf/basic
parent27079765d00123f8e53d0e1ef7f9d46559266e6d (diff)
downloadgcc-8aa540d2f783474d1d2e06f16744bf67b9c1facc.tar.gz
Imported GNU Classpath 0.90
Imported GNU Classpath 0.90 * scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore. * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant. * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5. * java/lang/Math.java: New override file. * java/lang/Character.java: Merged from Classpath. (start, end): Now 'int's. (canonicalName): New field. (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants. (UnicodeBlock): Added argument. (of): New overload. (forName): New method. Updated unicode blocks. (sets): Updated. * sources.am: Regenerated. * Makefile.in: Likewise. From-SVN: r111942
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic')
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicBorders.java36
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java1
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicColorChooserUI.java5
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java16
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicHTML.java297
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java70
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java57
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicListUI.java40
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java141
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java3
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicPopupMenuUI.java323
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java1
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java6
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java42
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java206
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java31
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java108
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java7
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java351
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java160
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java250
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java297
22 files changed, 1475 insertions, 973 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicBorders.java b/libjava/classpath/javax/swing/plaf/basic/BasicBorders.java
index 5d4ce18932b..5e2cf2e48ca 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicBorders.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicBorders.java
@@ -299,9 +299,7 @@ public class BasicBorders
public static Border getSplitPaneDividerBorder()
{
/* See comment in methods above for why this border is not shared. */
- return new SplitPaneDividerBorder(
- UIManager.getColor("SplitPane.highlight"),
- UIManager.getColor("SplitPane.darkShadow"));
+ return new SplitPaneDividerBorder();
}
@@ -1518,34 +1516,15 @@ public class BasicBorders
implements Border, UIResource, Serializable
{
/**
- * The highlight color, which is drawn on the left or top edge
- * depending on the orientation of the JSplitPanel.
- */
- protected Color highlight;
-
-
- /**
- * The highlight color, which is drawn on the right or bottom edge
- * depending on the orientation of the JSplitPanel.
- */
- protected Color shadow;
-
-
- /**
* Constructs a new border for drawing the divider of a JSplitPane
* in the Basic look and feel. The outer parts of the JSplitPane have
* their own border class, <code>SplitPaneBorder</code>.
- *
- * @param shadow the shadow color.
- * @param highlight the highlight color.
*/
- public SplitPaneDividerBorder(Color highlight, Color shadow)
+ public SplitPaneDividerBorder()
{
- this.highlight = (highlight != null) ? highlight : Color.white;
- this.shadow = (shadow != null) ? shadow : Color.black;
+ // Nothing to do here.
}
-
/**
* Paints the border around the divider of a <code>JSplitPane</code>.
*
@@ -1564,6 +1543,8 @@ public class BasicBorders
public void paintBorder(Component c, Graphics g,
int x, int y, int width, int height)
{
+ Color highlight = UIManager.getColor("SplitPane.highlight");
+ Color shadow = UIManager.getColor("SplitPane.shadow");
Color oldColor, dcol;
int x2, y2;
JSplitPane sp;
@@ -1624,17 +1605,15 @@ public class BasicBorders
return new Insets(1, 1, 1, 1);
}
-
/**
* Determines whether this border fills every pixel in its area
* when painting.
*
- * @return <code>true</code> if both highlight and shadow
- * color are fully opaque.
+ * @return <code>true</code>
*/
public boolean isBorderOpaque()
{
- return (highlight.getAlpha() == 255) && (shadow.getAlpha() == 255);
+ return true;
}
@@ -1785,4 +1764,5 @@ public class BasicBorders
return insets;
}
}
+
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
index 95e0dc98257..e45970ed02c 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
@@ -45,7 +45,6 @@ import javax.swing.JMenuItem;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.UIDefaults;
-import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicColorChooserUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicColorChooserUI.java
index 5a872ae6368..f37cbd7b838 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicColorChooserUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicColorChooserUI.java
@@ -141,10 +141,9 @@ public class BasicColorChooserUI extends ColorChooserUI
protected PropertyChangeListener propertyChangeListener;
/**
- * The JColorChooser.
- * This is package-private to avoid an accessor method.
+ * The JColorChooser this is installed on.
*/
- JColorChooser chooser;
+ protected JColorChooser chooser;
/** The JTabbedPane that is used. */
JTabbedPane pane;
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java
index 08dab7f9f36..798101d0d85 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java
@@ -69,6 +69,7 @@ import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
+import javax.swing.UIManager;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
@@ -193,8 +194,23 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
if (selectedIndex > comboBox.getMaximumRowCount())
scrollbar.setValue(getPopupHeightForRowCount(selectedIndex));
+ // We put the autoclose-registration inside an InvocationEvent, so that
+ // the same event that triggered this show() call won't hide the popup
+ // immediately.
+ SwingUtilities.invokeLater
+ (new Runnable()
+ {
+ public void run()
+ {
+ // Register this popup to be autoclosed when user clicks outside the
+ // popup.
+ BasicLookAndFeel laf = (BasicLookAndFeel) UIManager.getLookAndFeel();
+ laf.registerForAutoClose(BasicComboPopup.this);
+ }});
+
// location specified is relative to comboBox
super.show(comboBox, 0, cbBounds.height);
+
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java
index b9891e14401..98c9cb277f4 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java
@@ -38,12 +38,21 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.Container;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
import java.io.IOException;
import java.io.StringReader;
import javax.swing.JComponent;
+import javax.swing.SwingConstants;
+import javax.swing.event.DocumentEvent;
import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.EditorKit;
import javax.swing.text.Element;
+import javax.swing.text.Position;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTMLDocument;
@@ -59,6 +68,287 @@ public class BasicHTML
{
/**
+ * This class serves as the root view for HTML rendering components.
+ * Its purpose and implementation is similar to the BasicTextUI.RootView
+ * class, only that is implements some stuff differently due to the nature
+ * of not beeing inside a JTextComponent.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ private static class HTMLRootView extends View
+ {
+ /**
+ * The real root view.
+ */
+ private View view;
+
+ /**
+ * The component on which to render the view.
+ */
+ private JComponent component;
+
+ /**
+ * The EditorKit.
+ */
+ private EditorKit editorKit;
+
+ /**
+ * The document to use.
+ */
+ private Document document;
+
+ /**
+ * Creates a new RootView.
+ */
+ public HTMLRootView(JComponent c, View view, EditorKit kit, Document doc)
+ {
+ super(null);
+ component = c;
+ editorKit = kit;
+ document = doc;
+ setView(view);
+ }
+
+ /**
+ * Returns the ViewFactory for this RootView. If the current EditorKit
+ * provides a ViewFactory, this is used. Otherwise the TextUI itself
+ * is returned as a ViewFactory.
+ *
+ * @return the ViewFactory for this RootView
+ */
+ public ViewFactory getViewFactory()
+ {
+ return editorKit.getViewFactory();
+ }
+
+ /**
+ * Indicates that the preferences of one of the child view has changed.
+ * This calls revalidate on the text component.
+ *
+ * @param v the child view which's preference has changed
+ * @param width <code>true</code> if the width preference has changed
+ * @param height <code>true</code> if the height preference has changed
+ */
+ public void preferenceChanged(View v, boolean width, boolean height)
+ {
+ component.revalidate();
+ }
+
+ /**
+ * Sets the real root view.
+ *
+ * @param v the root view to set
+ */
+ public void setView(View v)
+ {
+ if (view != null)
+ view.setParent(null);
+
+ if (v != null)
+ v.setParent(this);
+
+ view = v;
+ }
+
+ /**
+ * Returns the real root view, regardless of the index.
+ *
+ * @param index not used here
+ *
+ * @return the real root view, regardless of the index.
+ */
+ public View getView(int index)
+ {
+ return view;
+ }
+
+ /**
+ * Returns <code>1</code> since the RootView always contains one
+ * child, that is the real root of the View hierarchy.
+ *
+ * @return <code>1</code> since the RootView always contains one
+ * child, that is the real root of the View hierarchy
+ */
+ public int getViewCount()
+ {
+ int count = 0;
+ if (view != null)
+ count = 1;
+ return count;
+ }
+
+ /**
+ * Returns the <code>Container</code> that contains this view. This
+ * normally will be the text component that is managed by this TextUI.
+ *
+ * @return the <code>Container</code> that contains this view
+ */
+ public Container getContainer()
+ {
+ return component;
+ }
+
+ /**
+ * 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
+ */
+ public float getPreferredSpan(int axis)
+ {
+ if (view != null)
+ return view.getPreferredSpan(axis);
+
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * Paints the view. This is delegated to the real root view.
+ *
+ * @param g the <code>Graphics</code> context to paint to
+ * @param s the allocation for the View
+ */
+ public void paint(Graphics g, Shape s)
+ {
+ if (view != null)
+ {
+ Rectangle b = s.getBounds();
+ view.setSize(b.width, b.height);
+ view.paint(g, s);
+ }
+ }
+
+
+ /**
+ * Maps a position in the document into the coordinate space of the View.
+ * The output rectangle usually reflects the font height but has a width
+ * of zero.
+ *
+ * This is delegated to the real root view.
+ *
+ * @param position the position of the character in the model
+ * @param a the area that is occupied by the view
+ * @param bias either {@link Position.Bias#Forward} or
+ * {@link Position.Bias#Backward} depending on the preferred
+ * direction bias. If <code>null</code> this defaults to
+ * <code>Position.Bias.Forward</code>
+ *
+ * @return a rectangle that gives the location of the document position
+ * inside the view coordinate space
+ *
+ * @throws BadLocationException if <code>pos</code> is invalid
+ * @throws IllegalArgumentException if b is not one of the above listed
+ * valid values
+ */
+ public Shape modelToView(int position, Shape a, Position.Bias bias)
+ throws BadLocationException
+ {
+ return view.modelToView(position, a, bias);
+ }
+
+ /**
+ * Maps coordinates from the <code>View</code>'s space into a position
+ * in the document model.
+ *
+ * @param x the x coordinate in the view space
+ * @param y the y coordinate in the view space
+ * @param a the allocation of this <code>View</code>
+ * @param b the bias to use
+ *
+ * @return the position in the document that corresponds to the screen
+ * coordinates <code>x, y</code>
+ */
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
+ {
+ return view.viewToModel(x, y, a, b);
+ }
+
+ /**
+ * Notification about text insertions. These are forwarded to the
+ * real root view.
+ *
+ * @param ev the DocumentEvent describing the change
+ * @param shape the current allocation of the view's display
+ * @param vf the ViewFactory to use for creating new Views
+ */
+ public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ view.insertUpdate(ev, shape, vf);
+ }
+
+ /**
+ * Notification about text removals. These are forwarded to the
+ * real root view.
+ *
+ * @param ev the DocumentEvent describing the change
+ * @param shape the current allocation of the view's display
+ * @param vf the ViewFactory to use for creating new Views
+ */
+ public void removeUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ view.removeUpdate(ev, shape, vf);
+ }
+
+ /**
+ * Notification about text changes. These are forwarded to the
+ * real root view.
+ *
+ * @param ev the DocumentEvent describing the change
+ * @param shape the current allocation of the view's display
+ * @param vf the ViewFactory to use for creating new Views
+ */
+ public void changedUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
+ {
+ view.changedUpdate(ev, shape, vf);
+ }
+
+ /**
+ * Returns the document position that is (visually) nearest to the given
+ * document position <code>pos</code> in the given direction <code>d</code>.
+ *
+ * @param pos the document position
+ * @param b the bias for <code>pos</code>
+ * @param a the allocation for the view
+ * @param d the direction, must be either {@link SwingConstants#NORTH},
+ * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or
+ * {@link SwingConstants#EAST}
+ * @param biasRet an array of {@link Position.Bias} that can hold at least
+ * one element, which is filled with the bias of the return position
+ * on method exit
+ *
+ * @return the document position that is (visually) nearest to the given
+ * document position <code>pos</code> in the given direction
+ * <code>d</code>
+ *
+ * @throws BadLocationException if <code>pos</code> is not a valid offset in
+ * the document model
+ */
+ public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a,
+ int d, Position.Bias[] biasRet)
+ throws BadLocationException
+ {
+ return view.getNextVisualPositionFrom(pos, b, a, d, biasRet);
+ }
+
+ public int getStartOffset()
+ {
+ return 0;
+ }
+
+ public int getEndOffset()
+ {
+ return getDocument().getLength();
+ }
+
+ public Document getDocument()
+ {
+ return document;
+ }
+ }
+
+ /**
* The key that is used to store a HTML view in a JComponent's client
* properties.
*/
@@ -116,7 +406,8 @@ public class BasicHTML
ViewFactory vf = kit.getViewFactory();
Element root = doc.getDefaultRootElement();
View view = vf.create(root);
- return view;
+ HTMLRootView rootView = new HTMLRootView(c, view, kit, doc);
+ return rootView;
}
/**
@@ -132,13 +423,13 @@ public class BasicHTML
{
// We consider a string to be HTML if it contains both the '<' and '>'
// character at least once.
- return s.contains("<") && s.contains(">");
+ return (s != null) && s.contains("<") && s.contains(">");
}
/**
* Stores a HTML renderer in <code>c</code>'s client property if
* <code>text</code> is HTML, otherwise it clears the corresponding client
- * property. This is useful for {@link java.swing.plaf.ComponentUI}
+ * property. This is useful for {@link javax.swing.plaf.ComponentUI}
* implementations that are shared between it's components.
*
* @param c the component to update the renderer for
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
index f9653bd2edd..f6cbeec8879 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -54,8 +54,6 @@ import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.beans.PropertyVetoException;
-import java.beans.VetoableChangeListener;
import javax.swing.DefaultDesktopManager;
import javax.swing.DesktopManager;
@@ -94,7 +92,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void internalFrameActivated(InternalFrameEvent e)
{
- // FIXME: Implement.
+ frame.getGlassPane().setVisible(false);
}
/**
@@ -124,7 +122,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void internalFrameDeactivated(InternalFrameEvent e)
{
- // FIXME: Implement.
+ frame.getGlassPane().setVisible(true);
}
/**
@@ -464,8 +462,6 @@ public class BasicInternalFrameUI extends InternalFrameUI
dims.width -= insets.left + insets.right;
dims.height -= insets.top + insets.bottom;
- frame.getRootPane().getGlassPane().setBounds(0, 0, dims.width,
- dims.height);
int nh = 0;
int sh = 0;
int ew = 0;
@@ -526,18 +522,6 @@ public class BasicInternalFrameUI extends InternalFrameUI
}
/**
- * This method returns the maximum layout size.
- *
- * @param c
- * The Container to find a maximum layout size for.
- * @return The maximum dimensions for the JInternalFrame.
- */
- public Dimension maximumLayoutSize(Container c)
- {
- return preferredLayoutSize(c);
- }
-
- /**
* Th8is method returns the preferred layout size.
*
* @param c
@@ -891,40 +875,12 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This helper class listens for PropertyChangeEvents from the
* JInternalFrame.
*/
- public class InternalFramePropertyChangeListener implements
- PropertyChangeListener, VetoableChangeListener
+ public class InternalFramePropertyChangeListener
+ implements PropertyChangeListener
{
/**
* This method is called when one of the JInternalFrame's properties change.
- * This method is to allow JInternalFrame to veto an attempt to close the
- * internal frame. This allows JInternalFrame to honour its
- * defaultCloseOperation if that is DO_NOTHING_ON_CLOSE.
- */
- public void vetoableChange(PropertyChangeEvent e)
- throws PropertyVetoException
- {
- if (e.getPropertyName().equals(JInternalFrame.IS_CLOSED_PROPERTY))
- {
- if (frame.getDefaultCloseOperation() == JInternalFrame.HIDE_ON_CLOSE)
- {
- frame.setVisible(false);
- frame.getDesktopPane().repaint();
- throw new PropertyVetoException(
- "close operation is HIDE_ON_CLOSE\n",
- e);
- }
- else if (frame.getDefaultCloseOperation() == JInternalFrame.DISPOSE_ON_CLOSE)
- closeFrame(frame);
- else
- throw new PropertyVetoException(
- "close operation is DO_NOTHING_ON_CLOSE\n",
- e);
- }
- }
-
- /**
- * This method is called when one of the JInternalFrame's properties change.
*
* @param evt
* The PropertyChangeEvent.
@@ -1091,13 +1047,6 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
protected PropertyChangeListener propertyChangeListener;
- /**
- * The VetoableChangeListener. Listens to PropertyChangeEvents
- * from the JInternalFrame and allows the JInternalFrame to
- * veto attempts to close it.
- */
- private VetoableChangeListener internalFrameVetoableChangeListener;
-
/** The InternalFrameListener that listens to the JInternalFrame. */
private transient BasicInternalFrameListener internalFrameListener;
@@ -1165,14 +1114,15 @@ public class BasicInternalFrameUI extends InternalFrameUI
{
frame = (JInternalFrame) c;
- ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
- frame.getRootPane().getGlassPane().setVisible(true);
-
installDefaults();
installListeners();
installComponents();
installKeyboardActions();
+ ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
+ if (! frame.isSelected())
+ frame.getRootPane().getGlassPane().setVisible(true);
+
frame.setOpaque(true);
frame.invalidate();
}
@@ -1205,8 +1155,6 @@ public class BasicInternalFrameUI extends InternalFrameUI
frame.setLayout(internalFrameLayout);
LookAndFeel.installBorder(frame, "InternalFrame.border");
frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
- // InternalFrames are invisible by default.
- frame.setVisible(false);
}
/**
@@ -1238,13 +1186,11 @@ public class BasicInternalFrameUI extends InternalFrameUI
borderListener = createBorderListener(frame);
componentListener = createComponentListener();
propertyChangeListener = createPropertyChangeListener();
- internalFrameVetoableChangeListener = new InternalFramePropertyChangeListener();
frame.addMouseListener(borderListener);
frame.addMouseMotionListener(borderListener);
frame.addInternalFrameListener(internalFrameListener);
frame.addPropertyChangeListener(propertyChangeListener);
- frame.addVetoableChangeListener(internalFrameVetoableChangeListener);
frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
index fd4cff56895..d0964f4733e 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java
@@ -53,6 +53,7 @@ import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.LabelUI;
+import javax.swing.text.View;
/**
* This is the Basic Look and Feel class for the JLabel. One BasicLabelUI
@@ -64,11 +65,22 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
protected static BasicLabelUI labelUI;
/**
+ * These fields hold the rectangles for the whole label,
+ * the icon and the text.
+ */
+ private Rectangle vr;
+ private Rectangle ir;
+ private Rectangle tr;
+
+ /**
* Creates a new BasicLabelUI object.
*/
public BasicLabelUI()
{
super();
+ vr = new Rectangle();
+ ir = new Rectangle();
+ tr = new Rectangle();
}
/**
@@ -99,13 +111,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
public Dimension getPreferredSize(JComponent c)
{
JLabel lab = (JLabel) c;
- Rectangle vr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
Insets insets = lab.getInsets();
FontMetrics fm = lab.getFontMetrics(lab.getFont());
layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr);
- Rectangle cr = tr.union(ir);
+ 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);
@@ -148,11 +158,6 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
public void paint(Graphics g, JComponent c)
{
JLabel b = (JLabel) c;
-
- Rectangle tr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle vr = new Rectangle();
-
FontMetrics fm = g.getFontMetrics();
vr = SwingUtilities.calculateInnerArea(c, vr);
@@ -168,13 +173,21 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
if (icon != null)
icon.paintIcon(b, g, ir.x, ir.y);
- if (text != null && !text.equals(""))
- {
- if (b.isEnabled())
- paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
- else
- paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
- }
+ Object htmlRenderer = b.getClientProperty(BasicHTML.propertyKey);
+ if (htmlRenderer == null)
+ {
+ if (text != null && !text.equals(""))
+ {
+ if (b.isEnabled())
+ paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
+ else
+ paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
+ }
+ }
+ else
+ {
+ ((View) htmlRenderer).paint(g, tr);
+ }
}
/**
@@ -312,7 +325,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
*/
protected void installComponents(JLabel c)
{
- //FIXME: fix javadoc + implement.
+ BasicHTML.updateRenderer(c, c.getText());
}
/**
@@ -322,7 +335,8 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
*/
protected void uninstallComponents(JLabel c)
{
- //FIXME: fix javadoc + implement.
+ c.putClientProperty(BasicHTML.propertyKey, null);
+ c.putClientProperty(BasicHTML.documentBaseKey, null);
}
/**
@@ -402,6 +416,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
*/
public void propertyChange(PropertyChangeEvent e)
{
- // What to do here?
+ if (e.getPropertyName().equals("text"))
+ {
+ String text = (String) e.getNewValue();
+ JLabel l = (JLabel) e.getSource();
+ BasicHTML.updateRenderer(l, text);
+ }
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
index 00d157a62c4..19dfe21f889 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java
@@ -64,6 +64,7 @@ import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.LookAndFeel;
+import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ListDataEvent;
@@ -135,6 +136,7 @@ public class BasicListUI extends ListUI
*/
public void contentsChanged(ListDataEvent e)
{
+ updateLayoutStateNeeded |= modelChanged;
list.revalidate();
}
@@ -145,6 +147,7 @@ public class BasicListUI extends ListUI
*/
public void intervalAdded(ListDataEvent e)
{
+ updateLayoutStateNeeded |= modelChanged;
list.revalidate();
}
@@ -155,6 +158,7 @@ public class BasicListUI extends ListUI
*/
public void intervalRemoved(ListDataEvent e)
{
+ updateLayoutStateNeeded |= modelChanged;
list.revalidate();
}
}
@@ -541,17 +545,21 @@ public class BasicListUI extends ListUI
*/
public void propertyChange(PropertyChangeEvent e)
{
- if (e.getSource() == BasicListUI.this.list)
+ if (e.getPropertyName().equals("model"))
{
if (e.getOldValue() != null && e.getOldValue() instanceof ListModel)
- ((ListModel) e.getOldValue()).removeListDataListener(BasicListUI.this.listDataListener);
-
+ {
+ ListModel oldModel = (ListModel) e.getOldValue();
+ oldModel.removeListDataListener(listDataListener);
+ }
if (e.getNewValue() != null && e.getNewValue() instanceof ListModel)
- ((ListModel) e.getNewValue()).addListDataListener(BasicListUI.this.listDataListener);
+ {
+ ListModel newModel = (ListModel) e.getNewValue();
+ newModel.addListDataListener(BasicListUI.this.listDataListener);
+ }
+
+ updateLayoutStateNeeded |= modelChanged;
}
- // Update the updateLayoutStateNeeded flag.
- if (e.getPropertyName().equals("model"))
- updateLayoutStateNeeded |= modelChanged;
else if (e.getPropertyName().equals("selectionModel"))
updateLayoutStateNeeded |= selectionModelChanged;
else if (e.getPropertyName().equals("font"))
@@ -720,14 +728,20 @@ public class BasicListUI extends ListUI
int minIndex = Math.min(index1, index2);
int maxIndex = Math.max(index1, index2);
Point loc = indexToLocation(list, minIndex);
- Rectangle bounds = new Rectangle(loc.x, loc.y, cellWidth,
+
+ // When the layoutOrientation is VERTICAL, then the width == the list
+ // width. Otherwise the cellWidth field is used.
+ int width = cellWidth;
+ if (l.getLayoutOrientation() == JList.VERTICAL)
+ width = l.getWidth();
+
+ Rectangle bounds = new Rectangle(loc.x, loc.y, width,
getCellHeight(minIndex));
for (int i = minIndex + 1; i <= maxIndex; i++)
{
Point hiLoc = indexToLocation(list, i);
- Rectangle hibounds = new Rectangle(hiLoc.x, hiLoc.y, cellWidth,
- getCellHeight(i));
- bounds = bounds.union(hibounds);
+ bounds = SwingUtilities.computeUnion(hiLoc.x, hiLoc.y, width,
+ getCellHeight(i), bounds);
}
return bounds;
@@ -883,8 +897,6 @@ public class BasicListUI extends ListUI
Dimension dim = flyweight.getPreferredSize();
cellWidth = Math.max(cellWidth, dim.width);
}
- if (list.getLayoutOrientation() == JList.VERTICAL)
- cellWidth = Math.max(cellWidth, list.getSize().width);
}
}
@@ -894,7 +906,7 @@ public class BasicListUI extends ListUI
*/
protected void maybeUpdateLayoutState()
{
- if (updateLayoutStateNeeded != 0 || !list.isValid())
+ if (updateLayoutStateNeeded != 0)
{
updateLayoutState();
updateLayoutStateNeeded = 0;
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
index f5217be1ff6..3451224beeb 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java
@@ -38,15 +38,24 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.AWTEvent;
import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.WeakHashMap;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
@@ -57,8 +66,11 @@ import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
+import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
@@ -77,6 +89,96 @@ import javax.swing.plaf.InsetsUIResource;
public abstract class BasicLookAndFeel extends LookAndFeel
implements Serializable
{
+
+ /**
+ * Helps closing menu popups when the user clicks outside of any menu area.
+ * This is implemented as an AWTEventListener that listens on the event
+ * queue directly, grabs all mouse events from there and finds out of they
+ * are targetted at a menu/submenu/menubar or not. If not,
+ * the MenuSelectionManager is messaged to close the currently opened menus,
+ * if any.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ private class PopupHelper implements AWTEventListener
+ {
+
+ /**
+ * Registered popups for autoclose.
+ */
+ private WeakHashMap autoClosePopups = new WeakHashMap();
+
+ /**
+ * Receives an event from the event queue.
+ *
+ * @param event
+ */
+ public void eventDispatched(AWTEvent event)
+ {
+ if (event instanceof MouseEvent)
+ {
+ MouseEvent mouseEvent = (MouseEvent) event;
+ if (mouseEvent.getID() == MouseEvent.MOUSE_PRESSED)
+ mousePressed(mouseEvent);
+ }
+ }
+
+ /**
+ * Handles mouse pressed events from the event queue.
+ *
+ * @param ev the mouse pressed event
+ */
+ private void mousePressed(MouseEvent ev)
+ {
+ // Autoclose all menus managed by the MenuSelectionManager.
+ MenuSelectionManager m = MenuSelectionManager.defaultManager();
+ Component target = ev.getComponent();
+ if (target instanceof Container)
+ target = ((Container) target).findComponentAt(ev.getPoint());
+ if (! m.isComponentPartOfCurrentMenu(target))
+ m.clearSelectedPath();
+
+ // Handle other registered popup instances, like ComboBox popups.
+ autoClosePopups(ev, target);
+ }
+
+ /**
+ * Registers Popup and its content to be autoclosed when a mouseclick
+ * occurs outside of the popup.
+ *
+ * @param popup the popup to be autoclosed when clicked outside
+ */
+ void registerForAutoClose(JPopupMenu popup)
+ {
+ autoClosePopups.put(popup, null);
+ }
+
+ /**
+ * Automatically closes all popups that are not 'hit' by the mouse event.
+ *
+ * @param ev the mouse event
+ * @param target the target of the mouse event
+ */
+ private void autoClosePopups(MouseEvent ev, Component target)
+ {
+ if (autoClosePopups.size() != 0)
+ {
+ Set popups = autoClosePopups.keySet();
+ Iterator i = popups.iterator();
+ while (i.hasNext())
+ {
+ JPopupMenu popup = (JPopupMenu) i.next();
+ if (!(target == popup
+ || SwingUtilities.isDescendingFrom(target, popup)))
+ {
+ popup.setVisible(false);
+ i.remove();
+ }
+ }
+ }
+ }
+ }
+
/**
* An action that can play an audio file.
*
@@ -137,6 +239,11 @@ public abstract class BasicLookAndFeel extends LookAndFeel
static final long serialVersionUID = -6096995660290287879L;
+ /**
+ * Helps closing menu popups when user clicks outside of the menu area.
+ */
+ private transient PopupHelper popupHelper;
+
private ActionMap audioActionMap;
/**
@@ -1023,6 +1130,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"SplitPane.dividerSize", new Integer(7),
"SplitPane.highlight", new ColorUIResource(highLight),
"SplitPane.shadow", new ColorUIResource(shadow),
+ "SplitPaneDivider.border", BasicBorders.getSplitPaneDividerBorder(),
+ "SplitPaneDivider.draggingColor", new ColorUIResource(Color.DARK_GRAY),
"TabbedPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
"ctrl PAGE_DOWN","navigatePageDown",
"ctrl PAGE_UP", "navigatePageUp",
@@ -1520,4 +1629,36 @@ public abstract class BasicLookAndFeel extends LookAndFeel
}
}
+ /**
+ * Initializes the Look and Feel.
+ */
+ public void initialize()
+ {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ popupHelper = new PopupHelper();
+ toolkit.addAWTEventListener(popupHelper, AWTEvent.MOUSE_EVENT_MASK);
+ }
+
+ /**
+ * Uninitializes the Look and Feel.
+ */
+ public void uninitialize()
+ {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ toolkit.removeAWTEventListener(popupHelper);
+ popupHelper = null;
+ }
+
+ /**
+ * Registers a JPopupMenu for autoclosing when a mouseclick occurs outside
+ * of the JPopupMenu. This must be called when the popup gets opened. The
+ * popup is unregistered from autoclosing as soon as it either got closed
+ * by this helper, or when it has been garbage collected.
+ *
+ * @param popup the popup menu to autoclose
+ */
+ void registerForAutoClose(JPopupMenu popup)
+ {
+ popupHelper.registerForAutoClose(popup);
+ }
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
index 63f0ce2068b..9166c49ee83 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java
@@ -610,8 +610,7 @@ public class BasicMenuItemUI extends MenuItemUI
Font f = m.getFont();
g.setFont(f);
FontMetrics fm = g.getFontMetrics(f);
- SwingUtilities.calculateInnerArea(m, br);
- SwingUtilities.calculateInsetArea(br, m.getInsets(), vr);
+ SwingUtilities.calculateInnerArea(m, vr);
paintBackground(g, m, background);
/*
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicPopupMenuUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicPopupMenuUI.java
index e15a17bab28..6ecd06b3988 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicPopupMenuUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicPopupMenuUI.java
@@ -37,28 +37,20 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import java.awt.AWTEvent;
import java.awt.Component;
-import java.awt.Container;
-import java.awt.Cursor;
import java.awt.Dimension;
-import java.awt.Point;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
-import javax.swing.JLayeredPane;
-import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.LookAndFeel;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
-import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
-import javax.swing.event.MouseInputListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.ComponentUI;
@@ -73,9 +65,6 @@ public class BasicPopupMenuUI extends PopupMenuUI
/* popupMenu for which this UI delegate is for*/
protected JPopupMenu popupMenu;
- /* MouseInputListener listens to mouse events. Package private for inner classes. */
- static transient MouseInputListener mouseInputListener;
-
/* PopupMenuListener listens to popup menu events fired by JPopupMenu*/
private transient PopupMenuListener popupMenuListener;
@@ -270,30 +259,9 @@ public class BasicPopupMenuUI extends PopupMenuUI
// remove listener that listens to component events fired
// by the top - level window that this popup belongs to.
Component invoker = popupMenu.getInvoker();
-
- RootPaneContainer rootContainer = (RootPaneContainer) SwingUtilities
- .getRoot(invoker);
+ Component rootContainer = SwingUtilities.getRoot(invoker);
if (rootContainer != null)
- {
- ((Container) rootContainer).removeComponentListener(topWindowListener);
-
- // If this popup menu is the last popup menu visible on the screen,
- // then
- // stop interrupting mouse events in the glass pane before hiding this
- // last popup menu.
- boolean topLevelMenu = (popupMenu.getInvoker() instanceof JMenu)
- && ((JMenu) popupMenu.getInvoker()).isTopLevelMenu();
-
- if (topLevelMenu || !(popupMenu.getInvoker() instanceof MenuElement))
- {
- // set glass pane not to interrupt mouse events and remove
- // mouseInputListener
- Container glassPane = (Container) rootContainer.getGlassPane();
- glassPane.setVisible(false);
- glassPane.removeMouseListener(mouseInputListener);
- mouseInputListener = null;
- }
- }
+ rootContainer.removeComponentListener(topWindowListener);
}
/**
@@ -307,20 +275,8 @@ public class BasicPopupMenuUI extends PopupMenuUI
// ComponentEvents fired by it. We need to cancel this popup menu
// if topWindow to which this popup belongs was resized or moved.
Component invoker = popupMenu.getInvoker();
- RootPaneContainer rootContainer = (RootPaneContainer) SwingUtilities
- .getRoot(invoker);
- ((Container) rootContainer).addComponentListener(topWindowListener);
-
- // Set the glass pane to interrupt all mouse events originating in root
- // container
- if (mouseInputListener == null)
- {
- Container glassPane = (Container) rootContainer.getGlassPane();
- glassPane.setVisible(true);
- mouseInputListener = new MouseInputHandler(rootContainer);
- glassPane.addMouseListener(mouseInputListener);
- glassPane.addMouseMotionListener(mouseInputListener);
- }
+ Component rootContainer = SwingUtilities.getRoot(invoker);
+ rootContainer.addComponentListener(topWindowListener);
// if this popup menu is a free floating popup menu,
// then by default its first element should be always selected when
@@ -399,275 +355,4 @@ public class BasicPopupMenuUI extends PopupMenuUI
}
}
- /**
- * MouseInputHandler listens to all mouse events originated in the root
- * container. This class is responsible for closing menu hierarchy when the
- * user presses mouse over any component that do not belong to the current
- * menu hierarchy. This is acomplished by interrupting all mouse event in
- * the glass pane and checking if other component was pressed while menu
- * was open, before redestributing events further to intended components
- */
- private class MouseInputHandler implements MouseInputListener
- {
- private JLayeredPane layeredPane;
- private Container glassPane;
- private Cursor nativeCursor;
- private transient Component mouseEventTarget;
- private transient Component pressedComponent;
- private transient Component lastComponentEntered;
- private transient Component tempComponent;
- private transient int pressCount;
-
- /**
- * Creates a new MouseInputHandler object.
- *
- * @param c the top most root container
- */
- public MouseInputHandler(RootPaneContainer c)
- {
- layeredPane = c.getLayeredPane();
- glassPane = (Container) c.getGlassPane();
- }
-
- /**
- * Handles mouse clicked event
- *
- * @param e Mouse event
- */
- public void mouseClicked(MouseEvent e)
- {
- handleEvent(e);
- }
-
- /**
- * Handles mouseDragged event
- *
- * @param e MouseEvent
- */
- public void mouseDragged(MouseEvent e)
- {
- handleEvent(e);
- }
-
- /**
- * Handles mouseEntered event
- *
- * @param e MouseEvent
- */
- public void mouseEntered(MouseEvent e)
- {
- handleEvent(e);
- }
-
- /**
- * Handles mouseExited event
- *
- * @param e MouseEvent
- */
- public void mouseExited(MouseEvent e)
- {
- handleEvent(e);
- }
-
- /**
- * Handles mouse moved event
- *
- * @param e MouseEvent
- */
- public void mouseMoved(MouseEvent e)
- {
- handleEvent(e);
- }
-
- /**
- * Handles mouse pressed event
- *
- * @param e MouseEvent
- */
- public void mousePressed(MouseEvent e)
- {
- handleEvent(e);
- }
-
- /**
- * Handles mouse released event
- *
- * @param e MouseEvent
- */
- public void mouseReleased(MouseEvent e)
- {
- handleEvent(e);
- }
-
- /*
- * This method determines component that was intended to received mouse
- * event, before it was interrupted within the glass pane. This method
- * also redispatches mouse entered and mouse exited events to the
- * appropriate components. This code is slightly modified code from
- * Container.LightweightDispatcher class, which is private inside
- * Container class and cannot be used here.
- */
- public void acquireComponentForMouseEvent(MouseEvent me)
- {
- int x = me.getX();
- int y = me.getY();
-
- // Find the candidate which should receive this event.
- Component parent = layeredPane;
- Component candidate = null;
- Point p = me.getPoint();
- while ((candidate == null) && (parent != null))
- {
- p = SwingUtilities.convertPoint(glassPane, p.x, p.y, parent);
- candidate = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
-
- if (candidate == null)
- {
- p = SwingUtilities.convertPoint(parent, p.x, p.y,
- parent.getParent());
- parent = parent.getParent();
- }
- }
-
- // If the only candidate we found was the native container itself,
- // don't dispatch any event at all. We only care about the lightweight
- // children here.
- if (candidate == layeredPane)
- candidate = null;
-
- // If our candidate is new, inform the old target we're leaving.
- if ((lastComponentEntered != null) && lastComponentEntered.isShowing()
- && (lastComponentEntered != candidate))
- {
- // Old candidate could have been removed from
- // the layeredPane so we check first.
- if (SwingUtilities.isDescendingFrom(lastComponentEntered, layeredPane))
- {
- Point tp = SwingUtilities.convertPoint(layeredPane, x, y,
- lastComponentEntered);
- MouseEvent exited = new MouseEvent(lastComponentEntered,
- MouseEvent.MOUSE_EXITED,
- me.getWhen(),
- me.getModifiersEx(), tp.x,
- tp.y, me.getClickCount(),
- me.isPopupTrigger(),
- me.getButton());
-
- tempComponent = lastComponentEntered;
- lastComponentEntered = null;
- tempComponent.dispatchEvent(exited);
- }
-
- lastComponentEntered = null;
- }
-
- // If we have a candidate, maybe enter it.
- if (candidate != null)
- {
- mouseEventTarget = candidate;
-
- if (candidate.isLightweight() && candidate.isShowing()
- && (candidate != layeredPane)
- && (candidate != lastComponentEntered))
- {
- lastComponentEntered = mouseEventTarget;
-
- Point cp = SwingUtilities.convertPoint(layeredPane, x, y,
- lastComponentEntered);
- MouseEvent entered = new MouseEvent(lastComponentEntered,
- MouseEvent.MOUSE_ENTERED,
- me.getWhen(),
- me.getModifiersEx(), cp.x,
- cp.y, me.getClickCount(),
- me.isPopupTrigger(),
- me.getButton());
- lastComponentEntered.dispatchEvent(entered);
- }
- }
-
- if ((me.getID() == MouseEvent.MOUSE_RELEASED)
- || ((me.getID() == MouseEvent.MOUSE_PRESSED) && (pressCount > 0))
- || (me.getID() == MouseEvent.MOUSE_DRAGGED))
- {
- // If any of the following events occur while a button is held down,
- // they should be dispatched to the same component to which the
- // original MOUSE_PRESSED event was dispatched:
- // - MOUSE_RELEASED
- // - MOUSE_PRESSED: another button pressed while the first is held down
- // - MOUSE_DRAGGED
- if (SwingUtilities.isDescendingFrom(pressedComponent, layeredPane))
- mouseEventTarget = pressedComponent;
- else if (me.getID() == MouseEvent.MOUSE_CLICKED)
- {
- // Don't dispatch CLICKED events whose target is not the same as the
- // target for the original PRESSED event.
- if (candidate != pressedComponent)
- mouseEventTarget = null;
- else if (pressCount == 0)
- pressedComponent = null;
- }
- }
- }
-
- /*
- * This method handles mouse events interrupted by glassPane. It
- * redispatches the mouse events appropriately to the intended components.
- * The code in this method is also taken from
- * Container.LightweightDispatcher class. The code is slightly modified
- * to handle the case when mouse is released over non-menu component. In
- * this case this method closes current menu hierarchy before
- * redispatching the event further.
- */
- public void handleEvent(AWTEvent e)
- {
- if (e instanceof MouseEvent)
- {
- MouseEvent me = (MouseEvent) e;
-
- acquireComponentForMouseEvent(me);
-
- // Avoid dispatching ENTERED and EXITED events twice.
- if (mouseEventTarget != null && mouseEventTarget.isShowing()
- && (e.getID() != MouseEvent.MOUSE_ENTERED)
- && (e.getID() != MouseEvent.MOUSE_EXITED))
- {
- MouseEvent newEvt = SwingUtilities.convertMouseEvent(glassPane,
- me,
- mouseEventTarget);
-
- mouseEventTarget.dispatchEvent(newEvt);
-
- // If mouse was clicked over the component that is not part
- // of menu hierarchy,then must close the menu hierarchy */
- if (e.getID() == MouseEvent.MOUSE_RELEASED)
- {
- boolean partOfMenuHierarchy = false;
- MenuSelectionManager manager = MenuSelectionManager
- .defaultManager();
-
- partOfMenuHierarchy = manager.isComponentPartOfCurrentMenu(mouseEventTarget);
-
- if (! partOfMenuHierarchy)
- manager.clearSelectedPath();
- }
-
- switch (e.getID())
- {
- case MouseEvent.MOUSE_PRESSED:
- if (pressCount++ == 0)
- pressedComponent = mouseEventTarget;
- break;
- case MouseEvent.MOUSE_RELEASED:
- // Clear our memory of the original PRESSED event, only if
- // we're not expecting a CLICKED event after this. If
- // there is a CLICKED event after this, it will do clean up.
- if ((--pressCount == 0)
- && (mouseEventTarget != pressedComponent))
- pressedComponent = null;
- break;
- }
- }
- }
- }
- }
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
index 8af5ff7f95c..f8f62e15651 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
@@ -45,7 +45,6 @@ import javax.swing.JMenuItem;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.UIDefaults;
-import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java
index 2a698e8a162..28e3b67c1a5 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicRootPaneUI.java
@@ -1,4 +1,4 @@
-/* BasicPanelUI.java --
+/* BasicRootPaneUI.java --
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,7 +43,6 @@ import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JRootPane;
-import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.RootPaneUI;
@@ -75,8 +74,7 @@ public class BasicRootPaneUI extends RootPaneUI
*/
protected void installDefaults(JRootPane rp)
{
- // Is this ok?
- rp.setBackground(UIManager.getColor("control"));
+ // TODO: What to do here, if anything? (might be a hook method)
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
index a2f5b82dbec..c8713c934dd 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -653,19 +653,17 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
if (scrollbar.getOrientation() == SwingConstants.HORIZONTAL)
{
- width += incrButton.getPreferredSize().getWidth();
- width += decrButton.getPreferredSize().getWidth();
-
- width += (scrollbar.getMaximum() - scrollbar.getMinimum());
- height = UIManager.getInt("ScrollBar.width");
+ width += incrButton.getPreferredSize().getWidth();
+ width += decrButton.getPreferredSize().getWidth();
+ width += 16;
+ height = UIManager.getInt("ScrollBar.width");
}
else
{
- height += incrButton.getPreferredSize().getHeight();
- height += decrButton.getPreferredSize().getHeight();
-
- height += (scrollbar.getMaximum() - scrollbar.getMinimum());
- width = UIManager.getInt("ScrollBar.width");
+ height += incrButton.getPreferredSize().getHeight();
+ height += decrButton.getPreferredSize().getHeight();
+ height += 16;
+ width = UIManager.getInt("ScrollBar.width");
}
Insets insets = scrollbar.getInsets();
@@ -721,18 +719,6 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
*/
protected void installComponents()
{
- if (incrButton != null)
- scrollbar.add(incrButton);
- if (decrButton != null)
- scrollbar.add(decrButton);
- }
-
- /**
- * This method installs the defaults for the scrollbar specified by the
- * Basic Look and Feel.
- */
- protected void installDefaults()
- {
int orientation = scrollbar.getOrientation();
switch (orientation)
{
@@ -746,6 +732,18 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
break;
}
+ if (incrButton != null)
+ scrollbar.add(incrButton);
+ if (decrButton != null)
+ scrollbar.add(decrButton);
+ }
+
+ /**
+ * This method installs the defaults for the scrollbar specified by the
+ * Basic Look and Feel.
+ */
+ protected void installDefaults()
+ {
LookAndFeel.installColors(scrollbar, "ScrollBar.background",
"ScrollBar.foreground");
LookAndFeel.installBorder(scrollbar, "ScrollBar.border");
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java
index 3b7399eafaa..6f7a41a1d96 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSpinnerUI.java
@@ -1,5 +1,5 @@
-/* SpinnerUI.java --
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+/* BasicSpinnerUI.java --
+ Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,6 +41,7 @@ package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
+import java.awt.Font;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
@@ -59,22 +60,21 @@ import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SpinnerUI;
/**
- * DOCUMENT ME!
+ * A UI delegate for the {@link JSpinner} component.
*
* @author Ka-Hing Cheung
*
- * @see javax.swing.JSpinner
* @since 1.4
*/
public class BasicSpinnerUI extends SpinnerUI
{
/**
- * Creates a new <code>ComponentUI</code> for the specified
+ * Creates a new <code>BasicSpinnerUI</code> for the specified
* <code>JComponent</code>
*
- * @param c DOCUMENT ME!
+ * @param c the component (ignored).
*
- * @return a ComponentUI
+ * @return A new instance of {@link BasicSpinnerUI}.
*/
public static ComponentUI createUI(JComponent c)
{
@@ -144,14 +144,15 @@ public class BasicSpinnerUI extends SpinnerUI
{
return new PropertyChangeListener()
{
- public void propertyChange(PropertyChangeEvent evt)
- {
- // FIXME: Add check for enabled property change. Need to
- // disable the buttons.
- if ("editor".equals(evt.getPropertyName()))
- BasicSpinnerUI.this.replaceEditor((JComponent) evt.getOldValue(),
- (JComponent) evt.getNewValue());
- }
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ // FIXME: Add check for enabled property change. Need to
+ // disable the buttons.
+ if ("editor".equals(event.getPropertyName()))
+ BasicSpinnerUI.this.replaceEditor((JComponent) event.getOldValue(),
+ (JComponent) event.getNewValue());
+ // FIXME: Handle 'font' property change
+ }
};
}
@@ -169,6 +170,12 @@ public class BasicSpinnerUI extends SpinnerUI
LookAndFeel.installColorsAndFont(spinner, "Spinner.background",
"Spinner.foreground", "Spinner.font");
LookAndFeel.installBorder(spinner, "Spinner.border");
+ JComponent e = spinner.getEditor();
+ if (e instanceof JSpinner.DefaultEditor)
+ {
+ JSpinner.DefaultEditor de = (JSpinner.DefaultEditor) e;
+ de.getTextField().setBorder(null);
+ }
spinner.setLayout(createLayout());
spinner.setOpaque(true);
}
@@ -352,7 +359,8 @@ public class BasicSpinnerUI extends SpinnerUI
private PropertyChangeListener listener = createPropertyChangeListener();
/**
- * DOCUMENT ME!
+ * A layout manager for the {@link JSpinner} component. The spinner has
+ * three subcomponents: an editor, a 'next' button and a 'previous' button.
*/
private class DefaultLayoutManager implements LayoutManager
{
@@ -365,58 +373,52 @@ public class BasicSpinnerUI extends SpinnerUI
{
synchronized (parent.getTreeLock())
{
- Insets i = parent.getInsets();
- boolean l2r = parent.getComponentOrientation().isLeftToRight();
- /*
- -------------- --------------
- | | n | | n | |
- | e | - | or | - | e |
- | | p | | p | |
- -------------- --------------
- */
- Dimension e = minSize(editor);
- Dimension n = minSize(next);
- Dimension p = minSize(previous);
- Dimension s = spinner.getPreferredSize();
-
- int x = l2r ? i.left : i.right;
- int y = i.top;
- int w = Math.max(p.width, n.width);
- int h = Math.max(p.height, n.height);
- h = Math.max(h, e.height / 2);
- int e_width = s.width - w;
-
- if (l2r)
- {
- setBounds(editor, x, y + (s.height - e.height) / 2, e_width,
- e.height);
- x += e_width;
-
- setBounds(next, x, y, w, h);
- y += h;
-
- setBounds(previous, x, y, w, h);
- }
- else
- {
- setBounds(next, x, y + (s.height - e.height) / 2, w, h);
- y += h;
-
- setBounds(previous, x, y, w, h);
- x += w;
- y -= h;
-
- setBounds(editor, x, y, e_width, e.height);
- }
+ Insets i = parent.getInsets();
+ boolean l2r = parent.getComponentOrientation().isLeftToRight();
+ /*
+ -------------- --------------
+ | | n | | n | |
+ | e | - | or | - | e |
+ | | p | | p | |
+ -------------- --------------
+ */
+ Dimension e = prefSize(editor);
+ Dimension n = prefSize(next);
+ Dimension p = prefSize(previous);
+ Dimension s = spinner.getPreferredSize();
+
+ int x = l2r ? i.left : i.right;
+ int y = i.top;
+ int w = Math.max(p.width, n.width);
+ int h = e.height / 2;
+ int e_width = s.width - w - i.left - i.right;
+
+ if (l2r)
+ {
+ setBounds(editor, x, y, e_width, 2 * h);
+ x += e_width;
+ setBounds(next, x, y, w, h);
+ y += h;
+ setBounds(previous, x, y, w, h);
+ }
+ else
+ {
+ setBounds(next, x, y + (s.height - e.height) / 2, w, h);
+ y += h;
+ setBounds(previous, x, y + (s.height - e.height) / 2, w, h);
+ x += w;
+ y -= h;
+ setBounds(editor, x, y, e_width, e.height);
+ }
}
}
/**
- * DOCUMENT ME!
+ * Calculates the minimum layout size.
*
- * @param parent DOCUMENT ME!
+ * @param parent the parent.
*
- * @return DOCUMENT ME!
+ * @return The minimum layout size.
*/
public Dimension minimumLayoutSize(Container parent)
{
@@ -424,36 +426,32 @@ public class BasicSpinnerUI extends SpinnerUI
if (editor != null)
{
- Dimension tmp = editor.getMinimumSize();
- d.width += tmp.width;
- d.height = tmp.height;
+ Dimension tmp = editor.getMinimumSize();
+ d.width += tmp.width;
+ d.height = tmp.height;
}
int nextWidth = 0;
int previousWidth = 0;
- int otherHeight = 0;
if (next != null)
{
- Dimension tmp = next.getMinimumSize();
- nextWidth = tmp.width;
- otherHeight += tmp.height;
+ Dimension tmp = next.getMinimumSize();
+ nextWidth = tmp.width;
}
if (previous != null)
{
- Dimension tmp = previous.getMinimumSize();
- previousWidth = tmp.width;
- otherHeight += tmp.height;
+ Dimension tmp = previous.getMinimumSize();
+ previousWidth = tmp.width;
}
- d.height = Math.max(d.height, otherHeight);
d.width += Math.max(nextWidth, previousWidth);
return d;
}
/**
- * DOCUMENT ME!
+ * Returns the preferred layout size of the container.
*
* @param parent DOCUMENT ME!
*
@@ -465,31 +463,29 @@ public class BasicSpinnerUI extends SpinnerUI
if (editor != null)
{
- Dimension tmp = editor.getPreferredSize();
- d.width += Math.max(tmp.width, 40);
- d.height = tmp.height;
+ Dimension tmp = editor.getPreferredSize();
+ d.width += Math.max(tmp.width, 40);
+ d.height = tmp.height;
}
int nextWidth = 0;
int previousWidth = 0;
- int otherHeight = 0;
if (next != null)
{
- Dimension tmp = next.getPreferredSize();
- nextWidth = tmp.width;
- otherHeight += tmp.height;
+ Dimension tmp = next.getPreferredSize();
+ nextWidth = tmp.width;
}
if (previous != null)
{
- Dimension tmp = previous.getPreferredSize();
- previousWidth = tmp.width;
- otherHeight += tmp.height;
+ Dimension tmp = previous.getPreferredSize();
+ previousWidth = tmp.width;
}
- d.height = Math.max(d.height, otherHeight);
d.width += Math.max(nextWidth, previousWidth);
-
+ Insets insets = parent.getInsets();
+ d.width = d.width + insets.left + insets.right;
+ d.height = d.height + insets.top + insets.bottom;
return d;
}
@@ -501,11 +497,11 @@ public class BasicSpinnerUI extends SpinnerUI
public void removeLayoutComponent(Component child)
{
if (child == editor)
- editor = null;
+ editor = null;
else if (child == next)
- next = null;
+ next = null;
else if (previous == child)
- previous = null;
+ previous = null;
}
/**
@@ -517,11 +513,11 @@ public class BasicSpinnerUI extends SpinnerUI
public void addLayoutComponent(String name, Component child)
{
if ("Editor".equals(name))
- editor = child;
+ editor = child;
else if ("Next".equals(name))
- next = child;
+ next = child;
else if ("Previous".equals(name))
- previous = child;
+ previous = child;
}
/**
@@ -531,36 +527,36 @@ public class BasicSpinnerUI extends SpinnerUI
*
* @return DOCUMENT ME!
*/
- private Dimension minSize(Component c)
+ private Dimension prefSize(Component c)
{
if (c == null)
- return new Dimension();
+ return new Dimension();
else
- return c.getMinimumSize();
+ return c.getPreferredSize();
}
/**
- * DOCUMENT ME!
+ * Sets the bounds for the specified component.
*
- * @param c DOCUMENT ME!
- * @param x DOCUMENT ME!
- * @param y DOCUMENT ME!
- * @param w DOCUMENT ME!
- * @param h DOCUMENT ME!
+ * @param c the component.
+ * @param x the x-coordinate for the top-left of the component bounds.
+ * @param y the y-coordinate for the top-left of the component bounds.
+ * @param w the width of the bounds.
+ * @param h the height of the bounds.
*/
private void setBounds(Component c, int x, int y, int w, int h)
{
if (c != null)
- c.setBounds(x, y, w, h);
+ c.setBounds(x, y, w, h);
}
- /** DOCUMENT ME! */
+ /** The editor component. */
private Component editor;
- /** DOCUMENT ME! */
+ /** The next button. */
private Component next;
- /** DOCUMENT ME! */
+ /** The previous button. */
private Component previous;
}
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java
index ff17ff084c2..06d32984efb 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java
@@ -38,7 +38,6 @@ 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;
@@ -161,31 +160,6 @@ public class BasicSplitPaneDivider extends Container
*/
transient int currentDividerLocation = 1;
- /** DOCUMENT ME! */
- private transient Border tmpBorder = new Border()
- {
- public Insets getBorderInsets(Component c)
- {
- return new Insets(2, 2, 2, 2);
- }
-
- public boolean isBorderOpaque()
- {
- return false;
- }
-
- public void paintBorder(Component c, Graphics g, int x, int y,
- int width, int height)
- {
- Color saved = g.getColor();
- g.setColor(Color.BLACK);
-
- g.drawRect(x + 2, y + 2, width - 4, height - 4);
-
- g.setColor(saved);
- }
- };
-
/**
* Constructs a new divider.
*
@@ -196,7 +170,6 @@ public class BasicSplitPaneDivider extends Container
setLayout(new DividerLayout());
setBasicSplitPaneUI(ui);
setDividerSize(splitPane.getDividerSize());
- setBorder(tmpBorder);
}
/**
@@ -212,8 +185,6 @@ public class BasicSplitPaneDivider extends Container
if (splitPane != null)
{
splitPane.removePropertyChangeListener(this);
- splitPane.removeMouseListener(mouseHandler);
- splitPane.removeMouseMotionListener(mouseHandler);
removeMouseListener(mouseHandler);
removeMouseMotionListener(mouseHandler);
splitPane = null;
@@ -227,8 +198,6 @@ public class BasicSplitPaneDivider extends Container
if (splitPane != null)
{
splitPane.addPropertyChangeListener(this);
- splitPane.addMouseListener(mouseHandler);
- splitPane.addMouseMotionListener(mouseHandler);
addMouseListener(mouseHandler);
addMouseMotionListener(mouseHandler);
hiddenDivider = splitPaneUI.getNonContinuousLayoutDivider();
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
index cf31e8b5df1..8a7c9d2a290 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java
@@ -62,6 +62,7 @@ import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SplitPaneUI;
+import javax.swing.plaf.UIResource;
/**
* This is the Basic Look and Feel implementation of the SplitPaneUI class.
@@ -253,20 +254,21 @@ public class BasicSplitPaneUI extends SplitPaneUI
JSplitPane split = (JSplitPane) container;
distributeExtraSpace();
Insets insets = split.getInsets();
- int width = getInitialLocation(insets);
Dimension dims = split.getSize();
- for (int i = 0; i < components.length; i += 2)
- {
- if (components[i] == null)
- continue;
- setComponentToSize(components[i], sizes[i], width, insets, dims);
- width += sizes[i];
- }
- if (components[1] != null)
- {
- setComponentToSize(components[1], sizes[1], width, insets, dims);
- width += sizes[1];
- }
+ int loc = getInitialLocation(insets);
+ int available = getAvailableSize(dims, insets);
+ sizes[0] = getDividerLocation(split) - loc;
+ sizes[1] = available - sizes[0] - sizes[2];
+ // The size of the divider won't change.
+
+ // Layout component#1.
+ setComponentToSize(components[0], sizes[0], loc, insets, dims);
+ // Layout divider.
+ loc += sizes[0];
+ setComponentToSize(components[2], sizes[2], loc, insets, dims);
+ // Layout component#2.
+ loc += sizes[2];
+ setComponentToSize(components[1], sizes[1], loc, insets, dims);
}
}
@@ -388,6 +390,8 @@ public class BasicSplitPaneUI extends SplitPaneUI
{
for (int i = 0; i < components.length; i++)
resetSizeAt(i);
+ setDividerLocation(splitPane,
+ getInitialLocation(splitPane.getInsets()) + sizes[0]);
}
/**
@@ -451,21 +455,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
void distributeExtraSpace()
{
- int availSize = getAvailableSize(splitPane.getSize(),
- splitPane.getInsets());
- int[] newSizes = new int[3];
- double weight = splitPane.getResizeWeight();
-
- int oldLen = sizes[0] + sizes[1];
-
- // dividers don't change size.
- availSize -= sizes[2] + oldLen;
-
- int rightAlloc = (int) (availSize * (1 - weight));
- int leftAlloc = availSize - rightAlloc;
-
- sizes[0] += leftAlloc;
- sizes[1] += rightAlloc;
+ // FIXME: This needs to be reimplemented correctly.
}
/**
@@ -835,8 +825,6 @@ public class BasicSplitPaneUI extends SplitPaneUI
if (prop <= 1 && prop >= 0)
splitPane.setDividerLocation(prop);
}
- layoutManager.layoutContainer(splitPane);
- splitPane.repaint();
// Don't have to deal with continuous_layout - only
// necessary in dragging modes (and it's checked
// every time you drag there)
@@ -933,6 +921,8 @@ public class BasicSplitPaneUI extends SplitPaneUI
/** The JSplitPane that this UI draws. */
protected JSplitPane splitPane;
+ private int dividerLocation;
+
/**
* Creates a new BasicSplitPaneUI object.
*/
@@ -992,6 +982,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
"SplitPane.foreground");
LookAndFeel.installBorder(splitPane, "SplitPane.border");
divider = createDefaultDivider();
+ divider.setBorder(UIManager.getBorder("SplitPaneDivider.border"));
resetLayoutManager();
nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider();
splitPane.add(divider, JSplitPane.DIVIDER);
@@ -1012,8 +1003,10 @@ public class BasicSplitPaneUI extends SplitPaneUI
divider = null;
nonContinuousLayoutDivider = null;
- splitPane.setBackground(null);
- splitPane.setBorder(null);
+ if (splitPane.getBackground() instanceof UIResource)
+ splitPane.setBackground(null);
+ if (splitPane.getBorder() instanceof UIResource)
+ splitPane.setBorder(null);
}
/**
@@ -1219,7 +1212,8 @@ public class BasicSplitPaneUI extends SplitPaneUI
if (nonContinuousLayoutDivider == null)
{
nonContinuousLayoutDivider = new Canvas();
- nonContinuousLayoutDivider.setBackground(Color.DARK_GRAY);
+ Color c = UIManager.getColor("SplitPaneDivider.draggingColor");
+ nonContinuousLayoutDivider.setBackground(c);
}
return nonContinuousLayoutDivider;
}
@@ -1298,44 +1292,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public void setDividerLocation(JSplitPane jc, int location)
{
- location = validLocation(location);
- Container p = jc.getParent();
- Component right = jc.getRightComponent();
- Dimension rightPrefSize = right == null ? new Dimension(0, 0)
- : right.getPreferredSize();
- Dimension size = jc.getSize();
- // check if the size has been set for the splitpane
- if (size.width == 0 && size.height == 0)
- size = jc.getPreferredSize();
-
- if (getOrientation() == 0 && location > size.height)
- {
- location = size.height;
- while (p != null)
- {
- p.setSize(p.getWidth(), p.getHeight() + rightPrefSize.height);
- p = p.getParent();
- }
- }
- else if (location > size.width)
- {
- location = size.width;
- while (p != null)
- {
- p.setSize(p.getWidth() + rightPrefSize.width, p.getHeight());
- p = p.getParent();
- }
- }
-
- setLastDragLocation(getDividerLocation(splitPane));
- splitPane.setLastDividerLocation(getDividerLocation(splitPane));
- int[] tmpSizes = layoutManager.getSizes();
- tmpSizes[0] = location
- - layoutManager.getInitialLocation(splitPane.getInsets());
- tmpSizes[1] = layoutManager.getAvailableSize(splitPane.getSize(),
- splitPane.getInsets())
- - tmpSizes[0];
- layoutManager.setSizes(tmpSizes);
+ dividerLocation = location;
splitPane.revalidate();
splitPane.repaint();
}
@@ -1349,8 +1306,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
*/
public int getDividerLocation(JSplitPane jc)
{
- return layoutManager.sizes[0]
- + layoutManager.getInitialLocation(splitPane.getInsets());
+ return dividerLocation;
}
/**
@@ -1365,7 +1321,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
{
int value = layoutManager.getInitialLocation(jc.getInsets());
if (layoutManager.components[0] != null)
- value -= layoutManager.minimumSizeOfComponent(0);
+ value += layoutManager.minimumSizeOfComponent(0);
return value;
}
@@ -1501,8 +1457,6 @@ public class BasicSplitPaneUI extends SplitPaneUI
nonContinuousLayoutDivider.setVisible(true);
nonContinuousLayoutDivider.setBounds(divider.getBounds());
}
- splitPane.revalidate();
- splitPane.repaint();
}
/**
@@ -1544,11 +1498,9 @@ public class BasicSplitPaneUI extends SplitPaneUI
nonContinuousLayoutDivider.setVisible(false);
draggingHW = false;
location = validLocation(location);
- dragDividerTo(location);
splitPane.setDividerLocation(location);
splitPane.setLastDividerLocation(beginDragDividerLocation);
beginDragDividerLocation = -1;
- splitPane.repaint();
}
/**
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index a8f52cef617..5b1e1ff0f60 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -451,6 +451,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
}
}
runCount = runs;
+ if (runCount > tabRuns.length)
+ expandTabRunsArray();
tabRuns[0] = 0;
normalizeTabRuns(tabPlacement, tabCount, start, max);
@@ -1025,6 +1027,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
}
}
runCount = runs;
+ if (runCount > tabRuns.length)
+ expandTabRunsArray();
padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
}
@@ -1733,9 +1737,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int tabCount = tabPane.getTabCount();
int currRun = 1;
- if (tabCount > runCount)
- runCount = tabCount;
-
if (tabCount < 1)
return;
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java
index 9c8a5ef9598..1e8e39f38c2 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java
@@ -39,14 +39,18 @@ exception statement from your version. */
package javax.swing.plaf.basic;
import java.awt.Component;
+import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.CellRendererPane;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
+import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.MouseInputListener;
@@ -57,62 +61,346 @@ import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
+/**
+ * Basic pluggable look and feel interface for JTableHeader.
+ */
public class BasicTableHeaderUI extends TableHeaderUI
{
-
+ /**
+ * The width of the space (in both direction) around the column boundary,
+ * where mouse cursor changes shape into "resize"
+ */
+ static int COLUMN_BOUNDARY_TOLERANCE = 3;
+
public static ComponentUI createUI(JComponent h)
{
return new BasicTableHeaderUI();
}
-
+
+ /**
+ * The table header that is using this interface.
+ */
protected JTableHeader header;
+
+ /**
+ * The mouse input listener, responsible for mouse manipulations with
+ * the table header.
+ */
protected MouseInputListener mouseInputListener;
+
+ /**
+ * Paint the header cell.
+ */
protected CellRendererPane rendererPane;
+
+ /**
+ * The header cell border.
+ */
protected Border cellBorder;
-
- public class MouseInputHandler implements MouseInputListener
+
+ /**
+ * If not null, one of the columns is currently being dragged.
+ */
+ Rectangle draggingHeaderRect;
+
+ /**
+ * Handles column movement and rearrangement by mouse. The same instance works
+ * both as mouse listener and the mouse motion listner.
+ */
+ public class MouseInputHandler
+ implements MouseInputListener
{
+ /**
+ * If true, the cursor is being already shown in the alternative "resize"
+ * shape.
+ */
+ boolean showingResizeCursor;
+
+ /**
+ * The position, from where the cursor is dragged during resizing. Double
+ * purpose field (absolute value during resizing and relative offset during
+ * column dragging).
+ */
+ int draggingFrom = - 1;
+
+ /**
+ * The number of the column being dragged.
+ */
+ int draggingColumnNumber;
+
+ /**
+ * The previous preferred width of the column.
+ */
+ int prevPrefWidth = - 1;
+
+ /**
+ * The timer to coalesce column resizing events.
+ */
+ Timer timer;
+
+ /**
+ * Returns without action, part of the MouseInputListener interface.
+ */
public void mouseClicked(MouseEvent e)
{
- // TODO: Implement this properly.
+ // Nothing to do.
}
+ /**
+ * If being in the resizing mode, handle resizing.
+ */
public void mouseDragged(MouseEvent e)
{
- // TODO: Implement this properly.
+ TableColumn resizeIt = header.getResizingColumn();
+ if (resizeIt != null && header.getResizingAllowed())
+ {
+ // The timer is intialised on demand.
+ if (timer == null)
+ {
+ // The purpose of timer is to coalesce events. If the queue
+ // is free, the repaint event is fired immediately.
+ timer = new Timer(1, new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ header.getTable().doLayout();
+ }
+ });
+ timer.setRepeats(false);
+ timer.setCoalesce(true);
+ }
+ resizeIt.setPreferredWidth(prevPrefWidth + e.getX() - draggingFrom);
+ timer.restart();
+ }
+ else if (draggingHeaderRect != null && header.getReorderingAllowed())
+ {
+ draggingHeaderRect.x = e.getX() + draggingFrom;
+ header.repaint();
+ }
}
+ /**
+ * Returns without action, part of the MouseInputListener interface.
+ */
public void mouseEntered(MouseEvent e)
{
- // TODO: Implement this properly.
+ // Nothing to do.
}
+ /**
+ * Reset drag information of the column resizing.
+ */
public void mouseExited(MouseEvent e)
{
- // TODO: Implement this properly.
+ if (header.getResizingColumn() != null && header.getResizingAllowed())
+ endResizing();
+ if (header.getDraggedColumn() != null && header.getReorderingAllowed())
+ endDragging(null);
}
+ /**
+ * Change the mouse cursor if the mouse if above the column boundary.
+ */
public void mouseMoved(MouseEvent e)
{
- // TODO: Implement this properly.
+ // When dragging, the functionality is handled by the mouseDragged.
+ if (e.getButton() == 0 && header.getResizingAllowed())
+ {
+ TableColumnModel model = header.getColumnModel();
+ int n = model.getColumnCount();
+ if (n < 2)
+ // It must be at least two columns to have at least one boundary.
+ // Otherwise, nothing to do.
+ return;
+
+ boolean onBoundary = false;
+
+ int x = e.getX();
+ int a = x - COLUMN_BOUNDARY_TOLERANCE;
+ int b = x + COLUMN_BOUNDARY_TOLERANCE;
+
+ int p = 0;
+
+ Scan: for (int i = 0; i < n - 1; i++)
+ {
+ p += model.getColumn(i).getWidth();
+
+ if (p >= a && p <= b)
+ {
+ TableColumn column = model.getColumn(i);
+ onBoundary = true;
+
+ draggingFrom = x;
+ prevPrefWidth = column.getWidth();
+ header.setResizingColumn(column);
+ break Scan;
+ }
+ }
+
+ if (onBoundary != showingResizeCursor)
+ {
+ // Change the cursor shape, if needed.
+ if (onBoundary)
+ {
+
+ if (p < x)
+ header.setCursor(Cursor.getPredefinedCursor
+ (Cursor.W_RESIZE_CURSOR));
+ else
+ header.setCursor(Cursor.getPredefinedCursor
+ (Cursor.E_RESIZE_CURSOR));
+ }
+ else
+ {
+ header.setCursor(Cursor.getDefaultCursor());
+ header.setResizingColumn(null);
+ }
+
+ showingResizeCursor = onBoundary;
+ }
+ }
}
+ /**
+ * Starts the dragging/resizing procedure.
+ */
public void mousePressed(MouseEvent e)
{
- // TODO: Implement this properly.
+ if (header.getResizingAllowed())
+ {
+ TableColumn resizingColumn = header.getResizingColumn();
+ if (resizingColumn != null)
+ {
+ resizingColumn.setPreferredWidth(resizingColumn.getWidth());
+ return;
+ }
+ }
+
+ if (header.getReorderingAllowed())
+ {
+ TableColumnModel model = header.getColumnModel();
+ int n = model.getColumnCount();
+ if (n < 2)
+ // It must be at least two columns to change the column location.
+ return;
+
+ boolean onBoundary = false;
+
+ int x = e.getX();
+ int p = 0;
+ int col = - 1;
+
+ Scan: for (int i = 0; i < n; i++)
+ {
+ p += model.getColumn(i).getWidth();
+ if (p > x)
+ {
+ col = i;
+ break Scan;
+ }
+ }
+ if (col < 0)
+ return;
+
+ TableColumn dragIt = model.getColumn(col);
+ header.setDraggedColumn(dragIt);
+
+ draggingFrom = (p - dragIt.getWidth()) - x;
+ draggingHeaderRect = new Rectangle(header.getHeaderRect(col));
+ draggingColumnNumber = col;
+ }
}
+ /**
+ * Set all column preferred width to the current width to prevend abrupt
+ * width changes during the next resize.
+ */
public void mouseReleased(MouseEvent e)
{
- // TODO: Implement this properly.
+ if (header.getResizingColumn() != null && header.getResizingAllowed())
+ endResizing();
+ if (header.getDraggedColumn() != null && header.getReorderingAllowed())
+ endDragging(e);
+ }
+
+ /**
+ * Stop resizing session.
+ */
+ void endResizing()
+ {
+ TableColumnModel model = header.getColumnModel();
+ int n = model.getColumnCount();
+ if (n > 2)
+ {
+ TableColumn c;
+ for (int i = 0; i < n; i++)
+ {
+ c = model.getColumn(i);
+ c.setPreferredWidth(c.getWidth());
+ }
+ }
+ header.setResizingColumn(null);
+ showingResizeCursor = false;
+ if (timer != null)
+ timer.stop();
+ header.setCursor(Cursor.getDefaultCursor());
}
- }
+ /**
+ * Stop the dragging session.
+ *
+ * @param e the "mouse release" mouse event, needed to determing the final
+ * location for the dragged column.
+ */
+ void endDragging(MouseEvent e)
+ {
+ header.setDraggedColumn(null);
+
+ // Return if the mouse have left the header area while pressed.
+ if (e == null)
+ {
+ header.repaint(draggingHeaderRect);
+ draggingHeaderRect = null;
+ return;
+ }
+ else
+ draggingHeaderRect = null;
+
+ TableColumnModel model = header.getColumnModel();
+
+ // Find where have we dragged the column.
+ int x = e.getX();
+ int p = 0;
+ int col = - 1;
+ int n = model.getColumnCount();
+
+ Scan: for (int i = 0; i < n; i++)
+ {
+ p += model.getColumn(i).getWidth();
+ if (p > x)
+ {
+ col = i;
+ break Scan;
+ }
+ }
+ if (col >= 0)
+ header.getTable().moveColumn(draggingColumnNumber, col);
+ }
+ }
+
+ /**
+ * Create and return the mouse input listener.
+ *
+ * @return the mouse listener ({@link MouseInputHandler}, if not overridden.
+ */
protected MouseInputListener createMouseInputListener()
{
return new MouseInputHandler();
}
-
+
+ /**
+ * Construct a new BasicTableHeaderUI, create mouse listeners.
+ */
public BasicTableHeaderUI()
{
mouseInputListener = createMouseInputListener();
@@ -131,9 +419,15 @@ public class BasicTableHeaderUI extends TableHeaderUI
// TODO: Implement this properly.
}
+ /**
+ * Add the mouse listener and the mouse motion listener to the table
+ * header. The listeners support table column resizing and rearrangement
+ * by mouse.
+ */
protected void installListeners()
{
header.addMouseListener(mouseInputListener);
+ header.addMouseMotionListener(mouseInputListener);
}
public void installUI(JComponent c)
@@ -156,10 +450,14 @@ public class BasicTableHeaderUI extends TableHeaderUI
{
// TODO: Implement this properly.
}
-
+
+ /**
+ * Remove the previously installed listeners.
+ */
protected void uninstallListeners()
{
header.removeMouseListener(mouseInputListener);
+ header.removeMouseMotionListener(mouseInputListener);
}
public void uninstallUI(JComponent c)
@@ -168,7 +466,10 @@ public class BasicTableHeaderUI extends TableHeaderUI
uninstallKeyboardActions();
uninstallDefaults();
}
-
+
+ /**
+ * Repaint the table header.
+ */
public void paint(Graphics gfx, JComponent c)
{
TableColumnModel cmod = header.getColumnModel();
@@ -206,10 +507,26 @@ public class BasicTableHeaderUI extends TableHeaderUI
bounds.width, bounds.height);
}
}
-
+
+ // This displays a running rectangle that is much simplier than the total
+ // animation, as it is seen in Sun's application.
+ // TODO animate the collumn dragging like in Sun's jre.
+ if (draggingHeaderRect!=null)
+ {
+ gfx.setColor(header.getForeground());
+ gfx.drawRect(draggingHeaderRect.x, draggingHeaderRect.y+2,
+ draggingHeaderRect.width-1, draggingHeaderRect.height-6);
+ }
}
- public Dimension getPreferredSize(JComponent c)
+ /**
+ * Get the preferred header size.
+ *
+ * @param ignored unused
+ *
+ * @return the preferred size of the associated header.
+ */
+ public Dimension getPreferredSize(JComponent ignored)
{
TableColumnModel cmod = header.getColumnModel();
TableCellRenderer defaultRend = header.getDefaultRenderer();
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
index 18b69120d11..8360a9ec771 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java
@@ -58,11 +58,11 @@ import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.CellRendererPane;
+import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListSelectionModel;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JTable;
-import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.LookAndFeel;
@@ -74,8 +74,8 @@ import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TableUI;
+import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
-import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
@@ -193,10 +193,31 @@ public class BasicTableUI extends TableUI
colModel.setSelectionInterval(lo_col, hi_col);
}
}
-
- public void mouseClicked(MouseEvent e)
+
+ /**
+ * For the double click, start the cell editor.
+ */
+ public void mouseClicked(MouseEvent e)
{
- // TODO: What should be done here, if anything?
+ Point p = e.getPoint();
+ int row = table.rowAtPoint(p);
+ int col = table.columnAtPoint(p);
+ if (table.isCellEditable(row, col))
+ {
+ // If the cell editor is the default editor, we request the
+ // number of the required clicks from it. Otherwise,
+ // require two clicks (double click).
+ TableCellEditor editor = table.getCellEditor(row, col);
+ if (editor instanceof DefaultCellEditor)
+ {
+ DefaultCellEditor ce = (DefaultCellEditor) editor;
+ if (e.getClickCount() < ce.getClickCountToStart())
+ return;
+ }
+ else if (e.getClickCount() < 2)
+ return;
+ table.editCellAt(row, col);
+ }
}
public void mouseDragged(MouseEvent e)
@@ -354,7 +375,8 @@ public class BasicTableUI extends TableUI
maxTotalColumnWidth += table.getColumnModel().getColumn(i).getMaxWidth();
if (maxTotalColumnWidth == 0 || table.getRowCount() == 0)
return null;
- return new Dimension(maxTotalColumnWidth, table.getRowCount()*table.getRowHeight());
+ return new Dimension(maxTotalColumnWidth, table.getRowCount()*
+ (table.getRowHeight()+table.getRowMargin()));
}
/**
@@ -380,7 +402,7 @@ public class BasicTableUI extends TableUI
public Dimension getPreferredSize(JComponent comp)
{
int width = table.getColumnModel().getTotalColumnWidth();
- int height = table.getRowCount() * table.getRowHeight();
+ int height = table.getRowCount() * (table.getRowHeight()+table.getRowMargin());
return new Dimension(width, height);
}
@@ -854,6 +876,10 @@ public class BasicTableUI extends TableUI
rowModel.setAnchorSelectionIndex(rowLead);
colModel.setAnchorSelectionIndex(colLead);
}
+ else if (command.equals("stopEditing"))
+ {
+ table.editingStopped(new ChangeEvent(command));
+ }
else
{
// If we're here that means we bound this TableAction class
@@ -1185,30 +1211,17 @@ public class BasicTableUI extends TableUI
* system beginning at <code>(0,0)</code> in the upper left corner of the
* table
* @param rend A cell renderer to paint with
- * @param data The data to provide to the cell renderer
- * @param rowLead The lead selection for the rows of the table.
- * @param colLead The lead selection for the columns of the table.
*/
void paintCell(Graphics g, int row, int col, Rectangle bounds,
- TableCellRenderer rend, TableModel data,
- int rowLead, int colLead)
+ TableCellRenderer rend)
{
Component comp = table.prepareRenderer(rend, row, col);
rendererPane.paintComponent(g, comp, table, bounds);
-
- // FIXME: this is manual painting of the Caret, why doesn't the
- // JTextField take care of this itself?
- if (comp instanceof JTextField)
- {
- Rectangle oldClip = g.getClipBounds();
- g.translate(bounds.x, bounds.y);
- g.clipRect(0, 0, bounds.width, bounds.height);
- ((JTextField)comp).getCaret().paint(g);
- g.translate(-bounds.x, -bounds.y);
- g.setClip(oldClip);
- }
}
+ /**
+ * Paint the associated table.
+ */
public void paint(Graphics gfx, JComponent ignored)
{
int ncols = table.getColumnCount();
@@ -1217,59 +1230,72 @@ public class BasicTableUI extends TableUI
return;
Rectangle clip = gfx.getClipBounds();
- TableColumnModel cols = table.getColumnModel();
-
- int height = table.getRowHeight();
- int x0 = 0, y0 = 0;
- int x = x0;
- int y = y0;
-
- Dimension gap = table.getIntercellSpacing();
- int ymax = clip.y + clip.height;
- int xmax = clip.x + clip.width;
+ // Determine the range of cells that are within the clip bounds.
+ Point p1 = new Point(clip.x, clip.y);
+ int c0 = table.columnAtPoint(p1);
+ if (c0 == -1)
+ c0 = 0;
+ int r0 = table.rowAtPoint(p1);
+ if (r0 == -1)
+ r0 = 0;
+ Point p2 = new Point(clip.x + clip.width, clip.y + clip.height);
+ int cn = table.columnAtPoint(p2);
+ if (cn == -1)
+ cn = table.getColumnCount() - 1;
+ int rn = table.rowAtPoint(p2);
+ if (rn == -1)
+ rn = table.getRowCount() - 1;
+
+ TableColumnModel cmodel = table.getColumnModel();
+ int [] widths = new int[cn+1];
+ for (int i = c0; i <=cn ; i++)
+ {
+ widths[i] = cmodel.getColumn(i).getWidth();
+ }
+
+ Rectangle bounds = table.getCellRect(r0, c0, false);
+ bounds.height = table.getRowHeight()+table.getRowMargin();
+
+ // The left boundary of the area being repainted.
+ int left = bounds.x;
+
+ // The top boundary of the area being repainted.
+ int top = bounds.y;
+
+ // The bottom boundary of the area being repainted.
+ int bottom;
+
+ // The cell height.
+ int height = bounds.height;
+
// paint the cell contents
- for (int c = 0; c < ncols && x < xmax; ++c)
+ Color grid = table.getGridColor();
+ for (int r = r0; r <= rn; ++r)
{
- y = y0;
- TableColumn col = cols.getColumn(c);
- int width = col.getWidth();
- int halfGapWidth = gap.width / 2;
- int halfGapHeight = gap.height / 2;
- for (int r = 0; r < nrows && y < ymax; ++r)
+ for (int c = c0; c <= cn; ++c)
{
- Rectangle bounds = new Rectangle(x + halfGapWidth,
- y + halfGapHeight + 1,
- width - gap.width + 1,
- height - gap.height);
- if (bounds.intersects(clip))
- {
- paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c),
- table.getModel(),
- table.getSelectionModel().getLeadSelectionIndex(),
- table.getColumnModel().getSelectionModel().getLeadSelectionIndex());
- }
- y += height;
+ bounds.width = widths[c];
+ paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c));
+ bounds.x += widths[c];
}
- x += width;
+ bounds.y += height;
+ bounds.x = left;
}
-
- // tighten up the x and y max bounds
- ymax = y;
- xmax = x;
-
- Color grid = table.getGridColor();
+
+ bottom = bounds.y;
// paint vertical grid lines
if (grid != null && table.getShowVerticalLines())
{
- x = x0;
Color save = gfx.getColor();
gfx.setColor(grid);
- for (int c = 0; c < ncols && x < xmax; ++c)
+ int x = left;
+
+ for (int c = c0; c <= cn; ++c)
{
- x += cols.getColumn(c).getWidth();
- gfx.drawLine(x, y0, x, ymax);
+ gfx.drawLine(x, top, x, bottom);
+ x += widths[c];
}
gfx.setColor(save);
}
@@ -1277,13 +1303,13 @@ public class BasicTableUI extends TableUI
// paint horizontal grid lines
if (grid != null && table.getShowHorizontalLines())
{
- y = y0;
Color save = gfx.getColor();
gfx.setColor(grid);
- for (int r = 0; r < nrows && y < ymax; ++r)
+ int y = top;
+ for (int r = r0; r <= rn; ++r)
{
+ gfx.drawLine(left, y, p2.x, y);
y += height;
- gfx.drawLine(x0, y, xmax, y);
}
gfx.setColor(save);
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
index fc388948419..beb1a6dfeac 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java
@@ -1,5 +1,5 @@
/* BasicTextUI.java --
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -46,15 +46,11 @@ import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
@@ -70,6 +66,7 @@ import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TextUI;
import javax.swing.plaf.UIResource;
+import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
@@ -82,6 +79,7 @@ import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
import javax.swing.text.Position;
+import javax.swing.text.Utilities;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
@@ -161,11 +159,11 @@ public abstract class BasicTextUI extends TextUI
* Indicates that the preferences of one of the child view has changed.
* This calls revalidate on the text component.
*
- * @param view the child view which's preference has changed
+ * @param v the child view which's preference has changed
* @param width <code>true</code> if the width preference has changed
* @param height <code>true</code> if the height preference has changed
*/
- public void preferenceChanged(View view, boolean width, boolean height)
+ public void preferenceChanged(View v, boolean width, boolean height)
{
textComponent.revalidate();
}
@@ -181,7 +179,7 @@ public abstract class BasicTextUI extends TextUI
view.setParent(null);
if (v != null)
- v.setParent(null);
+ v.setParent(this);
view = v;
}
@@ -207,10 +205,10 @@ public abstract class BasicTextUI extends TextUI
*/
public int getViewCount()
{
+ int count = 0;
if (view != null)
- return 1;
- else
- return 0;
+ count = 1;
+ return count;
}
/**
@@ -249,7 +247,11 @@ public abstract class BasicTextUI extends TextUI
public void paint(Graphics g, Shape s)
{
if (view != null)
- view.paint(g, s);
+ {
+ Rectangle b = s.getBounds();
+ view.setSize(b.width, b.height);
+ view.paint(g, s);
+ }
}
@@ -277,7 +279,7 @@ public abstract class BasicTextUI extends TextUI
public Shape modelToView(int position, Shape a, Position.Bias bias)
throws BadLocationException
{
- return ((View) view).modelToView(position, a, bias);
+ return view.modelToView(position, a, bias);
}
/**
@@ -363,12 +365,44 @@ public abstract class BasicTextUI extends TextUI
{
return view.getNextVisualPositionFrom(pos, b, a, d, biasRet);
}
+
+ /**
+ * Returns the startOffset of this view, which is always the beginning
+ * of the document.
+ *
+ * @return the startOffset of this view
+ */
+ public int getStartOffset()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the endOffset of this view, which is always the end
+ * of the document.
+ *
+ * @return the endOffset of this view
+ */
+ public int getEndOffset()
+ {
+ return getDocument().getLength();
+ }
+
+ /**
+ * Returns the document associated with this view.
+ *
+ * @return the document associated with this view
+ */
+ public Document getDocument()
+ {
+ return textComponent.getDocument();
+ }
}
/**
* Receives notifications when properties of the text component change.
*/
- class PropertyChangeHandler implements PropertyChangeListener
+ private class PropertyChangeHandler implements PropertyChangeListener
{
/**
* Notifies when a property of the text component changes.
@@ -448,7 +482,7 @@ public abstract class BasicTextUI extends TextUI
/**
* Receives notification when the model changes.
*/
- PropertyChangeHandler updateHandler = new PropertyChangeHandler();
+ private PropertyChangeHandler updateHandler = new PropertyChangeHandler();
/** The DocumentEvent handler. */
DocumentHandler documentHandler = new DocumentHandler();
@@ -515,20 +549,19 @@ public abstract class BasicTextUI extends TextUI
c.setOpaque(true);
textComponent = (JTextComponent) c;
-
Document doc = textComponent.getDocument();
if (doc == null)
{
- doc = getEditorKit(textComponent).createDefaultDocument();
- textComponent.setDocument(doc);
+ doc = getEditorKit(textComponent).createDefaultDocument();
+ textComponent.setDocument(doc);
}
-
- textComponent.addPropertyChangeListener(updateHandler);
- modelChanged();
-
installDefaults();
installListeners();
installKeyboardActions();
+
+ // We need to trigger this so that the view hierarchy gets initialized.
+ modelChanged();
+
}
/**
@@ -584,6 +617,7 @@ public abstract class BasicTextUI extends TextUI
protected void installListeners()
{
textComponent.addFocusListener(focuslistener);
+ textComponent.addPropertyChangeListener(updateHandler);
installDocumentListeners();
}
@@ -621,6 +655,11 @@ public abstract class BasicTextUI extends TextUI
*/
protected Keymap createKeymap()
{
+ // FIXME: It seems to me that this method implementation is wrong. It seems
+ // to fetch the focusInputMap and transform it to the KeyBinding/Keymap
+ // implemenation. I would think that it should be done the other way,
+ // fetching the keybindings (from prefix + ".bindings") and transform
+ // it to the newer InputMap/ActionMap implementation.
JTextComponent.KeyBinding[] bindings = null;
String prefix = getPropertyPrefix();
InputMapUIResource m = (InputMapUIResource) UIManager.get(prefix + ".focusInputMap");
@@ -637,10 +676,7 @@ public abstract class BasicTextUI extends TextUI
}
}
if (bindings == null)
- {
- bindings = new JTextComponent.KeyBinding[0];
- UIManager.put(prefix + ".focusInputMap", bindings);
- }
+ bindings = new JTextComponent.KeyBinding[0];
Keymap km = JTextComponent.addKeymap(getKeymapName(),
JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP));
@@ -726,8 +762,6 @@ public abstract class BasicTextUI extends TextUI
super.uninstallUI(component);
rootView.setView(null);
- textComponent.removePropertyChangeListener(updateHandler);
-
uninstallDefaults();
uninstallListeners();
uninstallKeyboardActions();
@@ -750,6 +784,7 @@ public abstract class BasicTextUI extends TextUI
*/
protected void uninstallListeners()
{
+ textComponent.removePropertyChangeListener(updateHandler);
textComponent.removeFocusListener(focuslistener);
textComponent.getDocument().removeDocumentListener(documentHandler);
}
@@ -786,7 +821,9 @@ public abstract class BasicTextUI extends TextUI
float w = v.getPreferredSpan(View.X_AXIS);
float h = v.getPreferredSpan(View.Y_AXIS);
- return new Dimension((int) w, (int) h);
+ Insets i = c.getInsets();
+ return new Dimension((int) w + i.left + i.right,
+ (int) h + i.top + i.bottom);
}
/**
@@ -817,18 +854,49 @@ public abstract class BasicTextUI extends TextUI
}
/**
- * Paints the text component.
+ * Paints the text component. This acquires a read lock on the model and then
+ * calls {@link #paintSafely(Graphics)} in order to actually perform the
+ * painting.
*
* @param g the <code>Graphics</code> context to paint to
* @param c not used here
*/
public final void paint(Graphics g, JComponent c)
{
- paintSafely(g);
+ try
+ {
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ {
+ AbstractDocument aDoc = (AbstractDocument) doc;
+ aDoc.readLock();
+ }
+
+ paintSafely(g);
+ }
+ finally
+ {
+ Document doc = textComponent.getDocument();
+ if (doc instanceof AbstractDocument)
+ {
+ AbstractDocument aDoc = (AbstractDocument) doc;
+ aDoc.readUnlock();
+ }
+ }
}
/**
- * Actually performs the painting.
+ * This paints the text component while beeing sure that the model is not
+ * modified while painting.
+ *
+ * The following is performed in this order:
+ * <ol>
+ * <li>If the text component is opaque, the background is painted by
+ * calling {@link #paintBackground(Graphics)}.</li>
+ * <li>If there is a highlighter, the highlighter is painted.</li>
+ * <li>The view hierarchy is painted.</li>
+ * <li>The Caret is painter.</li>
+ * </ol>
*
* @param g the <code>Graphics</code> context to paint to
*/
@@ -840,9 +908,19 @@ public abstract class BasicTextUI extends TextUI
if (textComponent.isOpaque())
paintBackground(g);
- if (highlighter != null
- && textComponent.getSelectionStart() != textComponent.getSelectionEnd())
- highlighter.paint(g);
+ // Try painting with the highlighter without checking whether there
+ // is a selection because a highlighter can be used to do more than
+ // marking selected text.
+ if (highlighter != null)
+ {
+ // Handle restoring of the color here to prevent
+ // drawing problems when the Highlighter implementor
+ // forgets to restore it.
+ Color oldColor = g.getColor();
+ highlighter.paint(g);
+ g.setColor(oldColor);
+ }
+
rootView.paint(g, getVisibleEditorRect());
@@ -857,10 +935,23 @@ public abstract class BasicTextUI extends TextUI
*/
protected void paintBackground(Graphics g)
{
- // This method does nothing. All the background filling is done by the
- // ComponentUI update method. However, the method is called by paint
- // to provide a way for subclasses to draw something different (e.g.
- // background images etc) on the background.
+ Color old = g.getColor();
+ g.setColor(textComponent.getBackground());
+ g.fillRect(0, 0, textComponent.getWidth(), textComponent.getHeight());
+ g.setColor(old);
+ }
+
+ /**
+ * Overridden for better control over background painting. This now simply
+ * calls {@link #paint} and this delegates the background painting to
+ * {@link #paintBackground}.
+ *
+ * @param g the graphics to use
+ * @param c the component to be painted
+ */
+ public void update(Graphics g, JComponent c)
+ {
+ paint(g, c);
}
/**
@@ -895,7 +986,84 @@ public abstract class BasicTextUI extends TextUI
public void damageRange(JTextComponent t, int p0, int p1,
Position.Bias firstBias, Position.Bias secondBias)
{
- // TODO: Implement me.
+ try
+ {
+ // Limit p0 and p1 to sane values to prevent unfriendly
+ // BadLocationExceptions. This makes it possible for the highlighter
+ // to send us illegal values which can happen when a large number
+ // of selected characters are removed (eg. by pressing delete
+ // or backspace).
+ // The reference implementation does not throw an exception, too.
+ p0 = Math.min(p0, t.getDocument().getLength());
+ p1 = Math.min(p1, t.getDocument().getLength());
+
+ Rectangle l1 = modelToView(t, p0, firstBias);
+ Rectangle l2 = modelToView(t, p1, secondBias);
+ if (l1.y == l2.y)
+ t.repaint(l1.union(l2));
+ else
+ {
+ // The two rectangles lie on different lines and we need a
+ // different algorithm to calculate the damaged area:
+ // 1. The line of p0 is damaged from the position of p0
+ // to the right border.
+ // 2. All lines between the ones where p0 and p1 lie on
+ // are completely damaged. Use the allocation area to find
+ // out the bounds.
+ // 3. The final line is damaged from the left bound to the
+ // position of p1.
+ Insets insets = t.getInsets();
+
+ // Damage first line until the end.
+ l1.width = insets.right + t.getWidth() - l1.x;
+ t.repaint(l1);
+
+ // Note: Utilities.getPositionBelow() may return the offset
+ // that was put in. In that case there is no next line and
+ // we should stop searching for one.
+
+ int posBelow = Utilities.getPositionBelow(t, p0, l1.x);
+ if (posBelow < p1 && posBelow != -1 && posBelow != p0)
+ {
+ // Take the rectangle of the offset we just found and grow it
+ // to the maximum width. Retain y because this is our start
+ // height.
+ Rectangle grow = modelToView(t, posBelow);
+ grow.x = insets.left;
+ grow.width = t.getWidth() + insets.right;
+
+ // Find further lines which have to be damaged completely.
+ int nextPosBelow = posBelow;
+ while (nextPosBelow < p1 && nextPosBelow != -1 && posBelow != nextPosBelow)
+ {
+ posBelow = nextPosBelow;
+ nextPosBelow = Utilities.getPositionBelow(t, posBelow, l1.x);
+ }
+ // Now posBelow is an offset on the last line which has to be damaged
+ // completely. (newPosBelow is on the same line as p1)
+
+ // Retrieve the rectangle of posBelow and use its y and height
+ // value to calculate the final height of the multiple line
+ // spanning rectangle.
+ Rectangle end = modelToView(t, posBelow);
+ grow.height = end.y + end.height - grow.y;
+
+ // Mark that area as damage.
+ t.repaint(grow);
+ }
+
+ // Damage last line from its beginning to the position of p1.
+ l2.width += l2.x;
+ l2.x = insets.left;
+ t.repaint(l2);
+ }
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError err = new AssertionError("Unexpected bad location");
+ err.initCause(ex);
+ throw err;
+ }
}
/**
@@ -1061,7 +1229,6 @@ public abstract class BasicTextUI extends TextUI
*/
protected Rectangle getVisibleEditorRect()
{
- JTextComponent textComponent = getComponent();
int width = textComponent.getWidth();
int height = textComponent.getHeight();
@@ -1082,7 +1249,6 @@ public abstract class BasicTextUI extends TextUI
protected final void setView(View view)
{
rootView.setView(view);
- view.setParent(rootView);
textComponent.revalidate();
textComponent.repaint();
}
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
index f2ebcfca9ac..1c6e6c5e502 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
@@ -45,6 +45,7 @@ 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;
@@ -114,9 +115,18 @@ import javax.swing.tree.TreeSelectionModel;
* @see javax.swing.JTree
* @author Lillian Angel (langel@redhat.com)
* @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
*/
public class BasicTreeUI extends TreeUI
{
+ /**
+ * The tree cell editing may be started by the single mouse click on the
+ * selected cell. To separate it from the double mouse click, the editing
+ * session starts after this time (in ms) after that single click, and only
+ * no other clicks were performed during that time.
+ */
+ static int WAIT_TILL_EDITING = 900;
+
/** Collapse Icon for the tree. */
protected transient Icon collapsedIcon;
@@ -225,12 +235,6 @@ public class BasicTreeUI extends TreeUI
/** Set to true if the editor has a different size than the renderer. */
protected boolean editorHasDifferentSize;
- /** The action listener for the editor's Timer. */
- Timer editorTimer = new EditorUpdateTimer();
-
- /** The new value of the node after editing. */
- Object newVal;
-
/** The action bound to KeyStrokes. */
TreeAction action;
@@ -266,6 +270,20 @@ public class BasicTreeUI extends TreeUI
private TreeExpansionListener treeExpansionListener;
private 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 special value of the mouse event is sent indicating that this is not
+ * just the mouse click, but the mouse click on the selected node. Sending
+ * such event forces to start the cell editing session.
+ */
+ static final MouseEvent EDIT = new MouseEvent(new Label(), 7,7,7,7,7,7, false);
/**
* Creates a new BasicTreeUI object.
@@ -303,7 +321,7 @@ public class BasicTreeUI extends TreeUI
{
return new BasicTreeUI();
}
-
+
/**
* Returns the Hash color.
*
@@ -796,7 +814,10 @@ public class BasicTreeUI extends TreeUI
public boolean stopEditing(JTree tree)
{
if (isEditing(tree))
- completeEditing(true, false, false);
+ {
+ completeEditing(false, false, true);
+ finish();
+ }
return !isEditing(tree);
}
@@ -807,9 +828,12 @@ public class BasicTreeUI extends TreeUI
* is the tree to cancel the editing session on.
*/
public void cancelEditing(JTree tree)
- {
- if (isEditing(tree))
- completeEditing(false, true, false);
+ {
+ // 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();
}
/**
@@ -1213,6 +1237,7 @@ public class BasicTreeUI extends TreeUI
protected void updateCachedPreferredSize()
{
int maxWidth = 0;
+ updateCurrentVisiblePath();
boolean isLeaf = false;
if (currentVisiblePath != null)
{
@@ -1246,7 +1271,7 @@ public class BasicTreeUI extends TreeUI
protected void pathWasExpanded(TreePath path)
{
validCachedPreferredSize = false;
- tree.repaint();
+ tree.repaint();
}
/**
@@ -1271,7 +1296,6 @@ public class BasicTreeUI extends TreeUI
leftChildIndent = UIManager.getInt("Tree.leftChildIndent");
setRowHeight(UIManager.getInt("Tree.rowHeight"));
tree.setRowHeight(getRowHeight());
- tree.requestFocusInWindow(false);
tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand"));
setExpandedIcon(UIManager.getIcon("Tree.expandedIcon"));
setCollapsedIcon(UIManager.getIcon("Tree.collapsedIcon"));
@@ -1621,7 +1645,14 @@ public class BasicTreeUI extends TreeUI
}
if (messageTree)
- treeModel.valueForPathChanged(tree.getLeadSelectionPath(), newVal);
+ {
+ TreeCellEditor editor = getCellEditor();
+ if (editor != null)
+ {
+ Object value = editor.getCellEditorValue();
+ treeModel.valueForPathChanged(tree.getLeadSelectionPath(), value);
+ }
+ }
}
/**
@@ -1636,44 +1667,48 @@ public class BasicTreeUI extends TreeUI
*/
protected boolean startEditing(TreePath path, MouseEvent event)
{
- int x;
- int y;
- if (event == null)
- {
- Rectangle bounds = getPathBounds(tree, path);
- x = bounds.x;
- y = bounds.y;
- }
- else
- {
- x = event.getX();
- y = event.getY();
- }
+ // Force to recalculate the maximal row height.
+ maxHeight = 0;
+
+ // Force to recalculate the cached preferred size.
+ validCachedPreferredSize = false;
updateCellEditor();
TreeCellEditor ed = getCellEditor();
- if (ed != null && ed.shouldSelectCell(event) && ed.isCellEditable(event))
+
+ if (ed != null
+ && (event == EDIT || ed.shouldSelectCell(event))
+ && ed.isCellEditable(event))
{
+ 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 val = editingPath.getLastPathComponent();
- cellEditor.addCellEditorListener(cellEditorListener);
+ Object value = editingPath.getLastPathComponent();
+
stopEditingInCompleteEditing = false;
boolean expanded = tree.isExpanded(editingPath);
isEditing = true;
- editingComponent = ed.getTreeCellEditorComponent(tree, val, true,
+ editingComponent = ed.getTreeCellEditorComponent(tree, value, true,
expanded,
isLeaf(editingRow),
editingRow);
- editingComponent.getParent().setVisible(true);
- editingComponent.getParent().validate();
- tree.add(editingComponent.getParent());
- editingComponent.getParent().validate();
- validCachedPreferredSize = false;
-
- ((JTextField) editingComponent).requestFocusInWindow(false);
- editorTimer.start();
+
+ // 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();
+
return true;
}
return false;
@@ -1922,7 +1957,7 @@ public class BasicTreeUI extends TreeUI
tree.clearSelection();
if (tree.isEditing() && !e.getActionCommand().equals("startEditing"))
- tree.cancelEditing();
+ tree.stopEditing();
tree.scrollPathToVisible(lead);
}
@@ -1957,51 +1992,7 @@ public class BasicTreeUI extends TreeUI
}
}
- /**
- * The timer that updates the editor component.
- */
- private class EditorUpdateTimer extends Timer implements ActionListener
- {
- /**
- * Creates a new EditorUpdateTimer object with a default delay of 0.3
- * seconds.
- */
- public EditorUpdateTimer()
- {
- super(300, null);
- addActionListener(this);
- }
-
- /**
- * Lets the caret blink and repaints the table.
- */
- public void actionPerformed(ActionEvent ev)
- {
- Caret c = ((JTextField) editingComponent).getCaret();
- if (c != null)
- c.setVisible(!c.isVisible());
- tree.repaint();
- }
-
- /**
- * Updates the blink delay according to the current caret.
- */
- public void update()
- {
- stop();
- Caret c = ((JTextField) editingComponent).getCaret();
- if (c != null)
- {
- setDelay(c.getBlinkRate());
- if (((JTextField) editingComponent).isEditable())
- start();
- else
- c.setVisible(false);
- }
- }
- }
-
- /**
+ /**
* Updates the preferred size when scrolling, if necessary.
*/
public class ComponentHandler extends ComponentAdapter implements
@@ -2089,29 +2080,7 @@ public class BasicTreeUI extends TreeUI
*/
public void editingStopped(ChangeEvent e)
{
- editingPath = null;
- editingRow = -1;
- stopEditingInCompleteEditing = false;
- if (editingComponent != null)
- {
- tree.remove(editingComponent.getParent());
- editingComponent = null;
- }
- if (cellEditor != null)
- {
- newVal = ((JTextField) getCellEditor().getCellEditorValue()).getText();
- completeEditing(false, false, true);
- if (cellEditor instanceof DefaultTreeCellEditor)
- tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
- cellEditor.removeCellEditorListener(cellEditorListener);
- setCellEditor(null);
- createdCellEditor = false;
- }
- isEditing = false;
- tree.requestFocusInWindow(false);
- editorTimer.stop();
- validCachedPreferredSize = false;
- tree.repaint();
+ stopEditing(tree);
}
/**
@@ -2123,25 +2092,7 @@ public class BasicTreeUI extends TreeUI
*/
public void editingCanceled(ChangeEvent e)
{
- editingPath = null;
- editingRow = -1;
- stopEditingInCompleteEditing = false;
- if (editingComponent != null)
- tree.remove(editingComponent.getParent());
- editingComponent = null;
- if (cellEditor != null)
- {
- if (cellEditor instanceof DefaultTreeCellEditor)
- tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
- cellEditor.removeCellEditorListener(cellEditorListener);
- setCellEditor(null);
- createdCellEditor = false;
- }
- tree.requestFocusInWindow(false);
- editorTimer.stop();
- isEditing = false;
- validCachedPreferredSize = false;
- tree.repaint();
+ cancelEditing(tree);
}
}// CellEditorHandler
@@ -2261,7 +2212,15 @@ public class BasicTreeUI extends TreeUI
* is the mouse event that occured
*/
public void mousePressed(MouseEvent e)
- {
+ {
+ // Any mouse click cancels the previous waiting edit action, initiated
+ // by the single click on the selected node.
+ if (startEditTimer != null)
+ {
+ startEditTimer.stop();
+ startEditTimer = null;
+ }
+
Point click = e.getPoint();
TreePath path = getClosestPathForLocation(tree, click.x, click.y);
@@ -2298,9 +2257,37 @@ public class BasicTreeUI extends TreeUI
{
if (inBounds)
{
- selectPath(tree, path);
- if (e.getClickCount() == 2 && !isLeaf(row))
- toggleExpandState(path);
+ TreePath currentLead = tree.getLeadSelectionPath();
+ if (
+ currentLead != null &&
+ currentLead.equals(path) &&
+ e.getClickCount() == 1 &&
+ tree.isEditable()
+ )
+ {
+ // Schedule the editing session.
+ final TreePath editPath = path;
+
+ if (startEditTimer != null)
+ startEditTimer.stop();
+
+ startEditTimer = new Timer(WAIT_TILL_EDITING,
+ new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ startEditing(editPath, EDIT);
+ }
+ });
+ startEditTimer.setRepeats(false);
+ startEditTimer.start();
+ }
+ else
+ {
+ selectPath(tree, path);
+ if (e.getClickCount() == 2 && !isLeaf(row))
+ toggleExpandState(path);
+ }
}
if (cntlClick)
@@ -2686,7 +2673,7 @@ public class BasicTreeUI extends TreeUI
public class TreeHomeAction extends AbstractAction
{
- /** direction is either home or end */
+ /** The direction, either home or end */
protected int direction;
/**
@@ -2983,7 +2970,7 @@ public class BasicTreeUI extends TreeUI
public void valueChanged(TreeSelectionEvent event)
{
if (tree.isEditing())
- tree.cancelEditing();
+ tree.stopEditing();
}
}// TreeSelectionHandler
@@ -3650,25 +3637,14 @@ public class BasicTreeUI extends TreeUI
if (row != 0)
bounds.x += gap;
bounds.width = preferredSize.width + bounds.x;
- if (editingComponent != null && editingPath != null && isEditing(tree)
- && node.equals(editingPath.getLastPathComponent()))
- {
- rendererPane.paintComponent(g, editingComponent.getParent(), null,
- bounds);
- }
- else
- {
- TreeCellRenderer dtcr = tree.getCellRenderer();
- if (dtcr == null)
- dtcr = createDefaultCellRenderer();
-
- Component c = dtcr.getTreeCellRendererComponent(tree, node,
- selected,
- isExpanded, isLeaf,
- row,
- tree.hasFocus());
- rendererPane.paintComponent(g, c, c.getParent(), bounds);
- }
+ TreeCellRenderer dtcr = tree.getCellRenderer();
+ if (dtcr == null)
+ dtcr = createDefaultCellRenderer();
+
+ Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
+ isExpanded, isLeaf,
+ row, tree.hasFocus());
+ rendererPane.paintComponent(g, c, c.getParent(), bounds);
}
}
@@ -3801,4 +3777,21 @@ public class BasicTreeUI extends TreeUI
}
return null;
}
+
+ /**
+ * Finish the editing session.
+ */
+ void finish()
+ {
+ editingPath = null;
+ editingRow = -1;
+ stopEditingInCompleteEditing = false;
+ isEditing = false;
+ tree.removeAll();
+ validCachedPreferredSize = false;
+
+ // Repaint the region, where was the editing component.
+ tree.repaint(editingComponent.getParent().getBounds());
+ editingComponent = null;
+ }
} // BasicTreeUI