001    /*
002     * Copyright 2002-2007 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.application.statusbar.support;
017    
018    import java.awt.BorderLayout;
019    import java.awt.Color;
020    import java.awt.Component;
021    import java.awt.Dimension;
022    import java.awt.SystemColor;
023    
024    import javax.swing.BorderFactory;
025    import javax.swing.JComponent;
026    import javax.swing.JLabel;
027    import javax.swing.JPanel;
028    import javax.swing.UIManager;
029    import javax.swing.border.BevelBorder;
030    import javax.swing.border.Border;
031    
032    import org.apache.commons.logging.Log;
033    import org.apache.commons.logging.LogFactory;
034    import org.springframework.richclient.application.statusbar.StatusBar;
035    import org.springframework.richclient.components.ShadowBorder;
036    import org.springframework.richclient.core.Message;
037    import org.springframework.richclient.factory.AbstractControlFactory;
038    import org.springframework.richclient.progress.ProgressMonitor;
039    
040    /**
041     * <p>
042     * A <tt>StatusBar</tt> control is a component with a horizontal layout which hosts a number of status indication
043     * controls. Typically it is situated below the content area of the window.
044     * </p>
045     * <p>
046     * By default a <tt>StatusBar</tt> has two predefined status controls: a <tt>JLabel</tt> and a <tt>JProgressBar</tt>
047     * and it provides API for easy access.
048     * </p>
049     *
050     * @author Peter De Bruycker
051     */
052    public class DefaultStatusBar extends AbstractControlFactory implements StatusBar {
053    
054        private static Log logger = LogFactory.getLog(DefaultStatusBar.class);
055    
056        private String message;
057    
058        private String errorMessage;
059    
060        private JLabel messageLabel;
061    
062        private JPanel statusBar;
063    
064        private StatusBarProgressMonitor progressMonitor;
065    
066        /**
067         * Returns the status bar's progress monitor
068         */
069        public ProgressMonitor getProgressMonitor() {
070            return progressMonitor;
071        }
072    
073        /**
074         * Controls whether the ProgressIndication provides UI for canceling a long running operation.
075         *
076         * If the ProgressIndication is currently visible calling this method may have a direct effect on the layout because
077         * it will make a cancel button visible.
078         */
079        public void setCancelEnabled(boolean enabled) {
080            progressMonitor.setCancelEnabled(enabled);
081        }
082    
083        /**
084         * Sets the message text to be displayed on the status bar.
085         * <p>
086         * The icon of the message is ignored
087         *
088         * @param message
089         *            the message to be set, if <code>null</code>, the status line is cleared.
090         */
091        public void setMessage(Message message) {
092            setMessage(message == null ? null : message.getMessage());
093        }
094    
095        /**
096         * Sets the message text to be displayed on the status bar.
097         *
098         * @param message
099         *            the message to be set, if <code>null</code>, the status line is cleared.
100         */
101        public void setMessage(String message) {
102            this.message = message;
103            if (errorMessage == null) {
104                logger.debug("Setting status bar message to \"" + message + "\"");
105                messageLabel.setText(this.message);
106            }
107        }
108    
109        /**
110         * Sets the error message text to be displayed on the status bar.
111         * <p>
112         * Error messages are shown over the standard message, and in a red color.
113         * <p>
114         * The icon of the message is ignored
115         *
116         * @param message
117         *            the error message to be set, if <code>null</code>, the error message is cleared, and the standard
118         *            message is shown again
119         */
120        public void setErrorMessage(Message errorMessage) {
121            setErrorMessage(errorMessage == null ? null : errorMessage.getMessage());
122        }
123    
124        /**
125         * Sets the error message text to be displayed on the status bar.
126         * <p>
127         * Error messages are shown over the standard message, and in a red color.
128         *
129         * @param message
130         *            the error message to be set, if <code>null</code>, the error message is cleared, and the standard
131         *            message is shown again
132         */
133        public void setErrorMessage(String errorMessage) {
134            if (errorMessage == null) {
135                logger.debug("Resetting the status bar message color to normal");
136                messageLabel.setForeground(SystemColor.controlText);
137    
138                this.errorMessage = null;
139                setMessage(message);
140            }
141            else {
142                logger.debug("Setting the status bar messsage color to red");
143                messageLabel.setForeground(Color.RED);
144    
145                logger.debug("Setting status bar error message to \"" + errorMessage + "\"");
146                this.errorMessage = errorMessage;
147                messageLabel.setText(this.errorMessage);
148            }
149        }
150    
151        /**
152         * Create the <code>JLabel</code> used to render the messages.
153         * <p>
154         * Can safely be overridden to customize the label
155         *
156         * @return the <code>JLabel</code>
157         */
158        protected JLabel createMessageLabel() {
159            JLabel messageLabel = new JLabel(" ");
160            messageLabel.setName("message");
161            Border bevelBorder = BorderFactory.createBevelBorder(BevelBorder.LOWERED, UIManager
162                    .getColor("controlHighlight"), UIManager.getColor("controlShadow"));
163            Border emptyBorder = BorderFactory.createEmptyBorder(1, 3, 1, 3);
164            messageLabel.setBorder(BorderFactory.createCompoundBorder(bevelBorder, emptyBorder));
165    
166            return messageLabel;
167        }
168    
169        protected JComponent createControl() {
170            statusBar = new JPanel(new BorderLayout());
171    
172            messageLabel = createMessageLabel();
173    
174            progressMonitor = createStatusBarProgressMonitor();
175    
176            statusBar.add(messageLabel);
177            statusBar.add(progressMonitor.getControl(), BorderLayout.EAST);
178    
179            progressMonitor.getControl().setPreferredSize(new Dimension(200, 17));
180    
181            statusBar.setBorder(new ShadowBorder());
182    
183            return statusBar;
184        }
185    
186        /**
187         * Create the <code>StatusBarProgressMonitor</code>.
188         * <p>
189         * Can safely be overridden to customize the progress monitor and its components
190         *
191         * @return the <code>StatusBarProgressMonitor</code>
192         */
193        protected StatusBarProgressMonitor createStatusBarProgressMonitor() {
194            return new StatusBarProgressMonitor();
195        }
196    
197        /**
198         * Shows or hides this status bar.
199         *
200         * @see Component#setVisible(boolean)
201         */
202        public void setVisible(boolean visible) {
203            statusBar.setVisible(visible);
204        }
205    
206        public void clear() {
207            setErrorMessage((String) null);
208            setMessage((String) null);
209        }
210    }