/*
JPC: An x86 PC Hardware Emulator for a pure Java Virtual Machine
Release Version 2.4
A project from the Physics Dept, The University of Oxford
Copyright (C) 2007-2010 The University of Oxford
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as published by
the Free Software Foundation.
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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Details (including contact information) can be found at:
jpc.sourceforge.net
or the developer website
sourceforge.net/projects/jpc/
Conceived and Developed by:
Rhys Newman, Ian Preston, Chris Dennis
End of licence header
*/
package org.jpc.debugger.util;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.util.*;
import java.text.*;
public class ReportPanel extends JPanel implements ActionListener
{
private static DateFormat dateFormat = DateFormat.getDateTimeInstance();
private Icon okIcon, errorIcon, busyIcon;
private JButton status, stop;
private JLabel statusText;
private String cause, infoString;
private Throwable error;
private long timeOfError;
public ReportPanel()
{
super(new BorderLayout());
setBorder(BorderFactory.createLoweredBevelBorder());
infoString = null;
okIcon = new ScaledIcon(UIManager.getIcon("OptionPane.informationIcon"), 17, 17);
busyIcon = new ScaledIcon(UIManager.getIcon("OptionPane.warningIcon"), 17, 17);
errorIcon = new ScaledIcon(UIManager.getIcon("OptionPane.errorIcon"), 17, 17);
stop = new JButton("Stop");
stop.addActionListener(this);
stop.setEnabled(false);
status = new JButton(okIcon);
status.addActionListener(this);
statusText = new JLabel("Ready ");
statusText.setPreferredSize(new Dimension(150, 20));
JToolBar tools = new JToolBar();
tools.setPreferredSize(new Dimension(20, okIcon.getIconHeight()+4));
tools.setFloatable(false);
tools.add(status);
//tools.add(stop);
tools.add(Box.createRigidArea(new Dimension(5,1)));
JPanel buffer = new JPanel(new BorderLayout(10, 10));
buffer.add("Center", statusText);
tools.add(buffer);
add("South", tools);
}
public void setInfo(String message)
{
infoString = message;
}
public static String formatTime(long time)
{
return formatDate(new Date(time));
}
public static String formatDate(Date d)
{
return dateFormat.format(d);
}
public void showStatus(String message)
{
statusText.setText(message);
}
public void setStopEnabled(boolean value)
{
stop.setEnabled(value);
}
public void clearError()
{
error = null;
status.setIcon(okIcon);
statusText.setText("Ready");
}
public Throwable getError()
{
return error;
}
public void unhandledAWTException(Throwable t)
{
setError("An error occurred while rendering the user interface", t);
}
public void setError(String cause, Throwable t)
{
error = t;
this.cause = cause;
timeOfError = System.currentTimeMillis();
status.setIcon(errorIcon);
statusText.setText(t.getLocalizedMessage());
}
public void showError()
{
showError(cause, error, timeOfError);
}
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == status)
{
if (error == null)
showInformation();
else
showError();
}
else if (evt.getSource() == stop)
cancelPendingActions();
}
protected void cancelPendingActions()
{
setStopEnabled(false);
}
protected void showInformation()
{
if (infoString == null)
return;
Component p1 = UtilityFrame.getSuitableDialogParent(this);
JOptionPane.showMessageDialog(p1, infoString, "Information", JOptionPane.INFORMATION_MESSAGE);
}
public void showError(String cause, Throwable err)
{
showError(cause, err, System.currentTimeMillis());
}
public void showError(String cause, Throwable err, long time)
{
showError(cause, err, time, true);
}
public void showError(String cause, Throwable err, long time, boolean allowClearing)
{
if (err == null)
return;
if (cause == null)
cause = "Unknown Cause";
Component p1 = UtilityFrame.getSuitableDialogParent(this);
ErrorDisplayDialog dlg = new ErrorDisplayDialog(p1, cause, err, time, allowClearing);
if (dlg.show(p1))
clearError();
else
setError(cause, err);
}
public static class ErrorDisplayDialog extends JDialog implements ActionListener
{
public static final String SHOW_DETAILS = "Show Details >>";
public static final String HIDE_DETAILS = "Hide Details <<";
private boolean errorCleared;
private JPanel main, details;
private JComponent detailView, description;
private boolean showingDetails;
private JButton ok, clearError, showDetails;
public ErrorDisplayDialog(Component parent, String message, Throwable err, long timeOfError)
{
this(parent, message, err, timeOfError, true);
}
public ErrorDisplayDialog(Component parent, String message, Throwable err, long timeOfError, boolean canBeCleared)
{
super(UtilityFrame.getApplicationFrame(parent), "Error Information", true);
showingDetails = false;
//setResizable(false);
main = new JPanel(new BorderLayout(10, 10));
main.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
if (timeOfError >= 0)
main.add("South", new JLabel("Error on "+dateFormat.format(new Date(timeOfError))));
if (message == null)
message = "";
description = new JTextArea(message+"\n-----------\n"+err.getMessage());
description.setBorder(BorderFactory.createLoweredBevelBorder());
description.setFont(new JLabel().getFont());
((JTextArea) description).setEditable(false);
//description.setBackground(getBackground());
main.add("Center", description);
ok = new JButton("OK");
ok.addActionListener(this);
clearError = new JButton("Clear Error");
clearError.addActionListener(this);
showDetails = new JButton(SHOW_DETAILS);
showDetails.addActionListener(this);
JPanel p3 = new JPanel();
p3.add(ok);
if (canBeCleared)
p3.add(clearError);
p3.add(showDetails);
main.add("North", p3);
TreeNode root = ErrorPanel.buildErrorTraceTree(message, err);
detailView = new JScrollPane(new JTree(new DefaultTreeModel(root)));
getContentPane().add("Center", main);
errorCleared = false;
}
public boolean show(Component parent)
{
int width = Math.max(400, description.getPreferredSize().width+50);
int height = description.getPreferredSize().height+150;
Rectangle bounds = UtilityFrame.getCentredDialogBounds(this, parent, width, height);
setBounds(bounds);
setVisible(true);
return errorCleared;
}
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == ok)
dispose();
else if (evt.getSource() == clearError)
{
errorCleared = true;
dispose();
}
else
{
if (!showingDetails)
{
showDetails.setText(HIDE_DETAILS);
Dimension s = getSize();
setSize(new Dimension(s.width, s.height+300));
main.remove(description);
details = new JPanel(new BorderLayout(10, 10));
details.add("North", description);
details.add("Center", detailView);
main.add("Center", details);
validate();
showingDetails = true;
}
else
{
showingDetails = false;
showDetails.setText(SHOW_DETAILS);
Dimension s = getSize();
Dimension size = new Dimension(s.width, description.getPreferredSize().height+150);
setSize(size);
details.remove(description);
main.remove(details);
main.add("Center", description);
validate();
}
}
}
}
}