EMMA Coverage Report (generated Tue Jan 14 02:29:45 CET 2014)
[all classes][org.jdtaus.core.text.util]

COVERAGE SUMMARY FOR SOURCE FILE [SwingMessagePane.java]

nameclass, %method, %block, %line, %
SwingMessagePane.java0%   (0/4)0%   (0/26)0%   (0/609)0%   (0/135)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class HtmlLabel0%   (0/1)0%   (0/2)0%   (0/80)0%   (0/17)
HtmlLabel (int): void 0%   (0/1)0%   (0/20)0%   (0/7)
computePreferredSize (): Dimension 0%   (0/1)0%   (0/60)0%   (0/10)
     
class HtmlLabel$10%   (0/1)0%   (0/2)0%   (0/37)0%   (0/4)
HtmlLabel$1 (HtmlLabel): void 0%   (0/1)0%   (0/6)0%   (0/1)
propertyChange (PropertyChangeEvent): void 0%   (0/1)0%   (0/31)0%   (0/3)
     
class SwingMessagePane0%   (0/1)0%   (0/20)0%   (0/205)0%   (0/53)
SwingMessagePane (Component): void 0%   (0/1)0%   (0/7)0%   (0/2)
SwingMessagePane (Component, int): void 0%   (0/1)0%   (0/7)0%   (0/2)
SwingMessagePane (Component, int, int): void 0%   (0/1)0%   (0/7)0%   (0/2)
SwingMessagePane (Component, int, int, boolean): void 0%   (0/1)0%   (0/39)0%   (0/12)
getColumns (): int 0%   (0/1)0%   (0/11)0%   (0/3)
getDefaultColumns (): Integer 0%   (0/1)0%   (0/6)0%   (0/1)
getDefaultMaximumMessages (): Integer 0%   (0/1)0%   (0/6)0%   (0/1)
getErrorMessage (Locale): String 0%   (0/1)0%   (0/7)0%   (0/1)
getInformationMessage (Locale): String 0%   (0/1)0%   (0/7)0%   (0/1)
getLocale (): Locale 0%   (0/1)0%   (0/6)0%   (0/1)
getLogger (): Logger 0%   (0/1)0%   (0/6)0%   (0/1)
getMaximumMessages (): int 0%   (0/1)0%   (0/11)0%   (0/3)
getNotificationMessage (Locale): String 0%   (0/1)0%   (0/7)0%   (0/1)
getParent (): Component 0%   (0/1)0%   (0/3)0%   (0/1)
getUnknownMessageEventTypeMessage (Locale, Number): String 0%   (0/1)0%   (0/12)0%   (0/1)
getWarningMessage (Locale): String 0%   (0/1)0%   (0/7)0%   (0/1)
isDefaultResizable (): Boolean 0%   (0/1)0%   (0/6)0%   (0/1)
isResizable (): boolean 0%   (0/1)0%   (0/11)0%   (0/3)
onMessage (MessageEvent): void 0%   (0/1)0%   (0/28)0%   (0/11)
setParent (Component): void 0%   (0/1)0%   (0/11)0%   (0/4)
     
class SwingMessagePane$10%   (0/1)0%   (0/2)0%   (0/287)0%   (0/61)
SwingMessagePane$1 (SwingMessagePane, MessageEvent): void 0%   (0/1)0%   (0/9)0%   (0/1)
run (): void 0%   (0/1)0%   (0/278)0%   (0/60)

