[kaffe] CVS kaffe (riccardo): updated focus, fields and introduced lightweight handling

Kaffe CVS cvs-commits at kaffe.org
Wed May 10 16:09:58 PDT 2006


PatchSet 7287 
Date: 2006/05/10 23:00:45
Author: riccardo
Branch: HEAD
Tag: (none) 
Log:
updated focus, fields and introduced lightweight handling

Members: 
	ChangeLog:1.4791->1.4792 
	libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.11->1.12 
	libraries/javalib/awt-implementations/kaffe/java/awt/Window.java:1.6->1.7 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4791 kaffe/ChangeLog:1.4792
--- kaffe/ChangeLog:1.4791	Wed May 10 19:51:21 2006
+++ kaffe/ChangeLog	Wed May 10 23:00:45 2006
@@ -1,3 +1,9 @@
+2006-05-11  Riccardo Mottola <riccardo at kaffe.org>
+
+	* libraries/javalib/awt-implementations/kaffe/java/awt/Component.java,
+	libraries/javalib/awt-implementations/kaffe/java/awt/Window.java:
+	updated focus, fields and introduced lightweight handling
+
 2006-05-10  Riccardo Mottola <riccardo at kaffe.org>
 
 	* libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:
Index: kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java
diff -u kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.11 kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.12
--- kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.11	Wed May 10 19:51:22 2006
+++ kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java	Wed May 10 23:00:46 2006
@@ -39,19 +39,30 @@
 import java.awt.event.PaintEvent;
 import java.awt.event.TextEvent;
 import java.awt.event.WindowEvent;
+import java.awt.image.BufferStrategy;
 import java.awt.image.ColorModel;
 import java.awt.image.ImageObserver;
 import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
 import java.awt.peer.ComponentPeer;
 import java.awt.peer.LightweightPeer;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.Serializable;
 import java.util.Locale;
+import java.util.Set;
+import java.util.Vector;
 import java.awt.dnd.DropTarget;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+
 import org.kaffe.awt.DoNothingPeer;
 
 
@@ -63,19 +74,8 @@
 {
 	// We're not actually compatible with Sun's serialization format, so don't claim to be:
 	//final private static long serialVersionUID = -7644114512714619750L;
-
-	Container parent;
-	int x;
-	int y;
-	int width;
-	int height;
 	Color fgClr;
 	Color bgClr;
-	Font font;
-	Cursor cursor;
-	String name;
-	int eventMask;
-	Locale locale;
 	PopupMenu popup;
 	Rectangle deco = noDeco;
 	int flags = IS_VISIBLE;
@@ -114,6 +114,282 @@
 	final static int IS_TEMP_HIDDEN = 0x20000;
 	final static int IS_SHOWING = IS_ADD_NOTIFIED | IS_PARENT_SHOWING | IS_VISIBLE;
 
+        /**
+            * The x position of the component in the parent's coordinate system.
+         *
+         * @see #getLocation()
+         * @serial the x position
+         */
+        int x;
+
+        /**
+            * The y position of the component in the parent's coordinate system.
+         *
+         * @see #getLocation()
+         * @serial the y position
+         */
+        int y;
+
+        /**
+            * The component width.
+         *
+         * @see #getSize()
+         * @serial the width
+         */
+        int width;
+
+        /**
+            * The component height.
+         *
+         * @see #getSize()
+         * @serial the height
+         */
+        int height;
+
+        /**
+            * The foreground color for the component. This may be null.
+         *
+         * @see #getForeground()
+         * @see #setForeground(Color)
+         * @serial the foreground color
+         */
+        Color foreground; // TODO update to use this as field
+
+        /**
+            * The background color for the component. This may be null.
+         *
+         * @see #getBackground()
+         * @see #setBackground(Color)
+         * @serial the background color
+         */
+        Color background; // TODO update to use this as field
+
+        /**
+            * The default font used in the component. This may be null.
+         *
+         * @see #getFont()
+         * @see #setFont(Font)
+         * @serial the font
+         */
+        Font font;
+
+        /**
+            * The font in use by the peer, or null if there is no peer.
+         *
+         * @serial the peer's font
+         */
+        Font peerFont;
+
+        /**
+            * The cursor displayed when the pointer is over this component. This may
+         * be null.
+         *
+         * @see #getCursor()
+         * @see #setCursor(Cursor)
+         */
+        Cursor cursor;
+
+        /**
+            * The locale for the component.
+         *
+         * @see #getLocale()
+         * @see #setLocale(Locale)
+         */
+        Locale locale = Locale.getDefault ();
+
+        /**
+            * True if the object should ignore repaint events (usually because it is
+                                                               * not showing).
+         *
+         * @see #getIgnoreRepaint()
+         * @see #setIgnoreRepaint(boolean)
+         * @serial true to ignore repaints
+         * @since 1.4
+         */
+        boolean ignoreRepaint;
+
+        /**
+            * True when the object is visible (although it is only showing if all
+                                               * ancestors are likewise visible). For component, this defaults to true.
+         *
+         * @see #isVisible()
+         * @see #setVisible(boolean)
+         * @serial true if visible
+         */
+        boolean visible = true;
+
+        /**
+            * True if the object is enabled, meaning it can interact with the user.
+         * For component, this defaults to true.
+         *
+         * @see #isEnabled()
+         * @see #setEnabled(boolean)
+         * @serial true if enabled
+         */
+        boolean enabled = true;
+
+        /**
+            * True if the object is valid. This is set to false any time a size
+         * adjustment means the component need to be layed out again.
+         *
+         * @see #isValid()
+         * @see #validate()
+         * @see #invalidate()
+         * @serial true if layout is valid
+         */
+        boolean valid;
+
+        /**
+            * The DropTarget for drag-and-drop operations.
+         *
+         * @see #getDropTarget()
+         * @see #setDropTarget(DropTarget)
+         * @serial the drop target, or null
+         * @since 1.2
+         */
+        DropTarget dropTarget;
+
+        /**
+            * The list of popup menus for this component.
+         *
+         * @see #add(PopupMenu)
+         * @serial the list of popups
+         */
+        Vector popups;
+
+        /**
+            * The component's name. May be null, in which case a default name is
+         * generated on the first use.
+         *
+         * @see #getName()
+         * @see #setName(String)
+         * @serial the name
+         */
+        String name;
+
+        /**
+            * True once the user has set the name. Note that the user may set the name
+         * to null.
+         *
+         * @see #name
+         * @see #getName()
+         * @see #setName(String)
+         * @serial true if the name has been explicitly set
+         */
+        boolean nameExplicitlySet;
+
+        /**
+            * Indicates if the object can be focused. Defaults to true for components.
+         *
+         * @see #isFocusable()
+         * @see #setFocusable(boolean)
+         * @since 1.4
+         */
+        boolean focusable = true;
+
+        /**
+            * Tracks whether this component's {@link #isFocusTraversable}
+         * method has been overridden.
+         *
+         * @since 1.4
+         */
+        int isFocusTraversableOverridden;
+
+        /**
+            * The focus traversal keys, if not inherited from the parent or
+         * default keyboard focus manager. These sets will contain only
+         * AWTKeyStrokes that represent press and release events to use as
+         * focus control.
+         *
+         * @see #getFocusTraversalKeys(int)
+         * @see #setFocusTraversalKeys(int, Set)
+         * @since 1.4
+         */
+        Set[] focusTraversalKeys;
+
+        /**
+            * True if focus traversal keys are enabled. This defaults to true for
+         * Component. If this is true, keystrokes in focusTraversalKeys are trapped
+         * and processed automatically rather than being passed on to the component.
+         *
+         * @see #getFocusTraversalKeysEnabled()
+         * @see #setFocusTraversalKeysEnabled(boolean)
+         * @since 1.4
+         */
+        boolean focusTraversalKeysEnabled = true;
+
+        /**
+            * Cached information on the minimum size. Should have been transient.
+         *
+         * @serial ignore
+         */
+        Dimension minSize;
+
+        /**
+            * Cached information on the preferred size. Should have been transient.
+         *
+         * @serial ignore
+         */
+        Dimension prefSize;
+
+        /**
+            * Set to true if an event is to be handled by this component, false if
+         * it is to be passed up the hierarcy.
+         *
+         * @see #dispatchEvent(AWTEvent)
+         * @serial true to process event locally
+         */
+        boolean newEventsOnly;
+
+        /**
+            * Set by subclasses to enable event handling of particular events, and
+         * left alone when modifying listeners. For component, this defaults to
+         * enabling only input methods.
+         *
+         * @see #enableInputMethods(boolean)
+         * @see AWTEvent
+         * @serial the mask of events to process
+         */
+        long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
+
+        /**
+            * Describes all registered PropertyChangeListeners.
+         *
+         * @see #addPropertyChangeListener(PropertyChangeListener)
+         * @see #removePropertyChangeListener(PropertyChangeListener)
+         * @see #firePropertyChange(String, Object, Object)
+         * @serial the property change listeners
+         * @since 1.2
+         */
+        PropertyChangeSupport changeSupport;
+
+        /**
+            * True if the component has been packed (layed out).
+         *
+         * @serial true if this is packed
+         */
+        boolean isPacked;
+
+        /**
+            * The serialization version for this class. Currently at version 4.
+         *
+         * XXX How do we handle prior versions?
+         *
+         * @serial the serialization version
+         */
+        int componentSerializedDataVersion = 4;
+
+        /**
+            * The accessible context associated with this component. This is only set
+         * by subclasses.
+         *
+         * @see #getAccessibleContext()
+         * @serial the accessibility context
+         * @since 1.2
+         */
+        AccessibleContext accessibleContext;
+        
+
         // Guess what - listeners are special cased in serialization. See
         // readObject and writeObject.
 
@@ -159,20 +435,36 @@
          * @since 1.3
          */
         transient HierarchyBoundsListener hierarchyBoundsListener;
-	
-  /** The associated native peer. */
-  transient ComponentPeer peer;
 
- /**
-   * Describes all registered PropertyChangeListeners.
-   *
-   * @see #addPropertyChangeListener(PropertyChangeListener)
-   * @see #removePropertyChangeListener(PropertyChangeListener)
-   * @see #firePropertyChange(String, Object, Object)
-   * @serial the property change listeners
-   * @since 1.2
-   */
-  PropertyChangeSupport changeSupport;
+        /** The parent. */
+        transient Container parent;
+
+        /** The associated native peer. */
+        transient ComponentPeer peer;
+
+        /** The preferred component orientation. */
+        transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN;
+
+        /**
+            * The associated graphics configuration.
+         *
+         * @since 1.4
+         */
+        transient GraphicsConfiguration graphicsConfig;
+
+        /**
+            * The buffer strategy for repainting.
+         *
+         * @since 1.4
+         */
+        transient BufferStrategy bufferStrategy;
+
+        /**
+            * true if requestFocus was called on this component when its
+         * top-level ancestor was not focusable.
+         */
+        private transient FocusEvent pendingFocusRequest = null;
+
 
 static class TreeLock
 {
@@ -328,6 +620,8 @@
 			if ( (((parent.flags & IS_OLD_EVENT) != 0) || props.useOldEvents) ){
 				flags |= (IS_OLD_EVENT | IS_MOUSE_AWARE);
 			}
+                    if (parent.isLightweight())
+                        new HeavyweightInLightweightListener(parent);
 		}
 		else { // Window
 			if ( props.useOldEvents )
@@ -815,10 +1109,10 @@
     return Toolkit.getDefaultToolkit();
 }
 
-Component getToplevel () {
+Window getToplevel () {
 	Component c;
 	for ( c=this; !(c instanceof Window) && c != null; c= c.parent );
-	return c;
+	return (Window)c;
 }
 
 final public Object getTreeLock() {
@@ -992,29 +1286,61 @@
 	        ((eventMask & AWTEvent.DISABLED_MASK) == 0));
 }
 
-// TODO this is was copied from isFocusTraversable, may be wrong.
-public boolean isFocusable() {
-	return (((flags & (IS_SHOWING|IS_NATIVE_LIKE)) == (IS_SHOWING|IS_NATIVE_LIKE)) && 
-	        ((eventMask & AWTEvent.DISABLED_MASK) == 0));
+/**
+* Tests if this component can receive focus.
+ *
+ * @return true if this component can receive focus
+ * @since 1.4
+ */
+public boolean isFocusable()
+{
+    return focusable;
 }
 
-// TODO this is a stub only
-public void setFocusable(boolean focusable) {
+/**
+* Specify whether this component can receive focus. This method also
+ * sets the {@link #isFocusTraversableOverridden} field to 1, which
+ * appears to be the undocumented way {@link
+     * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
+ * respect the {@link #isFocusable()} method of the component.
+ *
+ * @param focusable the new focusable status
+ * @since 1.4
+ */
+public void setFocusable(boolean focusable)
+{
+    firePropertyChange("focusable", this.focusable, focusable);
+    this.focusable = focusable;
+    this.isFocusTraversableOverridden = 1;
 }
 
-// TODO this is a stub only
-public boolean isFocusOwner() {
-	return true;
+/**
+* Tests if this component is the focus owner. Use {@link
+    * #isFocusOwner ()} instead.
+ *
+ * @return true if this component owns focus
+ * @since 1.2
+ */
+public boolean hasFocus ()
+{
+    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+    Component focusOwner = manager.getFocusOwner ();
+
+    return this == focusOwner;
 }
 
 /**
- * @deprecated
+* Tests if this component is the focus owner.
+ *
+ * @return true if this component owns focus
+ * @since 1.4
  */
-public boolean hasFocus() {
-	return isFocusOwner();
+public boolean isFocusOwner()
+{
+    return hasFocus ();
 }
 
-
 public boolean isShowing () {
 	// compare the costs of this with the standard upward iteration
  return  ((flags & (IS_PARENT_SHOWING | IS_VISIBLE | IS_ADD_NOTIFIED)) ==
@@ -1030,6 +1356,27 @@
 }
 
 /**
+* Tests if the component is displayable. It must be connected to a native
+ * screen resource.  This reduces to checking that peer is not null.  A
+ * containment  hierarchy is made displayable when a window is packed or
+ * made visible.
+ *
+ * @return true if the component is displayable
+ * @see Container#add(Component)
+ * @see Container#remove(Component)
+ * @see Window#pack()
+ * @see Window#show()
+ * @see Window#dispose()
+ * @since 1.2
+ */
+public boolean isDisplayable()
+{
+    // since we are peerless...
+    return true;
+//    return peer != null;
+}
+
+/**
  * @deprecated
  */
 public boolean keyDown(Event evt, int key) {
@@ -1208,12 +1555,35 @@
 	transferFocus();
 }
 
-public void paint ( Graphics g ) {
-	// nothing to do here, that all has to be donw in subclasses
+/**
+* Paints this component on the screen. The clipping region in the graphics
+ * context will indicate the region that requires painting. This is called
+ * whenever the component first shows, or needs to be repaired because
+ * something was temporarily drawn on top. It is not necessary for
+ * subclasses to call <code>super.paint(g)</code>. Components with no area
+ * are not painted.
+ *
+ * @param g the graphics context for this paint job
+ * @see #update(Graphics)
+ */
+public void paint(Graphics g)
+{
+    // This is a callback method and is meant to be overridden by subclasses
+    // that want to perform custom painting.
 }
 
-public void paintAll ( Graphics g ) {
-	paint( g);
+/**
+* Paints this entire component, including any sub-components.
+ *
+ * @param g the graphics context for this paint job
+ *
+ * @see #paint(Graphics)
+ */
+public void paintAll(Graphics g)
+{
+    if ((flags & IS_VISIBLE) == 0)
+        return;
+    paint(g);
 }
 
 void kaffePaintBorder () {
@@ -1719,34 +2089,188 @@
 	}
 }
 
-public void requestFocus () {
-	Component topNew;
+/**
+* Request that this Component be given the keyboard input focus and
+ * that its top-level ancestor become the focused Window.
+ *
+ * For the request to be granted, the Component must be focusable,
+ * displayable and showing and the top-level Window to which it
+ * belongs must be focusable.  If the request is initially denied on
+ * the basis that the top-level Window is not focusable, the request
+ * will be remembered and granted when the Window does become
+ * focused.
+ *
+ * Never assume that this Component is the focus owner until it
+ * receives a FOCUS_GAINED event.
+ *
+ * The behaviour of this method is platform-dependent.
+ * {@link #requestFocusInWindow()} should be used instead.
+ *
+ * @see #requestFocusInWindow ()
+ * @see FocusEvent
+ * @see #addFocusListener (FocusListener)
+ * @see #isFocusable ()
+ * @see #isDisplayable ()
+ * @see KeyboardFocusManager#clearGlobalFocusOwner ()
+ */
+public void requestFocus ()
+{
+    if (isDisplayable ()
+        && isShowing ()
+        && isFocusable ())
+    {
+        synchronized (getTreeLock ())
+    {
+            // Find this Component's top-level ancestor.
+            Container parent = (this instanceof Container) ? (Container) this
+            : getParent();
+            while (parent != null
+                   && !(parent instanceof Window))
+                parent = parent.getParent ();
+
+            if (parent == null)
+                return;
+
+            Window toplevel = (Window) parent;
+// we can't check for that or  choice windows won't get focus
+//            if (toplevel.isFocusableWindow ())
+//            {
+                //if (peer != null && !isLightweight()) { // we don't have a peer
+                if (!isLightweight()) {
+                    // This call will cause a FOCUS_GAINED event to be
+                    // posted to the system event queue if the native
+                    // windowing system grants the focus request.
+                    //peer.requestFocus ();
+                    if (toplevel != AWTEvent.activeWindow ) {  // this involves a change of active toplevels
+                        FocusEvt.keyTgtRequest = this;
+                        toplevel.requestFocus();
+                    }
+                    else {                                 // intra toplevel focus change
+                        Toolkit.eventQueue.postFocusEvent( FocusEvt.getEvent( this, FocusEvent.FOCUS_GAINED, false));
+                    }
+                } else
+                {
+                    // Either our peer hasn't been created yet or we're a
+                    // lightweight component.  In either case we want to
+                    // post a FOCUS_GAINED event.
+                    EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+                    synchronized (eq)
+                    {
+                        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+                        Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+                        if (currentFocusOwner != null)
+                        {
+                            eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
+                                                         false, this));
+                            eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false,
+                                                         currentFocusOwner));
+                        }
+                        else
+                            eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false));
+                    }
+                }
+            //}
+            //else
+            //    pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED);
+    }
+    }
+}
+
+/**
+* Request that this Component be given the keyboard input focus and
+ * that its top-level ancestor become the focused Window.
+ *
+ * For the request to be granted, the Component must be focusable,
+ * displayable and showing and the top-level Window to which it
+ * belongs must be focusable.  If the request is initially denied on
+ * the basis that the top-level Window is not focusable, the request
+ * will be remembered and granted when the Window does become
+ * focused.
+ *
+ * Never assume that this Component is the focus owner until it
+ * receives a FOCUS_GAINED event.
+ *
+ * The behaviour of this method is platform-dependent.
+ * {@link #requestFocusInWindow()} should be used instead.
+ *
+ * If the return value is false, the request is guaranteed to fail.
+ * If the return value is true, the request will succeed unless it
+ * is vetoed or something in the native windowing system intervenes,
+ * preventing this Component's top-level ancestor from becoming
+ * focused.  This method is meant to be called by derived
+ * lightweight Components that want to avoid unnecessary repainting
+ * when they know a given focus transfer need only be temporary.
+ *
+ * @param temporary true if the focus request is temporary
+ * @return true if the request has a chance of success
+ * @see #requestFocusInWindow ()
+ * @see FocusEvent
+ * @see #addFocusListener (FocusListener)
+ * @see #isFocusable ()
+ * @see #isDisplayable ()
+ * @see KeyboardFocusManager#clearGlobalFocusOwner ()
+ * @since 1.4
+ */
+protected boolean requestFocus (boolean temporary)
+{
+    if (isDisplayable ()
+        && isShowing ()
+        && isFocusable ())
+    {
+        synchronized (getTreeLock ())
+    {
+            // Find this Component's top-level ancestor.
+            Container parent = getParent ();
 
-	if ( AWTEvent.keyTgt == this ){   // nothing to do
-		return;
-	}
+            while (parent != null
+                   && !(parent instanceof Window))
+                parent = parent.getParent ();
 
-	topNew = getToplevel();
-	
-	// there are bad apps out there requesting the focus for Components
-	// which have not even been addNotified yet (hence no parent)
-	if ( topNew == null ) {
-		// most native AWTs will fail here, but with our mechanism, we
-		// can try harder: store request in the hope it will be honored
-		// by a subsequent requestFocus of the toplevel
-		FocusEvt.keyTgtRequest = this;
-	}
-	else {
-		if (topNew != AWTEvent.activeWindow ) {  // this involves a change of active toplevels
-			FocusEvt.keyTgtRequest = this;
-			topNew.requestFocus();
-		}
-		else {                                 // intra toplevel focus change
-			Toolkit.eventQueue.postFocusEvent( FocusEvt.getEvent( this, FocusEvent.FOCUS_GAINED, false));
-		}
-	}
+            Window toplevel = (Window) parent;
+            if (toplevel.isFocusableWindow ())
+            {
+                if (peer != null && !isLightweight())
+                    // This call will cause a FOCUS_GAINED event to be
+                    // posted to the system event queue if the native
+                    // windowing system grants the focus request.
+                    peer.requestFocus ();
+                else
+                {
+                    // Either our peer hasn't been created yet or we're a
+                    // lightweight component.  In either case we want to
+                    // post a FOCUS_GAINED event.
+                    EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+                    synchronized (eq)
+                    {
+                        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+                        Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
+                        if (currentFocusOwner != null)
+                        {
+                            eq.postEvent (new FocusEvent(currentFocusOwner,
+                                                         FocusEvent.FOCUS_LOST,
+                                                         temporary, this));
+                            eq.postEvent (new FocusEvent(this,
+                                                         FocusEvent.FOCUS_GAINED,
+                                                         temporary,
+                                                         currentFocusOwner));
+                        }
+                        else
+                            eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
+                    }
+                }
+            }
+            else
+                // FIXME: need to add a focus listener to our top-level
+                // ancestor, so that we can post this event when it becomes
+                // the focused window.
+                pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary);
+    }
+    }
+    // Always return true.
+    return true;
 }
 
+
 /**
  * @deprecated, use setBounds(x,y,w,h)
  * this is never called automatically, override setBounds in derived classes
@@ -1756,6 +2280,10 @@
 	// DEP - this should be in setBounds !! But we have to keep it here
 	// for compatibility reasons (Swing etc.)
 
+    int oldx = this.x;
+    int oldy = this.y;
+    int oldwidth = this.width;
+    int oldheight = this.height;
 	int      x0=0, x1=0, y0=0, y1=0, a, b;
 	boolean  sized = ( (width != wNew) || (height != hNew) );
 	boolean  moved = ( !sized && ((x != xNew) || (y != yNew)) );
@@ -1764,6 +2292,21 @@
 	// Don't do anything if we don't change anything.
 	if (sized || moved) {
 
+            // Erase old bounds and repaint new bounds for lightweights.
+            if (isLightweight() && isShowing())
+            {
+                if (parent != null)
+                {
+                    Rectangle oldBounds = new Rectangle(oldx, oldy, oldwidth,
+                                                        oldheight);
+                    Rectangle newBounds = new Rectangle(x, y, width, height);
+                    Rectangle destroyed = oldBounds.union(newBounds);
+                    if (!destroyed.isEmpty())
+                        parent.repaint(0, destroyed.x, destroyed.y, destroyed.width,
+                                       destroyed.height);
+                }
+            }
+
 		if ( parent != null ) {
 			// Strange, but happens (e.g. for Swing InternalFrames): somebody
 			// explicitly moved the mouseTgt or one of its parents (maybe in a mouse modal drag!)
@@ -1963,50 +2506,84 @@
 	resize( newWidth, newHeight);
 }
 
-public void setVisible ( boolean b ) {
-	show( b);
-}
 
-public void show () {
-	// DEP this should be in setVisible !! But we have to keep it here
-	// for compatibility reasons (Swing etc.)
+/**
+* Makes this component visible or invisible. Note that it wtill might
+ * not show the component, if a parent is invisible.
+ *
+ * @param visible true to make this component visible
+ *
+ * @see #isVisible()
+ *
+ * @since 1.1
+ */
+public void setVisible(boolean visible)
+{
+    // Inspection by subclassing shows that Sun's implementation calls
+    // show(boolean) which then calls show() or hide(). It is the show()
+    // method that is overriden in subclasses like Window.
+    show(visible);
+}
 
-	if ( (flags & IS_VISIBLE) == 0 ) {
-		flags |= IS_VISIBLE;
-		flags &= ~IS_TEMP_HIDDEN;
+/**
+* Makes this component visible on the screen.
+ *
+ * @deprecated use {@link #setVisible(boolean)} instead
+ */
+public void show()
+{
+    // We must set visible before showing the peer.  Otherwise the
+    // peer could post paint events before visible is true, in which
+    // case lightweight components are not initially painted --
+    // Container.paint first calls isShowing () before painting itself
+    // and its children.
+
+    // this is equivalent to isVisible()
+    if ( (flags & IS_VISIBLE) == 0 ) {
+        flags |= IS_VISIBLE;
+        flags &= ~IS_TEMP_HIDDEN;
+
+        // if we are a toplevel, the native window manager will take care
+        // of repainting
+        // Avoid NullPointerExceptions by creating a local reference.
+        ComponentPeer currentPeer=peer;
+        if (currentPeer != null)
+            currentPeer.show();
+
+        // The JDK repaints the component before invalidating the parent.
+        // So do we.
+        if (isShowing() && isLightweight())
+            repaint();
+        // Invalidate the parent if we have one. The component itself must
+        // not be invalidated. We also avoid NullPointerException with
+        // a local reference here.
+        Container currentParent = parent;
+        if (currentParent != null)
+            currentParent.invalidate();
 
-	  // if we are a toplevel, the native window manager will take care
-	  // of repainting
-		if ( (parent != null) && ((parent.flags & IS_LAYOUTING) == 0) ) {
-			if ( (flags & (IS_ADD_NOTIFIED | IS_PARENT_SHOWING))
-			       == (IS_ADD_NOTIFIED | IS_PARENT_SHOWING) ){
-			  //parent.repaint( x, y, width, height);
-				repaint();
-			}
-			
-			if ( (parent.flags & IS_VALID) != 0 )
-				parent.invalidate();
-		}
+        if ( (componentListener != null) || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ){
+            Toolkit.eventQueue.postEvent( ComponentEvt.getEvent( this, ComponentEvent.COMPONENT_SHOWN));
+        }
 
-		if ( (componentListener != null) || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ){
-			Toolkit.eventQueue.postEvent( ComponentEvt.getEvent( this,
-				                                    ComponentEvent.COMPONENT_SHOWN));
-		}
+        // update any resident graphics objects		
+        if ( linkedGraphs != null )
+            updateLinkedGraphics();
+    }
+}
 
-		// update any resident graphics objects		
-		if ( linkedGraphs != null )
-			updateLinkedGraphics();
-	}
-}
-
-public void show ( boolean b ) {
-	// DEP this should map to setVisible but we have to keep it that way because of
-	// compatibility, which in this case requires a double indirection)
-
-	if ( b)
-		show();
-	else
-		hide();
+/**
+* Makes this component visible or invisible.
+ *
+ * @param visible true to make this component visible
+ *
+ * @deprecated use {@link #setVisible(boolean)} instead
+ */
+public void show(boolean visible)
+{
+    if (visible)
+        show();
+    else
+        hide();
 }
 
 /**
@@ -2104,24 +2681,202 @@
 	}
 }
 
-public void update ( Graphics g ) {
-	g.clearRect( 0, 0, width, height);
-	paint( g);
+/**
+* Updates this component. This is called in response to
+ * <code>repaint</code>. This method fills the component with the
+ * background color, then sets the foreground color of the specified
+ * graphics context to the foreground color of this component and calls
+ * the <code>paint()</code> method. The coordinates of the graphics are
+ * relative to this component. Subclasses should call either
+ * <code>super.update(g)</code> or <code>paint(g)</code>.
+ *
+ * @param g the graphics context for this update
+ *
+ * @see #paint(Graphics)
+ * @see #repaint()
+ *
+ * @specnote In contrast to what the spec says, tests show that the exact
+ *           behaviour is to clear the background on lightweight and
+ *           top-level components only. Heavyweight components are not
+ *           affected by this method and only call paint().
+ */
+public void update(Graphics g)
+{
+    // Tests show that the clearing of the background is only done in
+    // two cases:
+    // - If the component is lightweight (yes this is in contrast to the spec).
+    // or
+    // - If the component is a toplevel container.
+    if (isLightweight() || getParent() == null)
+    {
+        Rectangle clip = g.getClipBounds();
+        if (clip == null)
+            g.clearRect(0, 0, width, height);
+        else
+            g.clearRect(clip.x, clip.y, clip.width, clip.height);
+    }
+    paint(g);
 }
 
-// TODO this is only a stub
-public ComponentOrientation getComponentOrientation() {
-	return ComponentOrientation.LEFT_TO_RIGHT;
+/**
+* Sets the text layout orientation of this component. New components default
+ * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only

*** Patch too long, truncated ***




More information about the kaffe mailing list