001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.util.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Component;
023: import java.awt.FlowLayout;
024: import java.awt.GridBagConstraints;
025: import java.awt.GridBagLayout;
026: import java.awt.Insets;
027: import java.awt.event.ActionEvent;
028: import java.io.PrintWriter;
029: import java.io.StringWriter;
030: import java.util.HashMap;
031: import java.util.Locale;
032: import java.util.Map;
033: import java.util.ResourceBundle;
034:
035: import javax.swing.AbstractAction;
036: import javax.swing.Action;
037: import javax.swing.BorderFactory;
038: import javax.swing.JButton;
039: import javax.swing.JComponent;
040: import javax.swing.JDialog;
041: import javax.swing.JLabel;
042: import javax.swing.JOptionPane;
043: import javax.swing.JPanel;
044: import javax.swing.JScrollPane;
045: import javax.swing.JSeparator;
046: import javax.swing.JTextArea;
047:
048: import org.apache.batik.util.gui.resource.ActionMap;
049: import org.apache.batik.util.gui.resource.ButtonFactory;
050: import org.apache.batik.util.gui.resource.MissingListenerException;
051: import org.apache.batik.util.gui.resource.ResourceManager;
052:
053: /**
054: * This class represents a dialog to display an error (message + Exception).
055: *
056: * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
057: * @version $Id: JErrorPane.java 478169 2006-11-22 14:23:24Z dvholten $
058: */
059: public class JErrorPane extends JPanel implements ActionMap {
060:
061: /**
062: * The resource file name
063: */
064: protected static final String RESOURCES = "org.apache.batik.util.gui.resources.JErrorPane";
065:
066: /**
067: * The resource bundle
068: */
069: protected static ResourceBundle bundle;
070:
071: /**
072: * The resource manager
073: */
074: protected static ResourceManager resources;
075:
076: static {
077: bundle = ResourceBundle.getBundle(RESOURCES, Locale
078: .getDefault());
079: resources = new ResourceManager(bundle);
080: }
081:
082: /**
083: * The error message.
084: */
085: protected String msg;
086:
087: /**
088: * The stack trace.
089: */
090: protected String stacktrace;
091:
092: /**
093: * The button factory.
094: */
095: protected ButtonFactory bf = new ButtonFactory(bundle, this );
096:
097: /**
098: * The text area used to show the stack trace.
099: */
100: protected JComponent detailsArea;
101:
102: /**
103: * The button used to show or not the details.
104: */
105: protected JButton showDetailButton;
106:
107: /**
108: * This flag bit indicates whether or not the stack trace is shown.
109: */
110: protected boolean isDetailShown = false;
111:
112: /**
113: * The sub panel that contains the stack trace text area.
114: */
115: protected JPanel subpanel;
116:
117: /**
118: * Constructs a new JErrorPane.
119: *
120: * @param th the throwable object that describes the errror
121: * @param type the dialog type
122: */
123: public JErrorPane(Throwable th, int type) {
124: super (new GridBagLayout());
125:
126: setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
127:
128: listeners.put("ShowDetailButtonAction",
129: new ShowDetailButtonAction());
130: listeners.put("OKButtonAction", new OKButtonAction());
131: this .msg = bundle.getString("Heading.text") + "\n\n"
132: + th.getMessage();
133:
134: StringWriter writer = new StringWriter();
135: th.printStackTrace(new PrintWriter(writer));
136: writer.flush();
137: this .stacktrace = writer.toString();
138:
139: ExtendedGridBagConstraints constraints = new ExtendedGridBagConstraints();
140:
141: JTextArea msgArea = new JTextArea();
142: msgArea.setText(msg);
143: msgArea.setColumns(50);
144: msgArea.setFont(new JLabel().getFont());
145: msgArea.setForeground(new JLabel().getForeground());
146: msgArea.setOpaque(false);
147: msgArea.setEditable(false);
148: msgArea.setLineWrap(true);
149:
150: constraints.setWeight(0, 0);
151: constraints.anchor = GridBagConstraints.WEST;
152: constraints.fill = GridBagConstraints.NONE;
153: constraints.setGridBounds(0, 0, 1, 1);
154: add(msgArea, constraints);
155:
156: constraints.setWeight(1, 0);
157: constraints.anchor = GridBagConstraints.CENTER;
158: constraints.fill = GridBagConstraints.HORIZONTAL;
159: constraints.setGridBounds(0, 1, 1, 1);
160: add(createButtonsPanel(), constraints);
161:
162: JTextArea details = new JTextArea();
163: msgArea.setColumns(50);
164: details.setText(stacktrace);
165: details.setEditable(false);
166:
167: detailsArea = new JPanel(new BorderLayout(0, 10));
168: detailsArea.add(new JSeparator(), BorderLayout.NORTH);
169: detailsArea.add(new JScrollPane(details), BorderLayout.CENTER);
170:
171: subpanel = new JPanel(new BorderLayout());
172:
173: constraints.insets = new Insets(10, 4, 4, 4);
174: constraints.setWeight(1, 1);
175: constraints.anchor = GridBagConstraints.CENTER;
176: constraints.fill = GridBagConstraints.BOTH;
177: constraints.setGridBounds(0, 2, 1, 1);
178: add(subpanel, constraints);
179: }
180:
181: public JDialog createDialog(Component owner, String title) {
182: JDialog dialog = new JDialog(JOptionPane
183: .getFrameForComponent(owner), title);
184: dialog.getContentPane().add(this , BorderLayout.CENTER);
185: dialog.pack();
186: return dialog;
187: }
188:
189: protected JPanel createButtonsPanel() {
190: JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
191:
192: showDetailButton = bf.createJButton("ShowDetailButton");
193: panel.add(showDetailButton);
194:
195: JButton okButton = bf.createJButton("OKButton");
196: panel.add(okButton);
197:
198: return panel;
199: }
200:
201: /**
202: * The map that contains the listeners
203: */
204: protected Map listeners = new HashMap();
205:
206: /**
207: * Returns the action associated with the given string or null on error
208: *
209: * @param key the key mapped with the action to get
210: * @throws MissingListenerException if the action is not found
211: */
212: public Action getAction(String key) throws MissingListenerException {
213: return (Action) listeners.get(key);
214: }
215:
216: /**
217: * The action associated with the 'OK' button.
218: */
219: protected class OKButtonAction extends AbstractAction {
220:
221: public void actionPerformed(ActionEvent evt) {
222: ((JDialog) getTopLevelAncestor()).dispose();
223: }
224: }
225:
226: /**
227: * The action associated with the 'Show Detail' button.
228: */
229: protected class ShowDetailButtonAction extends AbstractAction {
230:
231: public void actionPerformed(ActionEvent evt) {
232: if (isDetailShown) {
233: subpanel.remove(detailsArea);
234: isDetailShown = false;
235: showDetailButton.setText(resources
236: .getString("ShowDetailButton.text"));
237: } else {
238: subpanel.add(detailsArea, BorderLayout.CENTER);
239: showDetailButton.setText(resources
240: .getString("ShowDetailButton.text2"));
241: isDetailShown = true;
242: }
243: ((JDialog) getTopLevelAncestor()).pack();
244: }
245: }
246: }
|