Revision: 1342
Author: mathiasbr
Date: 2006-08-25 08:01:15 -0700 (Fri, 25 Aug 2006)
ViewCVS: http://svn.sourceforge.net/spring-rich-c/?rev=1342&view=rev
Log Message:
-----------
allow subclasses to define custom conditional constraints for enabled and
visible state.
Modified Paths:
--------------
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/command/AbstractCommand.java
Added Paths:
-----------
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/AdditionalStateTestCommand.java
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonTests.java
Removed Paths:
-------------
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonEnablingTests.java
Modified:
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/command/AbstractCommand.java
===================================================================
---
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/command/AbstractCommand.java
2006-08-25 08:28:12 UTC (rev 1341)
+++
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/command/AbstractCommand.java
2006-08-25 15:01:15 UTC (rev 1342)
@@ -32,9 +32,7 @@
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.binding.value.ValueModel;
import
org.springframework.binding.value.support.AbstractPropertyChangePublisher;
-import org.springframework.binding.value.support.ValueHolder;
import org.springframework.core.style.ToStringCreator;
import org.springframework.richclient.application.ApplicationServicesLocator;
import org.springframework.richclient.command.config.CommandButtonConfigurer;
@@ -47,6 +45,7 @@
import org.springframework.richclient.factory.ButtonFactory;
import org.springframework.richclient.factory.LabelInfoFactory;
import org.springframework.richclient.factory.MenuFactory;
+import org.springframework.util.Assert;
import org.springframework.util.CachingMapDecorator;
import org.springframework.util.StringUtils;
@@ -63,14 +62,12 @@
private String defaultFaceDescriptorId = DEFAULT_FACE_DESCRIPTOR_ID;
- private ValueModel enabled = new ValueHolder(Boolean.TRUE);
+ private boolean enabled = true;
private boolean visible = true;
private boolean authorized = true;
- private boolean maskedEnabledState = true;
-
private String securityControllerId = null;
private Map faceButtonManagers;
@@ -79,12 +76,19 @@
private CommandFaceDescriptorRegistry faceDescriptorRegistry;
+ private boolean oldEnabledState = enabled;
+
+ private boolean oldVisibleState = visible;
+
protected AbstractCommand() {
this(null);
}
protected AbstractCommand(String id) {
- this(id, (CommandFaceDescriptor)null);
+ super();
+ setId(id);
+ addEnabledListener(new ButtonEnablingListener()); // keep track of
enable state for buttons
+ addPropertyChangeListener(VISIBLE_PROPERTY_NAME, new
ButtonVisibleListener()); // keep track of visible state for buttons
}
protected AbstractCommand(String id, String encodedLabel) {
@@ -96,18 +100,14 @@
}
protected AbstractCommand(String id, CommandFaceDescriptor faceDescriptor)
{
- super();
- setId(id);
- addEnabledListener(new ButtonEnablingListener()); // keep track of
enable state for buttons
+ this(id);
if (faceDescriptor != null) {
setFaceDescriptor(faceDescriptor);
}
}
protected AbstractCommand(String id, Map faceDescriptors) {
- super();
- setId(id);
- addEnabledListener(new ButtonEnablingListener()); // keep track of
enable state for buttons
+ this(id);
setFaceDescriptors(faceDescriptors);
}
@@ -137,6 +137,7 @@
}
public void setFaceDescriptors(Map faceDescriptors) {
+ Assert.notNull(faceDescriptors);
Iterator it = faceDescriptors.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
@@ -275,25 +276,12 @@
* it can not be enabled.
* @param authorized Pass <code>true</code> if the object is to be
authorized
*/
- public void setAuthorized( boolean authorized ) {
+ public void setAuthorized(boolean authorized) {
boolean wasAuthorized = isAuthorized();
-
- if( hasChanged(isAuthorized(), authorized)) {
-
+ if (hasChanged(wasAuthorized, authorized)) {
this.authorized = authorized;
-
- // We need to apply a change to our enabled state depending on our
- // new authorized state.
- if( authorized ) {
- // install the last requested enabled state
- setEnabled(maskedEnabledState);
- } else {
- // Record the current enabled state and then disable
- maskedEnabledState = isEnabled();
- internalSetEnabled(false);
- }
-
- firePropertyChange(AUTHORIZED_PROPERTY, !wasAuthorized,
authorized);
+ firePropertyChange(AUTHORIZED_PROPERTY, wasAuthorized, authorized);
+ updatedEnabledState();
}
}
@@ -305,9 +293,29 @@
return authorized;
}
+ /**
+ * Get the enabled state
+ * @return if the command is enabled and [EMAIL PROTECTED]
#isAuthorized()} returns true
+ * @see #isAuthorized()
+ */
public boolean isEnabled() {
- return ((Boolean)enabled.getValue()).booleanValue();
+ return enabled && isAuthorized();
}
+
+ /**
+ * This method is called when any predicate for enabled state has changed.
This implemetation fires the enabled
+ * changed event if the return value of [EMAIL PROTECTED] #isEnabled()}
has changed.
+ * <p>
+ * Sublcasses which have an additional predicate to enabled state must
call this method if the state of the
+ * predicate changes.
+ */
+ protected void updatedEnabledState() {
+ boolean isEnabled = isEnabled();
+ if(hasChanged(oldEnabledState, isEnabled)) {
+ firePropertyChange(ENABLED_PROPERTY_NAME, oldEnabledState,
isEnabled);
+ }
+ oldEnabledState = isEnabled;
+ }
/**
* Set the enabled state of this command. Note that if we are currently
not
@@ -316,25 +324,13 @@
* @param enabled state
*/
public void setEnabled(boolean enabled) {
- maskedEnabledState = enabled;
- if( isAuthorized() ) {
- internalSetEnabled( enabled );
+ if( hasChanged(this.enabled, enabled)) {
+ this.enabled = enabled;
+ updatedEnabledState();
}
}
/**
- * Internal method to set the enabled state. This is needed so that calls
- * made to the public setEnabled and this method can be handled
differently.
- * @param enabled state
- * @see #setAuthorized(boolean)
- */
- protected void internalSetEnabled( boolean enabled ) {
- if (hasChanged(isEnabled(), enabled)) {
- this.enabled.setValue(Boolean.valueOf(enabled));
- }
- }
-
- /**
* Listener to keep track of enabled state. When enable on command changes,
* each button has to be checked and set.
*/
@@ -350,17 +346,38 @@
while (it.hasNext())
{
AbstractButton button = (AbstractButton)it.next();
- button.setEnabled(enabled);
+ button.setEnabled(enabled);
}
}
}
+ /**
+ * Listener to keep track of visible state. When visible on command
changes,
+ * each button has to be checked and set.
+ */
+ private class ButtonVisibleListener implements PropertyChangeListener
+ {
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // We need to keep the buttons in sync with the command, so go
through the buttons and set visible state.
+ // alternative is to add a listener to the visible value and
change buttons in that listener
+ // NOT redundant
+ boolean enabled = evt.getNewValue() == Boolean.TRUE ? true : false;
+ Iterator it = buttonIterator();
+ while (it.hasNext())
+ {
+ AbstractButton button = (AbstractButton)it.next();
+ button.setVisible(enabled);
+ }
+ }
+ }
+
public void addEnabledListener(PropertyChangeListener listener) {
- enabled.addValueChangeListener(listener);
+ addPropertyChangeListener(ENABLED_PROPERTY_NAME, listener);
}
public void removeEnabledListener(PropertyChangeListener listener) {
- enabled.removeValueChangeListener(listener);
+ removePropertyChangeListener(ENABLED_PROPERTY_NAME, listener);
}
protected final Iterator defaultButtonIterator() {
@@ -442,13 +459,24 @@
public void setVisible(boolean value) {
if (visible != value) {
this.visible = value;
- for (Iterator it = buttonIterator(); it.hasNext();) {
- AbstractButton button = (AbstractButton)it.next();
- button.setVisible(visible);
- }
- firePropertyChange(VISIBLE_PROPERTY_NAME, !visible, visible);
+ updatedVisibleState();
}
}
+
+ /**
+ * This method is called when any predicate for visible state has changed.
This implemetation fires the visible
+ * changed event if the return value of [EMAIL PROTECTED] #isVisible()}
has changed.
+ * <p>
+ * Sublcasses which have an additional predicate to visible state must
call this method if the state of the
+ * predicate changes.
+ */
+ protected void updatedVisibleState() {
+ boolean isVisible = isVisible();
+ if(hasChanged(oldVisibleState, isVisible)) {
+ firePropertyChange(VISIBLE_PROPERTY_NAME, oldVisibleState,
isVisible);
+ }
+ oldVisibleState = isVisible;
+ }
public final AbstractButton createButton() {
return createButton(getDefaultFaceDescriptorId(), getButtonFactory(),
getDefaultButtonConfigurer());
Added:
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/AdditionalStateTestCommand.java
===================================================================
---
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/AdditionalStateTestCommand.java
(rev 0)
+++
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/AdditionalStateTestCommand.java
2006-08-25 15:01:15 UTC (rev 1342)
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002-2004 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+package org.springframework.richclient.command.support;
+
+import org.springframework.richclient.command.ActionCommand;
+
+/**
+ * @author Peter De Bruycker
+ */
+public class AdditionalStateTestCommand extends ActionCommand {
+
+ private boolean myenabledState = true;
+
+ private boolean myvisibleState = true;
+
+ public AdditionalStateTestCommand() {
+ }
+
+ public AdditionalStateTestCommand(String id) {
+ super(id);
+ }
+
+ /**
+ * @see
org.springframework.richclient.command.ActionCommand#doExecuteCommand()
+ */
+ protected void doExecuteCommand() {
+ }
+
+ public boolean isMyenabledState() {
+ return myenabledState;
+ }
+
+ public boolean isEnabled() {
+ return super.isEnabled() && isMyenabledState();
+ }
+
+ public void setMyenabledState(boolean myenabledState) {
+ if (hasChanged(myenabledState, isMyenabledState())) {
+ this.myenabledState = myenabledState;
+ updatedEnabledState();
+ }
+ }
+
+ public boolean isVisible() {
+ return super.isVisible() && isMyvisibleState();
+ }
+
+ public boolean isMyvisibleState() {
+ return myvisibleState;
+ }
+
+ public void setMyvisibleState(boolean myvisibleState) {
+ if (hasChanged(myvisibleState, isMyvisibleState())) {
+ this.myvisibleState = myvisibleState;
+ updatedVisibleState();
+ }
+ }
+}
\ No newline at end of file
Property changes on:
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/AdditionalStateTestCommand.java
___________________________________________________________________
Name: svn:keywords
+ URL Author Revision Date
Name: svn:eol-style
+ native
Deleted:
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonEnablingTests.java
===================================================================
---
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonEnablingTests.java
2006-08-25 08:28:12 UTC (rev 1341)
+++
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonEnablingTests.java
2006-08-25 15:01:15 UTC (rev 1342)
@@ -1,86 +0,0 @@
-package org.springframework.richclient.command.support;
-
-import javax.swing.AbstractButton;
-
-import org.springframework.binding.value.support.EqualsValueChangeDetector;
-import org.springframework.richclient.application.ApplicationServicesLocator;
-import
org.springframework.richclient.application.config.ApplicationObjectConfigurer;
-import
org.springframework.richclient.application.support.DefaultApplicationServices;
-import org.springframework.richclient.command.AbstractCommand;
-import org.springframework.richclient.command.config.CommandFaceDescriptor;
-import org.springframework.richclient.test.SpringRichTestCase;
-
-
-public class ButtonEnablingTests extends SpringRichTestCase
-{
-
- /**
- * May be implemented in subclasses that need to register services with
the global
- * application services instance.
- */
- protected void registerAdditionalServices( DefaultApplicationServices
applicationServices ) {
- applicationServices.setValueChangeDetector(new
EqualsValueChangeDetector());
- }
-
- public void testButtonEnabling()
- {
- TestCommand testCommand = new TestCommand();
- AbstractButton button = testCommand.createButton();
- AbstractButton button2 = testCommand.createButton();
- enableTests(testCommand, new Object[]{button, button2});
- }
-
- public void enableTests(AbstractCommand command, Object[] buttons)
- {
- enableTest(command, buttons, false);
- enableTest(command, buttons, true);
- }
-
- public void enableTest(AbstractCommand command, Object[] buttons, boolean
enable)
- {
- command.setEnabled(enable);
- assertEquals(command.isEnabled(), enable);
- for (int i = 0; i < buttons.length; ++i)
- {
- assertEquals(((AbstractButton)buttons[i]).isEnabled(), enable);
- }
- }
-
- // testing different sequences because error was in sequence of hashmap:
- public void testMultipleFaceDescriptorsEnabling()
- {
- multipleFaceDescriptorSequence("face1", "face2", "face3");
- multipleFaceDescriptorSequence("face1", "face3", "face2");
-
- multipleFaceDescriptorSequence("face2", "face1", "face3");
- multipleFaceDescriptorSequence("face2", "face3", "face1");
-
- multipleFaceDescriptorSequence("face3", "face2", "face1");
- multipleFaceDescriptorSequence("face3", "face1", "face2");
- }
-
- private void multipleFaceDescriptorSequence(String face1, String face2,
String face3)
- {
- TestCommand testCommand = new TestCommand();
- registerCommandFaceDescriptor(face1, testCommand);
- registerCommandFaceDescriptor(face2, testCommand);
- registerCommandFaceDescriptor(face3, testCommand);
-
- AbstractButton face1button = testCommand.createButton(face1);
- enableTests(testCommand, new Object[]{face1button});
-
- AbstractButton face2button = testCommand.createButton(face2);
- enableTests(testCommand, new Object[]{face1button, face2button});
-
- AbstractButton face3button = testCommand.createButton(face3);
- enableTests(testCommand, new Object[]{face1button, face2button,
face3button});
- }
-
- private void registerCommandFaceDescriptor(String faceId, AbstractCommand
command)
- {
- CommandFaceDescriptor face = new CommandFaceDescriptor();
- ApplicationObjectConfigurer configurer =
(ApplicationObjectConfigurer)ApplicationServicesLocator.services().getService(ApplicationObjectConfigurer.class);
- configurer.configure(face, faceId);
- command.setFaceDescriptor(faceId, face);
- }
-}
Copied:
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonTests.java
(from rev 1341,
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonEnablingTests.java)
===================================================================
---
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonTests.java
(rev 0)
+++
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/command/support/ButtonTests.java
2006-08-25 15:01:15 UTC (rev 1342)
@@ -0,0 +1,142 @@
+package org.springframework.richclient.command.support;
+
+import javax.swing.AbstractButton;
+
+import org.springframework.binding.value.support.EqualsValueChangeDetector;
+import org.springframework.richclient.application.ApplicationServicesLocator;
+import
org.springframework.richclient.application.config.ApplicationObjectConfigurer;
+import
org.springframework.richclient.application.support.DefaultApplicationServices;
+import org.springframework.richclient.command.AbstractCommand;
+import org.springframework.richclient.command.config.CommandFaceDescriptor;
+import org.springframework.richclient.test.SpringRichTestCase;
+
+
+public class ButtonTests extends SpringRichTestCase
+{
+
+ /**
+ * May be implemented in subclasses that need to register services with
the global
+ * application services instance.
+ */
+ protected void registerAdditionalServices( DefaultApplicationServices
applicationServices ) {
+ applicationServices.setValueChangeDetector(new
EqualsValueChangeDetector());
+ }
+
+ public void testButtonEnabling()
+ {
+ TestCommand testCommand = new TestCommand();
+ AbstractButton button = testCommand.createButton();
+ AbstractButton button2 = testCommand.createButton();
+ enableTests(testCommand, new Object[]{button, button2});
+ }
+
+ public void enableTests(AbstractCommand command, Object[] buttons)
+ {
+ enableTest(command, buttons, false);
+ enableTest(command, buttons, true);
+ }
+
+ public void enableTest(AbstractCommand command, Object[] buttons, boolean
enable)
+ {
+ command.setEnabled(enable);
+ assertEquals(command.isEnabled(), enable);
+ for (int i = 0; i < buttons.length; ++i)
+ {
+ assertEquals(enable, ((AbstractButton)buttons[i]).isEnabled());
+ }
+ }
+
+ public void testButtonVisible()
+ {
+ TestCommand testCommand = new TestCommand();
+ AbstractButton button = testCommand.createButton();
+ AbstractButton button2 = testCommand.createButton();
+ visibleTests(testCommand, new Object[]{button, button2});
+ }
+
+ public void visibleTests(AbstractCommand command, Object[] buttons)
+ {
+ enableTest(command, buttons, false);
+ enableTest(command, buttons, true);
+ }
+
+ public void visibleTest(AbstractCommand command, Object[] buttons, boolean
visible)
+ {
+ command.setVisible(visible);
+ assertEquals(command.isVisible(), visible);
+ for (int i = 0; i < buttons.length; ++i)
+ {
+ assertEquals(visible, ((AbstractButton)buttons[i]).isVisible());
+ }
+ }
+
+ // testing different sequences because error was in sequence of hashmap:
+ public void testMultipleFaceDescriptorsEnabling()
+ {
+ multipleFaceDescriptorSequence("face1", "face2", "face3");
+ multipleFaceDescriptorSequence("face1", "face3", "face2");
+
+ multipleFaceDescriptorSequence("face2", "face1", "face3");
+ multipleFaceDescriptorSequence("face2", "face3", "face1");
+
+ multipleFaceDescriptorSequence("face3", "face2", "face1");
+ multipleFaceDescriptorSequence("face3", "face1", "face2");
+ }
+
+ private void multipleFaceDescriptorSequence(String face1, String face2,
String face3)
+ {
+ TestCommand testCommand = new TestCommand();
+ registerCommandFaceDescriptor(face1, testCommand);
+ registerCommandFaceDescriptor(face2, testCommand);
+ registerCommandFaceDescriptor(face3, testCommand);
+
+ AbstractButton face1button = testCommand.createButton(face1);
+ enableTests(testCommand, new Object[]{face1button});
+
+ AbstractButton face2button = testCommand.createButton(face2);
+ enableTests(testCommand, new Object[]{face1button, face2button});
+
+ AbstractButton face3button = testCommand.createButton(face3);
+ enableTests(testCommand, new Object[]{face1button, face2button,
face3button});
+ }
+
+ private void registerCommandFaceDescriptor(String faceId, AbstractCommand
command)
+ {
+ CommandFaceDescriptor face = new CommandFaceDescriptor();
+ ApplicationObjectConfigurer configurer =
(ApplicationObjectConfigurer)ApplicationServicesLocator.services().getService(ApplicationObjectConfigurer.class);
+ configurer.configure(face, faceId);
+ command.setFaceDescriptor(faceId, face);
+ }
+
+ /**
+ * Tests if a command subclass can use an additional condition when enable
is enabled or not
+ * @throws Exception
+ */
+ public void testAdditionalConditionToEnable() throws Exception {
+ AdditionalStateTestCommand testCommand = new
AdditionalStateTestCommand();
+ AbstractButton button = testCommand.createButton();
+ assertEquals(testCommand.isEnabled(), button.isEnabled());
+ testCommand.setMyenabledState(false);
+ assertEquals(false, testCommand.isEnabled());
+ assertEquals(testCommand.isEnabled(), button.isEnabled());
+ testCommand.setMyenabledState(true);
+ assertEquals(true, testCommand.isEnabled());
+ assertEquals(testCommand.isEnabled(), button.isEnabled());
+ }
+
+ /**
+ * Tests if a command subclass can use an additional condition when
visible is enabled or not
+ * @throws Exception
+ */
+ public void testAdditionalConditionToVisible() throws Exception {
+ AdditionalStateTestCommand testCommand = new
AdditionalStateTestCommand();
+ AbstractButton button = testCommand.createButton();
+ assertEquals(testCommand.isVisible(), button.isVisible());
+ testCommand.setMyvisibleState(false);
+ assertEquals(false, testCommand.isVisible());
+ assertEquals(testCommand.isVisible(), button.isVisible());
+ testCommand.setMyvisibleState(true);
+ assertEquals(true, testCommand.isVisible());
+ assertEquals(testCommand.isVisible(), button.isVisible());
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
spring-rich-c-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spring-rich-c-cvs