org.eclipse.jface.dialogs.TitleAreaDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jface.dialogs.TitleAreaDialog.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Konstantin Scheglov <scheglov_ke@nlmk.ru > - Fix for bug 41172
 *     [Dialogs] Bug with Image in TitleAreaDialog
 *     Sebastian Davids <sdavids@gmx.de> - Fix for bug 82064
 *     [Dialogs] TitleAreaDialog#setTitleImage cannot be called before open()
 *******************************************************************************/
package org.eclipse.jface.dialogs;

import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleAttributeAdapter;
import org.eclipse.swt.accessibility.AccessibleAttributeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * A dialog that has a title area for displaying a title and an image as well as
 * a common area for displaying a description, a message, or an error message.
 * <p>
 * This dialog class may be subclassed.
 */
public class TitleAreaDialog extends TrayDialog {
    /**
     * Image registry key for error message image.
     */
    public static final String DLG_IMG_TITLE_ERROR = DLG_IMG_MESSAGE_ERROR;

    /**
     * Image registry key for banner image (value
     * <code>"dialog_title_banner_image"</code>).
     */
    public static final String DLG_IMG_TITLE_BANNER = "dialog_title_banner_image";//$NON-NLS-1$

    /**
     * Message type constant used to display an info icon with the message.
     *
     * @since 2.0
     * @deprecated
     */
    @Deprecated
    public static final String INFO_MESSAGE = "INFO_MESSAGE"; //$NON-NLS-1$

    /**
     * Message type constant used to display a warning icon with the message.
     *
     * @since 2.0
     * @deprecated
     */
    @Deprecated
    public static final String WARNING_MESSAGE = "WARNING_MESSAGE"; //$NON-NLS-1$

    // Space between an image and a label
    private static final int H_GAP_IMAGE = 5;

    // Minimum dialog width (in dialog units)
    private static final int MIN_DIALOG_WIDTH = 350;

    // Minimum dialog height (in dialog units)
    private static final int MIN_DIALOG_HEIGHT = 150;

    private Label titleLabel;

    private Label titleImageLabel;

    private Label bottomFillerLabel;

    private Label leftFillerLabel;

    private RGB titleAreaRGB;

    Color titleAreaColor;

    private String message = ""; //$NON-NLS-1$

    private String errorMessage;

    private Text messageLabel;

    private Composite workArea;

    private Label messageImageLabel;

    private Image messageImage;

    private boolean showingError = false;

    private boolean titleImageLargest = true;

    private int messageLabelHeight;

    private Image titleAreaImage;

    private int xTrim;

    private int yTrim;

    /**
     * Instantiate a new title area dialog.
     *
     * @param parentShell
     *            the parent SWT shell
     */
    public TitleAreaDialog(Shell parentShell) {
        super(parentShell);
    }

    /*
     * @see Dialog.createContents(Composite)
     */
    @Override
    protected Control createContents(Composite parent) {
        // create the overall composite
        Composite contents = new Composite(parent, SWT.NONE);
        contents.setLayoutData(new GridData(GridData.FILL_BOTH));
        // initialize the dialog units
        initializeDialogUnits(contents);
        FormLayout layout = new FormLayout();
        contents.setLayout(layout);
        // Now create a work area for the rest of the dialog
        workArea = new Composite(contents, SWT.NONE);
        GridLayout childLayout = new GridLayout();
        childLayout.marginHeight = 0;
        childLayout.marginWidth = 0;
        childLayout.verticalSpacing = 0;
        workArea.setLayout(childLayout);
        Control top = createTitleArea(contents);
        resetWorkAreaAttachments(top);
        workArea.setFont(JFaceResources.getDialogFont());
        // initialize the dialog units
        initializeDialogUnits(workArea);
        // create the dialog area and button bar
        dialogArea = createDialogArea(workArea);
        buttonBar = createButtonBar(workArea);

        // computing trim for later
        Rectangle rect = messageLabel.computeTrim(0, 0, 100, 100);
        xTrim = rect.width - 100;
        yTrim = rect.height - 100;

        // need to react to new size of title area
        getShell().addListener(SWT.Resize, event -> layoutForNewMessage(true));
        return contents;
    }

    /**
     * Creates and returns the contents of the upper part of this dialog (above
     * the button bar).
     * <p>
     * The <code>Dialog</code> implementation of this framework method creates
     * and returns a new <code>Composite</code> with no margins and spacing.
     * Subclasses should override.
     * </p>
     *
     * @param parent
     *            The parent composite to contain the dialog area
     * @return the dialog area control
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        // create the top level composite for the dialog area
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setFont(parent.getFont());
        // Build the separator line
        Label titleBarSeparator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR);
        titleBarSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        return composite;
    }

    /**
     * Creates the dialog's title area.
     *
     * @param parent
     *            the SWT parent for the title area widgets
     * @return Control with the highest x axis value.
     */
    private Control createTitleArea(Composite parent) {

        // add a dispose listener
        parent.addDisposeListener(e -> {
            if (titleAreaColor != null) {
                titleAreaColor.dispose();
            }
        });
        // Determine the background color of the title bar
        Display display = parent.getDisplay();
        Color background;
        Color foreground;
        if (titleAreaRGB != null) {
            titleAreaColor = new Color(display, titleAreaRGB);
            background = titleAreaColor;
            foreground = null;
        } else {
            background = JFaceColors.getBannerBackground(display);
            foreground = JFaceColors.getBannerForeground(display);
        }

        parent.setBackground(background);
        int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        int horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        // Dialog image @ right
        titleImageLabel = new Label(parent, SWT.CENTER);
        titleImageLabel.setBackground(background);
        if (titleAreaImage == null)
            titleImageLabel.setImage(JFaceResources.getImage(DLG_IMG_TITLE_BANNER));
        else
            titleImageLabel.setImage(titleAreaImage);

        FormData imageData = new FormData();
        imageData.top = new FormAttachment(0, 0);
        // Note: do not use horizontalSpacing on the right as that would be a
        // regression from
        // the R2.x style where there was no margin on the right and images are
        // flush to the right
        // hand side. see reopened comments in 41172
        imageData.right = new FormAttachment(100, 0); // horizontalSpacing
        titleImageLabel.setLayoutData(imageData);
        // Title label @ top, left
        titleLabel = new Label(parent, SWT.LEFT);
        JFaceColors.setColors(titleLabel, foreground, background);
        titleLabel.setFont(JFaceResources.getBannerFont());
        titleLabel.setText(" ");//$NON-NLS-1$
        FormData titleData = new FormData();
        titleData.top = new FormAttachment(0, verticalSpacing);
        titleData.right = new FormAttachment(titleImageLabel);
        titleData.left = new FormAttachment(0, horizontalSpacing);
        titleLabel.setLayoutData(titleData);
        // Message image @ bottom, left
        messageImageLabel = new Label(parent, SWT.CENTER);
        messageImageLabel.setBackground(background);
        // Message label @ bottom, center
        messageLabel = new Text(parent, SWT.WRAP | SWT.READ_ONLY);
        JFaceColors.setColors(messageLabel, foreground, background);
        messageLabel.setText(" \n "); // two lines//$NON-NLS-1$
        messageLabel.setFont(JFaceResources.getDialogFont());
        // Bug 248410 -  This snippet will only work with Windows screen readers.
        messageLabel.getAccessible().addAccessibleAttributeListener(new AccessibleAttributeAdapter() {
            @Override
            public void getAttributes(AccessibleAttributeEvent e) {
                e.attributes = new String[] { "container-live", //$NON-NLS-1$
                        "polite", "live", "polite", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
                        "container-live-role", "status", }; //$NON-NLS-1$ //$NON-NLS-2$
            }
        });
        messageLabelHeight = messageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
        // Filler labels
        leftFillerLabel = new Label(parent, SWT.CENTER);
        leftFillerLabel.setBackground(background);
        bottomFillerLabel = new Label(parent, SWT.CENTER);
        bottomFillerLabel.setBackground(background);
        setLayoutsForNormalMessage(verticalSpacing, horizontalSpacing);
        determineTitleImageLargest();
        if (titleImageLargest)
            return titleImageLabel;
        return messageLabel;
    }

    /**
     * Determine if the title image is larger than the title message and message
     * area. This is used for layout decisions.
     */
    private void determineTitleImageLargest() {
        int titleY = titleImageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
        int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        int labelY = titleLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
        labelY += verticalSpacing;
        labelY += messageLabelHeight;
        labelY += verticalSpacing;
        titleImageLargest = titleY > labelY;
    }

    /**
     * Set the layout values for the messageLabel, messageImageLabel and
     * fillerLabel for the case where there is a normal message.
     *
     * @param verticalSpacing
     *            int The spacing between widgets on the vertical axis.
     * @param horizontalSpacing
     *            int The spacing between widgets on the horizontal axis.
     */
    private void setLayoutsForNormalMessage(int verticalSpacing, int horizontalSpacing) {
        FormData messageImageData = new FormData();
        messageImageData.top = new FormAttachment(titleLabel, verticalSpacing);
        messageImageData.left = new FormAttachment(0, H_GAP_IMAGE);
        messageImageLabel.setLayoutData(messageImageData);
        FormData messageLabelData = new FormData();
        messageLabelData.top = new FormAttachment(titleLabel, verticalSpacing);
        messageLabelData.right = new FormAttachment(titleImageLabel);
        messageLabelData.left = new FormAttachment(messageImageLabel, horizontalSpacing);
        messageLabelData.height = messageLabelHeight;
        if (titleImageLargest)
            messageLabelData.bottom = new FormAttachment(titleImageLabel, 0, SWT.BOTTOM);
        messageLabel.setLayoutData(messageLabelData);
        FormData fillerData = new FormData();
        fillerData.left = new FormAttachment(0, horizontalSpacing);
        fillerData.top = new FormAttachment(messageImageLabel, 0);
        fillerData.bottom = new FormAttachment(messageLabel, 0, SWT.BOTTOM);
        bottomFillerLabel.setLayoutData(fillerData);
        FormData data = new FormData();
        data.top = new FormAttachment(messageImageLabel, 0, SWT.TOP);
        data.left = new FormAttachment(0, 0);
        data.bottom = new FormAttachment(messageImageLabel, 0, SWT.BOTTOM);
        data.right = new FormAttachment(messageImageLabel, 0);
        leftFillerLabel.setLayoutData(data);
    }

    /**
     * The <code>TitleAreaDialog</code> implementation of this
     * <code>Window</code> methods returns an initial size which is at least
     * some reasonable minimum.
     *
     * @return the initial size of the dialog
     */
    @Override
    protected Point getInitialSize() {
        Point shellSize = super.getInitialSize();
        return new Point(Math.max(convertHorizontalDLUsToPixels(MIN_DIALOG_WIDTH), shellSize.x),
                Math.max(convertVerticalDLUsToPixels(MIN_DIALOG_HEIGHT), shellSize.y));
    }

    /**
     * Retained for backward compatibility.
     *
     * Returns the title area composite. There is no composite in this
     * implementation so the shell is returned.
     *
     * @return Composite
     * @deprecated
     */
    @Deprecated
    protected Composite getTitleArea() {
        return getShell();
    }

    /**
     * Returns the title image label.
     *
     * @return the title image label
     */
    protected Label getTitleImageLabel() {
        return titleImageLabel;
    }

    /**
     * Display the given error message. The currently displayed message is saved
     * and will be redisplayed when the error message is set to
     * <code>null</code>.
     *
     * @param newErrorMessage
     *            the newErrorMessage to display or <code>null</code>
     */
    public void setErrorMessage(String newErrorMessage) {
        // Any change?
        if (errorMessage == null ? newErrorMessage == null : errorMessage.equals(newErrorMessage))
            return;
        errorMessage = newErrorMessage;

        // Clear or set error message.
        if (errorMessage == null) {
            if (showingError) {
                // we were previously showing an error
                showingError = false;
            }
            // show the message
            // avoid calling setMessage in case it is overridden to call
            // setErrorMessage,
            // which would result in a recursive infinite loop
            if (message == null) // this should probably never happen since
                // setMessage does this conversion....
                message = ""; //$NON-NLS-1$
            updateMessage(message);
            messageImageLabel.setImage(messageImage);
            setImageLabelVisible(messageImage != null);
        } else {
            // Add in a space for layout purposes but do not
            // change the instance variable
            String displayedErrorMessage = " " + errorMessage; //$NON-NLS-1$
            updateMessage(displayedErrorMessage);
            if (!showingError) {
                // we were not previously showing an error
                showingError = true;
                messageImageLabel.setImage(JFaceResources.getImage(DLG_IMG_TITLE_ERROR));
                setImageLabelVisible(true);
            }
        }
        layoutForNewMessage(false);
    }

    /**
     * Re-layout the labels for the new message.
     *
     * @param forceLayout
     *            <code>true</code> to force a layout of the shell
     */
    private void layoutForNewMessage(boolean forceLayout) {
        int verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        int horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        // If there are no images then layout as normal
        if (errorMessage == null && messageImage == null) {
            setImageLabelVisible(false);
            setLayoutsForNormalMessage(verticalSpacing, horizontalSpacing);
        } else {
            messageImageLabel.setVisible(true);
            bottomFillerLabel.setVisible(true);
            leftFillerLabel.setVisible(true);
            /**
             * Note that we do not use horizontalSpacing here as when the
             * background of the messages changes there will be gaps between the
             * icon label and the message that are the background color of the
             * shell. We add a leading space elsewhere to compendate for this.
             */
            FormData data = new FormData();
            data.left = new FormAttachment(0, H_GAP_IMAGE);
            data.top = new FormAttachment(titleLabel, verticalSpacing);
            messageImageLabel.setLayoutData(data);
            data = new FormData();
            data.top = new FormAttachment(messageImageLabel, 0);
            data.left = new FormAttachment(0, 0);
            data.bottom = new FormAttachment(messageLabel, 0, SWT.BOTTOM);
            data.right = new FormAttachment(messageImageLabel, 0, SWT.RIGHT);
            bottomFillerLabel.setLayoutData(data);
            data = new FormData();
            data.top = new FormAttachment(messageImageLabel, 0, SWT.TOP);
            data.left = new FormAttachment(0, 0);
            data.bottom = new FormAttachment(messageImageLabel, 0, SWT.BOTTOM);
            data.right = new FormAttachment(messageImageLabel, 0);
            leftFillerLabel.setLayoutData(data);
            FormData messageLabelData = new FormData();
            messageLabelData.top = new FormAttachment(titleLabel, verticalSpacing);
            messageLabelData.right = new FormAttachment(titleImageLabel);
            messageLabelData.left = new FormAttachment(messageImageLabel, 0);
            messageLabelData.height = messageLabelHeight;
            if (titleImageLargest)
                messageLabelData.bottom = new FormAttachment(titleImageLabel, 0, SWT.BOTTOM);
            messageLabel.setLayoutData(messageLabelData);
        }

        if (forceLayout) {
            getShell().layout();
        } else {
            // Do not layout before the dialog area has been created
            // to avoid incomplete calculations.
            if (dialogArea != null)
                workArea.getParent().layout(true);
        }

        int messageLabelUnclippedHeight = messageLabel.computeSize(messageLabel.getSize().x - xTrim, SWT.DEFAULT,
                true).y;
        boolean messageLabelClipped = messageLabelUnclippedHeight > messageLabel.getSize().y - yTrim;
        if (messageLabel.getData() instanceof ToolTip) {
            ToolTip toolTip = (ToolTip) messageLabel.getData();
            toolTip.hide();
            toolTip.deactivate();
            messageLabel.setData(null);
        }
        if (messageLabelClipped) {
            ToolTip tooltip = new ToolTip(messageLabel, ToolTip.NO_RECREATE, false) {

                @Override
                protected Composite createToolTipContentArea(Event event, Composite parent) {
                    Composite result = new Composite(parent, SWT.NONE);
                    result.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
                    result.setLayout(new GridLayout());
                    Text text = new Text(result, SWT.WRAP);
                    text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
                    text.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
                    text.setText(messageLabel.getText());
                    GridData gridData = new GridData();
                    gridData.widthHint = messageLabel.getSize().x;
                    text.setLayoutData(gridData);
                    Dialog.applyDialogFont(result);
                    return result;
                }

                @Override
                public Point getLocation(Point tipSize, Event event) {
                    return messageLabel.getShell().toDisplay(messageLabel.getLocation());
                }
            };
            messageLabel.setData(tooltip);
            tooltip.setPopupDelay(0);
            tooltip.activate();
        }
    }

    /**
     * Set the message text. If the message line currently displays an error,
     * the message is saved and will be redisplayed when the error message is
     * set to <code>null</code>.
     * <p>
     * Shortcut for <code>setMessage(newMessage, IMessageProvider.NONE)</code>
     * </p>
     * This method should be called after the dialog has been opened as it
     * updates the message label immediately.
     *
     * @param newMessage
     *            the message, or <code>null</code> to clear the message
     */
    public void setMessage(String newMessage) {
        setMessage(newMessage, IMessageProvider.NONE);
    }

    /**
     * Sets the message for this dialog with an indication of what type of
     * message it is.
     * <p>
     * The valid message types are one of <code>NONE</code>,
     * <code>INFORMATION</code>,<code>WARNING</code>, or
     * <code>ERROR</code>.
     * </p>
     * <p>
     * Note that for backward compatibility, a message of type
     * <code>ERROR</code> is different than an error message (set using
     * <code>setErrorMessage</code>). An error message overrides the current
     * message until the error message is cleared. This method replaces the
     * current message and does not affect the error message.
     * </p>
     *
     * @param newMessage
     *            the message, or <code>null</code> to clear the message
     * @param newType
     *            the message type
     * @since 2.0
     */
    public void setMessage(String newMessage, int newType) {
        Image newImage = null;
        if (newMessage != null) {
            switch (newType) {
            case IMessageProvider.NONE:
                break;
            case IMessageProvider.INFORMATION:
                newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_INFO);
                break;
            case IMessageProvider.WARNING:
                newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_WARNING);
                break;
            case IMessageProvider.ERROR:
                newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_ERROR);
                break;
            }
        }
        showMessage(newMessage, newImage);
    }

    /**
     * Show the new message and image.
     *
     * @param newMessage
     * @param newImage
     */
    private void showMessage(String newMessage, Image newImage) {
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=249915
        if (newMessage == null)
            newMessage = ""; //$NON-NLS-1$

        // Any change?
        if (message.equals(newMessage) && messageImage == newImage) {
            return;
        }
        message = newMessage;

        // Message string to be shown - if there is an image then add in
        // a space to the message for layout purposes
        String shownMessage = (newImage == null) ? message : " " + message; //$NON-NLS-1$
        messageImage = newImage;
        if (!showingError) {
            // we are not showing an error
            updateMessage(shownMessage);
            messageImageLabel.setImage(messageImage);
            setImageLabelVisible(messageImage != null);
            layoutForNewMessage(false);
        }
    }

    /**
     * Update the contents of the messageLabel.
     *
     * @param newMessage
     *            the message to use
     */
    private void updateMessage(String newMessage) {
        String oldMessage = messageLabel.getText();
        messageLabel.setText(newMessage);
        // Bug 248410 -  This snippet will only work with Windows screen readers.
        messageLabel.getAccessible().sendEvent(ACC.EVENT_ATTRIBUTE_CHANGED, null);
        messageLabel.getAccessible().sendEvent(ACC.EVENT_TEXT_CHANGED,
                new Object[] { Integer.valueOf(ACC.TEXT_DELETE), Integer.valueOf(0),
                        Integer.valueOf(oldMessage.length()), oldMessage });
        messageLabel.getAccessible().sendEvent(ACC.EVENT_TEXT_CHANGED,
                new Object[] { Integer.valueOf(ACC.TEXT_INSERT), Integer.valueOf(0),
                        Integer.valueOf(newMessage.length()), newMessage });
    }

    /**
     * Sets the title to be shown in the title area of this dialog.
     *
     * @param newTitle
     *            the title show
     */
    public void setTitle(String newTitle) {
        if (titleLabel == null)
            return;
        String title = newTitle;
        if (title == null)
            title = "";//$NON-NLS-1$
        titleLabel.setText(title);
    }

    /**
     * Sets the title bar color for this dialog.
     *
     * @param color
     *            the title bar color
     */
    public void setTitleAreaColor(RGB color) {
        titleAreaRGB = color;
    }

    /**
     * Sets the title image to be shown in the title area of this dialog.
     *
     * @param newTitleImage
     *            the title image to be shown
     */
    public void setTitleImage(Image newTitleImage) {

        titleAreaImage = newTitleImage;
        if (titleImageLabel != null) {
            titleImageLabel.setImage(newTitleImage);
            determineTitleImageLargest();
            Control top;
            if (titleImageLargest)
                top = titleImageLabel;
            else
                top = messageLabel;
            resetWorkAreaAttachments(top);
        }
    }

    /**
     * Make the label used for displaying error images visible depending on
     * boolean.
     *
     * @param visible
     *            If <code>true</code> make the image visible, if not then
     *            make it not visible.
     */
    private void setImageLabelVisible(boolean visible) {
        messageImageLabel.setVisible(visible);
        bottomFillerLabel.setVisible(visible);
        leftFillerLabel.setVisible(visible);
    }

    /**
     * Reset the attachment of the workArea to now attach to top as the top
     * control.
     *
     * @param top
     */
    private void resetWorkAreaAttachments(Control top) {
        FormData childData = new FormData();
        childData.top = new FormAttachment(top);
        childData.right = new FormAttachment(100, 0);
        childData.left = new FormAttachment(0, 0);
        childData.bottom = new FormAttachment(100, 0);
        workArea.setLayoutData(childData);
    }

    /**
     * Returns the current message text for this dialog.  This message is
     * displayed in the message line of the dialog when the error message
     * is <code>null</code>.  If there is a non-null error message, this
     * message is not shown, but is stored so that it can be shown in
     * the message line whenever {@link #setErrorMessage(String)} is called with
     * a <code>null</code> parameter.
     *
     * @return the message text, which is never <code>null</code>.
     *
     * @see #setMessage(String)
     * @see #setErrorMessage(String)
     *
     * @since 3.6
     */

    public String getMessage() {
        return message;
    }

    /**
     * Returns the current error message being shown in the dialog, or
     * <code>null</code> if there is no error message being shown.
     *
     * @return the error message, which may be <code>null</code>.
     *
     * @see #setErrorMessage(String)
     * @see #setMessage(String)
     *
     * @since 3.6
     */

    public String getErrorMessage() {
        return errorMessage;
    }
}