/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.designer.core.status; import org.pentaho.reporting.designer.core.Messages; import org.pentaho.reporting.designer.core.util.dnd.ClipboardManager; import org.pentaho.reporting.designer.core.util.exceptions.UncaughtExceptionsModel; import org.pentaho.reporting.libraries.designtime.swing.LibSwingUtil; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.io.PrintWriter; import java.io.StringWriter; /** * Todo: Document Me * * @author Thomas Morgner */ public class ExceptionDialog extends JDialog { private class CopyAction extends AbstractAction { private CopyAction() { putValue( Action.NAME, Messages.getString( "ExceptionDialog.CopyToClipboard" ) ); // NON-NLS } public void actionPerformed( final ActionEvent e ) { final StringWriter b = new StringWriter(); final PrintWriter pw = new PrintWriter( b ); final ExceptionsListModel dataModel = getDataModel(); final int size = dataModel.getSize(); for ( int i = 0; i < size; i += 1 ) { if ( i != 0 ) { pw.println(); pw.println(); } final Throwable at = (Throwable) dataModel.getElementAt( i ); at.printStackTrace( pw ); } pw.close(); ClipboardManager.getManager().setRawContent( new StringSelection( b.toString() ) ); } } private class ClearAction extends AbstractAction { private ClearAction() { putValue( Action.NAME, Messages.getString( "ExceptionDialog.Clear" ) ); // NON-NLS } public void actionPerformed( final ActionEvent e ) { UncaughtExceptionsModel.getInstance().clearExceptions(); final ExceptionsListModel dataModel = getDataModel(); dataModel.refresh(); setStracktraceText( null ); } } private class ExceptionSelectionListener implements ListSelectionListener { private ExceptionSelectionListener() { } public void valueChanged( final ListSelectionEvent e ) { if ( !e.getValueIsAdjusting() ) { final Throwable selectedValue = getSelectedThrowable(); setStracktraceText( selectedValue ); } } } private class CloseAction extends AbstractAction { /** * Defines an <code>Action</code> object with a default description string and default icon. */ private CloseAction() { putValue( Action.NAME, Messages.getString( "ExceptionDialog.Close" ) ); // NON-NLS } /** * Invoked when an action occurs. */ public void actionPerformed( final ActionEvent e ) { dispose(); } } private ExceptionsListModel dataModel; private JTextArea stacktraceTextArea; private JList list; public ExceptionDialog() { init(); } public ExceptionDialog( final Frame owner ) { super( owner ); init(); } public ExceptionDialog( final Dialog owner ) { super( owner ); init(); } private void init() { setTitle( Messages.getString( "ExceptionDialog.Title" ) ); // NON-NLS setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE ); final JPanel contentPane = new JPanel(); contentPane.setLayout( new BorderLayout() ); dataModel = new ExceptionsListModel(); list = new JList( dataModel ); list.getSelectionModel().setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); list.setVisibleRowCount( 10 ); stacktraceTextArea = new JTextArea(); stacktraceTextArea.setEditable( false ); stacktraceTextArea.setColumns( 60 ); stacktraceTextArea.setRows( 10 ); final JPanel buttonPanel = new JPanel(); buttonPanel.setLayout( new GridLayout( 1, 3, 5, 5 ) ); buttonPanel.add( new JButton( new CloseAction() ) ); buttonPanel.add( new JButton( new ClearAction() ) ); buttonPanel.add( new JButton( new CopyAction() ) ); final JPanel buttonCarrier = new JPanel( new FlowLayout( FlowLayout.RIGHT ) ); buttonCarrier.add( buttonPanel ); contentPane.add( buttonCarrier, BorderLayout.SOUTH ); list.addListSelectionListener( new ExceptionSelectionListener() ); if ( dataModel.getSize() > 0 ) { list.setSelectedIndex( dataModel.getSize() - 1 ); } final JSplitPane splitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, new JScrollPane( list ), new JScrollPane( stacktraceTextArea ) ); splitPane.setDividerLocation( 150 ); contentPane.add( splitPane, BorderLayout.CENTER ); setContentPane( contentPane ); pack(); LibSwingUtil.centerFrameOnScreen( this ); final InputMap inputMap = contentPane.getInputMap(); final ActionMap actionMap = contentPane.getActionMap(); inputMap.put( KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ), "cancel" ); // NON-NLS actionMap.put( "cancel", new CloseAction() ); // NON-NLS } protected ExceptionsListModel getDataModel() { return dataModel; } protected Throwable getSelectedThrowable() { return (Throwable) list.getSelectedValue(); } protected static String getStacktraceText( final Throwable throwableInfo ) { final StringWriter sw = new StringWriter(); PrintWriter pw = null; try { //noinspection IOResourceOpenedButNotSafelyClosed pw = new PrintWriter( sw ); throwableInfo.printStackTrace( pw ); return sw.getBuffer().toString(); } finally { if ( pw != null ) { pw.close(); } } } protected void setStracktraceText( final Throwable t ) { if ( t == null ) { stacktraceTextArea.setText( "" ); } else { final String text = getStacktraceText( t ); stacktraceTextArea.setText( text ); stacktraceTextArea.setCaretPosition( 0 ); } } public void showDialog() { dataModel.refresh(); setVisible( true ); } public static void showDialog( final Component parent ) { final ExceptionDialog exceptionDialog; final Window window = LibSwingUtil.getWindowAncestor( parent ); if ( window instanceof Dialog ) { exceptionDialog = new ExceptionDialog( (Dialog) window ); } else if ( window instanceof Frame ) { exceptionDialog = new ExceptionDialog( (Frame) window ); } else { exceptionDialog = new ExceptionDialog(); } exceptionDialog.showDialog(); } }