KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > dialogs > TitleAreaDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Konstantin Scheglov <scheglov_ke@nlmk.ru > - Fix for bug 41172
11  * [Dialogs] Bug with Image in TitleAreaDialog
12  * Sebastian Davids <sdavids@gmx.de> - Fix for bug 82064
13  * [Dialogs] TitleAreaDialog#setTitleImage cannot be called before open()
14  *******************************************************************************/

15 package org.eclipse.jface.dialogs;
16
17 import org.eclipse.jface.resource.JFaceColors;
18 import org.eclipse.jface.resource.JFaceResources;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.DisposeEvent;
21 import org.eclipse.swt.events.DisposeListener;
22 import org.eclipse.swt.graphics.Color;
23 import org.eclipse.swt.graphics.Image;
24 import org.eclipse.swt.graphics.Point;
25 import org.eclipse.swt.graphics.RGB;
26 import org.eclipse.swt.layout.FormAttachment;
27 import org.eclipse.swt.layout.FormData;
28 import org.eclipse.swt.layout.FormLayout;
29 import org.eclipse.swt.layout.GridData;
30 import org.eclipse.swt.layout.GridLayout;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.Display;
34 import org.eclipse.swt.widgets.Label;
35 import org.eclipse.swt.widgets.Shell;
36 import org.eclipse.swt.widgets.Text;
37
38 /**
39  * A dialog that has a title area for displaying a title and an image as well as
40  * a common area for displaying a description, a message, or an error message.
41  * <p>
42  * This dialog class may be subclassed.
43  */

44 public class TitleAreaDialog extends TrayDialog {
45     /**
46      * Image registry key for error message image.
47      */

48     public static final String JavaDoc DLG_IMG_TITLE_ERROR = DLG_IMG_MESSAGE_ERROR;
49
50     /**
51      * Image registry key for banner image (value
52      * <code>"dialog_title_banner_image"</code>).
53      */

54     public static final String JavaDoc DLG_IMG_TITLE_BANNER = "dialog_title_banner_image";//$NON-NLS-1$
55

56     /**
57      * Message type constant used to display an info icon with the message.
58      *
59      * @since 2.0
60      * @deprecated
61      */

62     public final static String JavaDoc INFO_MESSAGE = "INFO_MESSAGE"; //$NON-NLS-1$
63

64     /**
65      * Message type constant used to display a warning icon with the message.
66      *
67      * @since 2.0
68      * @deprecated
69      */

70     public final static String JavaDoc WARNING_MESSAGE = "WARNING_MESSAGE"; //$NON-NLS-1$
71

72     // Space between an image and a label
73
private static final int H_GAP_IMAGE = 5;
74
75     // Minimum dialog width (in dialog units)
76
private static final int MIN_DIALOG_WIDTH = 350;
77
78     // Minimum dialog height (in dialog units)
79
private static final int MIN_DIALOG_HEIGHT = 150;
80
81     private Label titleLabel;
82
83     private Label titleImageLabel;
84
85     private Label bottomFillerLabel;
86
87     private Label leftFillerLabel;
88
89     private RGB titleAreaRGB;
90
91     Color titleAreaColor;
92
93     private String JavaDoc message = ""; //$NON-NLS-1$
94

95     private String JavaDoc errorMessage;
96
97     private Text messageLabel;
98
99     private Composite workArea;
100
101     private Label messageImageLabel;
102
103     private Image messageImage;
104
105     private boolean showingError = false;
106
107     private boolean titleImageLargest = true;
108
109     private int messageLabelHeight;
110
111     private Image titleAreaImage;
112
113     /**
114      * Instantiate a new title area dialog.
115      *
116      * @param parentShell
117      * the parent SWT shell
118      */

119     public TitleAreaDialog(Shell parentShell) {
120         super(parentShell);
121     }
122
123     /*
124      * @see Dialog.createContents(Composite)
125      */

126     protected Control createContents(Composite parent) {
127         // create the overall composite
128
Composite contents = new Composite(parent, SWT.NONE);
129         contents.setLayoutData(new GridData(GridData.FILL_BOTH));
130         // initialize the dialog units
131
initializeDialogUnits(contents);
132         FormLayout layout = new FormLayout();
133         contents.setLayout(layout);
134         // Now create a work area for the rest of the dialog
135
workArea = new Composite(contents, SWT.NONE);
136         GridLayout childLayout = new GridLayout();
137         childLayout.marginHeight = 0;
138         childLayout.marginWidth = 0;
139         childLayout.verticalSpacing = 0;
140         workArea.setLayout(childLayout);
141         Control top = createTitleArea(contents);
142         resetWorkAreaAttachments(top);
143         workArea.setFont(JFaceResources.getDialogFont());
144         // initialize the dialog units
145
initializeDialogUnits(workArea);
146         // create the dialog area and button bar
147
dialogArea = createDialogArea(workArea);
148         buttonBar = createButtonBar(workArea);
149         return contents;
150     }
151
152     /**
153      * Creates and returns the contents of the upper part of this dialog (above
154      * the button bar).
155      * <p>
156      * The <code>Dialog</code> implementation of this framework method creates
157      * and returns a new <code>Composite</code> with no margins and spacing.
158      * Subclasses should override.
159      * </p>
160      *
161      * @param parent
162      * The parent composite to contain the dialog area
163      * @return the dialog area control
164      */

165     protected Control createDialogArea(Composite parent) {
166         // create the top level composite for the dialog area
167
Composite composite = new Composite(parent, SWT.NONE);
168         GridLayout layout = new GridLayout();
169         layout.marginHeight = 0;
170         layout.marginWidth = 0;
171         layout.verticalSpacing = 0;
172         layout.horizontalSpacing = 0;
173         composite.setLayout(layout);
174         composite.setLayoutData(new GridData(GridData.FILL_BOTH));
175         composite.setFont(parent.getFont());
176         // Build the separator line
177
Label titleBarSeparator = new Label(composite, SWT.HORIZONTAL
178                 | SWT.SEPARATOR);
179         titleBarSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
180         return composite;
181     }
182
183     /**
184      * Creates the dialog's title area.
185      *
186      * @param parent
187      * the SWT parent for the title area widgets
188      * @return Control with the highest x axis value.
189      */

190     private Control createTitleArea(Composite parent) {
191
192         // add a dispose listener
193
parent.addDisposeListener(new DisposeListener() {
194             public void widgetDisposed(DisposeEvent e) {
195                 if (titleAreaColor != null) {
196                     titleAreaColor.dispose();
197                 }
198             }
199         });
200         // Determine the background color of the title bar
201
Display display = parent.getDisplay();
202         Color background;
203         Color foreground;
204         if (titleAreaRGB != null) {
205             titleAreaColor = new Color(display, titleAreaRGB);
206             background = titleAreaColor;
207             foreground = null;
208         } else {
209             background = JFaceColors.getBannerBackground(display);
210             foreground = JFaceColors.getBannerForeground(display);
211         }
212
213         parent.setBackground(background);
214         int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
215         int horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
216         // Dialog image @ right
217
titleImageLabel = new Label(parent, SWT.CENTER);
218         titleImageLabel.setBackground(background);
219         if (titleAreaImage == null)
220             titleImageLabel.setImage(JFaceResources
221                     .getImage(DLG_IMG_TITLE_BANNER));
222         else
223             titleImageLabel.setImage(titleAreaImage);
224
225         FormData imageData = new FormData();
226         imageData.top = new FormAttachment(0, 0);
227         // Note: do not use horizontalSpacing on the right as that would be a
228
// regression from
229
// the R2.x style where there was no margin on the right and images are
230
// flush to the right
231
// hand side. see reopened comments in 41172
232
imageData.right = new FormAttachment(100, 0); // horizontalSpacing
233
titleImageLabel.setLayoutData(imageData);
234         // Title label @ top, left
235
titleLabel = new Label(parent, SWT.LEFT);
236         JFaceColors.setColors(titleLabel, foreground, background);
237         titleLabel.setFont(JFaceResources.getBannerFont());
238         titleLabel.setText(" ");//$NON-NLS-1$
239
FormData titleData = new FormData();
240         titleData.top = new FormAttachment(0, verticalSpacing);
241         titleData.right = new FormAttachment(titleImageLabel);
242         titleData.left = new FormAttachment(0, horizontalSpacing);
243         titleLabel.setLayoutData(titleData);
244         // Message image @ bottom, left
245
messageImageLabel = new Label(parent, SWT.CENTER);
246         messageImageLabel.setBackground(background);
247         // Message label @ bottom, center
248
messageLabel = new Text(parent, SWT.WRAP | SWT.READ_ONLY);
249         JFaceColors.setColors(messageLabel, foreground, background);
250         messageLabel.setText(" \n "); // two lines//$NON-NLS-1$
251
messageLabel.setFont(JFaceResources.getDialogFont());
252         messageLabelHeight = messageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
253         // Filler labels
254
leftFillerLabel = new Label(parent, SWT.CENTER);
255         leftFillerLabel.setBackground(background);
256         bottomFillerLabel = new Label(parent, SWT.CENTER);
257         bottomFillerLabel.setBackground(background);
258         setLayoutsForNormalMessage(verticalSpacing, horizontalSpacing);
259         determineTitleImageLargest();
260         if (titleImageLargest)
261             return titleImageLabel;
262         return messageLabel;
263     }
264
265     /**
266      * Determine if the title image is larger than the title message and message
267      * area. This is used for layout decisions.
268      */

269     private void determineTitleImageLargest() {
270         int titleY = titleImageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
271         int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
272         int labelY = titleLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
273         labelY += verticalSpacing;
274         labelY += messageLabelHeight;
275         labelY += verticalSpacing;
276         titleImageLargest = titleY > labelY;
277     }
278
279     /**
280      * Set the layout values for the messageLabel, messageImageLabel and
281      * fillerLabel for the case where there is a normal message.
282      *
283      * @param verticalSpacing
284      * int The spacing between widgets on the vertical axis.
285      * @param horizontalSpacing
286      * int The spacing between widgets on the horizontal axis.
287      */

288     private void setLayoutsForNormalMessage(int verticalSpacing,
289             int horizontalSpacing) {
290         FormData messageImageData = new FormData();
291         messageImageData.top = new FormAttachment(titleLabel, verticalSpacing);
292         messageImageData.left = new FormAttachment(0, H_GAP_IMAGE);
293         messageImageLabel.setLayoutData(messageImageData);
294         FormData messageLabelData = new FormData();
295         messageLabelData.top = new FormAttachment(titleLabel, verticalSpacing);
296         messageLabelData.right = new FormAttachment(titleImageLabel);
297         messageLabelData.left = new FormAttachment(messageImageLabel,
298                 horizontalSpacing);
299         messageLabelData.height = messageLabelHeight;
300         if (titleImageLargest)
301             messageLabelData.bottom = new FormAttachment(titleImageLabel, 0,
302                     SWT.BOTTOM);
303         messageLabel.setLayoutData(messageLabelData);
304         FormData fillerData = new FormData();
305         fillerData.left = new FormAttachment(0, horizontalSpacing);
306         fillerData.top = new FormAttachment(messageImageLabel, 0);
307         fillerData.bottom = new FormAttachment(messageLabel, 0, SWT.BOTTOM);
308         bottomFillerLabel.setLayoutData(fillerData);
309         FormData data = new FormData();
310         data.top = new FormAttachment(messageImageLabel, 0, SWT.TOP);
311         data.left = new FormAttachment(0, 0);
312         data.bottom = new FormAttachment(messageImageLabel, 0, SWT.BOTTOM);
313         data.right = new FormAttachment(messageImageLabel, 0);
314         leftFillerLabel.setLayoutData(data);
315     }
316
317     /**
318      * The <code>TitleAreaDialog</code> implementation of this
319      * <code>Window</code> methods returns an initial size which is at least
320      * some reasonable minimum.
321      *
322      * @return the initial size of the dialog
323      */

324     protected Point getInitialSize() {
325         Point shellSize = super.getInitialSize();
326         return new Point(Math.max(
327                 convertHorizontalDLUsToPixels(MIN_DIALOG_WIDTH), shellSize.x),
328                 Math.max(convertVerticalDLUsToPixels(MIN_DIALOG_HEIGHT),
329                         shellSize.y));
330     }
331
332     /**
333      * Retained for backward compatibility.
334      *
335      * Returns the title area composite. There is no composite in this
336      * implementation so the shell is returned.
337      *
338      * @return Composite
339      * @deprecated
340      */

341     protected Composite getTitleArea() {
342         return getShell();
343     }
344
345     /**
346      * Returns the title image label.
347      *
348      * @return the title image label
349      */

350     protected Label getTitleImageLabel() {
351         return titleImageLabel;
352     }
353
354     /**
355      * Display the given error message. The currently displayed message is saved
356      * and will be redisplayed when the error message is set to
357      * <code>null</code>.
358      *
359      * @param newErrorMessage
360      * the newErrorMessage to display or <code>null</code>
361      */

362     public void setErrorMessage(String JavaDoc newErrorMessage) {
363         // Any change?
364
if (errorMessage == null ? newErrorMessage == null : errorMessage
365                 .equals(newErrorMessage))
366             return;
367         errorMessage = newErrorMessage;
368
369         // Clear or set error message.
370
if (errorMessage == null) {
371             if (showingError) {
372                 // we were previously showing an error
373
showingError = false;
374             }
375             // show the message
376
// avoid calling setMessage in case it is overridden to call
377
// setErrorMessage,
378
// which would result in a recursive infinite loop
379
if (message == null) // this should probably never happen since
380
// setMessage does this conversion....
381
message = ""; //$NON-NLS-1$
382
updateMessage(message);
383             messageImageLabel.setImage(messageImage);
384             setImageLabelVisible(messageImage != null);
385         } else {
386             // Add in a space for layout purposes but do not
387
// change the instance variable
388
String JavaDoc displayedErrorMessage = " " + errorMessage; //$NON-NLS-1$
389
updateMessage(displayedErrorMessage);
390             if (!showingError) {
391                 // we were not previously showing an error
392
showingError = true;
393                 messageImageLabel.setImage(JFaceResources
394                         .getImage(DLG_IMG_TITLE_ERROR));
395                 setImageLabelVisible(true);
396             }
397         }
398         layoutForNewMessage();
399     }
400
401     /**
402      * Re-layout the labels for the new message.
403      */

404     private void layoutForNewMessage() {
405         int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
406         int horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
407         // If there are no images then layout as normal
408
if (errorMessage == null && messageImage == null) {
409             setImageLabelVisible(false);
410             setLayoutsForNormalMessage(verticalSpacing, horizontalSpacing);
411         } else {
412             messageImageLabel.setVisible(true);
413             bottomFillerLabel.setVisible(true);
414             leftFillerLabel.setVisible(true);
415             /**
416              * Note that we do not use horizontalSpacing here as when the
417              * background of the messages changes there will be gaps between the
418              * icon label and the message that are the background color of the
419              * shell. We add a leading space elsewhere to compendate for this.
420              */

421             FormData data = new FormData();
422             data.left = new FormAttachment(0, H_GAP_IMAGE);
423             data.top = new FormAttachment(titleLabel, verticalSpacing);
424             messageImageLabel.setLayoutData(data);
425             data = new FormData();
426             data.top = new FormAttachment(messageImageLabel, 0);
427             data.left = new FormAttachment(0, 0);
428             data.bottom = new FormAttachment(messageLabel, 0, SWT.BOTTOM);
429             data.right = new FormAttachment(messageImageLabel, 0, SWT.RIGHT);
430             bottomFillerLabel.setLayoutData(data);
431             data = new FormData();
432             data.top = new FormAttachment(messageImageLabel, 0, SWT.TOP);
433             data.left = new FormAttachment(0, 0);
434             data.bottom = new FormAttachment(messageImageLabel, 0, SWT.BOTTOM);
435             data.right = new FormAttachment(messageImageLabel, 0);
436             leftFillerLabel.setLayoutData(data);
437             FormData messageLabelData = new FormData();
438             messageLabelData.top = new FormAttachment(titleLabel,
439                     verticalSpacing);
440             messageLabelData.right = new FormAttachment(titleImageLabel);
441             messageLabelData.left = new FormAttachment(messageImageLabel, 0);
442             messageLabelData.height = messageLabelHeight;
443             if (titleImageLargest)
444                 messageLabelData.bottom = new FormAttachment(titleImageLabel,
445                         0, SWT.BOTTOM);
446             messageLabel.setLayoutData(messageLabelData);
447         }
448         // Do not layout before the dialog area has been created
449
// to avoid incomplete calculations.
450
if (dialogArea != null)
451             workArea.getParent().layout(true);
452     }
453
454     /**
455      * Set the message text. If the message line currently displays an error,
456      * the message is saved and will be redisplayed when the error message is
457      * set to <code>null</code>.
458      * <p>
459      * Shortcut for <code>setMessage(newMessage, IMessageProvider.NONE)</code>
460      * </p>
461      * This method should be called after the dialog has been opened as it
462      * updates the message label immediately.
463      *
464      * @param newMessage
465      * the message, or <code>null</code> to clear the message
466      */

467     public void setMessage(String JavaDoc newMessage) {
468         setMessage(newMessage, IMessageProvider.NONE);
469     }
470
471     /**
472      * Sets the message for this dialog with an indication of what type of
473      * message it is.
474      * <p>
475      * The valid message types are one of <code>NONE</code>,
476      * <code>INFORMATION</code>,<code>WARNING</code>, or
477      * <code>ERROR</code>.
478      * </p>
479      * <p>
480      * Note that for backward compatibility, a message of type
481      * <code>ERROR</code> is different than an error message (set using
482      * <code>setErrorMessage</code>). An error message overrides the current
483      * message until the error message is cleared. This method replaces the
484      * current message and does not affect the error message.
485      * </p>
486      *
487      * @param newMessage
488      * the message, or <code>null</code> to clear the message
489      * @param newType
490      * the message type
491      * @since 2.0
492      */

493     public void setMessage(String JavaDoc newMessage, int newType) {
494         Image newImage = null;
495         if (newMessage != null) {
496             switch (newType) {
497             case IMessageProvider.NONE:
498                 break;
499             case IMessageProvider.INFORMATION:
500                 newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_INFO);
501                 break;
502             case IMessageProvider.WARNING:
503                 newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_WARNING);
504                 break;
505             case IMessageProvider.ERROR:
506                 newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_ERROR);
507                 break;
508             }
509         }
510         showMessage(newMessage, newImage);
511     }
512
513     /**
514      * Show the new message and image.
515      *
516      * @param newMessage
517      * @param newImage
518      */

519     private void showMessage(String JavaDoc newMessage, Image newImage) {
520         // Any change?
521
if (message.equals(newMessage) && messageImage == newImage) {
522             return;
523         }
524         message = newMessage;
525         if (message == null)
526             message = "";//$NON-NLS-1$
527
// Message string to be shown - if there is an image then add in
528
// a space to the message for layout purposes
529
String JavaDoc shownMessage = (newImage == null) ? message : " " + message; //$NON-NLS-1$
530
messageImage = newImage;
531         if (!showingError) {
532             // we are not showing an error
533
updateMessage(shownMessage);
534             messageImageLabel.setImage(messageImage);
535             setImageLabelVisible(messageImage != null);
536             layoutForNewMessage();
537         }
538     }
539
540     /**
541      * Update the contents of the messageLabel.
542      *
543      * @param newMessage
544      * the message to use
545      */

546     private void updateMessage(String JavaDoc newMessage) {
547         messageLabel.setText(newMessage);
548     }
549
550     /**
551      * Sets the title to be shown in the title area of this dialog.
552      *
553      * @param newTitle
554      * the title show
555      */

556     public void setTitle(String JavaDoc newTitle) {
557         if (titleLabel == null)
558             return;
559         String JavaDoc title = newTitle;
560         if (title == null)
561             title = "";//$NON-NLS-1$
562
titleLabel.setText(title);
563     }
564
565     /**
566      * Sets the title bar color for this dialog.
567      *
568      * @param color
569      * the title bar color
570      */

571     public void setTitleAreaColor(RGB color) {
572         titleAreaRGB = color;
573     }
574
575     /**
576      * Sets the title image to be shown in the title area of this dialog.
577      *
578      * @param newTitleImage
579      * the title image to be shown
580      */

581     public void setTitleImage(Image newTitleImage) {
582
583         titleAreaImage = newTitleImage;
584         if (titleImageLabel != null) {
585             titleImageLabel.setImage(newTitleImage);
586             titleImageLabel.setVisible(newTitleImage != null);
587             if (newTitleImage != null) {
588                 determineTitleImageLargest();
589                 Control top;
590                 if (titleImageLargest)
591                     top = titleImageLabel;
592                 else
593                     top = messageLabel;
594                 resetWorkAreaAttachments(top);
595             }
596         }
597     }
598
599     /**
600      * Make the label used for displaying error images visible depending on
601      * boolean.
602      *
603      * @param visible
604      * If <code>true</code> make the image visible, if not then
605      * make it not visible.
606      */

607     private void setImageLabelVisible(boolean visible) {
608         messageImageLabel.setVisible(visible);
609         bottomFillerLabel.setVisible(visible);
610         leftFillerLabel.setVisible(visible);
611     }
612
613     /**
614      * Reset the attachment of the workArea to now attach to top as the top
615      * control.
616      *
617      * @param top
618      */

619     private void resetWorkAreaAttachments(Control top) {
620         FormData childData = new FormData();
621         childData.top = new FormAttachment(top);
622         childData.right = new FormAttachment(100, 0);
623         childData.left = new FormAttachment(0, 0);
624         childData.bottom = new FormAttachment(100, 0);
625         workArea.setLayoutData(childData);
626     }
627 }
628
Popular Tags