Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JFace ErrorDialog: how do I show something in the details portion?

Tags:

java

jface

ErrorDialog.openError takes arguments for dialog title, message, and status (which has a message itself).

I want to show the exception's message in the main area, and the call stack in the details area. However, both of these variations show the call stack in the main area:

void showException(Throwable e) {
    Status status = 
        new Status(IStatus.ERROR, "SCS Admin", e.getLocalizedMessage(), e);
    e.printStackTrace;
    ErrorDialog.openError(getShell(), null, Util.getStackTrace(e), status);
}

void showException(Throwable e) {
    Status status = 
        new Status(IStatus.ERROR, "SCS Admin", Util.getStackTrace(e), e);
    e.printStackTrace;
    ErrorDialog.openError(getShell(), null, e.getLocalizedMessage(), status);
}

How can I switch it around?

like image 427
Alexey Romanov Avatar asked May 13 '10 13:05

Alexey Romanov


2 Answers

In default JFace ErrorDialog only way to show full exception stack trace (same as produced by printStackTrace()) is to build each row of stack trace as one status. And finally set these statuses as childen of MultiStatus.

Here's example of utility method I use in our RCP apps:

/**
 * Shows JFace ErrorDialog but improved by constructing full stack trace in
 * detail area.
 */
public static void errorDialogWithStackTrace(String msg, Throwable t) {

    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    t.printStackTrace(pw);

    final String trace = sw.toString(); // stack trace as a string

    // Temp holder of child statuses
    List<Status> childStatuses = new ArrayList<>();

    // Split output by OS-independend new-line
    for (String line : trace.split(System.getProperty("line.separator"))) {
        // build & add status
        childStatuses.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, line));
    }

    MultiStatus ms = new MultiStatus(Activator.PLUGIN_ID, IStatus.ERROR,
            childStatuses.toArray(new Status[] {}), // convert to array of statuses
            t.getLocalizedMessage(), t);

    ErrorDialog.openError(null, PxConstants.DIALOG_TITLE, msg, ms);
}
like image 174
Matt Avatar answered Sep 24 '22 01:09

Matt


You could wrap the exception with a new that contains the stacktrace as message.

public void showException(final Exception ex) {
    Display.getDefault().syncExec(new Runnable() {
        @Override
        public void run() {
            StringWriter sw = new StringWriter();
            ex.printStackTrace(new PrintWriter(sw));
            IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), new Exception(sw.toString()));
            ErrorDialog.openError(Display.getDefault().getActiveShell(), "Error", null, status);
        }
    });
}
like image 29
Niklaus Bucher Avatar answered Sep 24 '22 01:09

Niklaus Bucher