I was thinking of something more internal that wouldn't require public 
Component API changes. For example, in ApplicationContext.DisplayHost, if the 
"debugfocus" system property exists and is set to true, all we'd need to do is 
create a ComponentClassListener and set it via the static 
Component#getComponentClassListeners() method. Then we could attach/remove a 
focus decorator in the focusedComponentChanged() event.

The reason that I don't think this belongs in the public Component API is 
because it is a) a debug feature and b) up to the skin to determine how focus 
state should be represented, not the component or the application. Making this 
public implies otherwise.

I personally wouldn't worry about allowing the caller to specify a color. I'd 
just pick something visible (for example, old versions of the Flash player used 
to draw a yellow rectangle around the focused element).

G

On Sep 24, 2010, at 9:46 AM, [email protected] wrote:

> Author: cbartlett
> Date: Fri Sep 24 13:46:42 2010
> New Revision: 1000869
> 
> URL: http://svn.apache.org/viewvc?rev=1000869&view=rev
> Log:
> Resolve PIVOT-607
> Added static getFocusDecorator & setFocusDecorator methods to & Component
> ApplicationContext now looks for a 'org.apache.pivot.wtk.debugfocuscolor' 
> system property with a case insensitive value of 'red', 'green' or 'blue'.
> 
> Modified:
>    pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java
>    pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java
> 
> Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java
> URL: 
> http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java?rev=1000869&r1=1000868&r2=1000869&view=diff
> ==============================================================================
> --- pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java 
> (original)
> +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java Fri Sep 
> 24 13:46:42 2010
> @@ -17,6 +17,7 @@
> package org.apache.pivot.wtk;
> 
> import java.awt.AWTEvent;
> +import java.awt.Color;
> import java.awt.Graphics;
> import java.awt.Graphics2D;
> import java.awt.GraphicsConfiguration;
> @@ -61,6 +62,7 @@ import org.apache.pivot.serialization.Se
> import org.apache.pivot.util.Version;
> import org.apache.pivot.wtk.Component.DecoratorSequence;
> import org.apache.pivot.wtk.effects.Decorator;
> +import org.apache.pivot.wtk.effects.ShadeDecorator;
> 
> /**
>  * Base class for application contexts.
> @@ -297,6 +299,26 @@ public abstract class ApplicationContext
>                 // No-op
>             }
> 
> +            try {
> +                String property = 
> System.getProperty("org.apache.pivot.wtk.debugfocuscolor");
> +                if (property != null) {
> +                    property = property.trim().toLowerCase();
> +                    Color focusColor = null;
> +                    if ("red".equals(property)) {
> +                        focusColor = Color.RED;
> +                    } else if ("green".equals(property)) {
> +                        focusColor = Color.GREEN;
> +                    } else if ("blue".equals(property)) {
> +                        focusColor = Color.BLUE;
> +                    }
> +                    if (focusColor != null) {
> +                        Component.setFocusDecorator(new ShadeDecorator(0.2f, 
> focusColor));
> +                    }
> +                }
> +            } catch (SecurityException ex) {
> +                // No-op
> +            }
> +
>             // Add native drop support
>             new java.awt.dnd.DropTarget(this, dropTargetListener);
> 
> 
> Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java
> URL: 
> http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java?rev=1000869&r1=1000868&r2=1000869&view=diff
> ==============================================================================
> --- pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java (original)
> +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/Component.java Fri Sep 24 
> 13:46:42 2010
> @@ -676,6 +676,28 @@ public abstract class Component implemen
>     // The component that currently has the focus
>     private static Component focusedComponent = null;
> 
> +    // Decorator to apply to the focused component
> +    private static Decorator focusDecorator = null;
> +
> +    // Focus change listener to manage adding & removing of focusDecorator
> +    private static final ComponentClassListener FOCUS_CHANGE_LISTENER = new 
> ComponentClassListener() {
> +        @Override
> +        public void focusedComponentChanged(Component 
> previousFocusedComponent) {
> +            Decorator decorator = Component.getFocusDecorator();
> +            if (decorator != null) {
> +                if (previousFocusedComponent != null
> +                    && 
> previousFocusedComponent.getDecorators().indexOf(decorator) > -1) {
> +                    
> previousFocusedComponent.getDecorators().remove(decorator);
> +                }
> +                Component focusedComponent = Component.getFocusedComponent();
> +                if (focusedComponent != null
> +                    && focusedComponent.getDecorators().indexOf(decorator) 
> == -1) {
> +                    focusedComponent.getDecorators().add(decorator);
> +                }
> +            }
> +        }
> +    };
> +
>     // Typed and named styles
>     private static HashMap<Class<? extends Component>, Map<String, ?>> 
> typedStyles =
>         new HashMap<Class<? extends Component>, Map<String,?>>();
> @@ -2430,6 +2452,40 @@ public abstract class Component implemen
>     }
> 
>     /**
> +     * Returns the Decorator which is applied to all focused Components.
> +     *
> +     * @return The Decorator, or <tt>null</tt> if no Decorator has been set.
> +     */
> +    public static Decorator getFocusDecorator() {
> +        return focusDecorator;
> +    }
> +
> +    /**
> +     * Set the Decorator to be applied to all focused Components.
> +     *
> +     * @param focusDecorator
> +     */
> +    public static void setFocusDecorator(Decorator focusDecorator) {
> +        Component focusedComponent = getFocusedComponent();
> +        Decorator previousFocusDecorator = Component.focusDecorator;
> +        Component.focusDecorator = focusDecorator;
> +        if (focusedComponent != null) {
> +            if (previousFocusDecorator != null) {
> +                
> focusedComponent.getDecorators().remove(previousFocusDecorator);
> +            }
> +            if (focusDecorator != null) {
> +                focusedComponent.getDecorators().add(focusDecorator);
> +            }
> +        }
> +        if (focusDecorator == null && previousFocusDecorator != null) {
> +            
> Component.getComponentClassListeners().remove(FOCUS_CHANGE_LISTENER);
> +        }
> +        if (focusDecorator != null && previousFocusDecorator == null) {
> +            
> Component.getComponentClassListeners().add(FOCUS_CHANGE_LISTENER);
> +        }
> +    }
> +
> +    /**
>      * Copies bound values from the bind context to the component. This
>      * functionality must be provided by the subclass; the base implementation
>      * is a no-op.
> 
> 

Reply via email to