editor.GosuEditorFeedbackPanel Maven / Gradle / Ivy
/*
*
* Copyright 2010 Guidewire Software, Inc.
*
*/
package editor;
import editor.util.HTMLEscapeUtil;
import gw.lang.parser.IParseIssue;
import gw.lang.parser.exceptions.ParseException;
import gw.lang.parser.exceptions.ParseResultsException;
import gw.lang.parser.exceptions.ParseWarning;
import gw.lang.reflect.IType;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
/**
* Displays gosu parser error feedback within a GosuEditor.
*/
public class GosuEditorFeedbackPanel extends JPanel
{
private static final Color COLOR_ERROR = Color.RED;
private static final Color COLOR_ERROR_SHADOW = new Color( 128, 0, 0 );
private static final Color COLOR_WARNING = Color.YELLOW;
private static final Color COLOR_WARNING_SHADOW = new Color( 128, 128, 0 );
private JLabel _icon;
private FeedbackMargin _feedback;
private GosuEditor _editor;
public GosuEditorFeedbackPanel()
{
configureUI();
}
/**
* Updates this panel with current parser feedback.
*
* @param iResCode The parse result code. One of:
*
* - GosuEditor.RESCODE_VALID
*
- GosuEditor.RESCODE_WARNINGS
*
- GosuEditor.RESCODE_ERRORS
*
* @param editor The Gosu editor
*/
public void update( int iResCode, GosuEditor editor )
{
_icon.setIcon( loadIcon( iResCode ) );
_editor = editor;
_feedback.repaint();
repaint();
editor.repaint();
}
void configureUI()
{
setLayout( new BorderLayout() );
setBackground( editor.util.EditorUtilities.CONTROL );
setBorder( null );
_icon = new JLabel();
_icon.setBorder( BorderFactory.createEmptyBorder( 1, 1, 1, 1 ) );
add( _icon, BorderLayout.NORTH );
_feedback = new FeedbackMargin();
ToolTipManager.sharedInstance().registerComponent( _feedback );
add( _feedback, BorderLayout.CENTER );
}
protected Icon loadIcon( int iResCode )
{
switch( iResCode )
{
case GosuEditor.RESCODE_VALID:
return editor.util.EditorUtilities.loadIcon( "images/rule_green.gif" );
case GosuEditor.RESCODE_WARNINGS:
return editor.util.EditorUtilities.loadIcon( "images/rule_yellow.gif" );
case GosuEditor.RESCODE_PENDING:
return editor.util.EditorUtilities.loadIcon( "images/status_anim.gif" );
default:
return editor.util.EditorUtilities.loadIcon( "images/rule_red.gif" );
}
}
private class FeedbackMargin extends JPanel
{
private Point _iMousePos;
FeedbackMargin()
{
ErrorMarkMouseHandler errorMarkMouser = new ErrorMarkMouseHandler();
addMouseMotionListener( errorMarkMouser );
addMouseListener( errorMarkMouser );
}
@Override
public void paintComponent( Graphics g )
{
super.paintComponent( g );
if( _editor == null )
{
return;
}
ParseResultsException pe = _editor.getParseResultsException();
if( pe == null )
{
return;
}
int iLineCount = getLineCount();
List pws = pe.getParseWarnings();
for( int i = 0; i < pws.size(); i++ )
{
ParseWarning w = (ParseWarning)pws.get( i );
paintWarningMark( g, w, iLineCount );
}
List pes = pe.getParseExceptions();
for( int i = 0; i < pes.size(); i++ )
{
ParseException e = (ParseException)pes.get( i );
paintErrorMark( g, e, iLineCount );
}
}
private void paintWarningMark( Graphics g, ParseWarning w, int iLineCount )
{
int iMark = getMarkForIssue( w, iLineCount );
g.setColor( COLOR_WARNING );
g.fillRect( 1, iMark - 1, getWidth() - 2, 3 );
g.setColor( COLOR_WARNING_SHADOW );
g.drawLine( 2, iMark + 1, getWidth() - 2, iMark + 1 );
g.drawLine( getWidth() - 2, iMark - 1, getWidth() - 2, iMark + 1 );
}
private void paintErrorMark( Graphics g, ParseException e, int iLineCount )
{
int iMark = getMarkForIssue( e, iLineCount );
g.setColor( COLOR_ERROR );
g.fillRect( 1, iMark - 1, getWidth() - 2, 3 );
g.setColor( COLOR_ERROR_SHADOW );
g.drawLine( 2, iMark + 1, getWidth() - 2, iMark + 1 );
g.drawLine( getWidth() - 2, iMark - 1, getWidth() - 2, iMark + 1 );
}
@Override
public String getToolTipText()
{
if( _iMousePos == null )
{
return null;
}
return makeToolTipText( getErrorsFromCursorPos() );
}
private String makeToolTipText( List parseExceptions )
{
if( parseExceptions == null || parseExceptions.isEmpty() )
{
return null;
}
String strFeedback = "";
for( int i = parseExceptions.size() - 1; i >= 0; i-- )
{
if( strFeedback.length() > 0 )
{
strFeedback += "
";
}
else
{
strFeedback = "";
}
IParseIssue pi = (IParseIssue)parseExceptions.get( i );
strFeedback += " " + HTMLEscapeUtil.escape( pi.getUIMessage() );
if( pi instanceof ParseException )
{
ParseException pe = (ParseException)pi;
IType typeExpected = pe.getExpectedType();
if( typeExpected != null )
{
String strTypesExpected = ParseResultsException.getExpectedTypeName( typeExpected );
if( strTypesExpected.length() > 0 )
{
strFeedback += "\n" + "Expected Type" + ":" + strTypesExpected;
}
}
}
}
return strFeedback;
}
private List getErrorsFromCursorPos()
{
if( _editor == null )
{
return null;
}
List matches = new ArrayList();
ParseResultsException pe = _editor.getParseResultsException();
if( pe == null )
{
return matches;
}
int iLineCount = getLineCount();
List pes = pe.getParseIssues();
for( int i = pes.size() - 1; i >= 0; i-- )
{
IParseIssue e = (IParseIssue)pes.get( i );
int iMark = getMarkForIssue( e, iLineCount );
if( iMark >= _iMousePos.y - 3 && iMark <= _iMousePos.y + 3 )
{
matches.add( e );
}
}
return matches;
}
private int getMarkForIssue( IParseIssue e, int iLineCount )
{
iLineCount--;
if( iLineCount == 0 )
{
return getHeight() / 2;
}
int iLine = e.getLine() - 1;
float fOffset = (float)iLine / (float)iLineCount;
return (int)((getHeight() - 10) * fOffset) + 5;
}
public int getLineCount()
{
int iLinesOfCode = _editor.getEditor().getDocument().getDefaultRootElement().getElementCount();
int iViewHeight = _editor.getScroller().getViewport().getHeight();
FontMetrics fm = _editor.getEditor().getFontMetrics( _editor.getEditor().getFont() );
int iLineHeight = fm.getHeight();
int iViewLines = iViewHeight / iLineHeight;
return Math.max( iViewLines, iLinesOfCode );
}
private class ErrorMarkMouseHandler extends MouseAdapter implements MouseMotionListener
{
@Override
public void mouseMoved( MouseEvent e )
{
_iMousePos = e.getPoint();
List errors = getErrorsFromCursorPos();
setCursor( errors == null || errors.isEmpty()
? Cursor.getDefaultCursor()
: Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ) );
}
@Override
public void mouseClicked( MouseEvent e )
{
List errors = getErrorsFromCursorPos();
if( !errors.isEmpty() )
{
_editor.getEditor().requestFocusInWindow();
_editor.setCaretPositionForParseIssue( (IParseIssue)errors.get( 0 ) );
}
}
@Override
public void mouseDragged( MouseEvent e )
{
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy