001    /*
002     * Copyright 2002-2006 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.BorderLayout;
019    import java.awt.Font;
020    import java.beans.PropertyChangeEvent;
021    import java.beans.PropertyChangeListener;
022    import java.io.IOException;
023    import java.io.StringReader;
024    
025    import javax.swing.Icon;
026    import javax.swing.JComponent;
027    import javax.swing.JLabel;
028    import javax.swing.JPanel;
029    import javax.swing.UIManager;
030    import javax.swing.text.html.HTMLDocument;
031    
032    import org.springframework.richclient.core.Message;
033    import org.springframework.richclient.core.Severity;
034    import org.springframework.richclient.core.UIConstants;
035    import org.springframework.richclient.factory.AbstractControlFactory;
036    import org.springframework.richclient.text.HtmlPane;
037    import org.springframework.richclient.util.GuiStandardUtils;
038    import org.springframework.util.StringUtils;
039    
040    /**
041     * MessagePane implementation used by {@link MessageDialog}.
042     * 
043     * @author Peter De Bruycker
044     */
045    public class AlertMessageAreaPane extends AbstractControlFactory implements MessagePane, PropertyChangeListener {
046            
047        private Icon warningIcon;
048        private Icon errorIcon;
049        private Icon infoIcon;
050        private HtmlPane messageArea;
051        private JLabel iconLabel;
052        private DefaultMessageAreaModel messageAreaModel;
053    
054        /**
055         * Creates a new uninitialized {@code AlertMessageAreaPane}.
056         */
057        public AlertMessageAreaPane() {
058            init( this );
059        }
060    
061        /**
062         * Creates a new {@code AlertMessageAreaPane} that uses the given delegate
063         * as a message container.
064         * @param delegate The messagable delegate.
065         */
066        public AlertMessageAreaPane( Messagable delegate ) {
067            init( delegate );
068        }
069    
070        private void init( Messagable delegate ) {
071            this.messageAreaModel = new DefaultMessageAreaModel( delegate );
072            this.messageAreaModel.addPropertyChangeListener( this );
073    
074            iconLabel = new JLabel();
075            messageArea = new HtmlPane();
076    
077            Font defaultFont = UIManager.getFont( "Button.font" );
078            String stylesheet = "body {  font-family: " + defaultFont.getName() + "; font-size: " + defaultFont.getSize()
079                    + "pt;  }" + "a, p, li { font-family: " + defaultFont.getName() + "; font-size: "
080                    + defaultFont.getSize() + "pt;  }";
081            try {
082                ((HTMLDocument) messageArea.getDocument()).getStyleSheet().loadRules( new StringReader( stylesheet ), null );
083            } catch( IOException e ) {
084            }
085    
086            GuiStandardUtils.textComponentAsLabel( messageArea );
087            messageArea.setFont( new JLabel().getFont() );
088            messageArea.setFocusable(false);
089        }
090    
091        public int getPreferredHeight() {
092            return messageArea.getPreferredSize().height;
093        }
094    
095        protected JComponent createControl() {
096            JPanel panel = new JPanel( new BorderLayout( UIConstants.TWO_SPACES, 0 ) );
097            panel.add( iconLabel, BorderLayout.LINE_START );
098            panel.add( messageArea );
099    
100            return panel;
101        }
102    
103        public Message getMessage() {
104            return messageAreaModel.getMessage();
105        }
106    
107        public void setMessage( Message message ) {
108            messageAreaModel.setMessage( message );
109        }
110    
111        public boolean isMessageShowing() {
112            if( messageArea == null ) {
113                return false;
114            }
115            return StringUtils.hasText( messageArea.getText() ) && messageArea.isVisible();
116        }
117    
118        public void addPropertyChangeListener( PropertyChangeListener listener ) {
119            messageAreaModel.addPropertyChangeListener( listener );
120        }
121    
122        public void addPropertyChangeListener( String propertyName, PropertyChangeListener listener ) {
123            messageAreaModel.addPropertyChangeListener( propertyName, listener );
124        }
125    
126        public void removePropertyChangeListener( PropertyChangeListener listener ) {
127            messageAreaModel.removePropertyChangeListener( listener );
128        }
129    
130        public void removePropertyChangeListener( String propertyName, PropertyChangeListener listener ) {
131            messageAreaModel.removePropertyChangeListener( propertyName, listener );
132        }
133    
134        public void propertyChange( PropertyChangeEvent evt ) {
135            update( getMessage() );
136        }
137    
138        private void update( Message message ) {
139            String text = message.getMessage();
140    
141            // try to split it into two parts
142            String[] parts = message.getMessage().split( "\\n" );
143            if( parts.length > 1 ) {
144                StringBuffer sb = new StringBuffer();
145                sb.append( "<html>" );
146                sb.append( "<b>" );
147                sb.append( parts[0] );
148                sb.append( "</b>" );
149    
150                for( int i = 1; i < parts.length; i++ ) {
151                    sb.append( "<p>" );
152                    sb.append( parts[i] );
153                }
154    
155                text = sb.toString();
156            }
157    
158            messageArea.setText( text );
159            iconLabel.setIcon( getIcon( message.getSeverity() ) );
160        }
161    
162        /**
163         * Returns the icon for the given severity.
164         * @param severity The severity level.
165         * @return The icon for the given severity, never null.
166         */
167        private Icon getIcon( Severity severity ) {
168            if( severity == Severity.ERROR ) {
169                return getErrorIcon();
170            }
171            if( severity == Severity.WARNING ) {
172                return getWarningIcon();
173            }
174            return getInfoIcon();
175        }
176    
177        private Icon getErrorIcon() {
178            if( errorIcon == null ) {
179                errorIcon = UIManager.getIcon( "OptionPane.errorIcon" );
180            }
181            return errorIcon;
182        }
183    
184        /**
185         * Sets the icon to be shown when displaying messages with error-level severity.
186         * @param icon The error icon.
187         */
188        public void setErrorIcon( Icon icon ) {
189            errorIcon = icon;
190        }
191    
192        private Icon getWarningIcon() {
193            if( warningIcon == null ) {
194                warningIcon = UIManager.getIcon( "OptionPane.warningIcon" );
195            }
196            return warningIcon;
197        }
198    
199        /**
200         * Sets the icon to be shown when displaying messages with warning-level severity.
201         * @param icon The warning icon.
202         */
203        public void setWarningIcon( Icon icon ) {
204            warningIcon = icon;
205        }
206    
207        private Icon getInfoIcon() {
208            if( infoIcon == null ) {
209                infoIcon = UIManager.getIcon( "OptionPane.informationIcon" );
210            }
211            return infoIcon;
212        }
213    
214        /**
215         * The icon to be shown when dispalying messages with info-level severity.
216         * @param icon The info icon.
217         */
218        public void setInfoIcon( Icon icon ) {
219            infoIcon = icon;
220        }
221        
222    }
223