-
Notifications
You must be signed in to change notification settings - Fork 233
Friendly error messages with expanded content #771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sampottinger
wants to merge
25
commits into
benfry:main
Choose a base branch
from
WillRabalais04:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
1d200f6
Merge branch 'differentiate-offset' into sam-preview
sampottinger c7aea0e
Merge remote-tracking branch 'origin/fix-606-willrabalais' into sam-p…
sampottinger 777d051
New identifier status text.
sampottinger e541663
Merge branch 'main' into friendly-error-messages
sampottinger eddab45
Merge pull request #1 from processing/main
sampottinger 92af6cf
Add line number for friendly error messages.
sampottinger 52eb35a
up to flexmark
WillRabalais04 560bfcd
Merge pull request #2 from WillRabalais04/add-line-number
sampottinger 12e6881
Merge pull request #4 from WillRabalais04/friendly-error-messages
sampottinger 30fa34d
Merge pull request #3 from processing/main
sampottinger 113fc46
Fix JNA jar
sampottinger 5242f97
Update classpath.
sampottinger 75374bd
Add classloader elements for st and flexmark.
sampottinger 1803389
Move friendly error libs to app deps.
sampottinger 0f9685f
stringtemplate draft
WillRabalais04 fd9eb6f
pde.properties updated
WillRabalais04 b5ca737
sam's build file fix
WillRabalais04 bc1f095
excluded compiler errors from using StringTemplate
WillRabalais04 9f3cdcb
formatting tweaks, undoing unintentional changes to CompileErrorMessa…
WillRabalais04 2182b63
removed unnecessary whitespaces on Lanaguage.java
WillRabalais04 f447c6b
removed print statements
WillRabalais04 cd44531
minor formatting + javadoc comments added
WillRabalais04 ab52316
fixed semicolon error
WillRabalais04 9ba4d30
Minor fix on DefaultMessageSimplifier
sampottinger 44b35f6
Respond to @benfry on #771.
sampottinger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,15 +35,30 @@ | |
import java.awt.datatransfer.Clipboard; | ||
import java.awt.datatransfer.StringSelection; | ||
import java.awt.event.*; | ||
import java.awt.BorderLayout; | ||
import java.awt.Desktop; | ||
|
||
import javax.swing.*; | ||
import javax.swing.plaf.basic.BasicSplitPaneDivider; | ||
import javax.swing.plaf.basic.BasicSplitPaneUI; | ||
import javax.swing.JScrollPane; | ||
import javax.swing.event.*; | ||
import javax.swing.border.Border; | ||
|
||
import java.util.regex.Pattern; | ||
import java.util.regex.Matcher; | ||
import java.net.URI; | ||
|
||
import java.io.IOException; | ||
|
||
import processing.app.Platform; | ||
import processing.app.Preferences; | ||
import processing.core.PApplet; | ||
|
||
import com.vladsch.flexmark.html.HtmlRenderer; | ||
import com.vladsch.flexmark.parser.Parser; | ||
import com.vladsch.flexmark.util.ast.Node; | ||
import com.vladsch.flexmark.util.data.MutableDataSet; | ||
|
||
/** | ||
* Panel just below the editing area that contains status messages. | ||
|
@@ -68,6 +83,7 @@ public class EditorStatus extends BasicSplitPaneDivider { | |
|
||
int mode; | ||
String message = ""; | ||
String friendlyMessage = ""; | ||
|
||
int messageRight; | ||
String url; | ||
|
@@ -79,6 +95,8 @@ public class EditorStatus extends BasicSplitPaneDivider { | |
static final int COLLAPSE_PRESSED = 4; | ||
static final int CLIPBOARD_ROLLOVER = 5; | ||
static final int CLIPBOARD_PRESSED = 6; | ||
static final int MORE_INFO_ROLLOVER = 7; | ||
static final int MORE_INFO_PRESSED = 8; | ||
int mouseState; | ||
|
||
Font font; | ||
|
@@ -91,6 +109,8 @@ public class EditorStatus extends BasicSplitPaneDivider { | |
ImageIcon[] searchIcon; | ||
ImageIcon[] collapseIcon; | ||
ImageIcon[] expandIcon; | ||
ImageIcon[] moreInfoIcon; | ||
|
||
|
||
float btnEnabledAlpha; | ||
float btnRolloverAlpha; | ||
|
@@ -108,7 +128,121 @@ public class EditorStatus extends BasicSplitPaneDivider { | |
boolean indeterminate; | ||
Thread thread; | ||
|
||
/** | ||
* The friendly instance variable that determines whether a given error passed in is friendly (has additional information to be shown in a popup). | ||
*/ | ||
public boolean friendly = false; | ||
|
||
|
||
/* | ||
* Popup that shows additional info about the error message that shows up in the status bar. | ||
*/ | ||
|
||
public class FriendlyErrorPopup{ | ||
|
||
private JFrame popupFrame; | ||
final int PROCESSING_SAYS_OFFSET = 6; | ||
|
||
private String markdownToHtml(String target) { | ||
MutableDataSet options = new MutableDataSet(); | ||
Parser parser = Parser.builder(options).build(); | ||
HtmlRenderer renderer = HtmlRenderer.builder(options).build(); | ||
Node document = parser.parse(target); | ||
String html = renderer.render(document); | ||
html = "<div style=\"font-family: Source Code PRO;color:font-size: 13px " + "#0d335a" + ";\"> <br><b>🔵Processing says:</b>" + html + "</div>" ; | ||
return html; | ||
} | ||
|
||
/** | ||
* Constructor for FriendlyErrorPopup class. | ||
* @param messageText a String containing the full message to be simplified. | ||
*/ | ||
public FriendlyErrorPopup(String messageText){ | ||
|
||
int firstLineIndex = messageText.indexOf("<br>"); | ||
int lineCounter = 0; | ||
int newLineCount = 0; | ||
|
||
String firstSentence = messageText.substring(0,firstLineIndex); | ||
String pureText = messageText; | ||
|
||
Pattern newLineCounter = Pattern.compile("<br>"); | ||
Pattern linkSkipper = Pattern.compile("\\[([^\\]]+)\\]\\([^\\)]+\\)"); | ||
Matcher newLineMatcher = newLineCounter.matcher(pureText); | ||
Matcher linkSkipperMatcher = linkSkipper.matcher(pureText); | ||
|
||
// allows for error messages with markdown links in the first line although there currently are none | ||
while (linkSkipperMatcher.find()){ | ||
pureText = pureText.replace(linkSkipperMatcher.group(0),linkSkipperMatcher.group(1)); | ||
} | ||
|
||
firstSentence = pureText.substring(0,pureText.indexOf("<br>")); | ||
firstLineIndex = firstSentence.length(); | ||
|
||
int index = 0; | ||
|
||
while (index < pureText.length()) { | ||
lineCounter++; | ||
int nextBreakIndex = pureText.indexOf("<br>", index); | ||
index = (((nextBreakIndex - index) <= firstLineIndex) && nextBreakIndex != -1) ? nextBreakIndex + 4 : index + firstLineIndex; | ||
} | ||
|
||
pureText = pureText.replaceAll("<br>",""); | ||
messageText = markdownToHtml(messageText); | ||
|
||
JEditorPane errorPane = new JEditorPane(); | ||
errorPane.setContentType("text/html"); | ||
|
||
JScrollPane scrollPane = new JScrollPane(errorPane); | ||
|
||
errorPane.setFont(new Font("Source Code PRO", Font.PLAIN, 13)); //not actually necessary but it allows the window resizing to work | ||
errorPane.setText(messageText); | ||
errorPane.setBackground(Color.decode("#fafcff")); | ||
errorPane.setEditable(false); | ||
|
||
java.awt.FontMetrics fontMetrics = errorPane.getFontMetrics(errorPane.getFont()); | ||
|
||
int popupWidth = fontMetrics.stringWidth(firstSentence) - 25; | ||
int popupHeight = (lineCounter + PROCESSING_SAYS_OFFSET) * fontMetrics.getHeight(); | ||
|
||
errorPane.addHyperlinkListener((event) -> { | ||
HyperlinkEvent.EventType eventType = event.getEventType(); | ||
boolean linkClicked = eventType == HyperlinkEvent.EventType.ACTIVATED; | ||
if (linkClicked) { | ||
String url = event.getURL().toString(); | ||
URI targetUri = URI.create(url); | ||
try { | ||
Desktop.getDesktop().browse(targetUri); | ||
} | ||
catch(IOException e) { | ||
} | ||
} | ||
}); | ||
|
||
JFrame frame = new JFrame("Error Details"); | ||
|
||
Border paddingBorder = BorderFactory.createEmptyBorder(0, 20, 0, 0); | ||
Border border = BorderFactory.createLineBorder(java.awt.Color.decode("#58a2d1"), 10); | ||
Border compoundBorder = BorderFactory.createCompoundBorder(border, paddingBorder); | ||
|
||
errorPane.setBorder(compoundBorder); | ||
scrollPane.setBorder(null); | ||
frame.setSize(popupWidth, popupHeight); | ||
|
||
JPanel containerPanel = new JPanel(new BorderLayout()); | ||
containerPanel.add(scrollPane, BorderLayout.CENTER); | ||
frame.setContentPane(containerPanel); | ||
frame.setVisible(true); | ||
} | ||
} | ||
|
||
/** | ||
* A constructor for the EditorStatus class. It interacts with the BasicSplitPaneUI and Editor objects | ||
* to handle mouse events for opening URLs, copying text to the clipboard, and toggling collapse. | ||
* | ||
* @param ui an instance of the BasicSplitPaneUI class. | ||
* @param editor the editor panel associated with this status. | ||
*/ | ||
public EditorStatus(BasicSplitPaneUI ui, Editor editor) { | ||
super(ui); | ||
this.editor = editor; | ||
|
@@ -222,18 +356,26 @@ void updateMouse(MouseEvent e, boolean pressed) { | |
} else if (url != null && mouseX > LEFT_MARGIN && mouseX < messageRight) { | ||
mouseState = pressed ? URL_PRESSED : URL_ROLLOVER; | ||
} | ||
else if (mouseX > sizeW - (buttonEach * 3) && mouseX < sizeW - (2 * buttonEach)) { | ||
mouseState = pressed ? MORE_INFO_PRESSED : MORE_INFO_ROLLOVER; | ||
} | ||
} | ||
} | ||
|
||
// only change on the rollover, no need to update on press | ||
switch (mouseState) { | ||
case CLIPBOARD_ROLLOVER: | ||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); | ||
break; | ||
case URL_ROLLOVER: | ||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); | ||
break; | ||
case COLLAPSE_ROLLOVER: | ||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); | ||
break; | ||
case MORE_INFO_ROLLOVER: | ||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); | ||
break; | ||
case NONE: | ||
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); | ||
break; | ||
|
@@ -250,7 +392,6 @@ static String findURL(String message) { | |
return null; | ||
} | ||
|
||
|
||
protected void updateTheme() { | ||
urlEnabledAlpha = 255 * Theme.getInteger("status.url.enabled.alpha") / 100; | ||
urlRolloverAlpha = 255 * Theme.getInteger("status.url.rollover.alpha") / 100; | ||
|
@@ -268,6 +409,8 @@ protected void updateTheme() { | |
searchIcon = renderIcons("status/search", stateColors); | ||
collapseIcon = renderIcons("status/console-collapse", stateColors); | ||
expandIcon = renderIcons("status/console-expand", stateColors); | ||
moreInfoIcon = renderIcons("status/more-info", stateColors); | ||
|
||
|
||
btnEnabledAlpha = Theme.getInteger("status.button.enabled.alpha") / 100f; | ||
btnRolloverAlpha = Theme.getInteger("status.button.rollover.alpha") / 100f; | ||
|
@@ -310,12 +453,23 @@ public void empty() { | |
repaint(); | ||
} | ||
|
||
|
||
public void message(String message, int mode) { | ||
this.message = message; | ||
/** | ||
* The message method updates the message and mode instance variables and determines whether the error message being passed in is friendly or not. | ||
* @param message the error message being passed in. | ||
* @param mode represents whether the message is friendly or not. | ||
*/ | ||
public void message(String message, int mode) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Javadoc |
||
|
||
String newMessage = message; | ||
int indexOfNewLine = message.indexOf("<br>"); | ||
if (indexOfNewLine != -1) { | ||
this.friendly = true; | ||
this.friendlyMessage = message; | ||
newMessage = message.substring(0,indexOfNewLine); | ||
} | ||
this.message = newMessage; | ||
this.mode = mode; | ||
|
||
url = findURL(message); | ||
url = findURL(newMessage); | ||
repaint(); | ||
} | ||
|
||
|
@@ -449,9 +603,24 @@ public void paint(Graphics g) { | |
alpha = btnEnabledAlpha; | ||
} | ||
drawButton(g, 0, glyph, alpha); | ||
|
||
// draw more info button | ||
if (friendly) { | ||
ImageIcon glyph2; | ||
glyph2 = moreInfoIcon[mode]; | ||
if (mouseState == MORE_INFO_ROLLOVER) { | ||
alpha = btnRolloverAlpha; | ||
} else if (mouseState == MORE_INFO_PRESSED) { | ||
alpha = btnPressedAlpha; | ||
FriendlyErrorPopup friendlyPopup = new FriendlyErrorPopup(friendlyMessage); | ||
} | ||
else { | ||
alpha = btnEnabledAlpha; | ||
} | ||
drawButton(g,2,moreInfoIcon[mode],alpha); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* @param pos A zero-based button index with 0 as the rightmost button | ||
*/ | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add javadoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Field name should be
friendly
, theisXxxx
syntax is for methods, i.e.:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CC @WillRabalais04, @benfry this has been changed to
friendly
. Thanks!