1/*
2 *  jDTAUS Core Utilities
3 *  Copyright (C) 2005 Christian Schulte
4 *  <cs@schulte.it>
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU Lesser General Public
8 *  License as published by the Free Software Foundation; either
9 *  version 2.1 of the License, or any later version.
10 *
11 *  This library is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *  Lesser General Public License for more details.
15 *
16 *  You should have received a copy of the GNU Lesser General Public
17 *  License along with this library; if not, write to the Free Software
18 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21package org.jdtaus.core.text.util;
22 
23import java.awt.Component;
24import java.awt.Dimension;
25import java.awt.GraphicsEnvironment;
26import java.awt.GridBagConstraints;
27import java.awt.GridBagLayout;
28import java.awt.HeadlessException;
29import java.awt.Insets;
30import java.beans.PropertyChangeEvent;
31import java.beans.PropertyChangeListener;
32import java.lang.reflect.InvocationTargetException;
33import java.util.Locale;
34import javax.swing.JDialog;
35import javax.swing.JLabel;
36import javax.swing.JOptionPane;
37import javax.swing.JPanel;
38import javax.swing.SwingConstants;
39import javax.swing.SwingUtilities;
40import javax.swing.plaf.basic.BasicHTML;
41import javax.swing.text.View;
42import org.jdtaus.core.container.ContainerFactory;
43import org.jdtaus.core.logging.spi.Logger;
44import org.jdtaus.core.text.MessageEvent;
45import org.jdtaus.core.text.MessageListener;
46 
47/**
48 * {@code MessageListener} displaying messages using Swing's {@code JOptionPane}.
49 * <p>This implementation displays a dialog for each {@code MessageEvent} this {@code MessageListener} is notified
50 * about. Since a {@code MessageEvent} can hold multiple messages a maximum number of messages to display per event
51 * can be specified by property {@code maximumMessages} (defaults to 25).</p>
52 *
53 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
54 * @version $JDTAUS: SwingMessagePane.java 8786 2012-12-03 02:09:05Z schulte $
55 *
56 * @see #onMessage(MessageEvent)
57 */
58public final class SwingMessagePane implements MessageListener
59{
60    //--Dependencies------------------------------------------------------------
61 
62// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausDependencies
63    // This section is managed by jdtaus-container-mojo.
64 
65    /**
66     * Gets the configured <code>Logger</code> implementation.
67     *
68     * @return The configured <code>Logger</code> implementation.
69     */
70    private Logger getLogger()
71    {
72        return (Logger) ContainerFactory.getContainer().
73            getDependency( this, "Logger" );
74 
75    }
76 
77    /**
78     * Gets the configured <code>Locale</code> implementation.
79     *
80     * @return The configured <code>Locale</code> implementation.
81     */
82    private Locale getLocale()
83    {
84        return (Locale) ContainerFactory.getContainer().
85            getDependency( this, "Locale" );
86 
87    }
88 
89// </editor-fold>//GEN-END:jdtausDependencies
90 
91    //------------------------------------------------------------Dependencies--
92    //--Properties--------------------------------------------------------------
93 
94// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
95    // This section is managed by jdtaus-container-mojo.
96 
97    /**
98     * Gets the value of property <code>defaultResizable</code>.
99     *
100     * @return Default resizability of the message pane.
101     */
102    private java.lang.Boolean isDefaultResizable()
103    {
104        return (java.lang.Boolean) ContainerFactory.getContainer().
105            getProperty( this, "defaultResizable" );
106 
107    }
108 
109    /**
110     * Gets the value of property <code>defaultMaximumMessages</code>.
111     *
112     * @return Default maximum number of messages displayed per event.
113     */
114    private java.lang.Integer getDefaultMaximumMessages()
115    {
116        return (java.lang.Integer) ContainerFactory.getContainer().
117            getProperty( this, "defaultMaximumMessages" );
118 
119    }
120 
121    /**
122     * Gets the value of property <code>defaultColumns</code>.
123     *
124     * @return Default number of columns the preferred width of the message pane is computed with.
125     */
126    private java.lang.Integer getDefaultColumns()
127    {
128        return (java.lang.Integer) ContainerFactory.getContainer().
129            getProperty( this, "defaultColumns" );
130 
131    }
132 
133// </editor-fold>//GEN-END:jdtausProperties
134 
135    //--------------------------------------------------------------Properties--
136    //--MessageListener---------------------------------------------------------
137 
138    /**
139     * {@inheritDoc}
140     * <p>This method uses Swing's {@link JOptionPane} to display messages given by the event. It will block the event
141     * dispatch thread until the user confirms the message pane.</p>
142     *
143     * @param event The event holding messages.
144     */
145    public void onMessage( final MessageEvent event )
146    {
147        if ( event != null )
148        {
149            try
150            {
151                final Runnable r = new Runnable()
152                {
153 
154                    public void run()
155                    {
156                        final JPanel panel = new JPanel();
157                        panel.setLayout( new GridBagLayout() );
158 
159                        for ( int i = 0, s0 = event.getMessages().length; i < s0 && i < getMaximumMessages(); i++ )
160                        {
161                            String text = event.getMessages()[i].getText( getLocale() );
162 
163                            if ( !BasicHTML.isHTMLString( text ) )
164                            {
165                                text = "<html>" + HtmlEntities.escapeHtml( text ) + "</html>";
166                            }
167 
168                            final JLabel label = new HtmlLabel( getColumns() );
169                            label.setText( text );
170 
171                            final GridBagConstraints c = new GridBagConstraints();
172                            c.anchor = GridBagConstraints.NORTHWEST;
173                            c.fill = GridBagConstraints.BOTH;
174                            c.gridheight = 1;
175                            c.gridwidth = 1;
176                            c.gridx = 0;
177                            c.gridy = i;
178                            c.weightx = 1.0D;
179 
180                            panel.add( label, c );
181 
182                            if ( !( i + 1 < s0 && i + 1 < getMaximumMessages() ) )
183                            {
184                                final JPanel p = new JPanel();
185                                c.anchor = GridBagConstraints.SOUTH;
186                                c.weighty = 1.0D;
187                                c.gridy = i + 1;
188                                panel.add( p, c );
189                            }
190                        }
191 
192                        JOptionPane optionPane = null;
193                        JDialog dialog = null;
194 
195                        switch ( event.getType() )
196                        {
197                            case MessageEvent.INFORMATION:
198                                optionPane = new JOptionPane();
199                                optionPane.setMessage( panel );
200                                optionPane.setMessageType( JOptionPane.INFORMATION_MESSAGE );
201                                dialog = optionPane.createDialog( getParent(), getInformationMessage( getLocale() ) );
202                                dialog.setResizable( isResizable() );
203                                dialog.setVisible( true );
204                                dialog.dispose();
205                                break;
206 
207                            case MessageEvent.NOTIFICATION:
208                                optionPane = new JOptionPane();
209                                optionPane.setMessage( panel );
210                                optionPane.setMessageType( JOptionPane.INFORMATION_MESSAGE );
211                                dialog = optionPane.createDialog( getParent(), getNotificationMessage( getLocale() ) );
212                                dialog.setResizable( isResizable() );
213                                dialog.setVisible( true );
214                                dialog.dispose();
215                                break;
216 
217                            case MessageEvent.WARNING:
218                                optionPane = new JOptionPane();
219                                optionPane.setMessage( panel );
220                                optionPane.setMessageType( JOptionPane.WARNING_MESSAGE );
221                                dialog = optionPane.createDialog( getParent(), getWarningMessage( getLocale() ) );
222                                dialog.setResizable( isResizable() );
223                                dialog.setVisible( true );
224                                dialog.dispose();
225                                break;
226 
227                            case MessageEvent.ERROR:
228                                optionPane = new JOptionPane();
229                                optionPane.setMessage( panel );
230                                optionPane.setMessageType( JOptionPane.ERROR_MESSAGE );
231                                dialog = optionPane.createDialog( getParent(), getErrorMessage( getLocale() ) );
232                                dialog.setResizable( isResizable() );
233                                dialog.setVisible( true );
234                                dialog.dispose();
235                                break;
236 
237                            default:
238                                getLogger().warn( getUnknownMessageEventTypeMessage(
239                                    getLocale(), new Integer( event.getType() ) ) );
240 
241                        }
242                    }
243 
244                };
245 
246                if ( SwingUtilities.isEventDispatchThread() )
247                {
248                    r.run();
249                }
250                else
251                {
252                    SwingUtilities.invokeAndWait( r );
253                }
254            }
255            catch ( final InterruptedException e )
256            {
257                this.getLogger().error( e );
258            }
259            catch ( final InvocationTargetException e )
260            {
261                this.getLogger().error( e );
262            }
263        }
264    }
265 
266    //---------------------------------------------------------MessageListener--
267    //--SwingMessagePane--------------------------------------------------------
268 
269    /** The current parent component to use when displaying messages. */
270    private Component parent;
271 
272    /** Maximum number of messages displayed per event. */
273    private Integer maximumMessages;
274 
275    /** Number of columns the preferred width of the message pane is computed with. */
276    private Integer columns;
277 
278    /** Flag indicating the message pane is resizable. */
279    private Boolean resizable;
280 
281    /**
282     * Creates a new {@code SwingMessagePane} instance taking the parent component to use when displaying messages.
283     *
284     * @param parent The parent component to use when displaying messages.
285     *
286     * @throws NullPointerException if {@code parent} is {@code null}.
287     * @throws HeadlessException if this class is used in an environment not providing a keyboard, display, or mouse.
288     */
289    public SwingMessagePane( final Component parent )
290    {
291        this( parent, Integer.MIN_VALUE, Integer.MIN_VALUE, false );
292    }
293 
294    /**
295     * Creates a new {@code SwingMessagePane} instance taking the parent component to use when displaying messages and
296     * the maximum number of messages displayed per event.
297     *
298     * @param parent The parent component to use when displaying messages.
299     * @param maximumMessages Maximum number of messages displayed per event.
300     *
301     * @throws NullPointerException if {@code parent} is {@code null}.
302     * @throws HeadlessException if this class is used in an environment not providing a keyboard, display, or mouse.
303     */
304    public SwingMessagePane( final Component parent, final int maximumMessages )
305    {
306        this( parent, maximumMessages, Integer.MIN_VALUE, false );
307    }
308 
309    /**
310     * Creates a new {@code SwingMessagePane} instance taking the parent component to use when displaying messages, the
311     * maximum number of messages displayed per event and a number of columns to compute the preferred width of the
312     * message pane with.
313     *
314     * @param parent The parent component to use when displaying messages.
315     * @param maximumMessages Maximum number of messages displayed per event.
316     * @param columns Number of columns the preferred width of the message pane should be computed with.
317     *
318     * @throws NullPointerException if {@code parent} is {@code null}.
319     * @throws HeadlessException if this class is used in an environment not providing a keyboard, display, or mouse.
320     *
321     * @since 1.10
322     */
323    public SwingMessagePane( final Component parent, final int maximumMessages, final int columns )
324    {
325        this( parent, maximumMessages, columns, false );
326    }
327 
328    /**
329     * Creates a new {@code SwingMessagePane} instance taking the parent component to use when displaying messages, the
330     * maximum number of messages displayed per event, a number of columns to compute the preferred width of the
331     * message pane with and a flag indicating the message pane is resizable.
332     *
333     * @param parent The parent component to use when displaying messages.
334     * @param maximumMessages Maximum number of messages displayed per event.
335     * @param columns Number of columns the preferred width of the message pane should be computed with.
336     * @param resizable {@code true}, if the message pane should be resizable; {@code false} if the message pane should
337     * have a fixed size.
338     *
339     * @throws NullPointerException if {@code parent} is {@code null}.
340     * @throws HeadlessException if this class is used in an environment not providing a keyboard, display, or mouse.
341     *
342     * @since 1.11
343     */
344    public SwingMessagePane( final Component parent, final int maximumMessages, final int columns,
345                             final boolean resizable )
346    {
347        if ( parent == null )
348        {
349            throw new NullPointerException( "parent" );
350        }
351 
352        if ( GraphicsEnvironment.isHeadless() )
353        {
354            throw new HeadlessException();
355        }
356 
357        this.parent = parent;
358 
359        if ( maximumMessages > 0 )
360        {
361            this.maximumMessages = new Integer( maximumMessages );
362        }
363        if ( columns > 0 )
364        {
365            this.columns = new Integer( columns );
366        }
367 
368        this.resizable = Boolean.valueOf( resizable );
369    }
370 
371    /**
372     * Gets the parent component for any message displays.
373     *
374     * @return the parent component for any message displays.
375     */
376    public Component getParent()
377    {
378        return this.parent;
379    }
380 
381    /**
382     * Sets the parent component used by any message displays.
383     *
384     * @param parent the parent component used by any message displays.
385     *
386     * @throws NullPointerException if {@code parent} is {@code null}.
387     */
388    public void setParent( final Component parent )
389    {
390        if ( parent == null )
391        {
392            throw new NullPointerException( "parent" );
393        }
394 
395        this.parent = parent;
396    }
397 
398    /**
399     * Gets the maximum number of messages displayed per event.
400     *
401     * @return the maximum number of messages displayed per event.
402     */
403    public int getMaximumMessages()
404    {
405        if ( this.maximumMessages == null )
406        {
407            this.maximumMessages = this.getDefaultMaximumMessages();
408        }
409 
410        return this.maximumMessages.intValue();
411    }
412 
413    /**
414     * Gets the number of columns the preferred width of the message pane is computed with.
415     *
416     * @return The number of columns the preferred width of the message pane is computed with.
417     *
418     * @since 1.10
419     */
420    public int getColumns()
421    {
422        if ( this.columns == null )
423        {
424            this.columns = this.getDefaultColumns();
425        }
426 
427        return this.columns.intValue();
428    }
429 
430    /**
431     * Gets a flag indicating the message pane is resizable.
432     *
433     * @return {@code true}, if the message pane is resizable; {@code false} if the message pane is not resizable.
434     *
435     * @since 1.11
436     */
437    public boolean isResizable()
438    {
439        if ( this.resizable == null )
440        {
441            this.resizable = this.isDefaultResizable();
442        }
443 
444        return this.resizable.booleanValue();
445    }
446 
447    //--------------------------------------------------------SwingMessagePane--
448    //--Messages----------------------------------------------------------------
449 
450// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausMessages
451    // This section is managed by jdtaus-container-mojo.
452 
453    /**
454     * Gets the text of message <code>unknownMessageEventType</code>.
455     * <blockquote><pre>Meldung unbekannten Typs {0,number} ignoriert.</pre></blockquote>
456     * <blockquote><pre>Ignored message event of unknown type {0,number}.</pre></blockquote>
457     *
458     * @param locale The locale of the message instance to return.
459     * @param unknownEventType The unknown event type.
460     *
461     * @return Message stating that an unknown message event got ignored.
462     */
463    private String getUnknownMessageEventTypeMessage( final Locale locale,
464            final java.lang.Number unknownEventType )
465    {
466        return ContainerFactory.getContainer().
467            getMessage( this, "unknownMessageEventType", locale,
468                new Object[]
469                {
470                    unknownEventType
471                });
472 
473    }
474 
475    /**
476     * Gets the text of message <code>information</code>.
477     * <blockquote><pre>Information</pre></blockquote>
478     * <blockquote><pre>Information</pre></blockquote>
479     *
480     * @param locale The locale of the message instance to return.
481     *
482     * @return Information title.
483     */
484    private String getInformationMessage( final Locale locale )
485    {
486        return ContainerFactory.getContainer().
487            getMessage( this, "information", locale, null );
488 
489    }
490 
491    /**
492     * Gets the text of message <code>notification</code>.
493     * <blockquote><pre>Hinweis</pre></blockquote>
494     * <blockquote><pre>Notification</pre></blockquote>
495     *
496     * @param locale The locale of the message instance to return.
497     *
498     * @return Notification title.
499     */
500    private String getNotificationMessage( final Locale locale )
501    {
502        return ContainerFactory.getContainer().
503            getMessage( this, "notification", locale, null );
504 
505    }
506 
507    /**
508     * Gets the text of message <code>warning</code>.
509     * <blockquote><pre>Warnung</pre></blockquote>
510     * <blockquote><pre>Warning</pre></blockquote>
511     *
512     * @param locale The locale of the message instance to return.
513     *
514     * @return Warning title.
515     */
516    private String getWarningMessage( final Locale locale )
517    {
518        return ContainerFactory.getContainer().
519            getMessage( this, "warning", locale, null );
520 
521    }
522 
523    /**
524     * Gets the text of message <code>error</code>.
525     * <blockquote><pre>Fehler</pre></blockquote>
526     * <blockquote><pre>Error</pre></blockquote>
527     *
528     * @param locale The locale of the message instance to return.
529     *
530     * @return Error title.
531     */
532    private String getErrorMessage( final Locale locale )
533    {
534        return ContainerFactory.getContainer().
535            getMessage( this, "error", locale, null );
536 
537    }
538 
539// </editor-fold>//GEN-END:jdtausMessages
540 
541    //----------------------------------------------------------------Messages--
542}
543 
544/**
545 * Extension to {@code JLabel} adding support for a preferred width based on a number of columns.
546 *
547 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
548 * @version $JDTAUS: SwingMessagePane.java 8786 2012-12-03 02:09:05Z schulte $
549 */
550class HtmlLabel extends JLabel
551{
552 
553    /** Serial version UID for backwards compatibility with 1.10.x classes. */
554    private static final long serialVersionUID = -3022796716512336911L;
555 
556    /** The number of columns the preferred width of the label is computed with. */
557    private int columns;
558 
559    /**
560     * Creates a new {@code HtmlLabel} instance taking a number of columns to compute the preferred width of the label
561     * with.
562     *
563     * @param columns The number of columns to compute the preferred width of the label with.
564     */
565    HtmlLabel( final int columns )
566    {
567        super();
568        this.columns = columns;
569        this.setVerticalAlignment( SwingConstants.TOP );
570        this.setVerticalTextPosition( SwingConstants.TOP );
571 
572        if ( columns > 0 )
573        {
574            this.addPropertyChangeListener( new PropertyChangeListener()
575            {
576 
577                public void propertyChange( final PropertyChangeEvent evt )
578                {
579                    if ( ( "text".equals( evt.getPropertyName() )
580                           || "font".equals( evt.getPropertyName() )
581                           || "border".equals( evt.getPropertyName() ) )
582                         && getText() != null
583                         && BasicHTML.isHTMLString( getText() ) )
584                    {
585                        setPreferredSize( computePreferredSize() );
586                    }
587                }
588 
589            } );
590        }
591    }
592 
593    private Dimension computePreferredSize()
594    {
595        Dimension preferredSize = null;
596        final Insets insets = this.getInsets();
597        final int width = this.columns * this.getFontMetrics( this.getFont() ).charWidth( 'W' )
598                          + ( insets != null ? insets.left + insets.right : 0 );
599 
600        final JLabel label = new JLabel( this.getText() );
601        final Object html = label.getClientProperty( BasicHTML.propertyKey );
602 
603        if ( html instanceof View )
604        {
605            final View view = (View) html;
606            view.setSize( width, 0 );
607            preferredSize = new Dimension( (int) view.getPreferredSpan( View.X_AXIS ),
608                                           (int) view.getPreferredSpan( View.Y_AXIS ) );
609 
610        }
611 
612        return preferredSize;
613    }
614 
615}

[all classes][org.jdtaus.core.text.util]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov