Revision: 1129
Author: peterdb
Date: 2006-05-10 12:30:40 -0700 (Wed, 10 May 2006)
ViewCVS: http://svn.sourceforge.net/spring-rich-c/?rev=1129&view=rev
Log Message:
-----------
initial version of DirtyIndicatorInterceptor + small refactoring of
OverlayValidationInterceptor
Modified Paths:
--------------
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
Added Paths:
-----------
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptorFactory.java
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/InterceptorOverlayHelper.java
Added:
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptorFactory.java
===================================================================
---
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptorFactory.java
(rev 0)
+++
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/DirtyIndicatorInterceptorFactory.java
2006-05-10 19:30:40 UTC (rev 1129)
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2002-2006 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.form.builder.support;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Locale;
+
+import javax.swing.Icon;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+
+import org.springframework.binding.form.FormModel;
+import org.springframework.binding.value.support.ValueHolder;
+import org.springframework.richclient.application.Application;
+import org.springframework.richclient.form.builder.FormComponentInterceptor;
+import
org.springframework.richclient.form.builder.FormComponentInterceptorFactory;
+import org.springframework.richclient.util.OverlayHelper;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * Adds a "dirty overlay" to a component that is triggered by user editing.
The overlaid
+ * image is retrieved by the image key "dirty.overlay". The image is placed at
the
+ * top-left corner of the component, and the image's tooltip is set to a
message
+ * (retrieved with key "dirty.message") such as "{field} has changed, original
value was
+ * {value}.".
+ *
+ * @author Peter De Bruycker
+ */
+public class DirtyIndicatorInterceptorFactory implements
FormComponentInterceptorFactory {
+ private static final String DEFAULT_ICON_KEY = "dirty.overlay";
+ private static final String DEFAULT_MESSAGE_KEY = "dirty.message";
+
+ private String iconKey = DEFAULT_ICON_KEY;
+
+ public FormComponentInterceptor getInterceptor( FormModel formModel ) {
+ return new DirtyIndicatorInterceptor( formModel,
Application.instance().getServices().getIcon( iconKey ) );
+ }
+
+ public void setIconKey( String iconKey ) {
+ this.iconKey = iconKey;
+ }
+
+ public String getIconKey() {
+ return iconKey;
+ }
+
+ private static class DirtyIndicatorInterceptor extends
AbstractFormComponentInterceptor {
+ private Icon icon;
+
+ private DirtyIndicatorInterceptor( FormModel formModel, Icon icon ) {
+ super( formModel );
+ this.icon = icon;
+ }
+
+ public void processComponent( final String propertyName, final
JComponent component ) {
+ final JLabel overlay = new JLabel( icon );
+
+ final OriginalValueHolder originalValueHolder = new
OriginalValueHolder();
+ final ValueHolder reset = new ValueHolder( Boolean.FALSE );
+ getFormModel().getValueModel( propertyName
).addValueChangeListener( new PropertyChangeListener() {
+ public void propertyChange( PropertyChangeEvent evt ) {
+ if( reset.getValue() == Boolean.TRUE ) {
+ originalValueHolder.reset();
+ reset.setValue( Boolean.FALSE );
+
+ overlay.setVisible( false );
+
+ return;
+ }
+
+ if( !originalValueHolder.isInitialized() ) {
+ originalValueHolder.setOriginalValue(
evt.getOldValue() );
+ }
+
+ if( isDirty(originalValueHolder.getValue(),
evt.getNewValue()) ) {
+ String tooltip = Application.services().getMessage(
+ DEFAULT_MESSAGE_KEY,
+ new Object[] {
+ Application.services().getMessage(
propertyName + ".label", null,
+ Locale.getDefault() ),
originalValueHolder.getValue() }, null );
+ overlay.setToolTipText( tooltip );
+ overlay.setVisible( true );
+ } else {
+ overlay.setVisible( false );
+ }
+ }
+ } );
+ getFormModel().getFormObjectHolder().addValueChangeListener( new
PropertyChangeListener() {
+ public void propertyChange( PropertyChangeEvent evt ) {
+ // reset original value, new "original" value is in the
form model as
+ // the form object has changed
+ reset.setValue( Boolean.TRUE );
+ }
+ } );
+
+ InterceptorOverlayHelper.attachOverlay( overlay, component,
OverlayHelper.NORTH_WEST, 0, 0 );
+ overlay.setVisible( false );
+ }
+
+ private boolean isDirty( Object oldValue, Object newValue ) {
+ if( oldValue == null && newValue instanceof String ) {
+ // hack for string comparison: null equals empty string
+ return !ObjectUtils.nullSafeEquals( "", newValue );
+ } else {
+ return !ObjectUtils.nullSafeEquals( oldValue, newValue );
+ }
+ }
+ }
+
+ private static class OriginalValueHolder {
+ private boolean initialized;
+ private Object originalValue;
+
+ public void setOriginalValue( Object value ) {
+ initialized = true;
+ originalValue = value;
+ }
+
+ public void reset() {
+ initialized = false;
+ originalValue = null;
+ }
+
+ public Object getValue() {
+ return originalValue;
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+ }
+}
Added:
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/InterceptorOverlayHelper.java
===================================================================
---
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/InterceptorOverlayHelper.java
(rev 0)
+++
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/InterceptorOverlayHelper.java
2006-05-10 19:30:40 UTC (rev 1129)
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2002-2006 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.form.builder.support;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.JViewport;
+
+import org.springframework.richclient.util.OverlayHelper;
+
+/**
+ * Helper class to attach overlay components to form components. This is
needed as some
+ * form components are placed inside a scrollpane, and in that case the
overlay should be
+ * added to the scrollpane and not to the form component itself.
+ */
+public class InterceptorOverlayHelper {
+ private InterceptorOverlayHelper() {
+ // static class only
+ }
+
+ public static void attachOverlay( final JComponent overlay, final
JComponent component, final int center,
+ final int xOffset, final int yOffset ) {
+ if( component.getParent() == null ) {
+ PropertyChangeListener waitUntilHasParentListener = new
PropertyChangeListener() {
+ public void propertyChange( PropertyChangeEvent e ) {
+ if( component.getParent() != null ) {
+ component.removePropertyChangeListener( "ancestor",
this );
+ doAttachOverlay( overlay, component, center, xOffset,
yOffset );
+ }
+ }
+ };
+ component.addPropertyChangeListener( "ancestor",
waitUntilHasParentListener );
+ } else {
+ doAttachOverlay( overlay, component, center, xOffset, yOffset );
+ }
+ }
+
+ private static void doAttachOverlay( JComponent overlay, JComponent
component, int center, int xOffset, int yOffset ) {
+ JComponent componentToOverlay = hasParentScrollPane( component ) ?
getParentScrollPane( component ) : component;
+ OverlayHelper.attachOverlay( overlay, componentToOverlay, center,
xOffset, yOffset );
+ }
+
+ private static JScrollPane getParentScrollPane( JComponent component ) {
+ return (JScrollPane) component.getParent().getParent();
+ }
+
+ private static boolean hasParentScrollPane( JComponent component ) {
+ return component.getParent() != null && component.getParent()
instanceof JViewport
+ && component.getParent().getParent() instanceof JScrollPane;
+ }
+}
Modified:
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
===================================================================
---
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
2006-05-10 19:25:06 UTC (rev 1128)
+++
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/form/builder/support/OverlayValidationInterceptorFactory.java
2006-05-10 19:30:40 UTC (rev 1129)
@@ -20,9 +20,7 @@
import javax.swing.JComponent;
import javax.swing.JLabel;
-import javax.swing.JScrollPane;
import javax.swing.JTextField;
-import javax.swing.JViewport;
import org.springframework.binding.form.FormModel;
import org.springframework.binding.validation.Severity;
@@ -36,12 +34,11 @@
import org.springframework.richclient.util.OverlayHelper;
/**
- * Adds an "overlay" to a component that is triggered by a validation event.
The
- * overlaid image is retrieved by the image key
- * "severity.{severityShortCode}.overlay", where {severityShortCode} is the
- * number returned by [EMAIL PROTECTED] Severity#getShortCode()}. The image is
placed at
- * the bottom-left corner of the component, and the image's tooltip is set to
- * the validation message.
+ * Adds an "overlay" to a component that is triggered by a validation event.
The overlaid
+ * image is retrieved by the image key "severity.{severityShortCode}.overlay",
where
+ * {severityShortCode} is the number returned by [EMAIL PROTECTED]
Severity#getShortCode()}. The
+ * image is placed at the bottom-left corner of the component, and the image's
tooltip is
+ * set to the validation message.
*
* @author Oliver Hutchison
* @see OverlayHelper#attachOverlay
@@ -54,77 +51,66 @@
textCompHeight = new JTextField().getPreferredSize().height;
}
- public FormComponentInterceptor getInterceptor(FormModel formModel) {
- return new OverlayValidationInterceptor(formModel);
+ public FormComponentInterceptor getInterceptor( FormModel formModel ) {
+ return new OverlayValidationInterceptor( formModel );
}
public class OverlayValidationInterceptor extends ValidationInterceptor {
- public OverlayValidationInterceptor(FormModel formModel) {
- super(formModel);
+ public OverlayValidationInterceptor( FormModel formModel ) {
+ super( formModel );
}
- public void processComponent(String propertyName, final JComponent
component) {
+ public void processComponent( String propertyName, final JComponent
component ) {
final ErrorReportingOverlay overlay = new ErrorReportingOverlay();
- registerGuarded(propertyName, overlay);
- registerMessageReceiver(propertyName, overlay);
+ registerGuarded( propertyName, overlay );
+ registerMessageReceiver( propertyName, overlay );
- if (component.getParent() == null) {
+ if( component.getParent() == null ) {
PropertyChangeListener waitUntilHasParentListener = new
PropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent e) {
- if (component.getParent() != null) {
- component.removePropertyChangeListener("ancestor",
this);
- attachOverlay(overlay, component);
+ public void propertyChange( PropertyChangeEvent e ) {
+ if( component.getParent() != null ) {
+ component.removePropertyChangeListener(
"ancestor", this );
+ attachOverlay( overlay, component );
}
}
};
- component.addPropertyChangeListener("ancestor",
waitUntilHasParentListener);
+ component.addPropertyChangeListener( "ancestor",
waitUntilHasParentListener );
+ } else {
+ attachOverlay( overlay, component );
}
- else {
- attachOverlay(overlay, component);
- }
}
- private void attachOverlay(ErrorReportingOverlay overlay, JComponent
component) {
- JComponent componentToOverlay = hasParentScrollPane(component) ?
getParentScrollPane(component) : component;
- int yOffset = componentToOverlay.getPreferredSize().height;
- OverlayHelper.attachOverlay(overlay, componentToOverlay,
OverlayHelper.NORTH_WEST, 0, Math.min(yOffset,
- textCompHeight));
+ private void attachOverlay( ErrorReportingOverlay overlay, JComponent
component ) {
+ int yOffset = component.getPreferredSize().height;
+ InterceptorOverlayHelper.attachOverlay( overlay, component,
OverlayHelper.NORTH_WEST, 0, Math.min( yOffset,
+ textCompHeight ) );
}
-
- private JScrollPane getParentScrollPane(JComponent component) {
- return (JScrollPane)component.getParent().getParent();
- }
-
- private boolean hasParentScrollPane(JComponent component) {
- return component.getParent() != null && component.getParent()
instanceof JViewport
- && component.getParent().getParent() instanceof
JScrollPane;
- }
}
private class ErrorReportingOverlay extends JLabel implements Messagable,
Guarded {
- private DefaultMessageAreaModel messageBuffer = new
DefaultMessageAreaModel(this);
+ private DefaultMessageAreaModel messageBuffer = new
DefaultMessageAreaModel( this );
public boolean isEnabled() {
return true;
}
- public void setEnabled(boolean enabled) {
- setVisible(!enabled);
+ public void setEnabled( boolean enabled ) {
+ setVisible( !enabled );
}
- public void setMessage(Message message) {
- messageBuffer.setMessage(message);
+ public void setMessage( Message message ) {
+ messageBuffer.setMessage( message );
message = messageBuffer.getMessage();
- setToolTipText(message.getText());
+ setToolTipText( message.getText() );
Severity severity = message.getSeverity();
- if (severity != null) {
-
setIcon(Application.services().getIconSource().getIcon("severity." +
severity.getLabel() + ".overlay"));
+ if( severity != null ) {
+ setIcon( Application.services().getIconSource()
+ .getIcon( "severity." + severity.getLabel() +
".overlay" ) );
+ } else {
+ setIcon( null );
}
- else {
- setIcon(null);
- }
}
}
-}
\ No newline at end of file
+}
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