1 package net.sf.openrocket.gui.dialogs;
3 import java.awt.Desktop;
4 import java.awt.Dialog;
5 import java.awt.Dimension;
6 import java.awt.Window;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.io.IOException;
10 import java.io.PrintWriter;
11 import java.io.StringWriter;
12 import java.io.UnsupportedEncodingException;
14 import java.net.URISyntaxException;
15 import java.net.URLEncoder;
16 import java.util.SortedSet;
17 import java.util.TreeSet;
19 import javax.swing.JButton;
20 import javax.swing.JDialog;
21 import javax.swing.JLabel;
22 import javax.swing.JOptionPane;
23 import javax.swing.JPanel;
24 import javax.swing.JScrollPane;
25 import javax.swing.JTextArea;
27 import net.miginfocom.swing.MigLayout;
28 import net.sf.openrocket.communication.BugReporter;
29 import net.sf.openrocket.gui.components.StyledLabel;
30 import net.sf.openrocket.gui.components.SelectableLabel;
31 import net.sf.openrocket.util.GUIUtil;
32 import net.sf.openrocket.util.JarUtil;
33 import net.sf.openrocket.util.Prefs;
35 public class BugReportDialog extends JDialog {
37 private static final String REPORT_EMAIL = "openrocket-bugs@lists.sourceforge.net";
40 public BugReportDialog(Window parent, String labelText, String message) {
41 super(parent, "Bug report", Dialog.ModalityType.APPLICATION_MODAL);
43 JPanel panel = new JPanel(new MigLayout("fill"));
45 // Some fscking Swing bug that makes html labels initially way too high
46 JLabel label = new JLabel(labelText);
47 Dimension d = label.getPreferredSize();
49 label.setMaximumSize(d);
50 panel.add(label, "gapleft para, wrap para");
52 label = new JLabel("<html>If connected to the Internet, you can simply click " +
53 "<em>Send bug report</em>.");
54 d = label.getPreferredSize();
56 label.setMaximumSize(d);
57 panel.add(label, "gapleft para, wrap");
59 panel.add(new JLabel("Otherwise, send the text below to the address: "),
60 "gapleft para, split 2, gapright rel");
61 panel.add(new SelectableLabel(REPORT_EMAIL), "growx, wrap para");
64 final JTextArea textArea = new JTextArea(message, 20, 70);
65 textArea.setEditable(true);
66 panel.add(new JScrollPane(textArea), "grow, wrap");
69 panel.add(new StyledLabel("The information above may be included in a public " +
70 "bug report. Make sure it does not contain any sensitive information you " +
71 "do not want to be made public.", -1), "wrap para");
76 JButton close = new JButton("Close");
77 close.addActionListener(new ActionListener() {
79 public void actionPerformed(ActionEvent e) {
80 BugReportDialog.this.dispose();
83 panel.add(close, "right, sizegroup buttons, split");
87 // if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Action.MAIL)) {
88 // JButton mail = new JButton("Open email");
89 // mail.setToolTipText("Open email client with the suitable email ready.");
90 // mail.addActionListener(new ActionListener() {
92 // public void actionPerformed(ActionEvent e) {
93 // String text = textArea.getText();
97 // panel.add(mail, "right, sizegroup buttons");
102 JButton send = new JButton("Send bug report");
103 send.setToolTipText("Automatically send the bug report to the OpenRocket developers.");
104 send.addActionListener(new ActionListener() {
106 public void actionPerformed(ActionEvent e) {
107 String text = textArea.getText();
110 BugReporter.sendBugReport(text);
112 // Success if we came here
113 JOptionPane.showMessageDialog(BugReportDialog.this,
114 new Object[] { "Bug report successfully sent.",
115 "Thank you for helping make OpenRocket better!" },
116 "Bug report sent", JOptionPane.INFORMATION_MESSAGE);
118 } catch (Exception ex) {
119 // Sending the message failed.
120 JOptionPane.showMessageDialog(BugReportDialog.this,
121 new Object[] { "OpenRocket was unable to send the bug report:",
122 ex.getClass().getSimpleName() + ": " + ex.getMessage(), " ",
123 "Please send the report manually to " + REPORT_EMAIL },
124 "Error sending report", JOptionPane.ERROR_MESSAGE);
128 panel.add(send, "right, sizegroup buttons");
135 this.setLocationRelativeTo(parent);
137 GUIUtil.setDisposableDialogOptions(this, send);
143 * Show a general bug report dialog allowing the user to input information about
144 * the bug they encountered.
146 * @param parent the parent window (may be null).
148 public static void showBugReportDialog(Window parent) {
150 StringBuilder sb = new StringBuilder();
152 sb.append("---------- Bug report ----------\n");
154 sb.append("Include detailed steps on how to trigger the bug:\n");
161 sb.append("What does the software do and what in your opinion should it do in the " +
162 "case described above:\n");
167 sb.append("Include your email address (optional; it helps if we can " +
168 "contact you in case we need additional information):\n");
174 sb.append("(Do not modify anything below this line.)\n");
175 sb.append("---------- System information ----------\n");
176 addSystemInformation(sb);
177 sb.append("---------- End of information ----------\n");
180 BugReportDialog reportDialog =
181 new BugReportDialog(parent,
182 "<html>You can report a bug in OpenRocket by filling in and submitting " +
183 "the form below.<br>" +
184 "You can also report bugs and include attachments on the project " +
185 "web site.", sb.toString());
186 reportDialog.setVisible(true);
191 * Show a dialog presented when an uncaught exception occurs.
193 * @param parent the parent window (may be null).
194 * @param t the thread that encountered the exception (may be null).
195 * @param e the exception.
197 public static void showExceptionDialog(Window parent, Thread t, Throwable e) {
199 StringBuilder sb = new StringBuilder();
201 sb.append("---------- Bug report ----------\n");
203 sb.append("Please include a description about what actions you were " +
204 "performing when the exception occurred:\n");
211 sb.append("Include your email address (optional; it helps if we can " +
212 "contact you in case we need additional information):\n");
218 sb.append("(Do not modify anything below this line.)\n");
219 sb.append("---------- Exception stack trace ----------\n");
220 StringWriter sw = new StringWriter();
221 PrintWriter pw = new PrintWriter(sw);
222 e.printStackTrace(pw);
223 sb.append(sw.getBuffer());
227 sb.append("---------- Thread information ----------\n");
229 sb.append("Thread is not specified.");
236 sb.append("---------- System information ----------\n");
237 addSystemInformation(sb);
238 sb.append("---------- End of information ----------\n");
241 BugReportDialog reportDialog =
242 new BugReportDialog(parent, "Please include a short description about " +
243 "what you were doing when the exception occurred.", sb.toString());
244 reportDialog.setVisible(true);
248 private static void addSystemInformation(StringBuilder sb) {
249 sb.append("OpenRocket version: " + Prefs.getVersion() + "\n");
250 sb.append("OpenRocket source: " + Prefs.getBuildSource() + "\n");
251 sb.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
252 sb.append("System properties:\n");
255 SortedSet<String> keys = new TreeSet<String>();
256 for (Object key: System.getProperties().keySet()) {
257 keys.add((String)key);
260 for (String key: keys) {
261 String value = System.getProperty(key);
262 sb.append(" " + key + "=");
263 if (key.equals("line.separator")) {
264 for (char c: value.toCharArray()) {
265 sb.append(String.format("\\u%04x", (int)c));
277 * Open the default email client with the suitable bug report.
278 * Note that this does not work on some systems even if Desktop.isSupported()
281 * @param text the bug report text.
282 * @return whether opening the client succeeded.
284 private boolean openEmail(String text) {
288 text = URLEncoder.encode(text, "UTF-8");
289 version = URLEncoder.encode(Prefs.getVersion(), "UTF-8");
290 } catch (UnsupportedEncodingException e) {
291 throw new RuntimeException(e);
296 String mailto = "mailto:" + REPORT_EMAIL
297 + "?subject=Bug%20report%20for%20OpenRocket%20" + version
301 uri = new URI(mailto);
302 } catch (URISyntaxException e) {
307 Desktop desktop = Desktop.getDesktop();
310 } catch (IOException e) {