All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.page.messagebox.DetailedMessageBox Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2003, 2010 s IT Solutions AT Spardat GmbH .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/
// @(#) $Id:  $
package at.spardat.xma.page.messagebox;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * The {@link DetailedMessageBox} will be able to present a detail message in a collapsible area.
 * This information will contain:
 * 
    *
  • All elements in DetailedMessageBox.additionalInformationList
  • *
  • The formated Stacktrace located at DetailedMessageBox.exception
  • *
* So the caller can add custom "additional information" to the details.
* There is no need to set buttons and icons from the caller side, so the MessageBox will have a default * layout, button and icon set.
* The default style will be:
SWT.APPLICATION_MODAL | SWT.RESIZE

* Buttons: * *
  • Show Details / Hide Details
  • *
  • Copy text to Clipboard
  • *
  • OK
  • *
    * So we hope the name of the buttons wil be self-explanatory, but if there are any further questions, use * the ToolTip to get detailed information about the buttons and their actions behind them.

    * Icon:
    * This Detailed MessageBox will be used to display an Error to the EndUser, and provide the feature to get * detailed Information about the error. So there is no need to add another icon as the {@link SWT#ICON_ERROR}.

    * There is also another extra feature, because this MessageBox can be resized, so feel free to click the * Bottom-right corner of the Box and make it larger * * @author s3945 * @since 2.1.2 */ public class DetailedMessageBox extends AbstractMessagebox { /** the default height of the StackTrace element */ private static final int STACK_HEIGHT = 300; /** * this will be true, if the current used SWT version can display icons AND text on buttons.
    * * * * * * * * * *
    VERSIONNUMBER
    3.1.13139
    3.2.23236
    3.3.03346
    3.3.23349
    3.4.03448
    3.4.13449
    3.5.13555
    */ private static boolean DISPLAY_IMG_ON_BUTTONS = org.eclipse.swt.internal.Library.SWT_VERSION > 3139; /** the used {@link Button} on the MessageBox */ private Button detailButton, copyButton; /** the GUI representation of the information */ private Text infoText; /** this boolean will remember the state of the information field, so it will know if the detail is opend or not. */ private boolean detailOpen; /** the {@link Exception} contain the Stacktrace to present in details */ private Exception exception; /** this {@link List} of Strings will contain all additional information provided by the caller */ private List additionalInformationList = new ArrayList(); /** internal usage of newline */ private static final String NEWLINE = System.getProperty("line.separator"); /** the default style of the {@link DetailedMessageBox} */ private static final int DEFAULT_STYLE = SWT.APPLICATION_MODAL | SWT.RESIZE| SWT.ICON_ERROR; /** the internal cache of the text to display in the info box, because the copy context will be the same as the * context to display in the box, and the string building should only be done once. */ private String infoTextContent; /** all possible images added to the buttons, but can be null if SWT version will be not OK */ private Image copyImage, showDetailImage, hideDetailImage; /** * Creates a DetailedMessageBox with the following parameters: *
  • SWT.APPLICATION_MODAL
  • *
  • SWT.RESIZE
  • *
  • SWT.ICON_ERROR
  • *
  • Locale = Default
  • * @param parent shell to use to display */ public DetailedMessageBox(Shell parent) { super(parent, null, DEFAULT_STYLE); } /** * Creates a DetailedMessageBox with the following parameters: *
  • SWT.APPLICATION_MODAL
  • *
  • SWT.RESIZE
  • *
  • SWT.ICON_ERROR
  • * @param parent shell to use to display * @param locale the local to use to localize the buttons */ public DetailedMessageBox(Shell parent, Locale locale) { super(parent, locale, DEFAULT_STYLE); } /** * Creates a DetailedMessageBox with the following parameters: *
  • SWT.APPLICATION_MODAL
  • *
  • SWT.RESIZE
  • *
  • SWT.ICON_ERROR
  • * @param parent shell to use to display * @param locale the local to use to localize the buttons * @param exception the exception to display details for */ public DetailedMessageBox(Shell parent, Locale locale, Exception exception) { super(parent, locale, DEFAULT_STYLE); this.exception = exception; } /** * Creates a DetailedMessageBox with the following parameters: * @param parent shell to use to display * @param locale the local to use to localize the buttons * @param exception the exception to display details for * @param style the style of dialog to construct */ public DetailedMessageBox(Shell parent, Locale locale, Exception exception, int style) { super(parent, locale, style); this.exception = exception; } /** * This method will create all needed images to be able to use them on the buttons. */ private void initializeImages() { if (DISPLAY_IMG_ON_BUTTONS) { copyImage = new Image(getShell().getDisplay(), DetailedMessageBox.class.getClassLoader().getResourceAsStream("at/spardat/xma/page/messagebox/icon_copy.gif")); showDetailImage = new Image(getShell().getDisplay(), DetailedMessageBox.class.getClassLoader().getResourceAsStream("at/spardat/xma/page/messagebox/icon_show_details.gif")); hideDetailImage = new Image(getShell().getDisplay(), DetailedMessageBox.class.getClassLoader().getResourceAsStream("at/spardat/xma/page/messagebox/icon_hide_details.gif")); } } /** {@inheritDoc} */ protected void shellDisposed() { super.shellDisposed(); if (copyImage != null) { copyImage.dispose(); } if (showDetailImage != null) { showDetailImage.dispose(); } if (hideDetailImage != null) { hideDetailImage.dispose(); } } /** * create the buttons * @param lowerSeperator all buttons will be bottom attached to this separator */ private void createButtons(Label lowerSeparator) { initializeImages(); detailButton = new Button(getShell(), SWT.PUSH); detailButton.setText(getResourceBundle().getString("showdetails")); detailButton.setToolTipText(getResourceBundle().getString("showdetails.tooltip")); detailButton.addSelectionListener(getSelectionListener()); if (DISPLAY_IMG_ON_BUTTONS) { detailButton.setImage(showDetailImage); } copyButton = new Button(getShell(), SWT.PUSH); copyButton.setToolTipText(getResourceBundle().getString("copy.tooltip")); copyButton.addSelectionListener(getSelectionListener()); if (DISPLAY_IMG_ON_BUTTONS) { copyButton.setImage(copyImage); } copyButton.setText(getResourceBundle().getString("copy")); // DETAIL BUTTON FormData data = new FormData(); data.top = new FormAttachment(lowerSeparator, scaler.convertYToCurrent(5), SWT.BOTTOM); data.left = new FormAttachment(0, 100, scaler.convertXToCurrent(10)); detailButton.setLayoutData(data); // COPY BUTTON data = new FormData(); data.top = new FormAttachment(lowerSeparator, scaler.convertYToCurrent(5), SWT.BOTTOM); data.left = new FormAttachment(detailButton, scaler.convertXToCurrent(HORIZONTAL_OFFSET), SWT.RIGHT); copyButton.setLayoutData(data); } protected void layoutButtonComposite() { FormLayout layout = new FormLayout(); layout.marginBottom = scaler.convertYToCurrent(10); getButtonComposite().setLayout(layout); FormData data = new FormData(); data.top = new FormAttachment(getLowerSep(), 0, SWT.BOTTOM); data.right = new FormAttachment(100, 100, 0); getButtonComposite().setLayoutData(data); } /** * This selectionListener will set the local variable "answer" to the * selected Button or handle copy or display details. * @return the {@link SelectionListener} used for the button */ private SelectionListener getSelectionListener() { SelectionListener selectionListener = new SelectionListener() { public void widgetSelected(SelectionEvent e) { Button selButton = (Button) e.widget; boolean close = true; if (selButton.equals(copyButton)) { close = false; // by clicking the copy button, the MessageBox will not be closed copyTextToClipboard(); } else if (selButton.equals(detailButton)) { close = false; // by clicking the detail button, the MessageBox will not be closed handleDetail(); } if (close) { getShell().close(); } } public void widgetDefaultSelected(SelectionEvent e) { } }; return selectionListener; } /** * This method will collect the context to copy to {@link Clipboard}. * After successful copy this content to Clipboard, an {@link LocalizedMessageBox} with a * information text will be displayed to the user. */ private void copyTextToClipboard() { String text = getClipboardContent(); if (text != null && text.length() > 0) { Clipboard clipboard = new Clipboard(getShell().getDisplay()); try { clipboard.setContents(new Object[] { text }, new Transfer[] { TextTransfer.getInstance() }); LocalizedMessageBox msg = new LocalizedMessageBox(getShell(), getLocale(), SWT.OK | SWT.ICON_INFORMATION); msg.setMessage(getResourceBundle().getString("copy.information")); msg.open(); } finally { clipboard.dispose(); } } } /** * @return the String to be copied into {@link Clipboard}. */ private String getClipboardContent() { StringBuffer b = new StringBuffer(); String title = getTitle(); if(title!=null&&title.length()>0) b.append(title).append(NEWLINE).append(NEWLINE); String message = getMessage(); if(message!=null&&message.length()>0) b.append(message).append(NEWLINE).append(NEWLINE); b.append(getInfoTextContent()); return b.toString(); } /** * This method will handle the collapse and expand of the detail section. */ private void handleDetail() { if (detailOpen) { detailOpen = false; layoutInfoText(); detailButton.setText(getResourceBundle().getString("showdetails")); detailButton.setToolTipText(getResourceBundle().getString("showdetails.tooltip")); if (DISPLAY_IMG_ON_BUTTONS) { detailButton.setImage(showDetailImage); } } else { detailOpen = true; layoutInfoText(); infoText.setText(getInfoTextContent()); detailButton.setText(getResourceBundle().getString("hidedetails")); detailButton.setToolTipText(getResourceBundle().getString("hidedetails.tooltip")); if (DISPLAY_IMG_ON_BUTTONS) { detailButton.setImage(hideDetailImage); } } infoText.setVisible(detailOpen); calcShellSize(false); } private void layoutInfoText() { FormData infoTextData = new FormData(); infoTextData.left = new FormAttachment(0, 100, scaler.convertXToCurrent(10)); infoTextData.right = new FormAttachment(100, 100, 0); if (detailOpen) { infoTextData.top = new FormAttachment(getButtonComposite(), scaler.convertYToCurrent(5), SWT.BOTTOM); } else { infoTextData.top = new FormAttachment(getButtonComposite(), -40, SWT.BOTTOM); } infoTextData.bottom = new FormAttachment(100, 100, 0); infoTextData.height = detailOpen ? scaler.convertYToCurrent(STACK_HEIGHT) : 1; infoText.setLayoutData(infoTextData); } /** * This will provide the text to display in detail section.
    * The text will also add all additional information separated by a NEWLINE. * @return the text to display in detail box */ private String getInfoTextContent() { if (infoTextContent == null) { StringBuffer b = new StringBuffer(); // append all additional infos to text for(Iterator it=additionalInformationList.iterator();it.hasNext();) { String addInfo = (String) it.next(); b.append(addInfo).append(NEWLINE); } // append the stack trace final Writer result = new StringWriter(); final PrintWriter printWriter = new PrintWriter(result); this.exception.printStackTrace(printWriter); infoTextContent = b.append(result.toString()).toString(); } return infoTextContent; } /** {@inheritDoc} */ protected void createWidgets() { super.createWidgets(); createButtons(getLowerSep()); createInfoText(detailButton); } /** * Create the GUI representation of the info box. * @param lowerSep to attach */ private void createInfoText(Button topLayoutElement) { infoText = new Text(getShell(), SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); infoText.setVisible(false); infoText.setEditable(false); infoText.setText(getInfoTextContent()); FormData infoTextData = new FormData(); infoTextData.left = new FormAttachment(0, 100, scaler.convertXToCurrent(10)); infoTextData.right = new FormAttachment(100, 100, 0); infoTextData.top = new FormAttachment(topLayoutElement, -40, SWT.BOTTOM); infoTextData.height = detailOpen ? scaler.convertYToCurrent(STACK_HEIGHT) : 0; infoTextData.bottom = new FormAttachment(100, 100, 0); infoText.setLayoutData(infoTextData); } /** * The given string will be displayed in detail box and also copied to {@link Clipboard}. * @param additionalInformation the additionalInformationList to set */ public void addAdditionalInformation(String additionalInformation) { this.additionalInformationList.add(additionalInformation); } protected Point getMinSize() { int minWidth = scaler.convertXToCurrent(23) + detailButton.getSize().x + scaler.convertXToCurrent(HORIZONTAL_OFFSET); minWidth += copyButton.getSize().x + scaler.convertXToCurrent(HORIZONTAL_OFFSET); minWidth += getButtonComposite().getSize().x + scaler.convertXToCurrent(HORIZONTAL_OFFSET); int okBottomEnd = getButtonComposite().getLocation().y + getButtonComposite().getSize().y; int minHeight = okBottomEnd + scaler.convertYToCurrent(SHELL_DEFAULT_MIN_HEIGHT); if(detailOpen) { minHeight += scaler.convertYToCurrent(100); } return new Point(minWidth,minHeight); } protected int getButtonHeight() { return detailButton.computeSize(SWT.DEFAULT,SWT.DEFAULT).y; } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy