11package edu .wpi .grip .ui ;
22
33import com .google .common .base .Throwables ;
4- import com .google .common .net .UrlEscapers ;
54import javafx .application .HostServices ;
65import javafx .application .Platform ;
76import javafx .event .ActionEvent ;
1110import javafx .scene .input .Clipboard ;
1211import javafx .scene .input .ClipboardContent ;
1312import javafx .scene .layout .GridPane ;
13+ import javafx .scene .layout .Priority ;
1414
1515import static com .google .common .base .Preconditions .checkNotNull ;
1616
2020 * Also, provides links with quick access to the githup issue page.
2121 */
2222public final class ExceptionAlert extends Alert {
23- private static final String
24- PROJECT_ISSUE_LINK = "https://github.com/WPIRoboticsProjects/GRIP/issues/new" ,
25- ISSUE_PROMPT_QUESTION = "What were the actions performed prior to this error appearing?" ,
26- ISSUE_PROMPT_TEXT = "An exception occurred! Please open an issue on the project GitHub.\n "
27- + "We value your feedback and want to hear about the problems you encounter." ;
28-
29- private static final String systemOptions [] = {
30- "javafx.version" ,
31- "java.runtime.name" ,
32- "java.vm.version" ,
33- "java.vm.vendor" ,
34- "java.vm.name" ,
35- "java.runtime.version" ,
36- "java.awt.graphicsenv" ,
37- "javafx.runtime.version" ,
38- "os.name" ,
39- "os.version" ,
40- "os.arch" ,
41- "file.encoding" ,
42- "java.vm.info" ,
43- "java.version" ,
44- "sun.arch.data.model" ,
45- "sun.cpu.endian"
23+ private static final String PROJECT_ISSUE_LINK = "https://github.com/WPIRoboticsProjects/GRIP/issues/new?body=Ple" +
24+ "ase%20describe%20what%20actions%20we%20can%20take%20to%20reproduce%20the%20bug%20you%20found%2C%20includ" +
25+ "ing%20the%20error%20message." ;
26+
27+ private static final String ISSUE_PROMPT_TEXT = "An exception occurred! Please open an issue on the project " +
28+ "GitHub.\n We value your feedback and want to hear about the problems you encounter." ;
29+
30+ private static final String systemProperties [] = {
31+ "java.version" , "javafx.version" , "os.name" , "os.version" , "os.arch" ,
4632 };
4733
48- private final String exceptionMessage ;
49- private final String systemInfoMessage ;
50- private final String additionalInfoMessage ;
51- private final String message ;
52- private final Throwable initialCause ;
34+ private static final ButtonType COPY = new ButtonType ("Copy to Clipboard" );
35+ private static final ButtonType REPORT = new ButtonType ("Report Issue" );
5336
54- private final ButtonType openGitHubIssuesBtnType = new ButtonType ("Open GitHub Issues" );
55- private final ButtonType copyToClipboardBtnType = new ButtonType ("Copy To Clipboard" );
5637 private final Node initialFocusElement ;
5738
5839 /**
@@ -65,77 +46,63 @@ public ExceptionAlert(final Parent root, final Throwable throwable, final String
6546 super (AlertType .ERROR );
6647 checkNotNull (root , "The parent can not be null" );
6748 checkNotNull (throwable , "The Throwable can not be null" );
68- this .message = checkNotNull (message , "The message can not be null" );
6949 checkNotNull (services , "HostServices can not be null" );
7050
7151 final ButtonType closeBtnType = new ButtonType (isFatal ? "Quit" : "Cancel" , ButtonBar .ButtonData .CANCEL_CLOSE );
7252
73- this .exceptionMessage = generateExceptionMessage (throwable );
74- this .systemInfoMessage = generateSystemInfoMessage ();
75- this .additionalInfoMessage = generateAdditionalInfoMessage ();
76- this .initialCause = getInitialCause (throwable );
53+ String exceptionMessage = generateExceptionMessage (throwable );
54+ String systemInfoMessage = generateSystemInfoMessage ();
7755
78- this .setTitle (initialCause .getClass ().getSimpleName ());
56+ this .setTitle (getInitialCause ( throwable ) .getClass ().getSimpleName ());
7957 this .setHeaderText ((isFatal ? "FATAL: " : "" ) + message );
8058
8159 // Set stylesheet
8260 this .getDialogPane ().styleProperty ().bind (root .styleProperty ());
8361 this .getDialogPane ().getStylesheets ().addAll (root .getStylesheets ());
8462
63+ this .setResizable (true );
64+
8565 // Add two additional buttons
86- this .getButtonTypes ().removeIf ((buttonType ) -> buttonType .equals (ButtonType .OK ));
87- this .getButtonTypes ().addAll (openGitHubIssuesBtnType , copyToClipboardBtnType , closeBtnType );
66+ this .getButtonTypes ().setAll (COPY , closeBtnType , REPORT );
8867
8968
9069 final GridPane dialogContent = new GridPane ();
70+ dialogContent .getStyleClass ().add ("exception-pane" );
9171 dialogContent .setMaxWidth (Double .MAX_VALUE );
9272 dialogContent .setMaxHeight (Double .MAX_VALUE );
9373
9474
9575 final Label issuePasteLabel = new Label (ISSUE_PROMPT_TEXT );
9676 issuePasteLabel .setWrapText (true );
9777
98- final TextArea issueText = new TextArea (Throwables .getStackTraceAsString (throwable ));
78+ final TextArea issueText = new TextArea (message + "\n " + exceptionMessage + "\n " + systemInfoMessage );
79+ issueText .getStyleClass ().add ("exception-text" );
9980 issuePasteLabel .setLabelFor (issueText );
10081 issueText .setEditable (false );
101- issueText .setWrapText (true );
10282
10383 issueText .setMaxWidth (Double .MAX_VALUE );
10484 issueText .setMaxHeight (Double .MAX_VALUE );
10585
10686 dialogContent .add (issuePasteLabel , 0 , 0 );
10787 dialogContent .add (issueText , 0 , 1 );
88+ GridPane .setHgrow (issueText , Priority .ALWAYS );
89+ GridPane .setVgrow (issueText , Priority .ALWAYS );
10890 this .getDialogPane ().setContent (dialogContent );
10991
110-
111- // Prevent these two buttons from causing the alert to close
112- final Button copyToClipboardBtn = (Button ) this .getDialogPane ().lookupButton (copyToClipboardBtnType );
113- copyToClipboardBtn .addEventFilter (ActionEvent .ACTION , event -> {
92+ final Button copyBtn = (Button ) this .getDialogPane ().lookupButton (COPY );
93+ copyBtn .addEventFilter (ActionEvent .ACTION , event -> {
11494 final ClipboardContent content = new ClipboardContent ();
115- content .putString (issueText ());
95+ content .putString (issueText . getText ());
11696 Clipboard .getSystemClipboard ().setContent (content );
117- // Prevent the dialog from closing
118- event .consume ();
97+ issueText .requestFocus ();
98+ issueText .selectAll ();
99+ event .consume (); // Prevent the dialog from closing
119100 });
120101
121-
122- final Button openGitHubIssueBtn = (Button ) this .getDialogPane ().lookupButton (openGitHubIssuesBtnType );
102+ final Button openGitHubIssueBtn = (Button ) this .getDialogPane ().lookupButton (REPORT );
123103 openGitHubIssueBtn .addEventFilter (ActionEvent .ACTION , event -> {
124- final StringBuilder URL_STRING = new StringBuilder (PROJECT_ISSUE_LINK )
125- .append ("?title=" )
126- .append (
127- UrlEscapers .urlFormParameterEscaper ().escape (
128- initialCause .getClass ().getSimpleName () + ": " + initialCause .getMessage ()
129- )
130- ).append ("&body=" )
131- .append (UrlEscapers .urlFormParameterEscaper ().escape (
132- issueText ()
133- ));
134-
135-
136- services .showDocument (URL_STRING .toString ());
137- // Prevent the dialog from closing
138- event .consume ();
104+ services .showDocument (PROJECT_ISSUE_LINK );
105+ event .consume (); // Prevent the dialog from closing
139106 });
140107
141108 // Set the initial focus to the input box so the cursor goes there first
@@ -147,7 +114,7 @@ public ExceptionAlert(final Parent root, final Throwable throwable, final String
147114 * This is not done in the constructor so that the object is not exposed to any other threads from within the objects constructor
148115 */
149116 public final void setInitialFocus () {
150- Platform .runLater (() -> initialFocusElement . requestFocus () );
117+ Platform .runLater (initialFocusElement :: requestFocus );
151118 }
152119
153120 /**
@@ -164,10 +131,6 @@ private Throwable getInitialCause(Throwable throwable) {
164131 }
165132 }
166133
167- private String generateAdditionalInfoMessage () {
168- return "Message: " + message + "\n " ;
169- }
170-
171134 /**
172135 * Takes the throwable and generates the markdown for the exception.
173136 *
@@ -190,25 +153,9 @@ private String generateSystemInfoMessage() {
190153 final StringBuilder systemInfo = new StringBuilder ("## System Info:\n \n " );
191154 systemInfo .append ("Property Name | Property \n ----- | -----\n " );
192155 systemInfo .append ("GRIP Version | " + edu .wpi .grip .core .Main .class .getPackage ().getImplementationVersion () + "\n " );
193- for (String option : systemOptions ) {
156+ for (String option : systemProperties ) {
194157 systemInfo .append (option ).append (" | " ).append (System .getProperty (option )).append ("\n " );
195158 }
196159 return systemInfo .append ("\n " ).toString ();
197160 }
198-
199- /**
200- * Creates the text that gets pasted into the new github issue.
201- *
202- * @return The fully constructed issue text.
203- */
204- private String issueText () {
205- return ISSUE_PROMPT_QUESTION
206- + "\n \n \n \n "
207- + additionalInfoMessage
208- + "\n "
209- + systemInfoMessage
210- + exceptionMessage ;
211- }
212-
213-
214161}
0 commit comments