📄 codepanel.java
字号:
}
}
/**
* Displays the function at the specified index
* in the code window. The index corresponds to the
* position of the function in the original code file,
* with the first function at index position 1. This
* method is thread-safe.
*
* @param index The index position of the function
* to display. If the index is out of
* range, the display remains unchanged.
*/
public void displayFunction( final int index )
{
if( index < 1 || index > m_functions.size() ) return;
Runnable displayFunction =
new Runnable() {
public void run() {
Vector listData =
(Vector)m_functions.elementAt( index - 1 );
m_list.setListData( listData );
m_functionName =
new String( (String)m_functionNames.elementAt( index - 1) );
}
};
try {
if( SwingUtilities.isEventDispatchThread() )
displayFunction.run();
else
SwingUtilities.invokeLater( displayFunction );
}
catch( Exception e ) {
e.printStackTrace();
}
}
/**
* Highlights the specified line of code in the
* code window. This method is thread-safe.
*
* @param lineNum The line number to highlight.
* The first line in the window is line 1.
* If the line number is out of range, the
* display remains unchanged.
*/
public void notifyHighlight( final int lineNum )
{
if( lineNum < 1 || lineNum > m_list.getModel().getSize() ) return;
Runnable highlight =
new Runnable() {
public void run() {
m_list.ensureIndexIsVisible( lineNum - 1 );
m_list.setSelectedIndex( lineNum - 1 );
}
};
try {
if( SwingUtilities.isEventDispatchThread() )
highlight.run();
else
SwingUtilities.invokeLater( highlight );
}
catch( Exception e ) {
e.printStackTrace();
}
}
/**
* Clears the highlighted line in the code window.
* This method is thread-safe.
*/
public void notifyClearHighlight()
{
Runnable clearHighlight =
new Runnable() {
public void run() {
m_list.getSelectionModel().clearSelection();
}
};
try {
if( SwingUtilities.isEventDispatchThread() )
clearHighlight.run();
else
SwingUtilities.invokeLater( clearHighlight );
}
catch( Exception e ) {
e.printStackTrace();
}
}
// Private methods
/**
* Builds and arranges the various GUI components
* for this panel.
*/
private void buildPanel()
{
GridBagLayout layout = new GridBagLayout();
setLayout( layout );
GridBagConstraints c = new GridBagConstraints();
// Currently, there is only a single cell inside
// the panel, which holds the scrollable list.
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 1.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
m_list = new JList();
// The list is disabled, so the user can't manually
// highlight lines of code.
m_list.setEnabled( false );
// Fix the cell height, so that lines of
// pseudocode are spaced as closely as possible.
m_list.setFixedCellHeight( ROW_HEIGHT );
JScrollPane scrollPane = new JScrollPane( m_list );
scrollPane.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
scrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
layout.setConstraints( scrollPane, c );
add( scrollPane );
}
/**
* Parses the lines contained in the 'lines' Vector,
* extracting and assembling the various functions.
*
* @throws InvalidCodeFileException If the code file
* contains a syntax error.
*/
private void parseLines( Vector lines )
throws InvalidCodeFileException
{
m_functions = new Vector();
m_functionNames = new Vector();
while( true ) {
// Find the start of a function.
String text = null;
if( lines.size() == 0 ) return;
while( lines.size() != 0 ) {
text = (String)lines.remove( 0 );
if( text.indexOf( FUNCTION_START ) != -1 ) break;
if( lines.size() == 0 ) return;
}
// Extract the name of the function and
// store it.
text = extractFunctionName( text );
// Extract the lines of this function.
extractFunctionLines( text, lines );
}
}
/**
* Extract the name of a function from a 'function'
* tag contained in the supplied line of text.
*
* @return The remainder of the line, after the
* 'function' tag has been removed, or null
* if the line is empty after the tag.
*
* @throws InvalidCodeFileException If a function
* name cannot be extracted.
*/
private String extractFunctionName( String line )
throws InvalidCodeFileException
{
// Ignore the start of the line.
String parsedLine;
int functionStart =
line.indexOf( FUNCTION_START ) + FUNCTION_START.length();
try {
parsedLine = line.substring( functionStart );
}
catch( IndexOutOfBoundsException e ) {
throw new
InvalidCodeFileException( "Missing 'name' " +
"parameter after function tag start." );
}
int nameStart;
// Grab the function name.
if( (nameStart = parsedLine.indexOf( NAME_START ) ) != -1 ) {
nameStart += NAME_START.length();
int nameEnd = parsedLine.indexOf( NAME_END );
if( nameEnd > nameStart ) {
// Extract name.
m_functionNames.add( parsedLine.substring( nameStart, nameEnd ) );
if( parsedLine.length() > (nameEnd + NAME_END.length()) )
return parsedLine.substring( nameEnd + NAME_END.length() );
else
return null;
}
else {
throw new
InvalidCodeFileException( "Function name " +
"missing or tag malformed." );
}
}
else {
throw new
InvalidCodeFileException( "Function name " +
"missing or tag malformed." );
}
}
/**
* Extract the lines of text that form the function
* body.
*
* @param text A String containing any text remaining
* from previous parsing.
*
* @param lines Remaining lines of code text.
*
* @throws InvalidCodeFileException If the pseudo-code
* file contains a syntax error.
*
*/
private void extractFunctionLines( String text, Vector lines )
throws InvalidCodeFileException
{
StringBuffer codeLine = new StringBuffer( HTML_LINE_HEADER );
String currLine = null;
Vector function = new Vector();
if( text != null )
currLine = new String( text );
else
currLine = new String();
while( true ) {
while( !currLine.endsWith( "." ) ) {
if( currLine.length() > 0 )
codeLine.append( currLine );
if( lines.size() == 0 )
throw new
InvalidCodeFileException( "Missing " +
"line terminator and closing function tag." );
currLine = ((String)lines.remove( 0 )).trim();
}
// Strip the period off the end of the line.
codeLine.append( currLine.substring( 0, currLine.length() - 1 ) );
// Grabbed one complete line.
String newLine = modifyTabs( codeLine ) + HTML_LINE_TERMINATOR;
function.add( newLine );
codeLine = new StringBuffer( HTML_LINE_HEADER );
if( lines.size() == 0 )
throw new
InvalidCodeFileException( "Missing closing function tag." );
currLine = (String)lines.remove( 0 );
if( currLine.trim().endsWith( FUNCTION_END ) ) {
m_functions.add( function );
return;
}
}
}
/**
* Performs a search and replace, removing all the tab
* markers on a line and replacing them with their
* HTML equivalent.
*
* @return A String with all tab markers converted
* to HTML 'non-breaking' spaces.
*/
private String modifyTabs( StringBuffer text )
{
while( true ) {
String line = text.toString();
int pos;
if( (pos = line.indexOf( TAB_MARKER )) == - 1 ) return text.toString();
text.replace( pos, pos + TAB_MARKER.length(), TAB );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -