org.eclipse.jface.dialogs.IconAndMessageDialog Maven / Gradle / Ivy
The newest version!
/*******************************************************************************
* 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
* Stefan Xenos, IBM - bug 156790: Adopt GridLayoutFactory within JFace
*******************************************************************************/
package org.eclipse.jface.dialogs;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.LayoutConstants;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
/**
* The IconAndMessageDialog is the abstract superclass of dialogs that have an
* icon and a message as the first two widgets. In this dialog the icon and
* message are direct children of the shell in order that they can be read by
* accessibility tools more easily.
*
* Note: Clients are expected to call {@link #createMessageArea(Composite)},
* otherwise neither the icon nor the message will appear.
*
*/
public abstract class IconAndMessageDialog extends Dialog {
/**
* Message (a localized string).
*/
protected String message;
/**
* Message label is the label the message is shown on.
*/
protected Label messageLabel;
/**
* Return the label for the image.
*/
protected Label imageLabel;
/**
* Constructor for IconAndMessageDialog.
*
* @param parentShell
* the parent shell, or null
to create a top-level
* shell
*/
public IconAndMessageDialog(Shell parentShell) {
super(parentShell);
}
/**
* Create the area the message will be shown in.
*
* The parent composite is assumed to use GridLayout as its layout manager,
* since the parent is typically the composite created in
* {@link Dialog#createDialogArea}.
*
*
* Note: Clients are expected to call this method, otherwise
* neither the icon nor the message will appear.
*
*
* @param composite
* The composite to parent from.
* @return Control
*/
protected Control createMessageArea(Composite composite) {
// create composite
// create image
Image image = getImage();
if (image != null) {
imageLabel = new Label(composite, SWT.NULL);
image.setBackground(imageLabel.getBackground());
imageLabel.setImage(image);
imageLabel.setToolTipText(getAccessibleMessageFor(image));
addAccessibleListeners(imageLabel, image);
GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BEGINNING)
.applyTo(imageLabel);
}
// create message
if (message != null) {
messageLabel = new Label(composite, getMessageLabelStyle());
messageLabel.setText(message);
GridDataFactory
.fillDefaults()
.align(SWT.FILL, SWT.BEGINNING)
.grab(true, false)
.hint(
convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
SWT.DEFAULT).applyTo(messageLabel);
}
return composite;
}
private String getAccessibleMessageFor(Image image) {
if (image.equals(getErrorImage())) {
return JFaceResources.getString("error");//$NON-NLS-1$
}
if (image.equals(getWarningImage())) {
return JFaceResources.getString("warning");//$NON-NLS-1$
}
if (image.equals(getInfoImage())) {
return JFaceResources.getString("info");//$NON-NLS-1$
}
if (image.equals(getQuestionImage())) {
return JFaceResources.getString("question"); //$NON-NLS-1$
}
return null;
}
/**
* Add an accessible listener to the label if it can be inferred from the
* image.
*/
private void addAccessibleListeners(Label label, final Image image) {
label.getAccessible().addAccessibleListener(new AccessibleAdapter() {
@Override
public void getName(AccessibleEvent event) {
final String accessibleMessage = getAccessibleMessageFor(image);
if (accessibleMessage == null) {
return;
}
event.result = accessibleMessage;
}
});
}
/**
* Returns the style for the message label.
*
* @return the style for the message label
*
* @since 3.0
*/
protected int getMessageLabelStyle() {
return SWT.WRAP;
}
/*
* @see Dialog.createButtonBar()
*/
@Override
protected Control createButtonBar(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(0) // this is incremented
// by createButton
.equalWidth(true).applyTo(composite);
GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).span(2, 1)
.applyTo(composite);
composite.setFont(parent.getFont());
// Add the buttons to the button bar.
createButtonsForButtonBar(composite);
return composite;
}
/**
* Returns the image to display beside the message in this dialog.
*
* Subclasses may override.
*
*
* @return the image to display beside the message
* @since 2.0
*/
protected abstract Image getImage();
/*
* @see Dialog.createContents(Composite)
*/
@Override
protected Control createContents(Composite parent) {
// initialize the dialog units
initializeDialogUnits(parent);
Point defaultSpacing = LayoutConstants.getSpacing();
GridLayoutFactory.fillDefaults().margins(LayoutConstants.getMargins())
.spacing(defaultSpacing.x * 2,
defaultSpacing.y).numColumns(getColumnCount()).applyTo(parent);
GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
createDialogAndButtonArea(parent);
return parent;
}
/**
* Get the number of columns in the layout of the Shell of the dialog.
*
* @return int
* @since 3.22
*/
protected int getColumnCount() {
return 2;
}
/**
* Create the dialog area and the button bar for the receiver.
*
* @param parent the parent composite
*/
protected void createDialogAndButtonArea(Composite parent) {
// create the dialog area and button bar
dialogArea = createDialogArea(parent);
buttonBar = createButtonBar(parent);
// Apply to the parent so that the message gets it too.
applyDialogFont(parent);
}
/**
* Return the Image
to be used when displaying an error.
*
* @return image the error image
*/
public Image getErrorImage() {
return getSWTImage(SWT.ICON_ERROR);
}
/**
* Return the Image
to be used when displaying a warning.
*
* @return image the warning image
*/
public Image getWarningImage() {
return getSWTImage(SWT.ICON_WARNING);
}
/**
* Return the Image
to be used when displaying information.
*
* @return image the information image
*/
public Image getInfoImage() {
return getSWTImage(SWT.ICON_INFORMATION);
}
/**
* Return the Image
to be used when displaying a question.
*
* @return image the question image
*/
public Image getQuestionImage() {
return getSWTImage(SWT.ICON_QUESTION);
}
/**
* Get an Image
from the provide SWT image constant.
*
* @param imageID
* the SWT image constant
* @return image the image
*/
private Image getSWTImage(final int imageID) {
Shell shell = getShell();
final Display display;
if (shell == null || shell.isDisposed()) {
shell = getParentShell();
}
if (shell == null || shell.isDisposed()) {
display = Display.getCurrent();
// The dialog should be always instantiated in UI thread.
// However it was possible to instantiate it in other threads
// (the code worked in most cases) so the assertion covers
// only the failing scenario. See bug 107082 for details.
Assert.isNotNull(display,
"The dialog should be created in UI thread"); //$NON-NLS-1$
} else {
display = shell.getDisplay();
}
final Image[] image = new Image[1];
display.syncExec(() -> image[0] = display.getSystemImage(imageID));
return image[0];
}
}