Revision: 220 http://skycastle.svn.sourceforge.net/skycastle/?rev=220&view=rev Author: zzorn Date: 2007-10-05 12:40:09 -0700 (Fri, 05 Oct 2007) Log Message: ----------- Utility for changing the mouse cursor, and remembering previous mouse cursors (a cursor mode stack) Added Paths: ----------- trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/ trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChanger.java trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChangerImpl.java Added: trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChanger.java =================================================================== --- trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChanger.java (rev 0) +++ trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChanger.java 2007-10-05 19:40:09 UTC (rev 220) @@ -0,0 +1,31 @@ +package org.skycastle.util.cursor; + +import java.awt.Cursor; + +/** + * Allows setting the mouse cursor for some visual component from several different sources. + * <p/> + * Keeps track of who set the cursor to what shape, and resets to previous states when someone doesn't need to show + * their state anymore. + * + * @author Hans H\xE4ggstr\xF6m + */ +public interface CursorChanger +{ + /** + * Sets the current cursor state. Overrides earlier states. + * + * @param cursorSetter some object that represents the instance that is setting the cursor to an image. + * Used to allow resetting the change. Should not be null. + * @param cursor the cursor to use, or null to use an empty cursor. + */ + void setCursor( Object cursorSetter, Cursor cursor ); + + /** + * Removes the cursor icon set by the specified cursorSetter, and restores the cursor to the icon used before. + * + * @param cursorSetter the instance that set the cursor to some state. Should not be null. + */ + void resetCursor( Object cursorSetter ); + +} Property changes on: trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChanger.java ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Id Name: svn:eol-style + native Added: trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChangerImpl.java =================================================================== --- trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChangerImpl.java (rev 0) +++ trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChangerImpl.java 2007-10-05 19:40:09 UTC (rev 220) @@ -0,0 +1,217 @@ +package org.skycastle.util.cursor; + +import org.skycastle.util.ParameterChecker; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.util.Stack; + +/** + * @author Hans H\xE4ggstr\xF6m + */ +public final class CursorChangerImpl + implements CursorChanger +{ + + //====================================================================== + // Private Fields + + private Component myComponent = null; + private Cursor myOriginalCursor = null; + + private Stack<CursorEntry> myCursorStack = new Stack<CursorEntry>(); + + //====================================================================== + // Private Constants + + private static final Cursor EMPTY_CURSOR = createEmptyCursor(); + + //====================================================================== + // Public Methods + + //---------------------------------------------------------------------- + // Constructors + + /** + * Creates a new CursorChangerImpl. You can use setComponent to set the component to manage. + */ + public CursorChangerImpl() + { + } + + + /** + * @param component some component whose cursor should be managed by this cursor changer. + */ + public CursorChangerImpl( final Component component ) + { + setComponent( component ); + } + + //---------------------------------------------------------------------- + // CursorChanger Implementation + + public void setCursor( Object cursorSetter, Cursor cursor ) + { + ParameterChecker.checkNotNull( cursorSetter, "cursorSetter" ); + + myCursorStack.push( new CursorEntry( cursorSetter, cursor ) ); + setCursor( cursor ); + } + + + public void resetCursor( final Object cursorSetter ) + { + ParameterChecker.checkNotNull( cursorSetter, "cursorSetter" ); + + // If the setter is topmost, change the cursor to the previous cursor. + if ( !myCursorStack.isEmpty() && myCursorStack.peek().cursorSetter.equals( cursorSetter ) ) + { + myCursorStack.pop(); + + if ( myCursorStack.isEmpty() ) + { + setCursor( myOriginalCursor ); + } + else + { + setCursor( myCursorStack.peek().cursor ); + } + } + else + { + // Otherwise just remove the entry from the stack + removeEntry( cursorSetter ); + } + } + + //---------------------------------------------------------------------- + // Other Public Methods + + /** + * @param component some component whose cursor should be managed by this cursor changer. + */ + public void setComponent( final Component component ) + { + ParameterChecker.checkNotNull( component, "component" ); + + // Restore cursor for previous component + if ( myComponent != null ) + { + myComponent.setCursor( myOriginalCursor ); + } + + // Set new component + myComponent = component; + myOriginalCursor = myComponent.getCursor(); + + // Set latest cursor + if ( !myCursorStack.isEmpty() ) + { + setCursor( myCursorStack.peek().cursor ); + } + } + + //====================================================================== + // Private Methods + + private void setCursor( Cursor cursor ) + { + if ( cursor == null ) + { + cursor = EMPTY_CURSOR; + } + + if ( myComponent != null ) + { + myComponent.setCursor( cursor ); + } + } + + + private static Cursor createEmptyCursor() + { + final BufferedImage emptyImage = new BufferedImage( 1, 1, BufferedImage.TYPE_INT_ARGB ); + emptyImage.setRGB( 0, 0, 0 ); + return Toolkit.getDefaultToolkit().createCustomCursor( emptyImage, new Point( 0, 0 ), "EmptyCursor" ); + } + + + private void removeEntry( final Object cursorSetter ) + { + CursorEntry entryToRemove = null; + for ( CursorEntry cursorEntry : myCursorStack ) + { + if ( cursorEntry.cursorSetter.equals( cursorSetter ) ) + { + entryToRemove = cursorEntry; + break; + } + } + + if ( entryToRemove != null ) + { + myCursorStack.remove( entryToRemove ); + } + } + + //====================================================================== + // Inner Classes + + private static final class CursorEntry + { + + //====================================================================== + // Non-Private Fields + + final Object cursorSetter; + final Cursor cursor; + + //====================================================================== + // Public Methods + + //---------------------------------------------------------------------- + // Constructors + + public CursorEntry( final Object cursorSetter, final Cursor cursor ) + { + this.cursorSetter = cursorSetter; + this.cursor = cursor; + } + + //---------------------------------------------------------------------- + // Caononical Methods + + public boolean equals( final Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + + final CursorEntry that = (CursorEntry) o; + + if ( cursorSetter != null ? !cursorSetter.equals( that.cursorSetter ) : that.cursorSetter != null ) + { + return false; + } + + return true; + } + + + public int hashCode() + { + return ( cursorSetter != null ? cursorSetter.hashCode() : 0 ); + } + + } + +} Property changes on: trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/cursor/CursorChangerImpl.java ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Id Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.