2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2019 Kevin Lamonte
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
31 import java
.io
.FileWriter
;
32 import java
.io
.IOException
;
33 import java
.io
.PrintWriter
;
34 import java
.text
.MessageFormat
;
35 import java
.util
.ArrayList
;
36 import java
.util
.Date
;
37 import java
.util
.ResourceBundle
;
39 import jexer
.bits
.CellAttributes
;
42 * TExceptionDialog displays an exception and its stack trace to the user,
43 * and provides a means to save a troubleshooting report for support.
45 public class TExceptionDialog
extends TWindow
{
50 private static ResourceBundle i18n
= ResourceBundle
.getBundle(TExceptionDialog
.class.getName());
52 // ------------------------------------------------------------------------
53 // Constants --------------------------------------------------------------
54 // ------------------------------------------------------------------------
56 // ------------------------------------------------------------------------
57 // Variables --------------------------------------------------------------
58 // ------------------------------------------------------------------------
61 * The exception. We will actually make it Throwable, for the unlikely
62 * event we catch an Error rather than an Exception.
64 private Throwable exception
;
67 * The exception's stack trace.
69 private TList stackTrace
;
71 // ------------------------------------------------------------------------
72 // Constructors -----------------------------------------------------------
73 // ------------------------------------------------------------------------
78 * @param application TApplication that manages this window
79 * @param exception the exception to display
81 public TExceptionDialog(final TApplication application
,
82 final Throwable exception
) {
84 super(application
, i18n
.getString("windowTitle"),
85 1, 1, 70, 20, CENTERED
| MODAL
);
87 this.exception
= exception
;
89 addLabel(i18n
.getString("captionLine1"), 1, 1,
90 "twindow.background.modal");
91 addLabel(i18n
.getString("captionLine2"), 1, 2,
92 "twindow.background.modal");
93 addLabel(i18n
.getString("captionLine3"), 1, 3,
94 "twindow.background.modal");
95 addLabel(i18n
.getString("captionLine4"), 1, 4,
96 "twindow.background.modal");
98 addLabel(MessageFormat
.format(i18n
.getString("exceptionString"),
99 exception
.getClass().getName(), exception
.getMessage()),
100 2, 6, "ttext", false);
102 ArrayList
<String
> stackTraceStrings
= new ArrayList
<String
>();
103 StackTraceElement
[] stack
= exception
.getStackTrace();
104 for (int i
= 0; i
< stack
.length
; i
++) {
105 stackTraceStrings
.add(stack
[i
].toString());
107 stackTrace
= addList(stackTraceStrings
, 2, 7, getWidth() - 6, 8);
110 addButton(i18n
.getString("saveButton"), 19, getHeight() - 4,
117 TButton closeButton
= addButton(i18n
.getString("closeButton"),
121 // Don't do anything, just close the window.
122 TExceptionDialog
.this.close();
126 // Save this for last: make the close button default action.
127 activate(closeButton
);
130 // ------------------------------------------------------------------------
131 // TWindow ----------------------------------------------------------------
132 // ------------------------------------------------------------------------
135 * Draw the exception message background.
139 // Draw window and border.
142 CellAttributes boxColor
= getTheme().getColor("ttext");
143 hLineXY(3, 7, getWidth() - 6, ' ', boxColor
);
146 // ------------------------------------------------------------------------
147 // TExceptionDialog -------------------------------------------------------
148 // ------------------------------------------------------------------------
151 * Save a troubleshooting report to file. Note that we do NOT translate
152 * the strings within the error report.
154 private void saveToFile() {
155 // Prompt for filename.
156 PrintWriter writer
= null;
158 String filename
= fileSaveBox(".");
159 if (filename
== null) {
160 // User cancelled, bail out.
163 writer
= new PrintWriter(new FileWriter(filename
));
164 writer
.write("Date: " + new Date(System
.currentTimeMillis())
168 writer
.write("System properties:\n");
169 writer
.write("-----------------------------------\n");
170 System
.getProperties().store(writer
, null);
171 writer
.write("-----------------------------------\n");
174 // The exception we caught
175 writer
.write("Caught exception:\n");
176 writer
.write("-----------------------------------\n");
177 exception
.printStackTrace(writer
);
178 writer
.write("-----------------------------------\n");
180 // The exception's cause, if it was set
181 if (exception
.getCause() != null) {
182 writer
.write("Caught exception's cause:\n");
183 writer
.write("-----------------------------------\n");
184 exception
.getCause().printStackTrace(writer
);
185 writer
.write("-----------------------------------\n");
189 // The UI stack trace
190 writer
.write("UI stack trace:\n");
191 writer
.write("-----------------------------------\n");
192 (new Throwable("UI Thread")).printStackTrace(writer
);
193 writer
.write("-----------------------------------\n");
196 } catch (IOException e
) {
197 messageBox(i18n
.getString("errorDialogTitle"),
198 MessageFormat
.format(i18n
.
199 getString("errorSavingFile"), e
.getMessage()));
201 if (writer
!= null) {