001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.dialog;
017    
018    import java.awt.Image;
019    import java.awt.Window;
020    import java.beans.PropertyChangeEvent;
021    import java.beans.PropertyChangeListener;
022    
023    import javax.swing.Icon;
024    import javax.swing.JComponent;
025    import javax.swing.SwingUtilities;
026    
027    import org.springframework.richclient.core.Guarded;
028    import org.springframework.richclient.core.LabeledObjectSupport;
029    import org.springframework.richclient.core.Message;
030    import org.springframework.richclient.factory.AbstractControlFactory;
031    import org.springframework.richclient.factory.ControlFactory;
032    import org.springframework.richclient.image.config.IconConfigurable;
033    import org.springframework.util.Assert;
034    
035    /**
036     * A convenience implementation of the DialogPage interface. Recommended to be
037     * used as a base class for all GUI dialog pages (or panes.)
038     * 
039     * @author Keith Donald
040     * @see DialogPage
041     */
042    public abstract class AbstractDialogPage extends LabeledObjectSupport implements DialogPage, ControlFactory, Guarded,
043                    IconConfigurable {
044    
045            private final MessageChangeHandler messageChangeHandler = new MessageChangeHandler();
046    
047            private String pageId;
048    
049            private Icon icon;
050    
051            private boolean pageComplete = true;
052    
053            private DefaultMessageAreaModel messageBuffer;
054    
055            private boolean visible = true;
056    
057            private AbstractControlFactory factory = new AbstractControlFactory() {
058                    public JComponent createControl() {
059                            return AbstractDialogPage.this.createControl();
060                    }
061            };
062    
063            /**
064             * Creates a new dialog page. This titles of this dialog page will be
065             * configured using the default ObjectConfigurer.
066             * 
067             * @param pageId the id of this dialog page. This will be used to configure
068             * the page.
069             */
070            protected AbstractDialogPage(String pageId) {
071                    this(pageId, true);
072            }
073    
074            /**
075             * Creates a new dialog page.
076             * 
077             * @param pageId the id of this dialog page
078             * @param autoConfigure whether or not to use an ObjectConfigurer to
079             * configure the titles of this dialog page using the given pageId
080             */
081            protected AbstractDialogPage(String pageId, boolean autoConfigure) {
082                    this.messageBuffer = new DefaultMessageAreaModel(this);
083                    this.messageBuffer.addPropertyChangeListener(messageChangeHandler);
084                    setId(pageId, autoConfigure);
085            }
086    
087            /**
088             * Creates a new dialog page with the given title.
089             * 
090             * @param pageId the id of this dialog page
091             * @param autoConfigure whether or not to use an ObjectConfigurer to
092             * configure the titles of this dialog page using the given pageId
093             * @param title the title of this dialog page, or <code>null</code> if
094             * none
095             */
096            protected AbstractDialogPage(String pageId, boolean autoConfigure, String title) {
097                    this(pageId, autoConfigure);
098                    if (title != null) {
099                            setTitle(title);
100                    }
101            }
102    
103            /**
104             * Creates a new dialog page with the given title and image.
105             * 
106             * @param pageId the id of this dialog page
107             * @param autoConfigure whether or not to use an ObjectConfigurer to
108             * configure the titles of this dialog page using the given pageId
109             * @param title the title of this dialog page, or <code>null</code> if
110             * none
111             * @param icon the image for this dialog page, or <code>null</code> if
112             * none
113             */
114            protected AbstractDialogPage(String pageId, boolean autoConfigure, String title, Image icon) {
115                    this(pageId, autoConfigure, title);
116                    if (icon != null) {
117                            setImage(icon);
118                    }
119            }
120    
121            public String getId() {
122                    return pageId;
123            }
124    
125            protected void setId(String pageId, boolean autoConfigure) {
126                    Assert.hasText(pageId, "pageId is required");
127                    String oldValue = this.pageId;
128                    this.pageId = pageId;
129                    firePropertyChange("id", oldValue, pageId);
130                    if (autoConfigure) {
131                            if (logger.isDebugEnabled()) {
132                                    logger.debug("Auto configuring dialog page with id " + pageId);
133                            }
134                            getObjectConfigurer().configure(this, pageId);
135                    }
136            }
137    
138            public String getTitle() {
139                    return getDisplayName();
140            }
141    
142            public Message getMessage() {
143                    return messageBuffer.getMessage();
144            }
145    
146            /**
147             * Sets or clears the message for this page.
148             * 
149             * @param newMessage the message, or <code>null</code> to clear the
150             * message
151             */
152            public void setMessage(Message newMessage) {
153                    messageBuffer.setMessage(newMessage);
154            }
155    
156            public boolean hasErrorMessage() {
157                    return messageBuffer.hasErrorMessage();
158            }
159    
160            public boolean hasWarningMessage() {
161                    return messageBuffer.hasWarningMessage();
162            }
163    
164            public boolean hasInfoMessage() {
165                    return messageBuffer.hasInfoMessage();
166            }
167    
168            public void setVisible(boolean visible) {
169                    boolean oldValue = this.visible;
170                    getControl().setVisible(visible);
171                    this.visible = visible;
172                    firePropertyChange("visible", oldValue, visible);
173            }
174    
175            public boolean isVisible() {
176                    return visible;
177            }
178    
179            public boolean isPageComplete() {
180                    return pageComplete;
181            }
182    
183            public void setPageComplete(boolean pageComplete) {
184                    boolean oldValue = this.pageComplete;
185                    this.pageComplete = pageComplete;
186                    firePropertyChange("pageComplete", oldValue, pageComplete);
187            }
188    
189            public boolean isEnabled() {
190                    return isPageComplete();
191            }
192    
193            public void setEnabled(boolean enabled) {
194                    setPageComplete(enabled);
195            }
196    
197            public JComponent getControl() {
198                    return factory.getControl();
199            }
200    
201            public boolean isControlCreated() {
202                    return factory.isControlCreated();
203            }
204    
205            public Window getParentWindowControl() {
206                    return SwingUtilities.getWindowAncestor(getControl());
207            }
208    
209            /**
210             * This default implementation of an <code>AbstractDialogPage</code>
211             * method does nothing. Subclasses should override to take some action in
212             * response to a help request.
213             */
214            public void performHelp() {
215                    // do nothing by default
216            }
217    
218            protected abstract JComponent createControl();
219    
220            private class MessageChangeHandler implements PropertyChangeListener {
221                    public void propertyChange(PropertyChangeEvent evt) {
222                            firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
223                    }
224            }
225    
226            public void setIcon(Icon icon) {
227                    this.icon = icon;
228            }
229    
230            public Icon getIcon() {
231                    return icon;
232            }
233    }