package com.quantum.ui.dialog; import com.quantum.Messages; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; /** * @author BC */ public class ExceptionDisplayDialog extends Dialog { private Control detailsArea; private Throwable throwable; private String message; /** * @param parentShell */ public ExceptionDisplayDialog(Shell parentShell, Throwable throwable) { super(parentShell); this.throwable = throwable; } /** * The Details button. */ private Button detailsButton; /** * The title of the dialog. */ private String title; /** * Indicates whether the error details viewer is currently created. */ private boolean detailsShown = false; /** * Creates an error dialog. * Note that the dialog will have no visual representation (no widgets) * until it is told to open. *
* Normally one should use openError
to create and open one of these.
* This constructor is useful only if the error object being displayed contains child
* items
null
to indicate that the default title should be used
* @param message the message to show in this dialog,
* or null
to indicate that the error's message should be shown
* as the primary message
* @param status the error to show to the user
* @param displayMask the mask to use to filter the displaying of child items,
* as per IStatus.matches
* @see org.eclipse.core.runtime.IStatus#matches(int)
*/
public ExceptionDisplayDialog(
Shell parentShell,
String dialogTitle,
String message,
Throwable throwable) {
super(parentShell);
this.title = dialogTitle;
this.message = message;
this.throwable = throwable;
setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
}
/* (non-Javadoc)
* Method declared on Dialog.
* Handles the pressing of the Ok or Details button in this dialog.
* If the Ok button was pressed then close this dialog. If the Details
* button was pressed then toggle the displaying of the error details area.
* Note that the Details button will only be visible if the error being
* displayed specifies child details.
*/
protected void buttonPressed(int id) {
if (id == IDialogConstants.DETAILS_ID) {
// was the details button pressed?
toggleDetailsArea();
} else {
super.buttonPressed(id);
}
}
/* (non-Javadoc)
* Method declared in Window.
*/
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText(title);
}
/* (non-Javadoc)
* Method declared on Dialog.
*/
protected void createButtonsForButtonBar(Composite parent) {
// create OK and Details buttons
createButton(
parent,
IDialogConstants.OK_ID,
IDialogConstants.OK_LABEL,
true);
this.detailsButton =
createButton(
parent,
IDialogConstants.DETAILS_ID,
IDialogConstants.SHOW_DETAILS_LABEL,
false);
}
protected Control createDialogArea(Composite parent) {
// create a composite with standard margins and spacing
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight =
convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.marginWidth =
convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.verticalSpacing =
convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing =
convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
composite.setLayout(layout);
GridData childData = new GridData(GridData.FILL_BOTH);
childData.horizontalSpan = 2;
composite.setLayoutData(childData);
composite.setFont(parent.getFont());
Label label = new Label(composite, 0);
label.setText(this.message);
label.setFont(parent.getFont());
GridData full = new GridData();
full.horizontalAlignment = GridData.FILL;
full.verticalAlignment = GridData.FILL;
full.heightHint = convertHeightInCharsToPixels(3);
full.widthHint = convertWidthInCharsToPixels(60);
label.setLayoutData(full);
return composite;
}
/**
* Create the expandable details arae.
*
* @param parent the parent composite
* @return the details text control
*/
protected Control createDetailsArea(Composite parent) {
// create a composite with standard margins and spacing
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight =
convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.marginWidth =
convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.verticalSpacing =
convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing =
convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
composite.setLayout(layout);
GridData childData = new GridData(GridData.FILL_BOTH);
childData.horizontalSpan = 2;
composite.setLayoutData(childData);
composite.setFont(parent.getFont());
Label label = new Label(composite, 0);
label.setText(Messages.getString("ExceptionDisplayDialog.stackTrace"));
label.setFont(parent.getFont());
GridData full = new GridData();
full.horizontalAlignment = GridData.FILL;
full.verticalAlignment = GridData.FILL;
full.heightHint = convertHeightInCharsToPixels(3);
full.widthHint = convertWidthInCharsToPixels(60);
label.setLayoutData(full);
Text text =
new Text(
composite,
SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
text.setText(this.throwable.getLocalizedMessage());
GridData data =
new GridData(
GridData.HORIZONTAL_ALIGN_FILL
| GridData.GRAB_HORIZONTAL
| GridData.VERTICAL_ALIGN_FILL
| GridData.GRAB_VERTICAL);
data.heightHint = convertHeightInCharsToPixels(8);
text.setLayoutData(data);
text.setFont(parent.getFont());
this.detailsShown = true;
return composite;
}
/**
* Opens an error dialog to display the given error. Use this method if the
* error object being displayed contains child items null
if none
* @param title the title to use for this dialog,
* or null
to indicate that the default title should be used
* @param message the message to show in this dialog,
* or null
to indicate that the error's message should be shown
* as the primary message
* as per IStatus.matches
* @return the code of the button that was pressed that resulted in this dialog
* closing. This will be Dialog.OK
if the OK button was
* pressed, or Dialog.CANCEL
if this dialog's close window
* decoration or the ESC key was used.
* @see org.eclipse.core.runtime.IStatus#matches(int)
*/
public static int openError(
Shell parentShell,
String title,
String message,
Throwable throwable) {
if (title == null) {
title = Messages.getString(ExceptionDisplayDialog.class.getName() +
"." + throwable.getClass().getName() + ".title");
}
if (message == null) {
message = Messages.getString(ExceptionDisplayDialog.class.getName() +
"." + throwable.getClass().getName() + ".message");
}
ExceptionDisplayDialog dialog =
new ExceptionDisplayDialog(parentShell, title, message, throwable);
return dialog.open();
}
/**
* Toggles the unfolding of the details area. This is triggered by
* the user pressing the details button.
*/
private void toggleDetailsArea() {
Point windowSize = getShell().getSize();
Point oldSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
if (this.detailsShown) {
this.detailsArea.dispose();
this.detailsShown = false;
detailsButton.setText(IDialogConstants.SHOW_DETAILS_LABEL);
} else {
this.detailsArea = createDetailsArea((Composite) getContents());
detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL);
}
Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
getShell().setSize(
new Point(windowSize.x, windowSize.y + (newSize.y - oldSize.y)));
}
}