1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jdtaus.core.text.util;
22
23 import java.awt.Component;
24 import java.awt.Dimension;
25 import java.awt.FontMetrics;
26 import java.awt.GraphicsEnvironment;
27 import java.awt.GridBagConstraints;
28 import java.awt.GridBagLayout;
29 import java.awt.HeadlessException;
30 import java.awt.Insets;
31 import java.lang.reflect.InvocationTargetException;
32 import java.util.Locale;
33 import javax.swing.JDialog;
34 import javax.swing.JLabel;
35 import javax.swing.JOptionPane;
36 import javax.swing.JPanel;
37 import javax.swing.SwingConstants;
38 import javax.swing.SwingUtilities;
39 import javax.swing.UIManager;
40 import javax.swing.plaf.basic.BasicHTML;
41 import org.jdtaus.core.container.ContainerFactory;
42 import org.jdtaus.core.logging.spi.Logger;
43 import org.jdtaus.core.text.MessageEvent;
44 import org.jdtaus.core.text.MessageListener;
45
46
47
48
49
50
51
52
53
54
55
56
57 public final class SwingMessagePane implements MessageListener
58 {
59
60
61
62
63
64
65
66
67
68
69 private Logger getLogger()
70 {
71 return (Logger) ContainerFactory.getContainer().
72 getDependency( this, "Logger" );
73
74 }
75
76
77
78
79
80
81 private Locale getLocale()
82 {
83 return (Locale) ContainerFactory.getContainer().
84 getDependency( this, "Locale" );
85
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 private java.lang.Boolean isDefaultResizable()
102 {
103 return (java.lang.Boolean) ContainerFactory.getContainer().
104 getProperty( this, "defaultResizable" );
105
106 }
107
108
109
110
111
112
113 private java.lang.Integer getDefaultMaximumMessages()
114 {
115 return (java.lang.Integer) ContainerFactory.getContainer().
116 getProperty( this, "defaultMaximumMessages" );
117
118 }
119
120
121
122
123
124
125 private java.lang.Integer getDefaultColumns()
126 {
127 return (java.lang.Integer) ContainerFactory.getContainer().
128 getProperty( this, "defaultColumns" );
129
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144 public void onMessage( final MessageEvent event )
145 {
146 if ( event != null )
147 {
148 try
149 {
150 final Runnable r = new Runnable()
151 {
152
153 public void run()
154 {
155 final JPanel panel = new JPanel();
156 panel.setLayout( new GridBagLayout() );
157
158 for ( int i = 0, s0 = event.getMessages().length; i < s0 && i < getMaximumMessages(); i++ )
159 {
160 String text = event.getMessages()[i].getText( getLocale() );
161
162 if ( !BasicHTML.isHTMLString( text ) )
163 {
164 text = "<html>" + HtmlEntities.escapeHtml( text ) + "</html>";
165 }
166
167 final JLabel label = new HtmlLabel( getColumns() );
168 label.setText( text );
169
170 final GridBagConstraints c = new GridBagConstraints();
171 c.anchor = GridBagConstraints.NORTHWEST;
172 c.fill = GridBagConstraints.BOTH;
173 c.gridheight = 1;
174 c.gridwidth = 1;
175 c.gridx = 0;
176 c.gridy = i;
177 c.weightx = 1.0D;
178
179 panel.add( label, c );
180
181 if ( !( i + 1 < s0 && i + 1 < getMaximumMessages() ) )
182 {
183 final JPanel p = new JPanel();
184 c.anchor = GridBagConstraints.SOUTH;
185 c.weighty = 1.0D;
186 c.gridy = i + 1;
187 panel.add( p, c );
188 }
189 }
190
191 JOptionPane optionPane = null;
192 JDialog dialog = null;
193
194 switch ( event.getType() )
195 {
196 case MessageEvent.INFORMATION:
197 optionPane = new JOptionPane();
198 optionPane.setMessage( panel );
199 optionPane.setMessageType( JOptionPane.INFORMATION_MESSAGE );
200 dialog = optionPane.createDialog( getParent(), getInformationMessage( getLocale() ) );
201 dialog.setResizable( isResizable() );
202 dialog.setVisible( true );
203 dialog.dispose();
204 break;
205
206 case MessageEvent.NOTIFICATION:
207 optionPane = new JOptionPane();
208 optionPane.setMessage( panel );
209 optionPane.setMessageType( JOptionPane.INFORMATION_MESSAGE );
210 dialog = optionPane.createDialog( getParent(), getNotificationMessage( getLocale() ) );
211 dialog.setResizable( isResizable() );
212 dialog.setVisible( true );
213 dialog.dispose();
214 break;
215
216 case MessageEvent.WARNING:
217 optionPane = new JOptionPane();
218 optionPane.setMessage( panel );
219 optionPane.setMessageType( JOptionPane.WARNING_MESSAGE );
220 dialog = optionPane.createDialog( getParent(), getWarningMessage( getLocale() ) );
221 dialog.setResizable( isResizable() );
222 dialog.setVisible( true );
223 dialog.dispose();
224 break;
225
226 case MessageEvent.ERROR:
227 optionPane = new JOptionPane();
228 optionPane.setMessage( panel );
229 optionPane.setMessageType( JOptionPane.ERROR_MESSAGE );
230 dialog = optionPane.createDialog( getParent(), getErrorMessage( getLocale() ) );
231 dialog.setResizable( isResizable() );
232 dialog.setVisible( true );
233 dialog.dispose();
234 break;
235
236 default:
237 getLogger().warn( getUnknownMessageEventTypeMessage(
238 getLocale(), new Integer( event.getType() ) ) );
239
240 }
241 }
242
243 };
244
245 if ( SwingUtilities.isEventDispatchThread() )
246 {
247 r.run();
248 }
249 else
250 {
251 SwingUtilities.invokeAndWait( r );
252 }
253 }
254 catch ( final InterruptedException e )
255 {
256 this.getLogger().error( e );
257 }
258 catch ( final InvocationTargetException e )
259 {
260 this.getLogger().error( e );
261 }
262 }
263 }
264
265
266
267
268
269 private Component parent;
270
271
272 private Integer maximumMessages;
273
274
275 private Integer columns;
276
277
278 private Boolean resizable;
279
280
281
282
283
284
285
286
287
288 public SwingMessagePane( final Component parent )
289 {
290 this( parent, Integer.MIN_VALUE, Integer.MIN_VALUE, false );
291 }
292
293
294
295
296
297
298
299
300
301
302
303 public SwingMessagePane( final Component parent, final int maximumMessages )
304 {
305 this( parent, maximumMessages, Integer.MIN_VALUE, false );
306 }
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 public SwingMessagePane( final Component parent, final int maximumMessages, final int columns )
323 {
324 this( parent, maximumMessages, columns, false );
325 }
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343 public SwingMessagePane( final Component parent, final int maximumMessages, final int columns,
344 final boolean resizable )
345 {
346 if ( parent == null )
347 {
348 throw new NullPointerException( "parent" );
349 }
350
351 if ( GraphicsEnvironment.isHeadless() )
352 {
353 throw new HeadlessException();
354 }
355
356 this.parent = parent;
357
358 if ( maximumMessages > 0 )
359 {
360 this.maximumMessages = new Integer( maximumMessages );
361 }
362 if ( columns > 0 )
363 {
364 this.columns = new Integer( columns );
365 }
366
367 this.resizable = Boolean.valueOf( resizable );
368 }
369
370
371
372
373
374
375 public Component getParent()
376 {
377 return this.parent;
378 }
379
380
381
382
383
384
385
386
387 public void setParent( final Component parent )
388 {
389 if ( parent == null )
390 {
391 throw new NullPointerException( "parent" );
392 }
393
394 this.parent = parent;
395 }
396
397
398
399
400
401
402 public int getMaximumMessages()
403 {
404 if ( this.maximumMessages == null )
405 {
406 this.maximumMessages = this.getDefaultMaximumMessages();
407 }
408
409 return this.maximumMessages.intValue();
410 }
411
412
413
414
415
416
417
418
419 public int getColumns()
420 {
421 if ( this.columns == null )
422 {
423 this.columns = this.getDefaultColumns();
424 }
425
426 return this.columns.intValue();
427 }
428
429
430
431
432
433
434
435
436 public boolean isResizable()
437 {
438 if ( this.resizable == null )
439 {
440 this.resizable = this.isDefaultResizable();
441 }
442
443 return this.resizable.booleanValue();
444 }
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462 private String getUnknownMessageEventTypeMessage( final Locale locale,
463 final java.lang.Number unknownEventType )
464 {
465 return ContainerFactory.getContainer().
466 getMessage( this, "unknownMessageEventType", locale,
467 new Object[]
468 {
469 unknownEventType
470 });
471
472 }
473
474
475
476
477
478
479
480
481
482
483 private String getInformationMessage( final Locale locale )
484 {
485 return ContainerFactory.getContainer().
486 getMessage( this, "information", locale, null );
487
488 }
489
490
491
492
493
494
495
496
497
498
499 private String getNotificationMessage( final Locale locale )
500 {
501 return ContainerFactory.getContainer().
502 getMessage( this, "notification", locale, null );
503
504 }
505
506
507
508
509
510
511
512
513
514
515 private String getWarningMessage( final Locale locale )
516 {
517 return ContainerFactory.getContainer().
518 getMessage( this, "warning", locale, null );
519
520 }
521
522
523
524
525
526
527
528
529
530
531 private String getErrorMessage( final Locale locale )
532 {
533 return ContainerFactory.getContainer().
534 getMessage( this, "error", locale, null );
535
536 }
537
538
539
540
541 }
542
543
544
545
546
547
548
549 class HtmlLabel extends JLabel
550 {
551
552
553 private static final long serialVersionUID = -3022796716512336911L;
554
555
556 private int columns;
557
558
559
560
561
562
563
564 HtmlLabel( final int columns )
565 {
566 super();
567 this.columns = columns;
568 this.setVerticalAlignment( SwingConstants.TOP );
569 this.setVerticalTextPosition( SwingConstants.TOP );
570 }
571
572 public Dimension getPreferredSize()
573 {
574 final Dimension size = super.getPreferredSize();
575 String text = this.getText();
576
577 if ( this.columns > 0 && text != null && text.length() > 0 )
578 {
579 int rows = 1;
580 int currentRowWidth = 0;
581 int maxRowWidth = 0;
582 boolean parsingTag = false;
583 text = text.trim();
584 text = text.substring( "<html>".length(), text.length() - "</html>".length() );
585 text = HtmlEntities.unescapeHtml( text );
586 final Insets insets = this.getInsets();
587 final FontMetrics fontMetrics = this.getFontMetrics( this.getFont() );
588
589 for ( int i = 0, column = 0, s0 = text.length(); i < s0; i++ )
590 {
591 final char c = text.charAt( i );
592
593 if ( c == '<' )
594 {
595 parsingTag = true;
596 }
597
598 if ( !parsingTag )
599 {
600 currentRowWidth += fontMetrics.charWidth( c );
601
602 if ( maxRowWidth < currentRowWidth )
603 {
604 maxRowWidth = currentRowWidth;
605 }
606
607 column++;
608 }
609
610 if ( parsingTag && c == '>' )
611 {
612 parsingTag = false;
613 }
614
615 if ( column == this.columns )
616 {
617 rows++;
618 column = 0;
619 currentRowWidth = 0;
620 }
621 }
622
623 size.width = maxRowWidth + insets.left + insets.right;
624 size.height = rows * fontMetrics.getHeight() + insets.top + insets.bottom;
625 }
626
627 return size;
628 }
629
630 }