Fixes and updates

This commit is contained in:
Nico committed 2021-03-07 15:22:55 +01:00
1 parent d1710ea6a5
commit fb4da77359
211 files changed
+45363 -45571

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@
<baseFont size="12"/>
<!-- General editor colors. -->
<background color="ffffff"/>
<background color="c0c0c0"/>
<caret color="000000"/>
<selection bg="dddddd" fg="000000"/>
<currentLineHighlight color="dddddd" fade="false"/>
+3 -3
View File
@@ -12,10 +12,10 @@
<baseFont size="12"/>
<!-- General editor colors. -->
<background color="000000"/>
<background color="2f2f2f"/>
<caret color="eeeeee"/>
<selection bg="222222" fg="eeeeee"/>
<currentLineHighlight color="222222" fade="false"/>
<selection bg="111111" fg="eeeeee"/>
<currentLineHighlight color="111111" fade="false"/>
<marginLine fg="4f4b46"/>
<markAllHighlight color="947e76"/> <!-- TODO: Fix me -->
<markOccurrencesHighlight color="2b2b2b" border="false"/>
+38 -46
View File
@@ -20,7 +20,7 @@ import javax.swing.text.Segment;
* @version 1.0
*/
public class DocumentReader extends Reader {
/**
* The stream's position in the document.
*/
@@ -37,12 +37,11 @@ public class DocumentReader extends Reader {
* Used for fast character access.
*/
private Segment segment;
/**
* Constructor.
*
* @param document
* The document we're 'reading'.
* @param document The document we're 'reading'.
*/
public DocumentReader(Document document) {
position = 0;
@@ -50,34 +49,34 @@ public class DocumentReader extends Reader {
this.document = document;
this.segment = new Segment();
}
/**
* This currently does nothing...
*/
@Override
public void close() {}
public void close() {
}
/**
* Marks the present position in the stream. Subsequent calls to
* <code>reset()</code> will reposition the stream to this point.
*
* @param readAheadLimit
* Ignored.
* @param readAheadLimit Ignored.
*/
@Override
public void mark(int readAheadLimit) {
mark = position;
}
/**
* Tells whether this reader supports the <code>mark</code> operation.
* This always returns <code>true</code> for <code>DocumentReader</code>.
* Tells whether this reader supports the <code>mark</code> operation. This
* always returns <code>true</code> for <code>DocumentReader</code>.
*/
@Override
public boolean markSupported() {
return true;
}
/**
* Reads the single character at the current position in the document.
*/
@@ -96,31 +95,27 @@ public class DocumentReader extends Reader {
return -1;
}
}
/**
* Read <code>array.length</code> characters from the beginning
* of the document into <code>array</code>.
* Read <code>array.length</code> characters from the beginning of the document
* into <code>array</code>.
*
* @param array
* The array to read characters into.
* @param array The array to read characters into.
* @return The number of characters read.
*/
@Override
public int read(char[] array) {
return read(array, 0, array.length);
}
/**
* Reads characters into a portion of an array.
*
* @param cbuf
* The destination buffer.
* @param off
* Offset at which to start storing characters.
* @param len
* Maximum number of characters to read.
* @return The number of characters read, or <code>-1</code> if the
* end of the stream (document) has been reached.
* @param cbuf The destination buffer.
* @param off Offset at which to start storing characters.
* @param len Maximum number of characters to read.
* @return The number of characters read, or <code>-1</code> if the end of the
* stream (document) has been reached.
*/
@Override
public int read(char[] cbuf, int off, int len) {
@@ -145,24 +140,23 @@ public class DocumentReader extends Reader {
return -1;
}
}
/**
* Tells whether this reader is ready to be read without
* blocking for input. <code>DocumentReader</code> will
* always return true.
* Tells whether this reader is ready to be read without blocking for input.
* <code>DocumentReader</code> will always return true.
*
* @return <code>true</code> if the next read operation will
* return without blocking.
* @return <code>true</code> if the next read operation will return without
* blocking.
*/
@Override
public boolean ready() {
return true;
}
/**
* Resets the stream. If the stream has been marked, then attempt to
* reposition it at the mark. If the stream has not been marked, then
* move it to the beginning of the document.
* Resets the stream. If the stream has been marked, then attempt to reposition
* it at the mark. If the stream has not been marked, then move it to the
* beginning of the document.
*/
@Override
public void reset() {
@@ -173,12 +167,11 @@ public class DocumentReader extends Reader {
mark = -1;
}
}
/**
* Skips characters. This will not 'skip' past the end of the document.
*
* @param n
* The number of characters to skip.
* @param n The number of characters to skip.
* @return The number of characters actually skipped.
*/
@Override
@@ -191,14 +184,13 @@ public class DocumentReader extends Reader {
position = document.getLength();
return document.getLength() - temp;
}
/**
* Move to the specified position in the document. If <code>pos</code>
* is greater than the document's length, the stream's position is moved
* to the end of the document.
* Move to the specified position in the document. If <code>pos</code> is
* greater than the document's length, the stream's position is moved to the end
* of the document.
*
* @param pos
* The position in the document to move to.
* @param pos The position in the document to move to.
*/
public void seek(long pos) {
position = Math.min(pos, document.getLength());
+47 -73
View File
@@ -28,12 +28,11 @@ import java.io.Writer;
* @version 0.7
*/
public class UnicodeWriter extends Writer {
/**
* If this system property evaluates to "<code>false</code>", ignoring
* case, files written out as UTF-8 will not have a BOM written for them.
* Otherwise (even if the property is not set), UTF-8 files will have a
* BOM written.
* If this system property evaluates to "<code>false</code>", ignoring case,
* files written out as UTF-8 will not have a BOM written for them. Otherwise
* (even if the property is not set), UTF-8 files will have a BOM written.
*/
public static final String PROPERTY_WRITE_UTF8_BOM = "UnicodeWriter.writeUtf8BOM";
/**
@@ -45,73 +44,62 @@ public class UnicodeWriter extends Writer {
private static final byte[] UTF16BE_BOM = new byte[] { (byte) 0xFE, (byte) 0xFF };
private static final byte[] UTF32LE_BOM = new byte[] { (byte) 0xFF, (byte) 0xFE, (byte) 0x00, (byte) 0x00 };
private static final byte[] UTF32BE_BOM = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0xFE, (byte) 0xFF };
/**
* This is a utility constructor since the vast majority of the time, this
* class will be used to write Unicode files.
* This is a utility constructor since the vast majority of the time, this class
* will be used to write Unicode files.
*
* @param fileName
* The file to which to write the Unicode output.
* @param encoding
* The encoding to use.
* @throws IOException
* If an IO exception occurs.
* @param fileName The file to which to write the Unicode output.
* @param encoding The encoding to use.
* @throws IOException If an IO exception occurs.
*/
public UnicodeWriter(String fileName, String encoding) throws IOException {
this(new FileOutputStream(fileName), encoding);
}
/**
* This is a utility constructor since the vast majority of the time, this
* class will be used to write Unicode files.
* This is a utility constructor since the vast majority of the time, this class
* will be used to write Unicode files.
*
* @param file
* The file to which to write the Unicode output.
* @param encoding
* The encoding to use.
* @throws IOException
* If an IO exception occurs.
* @param file The file to which to write the Unicode output.
* @param encoding The encoding to use.
* @throws IOException If an IO exception occurs.
*/
public UnicodeWriter(File file, String encoding) throws IOException {
this(new FileOutputStream(file), encoding);
}
/**
* Creates a new writer.
*
* @param out
* The output stream to write.
* @param encoding
* The encoding to use.
* @throws IOException
* If an IO exception occurs.
* @param out The output stream to write.
* @param encoding The encoding to use.
* @throws IOException If an IO exception occurs.
*/
public UnicodeWriter(OutputStream out, String encoding) throws IOException {
init(out, encoding);
}
/**
* Closes this writer.
*
* @throws IOException
* If an IO exception occurs.
* @throws IOException If an IO exception occurs.
*/
@Override
public void close() throws IOException {
internalOut.close();
}
/**
* Flushes the stream.
*
* @throws IOException
* If an IO exception occurs.
* @throws IOException If an IO exception occurs.
*/
@Override
public void flush() throws IOException {
internalOut.flush();
}
/**
* Returns the encoding being used to write this output stream (i.e., the
* encoding of the file).
@@ -121,7 +109,7 @@ public class UnicodeWriter extends Writer {
public String getEncoding() {
return internalOut.getEncoding();
}
/**
* Returns whether UTF-8 files should have a BOM in them when written.
*
@@ -137,17 +125,14 @@ public class UnicodeWriter extends Writer {
}
return true;
}
/**
* Initializes the internal output stream and writes the BOM if the
* specified encoding is a Unicode encoding.
* Initializes the internal output stream and writes the BOM if the specified
* encoding is a Unicode encoding.
*
* @param out
* The output stream we are writing.
* @param encoding
* The encoding in which to write.
* @throws IOException
* If an I/O error occurs while writing a BOM.
* @param out The output stream we are writing.
* @param encoding The encoding in which to write.
* @throws IOException If an I/O error occurs while writing a BOM.
*/
private void init(OutputStream out, String encoding) throws IOException {
internalOut = new OutputStreamWriter(out, encoding);
@@ -169,60 +154,49 @@ public class UnicodeWriter extends Writer {
out.write(UTF32BE_BOM, 0, UTF32BE_BOM.length);
}
}
/**
* Sets whether UTF-8 files should have a BOM written in them.
*
* @param write
* Whether to write a BOM.
* @param write Whether to write a BOM.
* @see #getWriteUtf8BOM()
* @see UnicodeWriter
*/
public static void setWriteUtf8BOM(boolean write) {
System.setProperty(UnicodeWriter.PROPERTY_WRITE_UTF8_BOM, Boolean.toString(write));
}
/**
* Writes a portion of an array of characters.
*
* @param cbuf
* The buffer of characters.
* @param off
* The offset from which to start writing characters.
* @param len
* The number of characters to write.
* @throws IOException
* If an I/O error occurs.
* @param cbuf The buffer of characters.
* @param off The offset from which to start writing characters.
* @param len The number of characters to write.
* @throws IOException If an I/O error occurs.
*/
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
internalOut.write(cbuf, off, len);
}
/**
* Writes a single character.
*
* @param c
* An integer specifying the character to write.
* @throws IOException
* If an IO error occurs.
* @param c An integer specifying the character to write.
* @throws IOException If an IO error occurs.
*/
@Override
public void write(int c) throws IOException {
internalOut.write(c);
}
/**
* Writes a portion of a string.
*
* @param str
* The string from which to write.
* @param off
* The offset from which to start writing characters.
* @param len
* The number of characters to write.
* @throws IOException
* If an IO error occurs.
* @param str The string from which to write.
* @param off The offset from which to start writing characters.
* @param len The number of characters to write.
* @throws IOException If an IO error occurs.
*/
@Override
public void write(String str, int off, int len) throws IOException {
+65 -88
View File
@@ -30,7 +30,7 @@ import javax.swing.text.Utilities;
* @version 1.0
*/
public abstract class RPrintUtilities {
private static int currentDocLineNumber; // The line number in the document
// we are currently on.
private static int numDocLines; // The number of lines in the current
@@ -52,27 +52,21 @@ public abstract class RPrintUtilities {
* The metrics of the font currently being used to print.
*/
private static FontMetrics fm;
/**
* Returns the position closest to, but before, position
* <code>maxCharsPerLine</code> in
* <code>line</code> of one of the chars in <code>breakChars</code>, or
* simply returns
* <code>maxCharsPerLine-1</code> if none of the <code>breakChars</code>
* comes before
* that position. This position represents the logical line break for this
* <code>java.lang.String</code>
* if it is being printed in a monospaced font when lines can only be
* <code>maxCharsPerLine</code>
* characters long.
* <code>maxCharsPerLine</code> in <code>line</code> of one of the chars in
* <code>breakChars</code>, or simply returns <code>maxCharsPerLine-1</code> if
* none of the <code>breakChars</code> comes before that position. This position
* represents the logical line break for this <code>java.lang.String</code> if
* it is being printed in a monospaced font when lines can only be
* <code>maxCharsPerLine</code> characters long.
*
* @param line
* The text being printed.
* @param maxCharsPerLine
* Only up-to this many characters from
* <code>line</code> can be printed on one line.
* @return The logical position at which to stop printing <code>line</code>
* to simulate word wrap.
* @param line The text being printed.
* @param maxCharsPerLine Only up-to this many characters from <code>line</code>
* can be printed on one line.
* @return The logical position at which to stop printing <code>line</code> to
* simulate word wrap.
*/
private static int getLineBreakPoint(String line, final int maxCharsPerLine) {
int breakPoint = -1;
@@ -84,30 +78,23 @@ public abstract class RPrintUtilities {
}
return (breakPoint == -1 ? maxCharsPerLine - 1 : breakPoint);
}
/**
* Prints a <code>Document</code> using a monospaced font, and does no word
* wrapping (ie,
* words will wrap mid-word to the next line). This method is expected to be
* called from
* Printable 'print(Graphics g)' functions.
* wrapping (ie, words will wrap mid-word to the next line). This method is
* expected to be called from Printable 'print(Graphics g)' functions.
*
* @param g
* The graphics context to write to.
* @param doc
* The <code>javax.swing.text.Document</code> to print.
* @param fontSize
* the point size to use for the monospaced font.
* @param pageIndex
* The page number to print.
* @param pageFormat
* The format to print the page with.
* @param tabSize
* The number of spaces to expand tabs to.
* @param g The graphics context to write to.
* @param doc The <code>javax.swing.text.Document</code> to print.
* @param fontSize the point size to use for the monospaced font.
* @param pageIndex The page number to print.
* @param pageFormat The format to print the page with.
* @param tabSize The number of spaces to expand tabs to.
*
* @see #printDocumentMonospacedWordWrap
*/
public static int printDocumentMonospaced(Graphics g, Document doc, int fontSize, int pageIndex, PageFormat pageFormat, int tabSize) {
public static int printDocumentMonospaced(Graphics g, Document doc, int fontSize, int pageIndex,
PageFormat pageFormat, int tabSize) {
g.setColor(Color.BLACK);
g.setFont(new Font("Monospaced", Font.PLAIN, fontSize));
// Initialize our static variables (these are used by our tab expander
@@ -202,29 +189,23 @@ public abstract class RPrintUtilities {
}
return Printable.NO_SUCH_PAGE;
}
/**
* Prints a <code>Document</code> using a monospaced font, word wrapping on
* the characters ' ', '\t', '\n', ',', '.', and ';'. This method is
* expected to be called from Printable 'print(Graphics g)' functions.
* Prints a <code>Document</code> using a monospaced font, word wrapping on the
* characters ' ', '\t', '\n', ',', '.', and ';'. This method is expected to be
* called from Printable 'print(Graphics g)' functions.
*
* @param g
* The graphics context to write to.
* @param doc
* The <code>javax.swing.text.Document</code> to print.
* @param fontSize
* the point size to use for the monospaced font.
* @param pageIndex
* The page number to print.
* @param pageFormat
* The format to print the page with.
* @param tabSize
* The number of spaces to expand tabs to.
* @param g The graphics context to write to.
* @param doc The <code>javax.swing.text.Document</code> to print.
* @param fontSize the point size to use for the monospaced font.
* @param pageIndex The page number to print.
* @param pageFormat The format to print the page with.
* @param tabSize The number of spaces to expand tabs to.
*
* @see #printDocumentMonospaced
*/
public static int printDocumentMonospacedWordWrap(Graphics g, Document doc, int fontSize, int pageIndex, PageFormat pageFormat,
int tabSize) {
public static int printDocumentMonospacedWordWrap(Graphics g, Document doc, int fontSize, int pageIndex,
PageFormat pageFormat, int tabSize) {
g.setColor(Color.BLACK);
g.setFont(new Font("Monospaced", Font.PLAIN, fontSize));
// Initialize our static variables (these are used by our tab expander
@@ -320,30 +301,24 @@ public abstract class RPrintUtilities {
}
return Printable.NO_SUCH_PAGE;
}
/**
* Prints a <code>Document</code> using the specified font, word wrapping
* on the characters ' ', '\t', '\n', ',', '.', and ';'. This method is
* expected to be called from Printable 'print(Graphics g)' functions.
* Prints a <code>Document</code> using the specified font, word wrapping on the
* characters ' ', '\t', '\n', ',', '.', and ';'. This method is expected to be
* called from Printable 'print(Graphics g)' functions.
*
* @param g
* The graphics context to write to.
* @param textComponent
* The <code>javax.swing.text.JTextComponent</code>
* whose text you're printing.
* @param font
* The font to use for printing. If <code>null</code>, then
* <code>textComponent</code>'s font is used.
* @param pageIndex
* The page number to print.
* @param pageFormat
* The format to print the page with.
* @param tabSize
* The number of spaces to convert tabs to.
* @param g The graphics context to write to.
* @param textComponent The <code>javax.swing.text.JTextComponent</code> whose
* text you're printing.
* @param font The font to use for printing. If <code>null</code>, then
* <code>textComponent</code>'s font is used.
* @param pageIndex The page number to print.
* @param pageFormat The format to print the page with.
* @param tabSize The number of spaces to convert tabs to.
*
*/
public static int printDocumentWordWrap(Graphics g, JTextComponent textComponent, Font font, int pageIndex, PageFormat pageFormat,
int tabSize) {
public static int printDocumentWordWrap(Graphics g, JTextComponent textComponent, Font font, int pageIndex,
PageFormat pageFormat, int tabSize) {
// Initialize our graphics object.
g.setColor(Color.BLACK);
g.setFont(font != null ? font : textComponent.getFont());
@@ -389,7 +364,8 @@ public abstract class RPrintUtilities {
// we'd start after the part
// that has already been printed).
try {
doc.getText(currentLineStart + startingOffset, currentLineEnd - (currentLineStart + startingOffset), currentLineSeg);
doc.getText(currentLineStart + startingOffset, currentLineEnd - (currentLineStart + startingOffset),
currentLineSeg);
} catch (BadLocationException ble) {
System.err.println("BadLocationException in print (where there shouldn't be one!): " + ble);
return Printable.NO_SUCH_PAGE;
@@ -452,7 +428,8 @@ public abstract class RPrintUtilities {
System.err.println(ble);
return Printable.NO_SUCH_PAGE;
}
currentLineLengthInPixels = Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0);
currentLineLengthInPixels = Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander,
0);
} while (currentLineLengthInPixels <= lineLengthInPixels);
currentPos--;
}
@@ -460,8 +437,8 @@ public abstract class RPrintUtilities {
doc.getText((currentLineStart + startingOffset), currentPos, currentLineSeg);
} catch (BadLocationException ble) {
System.err.println("BadLocationException in print (a):");
System.err.println("==> currentLineStart: " + currentLineStart + "; startingOffset: " + startingOffset
+ "; currentPos: " + currentPos);
System.err.println("==> currentLineStart: " + currentLineStart + "; startingOffset: "
+ startingOffset + "; currentPos: " + currentPos);
System.err.println("==> Range: " + (currentLineStart + startingOffset) + " - "
+ (currentLineStart + startingOffset + currentPos));
ble.printStackTrace();
@@ -491,12 +468,11 @@ public abstract class RPrintUtilities {
}
return Printable.NO_SUCH_PAGE;
}
/**
* Removes any spaces or tabs from the end of the segment.
*
* @param segment
* The segment from which to remove tailing whitespace.
* @param segment The segment from which to remove tailing whitespace.
* @return <code>segment</code> with trailing whitespace removed.
*/
private static Segment removeEndingWhitespace(Segment segment) {
@@ -510,15 +486,16 @@ public abstract class RPrintUtilities {
String newStringVal = stringVal.substring(0, stringVal.length() - toTrim);
return new Segment(newStringVal.toCharArray(), 0, newStringVal.length());
}
/**
* A tab expander for the document currently being printed with the
* font being used for the printing.
* A tab expander for the document currently being printed with the font being
* used for the printing.
*/
private static class RPrintTabExpander implements TabExpander {
RPrintTabExpander() {}
RPrintTabExpander() {
}
@Override
public float nextTabStop(float x, int tabOffset) {
if (tabSizeInSpaces == 0) {
@@ -17,17 +17,17 @@ import javax.swing.text.JTextComponent;
* lexicographically (ignoring case).
* <p>
*
* This implementation assumes the input text and replacement text are the
* same value. It also returns the input text from its {@link #toString()}
* method (which is what <code>DefaultListCellRenderer</code> uses to render
* objects). Subclasses that wish to override any of this behavior can simply
* override the corresponding method(s) needed to do so.
* This implementation assumes the input text and replacement text are the same
* value. It also returns the input text from its {@link #toString()} method
* (which is what <code>DefaultListCellRenderer</code> uses to render objects).
* Subclasses that wish to override any of this behavior can simply override the
* corresponding method(s) needed to do so.
*
* @author Robert Futrell
* @version 1.0
*/
public abstract class AbstractCompletion implements Completion {
/**
* The provider that created this completion;
*/
@@ -38,35 +38,32 @@ public abstract class AbstractCompletion implements Completion {
private Icon icon;
/**
* The relevance of this completion. Completion instances with higher
* "relevance" values are inserted higher into the list of possible
* completions than those with lower values. Completion instances with
* equal relevance values are sorted alphabetically.
* "relevance" values are inserted higher into the list of possible completions
* than those with lower values. Completion instances with equal relevance
* values are sorted alphabetically.
*/
private int relevance;
/**
* Constructor.
*
* @param provider
* The provider that created this completion.
* @param provider The provider that created this completion.
*/
protected AbstractCompletion(CompletionProvider provider) {
this.provider = provider;
}
/**
* Constructor.
*
* @param provider
* The provider that created this completion.
* @param icon
* The icon for this completion.
* @param provider The provider that created this completion.
* @param icon The icon for this completion.
*/
protected AbstractCompletion(CompletionProvider provider, Icon icon) {
this(provider);
setIcon(icon);
}
/**
* {@inheritDoc}
*/
@@ -79,7 +76,7 @@ public abstract class AbstractCompletion implements Completion {
}
return -1;
}
/**
* {@inheritDoc}
*/
@@ -87,7 +84,7 @@ public abstract class AbstractCompletion implements Completion {
public String getAlreadyEntered(JTextComponent comp) {
return provider.getAlreadyEnteredText(comp);
}
/**
* {@inheritDoc}
*/
@@ -95,10 +92,10 @@ public abstract class AbstractCompletion implements Completion {
public Icon getIcon() {
return icon;
}
/**
* Returns the text the user has to (start) typing for this completion
* to be offered. The default implementation simply returns
* Returns the text the user has to (start) typing for this completion to be
* offered. The default implementation simply returns
* {@link #getReplacementText()}.
*
* @return The text the user has to (start) typing for this completion.
@@ -108,7 +105,7 @@ public abstract class AbstractCompletion implements Completion {
public String getInputText() {
return getReplacementText();
}
/**
* {@inheritDoc}
*/
@@ -116,7 +113,7 @@ public abstract class AbstractCompletion implements Completion {
public CompletionProvider getProvider() {
return provider;
}
/**
* {@inheritDoc}
*/
@@ -124,10 +121,10 @@ public abstract class AbstractCompletion implements Completion {
public int getRelevance() {
return relevance;
}
/**
* The default implementation returns <code>null</code>. Subclasses
* can override this method.
* The default implementation returns <code>null</code>. Subclasses can override
* this method.
*
* @return The tool tip text.
*/
@@ -135,29 +132,27 @@ public abstract class AbstractCompletion implements Completion {
public String getToolTipText() {
return null;
}
/**
* Sets the icon to use for this completion.
*
* @param icon
* The icon to use.
* @param icon The icon to use.
* @see #getIcon()
*/
public void setIcon(Icon icon) {
this.icon = icon;
}
/**
* Sets the relevance of this completion.
*
* @param relevance
* The new relevance of this completion.
* @param relevance The new relevance of this completion.
* @see #getRelevance()
*/
public void setRelevance(int relevance) {
this.relevance = relevance;
}
/**
* Returns a string representation of this completion. The default
* implementation returns {@link #getInputText()}.
@@ -43,14 +43,14 @@ import javax.swing.event.HyperlinkListener;
import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
/**
* The optional "description" window that describes the currently selected
* item in the auto-completion window.
* The optional "description" window that describes the currently selected item
* in the auto-completion window.
*
* @author Robert Futrell
* @version 1.0
*/
class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescWindowCallback {
/**
* The parent AutoCompletion instance.
*/
@@ -89,9 +89,8 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
private int historyPos;
/**
* Provides a slight delay between asking to set a description and actually
* displaying it, so that if the user is scrolling quickly through
* completions, those with slow-to-calculate summaries won't bog down the
* scrolling.
* displaying it, so that if the user is scrolling quickly through completions,
* those with slow-to-calculate summaries won't bog down the scrolling.
*/
private Timer timer;
/**
@@ -103,24 +102,21 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
*/
private ResourceBundle bundle;
/**
* The amount of time to wait after the user changes the selected
* completion to refresh the description. This delay is in place to help
* performance for {@link Completion}s that may be slow to compute their
* summary text.
* The amount of time to wait after the user changes the selected completion to
* refresh the description. This delay is in place to help performance for
* {@link Completion}s that may be slow to compute their summary text.
*/
private static final int INITIAL_TIMER_DELAY = 120;
/**
* The resource bundle name.
*/
private static final String MSG = "org.fife.ui.autocomplete.AutoCompleteDescWindow";
/**
* Constructor.
*
* @param owner
* The parent window.
* @param ac
* The parent auto-completion.
* @param owner The parent window.
* @param ac The parent auto-completion.
*/
public AutoCompleteDescWindow(Window owner, AutoCompletion ac) {
super(owner);
@@ -146,12 +142,12 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
descWindowNavBar.add(new JButton(forwardAction));
bottomPanel = new JPanel(new BorderLayout());
b = new AbstractBorder() {
@Override
public Insets getBorderInsets(Component c) {
return new Insets(1, 0, 0, 0);
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
g.setColor(UIManager.getColor("controlDkShadow"));
@@ -179,19 +175,18 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
timer = new Timer(INITIAL_TIMER_DELAY, timerAction);
timer.setRepeats(false);
}
/**
* Sets the currently displayed description and updates the history.
*
* @param historyItem
* The item to add to the history.
* @param historyItem The item to add to the history.
*/
private void addToHistory(HistoryEntry historyItem) {
history.add(++historyPos, historyItem);
clearHistoryAfterCurrentPos();
setActionStates();
}
/**
* Clears the history of viewed descriptions.
*/
@@ -202,7 +197,7 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
setActionStates();
}
}
/**
* Makes the current history page the last one in the history.
*/
@@ -212,10 +207,10 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
setActionStates();
}
/**
* Copies from the description text area, if it is visible and there is
* a selection.
* Copies from the description text area, if it is visible and there is a
* selection.
*
* @return Whether a copy occurred.
*/
@@ -226,12 +221,11 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
return false;
}
/**
* Returns the localized message for the specified key.
*
* @param key
* The key.
* @param key The key.
* @return The localized message.
*/
private String getString(String key) {
@@ -240,12 +234,11 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
return bundle.getString(key);
}
/**
* Called when a hyperlink is clicked.
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
@@ -261,7 +254,8 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
URL newUrl = redirector.possiblyRedirect(url);
if (newUrl != null && newUrl != url) {
url = newUrl;
e = new HyperlinkEvent(e.getSource(), e.getEventType(), newUrl, e.getDescription(), e.getSourceElement());
e = new HyperlinkEvent(e.getSource(), e.getEventType(), newUrl, e.getDescription(),
e.getSourceElement());
}
}
}
@@ -300,7 +294,7 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
}
}
/**
* Enables or disables the back and forward actions as appropriate.
*/
@@ -323,47 +317,41 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
forwardAction.putValue(Action.SHORT_DESCRIPTION, desc);
}
/**
* Sets the description displayed in this window. This clears the
* history.
* Sets the description displayed in this window. This clears the history.
*
* @param item
* The item whose description you want to display.
* @param item The item whose description you want to display.
*/
public void setDescriptionFor(Completion item) {
setDescriptionFor(item, false);
}
/**
* Sets the description displayed in this window.
*
* @param item
* The item whose description you want to display.
* @param addToHistory
* Whether to add this page to the page history
* (as opposed to clearing it and starting anew).
* @param item The item whose description you want to display.
* @param addToHistory Whether to add this page to the page history (as opposed
* to clearing it and starting anew).
*/
protected void setDescriptionFor(Completion item, boolean addToHistory) {
setDescriptionFor(item, null, addToHistory);
}
/**
* Sets the description displayed in this window.
*
* @param item
* The item whose description you want to display.
* @param item The item whose description you want to display.
* @parma anchor The anchor to jump to, or <code>null</code> if none.
* @param addToHistory
* Whether to add this page to the page history
* (as opposed to clearing it and starting anew).
* @param addToHistory Whether to add this page to the page history (as opposed
* to clearing it and starting anew).
*/
protected void setDescriptionFor(Completion item, String anchor, boolean addToHistory) {
timer.stop();
timerAction.setCompletion(item, anchor, addToHistory);
timer.start();
}
private void setDisplayedDesc(Completion completion, final String anchor, boolean addToHistory) {
String desc = completion == null ? null : completion.getSummary();
if (desc == null) {
@@ -372,7 +360,7 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
descArea.setText(desc);
if (anchor != null) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
descArea.scrollToReference(anchor);
@@ -388,7 +376,7 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
addToHistory(new HistoryEntry(completion, desc, null));
}
/**
* {@inheritDoc}
*/
@@ -399,21 +387,19 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
super.setVisible(visible);
}
/**
* Callback for custom <code>ExternalURLHandler</code>s.
*
* @param completion
* The completion to display.
* @param anchor
* The anchor in the HTML to jump to, or <code>null</code>
* if none.
* @param completion The completion to display.
* @param anchor The anchor in the HTML to jump to, or <code>null</code> if
* none.
*/
@Override
public void showSummaryFor(Completion completion, String anchor) {
setDescriptionFor(completion, anchor, true);
}
/**
* Called by the parent completion popup window the LookAndFeel is updated.
*/
@@ -425,25 +411,25 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
scrollPane.getViewport().setBackground(descArea.getBackground());
((JPanel) getContentPane()).setBorder(TipUtil.getToolTipBorder());
}
/**
* A completion and its cached summary text.
*/
private static class HistoryEntry {
public Completion completion;
public String summary;
public String anchor;
public HistoryEntry(Completion completion, String summary, String anchor) {
this.completion = completion;
this.summary = summary;
this.anchor = anchor;
}
/**
* Overridden to display a short name for the completion, since it's
* used in the tool tips for the "back" and "forward" buttons.
* Overridden to display a short name for the completion, since it's used in the
* tool tips for the "back" and "forward" buttons.
*
* @return A string representation of this history entry.
*/
@@ -452,16 +438,16 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
return completion.getInputText();
}
}
/**
* Action that actually updates the summary text displayed.
*/
private class TimerAction extends AbstractAction {
private Completion completion;
private String anchor;
private boolean addToHistory;
/**
* Called when the timer is fired.
*/
@@ -469,26 +455,26 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
public void actionPerformed(ActionEvent e) {
setDisplayedDesc(completion, anchor, addToHistory);
}
public void setCompletion(Completion c, String anchor, boolean addToHistory) {
this.completion = c;
this.anchor = anchor;
this.addToHistory = addToHistory;
}
}
/**
* Action that moves to the previous description displayed.
*/
class ToolBarBackAction extends AbstractAction {
public ToolBarBackAction(boolean ltr) {
String img = "org/fife/ui/autocomplete/arrow_" + (ltr ? "left.png" : "right.png");
ClassLoader cl = getClass().getClassLoader();
Icon icon = new ImageIcon(cl.getResource(img));
putValue(Action.SMALL_ICON, icon);
}
@Override
public void actionPerformed(ActionEvent e) {
if (historyPos > 0) {
@@ -504,19 +490,19 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener, DescW
}
}
}
/**
* Action that moves to the previous description displayed.
*/
class ToolBarForwardAction extends AbstractAction {
public ToolBarForwardAction(boolean ltr) {
String img = "org/fife/ui/autocomplete/arrow_" + (ltr ? "right.png" : "left.png");
ClassLoader cl = getClass().getClassLoader();
Icon icon = new ImageIcon(cl.getResource(img));
putValue(Action.SMALL_ICON, icon);
}
@Override
public void actionPerformed(ActionEvent e) {
if (history != null && historyPos < history.size() - 1) {
@@ -43,16 +43,15 @@ import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
/**
* The actual popup window of choices. When visible, this window intercepts
* certain keystrokes in the parent text component and uses them to navigate
* the completion choices instead. If Enter or Escape is pressed, the window
* hides itself and notifies the {@link AutoCompletion} to insert the selected
* text.
* certain keystrokes in the parent text component and uses them to navigate the
* completion choices instead. If Enter or Escape is pressed, the window hides
* itself and notifies the {@link AutoCompletion} to insert the selected text.
*
* @author Robert Futrell
* @version 1.0
*/
class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSelectionListener, MouseListener {
/**
* The parent AutoCompletion instance.
*/
@@ -66,27 +65,26 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
*/
private CompletionListModel model;
/**
* A hack to work around the fact that we clear our completion model (and
* our selection) when hiding the completion window. This allows us to
* still know what the user selected after the popup is hidden.
* A hack to work around the fact that we clear our completion model (and our
* selection) when hiding the completion window. This allows us to still know
* what the user selected after the popup is hidden.
*/
private Completion lastSelection;
/**
* Optional popup window containing a description of the currently
* selected completion.
* Optional popup window containing a description of the currently selected
* completion.
*/
private AutoCompleteDescWindow descWindow;
/**
* The preferred size of the optional description window. This field
* only exists because the user may (and usually will) set the size of
* the description window before it exists (it must be parented to a
* Window).
* The preferred size of the optional description window. This field only exists
* because the user may (and usually will) set the size of the description
* window before it exists (it must be parented to a Window).
*/
private Dimension preferredDescWindowSize;
/**
* Whether the completion window and the optional description window
* should be displayed above the current caret position (as opposed to
* underneath it, which is preferred unless there is not enough space).
* Whether the completion window and the optional description window should be
* displayed above the current caret position (as opposed to underneath it,
* which is preferred unless there is not enough space).
*/
private boolean aboveCaret;
private int lastLine;
@@ -103,7 +101,8 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
private KeyActionPair pageUpKap;
private KeyActionPair pageDownKap;
private KeyActionPair ctrlCKap;
private KeyActionPair oldEscape, oldUp, oldDown, oldLeft, oldRight, oldEnter, oldTab, oldHome, oldEnd, oldPageUp, oldPageDown, oldCtrlC;
private KeyActionPair oldEscape, oldUp, oldDown, oldLeft, oldRight, oldEnter, oldTab, oldHome, oldEnd, oldPageUp,
oldPageDown, oldCtrlC;
/**
* The space between the caret and the completion popup.
*/
@@ -112,14 +111,12 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
* The class name of the Substance List UI.
*/
private static final String SUBSTANCE_LIST_UI = "org.pushingpixels.substance.internal.ui.SubstanceListUI";
/**
* Constructor.
*
* @param parent
* The parent window (hosting the text component).
* @param ac
* The auto-completion instance.
* @param parent The parent window (hosting the text component).
* @param ac The auto-completion instance.
*/
public AutoCompletePopupWindow(Window parent, final AutoCompletion ac) {
super(parent);
@@ -131,7 +128,8 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
list.addListSelectionListener(this);
list.addMouseListener(this);
JPanel contentPane = new JPanel(new BorderLayout());
JScrollPane sp = new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JScrollPane sp = new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
// In 1.4, JScrollPane.setCorner() has a bug where it won't accept
// JScrollPane.LOWER_TRAILING_CORNER, even though that constant is
// defined. So we have to put the logic added in 1.5 to handle it
@@ -155,7 +153,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
setFocusableWindowState(false);
lastLine = -1;
}
@Override
public void caretUpdate(CaretEvent e) {
if (isVisible()) { // Should always be true
@@ -170,7 +168,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
Thread.dumpStack();
}
}
/**
* Creates the description window.
*
@@ -186,10 +184,10 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
dw.setSize(size);
return dw;
}
/**
* Creates the mappings from keys to Actions we'll be putting into the
* text component's ActionMap and InputMap.
* Creates the mappings from keys to Actions we'll be putting into the text
* component's ActionMap and InputMap.
*/
private void createKeyActionPairs() {
// Actions we'll install.
@@ -220,11 +218,11 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
oldPageDown = new KeyActionPair();
oldCtrlC = new KeyActionPair();
}
protected void doAutocomplete() {
lastLine = ac.refreshPopupWindow();
}
/**
* Returns the copy keystroke to use for this platform.
*
@@ -235,10 +233,10 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
return KeyStroke.getKeyStroke(key, mask);
}
/**
* Returns the default list cell renderer used when a completion provider
* does not supply its own.
* Returns the default list cell renderer used when a completion provider does
* not supply its own.
*
* @return The default list cell renderer.
* @see #setListCellRenderer(ListCellRenderer)
@@ -247,7 +245,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list.getCellRenderer();
return dcr.getFallbackCellRenderer();
}
/**
* Returns the selected value, or <code>null</code> if nothing is selected.
*
@@ -256,7 +254,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
public Completion getSelection() {
return isShowing() ? (Completion) list.getSelectedValue() : lastSelection;
}
/**
* Inserts the currently selected completion.
*
@@ -266,10 +264,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
Completion comp = getSelection();
ac.insertCompletion(comp);
}
/**
* Registers keyboard actions to listen for in the text component and
* intercept.
* Registers keyboard actions to listen for in the text component and intercept.
*
* @see #uninstallKeyBindings()
*/
@@ -313,30 +310,34 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
comp.addCaretListener(this);
keyBindingsInstalled = true;
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
insertSelectedCompletion();
}
}
@Override
public void mouseEntered(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {}
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
}
/**
* Positions the description window relative to the completion choices
* window. We assume there is room on one side of the other for this
* entire window to fit.
* Positions the description window relative to the completion choices window.
* We assume there is room on one side of the other for this entire window to
* fit.
*/
private void positionDescWindow() {
boolean showDescWindow = descWindow != null && ac.getShowDescWindow();
@@ -372,42 +373,31 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
descWindow.setLocation(x, y);
}
}
/**
* "Puts back" the original key/Action pair for a keystroke. This is used
* when this popup is hidden.
* "Puts back" the original key/Action pair for a keystroke. This is used when
* this popup is hidden.
*
* @param im
* The input map.
* @param am
* The action map.
* @param key
* The keystroke whose key/Action pair to change.
* @param kap
* The (original) key/Action pair.
* @see #replaceAction(InputMap, ActionMap, int, KeyActionPair,
* KeyActionPair)
* @param im The input map.
* @param am The action map.
* @param key The keystroke whose key/Action pair to change.
* @param kap The (original) key/Action pair.
* @see #replaceAction(InputMap, ActionMap, int, KeyActionPair, KeyActionPair)
*/
private void putBackAction(InputMap im, ActionMap am, int key, KeyActionPair kap) {
KeyStroke ks = KeyStroke.getKeyStroke(key, 0);
am.put(im.get(ks), kap.action); // Original action for the "new" key
im.put(ks, kap.key); // Original key for the keystroke.
}
/**
* Replaces a key/Action pair in an InputMap and ActionMap with a new
* pair.
* Replaces a key/Action pair in an InputMap and ActionMap with a new pair.
*
* @param im
* The input map.
* @param am
* The action map.
* @param key
* The keystroke whose information to replace.
* @param kap
* The new key/Action pair for <code>key</code>.
* @param old
* A buffer in which to place the old key/Action pair.
* @param im The input map.
* @param am The action map.
* @param key The keystroke whose information to replace.
* @param kap The new key/Action pair for <code>key</code>.
* @param old A buffer in which to place the old key/Action pair.
* @see #putBackAction(InputMap, ActionMap, int, KeyActionPair)
*/
private void replaceAction(InputMap im, ActionMap am, int key, KeyActionPair kap, KeyActionPair old) {
@@ -417,7 +407,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
old.action = am.get(kap.key);
am.put(kap.key, kap.action);
}
/**
* Selects the first item in the completion list.
*
@@ -429,7 +419,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
list.ensureIndexIsVisible(0);
}
}
/**
* Selects the last item in the completion list.
*
@@ -442,7 +432,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
list.ensureIndexIsVisible(index);
}
}
/**
* Selects the next item in the completion list.
*
@@ -456,10 +446,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
list.ensureIndexIsVisible(index);
}
}
/**
* Selects the completion item one "page down" from the currently selected
* one.
* Selects the completion item one "page down" from the currently selected one.
*
* @see #selectPageUpItem()
*/
@@ -469,10 +458,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
list.setSelectedIndex(i);
list.ensureIndexIsVisible(i);
}
/**
* Selects the completion item one "page up" from the currently selected
* one.
* Selects the completion item one "page up" from the currently selected one.
*
* @see #selectPageDownItem()
*/
@@ -482,7 +470,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
list.setSelectedIndex(i);
list.ensureIndexIsVisible(i);
}
/**
* Selects the previous item in the completion list.
*
@@ -491,40 +479,38 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
private void selectPreviousItem() {
int index = list.getSelectedIndex();
switch (index) {
case 0:
index = list.getModel().getSize() - 1;
break;
case -1: // Check for an empty list (would be an error)
index = list.getModel().getSize() - 1;
if (index == -1) {
return;
}
break;
default:
index = index - 1;
break;
case 0:
index = list.getModel().getSize() - 1;
break;
case -1: // Check for an empty list (would be an error)
index = list.getModel().getSize() - 1;
if (index == -1) {
return;
}
break;
default:
index = index - 1;
break;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
/**
* Sets the completions to display in the choices list. The first
* completion is selected.
* Sets the completions to display in the choices list. The first completion is
* selected.
*
* @param completions
* The completions to display.
* @param completions The completions to display.
*/
public void setCompletions(List<Completion> completions) {
model.setContents(completions);
selectFirstItem();
}
/**
* Sets the size of the description window.
*
* @param size
* The new size. This cannot be <code>null</code>.
* @param size The new size. This cannot be <code>null</code>.
*/
public void setDescriptionWindowSize(Dimension size) {
if (descWindow != null) {
@@ -533,28 +519,26 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
preferredDescWindowSize = size;
}
}
/**
* Sets the default list cell renderer to use when a completion provider
* does not supply its own.
* Sets the default list cell renderer to use when a completion provider does
* not supply its own.
*
* @param renderer
* The renderer to use. If this is <code>null</code>,
* a default renderer is used.
* @param renderer The renderer to use. If this is <code>null</code>, a default
* renderer is used.
* @see #getListCellRenderer()
*/
public void setListCellRenderer(ListCellRenderer renderer) {
DelegatingCellRenderer dcr = (DelegatingCellRenderer) list.getCellRenderer();
dcr.setFallbackCellRenderer(renderer);
}
/**
* Sets the location of this window to be "good" relative to the specified
* rectangle. That rectangle should be the location of the text
* component's caret, in screen coordinates.
* rectangle. That rectangle should be the location of the text component's
* caret, in screen coordinates.
*
* @param r
* The text component's caret position, in screen coordinates.
* @param r The text component's caret position, in screen coordinates.
*/
public void setLocationRelativeTo(Rectangle r) {
// Multi-monitor support - make sure the completion window (and
@@ -596,12 +580,11 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
positionDescWindow();
}
}
/**
* Toggles the visibility of this popup window.
*
* @param visible
* Whether this window should be visible.
* @param visible Whether this window should be visible.
*/
@Override
public void setVisible(boolean visible) {
@@ -649,7 +632,7 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
/**
* Stops intercepting certain keystrokes from the text component.
*
@@ -683,10 +666,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
comp.removeCaretListener(this);
keyBindingsInstalled = false;
}
/**
* Updates the <tt>LookAndFeel</tt> of this window and the description
* window.
* Updates the <tt>LookAndFeel</tt> of this window and the description window.
*/
public void updateUI() {
SwingUtilities.updateComponentTreeUI(this);
@@ -694,12 +676,11 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
descWindow.updateUI();
}
}
/**
* Called when a new item is selected in the popup list.
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void valueChanged(ListSelectionEvent e) {
@@ -711,9 +692,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class CopyAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
boolean doNormalCopy = false;
@@ -725,9 +706,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class DownAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -735,9 +716,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class EndAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -745,9 +726,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class EnterAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -755,9 +736,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class EscapeAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -765,9 +746,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class HomeAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -775,25 +756,26 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
/**
* A mapping from a key (an Object) to an Action.
*/
private static class KeyActionPair {
public Object key;
public Action action;
public KeyActionPair() {}
public KeyActionPair() {
}
public KeyActionPair(Object key, Action a) {
this.key = key;
this.action = a;
}
}
class LeftAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -813,9 +795,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class PageDownAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -823,9 +805,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class PageUpAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -833,16 +815,16 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
/**
* The actual list of completion choices in this popup window.
*/
private class PopupList extends JList {
public PopupList(CompletionListModel model) {
super(model);
}
@Override
public void setUI(ListUI ui) {
if (Util.getUseSubstanceRenderers() && SUBSTANCE_LIST_UI.equals(ui.getClass().getName())) {
@@ -863,9 +845,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
super.setUI(ui);
}
}
class RightAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
@@ -885,9 +867,9 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, ListSele
}
}
}
class UpAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isVisible()) {
File diff suppressed because it is too large. Load diff
@@ -8,34 +8,31 @@ package org.fife.ui.autocomplete;
import java.util.EventObject;
/**
* An event fired by an instance of {@link AutoCompletion}. This can be
* used by applications that wish to be notified of the auto-complete popup
* window showing and hiding.
* An event fired by an instance of {@link AutoCompletion}. This can be used by
* applications that wish to be notified of the auto-complete popup window
* showing and hiding.
*
* @author Robert Futrell
* @version 1.0
*/
public class AutoCompletionEvent extends EventObject {
/**
* The type of this event.
*/
private Type type;
/**
* Constructor.
*
* @param source
* The <code>AutoCompletion</code> instance that fired
* this event.
* @param type
* The event type.
* @param source The <code>AutoCompletion</code> instance that fired this event.
* @param type The event type.
*/
public AutoCompletionEvent(AutoCompletion source, Type type) {
super(source);
this.type = type;
}
/**
* Returns the source <code>AutoCompletion</code> instance. This is just
* shorthand for <code>return (AutoCompletion)getSource();</code>.
@@ -45,7 +42,7 @@ public class AutoCompletionEvent extends EventObject {
public AutoCompletion getAutoCompletion() {
return (AutoCompletion) getSource();
}
/**
* Returns the type of this event.
*
@@ -54,7 +51,7 @@ public class AutoCompletionEvent extends EventObject {
public Type getEventType() {
return type;
}
/**
* Enumeration of the various types of this event.
*/
@@ -15,13 +15,12 @@ import java.util.EventListener;
* @version 1.0
*/
public interface AutoCompletionListener extends EventListener {
/**
* Callback notified when a change to the <code>AutoCompletion</code>'s
* status occurs.
* Callback notified when a change to the <code>AutoCompletion</code>'s status
* occurs.
*
* @param e
* The event.
* @param e The event.
*/
void autoCompleteUpdate(AutoCompletionEvent e);
}
@@ -15,32 +15,32 @@ import java.awt.Color;
* @version 1.0
*/
public class AutoCompletionStyleContext {
/**
* The color used to denote the ending caret position for parameterized
* completions.
*/
private Color parameterizedCompletionCursorPositionColor;
/**
* The color used to highlight copies of editable parameters in
* parameterized completions.
* The color used to highlight copies of editable parameters in parameterized
* completions.
*/
private Color parameterCopyColor;
/**
* The color of the outline highlight used to denote editable parameters
* in parameterized completions.
* The color of the outline highlight used to denote editable parameters in
* parameterized completions.
*/
private Color parameterOutlineColor;
public AutoCompletionStyleContext() {
setParameterOutlineColor(Color.gray);
setParameterCopyColor(new Color(0xb4d7ff));
setParameterizedCompletionCursorPositionColor(new Color(0x00b400));
}
/**
* Returns the color of the highlight painted on copies of editable
* parameters in parameterized completions.
* Returns the color of the highlight painted on copies of editable parameters
* in parameterized completions.
*
* @return The color used.
* @see #setParameterCopyColor(Color)
@@ -48,10 +48,10 @@ public class AutoCompletionStyleContext {
public Color getParameterCopyColor() {
return parameterCopyColor;
}
/**
* Returns the color used to denote the ending caret position for
* parameterized completions.
* Returns the color used to denote the ending caret position for parameterized
* completions.
*
* @return The color used.
* @see #setParameterizedCompletionCursorPositionColor(Color)
@@ -59,10 +59,10 @@ public class AutoCompletionStyleContext {
public Color getParameterizedCompletionCursorPositionColor() {
return parameterizedCompletionCursorPositionColor;
}
/**
* Returns the color of the outline highlight used to denote editable
* parameters in parameterized completions.
* Returns the color of the outline highlight used to denote editable parameters
* in parameterized completions.
*
* @return The color used.
* @see #setParameterOutlineColor(Color)
@@ -70,37 +70,34 @@ public class AutoCompletionStyleContext {
public Color getParameterOutlineColor() {
return parameterOutlineColor;
}
/**
* Sets the color of the highlight painted on copies of editable
* parameters in parameterized completions.
* Sets the color of the highlight painted on copies of editable parameters in
* parameterized completions.
*
* @param color
* The color to use.
* @param color The color to use.
* @see #setParameterCopyColor(Color)
*/
public void setParameterCopyColor(Color color) {
this.parameterCopyColor = color;
}
/**
* Sets the color used to denote the ending caret position for
* parameterized completions.
* Sets the color used to denote the ending caret position for parameterized
* completions.
*
* @param color
* The color to use.
* @param color The color to use.
* @see #getParameterizedCompletionCursorPositionColor()
*/
public void setParameterizedCompletionCursorPositionColor(Color color) {
this.parameterizedCompletionCursorPositionColor = color;
}
/**
* Sets the color of the outline highlight used to denote editable
* parameters in parameterized completions.
* Sets the color of the outline highlight used to denote editable parameters in
* parameterized completions.
*
* @param color
* The color to use.
* @param color The color to use.
* @see #getParameterOutlineColor()
*/
public void setParameterOutlineColor(Color color) {
@@ -7,9 +7,9 @@
package org.fife.ui.autocomplete;
/**
* A straightforward {@link Completion} implementation. This implementation
* can be used if you have a relatively short number of static completions
* with no (or short) summaries.
* A straightforward {@link Completion} implementation. This implementation can
* be used if you have a relatively short number of static completions with no
* (or short) summaries.
* <p>
*
* This implementation uses the replacement text as the input text. It also
@@ -20,53 +20,44 @@ package org.fife.ui.autocomplete;
* @version 1.0
*/
public class BasicCompletion extends AbstractCompletion {
private String replacementText;
private String shortDesc;
private String summary;
/**
* Constructor.
*
* @param provider
* The parent completion provider.
* @param replacementText
* The text to replace.
* @param provider The parent completion provider.
* @param replacementText The text to replace.
*/
public BasicCompletion(CompletionProvider provider, String replacementText) {
this(provider, replacementText, null);
}
/**
* Constructor.
*
* @param provider
* The parent completion provider.
* @param replacementText
* The text to replace.
* @param shortDesc
* A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
* @param provider The parent completion provider.
* @param replacementText The text to replace.
* @param shortDesc A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
*/
public BasicCompletion(CompletionProvider provider, String replacementText, String shortDesc) {
this(provider, replacementText, shortDesc, null);
}
/**
* Constructor.
*
* @param provider
* The parent completion provider.
* @param replacementText
* The text to replace.
* @param shortDesc
* A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
* @param summary
* The summary of this completion. This should be HTML.
* This may be <code>null</code>.
* @param provider The parent completion provider.
* @param replacementText The text to replace.
* @param shortDesc A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
* @param summary The summary of this completion. This should be HTML.
* This may be <code>null</code>.
*/
public BasicCompletion(CompletionProvider provider, String replacementText, String shortDesc, String summary) {
super(provider);
@@ -74,7 +65,7 @@ public class BasicCompletion extends AbstractCompletion {
this.shortDesc = shortDesc;
this.summary = summary;
}
/**
* {@inheritDoc}
*/
@@ -82,10 +73,10 @@ public class BasicCompletion extends AbstractCompletion {
public String getReplacementText() {
return replacementText;
}
/**
* Returns the short description of this completion, usually used in
* the completion choices list.
* Returns the short description of this completion, usually used in the
* completion choices list.
*
* @return The short description, or <code>null</code> if there is none.
* @see #setShortDescription(String)
@@ -93,7 +84,7 @@ public class BasicCompletion extends AbstractCompletion {
public String getShortDescription() {
return shortDesc;
}
/**
* {@inheritDoc}
*/
@@ -101,32 +92,30 @@ public class BasicCompletion extends AbstractCompletion {
public String getSummary() {
return summary;
}
/**
* Sets the short description of this completion.
*
* @param shortDesc
* The short description of this completion.
* @param shortDesc The short description of this completion.
* @see #getShortDescription()
*/
public void setShortDescription(String shortDesc) {
this.shortDesc = shortDesc;
}
/**
* Sets the summary for this completion.
*
* @param summary
* The summary for this completion.
* @param summary The summary for this completion.
* @see #getSummary()
*/
public void setSummary(String summary) {
this.summary = summary;
}
/**
* Returns a string representation of this completion. If the short
* description is not <code>null</code>, this method will return:
* Returns a string representation of this completion. If the short description
* is not <code>null</code>, this method will return:
*
* <code>getInputText() + " - " + shortDesc</code>
*
+51 -59
View File
@@ -10,20 +10,20 @@ import javax.swing.Icon;
import javax.swing.text.JTextComponent;
/**
* Represents a completion choice. A {@link CompletionProvider} returns lists
* of objects implementing this interface. A <tt>Completion</tt> contains the
* Represents a completion choice. A {@link CompletionProvider} returns lists of
* objects implementing this interface. A <tt>Completion</tt> contains the
* following information:
*
* <ul>
* <li>The text the user must (begin to) input for this to be a completion
* choice.
* <li>The text that will be filled in if the user chooses this completion.
* Note that often, this is the same as the text the user must (begin to)
* enter, but this doesn't have to be the case.
* <li>Summary HTML that describes this completion. This is information that
* can be displayed in a helper "tooltip"-style window beside the
* completion list. This may be <code>null</code>. It may also be
* lazily generated to cut down on memory usage.
* <li>The text that will be filled in if the user chooses this completion. Note
* that often, this is the same as the text the user must (begin to) enter, but
* this doesn't have to be the case.
* <li>Summary HTML that describes this completion. This is information that can
* be displayed in a helper "tooltip"-style window beside the completion list.
* This may be <code>null</code>. It may also be lazily generated to cut down on
* memory usage.
* <li>The <tt>CompletionProvider</tt> that returned this completion.
* <li>Tool tip text that can be displayed when a mouse hovers over this
* completion in a text component.
@@ -34,112 +34,104 @@ import javax.swing.text.JTextComponent;
* @see AbstractCompletion
*/
public interface Completion extends Comparable<Completion> {
/**
* Compares this completion to another one lexicographically, ignoring
* case.
* Compares this completion to another one lexicographically, ignoring case.
*
* @param other
* Another completion instance.
* @param other Another completion instance.
* @return How this completion compares to the other one.
*/
@Override
public int compareTo(Completion other);
/**
* Returns the portion of this completion that has already been entered
* into the text component. The match is case-insensitive.
* Returns the portion of this completion that has already been entered into the
* text component. The match is case-insensitive.
* <p>
*
* This is a convenience method for:
* <code>getProvider().getAlreadyEnteredText(comp)</code>.
*
* @param comp
* The text component.
* @param comp The text component.
* @return The already-entered portion of this completion.
*/
public String getAlreadyEntered(JTextComponent comp);
/**
* Returns the icon to use for this completion.
*
* @return The icon, or <code>null</code> for none.
*/
public Icon getIcon();
/**
* Returns the text that the user has to (start) typing for this completion
* to be offered. Note that this will usually be the same value as
* {@link #getReplacementText()}, but not always (a completion could be
* a way to implement shorthand, for example, "<code>sysout</code>" mapping
* to "<code>System.out.println(</code>").
* Returns the text that the user has to (start) typing for this completion to
* be offered. Note that this will usually be the same value as
* {@link #getReplacementText()}, but not always (a completion could be a way to
* implement shorthand, for example, "<code>sysout</code>" mapping to
* "<code>System.out.println(</code>").
*
* @return The text the user has to (start) typing for this completion to
* be offered.
* @return The text the user has to (start) typing for this completion to be
* offered.
* @see #getReplacementText()
*/
public String getInputText();
/**
* Returns the provider that returned this completion.
*
* @return The provider.
*/
public CompletionProvider getProvider();
/**
* Returns the "relevance" of this completion. This is used when sorting
* completions by their relevance. It is an abstract concept that may
* mean different things to different languages, and may depend on the
* context of the completion.
* completions by their relevance. It is an abstract concept that may mean
* different things to different languages, and may depend on the context of the
* completion.
* <p>
*
* By default, all completions have a relevance of <code>0</code>. The
* higher the value returned by this method, the higher up in the list
* this completion will be; the lower the value returned, the lower it will
* be. <code>Completion</code>s with equal relevance values will be
* sorted alphabetically.
* By default, all completions have a relevance of <code>0</code>. The higher
* the value returned by this method, the higher up in the list this completion
* will be; the lower the value returned, the lower it will be.
* <code>Completion</code>s with equal relevance values will be sorted
* alphabetically.
*
* @return The relevance of this completion.
*/
public int getRelevance();
/**
* Returns the text to insert as the result of this auto-completion. This
* is the "complete" text, including any text that replaces what the user
* has already typed.
* Returns the text to insert as the result of this auto-completion. This is the
* "complete" text, including any text that replaces what the user has already
* typed.
*
* @return The replacement text.
* @see #getInputText()
*/
public String getReplacementText();
/**
* Returns the description of this auto-complete choice. This can be
* used in a popup "description window."
* Returns the description of this auto-complete choice. This can be used in a
* popup "description window."
*
* @return This item's description. This should be HTML. It may be
* <code>null</code> if there is no description for this
* completion.
* <code>null</code> if there is no description for this completion.
*/
public String getSummary();
/**
* Returns the tool tip text to display for mouse hovers over this
* completion.
* Returns the tool tip text to display for mouse hovers over this completion.
* <p>
*
* Note that for this functionality to be enabled, a
* <tt>JTextComponent</tt> must be registered with the
* <tt>ToolTipManager</tt>, and the text component must know to search
* for this value. In the case of an
* <a href="http://fifesoft.com/rsyntaxtextarea">RSyntaxTextArea</a>, this
* can be done with a <tt>org.fife.ui.rtextarea.ToolTipSupplier</tt> that
* calls into
* Note that for this functionality to be enabled, a <tt>JTextComponent</tt>
* must be registered with the <tt>ToolTipManager</tt>, and the text component
* must know to search for this value. In the case of an
* <a href="http://fifesoft.com/rsyntaxtextarea">RSyntaxTextArea</a>, this can
* be done with a <tt>org.fife.ui.rtextarea.ToolTipSupplier</tt> that calls into
* {@link CompletionProvider#getCompletionsAt(JTextComponent, java.awt.Point)}.
*
* @return The tool tip text for this completion, or <code>null</code> if
* none.
* @return The tool tip text for this completion, or <code>null</code> if none.
*/
public String getToolTipText();
}
@@ -26,8 +26,8 @@ import javax.swing.text.View;
/**
* A cell renderer that adds some pizazz when rendering the standard
* {@link Completion} types, like Eclipse and NetBeans do. Specifically,
* this renderer handles:
* {@link Completion} types, like Eclipse and NetBeans do. Specifically, this
* renderer handles:
*
* <ul>
* <li>{@link FunctionCompletion}s</li>
@@ -41,20 +41,20 @@ import javax.swing.text.View;
* @version 1.0
*/
public class CompletionCellRenderer extends DefaultListCellRenderer {
/**
* The alternating background color, or <code>null</code> if alternating
* row colors should not be used.
* The alternating background color, or <code>null</code> if alternating row
* colors should not be used.
*/
private static Color altBG;
/**
* The font to use when rendering items, or <code>null</code> if the
* list's default font should be used.
* The font to use when rendering items, or <code>null</code> if the list's
* default font should be used.
*/
private Font font;
/**
* Whether to display the types of fields and return types of functions
* in the completion text.
* Whether to display the types of fields and return types of functions in the
* completion text.
*/
private boolean showTypes;
/**
@@ -92,33 +92,32 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
* words.
*/
private static final String PREFIX = "<html><nobr>";
/**
* Constructor.
*/
public CompletionCellRenderer() {
init();
}
/**
* Constructor. This is primarily a hook for Substance, or any other
* Look and Feel whose renderers look drastically different than standard
* Constructor. This is primarily a hook for Substance, or any other Look and
* Feel whose renderers look drastically different than standard
* <code>DefaultListCellRenderer</code>s. Everything except for the text
* rendering will be done by the delegate. In almost all scenarios, you
* will want to use the no-argument constructor instead of this one.
* rendering will be done by the delegate. In almost all scenarios, you will
* want to use the no-argument constructor instead of this one.
*
* @param delegate
* The delegate renderer.
* @param delegate The delegate renderer.
* @see #delegateToSubstanceRenderer()
*/
public CompletionCellRenderer(DefaultListCellRenderer delegate) {
setDelegateRenderer(delegate);
init();
}
/**
* Creates the icon to use if no icon is found for a specific completion.
* The default implementation returns a 16x16 empty icon.
* Creates the icon to use if no icon is found for a specific completion. The
* default implementation returns a 16x16 empty icon.
*
* @return The icon.
* @see #getEmptyIcon()
@@ -126,34 +125,32 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
protected Icon createEmptyIcon() {
return new EmptyIcon(16);
}
/**
* Returns a decent "parameter" color based on the current default
* foreground color.
* Returns a decent "parameter" color based on the current default foreground
* color.
*
* @return The parameter color to use.
*/
private String createParamColor() {
return Util.isLightForeground(getForeground()) ? Util.getHexString(Util.getHyperlinkForeground()) : "#aa0077";
}
/**
* Returns a decent "type" color based on the current default foreground
* color.
* Returns a decent "type" color based on the current default foreground color.
*
* @return The type color to use.
*/
private String createTypeColor() {
return "#808080";
}
/**
* Attempts to delegate rendering to a Substance cell renderer. This
* should only be called if Substance is known to be on the classpath.
* Attempts to delegate rendering to a Substance cell renderer. This should only
* be called if Substance is known to be on the classpath.
*
* @throws Exception
* If Substance is not on the classpath, or some other
* error occurs creating the Substance cell renderer.
* @throws Exception If Substance is not on the classpath, or some other error
* occurs creating the Substance cell renderer.
* @see Util#getUseSubstanceRenderers()
* @see #setDelegateRenderer(DefaultListCellRenderer)
*/
@@ -162,7 +159,7 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
DefaultListCellRenderer delegate = (DefaultListCellRenderer) clazz.newInstance();
setDelegateRenderer(delegate);
}
/**
* Returns the background color to use on alternating lines.
*
@@ -173,7 +170,7 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
public static Color getAlternateBackground() {
return altBG;
}
/**
* Returns the delegate renderer, or <code>null</code> if there is none.
*
@@ -183,21 +180,21 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
public DefaultListCellRenderer getDelegateRenderer() {
return delegate;
}
/**
* Returns the font used when rendering completions.
*
* @return The font. If this is <code>null</code>, then the default list
* font is used.
* @return The font. If this is <code>null</code>, then the default list font is
* used.
* @see #setDisplayFont(Font)
*/
public Font getDisplayFont() {
return font;
}
/**
* Returns the icon to use if no icon is found for a specific completion.
* This icon is lazily created if necessary.
* Returns the icon to use if no icon is found for a specific completion. This
* icon is lazily created if necessary.
*
* @return The icon.
* @see #createEmptyIcon()
@@ -208,13 +205,12 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
return emptyIcon;
}
/**
* Returns an icon.
*
* @param resource
* The icon to retrieve. This should either be a file,
* or a resource loadable by the current ClassLoader.
* @param resource The icon to retrieve. This should either be a file, or a
* resource loadable by the current ClassLoader.
* @return The icon.
*/
protected Icon getIcon(String resource) {
@@ -229,23 +225,19 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
return url != null ? new ImageIcon(url) : null;
}
/**
* Returns the renderer.
*
* @param list
* The list of choices being rendered.
* @param value
* The {@link Completion} being rendered.
* @param index
* The index into <code>list</code> being rendered.
* @param selected
* Whether the item is selected.
* @param hasFocus
* Whether the item has focus.
* @param list The list of choices being rendered.
* @param value The {@link Completion} being rendered.
* @param index The index into <code>list</code> being rendered.
* @param selected Whether the item is selected.
* @param hasFocus Whether the item has focus.
*/
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean hasFocus) {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected,
boolean hasFocus) {
super.getListCellRendererComponent(list, value, index, selected, hasFocus);
if (font != null) {
setFont(font); // Overrides super's setFont(list.getFont()).
@@ -282,10 +274,10 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
return this;
}
/**
* Returns whether the types of fields and return types of methods are
* shown in the completion text.
* Returns whether the types of fields and return types of methods are shown in
* the completion text.
*
* @return Whether to show the types.
* @see #setShowTypes(boolean)
@@ -293,7 +285,7 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
public boolean getShowTypes() {
return showTypes;
}
private void init() {
// setDisplayFont(new Font("Monospaced", Font.PLAIN, 12));
setShowTypes(true);
@@ -301,7 +293,7 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
paramColor = createParamColor();
paintTextR = new Rectangle();
}
@Override
protected void paintComponent(Graphics g) {
// super.paintComponent(g);
@@ -342,22 +334,18 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
}
}
/**
* Prepares this renderer to display a function completion.
*
* @param list
* The list of choices being rendered.
* @param fc
* The completion to render.
* @param index
* The index into <code>list</code> being rendered.
* @param selected
* Whether the item is selected.
* @param hasFocus
* Whether the item has focus.
* @param list The list of choices being rendered.
* @param fc The completion to render.
* @param index The index into <code>list</code> being rendered.
* @param selected Whether the item is selected.
* @param hasFocus Whether the item has focus.
*/
protected void prepareForFunctionCompletion(JList list, FunctionCompletion fc, int index, boolean selected, boolean hasFocus) {
protected void prepareForFunctionCompletion(JList list, FunctionCompletion fc, int index, boolean selected,
boolean hasFocus) {
StringBuilder sb = new StringBuilder(PREFIX);
sb.append(fc.getName());
char paramListStart = fc.getProvider().getParameterListStart();
@@ -404,41 +392,32 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
setText(sb.toString());
}
/**
* Prepares this renderer to display a markup tag completion.
*
* @param list
* The list of choices being rendered.
* @param mc
* The completion to render.
* @param index
* The index into <code>list</code> being rendered.
* @param selected
* Whether the item is selected.
* @param hasFocus
* Whether the item has focus.
* @param list The list of choices being rendered.
* @param mc The completion to render.
* @param index The index into <code>list</code> being rendered.
* @param selected Whether the item is selected.
* @param hasFocus Whether the item has focus.
*/
protected void prepareForMarkupTagCompletion(JList list, MarkupTagCompletion mc, int index, boolean selected, boolean hasFocus) {
protected void prepareForMarkupTagCompletion(JList list, MarkupTagCompletion mc, int index, boolean selected,
boolean hasFocus) {
StringBuilder sb = new StringBuilder(PREFIX);
sb.append(mc.getName());
setText(sb.toString());
}
/**
* Prepares this renderer to display a completion not specifically handled
* elsewhere.
*
* @param list
* The list of choices being rendered.
* @param c
* The completion to render.
* @param index
* The index into <code>list</code> being rendered.
* @param selected
* Whether the item is selected.
* @param hasFocus
* Whether the item has focus.
* @param list The list of choices being rendered.
* @param c The completion to render.
* @param index The index into <code>list</code> being rendered.
* @param selected Whether the item is selected.
* @param hasFocus Whether the item has focus.
*/
protected void prepareForOtherCompletion(JList list, Completion c, int index, boolean selected, boolean hasFocus) {
StringBuilder sb = new StringBuilder(PREFIX);
@@ -458,22 +437,18 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
setText(sb.toString());
}
/**
* Prepares this renderer to display a template completion.
*
* @param list
* The list of choices being rendered.
* @param tc
* The completion to render.
* @param index
* The index into <code>list</code> being rendered.
* @param selected
* Whether the item is selected.
* @param hasFocus
* Whether the item has focus.
* @param list The list of choices being rendered.
* @param tc The completion to render.
* @param index The index into <code>list</code> being rendered.
* @param selected Whether the item is selected.
* @param hasFocus Whether the item has focus.
*/
protected void prepareForTemplateCompletion(JList list, TemplateCompletion tc, int index, boolean selected, boolean hasFocus) {
protected void prepareForTemplateCompletion(JList list, TemplateCompletion tc, int index, boolean selected,
boolean hasFocus) {
StringBuilder sb = new StringBuilder(PREFIX);
sb.append(tc.getInputText());
String definition = tc.getShortDescription();
@@ -489,22 +464,18 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
setText(sb.toString());
}
/**
* Prepares this renderer to display a variable completion.
*
* @param list
* The list of choices being rendered.
* @param vc
* The completion to render.
* @param index
* The index into <code>list</code> being rendered.
* @param selected
* Whether the item is selected.
* @param hasFocus
* Whether the item has focus.
* @param list The list of choices being rendered.
* @param vc The completion to render.
* @param index The index into <code>list</code> being rendered.
* @param selected Whether the item is selected.
* @param hasFocus Whether the item has focus.
*/
protected void prepareForVariableCompletion(JList list, VariableCompletion vc, int index, boolean selected, boolean hasFocus) {
protected void prepareForVariableCompletion(JList list, VariableCompletion vc, int index, boolean selected,
boolean hasFocus) {
StringBuilder sb = new StringBuilder(PREFIX);
sb.append(vc.getName());
if (getShowTypes() && vc.getType() != null) {
@@ -519,81 +490,73 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
}
setText(sb.toString());
}
/**
* Sets the background color to use on alternating lines.
*
* @param altBG
* The new alternate background color. If this is
* <code>null</code>, alternating lines will not use different
* background colors.
* @param altBG The new alternate background color. If this is
* <code>null</code>, alternating lines will not use different
* background colors.
* @see #getAlternateBackground()
*/
public static void setAlternateBackground(Color altBG) {
CompletionCellRenderer.altBG = altBG;
}
/**
* Sets the delegate renderer. Most users will never use this method; it
* is primarily a hook for Substance and other Look and Feels whose
* renderers look drastically different from the standard
* <code>DefaultListCellRenderer</code>.
* Sets the delegate renderer. Most users will never use this method; it is
* primarily a hook for Substance and other Look and Feels whose renderers look
* drastically different from the standard <code>DefaultListCellRenderer</code>.
*
* @param delegate
* The new delegate renderer. If this is <code>null</code>,
* the default rendering of this component is used.
* @param delegate The new delegate renderer. If this is <code>null</code>, the
* default rendering of this component is used.
* @see #getDelegateRenderer()
* @see #delegateToSubstanceRenderer()
*/
public void setDelegateRenderer(DefaultListCellRenderer delegate) {
this.delegate = delegate;
}
/**
* Sets the font to use when rendering completion items.
*
* @param font
* The font to use. If this is <code>null</code>, then
* the default list font is used.
* @param font The font to use. If this is <code>null</code>, then the default
* list font is used.
* @see #getDisplayFont()
*/
public void setDisplayFont(Font font) {
this.font = font;
}
/**
* Sets the icon to display based off of a completion, falling back to the
* empty icon if the completion has no icon.
* Sets the icon to display based off of a completion, falling back to the empty
* icon if the completion has no icon.
*
* @param completion
* The completion to check.
* @param completion The completion to check.
* @see #setIconWithDefault(Completion, Icon)
*/
protected void setIconWithDefault(Completion completion) {
setIconWithDefault(completion, getEmptyIcon());
}
/**
* Sets the icon to display based off of a completion, falling back to a
* default icon if the completion has no icon.
* Sets the icon to display based off of a completion, falling back to a default
* icon if the completion has no icon.
*
* @param completion
* The completion to check.
* @param defaultIcon
* The icon to use if <code>completion</code> does not
* specify an icon.
* @param completion The completion to check.
* @param defaultIcon The icon to use if <code>completion</code> does not
* specify an icon.
* @see #setIconWithDefault(Completion)
*/
protected void setIconWithDefault(Completion completion, Icon defaultIcon) {
Icon icon = completion.getIcon();
setIcon(icon != null ? icon : (defaultIcon != null ? defaultIcon : emptyIcon));
}
/**
* Sets the color to use for function arguments.
*
* @param color
* The color to use. This is ignored if <code>null</code>.
* @param color The color to use. This is ignored if <code>null</code>.
* @see #setTypeColor(Color)
*/
public void setParamColor(Color color) {
@@ -601,27 +564,25 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
paramColor = Util.getHexString(color);
}
}
/**
* Sets whether the types of fields and return types of methods are
* shown in the completion text.
* Sets whether the types of fields and return types of methods are shown in the
* completion text.
*
* @param show
* Whether to show the types.
* @param show Whether to show the types.
* @see #getShowTypes()
*/
public void setShowTypes(boolean show) {
this.showTypes = show;
}
/**
* Sets the color to use for function/field types. Note that if
* {@link #getShowTypes()} returns <code>false</code>, this property
* effectively does nothing.
* {@link #getShowTypes()} returns <code>false</code>, this property effectively
* does nothing.
*
* @param color
* The color to use for types. This is ignored if
* <code>null</code>.
* @param color The color to use for types. This is ignored if
* <code>null</code>.
* @see #setShowTypes(boolean)
* @see #setParamColor(Color)
*/
@@ -630,7 +591,7 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
typeColor = Util.getHexString(color);
}
}
/**
* Overridden to update our delegate, if necessary.
*/
@@ -13,30 +13,29 @@ import java.util.List;
import javax.swing.AbstractListModel;
/**
* A list model implementation that allows the bulk addition of elements.
* This is the only feature missing from <code>DefaultListModel</code> that
* we need.
* A list model implementation that allows the bulk addition of elements. This
* is the only feature missing from <code>DefaultListModel</code> that we need.
*
* @author Robert Futrell
* @version 1.0
*/
class CompletionListModel extends AbstractListModel {
/**
* Container for items in this model.
*/
private List<Completion> delegate;
/**
* Constructor.
*/
public CompletionListModel() {
delegate = new ArrayList<Completion>();
}
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns (unless it throws an exception).
* Removes all of the elements from this list. The list will be empty after this
* call returns (unless it throws an exception).
*
* @see #setContents(Collection)
*/
@@ -47,7 +46,7 @@ class CompletionListModel extends AbstractListModel {
fireIntervalRemoved(this, 0, end);
}
}
/**
* {@inheritDoc}
*/
@@ -55,7 +54,7 @@ class CompletionListModel extends AbstractListModel {
public Object getElementAt(int index) {
return delegate.get(index);
}
/**
* {@inheritDoc}
*/
@@ -63,12 +62,11 @@ class CompletionListModel extends AbstractListModel {
public int getSize() {
return delegate.size();
}
/**
* Sets the contents of this model. All previous contents are removed.
*
* @param contents
* The new contents of this model.
* @param contents The new contents of this model.
*/
public void setContents(Collection<Completion> contents) {
clear();
@@ -25,7 +25,7 @@ import javax.swing.text.JTextComponent;
* @version 1.0
*/
public interface CompletionProvider {
/**
* Clears the values used to identify and insert "parameterized completions"
* (e.g. functions or methods). After this method is called, functions and
@@ -34,111 +34,103 @@ public interface CompletionProvider {
* @see #setParameterizedCompletionParams(char, String, char)
*/
public void clearParameterizedCompletionParams();
/**
* Returns the text just before the current caret position that could be
* the start of something auto-completable.
* Returns the text just before the current caret position that could be the
* start of something auto-completable.
*
* @param comp
* The text component.
* @return The text. A return value of <code>null</code> means nothing
* should be auto-completed; a value of an empty string
* (<code>""</code>) means auto-completion should still be
* considered (i.e., all possible choices are valid).
* @param comp The text component.
* @return The text. A return value of <code>null</code> means nothing should be
* auto-completed; a value of an empty string (<code>""</code>) means
* auto-completion should still be considered (i.e., all possible
* choices are valid).
*/
public String getAlreadyEnteredText(JTextComponent comp);
/**
* Gets the possible completions for the text component at the current
* caret position.
* Gets the possible completions for the text component at the current caret
* position.
*
* @param comp
* The text component.
* @return The list of {@link Completion}s. If no completions are
* available, this method should return an empty list.
* @param comp The text component.
* @return The list of {@link Completion}s. If no completions are available,
* this method should return an empty list.
*/
public List<Completion> getCompletions(JTextComponent comp);
/**
* Returns the completions that have been entered at the specified visual
* location. This can be used for tool tips when the user hovers the
* mouse over completed text.
* location. This can be used for tool tips when the user hovers the mouse over
* completed text.
*
* @param comp
* The text component.
* @param p
* The position, usually from a <tt>MouseEvent</tt>.
* @param comp The text component.
* @param p The position, usually from a <tt>MouseEvent</tt>.
* @return The completions, or an empty list if there are none.
*/
public List<Completion> getCompletionsAt(JTextComponent comp, Point p);
/**
* Returns the cell renderer for completions returned from this provider.
*
* @return The cell renderer, or <code>null</code> if the default should
* be used.
* @return The cell renderer, or <code>null</code> if the default should be
* used.
* @see #setListCellRenderer(ListCellRenderer)
*/
public ListCellRenderer getListCellRenderer();
/**
* Returns an object that can return a list of completion choices for
* parameters. This is used when a user code-completes a parameterized
* completion, such as a function or method. For any parameter to the
* function/method, this object can return possible completions.
*
* @return The parameter choices provider, or <code>null</code> if
* none is installed.
* @return The parameter choices provider, or <code>null</code> if none is
* installed.
*/
public ParameterChoicesProvider getParameterChoicesProvider();
/**
* Returns a list of parameterized completions that have been entered
* at the current caret position of a text component (and thus can have
* their completion choices displayed).
* Returns a list of parameterized completions that have been entered at the
* current caret position of a text component (and thus can have their
* completion choices displayed).
*
* @param tc
* The text component.
* @return The list of {@link ParameterizedCompletion}s. If no completions
* are available, this may be <code>null</code>.
* @param tc The text component.
* @return The list of {@link ParameterizedCompletion}s. If no completions are
* available, this may be <code>null</code>.
*/
public List<ParameterizedCompletion> getParameterizedCompletions(JTextComponent tc);
/**
* Returns the text that marks the end of a list of parameters to a
* function or method.
* Returns the text that marks the end of a list of parameters to a function or
* method.
*
* @return The text for a parameter list end, for example,
* '<code>)</code>'.
* @return The text for a parameter list end, for example, '<code>)</code>'.
* @see #getParameterListStart()
* @see #getParameterListSeparator()
* @see #setParameterizedCompletionParams(char, String, char)
*/
public char getParameterListEnd();
/**
* Returns the text that separates parameters to a function or method.
*
* @return The text that separates parameters, for example,
* "<code>, </code>".
* @return The text that separates parameters, for example, "<code>, </code>".
* @see #getParameterListStart()
* @see #getParameterListEnd()
* @see #setParameterizedCompletionParams(char, String, char)
*/
public String getParameterListSeparator();
/**
* Returns the text that marks the start of a list of parameters to a
* function or method.
* Returns the text that marks the start of a list of parameters to a function
* or method.
*
* @return The text for a parameter list start, for example,
* "<code>(</code>".
* @return The text for a parameter list start, for example, "<code>(</code>".
* @see #getParameterListEnd()
* @see #getParameterListSeparator()
* @see #setParameterizedCompletionParams(char, String, char)
*/
public char getParameterListStart();
/**
* Returns the parent completion provider.
*
@@ -146,59 +138,53 @@ public interface CompletionProvider {
* @see #setParent(CompletionProvider)
*/
public CompletionProvider getParent();
/**
* This method is called if auto-activation is enabled in the parent
* {@link AutoCompletion} after the user types a single character. This
* provider should check the text at the current caret position of the
* text component, and decide whether auto-activation would be appropriate
* here. For example, a <code>CompletionProvider</code> for Java might
* want to return <code>true</code> for this method only if the last
* character typed was a '<code>.</code>'.
* {@link AutoCompletion} after the user types a single character. This provider
* should check the text at the current caret position of the text component,
* and decide whether auto-activation would be appropriate here. For example, a
* <code>CompletionProvider</code> for Java might want to return
* <code>true</code> for this method only if the last character typed was a
* '<code>.</code>'.
*
* @param tc
* The text component.
* @param tc The text component.
* @return Whether auto-activation would be appropriate.
*/
public boolean isAutoActivateOkay(JTextComponent tc);
/**
* Sets the renderer to use when displaying completion choices.
*
* @param r
* The renderer to use.
* @param r The renderer to use.
* @see #getListCellRenderer()
*/
public void setListCellRenderer(ListCellRenderer r);
/**
* Sets the values used to identify and insert "parameterized completions"
* (e.g. functions or methods). If this method isn't called, functions
* and methods will not have their parameters auto-completed.
* Sets the values used to identify and insert "parameterized completions" (e.g.
* functions or methods). If this method isn't called, functions and methods
* will not have their parameters auto-completed.
*
* @param listStart
* The character that marks the beginning of a list of
* parameters, such as '<tt>(</tt>' in C or Java.
* @param separator
* Text that should separate parameters in a parameter
* list when one is inserted. For example, "<tt>, </tt>".
* @param listEnd
* The character that marks the end of a list of parameters,
* such as '<tt>)</tt>' in C or Java.
* @throws IllegalArgumentException
* If either <tt>listStart</tt> or
* <tt>listEnd</tt> is not printable ASCII, or if
* <tt>separator</tt> is <code>null</code> or an empty string.
* @param listStart The character that marks the beginning of a list of
* parameters, such as '<tt>(</tt>' in C or Java.
* @param separator Text that should separate parameters in a parameter list
* when one is inserted. For example, "<tt>, </tt>".
* @param listEnd The character that marks the end of a list of parameters,
* such as '<tt>)</tt>' in C or Java.
* @throws IllegalArgumentException If either <tt>listStart</tt> or
* <tt>listEnd</tt> is not printable ASCII, or
* if <tt>separator</tt> is <code>null</code>
* or an empty string.
* @see #clearParameterizedCompletionParams()
*/
public void setParameterizedCompletionParams(char listStart, String separator, char listEnd);
/**
* Sets the parent completion provider.
*
* @param parent
* The parent provider. <code>null</code> means there will
* be no parent provider.
* @param parent The parent provider. <code>null</code> means there will be no
* parent provider.
* @see #getParent()
*/
public void setParent(CompletionProvider parent);
@@ -182,7 +182,8 @@ public abstract class CompletionProviderBase implements CompletionProvider {
} catch (BadLocationException ble) { // Never happens
ble.printStackTrace();
}
return (autoActivateAfterLetters && Character.isLetter(ch)) || (autoActivateChars != null && autoActivateChars.indexOf(ch) > -1);
return (autoActivateAfterLetters && Character.isLetter(ch))
|| (autoActivateChars != null && autoActivateChars.indexOf(ch) > -1);
}
/**
@@ -18,15 +18,15 @@ import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Parser for an XML file describing a procedural language such as C. XML
* files will be validated against the <code>CompletionXml.dtd</code> DTD
* found in this package.
* Parser for an XML file describing a procedural language such as C. XML files
* will be validated against the <code>CompletionXml.dtd</code> DTD found in
* this package.
*
* @author Robert Futrell
* @version 1.0
*/
public class CompletionXMLParser extends DefaultHandler {
/**
* The completions found after parsing the XML.
*/
@@ -68,36 +68,31 @@ public class CompletionXMLParser extends DefaultHandler {
*/
private String funcCompletionType;
/**
* The class loader to use to load custom completion classes, such as
* the one defined by {@link #funcCompletionType}. If this is
* <code>null</code>, then a default class loader is used. This field
* will usually be <code>null</code>.
* The class loader to use to load custom completion classes, such as the one
* defined by {@link #funcCompletionType}. If this is <code>null</code>, then a
* default class loader is used. This field will usually be <code>null</code>.
*/
private static ClassLoader DEFAULT_COMPLETION_CLASS_LOADER;
/**
* Constructor.
*
* @param provider
* The provider to get completions for.
* @param provider The provider to get completions for.
* @see #reset(CompletionProvider)
*/
public CompletionXMLParser(CompletionProvider provider) {
this(provider, null);
}
/**
* Constructor.
*
* @param provider
* The provider to get completions for.
* @param cl
* The class loader to use, if necessary, when loading classes
* from the XML (custom {@link FunctionCompletion}s, for
* example).
* This may be <code>null</code> if the default is to be used, or
* if the XML does not define specific classes for completion
* types.
* @param provider The provider to get completions for.
* @param cl The class loader to use, if necessary, when loading classes
* from the XML (custom {@link FunctionCompletion}s, for
* example). This may be <code>null</code> if the default is to
* be used, or if the XML does not define specific classes for
* completion types.
* @see #reset(CompletionProvider)
*/
public CompletionXMLParser(CompletionProvider provider, ClassLoader cl) {
@@ -115,7 +110,7 @@ public class CompletionXMLParser extends DefaultHandler {
paramStartChar = paramEndChar = 0;
paramSeparator = null;
}
/**
* Called when character data inside an element is found.
*/
@@ -129,7 +124,7 @@ public class CompletionXMLParser extends DefaultHandler {
returnValDesc.append(ch, start, length);
}
}
private FunctionCompletion createFunctionCompletion() {
FunctionCompletion fc = null;
if (funcCompletionType != null) {
@@ -163,7 +158,7 @@ public class CompletionXMLParser extends DefaultHandler {
}
return fc;
}
private BasicCompletion createOtherCompletion() {
BasicCompletion bc = new BasicCompletion(provider, name);
if (desc.length() > 0) {
@@ -172,7 +167,7 @@ public class CompletionXMLParser extends DefaultHandler {
}
return bc;
}
private MarkupTagCompletion createMarkupTagCompletion() {
MarkupTagCompletion mc = new MarkupTagCompletion(provider, name);
if (desc.length() > 0) {
@@ -183,7 +178,7 @@ public class CompletionXMLParser extends DefaultHandler {
mc.setDefinedIn(definedIn);
return mc;
}
private VariableCompletion createVariableCompletion() {
VariableCompletion vc = new VariableCompletion(provider, name, returnType);
if (desc.length() > 0) {
@@ -193,7 +188,7 @@ public class CompletionXMLParser extends DefaultHandler {
vc.setDefinedIn(definedIn);
return vc;
}
/**
* Called when an element is closed.
*/
@@ -246,12 +241,12 @@ public class CompletionXMLParser extends DefaultHandler {
}
}
}
@Override
public void error(SAXParseException e) throws SAXException {
throw e;
}
/**
* Returns the completions found after parsing the XML.
*
@@ -260,7 +255,7 @@ public class CompletionXMLParser extends DefaultHandler {
public List<Completion> getCompletions() {
return completions;
}
/**
* Returns the parameter end character specified.
*
@@ -269,7 +264,7 @@ public class CompletionXMLParser extends DefaultHandler {
public char getParamEndChar() {
return paramEndChar;
}
/**
* Returns the parameter end string specified.
*
@@ -278,7 +273,7 @@ public class CompletionXMLParser extends DefaultHandler {
public String getParamSeparator() {
return paramSeparator;
}
/**
* Returns the parameter start character specified.
*
@@ -287,16 +282,15 @@ public class CompletionXMLParser extends DefaultHandler {
public char getParamStartChar() {
return paramStartChar;
}
private static final char getSingleChar(String str) {
return str.length() == 1 ? str.charAt(0) : 0;
}
/**
* Resets this parser to grab more completions.
*
* @param provider
* The new provider to get completions for.
* @param provider The new provider to get completions for.
*/
public void reset(CompletionProvider provider) {
this.provider = provider;
@@ -305,28 +299,26 @@ public class CompletionXMLParser extends DefaultHandler {
paramStartChar = paramEndChar = 0;
paramSeparator = null;
}
@Override
public InputSource resolveEntity(String publicID, String systemID) throws SAXException {
return new InputSource(getClass().getResourceAsStream("CompletionXml.dtd"));
}
/**
* Sets the class loader to use when loading custom classes to use for
* various {@link Completion} types, such as {@link FunctionCompletion}s,
* from XML.
* Sets the class loader to use when loading custom classes to use for various
* {@link Completion} types, such as {@link FunctionCompletion}s, from XML.
* <p>
*
* Users should very rarely have a need to use this method.
*
* @param cl
* The class loader to use. If this is <code>null</code>, then
* a default is used.
* @param cl The class loader to use. If this is <code>null</code>, then a
* default is used.
*/
public static void setDefaultCompletionClassLoader(ClassLoader cl) {
DEFAULT_COMPLETION_CLASS_LOADER = cl;
}
/**
* Called when an element starts.
*/
@@ -375,7 +367,7 @@ public class CompletionXMLParser extends DefaultHandler {
}
}
}
@Override
public void warning(SAXParseException e) throws SAXException {
throw e;
@@ -28,29 +28,29 @@ import org.xml.sax.SAXException;
/**
* A basic completion provider implementation. This provider has no
* understanding of language semantics. It simply checks the text entered up
* to the caret position for a match against known completions. This is all
* that is needed in the majority of cases.
* understanding of language semantics. It simply checks the text entered up to
* the caret position for a match against known completions. This is all that is
* needed in the majority of cases.
*
* @author Robert Futrell
* @version 1.0
*/
public class DefaultCompletionProvider extends AbstractCompletionProvider {
protected Segment seg;
/**
* Used to speed up {@link #getCompletionsAt(JTextComponent, Point)}.
*/
private String lastCompletionsAtText;
/**
* Used to speed up {@link #getCompletionsAt(JTextComponent, Point)},
* since this may be called multiple times in succession (this is usually
* called by <tt>JTextComponent.getToolTipText()</tt>, and if the user
* wiggles the mouse while a tool tip is displayed, this method gets
* repeatedly called. It can be costly so we try to speed it up a tad).
* Used to speed up {@link #getCompletionsAt(JTextComponent, Point)}, since this
* may be called multiple times in succession (this is usually called by
* <tt>JTextComponent.getToolTipText()</tt>, and if the user wiggles the mouse
* while a tool tip is displayed, this method gets repeatedly called. It can be
* costly so we try to speed it up a tad).
*/
private List<Completion> lastParameterizedCompletionsAt;
/**
* Constructor. The returned provider will not be aware of any completions.
*
@@ -59,28 +59,27 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
public DefaultCompletionProvider() {
init();
}
/**
* Creates a completion provider that provides completion for a simple
* list of words.
* Creates a completion provider that provides completion for a simple list of
* words.
*
* @param words
* The words to offer as completion suggestions. If this is
* <code>null</code>, no completions will be known.
* @param words The words to offer as completion suggestions. If this is
* <code>null</code>, no completions will be known.
* @see BasicCompletion
*/
public DefaultCompletionProvider(String[] words) {
init();
addWordCompletions(words);
}
/**
* Returns the text just before the current caret position that could be
* the start of something auto-completable.
* Returns the text just before the current caret position that could be the
* start of something auto-completable.
* <p>
*
* This method returns all characters before the caret that are matched
* by {@link #isValidChar(char)}.
* This method returns all characters before the caret that are matched by
* {@link #isValidChar(char)}.
*
* {@inheritDoc}
*/
@@ -108,7 +107,7 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
len = segEnd - start;
return len == 0 ? EMPTY_STRING : new String(seg.array, start, len);
}
/**
* {@inheritDoc}
*/
@@ -156,7 +155,7 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
lastCompletionsAtText = null;
return lastParameterizedCompletionsAt = null;
}
/**
* {@inheritDoc}
*/
@@ -212,36 +211,33 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
}
return list;
}
/**
* Initializes this completion provider.
*/
protected void init() {
seg = new Segment();
}
/**
* Returns whether the specified character is valid in an auto-completion.
* The default implementation is equivalent to
* "<code>Character.isLetterOrDigit(ch) || ch=='_'</code>". Subclasses
* can override this method to change what characters are matched.
* Returns whether the specified character is valid in an auto-completion. The
* default implementation is equivalent to
* "<code>Character.isLetterOrDigit(ch) || ch=='_'</code>". Subclasses can
* override this method to change what characters are matched.
*
* @param ch
* The character.
* @param ch The character.
* @return Whether the character is valid.
*/
protected boolean isValidChar(char ch) {
return Character.isLetterOrDigit(ch) || ch == '_';
}
/**
* Loads completions from an XML file. The XML should validate against
* <code>CompletionXml.dtd</code>.
*
* @param file
* An XML file to load from.
* @throws IOException
* If an IO error occurs.
* @param file An XML file to load from.
* @throws IOException If an IO error occurs.
*/
public void loadFromXML(File file) throws IOException {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(file));
@@ -251,34 +247,28 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
bin.close();
}
}
/**
* Loads completions from an XML input stream. The XML should validate
* against <code>CompletionXml.dtd</code>.
* Loads completions from an XML input stream. The XML should validate against
* <code>CompletionXml.dtd</code>.
*
* @param in
* The input stream to read from.
* @throws IOException
* If an IO error occurs.
* @param in The input stream to read from.
* @throws IOException If an IO error occurs.
*/
public void loadFromXML(InputStream in) throws IOException {
loadFromXML(in, null);
}
/**
* Loads completions from an XML input stream. The XML should validate
* against <code>CompletionXml.dtd</code>.
* Loads completions from an XML input stream. The XML should validate against
* <code>CompletionXml.dtd</code>.
*
* @param in
* The input stream to read from.
* @param cl
* The class loader to use when loading any extra classes defined
* in the XML, such as custom {@link FunctionCompletion}s. This
* may be <code>null</code> if the default is to be used, or if
* no
* custom completions are defined in the XML.
* @throws IOException
* If an IO error occurs.
* @param in The input stream to read from.
* @param cl The class loader to use when loading any extra classes defined in
* the XML, such as custom {@link FunctionCompletion}s. This may be
* <code>null</code> if the default is to be used, or if no custom
* completions are defined in the XML.
* @throws IOException If an IO error occurs.
*/
public void loadFromXML(InputStream in, ClassLoader cl) throws IOException {
// long start = System.currentTimeMillis();
@@ -309,15 +299,13 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
bin.close();
}
}
/**
* Loads completions from an XML file. The XML should validate against
* <code>CompletionXml.dtd</code>.
*
* @param resource
* A resource the current ClassLoader can get to.
* @throws IOException
* If an IO error occurs.
* @param resource A resource the current ClassLoader can get to.
* @throws IOException If an IO error occurs.
*/
public void loadFromXML(String resource) throws IOException {
ClassLoader cl = getClass().getClassLoader();
@@ -15,22 +15,22 @@ import javax.swing.JList;
import javax.swing.ListCellRenderer;
/**
* List cell renderer that delegates to a {@link CompletionProvider}'s
* renderer, if it has one. If it doesn't, it calls into a fallback renderer.
* If a fallback renderer isn't specified, it simply renders
* List cell renderer that delegates to a {@link CompletionProvider}'s renderer,
* if it has one. If it doesn't, it calls into a fallback renderer. If a
* fallback renderer isn't specified, it simply renders
* <code>(({@link Completion})value).toString()</code>.
*
* @author Robert Futrell
* @version 1.0
*/
class DelegatingCellRenderer extends DefaultListCellRenderer {
/**
* The renderer to fall back on if one isn't specified by a provider.
* This is usually <tt>this</tt>.
* The renderer to fall back on if one isn't specified by a provider. This is
* usually <tt>this</tt>.
*/
private ListCellRenderer fallback;
/**
* Returns the fallback cell renderer.
*
@@ -40,12 +40,13 @@ class DelegatingCellRenderer extends DefaultListCellRenderer {
public ListCellRenderer getFallbackCellRenderer() {
return fallback;
}
/**
* {@inheritDoc}
*/
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean hasFocus) {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected,
boolean hasFocus) {
Completion c = (Completion) value;
CompletionProvider p = c.getProvider();
ListCellRenderer r = p.getListCellRenderer();
@@ -57,19 +58,18 @@ class DelegatingCellRenderer extends DefaultListCellRenderer {
}
return fallback.getListCellRendererComponent(list, value, index, selected, hasFocus);
}
/**
* Sets the fallback cell renderer.
*
* @param fallback
* The fallback cell renderer. If this is
* <code>null</code>, <tt>this</tt> will be used.
* @param fallback The fallback cell renderer. If this is <code>null</code>,
* <tt>this</tt> will be used.
* @see #getFallbackCellRenderer()
*/
public void setFallbackCellRenderer(ListCellRenderer fallback) {
this.fallback = fallback;
}
/**
* {@inheritDoc}
*/
@@ -14,15 +14,13 @@ package org.fife.ui.autocomplete;
* @see ExternalURLHandler
*/
public interface DescWindowCallback {
/**
* Callback allowing a new code completion's description to be displayed
* in the description window.
* Callback allowing a new code completion's description to be displayed in the
* description window.
*
* @param completion
* The new completion.
* @param anchor
* The anchor to scroll to, or <code>null</code> if none.
* @param completion The new completion.
* @param anchor The anchor to scroll to, or <code>null</code> if none.
*/
public void showSummaryFor(Completion completion, String anchor);
}
+7 -6
View File
@@ -21,23 +21,24 @@ import javax.swing.Icon;
* @version 1.0
*/
public class EmptyIcon implements Icon, Serializable {
private int size;
public EmptyIcon(int size) {
this.size = size;
}
@Override
public int getIconHeight() {
return size;
}
@Override
public int getIconWidth() {
return size;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {}
public void paintIcon(Component c, Graphics g, int x, int y) {
}
}
@@ -10,12 +10,12 @@ package org.fife.ui.autocomplete;
import javax.swing.event.HyperlinkEvent;
/**
* A callback for when an external URL is clicked in the description window.
* If no handler is installed, and if running in Java 6, the system default
* web browser is used to open the URL. If not running Java 6, nothing will
* happen. If you want browser support for pre-Java 6 JRE's, you will need
* to register one of these callbacks on your {@link AutoCompletion}, and
* open the URL in a web browser yourself.
* A callback for when an external URL is clicked in the description window. If
* no handler is installed, and if running in Java 6, the system default web
* browser is used to open the URL. If not running Java 6, nothing will happen.
* If you want browser support for pre-Java 6 JRE's, you will need to register
* one of these callbacks on your {@link AutoCompletion}, and open the URL in a
* web browser yourself.
* <p>
*
* Alternatively, folks implementing robust code completion support for a
@@ -27,17 +27,13 @@ import javax.swing.event.HyperlinkEvent;
* @see AutoCompletion#setExternalURLHandler(ExternalURLHandler)
*/
public interface ExternalURLHandler {
/**
* Called when an external URL is clicked in the description window.
*
* @param e
* The event containing the hyperlink clicked.
* @param c
* The completion currently being displayed.
* @param callback
* Allows you to display new content in the description
* window.
* @param e The event containing the hyperlink clicked.
* @param c The completion currently being displayed.
* @param callback Allows you to display new content in the description window.
*/
public void urlClicked(HyperlinkEvent e, Completion c, DescWindowCallback callback);
}
+27 -29
View File
@@ -20,37 +20,37 @@ import javax.swing.plaf.basic.BasicListUI;
/**
* A custom list UI, used by the completion choices list. If the number of
* completion choices is "large," it does a fast estimate of the preferred
* width and height of list items. This allows HTML renderers to be used (such
* as {@link CompletionCellRenderer}), with thousands of completion choices,
* with no performance penalty. With standard BasicListUI subclasses, this can
* cause very poor performance <b>each time</b> the list is displayed, which
* is bad for lists that are repeatedly hidden and re-displayed, such as
* completion choices. This is all because the calculation to get the
* preferred size of each list item, when it is displayed with HTML, is slow.
* completion choices is "large," it does a fast estimate of the preferred width
* and height of list items. This allows HTML renderers to be used (such as
* {@link CompletionCellRenderer}), with thousands of completion choices, with
* no performance penalty. With standard BasicListUI subclasses, this can cause
* very poor performance <b>each time</b> the list is displayed, which is bad
* for lists that are repeatedly hidden and re-displayed, such as completion
* choices. This is all because the calculation to get the preferred size of
* each list item, when it is displayed with HTML, is slow.
*
* @author Robert Futrell
* @version 1.0
*/
class FastListUI extends BasicListUI {
/**
* Whether the selection background was overridden (usually because of
* Nimbus) so we know to manually uninstall the color we installed.
* Whether the selection background was overridden (usually because of Nimbus)
* so we know to manually uninstall the color we installed.
*/
private boolean overriddenBackground;
/**
* Whether the selection foreground was overridden (usually because of
* Nimbus) so we know to manually uninstall the color we installed.
* Whether the selection foreground was overridden (usually because of Nimbus)
* so we know to manually uninstall the color we installed.
*/
private boolean overriddenForeground;
/**
* If there are more than this many completions in a single list, this
* UI will estimate the cell width and height needed for each item instead
* of computing it, for performance reasons.
* If there are more than this many completions in a single list, this UI will
* estimate the cell width and height needed for each item instead of computing
* it, for performance reasons.
*/
private static final int ESTIMATION_THRESHOLD = 200;
private Color determineSelectionBackground() {
Color c = UIManager.getColor("List.selectionBackground");
if (c == null) {
@@ -68,7 +68,7 @@ class FastListUI extends BasicListUI {
// actually be a ColorUIResource
return new Color(c.getRGB());// new ColorUIResource(c);
}
private Color determineSelectionForeground() {
Color c = UIManager.getColor("List.selectionForeground");
if (c == null) {
@@ -84,12 +84,11 @@ class FastListUI extends BasicListUI {
// may actually be a ColorUIResource
return new Color(c.getRGB());
}
/**
* Overridden to ensure we have selection background/foreground colors
* defined, even if we're in some weirdo LAF such as Nimbus which doesn't
* define them. Since FastListUI extends BasicListUI, we need these values
* to be defined.
* Overridden to ensure we have selection background/foreground colors defined,
* even if we're in some weirdo LAF such as Nimbus which doesn't define them.
* Since FastListUI extends BasicListUI, we need these values to be defined.
*/
@Override
protected void installDefaults() {
@@ -103,7 +102,7 @@ class FastListUI extends BasicListUI {
overriddenForeground = true;
}
}
/**
* Overridden to work around a Nimbus issue.
*/
@@ -117,12 +116,11 @@ class FastListUI extends BasicListUI {
list.setSelectionForeground(null);
}
}
/**
* Recalculates the cell width and height of each cell in the list. This
* method is overridden to do a fast estimation if the completion list is
* too long, to improve performance for lists with huge amounts of
* completions.
* Recalculates the cell width and height of each cell in the list. This method
* is overridden to do a fast estimation if the completion list is too long, to
* improve performance for lists with huge amounts of completions.
*/
@Override
protected void updateLayoutState() {
@@ -20,7 +20,7 @@ import javax.swing.text.Position;
* @version 1.0
*/
public class FunctionCompletion extends VariableCompletion implements ParameterizedCompletion {
/**
* Parameters to the function.
*/
@@ -33,33 +33,29 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
* Used to improve performance of sorting FunctionCompletions.
*/
private String compareString;
/**
* Constructor.
*
* @param provider
* The parent provider.
* @param name
* The name of this function.
* @param returnType
* The return type of this function.
* @param provider The parent provider.
* @param name The name of this function.
* @param returnType The return type of this function.
*/
public FunctionCompletion(CompletionProvider provider, String name, String returnType) {
super(provider, name, returnType);
}
@Override
protected void addDefinitionString(StringBuilder sb) {
sb.append("<html><b>");
sb.append(getDefinitionString());
sb.append("</b>");
}
/**
* Adds HTML describing the parameters to this function to a buffer.
*
* @param sb
* The buffer to append to.
* @param sb The buffer to append to.
*/
protected void addParameters(StringBuilder sb) {
// TODO: Localize me
@@ -86,12 +82,11 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
sb.append("</td></tr></table></center><br><br>");
}
}
/**
* Overridden to compare methods by their comparison strings.
*
* @param c2
* A <code>Completion</code> to compare to.
* @param c2 A <code>Completion</code> to compare to.
* @return The sort order.
*/
@Override
@@ -106,7 +101,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
}
return rc;
}
/**
* Returns a string used to compare this method completion to another.
*
@@ -114,11 +109,9 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
*/
private String getCompareString() {
/*
* This string compares the following parts of methods in this order,
* to optimize sort order in completion lists.
* 1. First, by name
* 2. Next, by number of parameters.
* 3. Finally, by parameter type.
* This string compares the following parts of methods in this order, to
* optimize sort order in completion lists. 1. First, by name 2. Next, by number
* of parameters. 3. Finally, by parameter type.
*/
if (compareString == null) {
StringBuilder sb = new StringBuilder(getName());
@@ -139,10 +132,10 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
}
return compareString;
}
/**
* Returns the "definition string" for this function completion. For
* example, for the C "<code>printf</code>" function, this would return
* Returns the "definition string" for this function completion. For example,
* for the C "<code>printf</code>" function, this would return
* "<code>int printf(const char *, ...)</code>".
*
* @return The definition string.
@@ -186,7 +179,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
}
return sb.toString();
}
@Override
public ParameterizedCompletionInsertionInfo getInsertionInfo(JTextComponent tc, boolean replaceTabsWithSpaces) {
ParameterizedCompletionInsertionInfo info = new ParameterizedCompletionInsertionInfo();
@@ -238,7 +231,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
info.setTextToInsert(sb.toString());
return info;
}
/**
* {@inheritDoc}
*/
@@ -246,7 +239,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
public Parameter getParam(int index) {
return params.get(index);
}
/**
* Returns the number of parameters to this function.
*
@@ -257,7 +250,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
public int getParamCount() {
return params == null ? 0 : params.size();
}
/**
* {@inheritDoc}
*/
@@ -265,12 +258,11 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
public boolean getShowParameterToolTip() {
return true;
}
/**
* Returns the text to insert for a parameter.
*
* @param param
* The parameter.
* @param param The parameter.
* @return The text.
*/
private String getParamText(ParameterizedCompletion.Parameter param) {
@@ -283,7 +275,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
}
return text;
}
/**
* Returns the description of the return value of this function.
*
@@ -293,7 +285,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
public String getReturnValueDescription() {
return returnValDesc;
}
/**
* {@inheritDoc}
*/
@@ -308,7 +300,7 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
possiblyAddDefinedIn(sb);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@@ -320,13 +312,12 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
}
return text;
}
/**
* Sets the parameters to this function.
*
* @param params
* The parameters. This should be a list of
* {@link ParameterizedCompletion.Parameter}s.
* @param params The parameters. This should be a list of
* {@link ParameterizedCompletion.Parameter}s.
* @see #getParam(int)
* @see #getParamCount()
*/
@@ -336,12 +327,11 @@ public class FunctionCompletion extends VariableCompletion implements Parameteri
this.params = new ArrayList<Parameter>(params);
}
}
/**
* Sets the description of the return value of this function.
*
* @param desc
* The description.
* @param desc The description.
* @see #getReturnValueDescription()
*/
public void setReturnValueDescription(String desc) {
@@ -33,13 +33,13 @@ import org.fife.ui.rtextarea.ToolTipSupplier;
* <li>A documentation comment</li>
* </ul>
*
* This allows for different completion choices in comments than in code,
* for example.
* This allows for different completion choices in comments than in code, for
* example.
* <p>
*
* This provider also implements the
* <tt>org.fife.ui.rtextarea.ToolTipSupplier</tt> interface, which allows it
* to display tooltips for completion choices. Thus the standard
* <tt>org.fife.ui.rtextarea.ToolTipSupplier</tt> interface, which allows it to
* display tooltips for completion choices. Thus the standard
* {@link VariableCompletion} and {@link FunctionCompletion} completions should
* be able to display tooltips with the variable declaration or function
* definition (provided the <tt>RSyntaxTextArea</tt> was registered with the
@@ -49,10 +49,9 @@ import org.fife.ui.rtextarea.ToolTipSupplier;
* @version 1.0
*/
public class LanguageAwareCompletionProvider extends CompletionProviderBase implements ToolTipSupplier {
/**
* The provider to use when no provider is assigned to a particular token
* type.
* The provider to use when no provider is assigned to a particular token type.
*/
private CompletionProvider defaultProvider;
/**
@@ -67,41 +66,40 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
* The provider to use while in documentation comments.
*/
private CompletionProvider docCommentCompletionProvider;
/**
* Constructor subclasses can use when they don't have their default
* provider created at construction time. They should call
* Constructor subclasses can use when they don't have their default provider
* created at construction time. They should call
* {@link #setDefaultCompletionProvider(CompletionProvider)} in this
* constructor.
*/
protected LanguageAwareCompletionProvider() {}
protected LanguageAwareCompletionProvider() {
}
/**
* Constructor.
*
* @param defaultProvider
* The provider to use when no provider is assigned
* to a particular token type. This cannot be <code>null</code>.
* @param defaultProvider The provider to use when no provider is assigned to a
* particular token type. This cannot be
* <code>null</code>.
*/
public LanguageAwareCompletionProvider(CompletionProvider defaultProvider) {
setDefaultCompletionProvider(defaultProvider);
}
/**
* Calling this method will result in an
* {@link UnsupportedOperationException} being thrown. To set the
* parameter completion parameters, do so on the provider returned by
* {@link #getDefaultCompletionProvider()}.
* Calling this method will result in an {@link UnsupportedOperationException}
* being thrown. To set the parameter completion parameters, do so on the
* provider returned by {@link #getDefaultCompletionProvider()}.
*
* @throws UnsupportedOperationException
* Always.
* @throws UnsupportedOperationException Always.
* @see #setParameterizedCompletionParams(char, String, char)
*/
@Override
public void clearParameterizedCompletionParams() {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@@ -113,7 +111,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
CompletionProvider provider = getProviderFor(comp);
return provider != null ? provider.getAlreadyEnteredText(comp) : null;
}
/**
* Returns the completion provider to use for comments.
*
@@ -123,7 +121,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public CompletionProvider getCommentCompletionProvider() {
return commentCompletionProvider;
}
/**
* {@inheritDoc}
*/
@@ -131,14 +129,12 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public List<Completion> getCompletionsAt(JTextComponent tc, Point p) {
return defaultProvider == null ? null : defaultProvider.getCompletionsAt(tc, p);
}
/**
* Does the dirty work of creating a list of completions.
*
* @param comp
* The text component to look in.
* @return The list of possible completions, or an empty list if there
* are none.
* @param comp The text component to look in.
* @return The list of possible completions, or an empty list if there are none.
*/
@Override
protected List<Completion> getCompletionsImpl(JTextComponent comp) {
@@ -150,10 +146,10 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
}
return Collections.emptyList();
}
/**
* Returns the completion provider used when one isn't defined for a
* particular token type.
* Returns the completion provider used when one isn't defined for a particular
* token type.
*
* @return The completion provider to use.
* @see #setDefaultCompletionProvider(CompletionProvider)
@@ -161,7 +157,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public CompletionProvider getDefaultCompletionProvider() {
return defaultProvider;
}
/**
* Returns the completion provider to use for documentation comments.
*
@@ -171,7 +167,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public CompletionProvider getDocCommentCompletionProvider() {
return docCommentCompletionProvider;
}
/**
* {@inheritDoc}
*/
@@ -183,7 +179,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
CompletionProvider provider = getProviderFor(tc);
return provider == defaultProvider ? provider.getParameterizedCompletions(tc) : null;
}
/**
* {@inheritDoc}
*/
@@ -191,7 +187,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public char getParameterListEnd() {
return defaultProvider.getParameterListEnd();
}
/**
* {@inheritDoc}
*/
@@ -199,7 +195,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public String getParameterListSeparator() {
return defaultProvider.getParameterListSeparator();
}
/**
* {@inheritDoc}
*/
@@ -207,13 +203,12 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public char getParameterListStart() {
return defaultProvider.getParameterListStart();
}
/**
* Returns the completion provider to use at the current caret position in
* a text component.
* Returns the completion provider to use at the current caret position in a
* text component.
*
* @param comp
* The text component to check.
* @param comp The text component to check.
* @return The completion provider to use.
*/
private CompletionProvider getProviderFor(JTextComponent comp) {
@@ -242,15 +237,15 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
type = doc.getClosestStandardTokenTypeForInternalType(type);
}
switch (type) {
case Token.ERROR_STRING_DOUBLE:
return getStringCompletionProvider();
case Token.COMMENT_EOL:
case Token.COMMENT_MULTILINE:
return getCommentCompletionProvider();
case Token.COMMENT_DOCUMENTATION:
return getDocCommentCompletionProvider();
default:
return getDefaultCompletionProvider();
case Token.ERROR_STRING_DOUBLE:
return getStringCompletionProvider();
case Token.COMMENT_EOL:
case Token.COMMENT_MULTILINE:
return getCommentCompletionProvider();
case Token.COMMENT_DOCUMENTATION:
return getDocCommentCompletionProvider();
default:
return getDefaultCompletionProvider();
}
}
// FIXME: This isn't always a safe assumption.
@@ -261,27 +256,27 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
return getDefaultCompletionProvider();
}
switch (curToken.getType()) {
case Token.LITERAL_STRING_DOUBLE_QUOTE:
case Token.ERROR_STRING_DOUBLE:
return getStringCompletionProvider();
case Token.COMMENT_EOL:
case Token.COMMENT_MULTILINE:
return getCommentCompletionProvider();
case Token.COMMENT_DOCUMENTATION:
return getDocCommentCompletionProvider();
case Token.NULL:
case Token.WHITESPACE:
case Token.IDENTIFIER:
case Token.VARIABLE:
case Token.PREPROCESSOR:
case Token.DATA_TYPE:
case Token.FUNCTION:
case Token.OPERATOR:
return getDefaultCompletionProvider();
case Token.LITERAL_STRING_DOUBLE_QUOTE:
case Token.ERROR_STRING_DOUBLE:
return getStringCompletionProvider();
case Token.COMMENT_EOL:
case Token.COMMENT_MULTILINE:
return getCommentCompletionProvider();
case Token.COMMENT_DOCUMENTATION:
return getDocCommentCompletionProvider();
case Token.NULL:
case Token.WHITESPACE:
case Token.IDENTIFIER:
case Token.VARIABLE:
case Token.PREPROCESSOR:
case Token.DATA_TYPE:
case Token.FUNCTION:
case Token.OPERATOR:
return getDefaultCompletionProvider();
}
return null; // In a token type we can't auto-complete from.
}
/**
* Returns the completion provider to use for strings.
*
@@ -291,7 +286,7 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
public CompletionProvider getStringCompletionProvider() {
return stringCompletionProvider;
}
/**
* {@inheritDoc}
*/
@@ -300,24 +295,22 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
CompletionProvider provider = getProviderFor(tc);
return provider != null ? provider.isAutoActivateOkay(tc) : false;
}
/**
* Sets the comment completion provider.
*
* @param provider
* The provider to use in comments.
* @param provider The provider to use in comments.
* @see #getCommentCompletionProvider()
*/
public void setCommentCompletionProvider(CompletionProvider provider) {
this.commentCompletionProvider = provider;
}
/**
* Sets the default completion provider.
*
* @param provider
* The provider to use when no provider is assigned to a
* particular token type. This cannot be <code>null</code>.
* @param provider The provider to use when no provider is assigned to a
* particular token type. This cannot be <code>null</code>.
* @see #getDefaultCompletionProvider()
*/
public void setDefaultCompletionProvider(CompletionProvider provider) {
@@ -326,59 +319,53 @@ public class LanguageAwareCompletionProvider extends CompletionProviderBase impl
}
this.defaultProvider = provider;
}
/**
* Sets the documentation comment completion provider.
*
* @param provider
* The provider to use in comments.
* @param provider The provider to use in comments.
* @see #getDocCommentCompletionProvider()
*/
public void setDocCommentCompletionProvider(CompletionProvider provider) {
this.docCommentCompletionProvider = provider;
}
/**
* Calling this method will result in an
* {@link UnsupportedOperationException} being thrown. To set the
* parameter completion parameters, do so on the provider returned by
* {@link #getDefaultCompletionProvider()}.
* Calling this method will result in an {@link UnsupportedOperationException}
* being thrown. To set the parameter completion parameters, do so on the
* provider returned by {@link #getDefaultCompletionProvider()}.
*
* @throws UnsupportedOperationException
* Always.
* @throws UnsupportedOperationException Always.
* @see #clearParameterizedCompletionParams()
*/
@Override
public void setParameterizedCompletionParams(char listStart, String separator, char listEnd) {
throw new UnsupportedOperationException();
}
/**
* Sets the completion provider to use while in a string.
*
* @param provider
* The provider to use.
* @param provider The provider to use.
* @see #getStringCompletionProvider()
*/
public void setStringCompletionProvider(CompletionProvider provider) {
stringCompletionProvider = provider;
}
/**
* Returns the tool tip to display for a mouse event.
* <p>
*
* For this method to be called, the <tt>RSyntaxTextArea</tt> must be
* registered with the <tt>javax.swing.ToolTipManager</tt> like so:
* For this method to be called, the <tt>RSyntaxTextArea</tt> must be registered
* with the <tt>javax.swing.ToolTipManager</tt> like so:
*
* <pre>
* ToolTipManager.sharedInstance().registerComponent(textArea);
* </pre>
*
* @param textArea
* The text area.
* @param e
* The mouse event.
* @param textArea The text area.
* @param e The mouse event.
* @return The tool tip text, or <code>null</code> if none.
*/
@Override
@@ -8,14 +8,13 @@ package org.fife.ui.autocomplete;
import java.net.URL;
/**
* Possibly redirects one URL to another. Useful if you want "external" URL's
* in code completion documentation to point to a local copy instead, for
* example.
* Possibly redirects one URL to another. Useful if you want "external" URL's in
* code completion documentation to point to a local copy instead, for example.
*
* @author Robert Futrell
* @version 1.0
*/
public interface LinkRedirector {
public URL possiblyRedirect(URL original);
}
@@ -19,7 +19,7 @@ import org.fife.ui.autocomplete.ParameterizedCompletion.Parameter;
* @version 1.0
*/
public class MarkupTagCompletion extends AbstractCompletion {
private String name;
private String desc;
private String definedIn;
@@ -27,25 +27,22 @@ public class MarkupTagCompletion extends AbstractCompletion {
* Attributes of the tag.
*/
private List<Parameter> attrs;
/**
* Constructor.
*
* @param provider
* The parent provider instance.
* @param name
* The name of the tag.
* @param provider The parent provider instance.
* @param name The name of the tag.
*/
public MarkupTagCompletion(CompletionProvider provider, String name) {
super(provider);
this.name = name;
}
/**
* Adds HTML describing the attributes of this tag to a buffer.
*
* @param sb
* The buffer to append to.
* @param sb The buffer to append to.
*/
protected void addAttributes(StringBuilder sb) {
// TODO: Localize me.
@@ -67,11 +64,11 @@ public class MarkupTagCompletion extends AbstractCompletion {
sb.append("</td></tr></table></center><br><br>");
}
}
protected void addDefinitionString(StringBuilder sb) {
sb.append("<html><b>").append(name).append("</b>");
}
/**
* Returns all attributes of this tag.
*
@@ -82,19 +79,18 @@ public class MarkupTagCompletion extends AbstractCompletion {
public List<Parameter> getAttributes() {
return attrs;
}
/**
* Returns the specified {@link ParameterizedCompletion.Parameter}.
*
* @param index
* The index of the attribute to retrieve.
* @param index The index of the attribute to retrieve.
* @return The attribute.
* @see #getAttributeCount()
*/
public Parameter getAttribute(int index) {
return attrs.get(index);
}
/**
* Returns the number of attributes of this tag.
*
@@ -104,7 +100,7 @@ public class MarkupTagCompletion extends AbstractCompletion {
public int getAttributeCount() {
return attrs == null ? 0 : attrs.size();
}
/**
* Returns where this variable is defined.
*
@@ -114,19 +110,17 @@ public class MarkupTagCompletion extends AbstractCompletion {
public String getDefinedIn() {
return definedIn;
}
/**
* Returns a short description of this variable. This should be an
* HTML snippet.
* Returns a short description of this variable. This should be an HTML snippet.
*
* @return A short description of this variable. This may be
* <code>null</code>.
* @return A short description of this variable. This may be <code>null</code>.
* @see #setDescription(String)
*/
public String getDescription() {
return desc;
}
/**
* Returns the name of this tag.
*
@@ -135,7 +129,7 @@ public class MarkupTagCompletion extends AbstractCompletion {
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
@@ -143,7 +137,7 @@ public class MarkupTagCompletion extends AbstractCompletion {
public String getReplacementText() {
return getName();
}
/**
* {@inheritDoc}
*/
@@ -156,13 +150,12 @@ public class MarkupTagCompletion extends AbstractCompletion {
possiblyAddDefinedIn(sb);
return sb.toString();
}
/**
* Adds some HTML describing where this variable is defined, if this
* information is known.
* Adds some HTML describing where this variable is defined, if this information
* is known.
*
* @param sb
* The buffer to append to.
* @param sb The buffer to append to.
*/
protected void possiblyAddDefinedIn(StringBuilder sb) {
if (definedIn != null) {
@@ -170,13 +163,11 @@ public class MarkupTagCompletion extends AbstractCompletion {
sb.append(" <em>").append(definedIn).append("</em>");
}
}
/**
* Adds the description text as HTML to a buffer, if a description is
* defined.
* Adds the description text as HTML to a buffer, if a description is defined.
*
* @param sb
* The buffer to append to.
* @param sb The buffer to append to.
*/
protected void possiblyAddDescription(StringBuilder sb) {
if (desc != null) {
@@ -185,36 +176,31 @@ public class MarkupTagCompletion extends AbstractCompletion {
sb.append("<br><br><br>");
}
}
/**
* Sets where this variable is defined.
*
* @param definedIn
* Where this variable is defined.
* @param definedIn Where this variable is defined.
* @see #getDefinedIn()
*/
public void setDefinedIn(String definedIn) {
this.definedIn = definedIn;
}
/**
* Sets the short description of this tag. This should be an
* HTML snippet.
* Sets the short description of this tag. This should be an HTML snippet.
*
* @param desc
* A short description of this tag. This may be
* <code>null</code>.
* @param desc A short description of this tag. This may be <code>null</code>.
* @see #getDescription()
*/
public void setDescription(String desc) {
this.desc = desc;
}
/**
* Sets the attributes of this tag.
*
* @param attrs
* The attributes.
* @param attrs The attributes.
* @see #getAttribute(int)
* @see #getAttributeCount()
*/
@@ -19,40 +19,39 @@ import javax.swing.text.Position;
import javax.swing.text.View;
/**
* Highlight painter that draws an outline around the text. This is used to
* draw bounds around function/method parameters.
* Highlight painter that draws an outline around the text. This is used to draw
* bounds around function/method parameters.
*
* @author Robert Futrell
* @version 1.0
*/
/*
* NOTE: Whenever you see text like "Workaround for Java Highlight issues",
* this is because highlighted text in a JTextComponent gets "pushed" forward
* when the caret is at the Highlight's start, when we need it to instead get
* NOTE: Whenever you see text like "Workaround for Java Highlight issues", this
* is because highlighted text in a JTextComponent gets "pushed" forward when
* the caret is at the Highlight's start, when we need it to instead get
* prepended to. For this reason, the auto-complete package adds its Highlights
* 1 char too long (1 char earlier than where it should really start), but only
* paint the Highlight from the 2nd char on.
*/
class OutlineHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter {
/**
* DefaultHighlightPainter doesn't allow changing color, so we must cache
* ours here.
* DefaultHighlightPainter doesn't allow changing color, so we must cache ours
* here.
*/
private Color color;
/**
* Constructor.
*
* @param color
* The color to draw the bounding boxes with. This cannot
* be <code>null</code>.
* @param color The color to draw the bounding boxes with. This cannot be
* <code>null</code>.
*/
public OutlineHighlightPainter(Color color) {
super(color);
setColor(color);
}
/**
* Returns the color to paint bounding boxes with.
*
@@ -63,7 +62,7 @@ class OutlineHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter
public Color getColor() {
return color;
}
/**
* {@inheritDoc}
*/
@@ -110,12 +109,11 @@ class OutlineHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter
return null;
}
}
/**
* Sets the color to paint the bounding boxes with.
*
* @param color
* The new color. This cannot be <code>null</code>.
* @param color The new color. This cannot be <code>null</code>.
* @see #getColor()
*/
public void setColor(Color color) {
@@ -12,25 +12,23 @@ import java.util.List;
import javax.swing.text.JTextComponent;
/**
* Provides completions for a {@link ParameterizedCompletion}'s parameters.
* So, for example, if the user code-completes a function or method, if
* a <code>ParameterChoicesProvider</code> is installed, it can return possible
* Provides completions for a {@link ParameterizedCompletion}'s parameters. So,
* for example, if the user code-completes a function or method, if a
* <code>ParameterChoicesProvider</code> is installed, it can return possible
* completions for the parameters to that function or method.
*
* @author Robert Futrell
* @version 1.0
*/
public interface ParameterChoicesProvider {
/**
* Returns a list of choices for a specific parameter.
*
* @param tc
* The text component.
* @param param
* The currently focused parameter.
* @return The list of parameters. This may be <code>null</code> for
* "no parameters," but might also be an empty list.
* @param tc The text component.
* @param param The currently focused parameter.
* @return The list of parameters. This may be <code>null</code> for "no
* parameters," but might also be an empty list.
*/
public List<Completion> getParameterChoices(JTextComponent tc, ParameterizedCompletion.Parameter param);
}
@@ -15,26 +15,25 @@ import javax.swing.text.JTextComponent;
* @version 1.0
*/
public interface ParameterizedCompletion extends Completion {
/**
* Returns the "definition string" for this completion. For example,
* for the C "<code>printf</code>" function, this would return
* Returns the "definition string" for this completion. For example, for the C
* "<code>printf</code>" function, this would return
* "<code>int printf(const char *, ...)</code>".
*
* @return The definition string.
*/
public String getDefinitionString();
/**
* Returns the specified {@link Parameter}.
*
* @param index
* The index of the parameter to retrieve.
* @param index The index of the parameter to retrieve.
* @return The parameter.
* @see #getParamCount()
*/
public Parameter getParam(int index);
/**
* Returns the number of parameters this completion takes.
*
@@ -42,82 +41,73 @@ public interface ParameterizedCompletion extends Completion {
* @see #getParam(int)
*/
public int getParamCount();
public ParameterizedCompletionInsertionInfo getInsertionInfo(JTextComponent tc, boolean replaceTabsWithSpaces);
/**
* Returns whether a tool tip displaying assistance for each parameter
* while it is being edited is appropriate for this completion.
* Returns whether a tool tip displaying assistance for each parameter while it
* is being edited is appropriate for this completion.
*
* @return Whether the tool tip is appropriate to display.
*/
public boolean getShowParameterToolTip();
/**
* A parameter passed to a parameterized {@link Completion}.
*/
public static class Parameter {
private String name;
private Object type;
private String desc;
private boolean isEndParam;
/**
* Constructor.
*
* @param type
* The type of this parameter. This may be
* <code>null</code> for languages without specific types,
* dynamic typing, etc. Usually you'll pass a String for this
* value, but you may pass any object representing a type in
* your language, as long as its <code>toString()</code>
* method
* returns a string representation of the type.
* @param name
* The name of the parameter.
* @param type The type of this parameter. This may be <code>null</code> for
* languages without specific types, dynamic typing, etc. Usually
* you'll pass a String for this value, but you may pass any object
* representing a type in your language, as long as its
* <code>toString()</code> method returns a string representation of
* the type.
* @param name The name of the parameter.
*/
public Parameter(Object type, String name) {
this(type, name, false);
}
/**
* Constructor.
*
* @param type
* The type of this parameter. This may be
* <code>null</code> for languages without specific types,
* dynamic typing, etc. Usually you'll pass a String for this
* value, but you may pass any object representing a type in
* your language, as long as its <code>toString()</code>
* method
* returns a string representation of the type.
* @param name
* The name of the parameter.
* @param endParam
* Whether this parameter is an "ending parameter;"
* that is, whether this parameter is at a logical "ending
* point" in the completion text. If the user types in a
* parameter that is an ending point, parameter completion
* mode
* terminates. Set this to <code>true</code> for a trailing
* parameter after a function call's closing ')', for
* example.
* @param type The type of this parameter. This may be <code>null</code> for
* languages without specific types, dynamic typing, etc.
* Usually you'll pass a String for this value, but you may pass
* any object representing a type in your language, as long as
* its <code>toString()</code> method returns a string
* representation of the type.
* @param name The name of the parameter.
* @param endParam Whether this parameter is an "ending parameter;" that is,
* whether this parameter is at a logical "ending point" in the
* completion text. If the user types in a parameter that is an
* ending point, parameter completion mode terminates. Set this
* to <code>true</code> for a trailing parameter after a
* function call's closing ')', for example.
*/
public Parameter(Object type, String name, boolean endParam) {
this.name = name;
this.type = type;
this.isEndParam = endParam;
}
public String getDescription() {
return desc;
}
public String getName() {
return name;
}
/**
* Returns the type of this parameter, as a string.
*
@@ -126,7 +116,7 @@ public interface ParameterizedCompletion extends Completion {
public String getType() {
return type == null ? null : type.toString();
}
/**
* Returns the object used to describe the type of this parameter.
*
@@ -135,22 +125,21 @@ public interface ParameterizedCompletion extends Completion {
public Object getTypeObject() {
return type;
}
/**
* @return Whether this parameter is an "ending parameter;"
* that is, whether this parameter is at a logical "ending
* point" in the completion text. If the user types in a
* parameter that is an ending point, parameter completion mode
* terminates.
* @return Whether this parameter is an "ending parameter;" that is, whether
* this parameter is at a logical "ending point" in the completion text.
* If the user types in a parameter that is an ending point, parameter
* completion mode terminates.
*/
public boolean isEndParam() {
return isEndParam;
}
public void setDescription(String desc) {
this.desc = desc;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -28,17 +28,17 @@ import javax.swing.text.JTextComponent;
import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
/**
* A small popup window offering a list of likely choices for a parameter
* when the user has code-completed a parameterized completion. For example,
* if they have just code-completed the C function "<code>fprintf</code>",
* when entering the file name, this popup might display all local variables
* of type "<code>char *</code>".
* A small popup window offering a list of likely choices for a parameter when
* the user has code-completed a parameterized completion. For example, if they
* have just code-completed the C function "<code>fprintf</code>", when entering
* the file name, this popup might display all local variables of type
* "<code>char *</code>".
*
* @author Robert Futrell
* @version 1.0
*/
public class ParameterizedCompletionChoicesWindow extends JWindow {
/**
* The parent AutoCompletion instance.
*/
@@ -60,22 +60,20 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
*/
private JScrollPane sp;
/**
* Comparator used to sort completions by their relevance before sorting
* them lexicographically.
* Comparator used to sort completions by their relevance before sorting them
* lexicographically.
*/
private static final Comparator<Completion> sortByRelevanceComparator = new SortByRelevanceComparator();
/**
* Constructor.
*
* @param parent
* The parent window (hosting the text component).
* @param ac
* The auto-completion instance.
* @param context
* The completion context.
* @param parent The parent window (hosting the text component).
* @param ac The auto-completion instance.
* @param context The completion context.
*/
public ParameterizedCompletionChoicesWindow(Window parent, AutoCompletion ac, final ParameterizedCompletionContext context) {
public ParameterizedCompletionChoicesWindow(Window parent, AutoCompletion ac,
final ParameterizedCompletionContext context) {
super(parent);
this.ac = ac;
ComponentOrientation o = ac.getTextComponentOrientation();
@@ -85,7 +83,7 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
list.setCellRenderer(ac.getParamChoicesRenderer());
}
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
@@ -103,23 +101,21 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
decorator.decorate(this);
}
}
/**
* Returns the selected value.
*
* @return The selected value, or <code>null</code> if nothing is
* selected.
* @return The selected value, or <code>null</code> if nothing is selected.
*/
public String getSelectedChoice() {
Completion c = (Completion) list.getSelectedValue();
return c == null ? null : c.toString();
}
/**
* Changes the selected index.
*
* @param amount
* The amount by which to change the selected index.
* @param amount The amount by which to change the selected index.
*/
public void incSelection(int amount) {
int selection = list.getSelectedIndex();
@@ -133,14 +129,12 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
list.setSelectedIndex(selection);
list.ensureIndexIsVisible(selection);
}
/**
* Initializes this window to offer suggestions for the parameters of
* a specific completion.
* Initializes this window to offer suggestions for the parameters of a specific
* completion.
*
* @param pc
* The completion whose parameters we should offer suggestions
* for.
* @param pc The completion whose parameters we should offer suggestions for.
*/
public void initialize(ParameterizedCompletion pc) {
CompletionProvider provider = pc.getProvider();
@@ -158,12 +152,11 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
choicesListList.add(choices);
}
}
/**
* Sets the location of this window relative to the given rectangle.
*
* @param r
* The visual position of the caret (in screen coordinates).
* @param r The visual position of the caret (in screen coordinates).
*/
public void setLocationRelativeTo(Rectangle r) {
// Multi-monitor support - make sure the completion window (and
@@ -187,18 +180,16 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
}
setLocation(x, y);
}
/**
* Displays the choices for the specified parameter matching the given
* text. This will display or hide this popup window as necessary.
* Displays the choices for the specified parameter matching the given text.
* This will display or hide this popup window as necessary.
*
* @param param
* The index of the parameter the caret is currently in.
* This may be <code>-1</code> if not in a parameter (i.e., on
* the comma between parameters).
* @param prefix
* Text in the parameter before the dot. This may
* be <code>null</code> to represent the empty string.
* @param param The index of the parameter the caret is currently in. This may
* be <code>-1</code> if not in a parameter (i.e., on the comma
* between parameters).
* @param prefix Text in the parameter before the dot. This may be
* <code>null</code> to represent the empty string.
*/
public void setParameter(int param, String prefix) {
model.clear();
@@ -250,12 +241,11 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
setVisible(false);
}
}
/**
* Toggles the visibility of this popup window.
*
* @param visible
* Whether this window should be visible.
* @param visible Whether this window should be visible.
*/
@Override
public void setVisible(boolean visible) {
@@ -268,7 +258,7 @@ public class ParameterizedCompletionChoicesWindow extends JWindow {
super.setVisible(visible);
}
}
/**
* Updates the <tt>LookAndFeel</tt> of this window.
*/
@@ -48,8 +48,8 @@ import org.fife.ui.rtextarea.ChangeableHighlightPainter;
/**
* Manages UI and state specific to parameterized completions - the parameter
* description tool tip, the parameter completion choices list, the actual
* highlights in the editor, etc. This component installs new key bindings
* when appropriate to allow the user to cycle through the parameters of the
* highlights in the editor, etc. This component installs new key bindings when
* appropriate to allow the user to cycle through the parameters of the
* completion, and optionally cycle through completion choices for those
* parameters.
*
@@ -57,7 +57,7 @@ import org.fife.ui.rtextarea.ChangeableHighlightPainter;
* @version 1.0
*/
class ParameterizedCompletionContext {
/**
* The parent window.
*/
@@ -95,13 +95,13 @@ class ParameterizedCompletionContext {
*/
private Listener listener;
/**
* The minimum offset into the document that the caret can move to
* before this tool tip disappears.
* The minimum offset into the document that the caret can move to before this
* tool tip disappears.
*/
private int minPos;
/**
* The maximum offset into the document that the caret can move to
* before this tool tip disappears.
* The maximum offset into the document that the caret can move to before this
* tool tip disappears.
*/
private Position maxPos; // Moves with text inserted.
private Position defaultEndOffs;
@@ -140,7 +140,7 @@ class ParameterizedCompletionContext {
private static final String IM_KEY_ESCAPE = "ParamCompKey.Escape";
private static final String IM_KEY_ENTER = "ParamCompKey.Enter";
private static final String IM_KEY_CLOSING = "ParamCompKey.Closing";
/**
* Constructor.
*/
@@ -156,7 +156,7 @@ class ParameterizedCompletionContext {
tags = new ArrayList<Object>(1); // Usually small
paramCopyInfos = new ArrayList<ParamCopyInfo>(1);
}
/**
* Activates parameter completion support.
*
@@ -195,7 +195,7 @@ class ParameterizedCompletionContext {
prepareParamChoicesWindow();
paramChoicesWindow.setVisible(true);
}
/**
* Creates the completion window offering suggestions for parameters.
*
@@ -206,10 +206,9 @@ class ParameterizedCompletionContext {
pcw.initialize(pc);
return pcw;
}
/**
* Hides any popup windows and terminates parameterized completion
* assistance.
* Hides any popup windows and terminates parameterized completion assistance.
*
* @see #activate()
*/
@@ -226,15 +225,13 @@ class ParameterizedCompletionContext {
paramChoicesWindow.setVisible(false);
}
}
/**
* Returns the text inserted for the parameter containing the specified
* offset.
* Returns the text inserted for the parameter containing the specified offset.
*
* @param offs
* The offset into the document.
* @return The text of the parameter containing the offset, or
* <code>null</code> if the offset is not in a parameter.
* @param offs The offset into the document.
* @return The text of the parameter containing the offset, or <code>null</code>
* if the offset is not in a parameter.
*/
public String getArgumentText(int offs) {
List<Highlight> paramHighlights = getParameterHighlights();
@@ -258,12 +255,12 @@ class ParameterizedCompletionContext {
}
return null;
}
/**
* Returns the highlight of the current parameter.
*
* @return The current parameter's highlight, or <code>null</code> if
* the caret is not in a parameter's bounds.
* @return The current parameter's highlight, or <code>null</code> if the caret
* is not in a parameter's bounds.
* @see #getCurrentParameterStartOffset()
*/
private Highlight getCurrentParameterHighlight() {
@@ -280,7 +277,7 @@ class ParameterizedCompletionContext {
}
return null;
}
private int getCurrentParameterIndex() {
JTextComponent tc = ac.getTextComponent();
int dot = tc.getCaretPosition();
@@ -296,27 +293,26 @@ class ParameterizedCompletionContext {
}
return -1;
}
/**
* Returns the starting offset of the current parameter.
*
* @return The current parameter's starting offset, or <code>-1</code> if
* the caret is not in a parameter's bounds.
* @return The current parameter's starting offset, or <code>-1</code> if the
* caret is not in a parameter's bounds.
* @see #getCurrentParameterHighlight()
*/
private int getCurrentParameterStartOffset() {
Highlight h = getCurrentParameterHighlight();
return h != null ? h.getStartOffset() + 1 : -1;
}
/**
* Returns the highlight from a list that comes "first" in a list. Even
* though most parameter highlights are ordered, sometimes they aren't
* (e.g. the "cursor" parameter in a template completion is always last,
* even though it can be anywhere in the template).
* Returns the highlight from a list that comes "first" in a list. Even though
* most parameter highlights are ordered, sometimes they aren't (e.g. the
* "cursor" parameter in a template completion is always last, even though it
* can be anywhere in the template).
*
* @param highlights
* The list of highlights. Assumed to be non-empty.
* @param highlights The list of highlights. Assumed to be non-empty.
* @return The highlight that comes first in the document.
* @see #getLastHighlight(List)
*/
@@ -332,15 +328,14 @@ class ParameterizedCompletionContext {
}
return first;
}
/**
* Returns the highlight from a list that comes "last" in that list. Even
* though most parameter highlights are ordered, sometimes they aren't
* (e.g. the "cursor" parameter in a template completion is always last,
* even though it can be anywhere in the template.
* Returns the highlight from a list that comes "last" in that list. Even though
* most parameter highlights are ordered, sometimes they aren't (e.g. the
* "cursor" parameter in a template completion is always last, even though it
* can be anywhere in the template.
*
* @param highlights
* The list of highlights. Assumed to be non-empty.
* @param highlights The list of highlights. Assumed to be non-empty.
* @return The highlight that comes last in the document.
* @see #getFirstHighlight(List)
*/
@@ -356,7 +351,7 @@ class ParameterizedCompletionContext {
}
return last;
}
public List<Highlight> getParameterHighlights() {
List<Highlight> paramHighlights = new ArrayList<Highlight>(2);
JTextComponent tc = ac.getTextComponent();
@@ -369,12 +364,12 @@ class ParameterizedCompletionContext {
}
return paramHighlights;
}
/**
* Inserts the choice selected in the parameter choices window.
*
* @return Whether the choice was inserted. This will be <code>false</code>
* if the window is not visible, or no choice is selected.
* @return Whether the choice was inserted. This will be <code>false</code> if
* the window is not visible, or no choice is selected.
*/
boolean insertSelectedChoice() {
if (paramChoicesWindow != null && paramChoicesWindow.isVisible()) {
@@ -396,10 +391,10 @@ class ParameterizedCompletionContext {
}
return false;
}
/**
* Installs key bindings on the text component that facilitate the user
* editing this completion's parameters.
* Installs key bindings on the text component that facilitate the user editing
* this completion's parameters.
*
* @see #uninstallKeyBindings()
*/
@@ -447,7 +442,7 @@ class ParameterizedCompletionContext {
oldClosingAction = am.get(IM_KEY_CLOSING);
am.put(IM_KEY_CLOSING, new ClosingAction());
}
/**
* Moves to and selects the next parameter.
*
@@ -486,7 +481,7 @@ class ParameterizedCompletionContext {
tc.setSelectionEnd(currentNext.getEndOffset());
updateToolTipText(pos);
}
/**
* Moves to and selects the previous parameter.
*
@@ -507,8 +502,8 @@ class ParameterizedCompletionContext {
List<Highlight> highlights = getParameterHighlights();
for (int i = 0; i < highlights.size(); i++) {
Highlight h = highlights.get(i);
if (currentPrev == null || currentPrev.getStartOffset() >= dot
|| (h.getStartOffset() < selStart && (h.getStartOffset() > currentPrev.getStartOffset() || pos == lastSelectedParam))) {
if (currentPrev == null || currentPrev.getStartOffset() >= dot || (h.getStartOffset() < selStart
&& (h.getStartOffset() > currentPrev.getStartOffset() || pos == lastSelectedParam))) {
currentPrev = h;
pos = i;
}
@@ -533,7 +528,7 @@ class ParameterizedCompletionContext {
deactivate();
}
}
private void possiblyUpdateParamCopies(Document doc) {
int index = getCurrentParameterIndex();
// FunctionCompletions add an extra param at end of inserted text
@@ -567,7 +562,7 @@ class ParameterizedCompletionContext {
deactivate();
}
}
/**
* Updates the optional window listing likely completion choices,
*/
@@ -595,7 +590,7 @@ class ParameterizedCompletionContext {
paramChoicesWindow.setParameter(lastSelectedParam, paramPrefix);
}
}
/**
* Removes the bounding boxes around parameters.
*/
@@ -611,19 +606,16 @@ class ParameterizedCompletionContext {
}
paramCopyInfos.clear();
}
/**
* Replaces highlighted text with new text. Takes special care so that
* the highlight stays just around the newly-highlighted text, since
* Swing's <code>Highlight</code> classes are funny about insertions at
* their start offsets.
* Replaces highlighted text with new text. Takes special care so that the
* highlight stays just around the newly-highlighted text, since Swing's
* <code>Highlight</code> classes are funny about insertions at their start
* offsets.
*
* @param doc
* The document.
* @param h
* The highlight whose text to change.
* @param replacement
* The new text to be in the highlight.
* @param doc The document.
* @param h The highlight whose text to change.
* @param replacement The new text to be in the highlight.
* @return The replacement highlight for <code>h</code>.
*/
private Highlight replaceHighlightedText(Document doc, Highlight h, String replacement) {
@@ -646,7 +638,7 @@ class ParameterizedCompletionContext {
}
return null;
}
/**
* Removes the key bindings we installed.
*
@@ -682,11 +674,10 @@ class ParameterizedCompletionContext {
im.put(ks, oldClosingKey);
am.put(IM_KEY_CLOSING, oldClosingAction);
}
/**
* Updates the text in the tool tip to have the current parameter
* displayed in bold. The "current parameter" is determined from the
* current caret position.
* Updates the text in the tool tip to have the current parameter displayed in
* bold. The "current parameter" is determined from the current caret position.
*
* @return The "prefix" of text in the caret's parameter before the caret.
*/
@@ -718,7 +709,7 @@ class ParameterizedCompletionContext {
updateToolTipText(index);
return paramPrefix;
}
private void updateToolTipText(int selectedParam) {
if (selectedParam != lastSelectedParam) {
if (tip != null) {
@@ -727,7 +718,7 @@ class ParameterizedCompletionContext {
this.lastSelectedParam = selectedParam;
}
}
/**
* Updates the <code>LookAndFeel</code> of all popup windows this context
* manages.
@@ -740,12 +731,12 @@ class ParameterizedCompletionContext {
paramChoicesWindow.updateUI();
}
}
/**
* Called when the user presses Enter while entering parameters.
*/
private class GotoEndAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
// If the param choices window is visible and something is chosen,
@@ -771,19 +762,19 @@ class ParameterizedCompletionContext {
}
}
}
private Action getDefaultEnterAction(JTextComponent tc) {
ActionMap am = tc.getActionMap();
return am.get(DefaultEditorKit.insertBreakAction);
}
}
/**
* Called when the user types the character marking the closing of the
* parameter list, such as '<code>)</code>'.
* Called when the user types the character marking the closing of the parameter
* list, such as '<code>)</code>'.
*/
private class ClosingAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
JTextComponent tc = ac.getTextComponent();
@@ -812,7 +803,7 @@ class ParameterizedCompletionContext {
tc.replaceSelection(Character.toString(end));
}
}
public int getCount(String text, char ch) {
int count = 0;
int old = 0;
@@ -824,12 +815,12 @@ class ParameterizedCompletionContext {
return count;
}
}
/**
* Action performed when the user hits the escape key.
*/
private class HideAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
// On first escape press, if the param choices window is visible,
@@ -844,20 +835,19 @@ class ParameterizedCompletionContext {
}
}
}
/**
* Listens for various events in the text component while this tool tip
* is visible.
* Listens for various events in the text component while this tool tip is
* visible.
*/
private class Listener implements FocusListener, CaretListener, DocumentListener {
private boolean markOccurrencesEnabled;
/**
* Called when the text component's caret moves.
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void caretUpdate(CaretEvent e) {
@@ -875,37 +865,36 @@ class ParameterizedCompletionContext {
prepareParamChoicesWindow();
}
}
@Override
public void changedUpdate(DocumentEvent e) {}
public void changedUpdate(DocumentEvent e) {
}
/**
* Called when the text component gains focus.
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void focusGained(FocusEvent e) {
// Do nothing
}
/**
* Called when the text component loses focus.
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void focusLost(FocusEvent e) {
deactivate();
}
private void handleDocumentEvent(final DocumentEvent e) {
if (!ignoringDocumentEvents) {
ignoringDocumentEvents = true;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
possiblyUpdateParamCopies(e.getDocument());
@@ -914,17 +903,16 @@ class ParameterizedCompletionContext {
});
}
}
@Override
public void insertUpdate(DocumentEvent e) {
handleDocumentEvent(e);
}
/**
* Installs this listener onto a text component.
*
* @param tc
* The text component to install onto.
* @param tc The text component to install onto.
* @see #uninstall()
*/
public void install(JTextComponent tc) {
@@ -950,7 +938,8 @@ class ParameterizedCompletionContext {
}
for (int i = 0; i < info.getReplacementCopyCount(); i++) {
ReplacementCopy rc = info.getReplacementCopy(i);
paramCopyInfos.add(new ParamCopyInfo(rc.getId(), (Highlight) h.addHighlight(rc.getStart(), rc.getEnd(), paramCopyP)));
paramCopyInfos.add(new ParamCopyInfo(rc.getId(),
(Highlight) h.addHighlight(rc.getStart(), rc.getEnd(), paramCopyP)));
}
// Go back and start at the first parameter.
tc.setCaretPosition(info.getSelectionStart());
@@ -981,12 +970,12 @@ class ParameterizedCompletionContext {
tc.addFocusListener(this);
installKeyBindings();
}
@Override
public void removeUpdate(DocumentEvent e) {
handleDocumentEvent(e);
}
/**
* Uninstalls this listener from the current text component.
*/
@@ -1005,21 +994,21 @@ class ParameterizedCompletionContext {
removeParameterHighlights();
}
}
/**
* Action performed when the user presses the up or down arrow keys and
* the parameter completion choices popup is visible.
* Action performed when the user presses the up or down arrow keys and the
* parameter completion choices popup is visible.
*/
private class NextChoiceAction extends AbstractAction {
private Action oldAction;
private int amount;
public NextChoiceAction(int amount, Action oldAction) {
this.amount = amount;
this.oldAction = oldAction;
}
@Override
public void actionPerformed(ActionEvent e) {
if (paramChoicesWindow != null && paramChoicesWindow.isVisible()) {
@@ -1031,34 +1020,34 @@ class ParameterizedCompletionContext {
}
}
}
/**
* Action performed when the user hits the tab key.
*/
private class NextParamAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
moveToNextParam();
}
}
private static class ParamCopyInfo {
private String paramName;
private Highlight h;
public ParamCopyInfo(String paramName, Highlight h) {
this.paramName = paramName;
this.h = h;
}
}
/**
* Action performed when the user hits shift+tab.
*/
private class PrevParamAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
moveToPreviousParam();
@@ -28,7 +28,7 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
* @version 1.0
*/
class ParameterizedCompletionDescriptionToolTip {
/**
* The actual tool tip.
*/
@@ -41,23 +41,21 @@ class ParameterizedCompletionDescriptionToolTip {
* The completion being described.
*/
private ParameterizedCompletion pc;
/**
* Constructor.
*
* @param owner
* The parent window.
* @param ac
* The parent auto-completion.
* @param pc
* The completion being described.
* @param owner The parent window.
* @param ac The parent auto-completion.
* @param pc The completion being described.
*/
public ParameterizedCompletionDescriptionToolTip(Window owner, ParameterizedCompletionContext context, AutoCompletion ac,
ParameterizedCompletion pc) {
public ParameterizedCompletionDescriptionToolTip(Window owner, ParameterizedCompletionContext context,
AutoCompletion ac, ParameterizedCompletion pc) {
tooltip = new JWindow(owner);
this.pc = pc;
descLabel = new JLabel();
descLabel.setBorder(BorderFactory.createCompoundBorder(TipUtil.getToolTipBorder(), BorderFactory.createEmptyBorder(2, 5, 2, 5)));
descLabel.setBorder(BorderFactory.createCompoundBorder(TipUtil.getToolTipBorder(),
BorderFactory.createEmptyBorder(2, 5, 2, 5)));
descLabel.setOpaque(true);
descLabel.setBackground(TipUtil.getToolTipBackground());
// It appears that if a JLabel is set as a content pane directly, when
@@ -77,7 +75,7 @@ class ParameterizedCompletionDescriptionToolTip {
updateText(0);
tooltip.setFocusableWindowState(false);
}
/**
* Returns whether this tool tip is visible.
*
@@ -87,12 +85,11 @@ class ParameterizedCompletionDescriptionToolTip {
public boolean isVisible() {
return tooltip.isVisible();
}
/**
* Sets the location of this tool tip relative to the given rectangle.
*
* @param r
* The visual position of the caret (in screen coordinates).
* @param r The visual position of the caret (in screen coordinates).
*/
public void setLocationRelativeTo(Rectangle r) {
// Multi-monitor support - make sure the completion window (and
@@ -119,24 +116,22 @@ class ParameterizedCompletionDescriptionToolTip {
}
tooltip.setLocation(x, y);
}
/**
* Toggles the visibility of this tool tip.
*
* @param visible
* Whether this tool tip should be visible.
* @param visible Whether this tool tip should be visible.
* @see #isVisible()
*/
public void setVisible(boolean visible) {
tooltip.setVisible(visible);
}
/**
* Updates the text in the tool tip to have the current parameter
* displayed in bold.
* Updates the text in the tool tip to have the current parameter displayed in
* bold.
*
* @param selectedParam
* The index of the selected parameter.
* @param selectedParam The index of the selected parameter.
* @return Whether the text needed to be updated.
*/
public boolean updateText(int selectedParam) {
@@ -170,10 +165,9 @@ class ParameterizedCompletionDescriptionToolTip {
tooltip.pack();
return true;
}
/**
* Updates the <tt>LookAndFeel</tt> of this window and the description
* window.
* Updates the <tt>LookAndFeel</tt> of this window and the description window.
*/
public void updateUI() {
SwingUtilities.updateComponentTreeUI(tooltip);
@@ -22,7 +22,7 @@ import org.fife.ui.rsyntaxtextarea.DocumentRange;
* @version 1.0
*/
class ParameterizedCompletionInsertionInfo {
private int minOffs;
private Position maxOffs;
private int defaultEnd;
@@ -31,26 +31,24 @@ class ParameterizedCompletionInsertionInfo {
private String textToInsert;
private List<DocumentRange> replacementLocations;
private List<ReplacementCopy> replacementCopies;
public ParameterizedCompletionInsertionInfo() {
defaultEnd = -1;
}
public void addReplacementCopy(String id, int start, int end) {
if (replacementCopies == null) {
replacementCopies = new ArrayList<ReplacementCopy>(1);
}
replacementCopies.add(new ReplacementCopy(id, start, end));
}
/**
* Marks a region of the replacement text as representing a variable name
* or some other construct that the user should replace.
* Marks a region of the replacement text as representing a variable name or
* some other construct that the user should replace.
*
* @param start
* The start offset.
* @param end
* The end offset.
* @param start The start offset.
* @param end The end offset.
* @see #getReplacementCount()
* @see #getReplacementLocation(int)
*/
@@ -60,14 +58,14 @@ class ParameterizedCompletionInsertionInfo {
}
replacementLocations.add(new DocumentRange(start, end));
}
public int getDefaultEndOffs() {
return defaultEnd > -1 ? defaultEnd : getMaxOffset().getOffset();
}
/**
* Returns the maximum offset the caret can move to before being outside
* of the text inserted for this completion.
* Returns the maximum offset the caret can move to before being outside of the
* text inserted for this completion.
*
* @return The maximum offset.
* @see #getMinOffset()
@@ -75,10 +73,10 @@ class ParameterizedCompletionInsertionInfo {
public Position getMaxOffset() {
return maxOffs;
}
/**
* Returns the minimum offset the caret can move to before being outside
* of the text inserted for this completion.
* Returns the minimum offset the caret can move to before being outside of the
* text inserted for this completion.
*
* @return The minimum offset.
* @see #getMaxOffset()
@@ -86,11 +84,11 @@ class ParameterizedCompletionInsertionInfo {
public int getMinOffset() {
return minOffs;
}
public int getReplacementCopyCount() {
return replacementCopies == null ? 0 : replacementCopies.size();
}
/**
* Returns the number of replacements in the completion.
*
@@ -99,28 +97,27 @@ class ParameterizedCompletionInsertionInfo {
public int getReplacementCount() {
return replacementLocations == null ? 0 : replacementLocations.size();
}
public ReplacementCopy getReplacementCopy(int index) {
return replacementCopies.get(index);
}
/**
* Returns the starting- and ending-offsets of the replacement regions
* in the completion.
* Returns the starting- and ending-offsets of the replacement regions in the
* completion.
*
* @param index
* The replacement region.
* @param index The replacement region.
* @return The range in the document of that replacement region.
* @see #getReplacementCount()
*/
public DocumentRange getReplacementLocation(int index) {
return replacementLocations.get(index);
}
/**
* Returns the offset that should be the end of the initially selected
* text when the completion is inserted (i.e., the end offset of the first
* replacement region).
* Returns the offset that should be the end of the initially selected text when
* the completion is inserted (i.e., the end offset of the first replacement
* region).
*
* @return The end offset for the initial selection.
* @see #getSelectionStart()
@@ -128,11 +125,11 @@ class ParameterizedCompletionInsertionInfo {
public int getSelectionEnd() {
return selEnd;
}
/**
* Returns the offset that should be the start of the initially selected
* text when the completion is inserted (i.e., the start offset of the
* first replacement region).
* Returns the offset that should be the start of the initially selected text
* when the completion is inserted (i.e., the start offset of the first
* replacement region).
*
* @return The start offset for the initial selection.
* @see #getSelectionEnd()
@@ -140,7 +137,7 @@ class ParameterizedCompletionInsertionInfo {
public int getSelectionStart() {
return selStart;
}
/**
* Returns the actual text to insert when the completion is selected.
*
@@ -150,24 +147,22 @@ class ParameterizedCompletionInsertionInfo {
public String getTextToInsert() {
return textToInsert;
}
/**
* Returns whether or not there is an initial selected region for the
* completion (i.e., whether the completion actually has any parameters).
* Returns whether or not there is an initial selected region for the completion
* (i.e., whether the completion actually has any parameters).
*
* @return Whether there is a region to initially select for the completion.
*/
public boolean hasSelection() {
return selEnd != selStart;
}
/**
* Sets the initially selected region for the completion.
*
* @param selStart
* The selection start.
* @param selEnd
* The selection end.
* @param selStart The selection start.
* @param selEnd The selection end.
* @see #getSelectionEnd()
* @see #getSelectionStart()
*/
@@ -175,16 +170,14 @@ class ParameterizedCompletionInsertionInfo {
this.selStart = selStart;
this.selEnd = selEnd;
}
/**
* Sets the document range the caret can move around in before being
* outside of the text inserted for the completion.
* Sets the document range the caret can move around in before being outside of
* the text inserted for the completion.
*
* @param minOffs
* The minimum offset.
* @param maxOffs
* The maximum offset, that will track its location as the
* document is modified.
* @param minOffs The minimum offset.
* @param maxOffs The maximum offset, that will track its location as the
* document is modified.
* @see #getMinOffset()
* @see #getMaxOffset()
*/
@@ -192,42 +185,41 @@ class ParameterizedCompletionInsertionInfo {
this.minOffs = minOffs;
this.maxOffs = maxOffs;
}
public void setDefaultEndOffs(int end) {
defaultEnd = end;
}
/**
* Sets the text to insert for the completion.
*
* @param text
* The text to insert.
* @param text The text to insert.
* @see #getTextToInsert()
*/
public void setTextToInsert(String text) {
this.textToInsert = text;
}
public static class ReplacementCopy {
private String id;
private int start;
private int end;
public ReplacementCopy(String id, int start, int end) {
this.id = id;
this.start = start;
this.end = end;
}
public int getEnd() {
return end;
}
public String getId() {
return id;
}
public int getStart() {
return start;
}
@@ -14,8 +14,8 @@ import javax.swing.Action;
/**
* An <code>AutoCompletion</code> that adds the ability to cycle through a set
* of <code>CompletionProvider</code>s via the trigger key. This allows the
* application to logically "group together" completions of similar kinds;
* for example, Java code completions vs. template completions.
* application to logically "group together" completions of similar kinds; for
* example, Java code completions vs. template completions.
* <p>
*
* Usage:
@@ -33,15 +33,14 @@ import javax.swing.Action;
* @author mschlegel
*/
public class RoundRobinAutoCompletion extends AutoCompletion {
/** The List of CompletionProviders to use */
private List<CompletionProvider> cycle = new ArrayList<CompletionProvider>();
/**
* Constructor.
*
* @param provider
* A single completion provider.
* @param provider A single completion provider.
* @see #addCompletionProvider(CompletionProvider)
*/
public RoundRobinAutoCompletion(CompletionProvider provider) {
@@ -58,25 +57,24 @@ public class RoundRobinAutoCompletion extends AutoCompletion {
// chosen.
setAutoCompleteSingleChoices(false);
}
/**
* Adds an additional <code>CompletionProvider</code> to the list to
* cycle through.
* Adds an additional <code>CompletionProvider</code> to the list to cycle
* through.
*
* @param provider
* The new completion provider.
* @param provider The new completion provider.
*/
public void addCompletionProvider(CompletionProvider provider) {
cycle.add(provider);
}
/**
* Moves to the next Provider internally. Needs refresh of the popup window
* to display the changes.
* Moves to the next Provider internally. Needs refresh of the popup window to
* display the changes.
*
* @return true if the next provider was the default one (thus returned to
* the default view). May be used in case you like to hide the
* popup in this case.
* @return true if the next provider was the default one (thus returned to the
* default view). May be used in case you like to hide the popup in this
* case.
*/
public boolean advanceProvider() {
CompletionProvider currentProvider = getCompletionProvider();
@@ -84,7 +82,7 @@ public class RoundRobinAutoCompletion extends AutoCompletion {
setCompletionProvider(cycle.get(i));
return i == 0;
}
/**
* Overridden to provide our own implementation of the action.
*/
@@ -92,7 +90,7 @@ public class RoundRobinAutoCompletion extends AutoCompletion {
protected Action createAutoCompleteAction() {
return new CycleAutoCompleteAction();
}
/**
* Resets the cycle to use the default provider on next refresh.
*/
@@ -103,14 +101,14 @@ public class RoundRobinAutoCompletion extends AutoCompletion {
setCompletionProvider(defaultProvider);
}
}
/**
* An implementation of the auto-complete action that ensures the proper
* <code>CompletionProvider</code> is displayed based on the context in
* which the user presses the trigger key.
* <code>CompletionProvider</code> is displayed based on the context in which
* the user presses the trigger key.
*/
private class CycleAutoCompleteAction extends AutoCompleteAction {
@Override
public void actionPerformed(ActionEvent e) {
if (isAutoCompleteEnabled()) {
@@ -17,68 +17,58 @@ package org.fife.ui.autocomplete;
* @version 1.0
*/
public class ShorthandCompletion extends BasicCompletion {
/**
* The text the user can start typing that will match this completion.
*/
private String inputText;
/**
* Constructor.
*
* @param provider
* The provider that returns this completion.
* @param inputText
* The text the user inputs to get this completion.
* @param replacementText
* The replacement text of the completion.
* @param provider The provider that returns this completion.
* @param inputText The text the user inputs to get this completion.
* @param replacementText The replacement text of the completion.
*/
public ShorthandCompletion(CompletionProvider provider, String inputText, String replacementText) {
super(provider, replacementText);
this.inputText = inputText;
}
/**
* Constructor.
*
* @param provider
* The provider that returns this completion.
* @param inputText
* The text the user inputs to get this completion.
* @param replacementText
* The replacement text of the completion.
* @param shortDesc
* A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
* @param provider The provider that returns this completion.
* @param inputText The text the user inputs to get this completion.
* @param replacementText The replacement text of the completion.
* @param shortDesc A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
*/
public ShorthandCompletion(CompletionProvider provider, String inputText, String replacementText, String shortDesc) {
public ShorthandCompletion(CompletionProvider provider, String inputText, String replacementText,
String shortDesc) {
super(provider, replacementText, shortDesc);
this.inputText = inputText;
}
/**
* Constructor.
*
* @param provider
* The provider that returns this completion.
* @param inputText
* The text the user inputs to get this completion.
* @param replacementText
* The replacement text of the completion.
* @param shortDesc
* A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
* @param summary
* The summary of this completion. This should be HTML.
* This may be <code>null</code>.
* @param provider The provider that returns this completion.
* @param inputText The text the user inputs to get this completion.
* @param replacementText The replacement text of the completion.
* @param shortDesc A short description of the completion. This will be
* displayed in the completion list. This may be
* <code>null</code>.
* @param summary The summary of this completion. This should be HTML.
* This may be <code>null</code>.
*/
public ShorthandCompletion(CompletionProvider provider, String inputText, String replacementText, String shortDesc, String summary) {
public ShorthandCompletion(CompletionProvider provider, String inputText, String replacementText, String shortDesc,
String summary) {
super(provider, replacementText, shortDesc, summary);
this.inputText = inputText;
}
/**
* Returns the text the user must start typing to get this completion.
*
@@ -88,13 +78,12 @@ public class ShorthandCompletion extends BasicCompletion {
public String getInputText() {
return inputText;
}
/**
* If a summary has been set, that summary is returned. Otherwise, the
* replacement text is returned.
*
* @return A description of this completion (the text that will be
* inserted).
* @return A description of this completion (the text that will be inserted).
* @see #getReplacementText()
*/
@Override
@@ -102,11 +91,11 @@ public class ShorthandCompletion extends BasicCompletion {
String summary = super.getSummary();
return summary != null ? summary : ("<html><body>" + getSummaryBody());
}
/**
* Returns the "body" of the HTML returned by {@link #getSummary()} when
* no summary text has been set. This is defined to return the replacement
* text in a monospaced font.
* Returns the "body" of the HTML returned by {@link #getSummary()} when no
* summary text has been set. This is defined to return the replacement text in
* a monospaced font.
*
* @return The summary text's body, if no other summary has been defined.
* @see #getReplacementText()
+21 -24
View File
@@ -37,32 +37,31 @@ import javax.swing.event.MouseInputAdapter;
* @version 1.0
*/
class SizeGrip extends JPanel {
/**
* The size grip to use if we're on OS X.
*/
private Image osxSizeGrip;
public SizeGrip() {
MouseHandler adapter = new MouseHandler();
addMouseListener(adapter);
addMouseMotionListener(adapter);
setPreferredSize(new Dimension(16, 16));
}
/**
* Overridden to ensure that the cursor for this component is appropriate
* for the orientation.
* Overridden to ensure that the cursor for this component is appropriate for
* the orientation.
*
* @param o
* The new orientation.
* @param o The new orientation.
*/
@Override
public void applyComponentOrientation(ComponentOrientation o) {
possiblyFixCursor(o.isLeftToRight());
super.applyComponentOrientation(o);
}
/**
* Creates and returns the OS X size grip image.
*
@@ -94,12 +93,11 @@ class SizeGrip extends JPanel {
}
return image;
}
/**
* Paints this panel.
*
* @param g
* The graphics context.
* @param g The graphics context.
*/
@Override
protected void paintComponent(Graphics g) {
@@ -147,13 +145,12 @@ class SizeGrip extends JPanel {
g.fillRect(2, height - 9, 2, 2);
}
}
/**
* Ensures that the cursor for this component is appropriate for the
* orientation.
*
* @param ltr
* Whether the current component orientation is LTR.
* @param ltr Whether the current component orientation is LTR.
*/
protected void possiblyFixCursor(boolean ltr) {
int cursor = Cursor.NE_RESIZE_CURSOR;
@@ -164,7 +161,7 @@ class SizeGrip extends JPanel {
setCursor(Cursor.getPredefinedCursor(cursor));
}
}
@Override
public void updateUI() {
super.updateUI();
@@ -178,21 +175,21 @@ class SizeGrip extends JPanel {
osxSizeGrip = null;
}
}
/**
* Listens for mouse events on this panel and resizes the parent window
* appropriately.
*/
/*
* NOTE: We use SwingUtilities.convertPointToScreen() instead of just using
* the locations relative to the corner component because the latter proved
* buggy - stretch the window too wide and some kind of arithmetic error
* started happening somewhere - our window would grow way too large.
* NOTE: We use SwingUtilities.convertPointToScreen() instead of just using the
* locations relative to the corner component because the latter proved buggy -
* stretch the window too wide and some kind of arithmetic error started
* happening somewhere - our window would grow way too large.
*/
private class MouseHandler extends MouseInputAdapter {
private Point origPos;
@Override
public void mouseDragged(MouseEvent e) {
Point newPos = e.getPoint();
@@ -222,13 +219,13 @@ class SizeGrip extends JPanel {
}
origPos.setLocation(newPos);
}
@Override
public void mousePressed(MouseEvent e) {
origPos = e.getPoint();
SwingUtilities.convertPointToScreen(origPos, SizeGrip.this);
}
@Override
public void mouseReleased(MouseEvent e) {
origPos = null;
@@ -10,14 +10,14 @@ package org.fife.ui.autocomplete;
import java.util.Comparator;
/**
* Compares two <code>Completion</code>s by their relevance before
* sorting them lexicographically.
* Compares two <code>Completion</code>s by their relevance before sorting them
* lexicographically.
*
* @author Robert Futrell
* @version 1.0
*/
public class SortByRelevanceComparator implements Comparator<Completion> {
@Override
public int compare(Completion c1, Completion c2) {
int rel1 = c1.getRelevance();
@@ -37,12 +37,12 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
* }
* </pre>
*
* In the above example, the first <code>${i}</code> is a parameter for the
* user to type into; all the other <code>${i}</code> instances are
* automatically changed to what the user types in the first one. The parameter
* named <code>${cursor}</code> is the "ending position" of the template. It's
* where the caret moves after it cycles through all other parameters. If the
* user types into it, template mode terminates. If more than one
* In the above example, the first <code>${i}</code> is a parameter for the user
* to type into; all the other <code>${i}</code> instances are automatically
* changed to what the user types in the first one. The parameter named
* <code>${cursor}</code> is the "ending position" of the template. It's where
* the caret moves after it cycles through all other parameters. If the user
* types into it, template mode terminates. If more than one
* <code>${cursor}</code> parameter is specified, behavior is undefined.
* <p>
*
@@ -51,15 +51,15 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
* fault-tolerant.
* <p>
*
* Leading whitespace is automatically added to lines if the template spans
* more than one line, and if used with a text component using a
* Leading whitespace is automatically added to lines if the template spans more
* than one line, and if used with a text component using a
* <code>PlainDocument</code>, tabs will be converted to spaces if requested.
*
* @author Robert Futrell
* @version 1.0
*/
public class TemplateCompletion extends AbstractCompletion implements ParameterizedCompletion {
private List<TemplatePiece> pieces;
private String inputText;
private String definitionString;
@@ -69,11 +69,11 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
* The template's parameters.
*/
private List<Parameter> params;
public TemplateCompletion(CompletionProvider provider, String inputText, String definitionString, String template) {
this(provider, inputText, definitionString, template, null, null);
}
public TemplateCompletion(CompletionProvider provider, String inputText, String definitionString, String template,
String shortDescription, String summary) {
super(provider);
@@ -85,7 +85,7 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
params = new ArrayList<Parameter>(3);
parse(template);
}
private void addTemplatePiece(TemplatePiece piece) {
pieces.add(piece);
if (piece instanceof Param && !"cursor".equals(piece.getText())) {
@@ -94,12 +94,12 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
params.add(param);
}
}
@Override
public String getInputText() {
return inputText;
}
private String getPieceText(int index, String leadingWS) {
TemplatePiece piece = pieces.get(index);
String text = piece.getText();
@@ -108,10 +108,10 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
}
return text;
}
/**
* Returns <code>null</code>; template completions insert all of their
* text via <code>getInsertionInfo()</code>.
* Returns <code>null</code>; template completions insert all of their text via
* <code>getInsertionInfo()</code>.
*
* @return <code>null</code> always.
*/
@@ -119,21 +119,21 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
public String getReplacementText() {
return null;
}
@Override
public String getSummary() {
return summary;
}
@Override
public String getDefinitionString() {
return definitionString;
}
public String getShortDescription() {
return shortDescription;
}
/**
* {@inheritDoc}
*/
@@ -141,7 +141,7 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
public boolean getShowParameterToolTip() {
return false;
}
@Override
public ParameterizedCompletionInsertionInfo getInsertionInfo(JTextComponent tc, boolean replaceTabsWithSpaces) {
ParameterizedCompletionInsertionInfo info = new ParameterizedCompletionInsertionInfo();
@@ -214,7 +214,7 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
info.setTextToInsert(sb.toString());
return info;
}
/**
* {@inheritDoc}
*/
@@ -222,7 +222,7 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
public Parameter getParam(int index) {
return params.get(index);
}
/**
* {@inheritDoc}
*/
@@ -230,12 +230,11 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
public int getParamCount() {
return params == null ? 0 : params.size();
}
/**
* Returns whether a parameter is already defined with a specific name.
*
* @param name
* The name.
* @param name The name.
* @return Whether a parameter is defined with that name.
*/
private boolean isParamDefined(String name) {
@@ -247,12 +246,11 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
}
return false;
}
/**
* Parses a template string into logical pieces used by this class.
*
* @param template
* The template to parse.
* @param template The template to parse.
*/
private void parse(String template) {
int offs = 0;
@@ -260,23 +258,23 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
while ((offs = template.indexOf('$', lastOffs)) > -1 && offs < template.length() - 1) {
char next = template.charAt(offs + 1);
switch (next) {
case '$': // "$$" => escaped single dollar sign
addTemplatePiece(new TemplatePiece.Text(template.substring(lastOffs, offs + 1)));
lastOffs = offs + 2;
break;
case '{': // "${...}" => variable
int closingCurly = template.indexOf('}', offs + 2);
if (closingCurly > -1) {
addTemplatePiece(new TemplatePiece.Text(template.substring(lastOffs, offs)));
String varName = template.substring(offs + 2, closingCurly);
if (!"cursor".equals(varName) && isParamDefined(varName)) {
addTemplatePiece(new TemplatePiece.ParamCopy(varName));
} else {
addTemplatePiece(new TemplatePiece.Param(varName));
}
lastOffs = closingCurly + 1;
case '$': // "$$" => escaped single dollar sign
addTemplatePiece(new TemplatePiece.Text(template.substring(lastOffs, offs + 1)));
lastOffs = offs + 2;
break;
case '{': // "${...}" => variable
int closingCurly = template.indexOf('}', offs + 2);
if (closingCurly > -1) {
addTemplatePiece(new TemplatePiece.Text(template.substring(lastOffs, offs)));
String varName = template.substring(offs + 2, closingCurly);
if (!"cursor".equals(varName) && isParamDefined(varName)) {
addTemplatePiece(new TemplatePiece.ParamCopy(varName));
} else {
addTemplatePiece(new TemplatePiece.Param(varName));
}
break;
lastOffs = closingCurly + 1;
}
break;
}
}
if (lastOffs < template.length()) {
@@ -284,7 +282,7 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
addTemplatePiece(new TemplatePiece.Text(text));
}
}
private int possiblyReplaceTabsWithSpaces(StringBuilder sb, String text, JTextComponent tc, int start) {
int tab = text.indexOf('\t');
if (tab > -1) {
@@ -315,18 +313,17 @@ public class TemplateCompletion extends AbstractCompletion implements Parameteri
}
return start;
}
/**
* Sets the short description of this template completion.
*
* @param shortDesc
* The new short description.
* @param shortDesc The new short description.
* @see #getShortDescription()
*/
public void setShortDescription(String shortDesc) {
this.shortDescription = shortDesc;
}
@Override
public String toString() {
return getDefinitionString();
+18 -18
View File
@@ -7,68 +7,68 @@
package org.fife.ui.autocomplete;
/**
* A piece of a <code>TemplateCompletion</code>. You add instances of this
* class to template completions to define them.
* A piece of a <code>TemplateCompletion</code>. You add instances of this class
* to template completions to define them.
*
* @author Robert Futrell
* @version 1.0
* @see TemplateCompletion
*/
interface TemplatePiece {
String getText();
public class Text implements TemplatePiece {
private String text;
public Text(String text) {
this.text = text;
}
@Override
public String getText() {
return text;
}
@Override
public String toString() {
return "[TemplatePiece.Text: text=" + text + "]";
}
}
public class Param implements TemplatePiece {
String text;
public Param(String text) {
this.text = text;
}
@Override
public String getText() {
return text;
}
@Override
public String toString() {
return "[TemplatePiece.Param: param=" + text + "]";
}
}
public class ParamCopy implements TemplatePiece {
private String text;
public ParamCopy(String text) {
this.text = text;
}
@Override
public String getText() {
return text;
}
@Override
public String toString() {
return "[TemplatePiece.ParamCopy: param=" + text + "]";
+23 -24
View File
@@ -22,17 +22,18 @@ import javax.swing.text.html.HTMLDocument;
* Static utility methods for homemade tool tips.
* <p>
*
* This is blatantly ripped off from RSyntaxTextArea's "FocusableTips" class
* of the same name, but isn't re-used to prevent a hard dependency on the
* RSTA library.
* This is blatantly ripped off from RSyntaxTextArea's "FocusableTips" class of
* the same name, but isn't re-used to prevent a hard dependency on the RSTA
* library.
*
* @author Robert Futrell
* @version 1.0
*/
class TipUtil {
private TipUtil() {}
private TipUtil() {
}
/**
* Returns the default background color to use for tool tip windows.
*
@@ -55,7 +56,7 @@ class TipUtil {
}
return c;
}
/**
* Returns the border used by tool tips in this look and feel.
*
@@ -71,21 +72,20 @@ class TipUtil {
}
return border;
}
/**
* Returns whether a color is a Nimbus DerivedColor, which is troublesome
* in that it doesn't use its RGB values (uses HSB instead?) and so
* querying them is useless.
* Returns whether a color is a Nimbus DerivedColor, which is troublesome in
* that it doesn't use its RGB values (uses HSB instead?) and so querying them
* is useless.
*
* @param c
* The color to check.
* @param c The color to check.
* @return Whether it is a DerivedColor
*/
private static final boolean isDerivedColor(Color c) {
return c != null
&& (c.getClass().getName().endsWith(".DerivedColor") || c.getClass().getName().endsWith(".DerivedColor$UIResource"));
return c != null && (c.getClass().getName().endsWith(".DerivedColor")
|| c.getClass().getName().endsWith(".DerivedColor$UIResource"));
}
/**
* Returns whether the Nimbus Look and Feel is installed.
*
@@ -94,14 +94,13 @@ class TipUtil {
private static final boolean isNimbusLookAndFeel() {
return UIManager.getLookAndFeel().getName().equals("Nimbus");
}
/**
* Tweaks a <code>JEditorPane</code> so it can be used to render the
* content in a focusable pseudo-tool tip. It is assumed that the editor
* pane is using an <code>HTMLDocument</code>.
* Tweaks a <code>JEditorPane</code> so it can be used to render the content in
* a focusable pseudo-tool tip. It is assumed that the editor pane is using an
* <code>HTMLDocument</code>.
*
* @param textArea
* The editor pane to tweak.
* @param textArea The editor pane to tweak.
*/
public static void tweakTipEditorPane(JEditorPane textArea) {
// Jump through a few hoops to get things looking nice in Nimbus
@@ -134,8 +133,8 @@ class TipUtil {
font = new Font("SansSerif", Font.PLAIN, 12);
}
HTMLDocument doc = (HTMLDocument) textArea.getDocument();
doc.getStyleSheet().addRule("body { font-family: " + font.getFamily() + "; font-size: " + font.getSize() + "pt" + "; color: "
+ Util.getHexString(fg) + "; }");
doc.getStyleSheet().addRule("body { font-family: " + font.getFamily() + "; font-size: " + font.getSize() + "pt"
+ "; color: " + Util.getHexString(fg) + "; }");
// Always add link foreground rule. Unfortunately these CSS rules
// stack each time the LaF is changed (how can we overwrite them
// without clearing out the important "standard" ones?).
+59 -67
View File
@@ -28,31 +28,31 @@ import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
* @version 1.0
*/
public class Util {
/**
* If a system property is defined with this name and set, ignoring case,
* to <code>true</code>, this library will not attempt to use Substance
* renderers. Otherwise, if a Substance Look and Feel is installed, we
* will attempt to use Substance cell renderers in all of our dropdowns.
* If a system property is defined with this name and set, ignoring case, to
* <code>true</code>, this library will not attempt to use Substance renderers.
* Otherwise, if a Substance Look and Feel is installed, we will attempt to use
* Substance cell renderers in all of our dropdowns.
* <p>
*
* Note that we do not have a build dependency on Substance, so all access
* to Substance stuff is done via reflection. We will fall back onto
* default renderers if something goes horribly wrong.
* Note that we do not have a build dependency on Substance, so all access to
* Substance stuff is done via reflection. We will fall back onto default
* renderers if something goes horribly wrong.
*/
public static final String PROPERTY_DONT_USE_SUBSTANCE_RENDERERS = "org.fife.ui.autocomplete.DontUseSubstanceRenderers";
/**
* If this system property is <code>true</code>, then even the "main" two
* auto-complete windows will allow window decorations via
* {@link PopupWindowDecorator}. If this property is undefined or
* <code>false</code>, they won't honor such decorations. This is due to
* certain performance issues with translucent windows (used for drop
* shadows), even as of Java 7u2.
* <code>false</code>, they won't honor such decorations. This is due to certain
* performance issues with translucent windows (used for drop shadows), even as
* of Java 7u2.
*/
public static final String PROPERTY_ALLOW_DECORATED_AUTOCOMPLETE_WINDOWS = "org.fife.ui.autocomplete.allowDecoratedAutoCompleteWindows";
/**
* Used for the color of hyperlinks when a LookAndFeel uses light text
* against a dark background.
* Used for the color of hyperlinks when a LookAndFeel uses light text against a
* dark background.
*/
private static final Color LIGHT_HYPERLINK_FG = new Color(0xd8ffff);
private static final Pattern TAG_PATTERN = Pattern.compile("<[^>]*>");
@@ -60,15 +60,14 @@ public class Util {
private static boolean desktopCreationAttempted;
private static Object desktop;
private static final Object LOCK_DESKTOP_CREATION = new Object();
/**
* Attempts to open a web browser to the specified URI.
*
* @param uri
* The URI to open. If this is <code>null</code>, nothing
* happens and this method returns <code>false</code>.
* @return Whether the operation was successful. This will be
* <code>false</code> on JRE's older than 1.6.
* @param uri The URI to open. If this is <code>null</code>, nothing happens and
* this method returns <code>false</code>.
* @return Whether the operation was successful. This will be <code>false</code>
* on JRE's older than 1.6.
*/
public static boolean browse(URI uri) {
boolean success = false;
@@ -88,11 +87,11 @@ public class Util {
}
return success;
}
/**
* Returns the singleton <code>java.awt.Desktop</code> instance, or
* <code>null</code> if it is unsupported on this platform (or the JRE
* is older than 1.6).
* <code>null</code> if it is unsupported on this platform (or the JRE is older
* than 1.6).
*
* @return The desktop, as an {@link Object}.
*/
@@ -117,14 +116,13 @@ public class Util {
}
return desktop;
}
/**
* Returns a hex string for the specified color, suitable for HTML.
*
* @param c
* The color.
* @return The string representation, in the form "<code>#rrggbb</code>",
* or <code>null</code> if <code>c</code> is <code>null</code>.
* @param c The color.
* @return The string representation, in the form "<code>#rrggbb</code>", or
* <code>null</code> if <code>c</code> is <code>null</code>.
*/
public static String getHexString(Color c) {
if (c == null) {
@@ -150,12 +148,12 @@ public class Util {
sb.append(Integer.toHexString(b));
return sb.toString();
}
/**
* Returns the color to use for hyperlink-style components. This method
* will return <code>Color.blue</code> unless it appears that the current
* LookAndFeel uses light text on a dark background, in which case a
* brighter alternative is returned.
* Returns the color to use for hyperlink-style components. This method will
* return <code>Color.blue</code> unless it appears that the current LookAndFeel
* uses light text on a dark background, in which case a brighter alternative is
* returned.
*
* @return The color to use for hyperlinks.
*/
@@ -168,16 +166,14 @@ public class Util {
}
return isLightForeground(fg) ? LIGHT_HYPERLINK_FG : Color.blue;
}
/**
* Returns the screen coordinates for the monitor that contains the
* specified point. This is useful for setups with multiple monitors,
* to ensure that popup windows are positioned properly.
* Returns the screen coordinates for the monitor that contains the specified
* point. This is useful for setups with multiple monitors, to ensure that popup
* windows are positioned properly.
*
* @param x
* The x-coordinate, in screen coordinates.
* @param y
* The y-coordinate, in screen coordinates.
* @param x The x-coordinate, in screen coordinates.
* @param y The y-coordinate, in screen coordinates.
* @return The bounds of the monitor that contains the specified point.
*/
public static Rectangle getScreenBoundsForPoint(int x, int y) {
@@ -193,12 +189,12 @@ public class Util {
// If point is outside all monitors, default to default monitor (?)
return env.getMaximumWindowBounds();
}
/**
* Give apps a chance to decorate us with drop shadows, etc. Since very
* scrolly things such as lists (of e.g. completions) are *very* slow when
* in per-pixel translucent windows, even as of Java 7u2, we force the user
* to specify an extra option for the two "main" auto-complete windows.
* Give apps a chance to decorate us with drop shadows, etc. Since very scrolly
* things such as lists (of e.g. completions) are *very* slow when in per-pixel
* translucent windows, even as of Java 7u2, we force the user to specify an
* extra option for the two "main" auto-complete windows.
*
* @return Whether to allow decorating the main auto-complete windows.
* @see #PROPERTY_ALLOW_DECORATED_AUTOCOMPLETE_WINDOWS
@@ -210,40 +206,37 @@ public class Util {
return false;
}
}
/**
* Returns whether we should attempt to use Substance cell renderers and
* styles for things such as completion choices, if a Substance Look and
* Feel is installed. If this is <code>false</code>, we'll use our
* standard rendering for completions, even when Substance is being used.
* Returns whether we should attempt to use Substance cell renderers and styles
* for things such as completion choices, if a Substance Look and Feel is
* installed. If this is <code>false</code>, we'll use our standard rendering
* for completions, even when Substance is being used.
*
* @return Whether to use Substance renderers if Substance is installed.
*/
public static boolean getUseSubstanceRenderers() {
return useSubstanceRenderers;
}
/**
* Returns whether the specified color is "light" to use as a foreground.
* Colors that return <code>true</code> indicate that the current Look and
* Feel probably uses light text colors on a dark background.
* Returns whether the specified color is "light" to use as a foreground. Colors
* that return <code>true</code> indicate that the current Look and Feel
* probably uses light text colors on a dark background.
*
* @param fg
* The foreground color.
* @param fg The foreground color.
* @return Whether it is a "light" foreground color.
*/
public static final boolean isLightForeground(Color fg) {
return fg.getRed() > 0xa0 && fg.getGreen() > 0xa0 && fg.getBlue() > 0xa0;
}
/**
* Returns whether a string starts with a specified prefix, ignoring case.
* This method does not support characters outside of the BMP.
* Returns whether a string starts with a specified prefix, ignoring case. This
* method does not support characters outside of the BMP.
*
* @param str
* The string to check. This cannot be {@code null}.
* @param prefix
* The prefix to check for. This cannot be {@code null}.
* @param str The string to check. This cannot be {@code null}.
* @param prefix The prefix to check for. This cannot be {@code null}.
* @return Whether {@code str} starts with {@code prefix}, ignoring case.
*/
public static boolean startsWithIgnoreCase(String str, String prefix) {
@@ -253,13 +246,12 @@ public class Util {
}
return false;
}
/**
* Strips any HTML from a string. The string must start with
* "<code>&lt;html&gt;</code>" for markup tags to be stripped.
*
* @param text
* The string.
* @param text The string.
* @return The string, with any HTML stripped.
*/
public static String stripHtml(String text) {
@@ -269,7 +261,7 @@ public class Util {
// TODO: Micro-optimize me, might be called in renderers and loops
return TAG_PATTERN.matcher(text).replaceAll("");
}
static {
boolean use = true;
try {
@@ -13,16 +13,16 @@ import javax.swing.text.JTextComponent;
* <p>
*
* This completion type uses its <tt>shortDescription</tt> property as part of
* its summary returned by {@link #getSummary()}; for this reason, it may be
* a little longer (even much longer), if desired, than what is recommended
* for <tt>BasicCompletion</tt>s (where the <tt>shortDescription</tt> is used
* in {@link #toString()} for <tt>ListCellRenderers</tt>).
* its summary returned by {@link #getSummary()}; for this reason, it may be a
* little longer (even much longer), if desired, than what is recommended for
* <tt>BasicCompletion</tt>s (where the <tt>shortDescription</tt> is used in
* {@link #toString()} for <tt>ListCellRenderers</tt>).
*
* @author Robert Futrell
* @version 1.0
*/
public class VariableCompletion extends BasicCompletion {
/**
* The variable's type.
*/
@@ -31,27 +31,24 @@ public class VariableCompletion extends BasicCompletion {
* What library (for example) this variable is defined in.
*/
private String definedIn;
/**
* Constructor.
*
* @param provider
* The parent provider.
* @param name
* The name of this variable.
* @param type
* The type of this variable (e.g. "<code>int</code>",
* "<code>String</code>", etc.).
* @param provider The parent provider.
* @param name The name of this variable.
* @param type The type of this variable (e.g. "<code>int</code>",
* "<code>String</code>", etc.).
*/
public VariableCompletion(CompletionProvider provider, String name, String type) {
super(provider, name);
this.type = type;
}
protected void addDefinitionString(StringBuilder sb) {
sb.append("<html><b>").append(getDefinitionString()).append("</b>");
}
public String getDefinitionString() {
StringBuilder sb = new StringBuilder();
// Add the return type if applicable (C macros like NULL have no type).
@@ -62,7 +59,7 @@ public class VariableCompletion extends BasicCompletion {
sb.append(getName());
return sb.toString();
}
/**
* Returns where this variable is defined.
*
@@ -72,7 +69,7 @@ public class VariableCompletion extends BasicCompletion {
public String getDefinedIn() {
return definedIn;
}
/**
* Returns the name of this variable.
*
@@ -81,7 +78,7 @@ public class VariableCompletion extends BasicCompletion {
public String getName() {
return getReplacementText();
}
/**
* {@inheritDoc}
*/
@@ -93,29 +90,25 @@ public class VariableCompletion extends BasicCompletion {
possiblyAddDefinedIn(sb);
return sb.toString();
}
/**
* Returns the tool tip text to display for mouse hovers over this
* completion.
* Returns the tool tip text to display for mouse hovers over this completion.
* <p>
*
* Note that for this functionality to be enabled, a
* <tt>JTextComponent</tt> must be registered with the
* <tt>ToolTipManager</tt>, and the text component must know to search
* for this value. In the case of an
* <a href="http://fifesoft.com/rsyntaxtextarea">RSyntaxTextArea</a>, this
* can be done with a <tt>org.fife.ui.rtextarea.ToolTipSupplier</tt> that
* calls into
* Note that for this functionality to be enabled, a <tt>JTextComponent</tt>
* must be registered with the <tt>ToolTipManager</tt>, and the text component
* must know to search for this value. In the case of an
* <a href="http://fifesoft.com/rsyntaxtextarea">RSyntaxTextArea</a>, this can
* be done with a <tt>org.fife.ui.rtextarea.ToolTipSupplier</tt> that calls into
* {@link CompletionProvider#getCompletionsAt(JTextComponent, java.awt.Point)}.
*
* @return The tool tip text for this completion, or <code>null</code> if
* none.
* @return The tool tip text for this completion, or <code>null</code> if none.
*/
@Override
public String getToolTipText() {
return getDefinitionString();
}
/**
* Returns the type of this variable.
*
@@ -124,13 +117,12 @@ public class VariableCompletion extends BasicCompletion {
public String getType() {
return type;
}
/**
* Adds some HTML describing where this variable is defined, if this
* information is known.
* Adds some HTML describing where this variable is defined, if this information
* is known.
*
* @param sb
* The buffer to append to.
* @param sb The buffer to append to.
*/
protected void possiblyAddDefinedIn(StringBuilder sb) {
if (definedIn != null) {
@@ -138,13 +130,11 @@ public class VariableCompletion extends BasicCompletion {
sb.append(" <em>").append(definedIn).append("</em>");
}
}
/**
* Adds the description text as HTML to a buffer, if a description is
* defined.
* Adds the description text as HTML to a buffer, if a description is defined.
*
* @param sb
* The buffer to append to.
* @param sb The buffer to append to.
* @return Whether there was a description to add.
*/
protected boolean possiblyAddDescription(StringBuilder sb) {
@@ -156,18 +146,17 @@ public class VariableCompletion extends BasicCompletion {
}
return false;
}
/**
* Sets where this variable is defined.
*
* @param definedIn
* Where this variable is defined.
* @param definedIn Where this variable is defined.
* @see #getDefinedIn()
*/
public void setDefinedIn(String definedIn) {
this.definedIn = definedIn;
}
/**
* Overridden to return the name of the variable being completed.
*
@@ -30,18 +30,18 @@ import org.fife.ui.rtextarea.RTextArea;
* @version 1.0
*/
public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
private final Action INSERT_BREAK_ACTION;
private static final Pattern MLC_PATTERN = Pattern.compile("([ \\t]*)(/?[\\*]+)([ \\t]*)");
protected AbstractJFlexCTokenMaker() {
INSERT_BREAK_ACTION = createInsertBreakAction();
}
/**
* Creates and returns the action to use when the user inserts a newline.
* The default implementation intelligently closes multi-line comments.
* Subclasses can override.
* Creates and returns the action to use when the user inserts a newline. The
* default implementation intelligently closes multi-line comments. Subclasses
* can override.
*
* @return The action.
* @see #getInsertBreakAction()
@@ -49,10 +49,10 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
protected Action createInsertBreakAction() {
return new CStyleInsertBreakAction();
}
/**
* Returns <code>true</code> always as C-style languages use curly braces
* to denote code blocks.
* Returns <code>true</code> always as C-style languages use curly braces to
* denote code blocks.
*
* @return <code>true</code> always.
*/
@@ -60,11 +60,10 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
public boolean getCurlyBracesDenoteCodeBlocks(int languageIndex) {
return true;
}
/**
* Returns an action to handle "insert break" key presses (i.e. Enter).
* An action is returned that handles newlines differently in multi-line
* comments.
* Returns an action to handle "insert break" key presses (i.e. Enter). An
* action is returned that handles newlines differently in multi-line comments.
*
* @return The action.
*/
@@ -72,7 +71,7 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
public Action getInsertBreakAction() {
return INSERT_BREAK_ACTION;
}
/**
* {@inheritDoc}
*/
@@ -80,7 +79,7 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
public boolean getMarkOccurrencesOfTokenType(int type) {
return type == Token.IDENTIFIER || type == Token.FUNCTION;
}
/**
* {@inheritDoc}
*/
@@ -92,19 +91,17 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
}
return false;
}
/**
* Returns whether a given token is an internal token type that represents
* an MLC or documentation comment continuing on to the next line. This is
* done by languages such as JavaScript that are a little more verbose
* than necessary so that their code can be copy-and-pasted into other
* <code>TokenMaker</code>s that use them as nested languages (such as
* HTML, JSP, etc.).
* Returns whether a given token is an internal token type that represents an
* MLC or documentation comment continuing on to the next line. This is done by
* languages such as JavaScript that are a little more verbose than necessary so
* that their code can be copy-and-pasted into other <code>TokenMaker</code>s
* that use them as nested languages (such as HTML, JSP, etc.).
*
* @param t
* The token to check. This cannot be <code>null</code>.
* @return Whether the token is an internal token representing the end of
* a line for an MLC/doc comment continuing on to the next line.
* @param t The token to check. This cannot be <code>null</code>.
* @return Whether the token is an internal token representing the end of a line
* for an MLC/doc comment continuing on to the next line.
*/
private boolean isInternalEolTokenForMLCs(Token t) {
int type = t.getType();
@@ -114,13 +111,13 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
}
return false;
}
/**
* Action that knows how to special-case inserting a newline in a
* multi-line comment for languages like C and Java.
* Action that knows how to special-case inserting a newline in a multi-line
* comment for languages like C and Java.
*/
protected class CStyleInsertBreakAction extends RSyntaxTextAreaEditorKit.InsertBreakAction {
@Override
public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
if (!textArea.isEditable() || !textArea.isEnabled()) {
@@ -141,13 +138,12 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
handleInsertBreak(rsta, true);
}
}
/**
* Returns whether the MLC token containing <code>offs</code> appears
* to have a "nested" comment (i.e., contains "<code>/*</code>"
* somewhere inside of it). This implies that it is likely a "new" MLC
* and needs to be closed. While not foolproof, this is usually good
* enough of a sign.
* Returns whether the MLC token containing <code>offs</code> appears to have a
* "nested" comment (i.e., contains "<code>/*</code>" somewhere inside of it).
* This implies that it is likely a "new" MLC and needs to be closed. While not
* foolproof, this is usually good enough of a sign.
*
* @param textArea
* @param line
@@ -183,7 +179,7 @@ public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {
}
return true; // No match - MLC goes to the end of the file
}
private void insertBreakInMLC(ActionEvent e, RSyntaxTextArea textArea, int line) {
Matcher m = null;
int start = -1;
@@ -11,35 +11,32 @@ import javax.swing.text.Segment;
/**
* Base class for JFlex-generated token makers. This class attempts to factor
* out all common code from these classes. Many methods <em>almost</em> could
* be factored out into this class, but cannot because they reference JFlex
* out all common code from these classes. Many methods <em>almost</em> could be
* factored out into this class, but cannot because they reference JFlex
* variables that we cannot access from this class.
*
* @author Robert Futrell
* @version 0.1
*/
public abstract class AbstractJFlexTokenMaker extends TokenMakerBase {
protected Segment s;
protected int start; // Just for states.
protected int offsetShift; // As parser always starts at 0, but our line
// doesn't.
/**
* Declared here so we can define overloads that refer to this method.
*
* @param newState
* The new JFlex state to enter.
* @param newState The new JFlex state to enter.
*/
public abstract void yybegin(int newState);
/**
* Starts a new JFlex state and changes the current language index.
*
* @param state
* The new JFlex state to enter.
* @param languageIndex
* The new language index.
* @param state The new JFlex state to enter.
* @param languageIndex The new language index.
*/
protected void yybegin(int state, int languageIndex) {
yybegin(state);
@@ -8,9 +8,9 @@ package org.fife.ui.rsyntaxtextarea;
/**
* An abstract implementation of the
* {@link org.fife.ui.rsyntaxtextarea.TokenMaker} interface. It should
* be overridden for every language for which you want to provide
* syntax highlighting.
* {@link org.fife.ui.rsyntaxtextarea.TokenMaker} interface. It should be
* overridden for every language for which you want to provide syntax
* highlighting.
* <p>
*
* @see Token
@@ -19,34 +19,33 @@ package org.fife.ui.rsyntaxtextarea;
* @version 0.2
*/
public abstract class AbstractTokenMaker extends TokenMakerBase {
/**
* Hash table of words to highlight and what token type they are.
* The keys are the words to highlight, and their values are the
* token types, for example, <code>Token.RESERVED_WORD</code> or
* <code>Token.FUNCTION</code>.
* Hash table of words to highlight and what token type they are. The keys are
* the words to highlight, and their values are the token types, for example,
* <code>Token.RESERVED_WORD</code> or <code>Token.FUNCTION</code>.
*/
protected TokenMap wordsToHighlight;
/**
* Constructor.
*/
public AbstractTokenMaker() {
wordsToHighlight = getWordsToHighlight();
}
/**
* Returns the words to highlight for this programming language.
*
* @return A <code>TokenMap</code> containing the words to highlight for
* this programming language.
* @return A <code>TokenMap</code> containing the words to highlight for this
* programming language.
*/
public abstract TokenMap getWordsToHighlight();
/**
* Removes the token last added from the linked list of tokens. The
* programmer should never have to call this directly; it can be called
* by subclasses of <code>TokenMaker</code> if necessary.
* Removes the token last added from the linked list of tokens. The programmer
* should never have to call this directly; it can be called by subclasses of
* <code>TokenMaker</code> if necessary.
*/
public void removeLastToken() {
if (previousToken == null) {
@@ -18,15 +18,14 @@ import java.util.Set;
* @version 1.0
*/
public abstract class AbstractTokenMakerFactory extends TokenMakerFactory {
/**
* A mapping from keys to the names of {@link TokenMaker} implementation
* class names. When {@link #getTokenMaker(String)} is called with a key
* defined in this map, a <code>TokenMaker</code> of the corresponding type
* is returned.
* A mapping from keys to the names of {@link TokenMaker} implementation class
* names. When {@link #getTokenMaker(String)} is called with a key defined in
* this map, a <code>TokenMaker</code> of the corresponding type is returned.
*/
private Map<String, Object> tokenMakerMap;
/**
* Constructor.
*/
@@ -34,14 +33,13 @@ public abstract class AbstractTokenMakerFactory extends TokenMakerFactory {
tokenMakerMap = new HashMap<String, Object>();
initTokenMakerMap();
}
/**
* Returns a {@link TokenMaker} for the specified key.
*
* @param key
* The key.
* @return The corresponding <code>TokenMaker</code>, or <code>null</code>
* if none matches the specified key.
* @param key The key.
* @return The corresponding <code>TokenMaker</code>, or <code>null</code> if
* none matches the specified key.
*/
@Override
protected TokenMaker getTokenMakerImpl(String key) {
@@ -57,18 +55,18 @@ public abstract class AbstractTokenMakerFactory extends TokenMakerFactory {
}
return null;
}
/**
* Populates the mapping from keys to instances of
* <code>TokenMakerCreator</code>s. Subclasses should override this method
* and call one of the <code>putMapping</code> overloads to register
* <code>TokenMakerCreator</code>s. Subclasses should override this method and
* call one of the <code>putMapping</code> overloads to register
* {@link TokenMaker}s for syntax constants.
*
* @see #putMapping(String, String)
* @see #putMapping(String, String, ClassLoader)
*/
protected abstract void initTokenMakerMap();
/**
* {@inheritDoc}
*/
@@ -76,50 +74,45 @@ public abstract class AbstractTokenMakerFactory extends TokenMakerFactory {
public Set<String> keySet() {
return tokenMakerMap.keySet();
}
/**
* Adds a mapping from a key to a <code>TokenMaker</code> implementation
* class name.
* Adds a mapping from a key to a <code>TokenMaker</code> implementation class
* name.
*
* @param key
* The key.
* @param className
* The <code>TokenMaker</code> class name.
* @param key The key.
* @param className The <code>TokenMaker</code> class name.
* @see #putMapping(String, String, ClassLoader)
*/
public void putMapping(String key, String className) {
putMapping(key, className, null);
}
/**
* Adds a mapping from a key to a <code>TokenMaker</code> implementation
* class name.
* Adds a mapping from a key to a <code>TokenMaker</code> implementation class
* name.
*
* @param key
* The key.
* @param className
* The <code>TokenMaker</code> class name.
* @param cl
* The class loader to use when loading the class.
* @param key The key.
* @param className The <code>TokenMaker</code> class name.
* @param cl The class loader to use when loading the class.
* @see #putMapping(String, String)
*/
public void putMapping(String key, String className, ClassLoader cl) {
tokenMakerMap.put(key, new TokenMakerCreator(className, cl));
}
/**
* Wrapper that handles the creation of TokenMaker instances.
*/
private static class TokenMakerCreator {
private String className;
private ClassLoader cl;
public TokenMakerCreator(String className, ClassLoader cl) {
this.className = className;
this.cl = cl != null ? cl : getClass().getClassLoader();
}
public TokenMaker create() throws Exception {
return (TokenMaker) Class.forName(className, true, cl).newInstance();
}
@@ -17,44 +17,39 @@ import java.util.EventObject;
* @version 1.0
*/
public class ActiveLineRangeEvent extends EventObject {
private int min;
private int max;
/**
* Constructor.
*
* @param source
* The text area.
* @param min
* The first line in the active line range, or
* <code>-1</code> if the line range is being cleared.
* @param max
* The last line in the active line range, or
* <code>-1</code> if the line range is being cleared.
* @param source The text area.
* @param min The first line in the active line range, or <code>-1</code> if
* the line range is being cleared.
* @param max The last line in the active line range, or <code>-1</code> if
* the line range is being cleared.
*/
public ActiveLineRangeEvent(RSyntaxTextArea source, int min, int max) {
super(source);
this.min = min;
this.max = max;
}
/**
* Returns the last line in the active line range.
*
* @return The last line, or <code>-1</code> if the range is being
* cleared.
* @return The last line, or <code>-1</code> if the range is being cleared.
* @see #getMin()
*/
public int getMax() {
return max;
}
/**
* Returns the first line in the active line range.
*
* @return The first line, or <code>-1</code> if the range is being
* cleared.
* @return The first line, or <code>-1</code> if the range is being cleared.
* @see #getMax()
*/
public int getMin() {
@@ -13,29 +13,27 @@ import java.util.EventListener;
* Listens for "active line range" events from an <code>RSyntaxTextArea</code>.
* If a text area contains some semantic knowledge of the programming language
* being edited, it may broadcast {@link ActiveLineRangeEvent}s whenever the
* caret moves into a new "block" of code. Listeners can listen for these
* events and respond accordingly.
* caret moves into a new "block" of code. Listeners can listen for these events
* and respond accordingly.
* <p>
*
* See the <code>RSTALanguageSupport</code> project at
* <a href="http://fifesoft.com">http://fifesoft.com</a> for some
* <code>LanguageSupport</code> implementations that may broadcast these
* events. Note that if an RSTA/LanguageSupport does not support broadcasting
* these events, the listener will simply never receive any notifications.
* <code>LanguageSupport</code> implementations that may broadcast these events.
* Note that if an RSTA/LanguageSupport does not support broadcasting these
* events, the listener will simply never receive any notifications.
*
* @author Robert Futrell
* @version 1.0
*/
public interface ActiveLineRangeListener extends EventListener {
/**
* Called whenever the "active line range" changes.
*
* @param e
* Information about the line range change. If there is no longer
* an "active line range," the "minimum" and "maximum" line
* values
* should both be <code>-1</code>.
* @param e Information about the line range change. If there is no longer an
* "active line range," the "minimum" and "maximum" line values should
* both be <code>-1</code>.
*/
void activeLineRangeChanged(ActiveLineRangeEvent e);
}
@@ -13,14 +13,14 @@ import javax.swing.text.Caret;
import org.fife.ui.rtextarea.SmartHighlightPainter;
/**
* The default implementation of {@link OccurrenceMarker}. It goes through
* the document and marks all instances of the specified token.
* The default implementation of {@link OccurrenceMarker}. It goes through the
* document and marks all instances of the specified token.
*
* @author Robert Futrell
* @version 1.0
*/
class DefaultOccurrenceMarker implements OccurrenceMarker {
/**
* {@inheritDoc}
*/
@@ -45,7 +45,7 @@ class DefaultOccurrenceMarker implements OccurrenceMarker {
}
return t;
}
/**
* {@inheritDoc}
*/
@@ -53,7 +53,7 @@ class DefaultOccurrenceMarker implements OccurrenceMarker {
public boolean isValidType(RSyntaxTextArea textArea, Token t) {
return textArea.getMarkOccurrencesOfTokenType(t.getType());
}
/**
* {@inheritDoc}
*/
@@ -61,21 +61,18 @@ class DefaultOccurrenceMarker implements OccurrenceMarker {
public void markOccurrences(RSyntaxDocument doc, Token t, RSyntaxTextAreaHighlighter h, SmartHighlightPainter p) {
markOccurrencesOfToken(doc, t, h, p);
}
/**
* Highlights all instances of tokens identical to <code>t</code> in the
* specified document.
*
* @param doc
* The document.
* @param t
* The document whose relevant occurrences should be marked.
* @param h
* The highlighter to add the highlights to.
* @param p
* The painter for the highlights.
* @param doc The document.
* @param t The document whose relevant occurrences should be marked.
* @param h The highlighter to add the highlights to.
* @param p The painter for the highlights.
*/
public static final void markOccurrencesOfToken(RSyntaxDocument doc, Token t, RSyntaxTextAreaHighlighter h, SmartHighlightPainter p) {
public static final void markOccurrencesOfToken(RSyntaxDocument doc, Token t, RSyntaxTextAreaHighlighter h,
SmartHighlightPainter p) {
char[] lexeme = t.getLexeme().toCharArray();
int type = t.getType();
int lineCount = doc.getDefaultRootElement().getElementCount();
@@ -10,46 +10,43 @@ import javax.swing.text.Segment;
/**
* This class generates tokens for a {@link TokenMaker}. This class is here
* because it reuses tokens when they aren't needed anymore to prevent
* This class doesn't actually create new tokens every time
* <code>createToken</code> is called. Instead, it internally keeps a stack of
* available already-created tokens. When more tokens are needed to properly
* display a line, more tokens are added to the available stack. This saves
* from needless repetitive memory allocation. However, it makes it IMPERATIVE
* that users call <code>resetTokenList</code> when creating a new token list so
* that the token maker can keep an accurate list of available tokens.
* because it reuses tokens when they aren't needed anymore to prevent This
* class doesn't actually create new tokens every time <code>createToken</code>
* is called. Instead, it internally keeps a stack of available already-created
* tokens. When more tokens are needed to properly display a line, more tokens
* are added to the available stack. This saves from needless repetitive memory
* allocation. However, it makes it IMPERATIVE that users call
* <code>resetTokenList</code> when creating a new token list so that the token
* maker can keep an accurate list of available tokens.
* <p>
*
* NOTE: This class should only be used by {@link TokenMaker}; nobody else
* needs it!
* NOTE: This class should only be used by {@link TokenMaker}; nobody else needs
* it!
*
* @author Robert Futrell
* @version 0.1
*/
class DefaultTokenFactory implements TokenFactory {
private int size;
private int increment;
private TokenImpl[] tokenList;
private int currentFreeToken;
protected static final int DEFAULT_START_SIZE = 30;
protected static final int DEFAULT_INCREMENT = 10;
/**
* Constructor.
*/
DefaultTokenFactory() {
this(DEFAULT_START_SIZE, DEFAULT_INCREMENT);
}
/**
* Constructor.
*
* @param size
* The initial number of tokens in this factory.
* @param increment
* How many tokens to increment by when the stack gets
* empty.
* @param size The initial number of tokens in this factory.
* @param increment How many tokens to increment by when the stack gets empty.
*/
DefaultTokenFactory(int size, int increment) {
this.size = size;
@@ -61,10 +58,10 @@ class DefaultTokenFactory implements TokenFactory {
tokenList[i] = new TokenImpl();
}
}
/**
* Adds tokens to the internal token list. This is called whenever a
* request is made and no more tokens are available.
* Adds tokens to the internal token list. This is called whenever a request is
* made and no more tokens are available.
*/
private void augmentTokenList() {
TokenImpl[] temp = new TokenImpl[size + increment];
@@ -76,37 +73,35 @@ class DefaultTokenFactory implements TokenFactory {
}
// System.err.println("... size up to: " + size);
}
/**
* {@inheritDoc}
*/
@Override
public TokenImpl createToken() {
TokenImpl token = tokenList[currentFreeToken];
token.text = null;
token.setType(Token.NULL);
token.setOffset(-1);
token.setNextToken(null);
currentFreeToken++;
if (currentFreeToken == size) {
token.reset();
if (++currentFreeToken == size) {
augmentTokenList();
}
return token;
}
/**
* {@inheritDoc}
*/
@Override
public TokenImpl createToken(final Segment line, final int beg, final int end, final int startOffset, final int type) {
public TokenImpl createToken(final Segment line, final int beg, final int end, final int startOffset,
final int type) {
return createToken(line.array, beg, end, startOffset, type);
}
/**
* {@inheritDoc}
*/
@Override
public TokenImpl createToken(final char[] line, final int beg, final int end, final int startOffset, final int type) {
public TokenImpl createToken(final char[] line, final int beg, final int end, final int startOffset,
final int type) {
TokenImpl token = tokenList[currentFreeToken];
token.set(line, beg, end, startOffset, type);
currentFreeToken++;
@@ -115,11 +110,11 @@ class DefaultTokenFactory implements TokenFactory {
}
return token;
}
/**
* Resets the state of this token maker. This method should be called
* by the <code>TokenMaker</code> every time a token list is generated for
* a new line so the tokens can be reused.
* Resets the state of this token maker. This method should be called by the
* <code>TokenMaker</code> every time a token list is generated for a new line
* so the tokens can be reused.
*/
@Override
public void resetAllTokens() {
@@ -15,7 +15,7 @@ package org.fife.ui.rsyntaxtextarea;
* @version 1.0
*/
class DefaultTokenMakerFactory extends AbstractTokenMakerFactory implements SyntaxConstants {
/**
* {@inheritDoc}
*/
@@ -20,22 +20,22 @@ import javax.swing.text.TabExpander;
* @version 1.0
*/
class DefaultTokenPainter implements TokenPainter {
/**
* Rectangle used for filling token backgrounds.
*/
private Rectangle2D.Float bgRect;
/**
* Micro-optimization; buffer used to compute tab width. If the width is
* correct it's not re-allocated, to prevent lots of very small garbage.
* Only used when painting tab lines.
* Micro-optimization; buffer used to compute tab width. If the width is correct
* it's not re-allocated, to prevent lots of very small garbage. Only used when
* painting tab lines.
*/
private static char[] tabBuf;
DefaultTokenPainter() {
bgRect = new Rectangle2D.Float();
}
/**
* {@inheritDoc}
*/
@@ -43,57 +43,51 @@ class DefaultTokenPainter implements TokenPainter {
public final float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e) {
return paint(token, g, x, y, host, e, 0);
}
/**
* {@inheritDoc}
*/
@Override
public float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart) {
public float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
float clipStart) {
return paintImpl(token, g, x, y, host, e, clipStart, false, false);
}
/**
* {@inheritDoc}
*/
@Override
public float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart, boolean paintBG) {
public float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
float clipStart, boolean paintBG) {
return paintImpl(token, g, x, y, host, e, clipStart, !paintBG, false);
}
/**
* Paints the background of a token.
*
* @param x
* The x-coordinate of the token.
* @param y
* The y-coordinate of the token.
* @param width
* The width of the token (actually, the width of the part of
* the token to paint).
* @param height
* The height of the token.
* @param g
* The graphics context with which to paint.
* @param fontAscent
* The ascent of the token's font.
* @param host
* The text area.
* @param color
* The color with which to paint.
* @param x The x-coordinate of the token.
* @param y The y-coordinate of the token.
* @param width The width of the token (actually, the width of the part of
* the token to paint).
* @param height The height of the token.
* @param g The graphics context with which to paint.
* @param fontAscent The ascent of the token's font.
* @param host The text area.
* @param color The color with which to paint.
*/
protected void paintBackground(float x, float y, float width, float height, Graphics2D g, int fontAscent, RSyntaxTextArea host,
Color color) {
protected void paintBackground(float x, float y, float width, float height, Graphics2D g, int fontAscent,
RSyntaxTextArea host, Color color) {
g.setColor(color);
bgRect.setRect(x, y - fontAscent, width, height);
// g.fill(bgRect);
g.fillRect((int) x, (int) (y - fontAscent), (int) width, (int) height);
}
/**
* Does the dirty-work of actually painting the token.
*/
protected float paintImpl(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart,
boolean selected, boolean useSTC) {
protected float paintImpl(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
float clipStart, boolean selected, boolean useSTC) {
int origX = (int) x;
int textOffs = token.getTextOffset();
char[] text = token.getTextArray();
@@ -107,22 +101,22 @@ class DefaultTokenPainter implements TokenPainter {
FontMetrics fm = host.getFontMetricsForTokenType(token.getType());
for (int i = textOffs; i < end; i++) {
switch (text[i]) {
case '\t':
nextX = e.nextTabStop(x + fm.charsWidth(text, flushIndex, flushLen), 0);
if (bg != null) {
paintBackground(x, y, nextX - x, fm.getHeight(), g, fm.getAscent(), host, bg);
}
if (flushLen > 0) {
g.setColor(fg);
g.drawChars(text, flushIndex, flushLen, (int) x, (int) y);
flushLen = 0;
}
flushIndex = i + 1;
x = nextX;
break;
default:
flushLen += 1;
break;
case '\t':
nextX = e.nextTabStop(x + fm.charsWidth(text, flushIndex, flushLen), 0);
if (bg != null) {
paintBackground(x, y, nextX - x, fm.getHeight(), g, fm.getAscent(), host, bg);
}
if (flushLen > 0) {
g.setColor(fg);
g.drawChars(text, flushIndex, flushLen, (int) x, (int) y);
flushLen = 0;
}
flushIndex = i + 1;
x = nextX;
break;
default:
flushLen += 1;
break;
}
}
nextX = x + fm.charsWidth(text, flushIndex, flushLen);
@@ -152,48 +146,43 @@ class DefaultTokenPainter implements TokenPainter {
}
return nextX;
}
/**
* {@inheritDoc}
*/
@Override
public float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, boolean useSTC) {
public float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
boolean useSTC) {
return paintSelected(token, g, x, y, host, e, 0, useSTC);
}
/**
* {@inheritDoc}
*/
@Override
public float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart,
boolean useSTC) {
public float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
float clipStart, boolean useSTC) {
return paintImpl(token, g, x, y, host, e, clipStart, true, useSTC);
}
/**
* Paints dotted "tab" lines; that is, lines that show where your caret
* would go to on the line if you hit "tab". This visual effect is usually
* done in the leading whitespace token(s) of lines.
* Paints dotted "tab" lines; that is, lines that show where your caret would go
* to on the line if you hit "tab". This visual effect is usually done in the
* leading whitespace token(s) of lines.
*
* @param token
* The token to render.
* @param x
* The starting x-offset of this token. It is assumed that this
* is the left margin of the text area (may be non-zero due to
* insets), since tab lines are only painted for leading
* whitespace.
* @param y
* The baseline where this token was painted.
* @param endX
* The ending x-offset of this token.
* @param g
* The graphics context.
* @param e
* Used to expand tabs.
* @param host
* The text area.
* @param token The token to render.
* @param x The starting x-offset of this token. It is assumed that this is
* the left margin of the text area (may be non-zero due to
* insets), since tab lines are only painted for leading
* whitespace.
* @param y The baseline where this token was painted.
* @param endX The ending x-offset of this token.
* @param g The graphics context.
* @param e Used to expand tabs.
* @param host The text area.
*/
protected void paintTabLines(Token token, int x, int y, int endX, Graphics2D g, TabExpander e, RSyntaxTextArea host) {
protected void paintTabLines(Token token, int x, int y, int endX, Graphics2D g, TabExpander e,
RSyntaxTextArea host) {
// We allow tab lines to be painted in more than just Token.WHITESPACE,
// i.e. for MLC's and Token.IDENTIFIERS (for TokenMakers that return
// whitespace as identifiers for performance). But we only paint tab
@@ -13,30 +13,27 @@ package org.fife.ui.rsyntaxtextarea;
* @version 1.0
*/
public class DocumentRange implements Comparable<DocumentRange> {
private int startOffs;
private int endOffs;
/**
* Constructor.
*
* @param startOffs
* The starting offset in the document, inclusive.
* @param endOffs
* The ending offset in the document, exclusive.
* @throws IllegalArgumentException
* If <code>endOffs</code> is less than
* <code>startOffs</code>, or either argument is less than zero.
* @param startOffs The starting offset in the document, inclusive.
* @param endOffs The ending offset in the document, exclusive.
* @throws IllegalArgumentException If <code>endOffs</code> is less than
* <code>startOffs</code>, or either argument
* is less than zero.
*/
public DocumentRange(int startOffs, int endOffs) {
set(startOffs, endOffs);
}
/**
* Compares this document range to another.
*
* @param other
* Another document range.
* @param other Another document range.
* @return How the two should be sorted relative to each other.
*/
@Override
@@ -50,14 +47,13 @@ public class DocumentRange implements Comparable<DocumentRange> {
}
return endOffs - other.endOffs;
}
/**
* Returns whether this document range is equal to another one.
*
* @param other
* Another object, presumably a document range.
* @return Whether <code>other</code> is also a document range, and equal
* to this one.
* @param other Another object, presumably a document range.
* @return Whether <code>other</code> is also a document range, and equal to
* this one.
*/
@Override
public boolean equals(Object other) {
@@ -69,7 +65,7 @@ public class DocumentRange implements Comparable<DocumentRange> {
}
return false;
}
/**
* Gets the end offset of the range.
*
@@ -79,7 +75,7 @@ public class DocumentRange implements Comparable<DocumentRange> {
public int getEndOffset() {
return endOffs;
}
/**
* Gets the starting offset of the range.
*
@@ -89,7 +85,7 @@ public class DocumentRange implements Comparable<DocumentRange> {
public int getStartOffset() {
return startOffs;
}
/**
* Overridden simply as a best practice, since {@link #equals(Object)} is
* overridden.
@@ -100,29 +96,26 @@ public class DocumentRange implements Comparable<DocumentRange> {
public int hashCode() {
return startOffs + endOffs;
}
/**
* Returns whether this document range has zero length. This can happen,
* for example, with regex searches of forms like
* <code>"foo|"</code>, where the right-hand sub-expression matches empty
* strings.
* Returns whether this document range has zero length. This can happen, for
* example, with regex searches of forms like <code>"foo|"</code>, where the
* right-hand sub-expression matches empty strings.
*
* @return Whether this document range has zero length.
*/
public boolean isZeroLength() {
return startOffs == endOffs;
}
/**
* Sets the document range.
*
* @param start
* The new start value, inclusive.
* @param end
* The new end value, exclusive.
* @throws IllegalArgumentException
* If <code>end</code> is less than
* <code>start</code>, or either argument is less than zero.
* @param start The new start value, inclusive.
* @param end The new end value, exclusive.
* @throws IllegalArgumentException If <code>end</code> is less than
* <code>start</code>, or either argument is
* less than zero.
*/
public void set(int start, int end) {
if (start < 0 || end < 0) {
@@ -134,7 +127,7 @@ public class DocumentRange implements Comparable<DocumentRange> {
this.startOffs = start;
this.endOffs = end;
}
/**
* Returns a string representation of this object.
*
@@ -144,12 +137,11 @@ public class DocumentRange implements Comparable<DocumentRange> {
public String toString() {
return "[DocumentRange: " + startOffs + "-" + endOffs + "]";
}
/**
* Translates this document range by a given amount.
*
* @param amount
* The amount to translate this range by.
* @param amount The amount to translate this range by.
* @return This (modified) range.
*/
public DocumentRange translate(int amount) {
+113 -130
View File
@@ -39,16 +39,15 @@ import org.fife.ui.rsyntaxtextarea.parser.TaskTagParser.TaskNotice;
import org.fife.ui.rtextarea.RTextArea;
/**
* A component to sit alongside an {@link RSyntaxTextArea} that displays
* colored markers for locations of interest (parser errors, marked
* occurrences, etc.).
* A component to sit alongside an {@link RSyntaxTextArea} that displays colored
* markers for locations of interest (parser errors, marked occurrences, etc.).
* <p>
*
* <code>ErrorStrip</code>s display <code>ParserNotice</code>s from
* {@link Parser}s. Currently, the only way to get lines flagged in this
* component is to register a <code>Parser</code> on an RSyntaxTextArea and
* return <code>ParserNotice</code>s for each line to display an icon for.
* The severity of each notice must be at least the threshold set by
* return <code>ParserNotice</code>s for each line to display an icon for. The
* severity of each notice must be at least the threshold set by
* {@link #setLevelThreshold(org.fife.ui.rsyntaxtextarea.parser.ParserNotice.Level)}
* to be displayed in this error strip. The default threshold is
* {@link org.fife.ui.rsyntaxtextarea.parser.ParserNotice.Level#WARNING}.
@@ -76,7 +75,7 @@ import org.fife.ui.rtextarea.RTextArea;
// are now "empty").
//
public class ErrorStrip extends JPanel {
/**
* The text area.
*/
@@ -86,23 +85,23 @@ public class ErrorStrip extends JPanel {
*/
private transient Listener listener;
/**
* Whether "marked occurrences" in the text area should be shown in this
* error strip.
* Whether "marked occurrences" in the text area should be shown in this error
* strip.
*/
private boolean showMarkedOccurrences;
/**
* Whether markers for "mark all" highlights should be shown in this
* error strip.
* Whether markers for "mark all" highlights should be shown in this error
* strip.
*/
private boolean showMarkAll;
/**
* Mapping of colors to brighter colors. This is kept to prevent
* unnecessary creation of the same Colors over and over.
* Mapping of colors to brighter colors. This is kept to prevent unnecessary
* creation of the same Colors over and over.
*/
private Map<Color, Color> brighterColors;
/**
* Only notices of this severity (or worse) will be displayed in this
* error strip.
* Only notices of this severity (or worse) will be displayed in this error
* strip.
*/
private ParserNotice.Level levelThreshold;
/**
@@ -130,12 +129,11 @@ public class ErrorStrip extends JPanel {
*/
private static final int PREFERRED_WIDTH = 14;
private static final ResourceBundle MSG = ResourceBundle.getBundle("org.fife.ui.rsyntaxtextarea.ErrorStrip");
/**
* Constructor.
*
* @param textArea
* The text area we are examining.
* @param textArea The text area we are examining.
*/
public ErrorStrip(RSyntaxTextArea textArea) {
this.textArea = textArea;
@@ -150,10 +148,10 @@ public class ErrorStrip extends JPanel {
setCaretMarkerColor(Color.BLACK);
setMarkerToolTipProvider(null); // Install default
}
/**
* Overridden so we only start listening for parser notices when this
* component (and presumably the text area) are visible.
* Overridden so we only start listening for parser notices when this component
* (and presumably the text area) are visible.
*/
@Override
public void addNotify() {
@@ -165,7 +163,7 @@ public class ErrorStrip extends JPanel {
textArea.addPropertyChangeListener(RSyntaxTextArea.MARK_ALL_OCCURRENCES_CHANGED_PROPERTY, listener);
refreshMarkers();
}
/**
* Manually manages layout since this component uses no layout manager.
*/
@@ -177,12 +175,11 @@ public class ErrorStrip extends JPanel {
}
listener.caretUpdate(null); // Force recalculation of caret line pos
}
/**
* Returns a "brighter" color.
*
* @param c
* The color.
* @param c The color.
* @return A brighter color.
*/
private Color getBrighterColor(Color c) {
@@ -201,7 +198,7 @@ public class ErrorStrip extends JPanel {
}
return brighter;
}
/**
* returns the color to use when painting the caret marker.
*
@@ -211,7 +208,7 @@ public class ErrorStrip extends JPanel {
public Color getCaretMarkerColor() {
return caretMarkerColor;
}
/**
* Returns whether the caret's position should be drawn.
*
@@ -221,7 +218,7 @@ public class ErrorStrip extends JPanel {
public boolean getFollowCaret() {
return followCaret;
}
/**
* {@inheritDoc}
*/
@@ -230,11 +227,11 @@ public class ErrorStrip extends JPanel {
int height = textArea.getPreferredScrollableViewportSize().height;
return new Dimension(PREFERRED_WIDTH, height);
}
/**
* Returns the minimum severity a parser notice must be for it to be
* displayed in this error strip. This will be one of the constants
* defined in the <code>ParserNotice</code> class.
* Returns the minimum severity a parser notice must be for it to be displayed
* in this error strip. This will be one of the constants defined in the
* <code>ParserNotice</code> class.
*
* @return The minimum severity.
* @see #setLevelThreshold(org.fife.ui.rsyntaxtextarea.parser.ParserNotice.Level)
@@ -242,7 +239,7 @@ public class ErrorStrip extends JPanel {
public ParserNotice.Level getLevelThreshold() {
return levelThreshold;
}
/**
* Returns whether "mark all" highlights are shown in this error strip.
*
@@ -252,7 +249,7 @@ public class ErrorStrip extends JPanel {
public boolean getShowMarkAll() {
return showMarkAll;
}
/**
* Returns whether marked occurrences are shown in this error strip.
*
@@ -262,7 +259,7 @@ public class ErrorStrip extends JPanel {
public boolean getShowMarkedOccurrences() {
return showMarkedOccurrences;
}
/**
* {@inheritDoc}
*/
@@ -276,13 +273,12 @@ public class ErrorStrip extends JPanel {
}
return text;
}
/**
* Returns the y-offset in this component corresponding to a line in the
* text component.
* Returns the y-offset in this component corresponding to a line in the text
* component.
*
* @param line
* The line.
* @param line The line.
* @return The y-offset.
* @see #yToLine(int)
*/
@@ -291,12 +287,11 @@ public class ErrorStrip extends JPanel {
float lineCount = textArea.getLineCount();
return (int) (((line - 1) / (lineCount - 1)) * (h - 2));
}
/**
* Overridden to (possibly) draw the caret's position.
*
* @param g
* The graphics context.
* @param g The graphics context.
*/
@Override
protected void paintComponent(Graphics g) {
@@ -306,12 +301,11 @@ public class ErrorStrip extends JPanel {
g.fillRect(0, caretLineY, getWidth(), 2);
}
}
/**
* Returns a possibly brighter component for a color.
*
* @param i
* An RGB component for a color (0-255).
* @param i An RGB component for a color (0-255).
* @return A possibly brighter value for the component.
*/
private static int possiblyBrighter(int i) {
@@ -320,7 +314,7 @@ public class ErrorStrip extends JPanel {
}
return i;
}
/**
* Refreshes the markers displayed in this error strip.
*/
@@ -354,16 +348,13 @@ public class ErrorStrip extends JPanel {
revalidate();
repaint();
}
/**
* Adds markers for a list of ranges in the document.
*
* @param ranges
* The list of ranges in the document.
* @param markerMap
* A mapping from line number to <code>Marker</code>.
* @param color
* The color to use for the markers.
* @param ranges The list of ranges in the document.
* @param markerMap A mapping from line number to <code>Marker</code>.
* @param color The color to use for the markers.
*/
private void addMarkersForRanges(List<DocumentRange> ranges, Map<Integer, Marker> markerMap, Color color) {
for (DocumentRange range : ranges) {
@@ -388,7 +379,7 @@ public class ErrorStrip extends JPanel {
}
}
}
/**
* {@inheritDoc}
*/
@@ -401,12 +392,11 @@ public class ErrorStrip extends JPanel {
textArea.removePropertyChangeListener(RSyntaxTextArea.MARKED_OCCURRENCES_CHANGED_PROPERTY, listener);
textArea.removePropertyChangeListener(RSyntaxTextArea.MARK_ALL_OCCURRENCES_CHANGED_PROPERTY, listener);
}
/**
* Sets the color to use when painting the caret marker.
*
* @param color
* The new caret marker color.
* @param color The new caret marker color.
* @see #getCaretMarkerColor()
*/
public void setCaretMarkerColor(Color color) {
@@ -415,12 +405,11 @@ public class ErrorStrip extends JPanel {
listener.caretUpdate(null); // Force repaint
}
}
/**
* Toggles whether the caret's current location should be drawn.
*
* @param follow
* Whether the caret's current location should be followed.
* @param follow Whether the caret's current location should be followed.
* @see #getFollowCaret()
*/
public void setFollowCaret(boolean follow) {
@@ -434,15 +423,14 @@ public class ErrorStrip extends JPanel {
listener.caretUpdate(null); // Possibly repaint
}
}
/**
* Sets the minimum severity a parser notice must be for it to be displayed
* in this error strip. This should be one of the constants defined in
* the <code>ParserNotice</code> class. The default value is
* Sets the minimum severity a parser notice must be for it to be displayed in
* this error strip. This should be one of the constants defined in the
* <code>ParserNotice</code> class. The default value is
* {@link org.fife.ui.rsyntaxtextarea.parser.ParserNotice.Level#WARNING}.
*
* @param level
* The new severity threshold.
* @param level The new severity threshold.
* @see #getLevelThreshold()
* @see ParserNotice
*/
@@ -452,25 +440,23 @@ public class ErrorStrip extends JPanel {
refreshMarkers();
}
}
/**
* Sets the provider of tool tips for markers in this error strip.
* Applications can use this method to control the content and format of
* the tool tip descriptions of line markers.
* Sets the provider of tool tips for markers in this error strip. Applications
* can use this method to control the content and format of the tool tip
* descriptions of line markers.
*
* @param provider
* The provider. If this is <code>null</code>, a default
* implementation will be used.
* @param provider The provider. If this is <code>null</code>, a default
* implementation will be used.
*/
public void setMarkerToolTipProvider(ErrorStripMarkerToolTipProvider provider) {
markerToolTipProvider = provider != null ? provider : new DefaultErrorStripMarkerToolTipProvider();
}
/**
* Sets whether "mark all" highlights are shown in this error strip.
*
* @param show
* Whether to show markers for "mark all" highlights.
* @param show Whether to show markers for "mark all" highlights.
* @see #getShowMarkAll()
*/
public void setShowMarkAll(boolean show) {
@@ -481,12 +467,11 @@ public class ErrorStrip extends JPanel {
}
}
}
/**
* Sets whether marked occurrences are shown in this error strip.
*
* @param show
* Whether to show marked occurrences.
* @param show Whether to show marked occurrences.
* @see #getShowMarkedOccurrences()
*/
public void setShowMarkedOccurrences(boolean show) {
@@ -497,13 +482,12 @@ public class ErrorStrip extends JPanel {
}
}
}
/**
* Returns the line in the text area corresponding to a y-offset in this
* component.
*
* @param y
* The y-offset.
* @param y The y-offset.
* @return The line.
* @see #lineToY(int)
*/
@@ -516,15 +500,15 @@ public class ErrorStrip extends JPanel {
}
return line;
}
/**
* The default implementation of the provider of tool tips for markers in
* an error strip.
* The default implementation of the provider of tool tips for markers in an
* error strip.
*
* @author predi
*/
private static class DefaultErrorStripMarkerToolTipProvider implements ErrorStripMarkerToolTipProvider {
@Override
public String getToolTipText(List<ParserNotice> notices) {
String text = null;
@@ -545,34 +529,33 @@ public class ErrorStrip extends JPanel {
return text;
}
}
/**
* Returns tool tip text for the markers in an {@link ErrorStrip} that
* denote one or more parser notices.
* Returns tool tip text for the markers in an {@link ErrorStrip} that denote
* one or more parser notices.
*
* @author predi
*/
public interface ErrorStripMarkerToolTipProvider {
/**
* Returns the tool tip text for a marker in an <code>ErrorStrip</code>
* that denotes a given list of parser notices.
* Returns the tool tip text for a marker in an <code>ErrorStrip</code> that
* denotes a given list of parser notices.
*
* @param notices
* The list of parser notices.
* @return The tool tip text. This may be HTML. Returning
* <code>null</code> will result in no tool tip being displayed.
* @param notices The list of parser notices.
* @return The tool tip text. This may be HTML. Returning <code>null</code> will
* result in no tool tip being displayed.
*/
String getToolTipText(List<ParserNotice> notices);
}
/**
* Listens for events in the error strip and its markers.
*/
private class Listener extends MouseAdapter implements PropertyChangeListener, CaretListener {
private Rectangle visibleRect = new Rectangle();
@Override
public void caretUpdate(CaretEvent e) {
if (getFollowCaret()) {
@@ -587,7 +570,7 @@ public class ErrorStrip extends JPanel {
}
}
}
@Override
public void mouseClicked(MouseEvent e) {
Component source = (Component) e.getSource();
@@ -605,7 +588,7 @@ public class ErrorStrip extends JPanel {
}
}
}
@Override
public void propertyChange(PropertyChangeEvent e) {
String propName = e.getPropertyName();
@@ -636,30 +619,30 @@ public class ErrorStrip extends JPanel {
}
}
}
/**
* A notice that wraps a "marked occurrence" instance.
*/
private class MarkedOccurrenceNotice implements ParserNotice {
private DocumentRange range;
private Color color;
MarkedOccurrenceNotice(DocumentRange range, Color color) {
this.range = range;
this.color = color;
}
@Override
public int compareTo(ParserNotice other) {
return 0; // Value doesn't matter
}
@Override
public boolean containsPosition(int pos) {
return pos >= range.getStartOffset() && pos < range.getEndOffset();
}
@Override
public boolean equals(Object o) {
// FindBugs - Define equals() when defining compareTo()
@@ -668,12 +651,12 @@ public class ErrorStrip extends JPanel {
}
return compareTo((ParserNotice) o) == 0;
}
@Override
public Color getColor() {
return color;
}
/**
* {@inheritDoc}
*/
@@ -681,17 +664,17 @@ public class ErrorStrip extends JPanel {
public boolean getKnowsOffsetAndLength() {
return true;
}
@Override
public int getLength() {
return range.getEndOffset() - range.getStartOffset();
}
@Override
public Level getLevel() {
return Level.INFO; // Won't matter
}
@Override
public int getLine() {
try {
@@ -700,7 +683,7 @@ public class ErrorStrip extends JPanel {
return 0;
}
}
@Override
public String getMessage() {
String text = null;
@@ -713,40 +696,40 @@ public class ErrorStrip extends JPanel {
}
return text;
}
@Override
public int getOffset() {
return range.getStartOffset();
}
@Override
public Parser getParser() {
return null;
}
@Override
public boolean getShowInEditor() {
return false; // Value doesn't matter
}
@Override
public String getToolTipText() {
return null;
}
@Override
public int hashCode() { // FindBugs, since we override equals()
return 0; // Value doesn't matter for us.
}
}
/**
* A "marker" in this error strip, representing one or more notices.
*/
private class Marker extends JComponent {
private List<ParserNotice> notices;
Marker(ParserNotice notice) {
notices = new ArrayList<ParserNotice>(1); // Usually just 1
addNotice(notice);
@@ -754,11 +737,11 @@ public class ErrorStrip extends JPanel {
setSize(getPreferredSize());
ToolTipManager.sharedInstance().registerComponent(this);
}
public void addNotice(ParserNotice notice) {
notices.add(notice);
}
public boolean containsMarkedOccurence() {
boolean result = false;
for (int i = 0; i < notices.size(); i++) {
@@ -769,7 +752,7 @@ public class ErrorStrip extends JPanel {
}
return result;
}
public Color getColor() {
// Return the color for the highest-level parser.
Color c = null;
@@ -782,18 +765,18 @@ public class ErrorStrip extends JPanel {
}
return c;
}
@Override
public Dimension getPreferredSize() {
int w = PREFERRED_WIDTH - 4; // 2-pixel empty border
return new Dimension(w, 5);
}
@Override
public String getToolTipText() {
return markerToolTipProvider.getToolTipText(Collections.unmodifiableList(notices));
}
protected void mouseClicked(MouseEvent e) {
ParserNotice pn = notices.get(0);
int offs = pn.getOffset();
@@ -812,7 +795,7 @@ public class ErrorStrip extends JPanel {
}
}
}
@Override
protected void paintComponent(Graphics g) {
// TODO: Give "priorities" and always pick color of a notice with
@@ -829,14 +812,14 @@ public class ErrorStrip extends JPanel {
g.setColor(borderColor);
g.drawRect(0, 0, w - 1, h - 1);
}
@Override
public void removeNotify() {
super.removeNotify();
ToolTipManager.sharedInstance().unregisterComponent(this);
removeMouseListener(listener);
}
public void updateLocation() {
int line = notices.get(0).getLine();
int y = lineToY(line);
@@ -20,17 +20,16 @@ import java.io.OutputStream;
* @version 1.0
*/
class FileFileLocation extends FileLocation {
/**
* The file. This may or may not actually exist.
*/
private File file;
/**
* Constructor.
*
* @param file
* The local file.
* @param file The local file.
*/
FileFileLocation(File file) {
try {
@@ -40,7 +39,7 @@ class FileFileLocation extends FileLocation {
this.file = file;
}
}
/**
* {@inheritDoc}
*/
@@ -48,7 +47,7 @@ class FileFileLocation extends FileLocation {
protected long getActualLastModified() {
return file.lastModified();
}
/**
* Returns the full path to the file.
*
@@ -59,7 +58,7 @@ class FileFileLocation extends FileLocation {
public String getFileFullPath() {
return file.getAbsolutePath();
}
/**
* {@inheritDoc}
*/
@@ -67,7 +66,7 @@ class FileFileLocation extends FileLocation {
public String getFileName() {
return file.getName();
}
/**
* {@inheritDoc}
*/
@@ -75,7 +74,7 @@ class FileFileLocation extends FileLocation {
protected InputStream getInputStream() throws IOException {
return new FileInputStream(file);
}
/**
* {@inheritDoc}
*/
@@ -83,7 +82,7 @@ class FileFileLocation extends FileLocation {
protected OutputStream getOutputStream() throws IOException {
return new FileOutputStream(file);
}
/**
* Always returns <code>true</code>.
*
@@ -94,10 +93,10 @@ class FileFileLocation extends FileLocation {
public boolean isLocal() {
return true;
}
/**
* Since file locations of this type are guaranteed to be local, this
* method returns whether the file exists.
* Since file locations of this type are guaranteed to be local, this method
* returns whether the file exists.
*
* @return Whether this local file actually exists.
* @see #isLocal()
@@ -14,23 +14,23 @@ import java.net.MalformedURLException;
import java.net.URL;
/**
* Holds the location of a local or remote file. This provides a common way
* to read, write, and check properties of both local and remote files.
* Holds the location of a local or remote file. This provides a common way to
* read, write, and check properties of both local and remote files.
*
* @author Robert Futrell
* @version 1.0
*/
public abstract class FileLocation {
/**
* Creates a {@link FileLocation} instance for the specified local file.
*
* @param fileFullPath
* The full path to a local file.
* @param fileFullPath The full path to a local file.
* @return The file's location.
*/
public static FileLocation create(String fileFullPath) {
if (fileFullPath.startsWith("http://") || fileFullPath.startsWith("https://") || fileFullPath.startsWith("ftp://")) {
if (fileFullPath.startsWith("http://") || fileFullPath.startsWith("https://")
|| fileFullPath.startsWith("ftp://")) {
try {
return new URLFileLocation(new URL(fileFullPath));
} catch (MalformedURLException mue) {
@@ -39,23 +39,21 @@ public abstract class FileLocation {
}
return new FileFileLocation(new File(fileFullPath));
}
/**
* Creates a {@link FileLocation} instance for the specified local file.
*
* @param file
* A local file.
* @param file A local file.
* @return The file's location.
*/
public static FileLocation create(File file) {
return new FileFileLocation(file);
}
/**
* Creates a {@link FileLocation} instance for the specified file.
*
* @param url
* The URL of a file.
* @param url The URL of a file.
* @return The file's location.
*/
public static FileLocation create(URL url) {
@@ -64,25 +62,25 @@ public abstract class FileLocation {
}
return new URLFileLocation(url);
}
/**
* Returns the last time this file was modified, or
* {@link TextEditorPane#LAST_MODIFIED_UNKNOWN} if this value cannot be
* computed (such as for a remote file).
* {@link TextEditorPane#LAST_MODIFIED_UNKNOWN} if this value cannot be computed
* (such as for a remote file).
*
* @return The last time this file was modified.
*/
protected abstract long getActualLastModified();
/**
* Returns the full path to the file. This will be stripped of
* sensitive information such as passwords for remote files.
* Returns the full path to the file. This will be stripped of sensitive
* information such as passwords for remote files.
*
* @return The full path to the file.
* @see #getFileName()
*/
public abstract String getFileFullPath();
/**
* Returns the name of the file.
*
@@ -90,26 +88,24 @@ public abstract class FileLocation {
* @see #getFileFullPath()
*/
public abstract String getFileName();
/**
* Opens an input stream for reading from this file.
*
* @return The input stream.
* @throws IOException
* If the file does not exist, or some other IO error
* occurs.
* @throws IOException If the file does not exist, or some other IO error
* occurs.
*/
protected abstract InputStream getInputStream() throws IOException;
/**
* Opens an output stream for writing this file.
*
* @return An output stream.
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
*/
protected abstract OutputStream getOutputStream() throws IOException;
/**
* Returns whether this file location is a local file.
*
@@ -117,16 +113,15 @@ public abstract class FileLocation {
* @see #isLocalAndExists()
*/
public abstract boolean isLocal();
/**
* Returns whether this file location is a local file that already
* exists.
* Returns whether this file location is a local file that already exists.
*
* @return Whether this file is local and actually exists.
* @see #isLocal()
*/
public abstract boolean isLocalAndExists();
/**
* Returns whether this file location is a remote location.
*
@@ -28,17 +28,16 @@ import org.fife.ui.rtextarea.IconRowHeader;
* @version 1.0
*/
public class FoldingAwareIconRowHeader extends IconRowHeader {
/**
* Constructor.
*
* @param textArea
* The parent text area.
* @param textArea The parent text area.
*/
public FoldingAwareIconRowHeader(RSyntaxTextArea textArea) {
super(textArea);
}
/**
* {@inheritDoc}
*/
@@ -160,11 +159,11 @@ public class FoldingAwareIconRowHeader extends IconRowHeader {
}
}
}
/**
* Paints icons when line wrapping is enabled. Note that this does not
* override the parent class's implementation to avoid this version being
* called when line wrapping is disabled.
* Paints icons when line wrapping is enabled. Note that this does not override
* the parent class's implementation to avoid this version being called when
* line wrapping is disabled.
*/
private void paintComponentWrapped(Graphics g) {
// The variables we use are as follows:
@@ -20,49 +20,49 @@ import javax.swing.text.Element;
import org.fife.ui.rtextarea.SmartHighlightPainter;
/**
* Marks occurrences of the current token for HTML. Tags that require a
* closing tag have their "opposite" tag closed.
* Marks occurrences of the current token for HTML. Tags that require a closing
* tag have their "opposite" tag closed.
*
* @author Robert Futrell
* @version 1.0
*/
public class HtmlOccurrenceMarker implements OccurrenceMarker {
private static final char[] CLOSE_TAG_START = { '<', '/' };
private static final char[] TAG_SELF_CLOSE = { '/', '>' };
private static final Set<String> TAGS_REQUIRING_CLOSING = getRequiredClosingTags();
public static final Set<String> getRequiredClosingTags() {
final String[] tags = { "html", "head", "title", "style", "script", "noscript", "body", "section", "nav", "article", "aside", "h1",
"h2", "h3", "h4", "h5", "h6", "header", "footer", "address", "pre", "dialog", "blockquote", "ol", "ul", "dl", "a", "q",
"cite", "em", "strong", "small", "mark", "dfn", "abbr", "time", "progress", "meter", "code", "var", "samp", "kbd", "sub",
"sup", "span", "i", "b", "bdo", "ruby", "rt", "rp", "ins", "del", "figure", "iframe", "object", "video", "audio", "canvas",
"map", "table", "caption", "form", "fieldset", "label", "button", "select", "datalist", "textarea", "output", "details",
"bb", "menu", "legend", "div",
final String[] tags = { "html", "head", "title", "style", "script", "noscript", "body", "section", "nav",
"article", "aside", "h1", "h2", "h3", "h4", "h5", "h6", "header", "footer", "address", "pre", "dialog",
"blockquote", "ol", "ul", "dl", "a", "q", "cite", "em", "strong", "small", "mark", "dfn", "abbr",
"time", "progress", "meter", "code", "var", "samp", "kbd", "sub", "sup", "span", "i", "b", "bdo",
"ruby", "rt", "rp", "ins", "del", "figure", "iframe", "object", "video", "audio", "canvas", "map",
"table", "caption", "form", "fieldset", "label", "button", "select", "datalist", "textarea", "output",
"details", "bb", "menu", "legend", "div",
// Obsolete elements
"acronym", "applet", "big", "blink", "center", "dir", "font", "frame", "frameset", "isindex", "listing", "marquee", "nobr",
"noembed", "noframes", "plaintext", "s", "spacer", "strike", "tt", "u", "xmp", };
"acronym", "applet", "big", "blink", "center", "dir", "font", "frame", "frameset", "isindex", "listing",
"marquee", "nobr", "noembed", "noframes", "plaintext", "s", "spacer", "strike", "tt", "u", "xmp", };
return new HashSet<String>(Arrays.asList(tags));
}
/**
* If the caret is inside of a tag, this method returns the token
* representing the tag name; otherwise, <code>null</code> is returned.
* If the caret is inside of a tag, this method returns the token representing
* the tag name; otherwise, <code>null</code> is returned.
* <p>
*
* Currently, this method only checks for tag names on the same line as
* the caret, for simplicity. In the future it could check prior lines
* until the tag name is found.
* Currently, this method only checks for tag names on the same line as the
* caret, for simplicity. In the future it could check prior lines until the tag
* name is found.
*
* @param textArea
* The text area.
* @param occurrenceMarker
* The occurrence marker.
* @return The token to mark occurrences of. Note that, if the
* specified occurrence marker identifies tokens other than
* tag names, these other element types may be returned.
* @param textArea The text area.
* @param occurrenceMarker The occurrence marker.
* @return The token to mark occurrences of. Note that, if the specified
* occurrence marker identifies tokens other than tag names, these other
* element types may be returned.
*/
public static final Token getTagNameTokenForCaretOffset(RSyntaxTextArea textArea, OccurrenceMarker occurrenceMarker) {
public static final Token getTagNameTokenForCaretOffset(RSyntaxTextArea textArea,
OccurrenceMarker occurrenceMarker) {
// Get the tag name token.
// For now, we only check for tags on the current line, for simplicity.
int dot = textArea.getCaretPosition();
@@ -93,7 +93,7 @@ public class HtmlOccurrenceMarker implements OccurrenceMarker {
}
return toMark;
}
/**
* {@inheritDoc}
*/
@@ -101,7 +101,7 @@ public class HtmlOccurrenceMarker implements OccurrenceMarker {
public Token getTokenToMark(RSyntaxTextArea textArea) {
return getTagNameTokenForCaretOffset(textArea, this);
}
/**
* {@inheritDoc}
*/
@@ -109,7 +109,7 @@ public class HtmlOccurrenceMarker implements OccurrenceMarker {
public boolean isValidType(RSyntaxTextArea textArea, Token t) {
return textArea.getMarkOccurrencesOfTokenType(t.getType());
}
/**
* {@inheritDoc}
*/
@@ -254,15 +254,15 @@ public class HtmlOccurrenceMarker implements OccurrenceMarker {
} while (curLine >= 0);
}
}
/**
* Used internally when searching backward for a matching "open" tag.
*/
private static class Entry {
private boolean open;
private Token t;
Entry(boolean open, Token t) {
this.open = open;
this.t = t;
@@ -28,17 +28,14 @@ package org.fife.ui.rsyntaxtextarea;
* @version 1.0
*/
public interface LinkGenerator {
/**
* If a region of text under the mouse position should be considered a
* hyperlink, a result object is returned. This object describes what
* region of text is the link, and what action to perform if the link is
* clicked.
* hyperlink, a result object is returned. This object describes what region of
* text is the link, and what action to perform if the link is clicked.
*
* @param textArea
* The text component.
* @param offs
* The offset in the document under the mouse position.
* @param textArea The text component.
* @param offs The offset in the document under the mouse position.
* @return The link information, or <code>null</code> if no link is at the
* specified offset.
*/
@@ -23,19 +23,19 @@ import javax.swing.event.HyperlinkEvent;
* @see SelectRegionLinkGeneratorResult
*/
public interface LinkGeneratorResult {
/**
* Executes the action associated with this object. If the result is a
* URL to open, a standard hyperlink event can be returned. Alternatively,
* <code>null</code> can be returned and the action performed in this
* method itself.
* Executes the action associated with this object. If the result is a URL to
* open, a standard hyperlink event can be returned. Alternatively,
* <code>null</code> can be returned and the action performed in this method
* itself.
*
* @return The hyperlink event to broadcast from the text area, or
* <code>null</code> if the action's behavior occurs in this method
* directly.
*/
HyperlinkEvent execute();
/**
* Returns the starting offset of the link specified by the parent
* <code>LinkGenerator</code>.
@@ -19,15 +19,15 @@ import javax.swing.text.Caret;
import org.fife.ui.rtextarea.SmartHighlightPainter;
/**
* Marks all occurrences of the token at the current caret position, if it is
* an identifier.
* Marks all occurrences of the token at the current caret position, if it is an
* identifier.
*
* @author Robert Futrell
* @version 1.0
* @see OccurrenceMarker
*/
class MarkOccurrencesSupport implements CaretListener, ActionListener {
private RSyntaxTextArea textArea;
private Timer timer;
private SmartHighlightPainter p;
@@ -39,36 +39,33 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
* The default delay.
*/
static final int DEFAULT_DELAY_MS = 1000;
/**
* Constructor. Creates a listener with a 1 second delay.
*/
MarkOccurrencesSupport() {
this(DEFAULT_DELAY_MS);
}
/**
* Constructor.
*
* @param delay
* The delay between when the caret last moves and when the
* text should be scanned for matching occurrences. This should
* be in milliseconds.
* @param delay The delay between when the caret last moves and when the text
* should be scanned for matching occurrences. This should be in
* milliseconds.
*/
MarkOccurrencesSupport(int delay) {
this(delay, DEFAULT_COLOR);
}
/**
* Constructor.
*
* @param delay
* The delay between when the caret last moves and when the
* text should be scanned for matching occurrences. This should
* be in milliseconds.
* @param color
* The color to use to mark the occurrences. This cannot be
* <code>null</code>.
* @param delay The delay between when the caret last moves and when the text
* should be scanned for matching occurrences. This should be in
* milliseconds.
* @param color The color to use to mark the occurrences. This cannot be
* <code>null</code>.
*/
MarkOccurrencesSupport(int delay, Color color) {
timer = new Timer(delay, this);
@@ -76,18 +73,17 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
p = new SmartHighlightPainter();
setColor(color);
}
/**
* Called after the caret has been moved and a fixed time delay has
* elapsed. This locates and highlights all occurrences of the identifier
* at the caret position, if any.
* Called after the caret has been moved and a fixed time delay has elapsed.
* This locates and highlights all occurrences of the identifier at the caret
* position, if any.
* <p>
*
* Callers should not call this method directly, but should rather prefer
* {@link #doMarkOccurrences()} to mark occurrences.
*
* @param e
* The event.
* @param e The event.
* @see #doMarkOccurrences()
*/
@Override
@@ -124,18 +120,17 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
textArea.fireMarkedOccurrencesChanged();
}
}
/**
* Called when the caret moves in the text area.
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void caretUpdate(CaretEvent e) {
timer.restart();
}
/**
* Removes all highlights added to the text area by this listener.
*/
@@ -145,16 +140,15 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
h.clearMarkOccurrencesHighlights();
}
}
/**
* Immediately marks all occurrences of the token at the current caret
* position.
* Immediately marks all occurrences of the token at the current caret position.
*/
public void doMarkOccurrences() {
timer.stop();
actionPerformed(null);
}
/**
* Returns the color being used to mark occurrences.
*
@@ -164,7 +158,7 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
public Color getColor() {
return (Color) p.getPaint();
}
/**
* Returns the delay, in milliseconds.
*
@@ -174,7 +168,7 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
public int getDelay() {
return timer.getDelay();
}
/**
* Returns whether a border is painted around marked occurrences.
*
@@ -185,13 +179,12 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
public boolean getPaintBorder() {
return p.getPaintBorder();
}
/**
* Installs this listener on a text area. If it is already installed on
* another text area, it is uninstalled first.
* Installs this listener on a text area. If it is already installed on another
* text area, it is uninstalled first.
*
* @param textArea
* The text area to install on.
* @param textArea The text area to install on.
*/
public void install(RSyntaxTextArea textArea) {
if (this.textArea != null) {
@@ -203,12 +196,11 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
setColor(textArea.getMarkOccurrencesColor());
}
}
/**
* Sets the color to use when marking occurrences.
*
* @param color
* The color to use.
* @param color The color to use.
* @see #getColor()
* @see #setPaintBorder(boolean)
*/
@@ -219,25 +211,23 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
caretUpdate(null); // Force a highlight repaint.
}
}
/**
* Sets the delay between the last caret position change and when the
* text is scanned for matching identifiers. A delay is needed to prevent
* repeated scanning while the user is typing.
* Sets the delay between the last caret position change and when the text is
* scanned for matching identifiers. A delay is needed to prevent repeated
* scanning while the user is typing.
*
* @param delay
* The new delay.
* @param delay The new delay.
* @see #getDelay()
*/
public void setDelay(int delay) {
timer.setInitialDelay(delay);
}
/**
* Toggles whether a border is painted around marked highlights.
*
* @param paint
* Whether to paint a border.
* @param paint Whether to paint a border.
* @see #getPaintBorder()
* @see #setColor(Color)
*/
@@ -249,10 +239,10 @@ class MarkOccurrencesSupport implements CaretListener, ActionListener {
}
}
}
/**
* Uninstalls this listener from the current text area. Does nothing if
* it not currently installed on any text area.
* Uninstalls this listener from the current text area. Does nothing if it not
* currently installed on any text area.
*
* @see #install(RSyntaxTextArea)
*/
@@ -41,11 +41,11 @@ import org.fife.ui.rsyntaxtextarea.focusabletip.TipUtil;
* @version 1.0
*/
class MatchedBracketPopup extends JWindow {
private RSyntaxTextArea textArea;
private transient Listener listener;
private static final int LEFT_EMPTY_BORDER = 5;
MatchedBracketPopup(Window parent, RSyntaxTextArea textArea, int offsToRender) {
super(parent);
this.textArea = textArea;
@@ -59,7 +59,7 @@ class MatchedBracketPopup extends JWindow {
listener = new Listener();
setLocation();
}
/**
* Overridden to ensure this popup stays in a specific size range.
*/
@@ -71,7 +71,7 @@ class MatchedBracketPopup extends JWindow {
}
return size;
}
private String getText(int offsToRender) {
int line = 0;
try {
@@ -110,7 +110,7 @@ class MatchedBracketPopup extends JWindow {
}
return sb.toString();
}
/**
* Adds key bindings to this popup.
*/
@@ -121,10 +121,9 @@ class MatchedBracketPopup extends JWindow {
im.put(escapeKS, "onEscape");
am.put("onEscape", new EscapeAction());
}
/**
* Positions this popup to be in the top right-hand corner of the parent
* editor.
* Positions this popup to be in the top right-hand corner of the parent editor.
*/
private void setLocation() {
Point topLeft = textArea.getVisibleRect().getLocation();
@@ -132,23 +131,23 @@ class MatchedBracketPopup extends JWindow {
topLeft.y = Math.max(topLeft.y - 24, 0);
setLocation(topLeft.x - LEFT_EMPTY_BORDER, topLeft.y);
}
/**
* Action performed when Escape is pressed in this popup.
*/
private class EscapeAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
listener.uninstallAndHide();
}
}
/**
* Listens for events in this popup.
*/
private class Listener extends WindowAdapter implements ComponentListener {
Listener() {
addWindowFocusListener(this);
// If anything happens to the "parent" window, hide this popup
@@ -157,42 +156,42 @@ class MatchedBracketPopup extends JWindow {
parent.addWindowListener(this);
parent.addComponentListener(this);
}
@Override
public void componentResized(ComponentEvent e) {
uninstallAndHide();
}
@Override
public void componentMoved(ComponentEvent e) {
uninstallAndHide();
}
@Override
public void componentShown(ComponentEvent e) {
uninstallAndHide();
}
@Override
public void componentHidden(ComponentEvent e) {
uninstallAndHide();
}
@Override
public void windowActivated(WindowEvent e) {
checkForParentWindowEvent(e);
}
@Override
public void windowLostFocus(WindowEvent e) {
uninstallAndHide();
}
@Override
public void windowIconified(WindowEvent e) {
checkForParentWindowEvent(e);
}
private boolean checkForParentWindowEvent(WindowEvent e) {
if (e.getSource() == getParent()) {
uninstallAndHide();
@@ -200,7 +199,7 @@ class MatchedBracketPopup extends JWindow {
}
return false;
}
private void uninstallAndHide() {
Window parent = (Window) getParent();
parent.removeWindowFocusListener(this);
@@ -10,52 +10,44 @@ import org.fife.ui.rtextarea.SmartHighlightPainter;
/**
* An <code>OccurrenceMarker</code> is called when the caret stops moving after
* a short period. If the current {@link TokenMaker} returns an instance of
* this class, it is told to mark all occurrences of the identifier at the
* caret position.
* a short period. If the current {@link TokenMaker} returns an instance of this
* class, it is told to mark all occurrences of the identifier at the caret
* position.
*
* @author Robert Futrell
* @version 1.0
*/
public interface OccurrenceMarker {
/**
* Returns the token to mark occurrences, of, provided it matches the
* criteria put forth by {@link #isValidType(RSyntaxTextArea, Token)}.
* For most languages, this method should return the token at the caret
* position.
* Returns the token to mark occurrences, of, provided it matches the criteria
* put forth by {@link #isValidType(RSyntaxTextArea, Token)}. For most
* languages, this method should return the token at the caret position.
*
* @param textArea
* The text area.
* @return The token to (possibly) mark occurrences of, or
* <code>null</code> if none.
* @param textArea The text area.
* @return The token to (possibly) mark occurrences of, or <code>null</code> if
* none.
*/
Token getTokenToMark(RSyntaxTextArea textArea);
/**
* Returns whether the specified token is a type that we can do a
* "mark occurrences" of. Typically, this will delegate to
* Returns whether the specified token is a type that we can do a "mark
* occurrences" of. Typically, this will delegate to
* {@link RSyntaxTextArea#getMarkOccurrencesOfTokenType(int)}.
*
* @param textArea
* The text area.
* @param t
* The token.
* @param textArea The text area.
* @param t The token.
* @return Whether we should mark all occurrences of this token.
*/
boolean isValidType(RSyntaxTextArea textArea, Token t);
/**
* Called when occurrences of a token should be marked.
*
* @param doc
* The document.
* @param t
* The document whose relevant occurrences should be marked.
* @param h
* The highlighter to add the highlights to.
* @param p
* The painter for the highlights.
* @param doc The document.
* @param t The document whose relevant occurrences should be marked.
* @param h The highlighter to add the highlights to.
* @param p The painter for the highlights.
*/
void markOccurrences(RSyntaxDocument doc, Token t, RSyntaxTextAreaHighlighter h, SmartHighlightPainter p);
}
+116 -153
View File
@@ -46,7 +46,7 @@ import org.fife.ui.rtextarea.RTextAreaHighlighter.HighlightInfo;
* @version 0.9
*/
class ParserManager implements DocumentListener, ActionListener, HyperlinkListener, PropertyChangeListener {
private RSyntaxTextArea textArea;
private List<Parser> parsers;
private Timer timer;
@@ -55,20 +55,21 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
private Position firstOffsetModded;
private Position lastOffsetModded;
/**
* Mapping of notices to their highlights in the editor. Can't use a Map
* since parsers could return two <code>ParserNotice</code>s that compare
* equally via <code>equals()</code>. Real-world example: The Perl
* compiler will return 2+ identical error messages if the same error is
* committed in a single line more than once.
* Mapping of notices to their highlights in the editor. Can't use a Map since
* parsers could return two <code>ParserNotice</code>s that compare equally via
* <code>equals()</code>. Real-world example: The Perl compiler will return 2+
* identical error messages if the same error is committed in a single line more
* than once.
*/
private List<NoticeHighlightPair> noticeHighlightPairs;
/**
* Painter used to underline errors.
*/
private SquiggleUnderlineHighlightPainter parserErrorHighlightPainter = new SquiggleUnderlineHighlightPainter(Color.RED);
private SquiggleUnderlineHighlightPainter parserErrorHighlightPainter = new SquiggleUnderlineHighlightPainter(
Color.RED);
/**
* If this system property is set to <code>true</code>, debug messages
* will be printed to stdout to help diagnose parsing issues.
* If this system property is set to <code>true</code>, debug messages will be
* printed to stdout to help diagnose parsing issues.
*/
private static final String PROPERTY_DEBUG_PARSING = "rsta.debugParsing";
/**
@@ -76,31 +77,26 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
*/
private static final boolean DEBUG_PARSING;
/**
* The default delay between the last key press and when the document
* is parsed, in milliseconds.
* The default delay between the last key press and when the document is parsed,
* in milliseconds.
*/
private static final int DEFAULT_DELAY_MS = 1250;
/**
* Constructor.
*
* @param textArea
* The text area whose document the parser will be
* parsing.
* @param textArea The text area whose document the parser will be parsing.
*/
ParserManager(RSyntaxTextArea textArea) {
this(DEFAULT_DELAY_MS, textArea);
}
/**
* Constructor.
*
* @param delay
* The delay between the last key press and when the document
* is parsed.
* @param textArea
* The text area whose document the parser will be
* parsing.
* @param delay The delay between the last key press and when the document is
* parsed.
* @param textArea The text area whose document the parser will be parsing.
*/
ParserManager(int delay, RSyntaxTextArea textArea) {
this.textArea = textArea;
@@ -111,12 +107,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
timer.setRepeats(false);
running = true;
}
/**
* Called when the timer fires (e.g. it's time to parse the document).
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void actionPerformed(ActionEvent e) {
@@ -132,7 +127,8 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument();
Element root = doc.getDefaultRootElement();
int firstLine = firstOffsetModded == null ? 0 : root.getElementIndex(firstOffsetModded.getOffset());
int lastLine = lastOffsetModded == null ? root.getElementCount() - 1 : root.getElementIndex(lastOffsetModded.getOffset());
int lastLine = lastOffsetModded == null ? root.getElementCount() - 1
: root.getElementIndex(lastOffsetModded.getOffset());
firstOffsetModded = lastOffsetModded = null;
if (DEBUG_PARSING) {
System.out.println("[DEBUG]: Minimum lines to parse: " + firstLine + "-" + lastLine);
@@ -158,13 +154,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
System.out.println("Total parsing time: " + time + " seconds");
}
}
/**
* Adds a parser for the text area.
*
* @param parser
* The new parser. If this is <code>null</code>, nothing
* happens.
* @param parser The new parser. If this is <code>null</code>, nothing happens.
* @see #getParser(int)
* @see #removeParser(Parser)
*/
@@ -183,13 +177,12 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
}
}
/**
* Adds highlights for a list of parser notices. Any current notices
* from the same Parser, in the same parsed range, are removed.
* Adds highlights for a list of parser notices. Any current notices from the
* same Parser, in the same parsed range, are removed.
*
* @param res
* The result of a parsing.
* @param res The result of a parsing.
* @see #clearParserNoticeHighlights()
*/
private void addParserNoticeHighlights(ParseResult res) {
@@ -227,16 +220,16 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
System.out.println("[DEBUG]: Done adding parser notices from " + res.getParser());
}
}
/**
* Called when the document is modified.
*
* @param e
* The document event.
* @param e The document event.
*/
@Override
public void changedUpdate(DocumentEvent e) {}
public void changedUpdate(DocumentEvent e) {
}
private void clearParserNoticeHighlights() {
RSyntaxTextAreaHighlighter h = (RSyntaxTextAreaHighlighter) textArea.getHighlighter();
if (h != null) {
@@ -246,12 +239,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
noticeHighlightPairs.clear();
}
}
/**
* Removes all parser notice highlights for a specific parser.
*
* @param parser
* The parser whose highlights to remove.
* @param parser The parser whose highlights to remove.
*/
private void clearParserNoticeHighlights(Parser parser) {
RSyntaxTextAreaHighlighter h = (RSyntaxTextAreaHighlighter) textArea.getHighlighter();
@@ -268,7 +260,7 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
}
}
/**
* Removes all parsers and any highlights they have created.
*
@@ -280,20 +272,18 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
parsers.clear();
textArea.fireParserNoticesChange();
}
/**
* Forces the given {@link Parser} to re-parse the content of this text
* area.
* Forces the given {@link Parser} to re-parse the content of this text area.
* <p>
*
* This method can be useful when a <code>Parser</code> can be configured
* as to what notices it returns. For example, if a Java language parser
* can be configured to set whether no serialVersionUID is a warning,
* error, or ignored, this method can be called after changing the expected
* notice type to have the document re-parsed.
* This method can be useful when a <code>Parser</code> can be configured as to
* what notices it returns. For example, if a Java language parser can be
* configured to set whether no serialVersionUID is a warning, error, or
* ignored, this method can be called after changing the expected notice type to
* have the document re-parsed.
*
* @param parser
* The index of the <code>Parser</code> to re-run.
* @param parser The index of the <code>Parser</code> to re-run.
* @see #getParser(int)
*/
public void forceReparsing(int parser) {
@@ -313,10 +303,10 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
doc.readUnlock();
}
}
/**
* Returns the delay between the last "concurrent" edit and when the
* document is re-parsed.
* Returns the delay between the last "concurrent" edit and when the document is
* re-parsed.
*
* @return The delay, in milliseconds.
* @see #setDelay(int)
@@ -324,12 +314,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
public int getDelay() {
return timer.getDelay();
}
/**
* Returns the specified parser.
*
* @param index
* The index of the parser.
* @param index The index of the parser.
* @return The parser.
* @see #getParserCount()
* @see #addParser(Parser)
@@ -338,7 +327,7 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
public Parser getParser(int index) {
return parsers.get(index);
}
/**
* Returns the number of registered parsers.
*
@@ -347,14 +336,12 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
public int getParserCount() {
return parsers.size();
}
/**
* Returns a list of the current parser notices for this text area.
* This method (like most Swing methods) should only be called on the
* EDT.
* Returns a list of the current parser notices for this text area. This method
* (like most Swing methods) should only be called on the EDT.
*
* @return The list of notices. This will be an empty list if there are
* none.
* @return The list of notices. This will be an empty list if there are none.
*/
public List<ParserNotice> getParserNotices() {
List<ParserNotice> notices = new ArrayList<ParserNotice>();
@@ -365,15 +352,13 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
return notices;
}
/**
* Returns the tool tip to display for a mouse event at the given
* location. This method is overridden to give a registered parser a
* chance to display a tool tip (such as an error description when the
* mouse is over an error highlight).
* Returns the tool tip to display for a mouse event at the given location. This
* method is overridden to give a registered parser a chance to display a tool
* tip (such as an error description when the mouse is over an error highlight).
*
* @param e
* The mouse event.
* @param e The mouse event.
* @return The tool tip to display, and possibly a hyperlink event handler.
*/
public ToolTipInfo getToolTipText(MouseEvent e) {
@@ -385,19 +370,12 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
int pos = textArea.viewToModel(p);
/*
* Highlighter.Highlight[] highlights = textArea.getHighlighter().
* getHighlights();
* for (int i=0; i<highlights.length; i++) {
* Highlighter.Highlight h = highlights[i];
* //if (h instanceof ParserNoticeHighlight) {
* // ParserNoticeHighlight pnh = (ParserNoticeHighlight)h;
* int start = h.getStartOffset();
* int end = h.getEndOffset();
* if (start<=pos && end>=pos) {
* //return pnh.getMessage();
* return textArea.getText(start, end-start);
* }
* //}
* }
* getHighlights(); for (int i=0; i<highlights.length; i++) {
* Highlighter.Highlight h = highlights[i]; //if (h instanceof
* ParserNoticeHighlight) { // ParserNoticeHighlight pnh =
* (ParserNoticeHighlight)h; int start = h.getStartOffset(); int end =
* h.getEndOffset(); if (start<=pos && end>=pos) { //return pnh.getMessage();
* return textArea.getText(start, end-start); } //} }
*/
if (noticeHighlightPairs != null) {
for (NoticeHighlightPair pair : noticeHighlightPairs) {
@@ -418,25 +396,23 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
URL imageBase = parserForTip == null ? null : parserForTip.getImageBase();
return new ToolTipInfo(tip, listener, imageBase);
}
/**
* Called when the document is modified.
*
* @param e
* The document event.
* @param e The document event.
*/
public void handleDocumentEvent(DocumentEvent e) {
if (running && parsers.size() > 0) {
timer.restart();
}
}
/**
* Called when the user clicks a hyperlink in a
* {@link org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip}.
*
* @param e
* The event.
* @param e The event.
*/
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
@@ -444,12 +420,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
parserForTip.getHyperlinkListener().linkClicked(textArea, e);
}
}
/**
* Called when the document is modified.
*
* @param e
* The document event.
* @param e The document event.
*/
@Override
public void insertUpdate(DocumentEvent e) {
@@ -469,14 +444,12 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
handleDocumentEvent(e);
}
/**
* Returns whether a parser notice contains the specified offset.
*
* @param notice
* The notice.
* @param offs
* The offset.
* @param notice The notice.
* @param offs The offset.
* @return Whether the notice contains the offset.
*/
private boolean noticeContainsPosition(ParserNotice notice, int offs) {
@@ -492,20 +465,18 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
Element elem = root.getElement(line);
return elem != null && offs >= elem.getStartOffset() && offs < elem.getEndOffset();
}
/**
* Since <code>viewToModel()</code> returns the <em>closest</em> model
* position, and the position doesn't <em>necessarily</em> contain the
* point passed in as an argument, this method checks whether the point is
* indeed contained in the view rectangle for the specified offset.
* Since <code>viewToModel()</code> returns the <em>closest</em> model position,
* and the position doesn't <em>necessarily</em> contain the point passed in as
* an argument, this method checks whether the point is indeed contained in the
* view rectangle for the specified offset.
*
* @param notice
* The parser notice.
* @param p
* The point possibly contained in the view range of the
* parser notice.
* @return Whether the parser notice actually contains the specified point
* in the view.
* @param notice The parser notice.
* @param p The point possibly contained in the view range of the parser
* notice.
* @return Whether the parser notice actually contains the specified point in
* the view.
*/
private boolean noticeContainsPointInView(ParserNotice notice, Point p) {
try {
@@ -543,12 +514,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
return true;
}
}
/**
* Called when a property we're interested in changes.
*
* @param e
* The property change event.
* @param e The property change event.
*/
@Override
public void propertyChange(PropertyChangeEvent e) {
@@ -565,12 +535,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
}
}
/**
* Removes a parser.
*
* @param parser
* The parser to remove.
* @param parser The parser to remove.
* @return Whether the parser was found.
* @see #addParser(Parser)
* @see #getParser(int)
@@ -583,13 +552,12 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
return removed;
}
/**
* Removes all parser notices (and clears highlights in the editor) from
* a particular parser.
* Removes all parser notices (and clears highlights in the editor) from a
* particular parser.
*
* @param parser
* The parser.
* @param parser The parser.
*/
private void removeParserNotices(Parser parser) {
if (noticeHighlightPairs != null) {
@@ -603,14 +571,13 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
}
}
/**
* Removes any currently stored notices (and the corresponding highlights
* from the editor) from the same Parser, and in the given line range,
* as in the results.
* Removes any currently stored notices (and the corresponding highlights from
* the editor) from the same Parser, and in the given line range, as in the
* results.
*
* @param res
* The results.
* @param res The results.
*/
private void removeParserNotices(ParseResult res) {
if (noticeHighlightPairs != null) {
@@ -632,12 +599,11 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
}
}
/**
* Called when the document is modified.
*
* @param e
* The document event.
* @param e The document event.
*/
@Override
public void removeUpdate(DocumentEvent e) {
@@ -658,7 +624,7 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
}
handleDocumentEvent(e);
}
/**
* Restarts parsing the document.
*
@@ -668,14 +634,13 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
timer.restart();
running = true;
}
/**
* Sets the delay between the last "concurrent" edit and when the document
* is re-parsed.
* Sets the delay between the last "concurrent" edit and when the document is
* re-parsed.
*
* @param millis
* The new delay, in milliseconds. This must be greater
* than <code>0</code>.
* @param millis The new delay, in milliseconds. This must be greater than
* <code>0</code>.
* @see #getDelay()
*/
public void setDelay(int millis) {
@@ -688,20 +653,18 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
timer.start();
}
}
/**
* Returns whether a parser notice should be removed, based on a parse
* result.
* Returns whether a parser notice should be removed, based on a parse result.
*
* @param notice
* The notice in question.
* @param res
* The result.
* @param notice The notice in question.
* @param res The result.
* @return Whether the notice should be removed.
*/
private boolean shouldRemoveNotice(ParserNotice notice, ParseResult res) {
if (DEBUG_PARSING) {
System.out.println("[DEBUG]: ... ... shouldRemoveNotice " + notice + ": " + (notice.getParser() == res.getParser()));
System.out.println(
"[DEBUG]: ... ... shouldRemoveNotice " + notice + ": " + (notice.getParser() == res.getParser()));
}
// NOTE: We must currently remove all notices for the parser. Parser
// implementors are required to parse the entire document each parsing
@@ -712,7 +675,7 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
// return same_parser && (in_reparsed_range || in_deleted_end_of_doc)
return notice.getParser() == res.getParser();
}
/**
* Stops parsing the document.
*
@@ -722,21 +685,21 @@ class ParserManager implements DocumentListener, ActionListener, HyperlinkListen
timer.stop();
running = false;
}
/**
* Mapping of a parser notice to its highlight in the editor.
*/
private static class NoticeHighlightPair {
private ParserNotice notice;
private HighlightInfo highlight;
NoticeHighlightPair(ParserNotice notice, HighlightInfo highlight) {
this.notice = notice;
this.highlight = highlight;
}
}
static {
boolean debugParsing = false;
try {
@@ -12,48 +12,45 @@ import javax.swing.JWindow;
/**
* A hook allowing hosting applications to decorate JWindows created by the
* AutoComplete library. For example, you could use the
* <a href="http://jgoodies.com/">JGoodies</a> library to add drop shadows
* to the windows.
* <a href="http://jgoodies.com/">JGoodies</a> library to add drop shadows to
* the windows.
*
* @author Robert Futrell
* @version 1.0
*/
public abstract class PopupWindowDecorator {
/**
* The singleton instance of this class.
*/
private static PopupWindowDecorator decorator;
/**
* Callback called whenever an appropriate JWindow is created by the
* AutoComplete library. Implementations can decorate the window however
* they see fit.
* AutoComplete library. Implementations can decorate the window however they
* see fit.
*
* @param window
* The newly-created window.
* @param window The newly-created window.
*/
public abstract void decorate(JWindow window);
/**
* Returns the singleton instance of this class. This should only be
* called on the EDT.
* Returns the singleton instance of this class. This should only be called on
* the EDT.
*
* @return The singleton instance of this class, or <code>null</code>
* for none.
* @return The singleton instance of this class, or <code>null</code> for none.
* @see #set(PopupWindowDecorator)
*/
public static PopupWindowDecorator get() {
return decorator;
}
/**
* Sets the singleton instance of this class. This should only be called
* on the EDT.
* Sets the singleton instance of this class. This should only be called on the
* EDT.
*
* @param decorator
* The new instance of this class. This may be
* <code>null</code>.
* @param decorator The new instance of this class. This may be
* <code>null</code>.
* @see #get()
*/
public static void set(PopupWindowDecorator decorator) {
+20 -28
View File
@@ -17,46 +17,38 @@ import javax.swing.text.BadLocationException;
* @version 1.0
*/
interface RSTAView {
/**
* Returns the y-coordinate of the specified line.
* <p>
*
* This method is quicker than using traditional
* <code>modelToView(int)</code> calls, as the entire bounding box isn't
* computed.
* This method is quicker than using traditional <code>modelToView(int)</code>
* calls, as the entire bounding box isn't computed.
*
* @param alloc
* The area the text area can render into.
* @param line
* The line number.
* @return The y-coordinate of the top of the line, or <code>-1</code> if
* this text area doesn't yet have a positive size or the line is
* hidden (i.e. from folding).
* @throws BadLocationException
* If <code>line</code> isn't a valid line
* number for this document.
* @param alloc The area the text area can render into.
* @param line The line number.
* @return The y-coordinate of the top of the line, or <code>-1</code> if this
* text area doesn't yet have a positive size or the line is hidden
* (i.e. from folding).
* @throws BadLocationException If <code>line</code> isn't a valid line number
* for this document.
*/
int yForLine(Rectangle alloc, int line) throws BadLocationException;
/**
* Returns the y-coordinate of the line containing a specified offset.
* <p>
*
* This method is quicker than using traditional
* <code>modelToView(int)</code> calls, as the entire bounding box isn't
* computed.
* This method is quicker than using traditional <code>modelToView(int)</code>
* calls, as the entire bounding box isn't computed.
*
* @param alloc
* The area the text area can render into.
* @param offs
* The offset info the document.
* @return The y-coordinate of the top of the offset, or <code>-1</code> if
* this text area doesn't yet have a positive size or the line is
* hidden (i.e. from folding).
* @throws BadLocationException
* If <code>offs</code> isn't a valid offset
* into the document.
* @param alloc The area the text area can render into.
* @param offs The offset info the document.
* @return The y-coordinate of the top of the offset, or <code>-1</code> if this
* text area doesn't yet have a positive size or the line is hidden
* (i.e. from folding).
* @throws BadLocationException If <code>offs</code> isn't a valid offset into
* the document.
*/
int yForLineContaining(Rectangle alloc, int offs) throws BadLocationException;
}
@@ -49,10 +49,9 @@ import me.ByteEdit.edit.JavaAssemblyTokenMaker;
* @version 1.0
*/
public class RSyntaxDocument extends RDocument implements Iterable<Token>, SyntaxConstants {
/**
* Creates a {@link TokenMaker} appropriate for a given programming
* language.
* Creates a {@link TokenMaker} appropriate for a given programming language.
*/
private transient TokenMakerFactory tokenMakerFactory;
/**
@@ -64,8 +63,7 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
*/
private String syntaxStyle;
/**
* Array of values representing the "last token type" on each line. This is
* used
* Array of values representing the "last token type" on each line. This is used
* in cases such as multi-line comments: if the previous line ended with an
* (unclosed) multi-line comment, we can use this knowledge and start the
* current line's syntax highlighting in multi-line comment state.
@@ -77,35 +75,28 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
private transient int tokenRetrievalCount = 0;
private transient Segment s;
/**
* If this is set to <code>true</code>, debug information about how much
* token
* If this is set to <code>true</code>, debug information about how much token
* caching is helping is printed to stdout.
*/
private static final boolean DEBUG_TOKEN_CACHING = false;
/**
* Constructs a plain text document. A default root element is created, and
* the
* Constructs a plain text document. A default root element is created, and the
* tab size set to 5.
*
* @param syntaxStyle
* The syntax highlighting scheme to use.
* @param syntaxStyle The syntax highlighting scheme to use.
*/
public RSyntaxDocument(String syntaxStyle) {
this(null, syntaxStyle);
}
/**
* Constructs a plain text document. A default root element is created, and
* the
* Constructs a plain text document. A default root element is created, and the
* tab size set to 5.
*
* @param tmf
* The <code>TokenMakerFactory</code> for this document. If this
* is
* <code>null</code>, a default factory is used.
* @param syntaxStyle
* The syntax highlighting scheme to use.
* @param tmf The <code>TokenMakerFactory</code> for this document. If
* this is <code>null</code>, a default factory is used.
* @param syntaxStyle The syntax highlighting scheme to use.
*/
public RSyntaxDocument(TokenMakerFactory tmf, String syntaxStyle) {
putProperty(tabSizeAttribute, Integer.valueOf(5));
@@ -115,27 +106,23 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
setTokenMakerFactory(tmf);
setSyntaxStyle(syntaxStyle);
}
/**
* Alerts all listeners to this document of an insertion. This is overridden
* so
* Alerts all listeners to this document of an insertion. This is overridden so
* we can update our syntax highlighting stuff.
* <p>
* The syntax highlighting stuff has to be here instead of in
* <code>insertUpdate</code> because <code>insertUpdate</code> is not called
* by
* <code>insertUpdate</code> because <code>insertUpdate</code> is not called by
* the undo/redo actions, but this method is.
*
* @param e
* The change.
* @param e The change.
*/
@Override
protected void fireInsertUpdate(DocumentEvent e) {
cachedTokenList = null;
/*
* Now that the text is actually inserted into the content and element
* structure, we can update our token elements and
* "last tokens on lines"
* structure, we can update our token elements and "last tokens on lines"
* structure.
*/
Element lineMap = getDefaultRootElement();
@@ -174,23 +161,20 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
// Let all listeners know about the insertion.
super.fireInsertUpdate(e);
}
/**
* This method is called AFTER the content has been inserted into the
* document
* This method is called AFTER the content has been inserted into the document
* and the element structure has been updated.
* <p>
* The syntax-highlighting updates need to be done here (as opposed to an
* override of <code>postRemoveUpdate</code>) as this method is called in
* response to undo/redo events, whereas <code>postRemoveUpdate</code> is
* not.
* response to undo/redo events, whereas <code>postRemoveUpdate</code> is not.
* <p>
* Now that the text is actually inserted into the content and element
* structure, we can update our token elements and "last tokens on lines"
* structure.
*
* @param chng
* The change that occurred.
* @param chng The change that occurred.
* @see #removeUpdate
*/
@Override
@@ -240,26 +224,22 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
// Let all of our listeners know about the removal.
super.fireRemoveUpdate(chng);
}
/**
* Returns the closest {@link TokenTypes "standard" token type} for a given
* "internal" token type (e.g. one whose value is <code>&lt; 0</code>).
*
* @param type
* The token type.
* @return The closest "standard" token type. If a mapping is not defined
* for
* @param type The token type.
* @return The closest "standard" token type. If a mapping is not defined for
* this language, then <code>type</code> is returned.
*/
public int getClosestStandardTokenTypeForInternalType(int type) {
return tokenMaker.getClosestStandardTokenTypeForInternalType(type);
}
/**
* Returns whether closing markup tags should be automatically completed.
* This
* method only returns <code>true</code> if {@link #getLanguageIsMarkup()}
* also
* Returns whether closing markup tags should be automatically completed. This
* method only returns <code>true</code> if {@link #getLanguageIsMarkup()} also
* returns <code>true</code>.
*
* @return Whether markup closing tags should be automatically completed.
@@ -269,26 +249,24 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
// TODO: Remove terrible dependency on AbstractMarkupTokenMaker
return getLanguageIsMarkup() && ((AbstractMarkupTokenMaker) tokenMaker).getCompleteCloseTags();
}
/**
* Returns whether the current programming language uses curly braces
* ('<code>{</code>' and '<code>}</code>') to denote code blocks.
*
* @param languageIndex
* The language index at the offset in question. Since some
* <code>TokenMaker</code>s effectively have nested languages
* (such
* as JavaScript in HTML), this parameter tells the
* <code>TokenMaker</code> what sub-language to look at.
* @param languageIndex The language index at the offset in question. Since some
* <code>TokenMaker</code>s effectively have nested
* languages (such as JavaScript in HTML), this parameter
* tells the <code>TokenMaker</code> what sub-language to
* look at.
* @return Whether curly braces denote code blocks.
*/
public boolean getCurlyBracesDenoteCodeBlocks(int languageIndex) {
return tokenMaker.getCurlyBracesDenoteCodeBlocks(languageIndex);
}
/**
* Returns whether the current language is a markup language, such as HTML,
* XML
* Returns whether the current language is a markup language, such as HTML, XML
* or PHP.
*
* @return Whether the current language is a markup language.
@@ -296,50 +274,42 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
public boolean getLanguageIsMarkup() {
return tokenMaker.isMarkupLanguage();
}
/**
* Returns the token type of the last token on the given line.
*
* @param line
* The line to inspect.
* @return The token type of the last token on the specified line. If the
* line
* @param line The line to inspect.
* @return The token type of the last token on the specified line. If the line
* is invalid, an exception is thrown.
*/
public int getLastTokenTypeOnLine(int line) {
return lastTokensOnLines.get(line);
}
/**
* Returns the text to place at the beginning and end of a line to "comment"
* it
* Returns the text to place at the beginning and end of a line to "comment" it
* in this programming language.
*
* @return The start and end strings to add to a line to "comment" it out. A
* <code>null</code> value for either means there is no string to
* add
* for that part. A value of <code>null</code> for the array means
* this
* <code>null</code> value for either means there is no string to add
* for that part. A value of <code>null</code> for the array means this
* language does not support commenting/uncommenting lines.
*/
public String[] getLineCommentStartAndEnd(int languageIndex) {
return tokenMaker.getLineCommentStartAndEnd(languageIndex);
}
/**
* Returns whether tokens of the specified type should have "mark
* occurrences"
* Returns whether tokens of the specified type should have "mark occurrences"
* enabled for the current programming language.
*
* @param type
* The token type.
* @return Whether tokens of this type should have "mark occurrences"
* enabled.
* @param type The token type.
* @return Whether tokens of this type should have "mark occurrences" enabled.
*/
boolean getMarkOccurrencesOfTokenType(int type) {
return tokenMaker.getMarkOccurrencesOfTokenType(type);
}
/**
* Returns the occurrence marker for the current language.
*
@@ -348,13 +318,12 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
OccurrenceMarker getOccurrenceMarker() {
return tokenMaker.getOccurrenceMarker();
}
/**
* This method returns whether auto indentation should be done if Enter is
* pressed at the end of the specified line.
*
* @param line
* The line to check.
* @param line The line to check.
* @return Whether an extra indentation should be done.
*/
public boolean getShouldIndentNextLine(int line) {
@@ -362,7 +331,7 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
t = t.getLastNonCommentNonWhitespaceToken();
return tokenMaker.getShouldIndentNextLineAfter(t);
}
/**
* Returns the syntax style being used.
*
@@ -372,16 +341,14 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
public String getSyntaxStyle() {
return syntaxStyle;
}
/**
* Returns a token list for the specified segment of text representing the
* specified line number. This method is basically a wrapper for
* <code>tokenMaker.getTokenList</code> that takes into account the last
* token
* <code>tokenMaker.getTokenList</code> that takes into account the last token
* on the previous line to assure token accuracy.
*
* @param line
* The line number of <code>text</code> in the document, &gt;= 0.
* @param line The line number of <code>text</code> in the document, &gt;= 0.
* @return A token list representing the specified line.
*/
public final Token getTokenListForLine(int line) {
@@ -412,7 +379,7 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
cachedTokenList = tokenMaker.getTokenList(s, initialTokenType, startOffset);
return cachedTokenList;
}
boolean insertBreakSpecialHandling(ActionEvent e) {
Action a = tokenMaker.getInsertBreakAction();
if (a != null) {
@@ -421,28 +388,23 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
}
return false;
}
/**
* Returns whether a character could be part of an "identifier" token in a
* specific language. This is used to identify such things as the bounds of
* the
* specific language. This is used to identify such things as the bounds of the
* "word" to select on double-clicking.
*
* @param languageIndex
* The language index the character was found in.
* @param ch
* The character.
* @param languageIndex The language index the character was found in.
* @param ch The character.
* @return Whether the character could be part of an "identifier" token.
*/
public boolean isIdentifierChar(int languageIndex, char ch) {
return tokenMaker.isIdentifierChar(languageIndex, ch);
}
/**
* Returns an iterator over the paintable tokens in this document. Results
* are
* undefined if this document is modified while the iterator is being
* iterated
* Returns an iterator over the paintable tokens in this document. Results are
* undefined if this document is modified while the iterator is being iterated
* through, so this should only be used on the EDT.
* <p>
*
@@ -455,12 +417,11 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
public Iterator<Token> iterator() {
return new TokenIterator(this);
}
/**
* Deserializes a document.
*
* @param in
* The stream to read from.
* @param in The stream to read from.
* @throws ClassNotFoundException
* @throws IOException
*/
@@ -476,16 +437,13 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
lastTokensOnLines = new DynamicIntArray(lineCount);
setSyntaxStyle(syntaxStyle); // Actually install (transient) TokenMaker
}
/**
* Makes our private <code>Segment s</code> point to the text in our
* document
* referenced by the specified element. Note that <code>line</code> MUST be
* a
* Makes our private <code>Segment s</code> point to the text in our document
* referenced by the specified element. Note that <code>line</code> MUST be a
* valid line number in the document.
*
* @param line
* The line number you want to get.
* @param line The line number you want to get.
*/
private void setSharedSegment(int line) {
Element map = getDefaultRootElement();
@@ -504,20 +462,17 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
throw new InternalError("Text range not in document: " + startOffset + "-" + endOffset);
}
}
/**
* Sets the syntax style being used for syntax highlighting in this
* document.
* Sets the syntax style being used for syntax highlighting in this document.
* What styles are supported by a document is determined by its
* {@link TokenMakerFactory}. By default, all <code>RSyntaxDocument</code>s
* support all languages built into <code>RSyntaxTextArea</code>.
*
* @param styleKey
* The new style to use, such as
* {@link SyntaxConstants#SYNTAX_STYLE_JAVA}. If this style is
* not
* known or supported by this document, then
* {@link SyntaxConstants#SYNTAX_STYLE_NONE} is used.
* @param styleKey The new style to use, such as
* {@link SyntaxConstants#SYNTAX_STYLE_JAVA}. If this style is
* not known or supported by this document, then
* {@link SyntaxConstants#SYNTAX_STYLE_NONE} is used.
* @see #setSyntaxStyle(TokenMaker)
* @see #getSyntaxStyle()
*/
@@ -530,15 +485,13 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
updateSyntaxHighlightingInformation();
this.syntaxStyle = styleKey;
}
/**
* Sets the syntax style being used for syntax highlighting in this
* document.
* Sets the syntax style being used for syntax highlighting in this document.
* You should call this method if you've created a custom token maker for a
* language not normally supported by <code>RSyntaxTextArea</code>.
*
* @param tokenMaker
* The new token maker to use.
* @param tokenMaker The new token maker to use.
* @see #setSyntaxStyle(String)
*/
public void setSyntaxStyle(TokenMaker tokenMaker) {
@@ -546,35 +499,28 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
updateSyntaxHighlightingInformation();
this.syntaxStyle = "text/unknown"; // TODO: Make me public?
}
/**
* Sets the token maker factory used by this document.
*
* @param tmf
* The <code>TokenMakerFactory</code> for this document. If this
* is
* @param tmf The <code>TokenMakerFactory</code> for this document. If this is
* <code>null</code>, a default factory is used.
*/
public void setTokenMakerFactory(TokenMakerFactory tmf) {
tokenMakerFactory = tmf != null ? tmf : TokenMakerFactory.getDefaultInstance();
}
/**
* Loops through the last-tokens-on-lines array from a specified point
* onward,
* updating last-token values until they stop changing. This should be
* called
* when lines are updated/inserted/removed, as doing so may cause lines
* below to
* Loops through the last-tokens-on-lines array from a specified point onward,
* updating last-token values until they stop changing. This should be called
* when lines are updated/inserted/removed, as doing so may cause lines below to
* change color.
*
* @param line
* The first line to check for a change in last-token value.
* @param numLines
* The number of lines in the document.
* @param previousTokenType
* The last-token value of the line just before
* <code>line</code>.
* @param line The first line to check for a change in last-token
* value.
* @param numLines The number of lines in the document.
* @param previousTokenType The last-token value of the line just before
* <code>line</code>.
* @return The last line that needs repainting.
*/
private int updateLastTokensBelow(int line, int numLines, int previousTokenType) {
@@ -627,7 +573,7 @@ public class RSyntaxDocument extends RDocument implements Iterable<Token>, Synta
}
return line;
}
/**
* Updates internal state information; e.g. the "last tokens on lines" data.
* After this, a changed update is fired to let listeners know that the
File diff suppressed because it is too large. Load diff
@@ -27,8 +27,8 @@ import org.fife.ui.rtextarea.SmartHighlightPainter;
/**
* The highlighter implementation used by {@link RSyntaxTextArea}s. It knows to
* always paint "marked occurrences" highlights below selection highlights,
* and squiggle underline highlights above all other highlights.
* always paint "marked occurrences" highlights below selection highlights, and
* squiggle underline highlights above all other highlights.
* <p>
*
* Most of this code is copied from javax.swing.text.DefaultHighlighter;
@@ -38,22 +38,22 @@ import org.fife.ui.rtextarea.SmartHighlightPainter;
* @version 1.0
*/
public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
/**
* Marked occurrences in the document (to be painted separately from
* other highlights).
* Marked occurrences in the document (to be painted separately from other
* highlights).
*/
private List<SyntaxLayeredHighlightInfoImpl> markedOccurrences;
/**
* Highlights from document parsers. These should be painted "on top of"
* all other highlights to ensure they are always above the selection.
* Highlights from document parsers. These should be painted "on top of" all
* other highlights to ensure they are always above the selection.
*/
private List<SyntaxLayeredHighlightInfoImpl> parserHighlights;
/**
* The default color used for parser notices when none is specified.
*/
private static final Color DEFAULT_PARSER_NOTICE_COLOR = Color.RED;
/**
* Constructor.
*/
@@ -62,7 +62,7 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
parserHighlights = new ArrayList<SyntaxLayeredHighlightInfoImpl>(0); // Often
// unused
}
/**
* Adds a special "marked occurrence" highlight.
*
@@ -88,12 +88,11 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
mapper.damageRange(textArea, start, end);
return i;
}
/**
* Adds a highlight from a parser.
*
* @param notice
* The notice from a {@link Parser}.
* @param notice The notice from a {@link Parser}.
* @return A tag with which to reference the highlight.
* @throws BadLocationException
* @see #clearParserHighlights()
@@ -128,7 +127,7 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
mapper.damageRange(textArea, start, end);
return i;
}
/**
* Removes all "marked occurrences" highlights from the view.
*
@@ -142,7 +141,7 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
}
markedOccurrences.clear();
}
/**
* Removes all parser highlights.
*
@@ -157,12 +156,11 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
}
parserHighlights.clear();
}
/**
* Removes all of the highlights for a specific parser.
*
* @param parser
* The parser.
* @param parser The parser.
*/
public void clearParserHighlights(Parser parser) {
Iterator<SyntaxLayeredHighlightInfoImpl> i = parserHighlights.iterator();
@@ -176,7 +174,7 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
}
}
}
/**
* {@inheritDoc}
*/
@@ -186,10 +184,10 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
markedOccurrences.clear();
parserHighlights.clear();
}
/**
* Returns a list of "marked occurrences" in the text area. If there are
* no marked occurrences, this will be an empty list.
* Returns a list of "marked occurrences" in the text area. If there are no
* marked occurrences, this will be an empty list.
*
* @return The list of marked occurrences, or an empty list if none. The
* contents of this list will be of type {@link DocumentRange}.
@@ -210,19 +208,19 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
}
return list;
}
@Override
public void paintLayeredHighlights(Graphics g, int lineStart, int lineEnd, Shape viewBounds, JTextComponent editor, View view) {
public void paintLayeredHighlights(Graphics g, int lineStart, int lineEnd, Shape viewBounds, JTextComponent editor,
View view) {
paintListLayered(g, lineStart, lineEnd, viewBounds, editor, view, markedOccurrences);
super.paintLayeredHighlights(g, lineStart, lineEnd, viewBounds, editor, view);
paintListLayered(g, lineStart, lineEnd, viewBounds, editor, view, parserHighlights);
}
/**
* Removes a parser highlight from this view.
*
* @param tag
* The reference to the highlight.
* @param tag The reference to the highlight.
* @see #addParserHighlight(ParserNotice,
* javax.swing.text.Highlighter.HighlightPainter)
*/
@@ -230,16 +228,15 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
repaintListHighlight(tag);
parserHighlights.remove(tag);
}
/**
* Highlight info implementation used for parser notices and marked
* occurrences.
* Highlight info implementation used for parser notices and marked occurrences.
*/
private static class SyntaxLayeredHighlightInfoImpl extends LayeredHighlightInfoImpl {
private ParserNotice notice;// Color color; // Used only by Parser
// highlights.
@Override
public Color getColor() {
// return color;
@@ -252,11 +249,11 @@ public class RSyntaxTextAreaHighlighter extends RTextAreaHighlighter {
}
return color;
}
@Override
public String toString() {
return "[SyntaxLayeredHighlightInfoImpl: " + "startOffs=" + getStartOffset() + ", endOffs=" + getEndOffset() + ", color="
+ getColor() + "]";
return "[SyntaxLayeredHighlightInfoImpl: " + "startOffs=" + getStartOffset() + ", endOffs=" + getEndOffset()
+ ", color=" + getColor() + "]";
}
}
}
@@ -27,34 +27,33 @@ import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaUI;
/**
* UI used by <code>RSyntaxTextArea</code>. This allows us to implement
* syntax highlighting.
* UI used by <code>RSyntaxTextArea</code>. This allows us to implement syntax
* highlighting.
*
* @author Robert Futrell
* @version 0.1
*/
public class RSyntaxTextAreaUI extends RTextAreaUI {
private static final String SHARED_ACTION_MAP_NAME = "RSyntaxTextAreaUI.actionMap";
private static final String SHARED_INPUT_MAP_NAME = "RSyntaxTextAreaUI.inputMap";
private static final EditorKit DEFAULT_KIT = new RSyntaxTextAreaEditorKit();
public static ComponentUI createUI(JComponent ta) {
return new RSyntaxTextAreaUI(ta);
}
/**
* Constructor.
*/
public RSyntaxTextAreaUI(JComponent rSyntaxTextArea) {
super(rSyntaxTextArea);
}
/**
* Creates the view for an element.
*
* @param elem
* The element.
* @param elem The element.
* @return The view.
*/
@Override
@@ -72,7 +71,7 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
}
return null;
}
/**
* Creates the highlighter to use for syntax text areas.
*
@@ -82,11 +81,11 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
protected Highlighter createHighlighter() {
return new RSyntaxTextAreaHighlighter();
}
/**
* Returns the name to use to cache/fetch the shared action map. This
* should be overridden by subclasses if the subclass has its own custom
* editor kit to install, so its actions get picked up.
* Returns the name to use to cache/fetch the shared action map. This should be
* overridden by subclasses if the subclass has its own custom editor kit to
* install, so its actions get picked up.
*
* @return The name of the cached action map.
*/
@@ -94,12 +93,11 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
protected String getActionMapName() {
return SHARED_ACTION_MAP_NAME;
}
/**
* Fetches the EditorKit for the UI.
*
* @param tc
* The text component for which this UI is installed.
* @param tc The text component for which this UI is installed.
* @return The editor capabilities.
* @see javax.swing.plaf.TextUI#getEditorKit
*/
@@ -107,16 +105,16 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
public EditorKit getEditorKit(JTextComponent tc) {
return DEFAULT_KIT;
}
/**
* Get the InputMap to use for the UI.
* <p>
*
* This method is not named <code>getInputMap()</code> because there is
* a package-private method in <code>BasicTextAreaUI</code> with that name.
* Thus, creating a new method with that name causes certain compilers to
* issue warnings that you are not actually overriding the original method
* (since it is package-private).
* This method is not named <code>getInputMap()</code> because there is a
* package-private method in <code>BasicTextAreaUI</code> with that name. Thus,
* creating a new method with that name causes certain compilers to issue
* warnings that you are not actually overriding the original method (since it
* is package-private).
*/
@Override
protected InputMap getRTextAreaInputMap() {
@@ -132,18 +130,17 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
map.setParent(shared);
return map;
}
@Override
protected void paintEditorAugmentations(Graphics g) {
super.paintEditorAugmentations(g);
paintMatchedBracket(g);
}
/**
* Paints the "matched bracket", if any.
*
* @param g
* The graphics context.
* @param g The graphics context.
*/
protected void paintMatchedBracket(Graphics g) {
RSyntaxTextArea rsta = (RSyntaxTextArea) textArea;
@@ -160,7 +157,7 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
}
}
}
protected void paintMatchedBracketImpl(Graphics g, RSyntaxTextArea rsta, Rectangle r) {
// We must add "-1" to the height because otherwise we'll paint below
// the region that gets invalidated.
@@ -183,13 +180,12 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
g.drawRect(r.x, r.y, r.width, r.height - 1);
}
}
/**
* Gets called whenever a bound property is changed on this UI's
* <code>RSyntaxTextArea</code>.
*
* @param e
* The property change event.
* @param e The property change event.
*/
@Override
protected void propertyChange(PropertyChangeEvent e) {
@@ -204,7 +200,7 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
super.propertyChange(e);
}
}
/**
* Updates the view. This should be called when the underlying
* <code>RSyntaxTextArea</code> changes its syntax editing style.
@@ -212,14 +208,13 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
public void refreshSyntaxHighlighting() {
modelChanged();
}
/**
* Returns the y-coordinate of the specified line.
* <p>
*
* This method is quicker than using traditional
* <code>modelToView(int)</code> calls, as the entire bounding box isn't
* computed.
* This method is quicker than using traditional <code>modelToView(int)</code>
* calls, as the entire bounding box isn't computed.
*/
@Override
public int yForLine(int line) throws BadLocationException {
@@ -230,7 +225,7 @@ public class RSyntaxTextAreaUI extends RTextAreaUI {
}
return -1;
}
/**
* Returns the y-coordinate of the line containing a specified offset.
* <p>
File diff suppressed because it is too large. Load diff
+89 -101
View File
@@ -20,25 +20,24 @@ import java.io.StringReader;
* Gets the plain text version of RTF documents.
* <p>
*
* This is used by <code>RtfTransferable</code> to return the plain text
* version of the transferable when the receiver does not support RTF.
* This is used by <code>RtfTransferable</code> to return the plain text version
* of the transferable when the receiver does not support RTF.
*
* @author Robert Futrell
* @version 1.0
*/
final class RtfToText {
private Reader r;
private StringBuilder sb;
private StringBuilder controlWord;
private int blockCount;
private boolean inControlWord;
/**
* Private constructor.
*
* @param r
* The reader to read RTF text from.
* @param r The reader to read RTF text from.
*/
private RtfToText(Reader r) {
this.r = r;
@@ -47,15 +46,14 @@ final class RtfToText {
blockCount = 0;
inControlWord = false;
}
/**
* Converts the RTF text read from this converter's <code>Reader</code>
* into plain text. It is the caller's responsibility to close the
* reader after this method is called.
* Converts the RTF text read from this converter's <code>Reader</code> into
* plain text. It is the caller's responsibility to close the reader after this
* method is called.
*
* @return The plain text.
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
*/
private String convert() throws IOException {
// Skip over first curly brace as the whole file is in '{' and '}'
@@ -66,76 +64,76 @@ final class RtfToText {
while ((i = r.read()) != -1) {
char ch = (char) i;
switch (ch) {
case '{':
if (inControlWord && controlWord.length() == 0) { // "\{"
sb.append('{');
controlWord.setLength(0);
inControlWord = false;
} else {
blockCount++;
}
break;
case '}':
if (inControlWord && controlWord.length() == 0) { // "\}"
sb.append('}');
controlWord.setLength(0);
inControlWord = false;
} else {
blockCount--;
}
break;
case '\\':
if (blockCount == 0) {
if (inControlWord) {
if (controlWord.length() == 0) { // "\\"
sb.append('\\');
controlWord.setLength(0);
inControlWord = false;
} else {
endControlWord();
inControlWord = true;
}
case '{':
if (inControlWord && controlWord.length() == 0) { // "\{"
sb.append('{');
controlWord.setLength(0);
inControlWord = false;
} else {
blockCount++;
}
break;
case '}':
if (inControlWord && controlWord.length() == 0) { // "\}"
sb.append('}');
controlWord.setLength(0);
inControlWord = false;
} else {
blockCount--;
}
break;
case '\\':
if (blockCount == 0) {
if (inControlWord) {
if (controlWord.length() == 0) { // "\\"
sb.append('\\');
controlWord.setLength(0);
inControlWord = false;
} else {
endControlWord();
inControlWord = true;
}
} else {
inControlWord = true;
}
break;
case ' ':
if (blockCount == 0) {
if (inControlWord) {
endControlWord();
} else {
sb.append(' ');
}
}
break;
case ' ':
if (blockCount == 0) {
if (inControlWord) {
endControlWord();
} else {
sb.append(' ');
}
break;
case '\r':
case '\n':
if (blockCount == 0) {
if (inControlWord) {
endControlWord();
}
// Otherwise, ignore
}
break;
case '\r':
case '\n':
if (blockCount == 0) {
if (inControlWord) {
endControlWord();
}
break;
default:
if (blockCount == 0) {
if (inControlWord) {
controlWord.append(ch);
} else {
sb.append(ch);
}
// Otherwise, ignore
}
break;
default:
if (blockCount == 0) {
if (inControlWord) {
controlWord.append(ch);
} else {
sb.append(ch);
}
break;
}
break;
}
}
return sb.toString();
}
/**
* Ends a control word. Checks whether it is a common one that affects
* the plain text output (such as "<code>par</code>" or "<code>tab</code>")
* and updates the text buffer accordingly.
* Ends a control word. Checks whether it is a common one that affects the plain
* text output (such as "<code>par</code>" or "<code>tab</code>") and updates
* the text buffer accordingly.
*/
private void endControlWord() {
String word = controlWord.toString();
@@ -147,58 +145,50 @@ final class RtfToText {
controlWord.setLength(0);
inControlWord = false;
}
/**
* Converts the contents of the specified byte array representing
* an RTF document into plain text.
* Converts the contents of the specified byte array representing an RTF
* document into plain text.
*
* @param rtf
* The byte array representing an RTF document.
* @param rtf The byte array representing an RTF document.
* @return The contents of the RTF document, in plain text.
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
*/
public static String getPlainText(byte[] rtf) throws IOException {
return getPlainText(new ByteArrayInputStream(rtf));
}
/**
* Converts the contents of the specified RTF file to plain text.
*
* @param file
* The RTF file to convert.
* @param file The RTF file to convert.
* @return The contents of the file, in plain text.
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
*/
public static String getPlainText(File file) throws IOException {
return getPlainText(new BufferedReader(new FileReader(file)));
}
/**
* Converts the contents of the specified input stream to plain text.
* The input stream will be closed when this method returns.
* Converts the contents of the specified input stream to plain text. The input
* stream will be closed when this method returns.
*
* @param in
* The input stream to convert. This will be closed when this
* method returns.
* @param in The input stream to convert. This will be closed when this method
* returns.
* @return The contents of the stream, in plain text.
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
*/
public static String getPlainText(InputStream in) throws IOException {
return getPlainText(new InputStreamReader(in, "US-ASCII"));
}
/**
* Converts the contents of the specified <code>Reader</code> to plain text.
*
* @param r
* The <code>Reader</code>. This will be closed when this method
* returns.
* @param r The <code>Reader</code>. This will be closed when this method
* returns.
* @return The contents of the <code>Reader</code>, in plain text.
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
*/
private static String getPlainText(Reader r) throws IOException {
try {
@@ -208,15 +198,13 @@ final class RtfToText {
r.close();
}
}
/**
* Converts the contents of the specified String to plain text.
*
* @param rtf
* A string whose contents represent an RTF document.
* @param rtf A string whose contents represent an RTF document.
* @return The contents of the String, in plain text.
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
*/
public static String getPlainText(String rtf) throws IOException {
return getPlainText(new StringReader(rtf));
+102 -135
View File
@@ -27,12 +27,10 @@ import org.fife.ui.rtextarea.RTextArea;
* </ul>
*
* The RTF generated isn't really "optimized," but it will do, especially for
* small amounts of text, such as what's common when copy-and-pasting. It
* tries to be sufficient for the use case of copying syntax highlighted
* code:
* small amounts of text, such as what's common when copy-and-pasting. It tries
* to be sufficient for the use case of copying syntax highlighted code:
* <ul>
* <li>It assumes that tokens changing foreground color often is fairly
* common.
* <li>It assumes that tokens changing foreground color often is fairly common.
* <li>It assumes that background highlighting is fairly uncommon.
* </ul>
*
@@ -40,7 +38,7 @@ import org.fife.ui.rtextarea.RTextArea;
* @version 1.0
*/
public class RtfGenerator {
private List<Font> fontList;
private List<Color> colorList;
private StringBuilder document;
@@ -53,16 +51,15 @@ public class RtfGenerator {
/**
* Java2D assumes a 72 dpi screen resolution, but on Windows the screen
* resolution is either 96 dpi or 120 dpi, depending on your font display
* settings. This is an attempt to make the RTF generated match the
* size of what's displayed in the RSyntaxTextArea.
* settings. This is an attempt to make the RTF generated match the size of
* what's displayed in the RSyntaxTextArea.
*/
private int screenRes;
/**
* The default font size for RTF. This is point size, in half
* points.
* The default font size for RTF. This is point size, in half points.
*/
private static final int DEFAULT_FONT_SIZE = 12;// 24;
/**
* Constructor.
*/
@@ -72,7 +69,7 @@ public class RtfGenerator {
document = new StringBuilder();
reset();
}
/**
* Adds a newline to the RTF document.
*
@@ -83,87 +80,68 @@ public class RtfGenerator {
document.append('\n'); // Just for ease of reading RTF.
lastWasControlWord = false;
}
/**
* Appends styled text to the RTF document being generated.
*
* @param text
* The text to append.
* @param f
* The font of the text. If this is <code>null</code>, the
* default font is used.
* @param fg
* The foreground of the text. If this is <code>null</code>,
* the default foreground color is used.
* @param bg
* The background color of the text. If this is
* <code>null</code>, the default background color is used.
* @param text The text to append.
* @param f The font of the text. If this is <code>null</code>, the default
* font is used.
* @param fg The foreground of the text. If this is <code>null</code>, the
* default foreground color is used.
* @param bg The background color of the text. If this is <code>null</code>,
* the default background color is used.
* @see #appendNewline()
*/
public void appendToDoc(String text, Font f, Color fg, Color bg) {
appendToDoc(text, f, fg, bg, false);
}
/**
* Appends styled text to the RTF document being generated.
*
* @param text
* The text to append.
* @param f
* The font of the text. If this is <code>null</code>, the
* default font is used.
* @param bg
* The background color of the text. If this is
* <code>null</code>, the default background color is used.
* @param underline
* Whether the text should be underlined.
* @param text The text to append.
* @param f The font of the text. If this is <code>null</code>, the
* default font is used.
* @param bg The background color of the text. If this is
* <code>null</code>, the default background color is used.
* @param underline Whether the text should be underlined.
* @see #appendNewline()
*/
public void appendToDocNoFG(String text, Font f, Color bg, boolean underline) {
appendToDoc(text, f, null, bg, underline, false);
}
/**
* Appends styled text to the RTF document being generated.
*
* @param text
* The text to append.
* @param f
* The font of the text. If this is <code>null</code>, the
* default font is used.
* @param fg
* The foreground of the text. If this is <code>null</code>,
* the default foreground color is used.
* @param bg
* The background color of the text. If this is
* <code>null</code>, the default background color is used.
* @param underline
* Whether the text should be underlined.
* @param text The text to append.
* @param f The font of the text. If this is <code>null</code>, the
* default font is used.
* @param fg The foreground of the text. If this is <code>null</code>,
* the default foreground color is used.
* @param bg The background color of the text. If this is
* <code>null</code>, the default background color is used.
* @param underline Whether the text should be underlined.
* @see #appendNewline()
*/
public void appendToDoc(String text, Font f, Color fg, Color bg, boolean underline) {
appendToDoc(text, f, fg, bg, underline, true);
}
/**
* Appends styled text to the RTF document being generated.
*
* @param text
* The text to append.
* @param f
* The font of the text. If this is <code>null</code>, the
* default font is used.
* @param fg
* The foreground of the text. If this is <code>null</code>,
* the default foreground color is used.
* @param bg
* The background color of the text. If this is
* <code>null</code>, the default background color is used.
* @param underline
* Whether the text should be underlined.
* @param setFG
* Whether the foreground specified by <code>fg</code> should
* be honored (if it is non-<code>null</code>).
* @param text The text to append.
* @param f The font of the text. If this is <code>null</code>, the
* default font is used.
* @param fg The foreground of the text. If this is <code>null</code>,
* the default foreground color is used.
* @param bg The background color of the text. If this is
* <code>null</code>, the default background color is used.
* @param underline Whether the text should be underlined.
* @param setFG Whether the foreground specified by <code>fg</code> should
* be honored (if it is non-<code>null</code>).
* @see #appendNewline()
*/
public void appendToDoc(String text, Font f, Color fg, Color bg, boolean underline, boolean setFG) {
@@ -248,70 +226,65 @@ public class RtfGenerator {
}
}
}
/**
* Appends some text to a buffer, with special care taken for special
* characters as defined by the RTF spec.
* Appends some text to a buffer, with special care taken for special characters
* as defined by the RTF spec.
*
* <ul>
* <li>All tab characters are replaced with the string
* "<code>\tab</code>"
* <li>All tab characters are replaced with the string "<code>\tab</code>"
* <li>'\', '{' and '}' are changed to "\\", "\{" and "\}"
* </ul>
*
* @param text
* The text to append (with tab chars substituted).
* @param sb
* The buffer to append to.
* @param text The text to append (with tab chars substituted).
* @param sb The buffer to append to.
*/
private void escapeAndAdd(StringBuilder sb, String text) {
int count = text.length();
for (int i = 0; i < count; i++) {
char ch = text.charAt(i);
switch (ch) {
case '\t':
// Micro-optimization: for syntax highlighting with
// tab indentation, there are often multiple tabs
// back-to-back at the start of lines, so don't put
// spaces between each "\tab".
case '\t':
// Micro-optimization: for syntax highlighting with
// tab indentation, there are often multiple tabs
// back-to-back at the start of lines, so don't put
// spaces between each "\tab".
sb.append("\\tab");
while ((++i < count) && text.charAt(i) == '\t') {
sb.append("\\tab");
while ((++i < count) && text.charAt(i) == '\t') {
sb.append("\\tab");
}
sb.append(' ');
i--; // We read one too far.
break;
case '\\':
case '{':
case '}':
sb.append('\\').append(ch);
break;
default:
if (ch <= 127) {
sb.append(ch);
} else {
sb.append("\\u").append((int) ch);
}
break;
}
sb.append(' ');
i--; // We read one too far.
break;
case '\\':
case '{':
case '}':
sb.append('\\').append(ch);
break;
default:
if (ch <= 127) {
sb.append(ch);
} else {
sb.append("\\u").append((int) ch);
}
break;
}
}
}
/**
* Returns a font point size, adjusted for the current screen resolution.
* <p>
*
* Java2D assumes 72 dpi. On systems with larger dpi (Windows, GTK, etc.),
* font rendering will appear too small if we simply return a Java "Font"
* object's getSize() value. We need to adjust it for the screen
* resolution.
* Java2D assumes 72 dpi. On systems with larger dpi (Windows, GTK, etc.), font
* rendering will appear too small if we simply return a Java "Font" object's
* getSize() value. We need to adjust it for the screen resolution.
*
* @param pointSize
* A Java Font's point size, as returned from
* <code>getSize2D()</code>.
* @return The font point size, adjusted for the current screen resolution.
* This will allow other applications to render fonts the same
* size as they appear in the Java application.
* @param pointSize A Java Font's point size, as returned from
* <code>getSize2D()</code>.
* @return The font point size, adjusted for the current screen resolution. This
* will allow other applications to render fonts the same size as they
* appear in the Java application.
*/
private int fixFontSize(float pointSize) {
if (screenRes != 72) { // Java2D assumes 72 dpi
@@ -319,15 +292,13 @@ public class RtfGenerator {
}
return (int) pointSize;
}
/**
* Returns the index of the specified item in a list. If the item
* is not in the list, it is added, and its new index is returned.
* Returns the index of the specified item in a list. If the item is not in the
* list, it is added, and its new index is returned.
*
* @param list
* The list (possibly) containing the item.
* @param item
* The item to get the index of.
* @param list The list (possibly) containing the item.
* @param item The item to get the index of.
* @return The index of the item.
*/
private static int getColorIndex(List<Color> list, Color item) {
@@ -338,7 +309,7 @@ public class RtfGenerator {
}
return pos;
}
private String getColorTableRtf() {
// Example:
// "{\\colortbl ;\\red255\\green0\\blue0;\\red0\\green0\\blue255; }"
@@ -353,20 +324,17 @@ public class RtfGenerator {
sb.append("}");
return sb.toString();
}
/**
* Returns the index of the specified font in a list of fonts. This
* method only checks for a font by its family name; its attributes such
* as bold and italic are ignored.
* Returns the index of the specified font in a list of fonts. This method only
* checks for a font by its family name; its attributes such as bold and italic
* are ignored.
* <p>
*
* If the font is not in the list, it is added, and its new index is
* returned.
* If the font is not in the list, it is added, and its new index is returned.
*
* @param list
* The list (possibly) containing the font.
* @param font
* The font to get the index of.
* @param list The list (possibly) containing the font.
* @param font The font to get the index of.
* @return The index of the font.
*/
private static int getFontIndex(List<Font> list, Font font) {
@@ -380,7 +348,7 @@ public class RtfGenerator {
list.add(font);
return list.size() - 1;
}
private String getFontTableRtf() {
// Example:
// "{\\fonttbl{\\f0\\fmodern\\fcharset0 Courier;}}"
@@ -402,10 +370,10 @@ public class RtfGenerator {
sb.append('}');
return sb.toString();
}
/**
* Returns a good "default" monospaced font to use when Java's logical
* font "Monospaced" is found.
* Returns a good "default" monospaced font to use when Java's logical font
* "Monospaced" is found.
*
* @return The monospaced font family to use.
*/
@@ -416,7 +384,7 @@ public class RtfGenerator {
}
return family;
}
/**
* Returns the RTF document created by this generator.
*
@@ -440,10 +408,9 @@ public class RtfGenerator {
// System.err.println("*** " + sb.length());
return sb.toString();
}
/**
* Resets this generator. All document information and content is
* cleared.
* Resets this generator. All document information and content is cleared.
*/
public void reset() {
fontList.clear();
@@ -14,17 +14,16 @@ import java.io.IOException;
import java.io.StringReader;
/**
* Object used during copy/paste and DnD operations to represent RTF text.
* It can return the text being moved as either RTF or plain text. This
* class is basically the same as
* <code>java.awt.datatransfer.StringSelection</code>, except that it can also
* return the text as RTF.
* Object used during copy/paste and DnD operations to represent RTF text. It
* can return the text being moved as either RTF or plain text. This class is
* basically the same as <code>java.awt.datatransfer.StringSelection</code>,
* except that it can also return the text as RTF.
*
* @author Robert Futrell
* @version 1.0
*/
class RtfTransferable implements Transferable {
/**
* The RTF data, in bytes (the RTF is 7-bit ascii).
*/
@@ -32,19 +31,19 @@ class RtfTransferable implements Transferable {
/**
* The "flavors" the text can be returned as.
*/
private static final DataFlavor[] FLAVORS = { new DataFlavor("text/rtf", "RTF"), DataFlavor.stringFlavor, DataFlavor.plainTextFlavor // deprecated
private static final DataFlavor[] FLAVORS = { new DataFlavor("text/rtf", "RTF"), DataFlavor.stringFlavor,
DataFlavor.plainTextFlavor // deprecated
};
/**
* Constructor.
*
* @param data
* The RTF data.
* @param data The RTF data.
*/
RtfTransferable(byte[] data) {
this.data = data;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (flavor.equals(FLAVORS[0])) { // RTF
@@ -61,12 +60,12 @@ class RtfTransferable implements Transferable {
throw new UnsupportedFlavorException(flavor);
}
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return FLAVORS.clone();
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
for (int i = 0; i < FLAVORS.length; i++) {
@@ -11,28 +11,28 @@ package org.fife.ui.rsyntaxtextarea;
import javax.swing.event.HyperlinkEvent;
/**
* A link generator result that selects a region of text in the text area.
* This will typically be used by IDE-style applications, to provide support
* for "linking" the use of a variable in a document to its declaration.
* A link generator result that selects a region of text in the text area. This
* will typically be used by IDE-style applications, to provide support for
* "linking" the use of a variable in a document to its declaration.
*
* @author Robert Futrell
* @version 1.0
* @see LinkGenerator
*/
public class SelectRegionLinkGeneratorResult implements LinkGeneratorResult {
private RSyntaxTextArea textArea;
private int sourceOffset;
private int selStart;
private int selEnd;
public SelectRegionLinkGeneratorResult(RSyntaxTextArea textArea, int sourceOffset, int selStart, int selEnd) {
this.textArea = textArea;
this.sourceOffset = sourceOffset;
this.selStart = selStart;
this.selEnd = selEnd;
}
/**
* Selects the text in the text area.
*/
@@ -41,7 +41,7 @@ public class SelectRegionLinkGeneratorResult implements LinkGeneratorResult {
textArea.select(selStart, selEnd);
return null;
}
/**
* {@inheritDoc}
*/
@@ -32,37 +32,29 @@ import org.fife.ui.rtextarea.ChangeableHighlightPainter;
* @version 1.0
*/
public class SquiggleUnderlineHighlightPainter extends ChangeableHighlightPainter {
private static final int AMT = 2;
/**
* Constructor.
*
* @param color
* The color of the squiggle. This cannot be
* <code>null</code>.
* @param color The color of the squiggle. This cannot be <code>null</code>.
*/
public SquiggleUnderlineHighlightPainter(Color color) {
super(color);
setPaint(color);
}
/**
* Paints a portion of a highlight.
*
* @param g
* the graphics context
* @param offs0
* the starting model offset &gt;= 0
* @param offs1
* the ending model offset &gt;= offs1
* @param bounds
* the bounding box of the view, which is not
* necessarily the region to paint.
* @param c
* the editor
* @param view
* View painting for
* @param g the graphics context
* @param offs0 the starting model offset &gt;= 0
* @param offs1 the ending model offset &gt;= offs1
* @param bounds the bounding box of the view, which is not necessarily the
* region to paint.
* @param c the editor
* @param view View painting for
* @return region drawing occurred in
*/
@Override
@@ -92,14 +84,12 @@ public class SquiggleUnderlineHighlightPainter extends ChangeableHighlightPainte
// Only if exception
return null;
}
/**
* Paints a squiggle underneath text in the specified rectangle.
*
* @param g
* The graphics context with which to paint.
* @param r
* The rectangle containing the text.
* @param g The graphics context with which to paint.
* @param r The rectangle containing the text.
*/
protected void paintSquiggle(Graphics g, Rectangle r) {
int x = r.x;
@@ -8,8 +8,8 @@ package org.fife.ui.rsyntaxtextarea;
/**
* Constants that define the different programming languages understood by
* <code>RSyntaxTextArea</code>. These constants are the values you can pass
* to {@link RSyntaxTextArea#setSyntaxEditingStyle(String)} to get syntax
* <code>RSyntaxTextArea</code>. These constants are the values you can pass to
* {@link RSyntaxTextArea#setSyntaxEditingStyle(String)} to get syntax
* highlighting.
* <p>
*
@@ -25,7 +25,7 @@ package org.fife.ui.rsyntaxtextarea;
* @version 1.0
*/
public interface SyntaxConstants {
/**
* Style meaning don't syntax highlight anything.
*/
@@ -123,8 +123,8 @@ public interface SyntaxConstants {
*/
String SYNTAX_STYLE_JSON = "text/json";
/**
* Style for highlighting .jshintrc files (JSON with comments, so can be
* used for other times when you want this behavior).
* Style for highlighting .jshintrc files (JSON with comments, so can be used
* for other times when you want this behavior).
*/
String SYNTAX_STYLE_JSON_WITH_COMMENTS = "text/jshintrc";
/**
+207 -268
View File
@@ -30,14 +30,14 @@ import org.fife.ui.rsyntaxtextarea.folding.FoldManager;
/**
* The <code>javax.swing.text.View</code> object used by {@link RSyntaxTextArea}
* when word wrap is disabled. It implements syntax highlighting for
* programming languages using the colors and font styles specified by the
* when word wrap is disabled. It implements syntax highlighting for programming
* languages using the colors and font styles specified by the
* <code>RSyntaxTextArea</code>.
* <p>
*
* You don't really have to do anything to use this class, as
* {@link RSyntaxTextAreaUI} automatically sets the text area's view to be
* an instance of this class if word wrap is disabled.
* {@link RSyntaxTextAreaUI} automatically sets the text area's view to be an
* instance of this class if word wrap is disabled.
* <p>
*
* The tokens that specify how to paint the syntax-highlighted text are gleaned
@@ -47,7 +47,7 @@ import org.fife.ui.rsyntaxtextarea.folding.FoldManager;
* @version 0.3
*/
public class SyntaxView extends View implements TabExpander, TokenOrientedView, RSTAView {
/**
* The default font used by the text area. If this changes we need to
* recalculate the longest line.
@@ -58,9 +58,9 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
*/
private FontMetrics metrics;
/**
* The current longest line. This is used to calculate the preferred width
* of the view. Since the calculation is potentially expensive, we try to
* avoid it by stashing which line is currently the longest.
* The current longest line. This is used to calculate the preferred width of
* the view. Since the calculation is potentially expensive, we try to avoid it
* by stashing which line is currently the longest.
*/
private Element longLine;
private float longLineWidth;
@@ -78,30 +78,28 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
private int clipStart;
private int clipEnd;
/**
* Temporary token used when we need to "modify" tokens for rendering
* purposes. Since tokens returned from RSyntaxDocuments are treated as
* immutable, we use this temporary token to do that work.
* Temporary token used when we need to "modify" tokens for rendering purposes.
* Since tokens returned from RSyntaxDocuments are treated as immutable, we use
* this temporary token to do that work.
*/
private TokenImpl tempToken;
/**
* Constructs a new <code>SyntaxView</code> wrapped around an element.
*
* @param elem
* The element representing the text to display.
* @param elem The element representing the text to display.
*/
public SyntaxView(Element elem) {
super(elem);
tempToken = new TokenImpl();
}
/**
* Iterate over the lines represented by the child elements
* of the element this view represents, looking for the line
* that is the longest. The <em>longLine</em> variable is updated to
* represent the longest line contained. The <em>font</em> variable
* is updated to indicate the font used to calculate the
* longest line.
* Iterate over the lines represented by the child elements of the element this
* view represents, looking for the line that is the longest. The
* <em>longLine</em> variable is updated to represent the longest line
* contained. The <em>font</em> variable is updated to indicate the font used to
* calculate the longest line.
*/
void calculateLongestLine() {
Component c = getContainer();
@@ -119,37 +117,30 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
}
}
/**
* Gives notification from the document that attributes were changed
* in a location that this view is responsible for.
* Gives notification from the document that attributes were changed in a
* location that this view is responsible for.
*
* @param changes
* the change information from the associated document
* @param a
* the current allocation of the view
* @param f
* the factory to use to rebuild if the view has children
* @param changes the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see View#changedUpdate
*/
@Override
public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
updateDamage(changes, a, f);
}
/**
* Repaint the given line range.
*
* @param line0
* The starting line number to repaint. This must
* be a valid line number in the model.
* @param line1
* The ending line number to repaint. This must
* be a valid line number in the model.
* @param a
* The region allocated for the view to render into.
* @param host
* The component hosting the view (used to call repaint).
* @param line0 The starting line number to repaint. This must be a valid line
* number in the model.
* @param line1 The ending line number to repaint. This must be a valid line
* number in the model.
* @param a The region allocated for the view to render into.
* @param host The component hosting the view (used to call repaint).
*/
protected void damageLineRange(int line0, int line1, Shape a, Component host) {
if (a != null) {
@@ -163,23 +154,17 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
}
}
/**
* Draws the passed-in text using syntax highlighting for the current
* language. It is assumed that the entire line is either not in a
* selected region, or painting with a selection-foreground color is turned
* off.
* Draws the passed-in text using syntax highlighting for the current language.
* It is assumed that the entire line is either not in a selected region, or
* painting with a selection-foreground color is turned off.
*
* @param painter
* The painter to render the tokens.
* @param token
* The list of tokens to draw.
* @param g
* The graphics context in which to draw.
* @param x
* The x-coordinate at which to draw.
* @param y
* The y-coordinate at which to draw.
* @param painter The painter to render the tokens.
* @param token The list of tokens to draw.
* @param g The graphics context in which to draw.
* @param x The x-coordinate at which to draw.
* @param y The y-coordinate at which to draw.
* @return The x-coordinate representing the end of the painted text.
*/
private float drawLine(TokenPainter painter, Token token, Graphics2D g, float x, float y, int line) {
@@ -199,29 +184,23 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
// Return the x-coordinate at the end of the painted text.
return nextX;
}
/**
* Draws the passed-in text using syntax highlighting for the current
* language. Tokens are checked for being in a selected region, and are
* rendered appropriately if they are.
* Draws the passed-in text using syntax highlighting for the current language.
* Tokens are checked for being in a selected region, and are rendered
* appropriately if they are.
*
* @param painter
* The painter to render the tokens.
* @param token
* The list of tokens to draw.
* @param g
* The graphics context in which to draw.
* @param x
* The x-coordinate at which to draw.
* @param y
* The y-coordinate at which to draw.
* @param selStart
* The start of the selection.
* @param selEnd
* The end of the selection.
* @param painter The painter to render the tokens.
* @param token The list of tokens to draw.
* @param g The graphics context in which to draw.
* @param x The x-coordinate at which to draw.
* @param y The y-coordinate at which to draw.
* @param selStart The start of the selection.
* @param selEnd The end of the selection.
* @return The x-coordinate representing the end of the painted text.
*/
private float drawLineWithSelection(TokenPainter painter, Token token, Graphics2D g, float x, float y, int selStart, int selEnd) {
private float drawLineWithSelection(TokenPainter painter, Token token, Graphics2D g, float x, float y, int selStart,
int selEnd) {
float nextX = x; // The x-value at the end of our text.
boolean useSTC = host.getUseSelectedTextColor();
while (token != null && token.isPaintable() && nextX < clipEnd) {
@@ -281,90 +260,81 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
// Return the x-coordinate at the end of the painted text.
return nextX;
}
/**
* Calculates the width of the line represented by the given element.
*
* @param line
* The line for which to get the length.
* @param lineNumber
* The line number of the specified line in the document.
* @param line The line for which to get the length.
* @param lineNumber The line number of the specified line in the document.
* @return The width of the line.
*/
private float getLineWidth(int lineNumber) {
Token tokenList = ((RSyntaxDocument) getDocument()).getTokenListForLine(lineNumber);
return RSyntaxUtilities.getTokenListWidth(tokenList, (RSyntaxTextArea) getContainer(), this);
}
/**
* Provides a way to determine the next visually represented model
* location that one might place a caret. Some views may not be visible,
* they might not be in the same order found in the model, or they just
* might not allow access to some of the locations in the model.
* Provides a way to determine the next visually represented model location that
* one might place a caret. Some views may not be visible, they might not be in
* the same order found in the model, or they just might not allow access to
* some of the locations in the model.
*
* @param pos
* the position to convert &gt;= 0
* @param a
* the allocated region to render into
* @param direction
* the direction from the current position that can
* be thought of as the arrow keys typically found on a keyboard.
* This may be SwingConstants.WEST, SwingConstants.EAST,
* SwingConstants.NORTH, or SwingConstants.SOUTH.
* @return the location within the model that best represents the next
* location visual position.
* @param pos the position to convert &gt;= 0
* @param a the allocated region to render into
* @param direction the direction from the current position that can be thought
* of as the arrow keys typically found on a keyboard. This may
* be SwingConstants.WEST, SwingConstants.EAST,
* SwingConstants.NORTH, or SwingConstants.SOUTH.
* @return the location within the model that best represents the next location
* visual position.
* @exception BadLocationException
* @exception IllegalArgumentException
* for an invalid direction
* @exception IllegalArgumentException for an invalid direction
*/
@Override
public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet)
throws BadLocationException {
return RSyntaxUtilities.getNextVisualPositionFrom(pos, b, a, direction, biasRet, this);
}
/**
* Determines the preferred span for this view along an
* axis.
* Determines the preferred span for this view along an axis.
*
* @param axis
* may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into &gt;= 0.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
* @exception IllegalArgumentException
* for an invalid axis
* @param axis may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into &gt;= 0. Typically
* the view is told to render into the span that is returned, although
* there is no guarantee. The parent may choose to resize or break the
* view.
* @exception IllegalArgumentException for an invalid axis
*/
@Override
public float getPreferredSpan(int axis) {
updateMetrics();
switch (axis) {
case View.X_AXIS:
float span = longLineWidth + getRhsCorrection(); // fudge factor
if (host.getEOLMarkersVisible()) {
span += metrics.charWidth('\u00B6');
}
return span;
case View.Y_AXIS:
// We update lineHeight here as when this method is first
// called, lineHeight isn't initialized. If we don't do it
// here, we get no vertical scrollbar (as lineHeight==0).
lineHeight = host != null ? host.getLineHeight() : lineHeight;
// return getElement().getElementCount() * lineHeight;
int visibleLineCount = getElement().getElementCount();
if (host.isCodeFoldingEnabled()) {
visibleLineCount -= host.getFoldManager().getHiddenLineCount();
}
return visibleLineCount * (float) lineHeight;
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
case View.X_AXIS:
float span = longLineWidth + getRhsCorrection(); // fudge factor
if (host.getEOLMarkersVisible()) {
span += metrics.charWidth('\u00B6');
}
return span;
case View.Y_AXIS:
// We update lineHeight here as when this method is first
// called, lineHeight isn't initialized. If we don't do it
// here, we get no vertical scrollbar (as lineHeight==0).
lineHeight = host != null ? host.getLineHeight() : lineHeight;
// return getElement().getElementCount() * lineHeight;
int visibleLineCount = getElement().getElementCount();
if (host.isCodeFoldingEnabled()) {
visibleLineCount -= host.getFoldManager().getHiddenLineCount();
}
return visibleLineCount * (float) lineHeight;
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
}
/**
* Workaround for JTextComponents allowing the caret to be rendered
* entirely off-screen if the entire "previous" character fit entirely.
* Workaround for JTextComponents allowing the caret to be rendered entirely
* off-screen if the entire "previous" character fit entirely.
*
* @return The amount of space to add to the x-axis preferred span.
*/
@@ -375,7 +345,7 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
return rhsCorrection;
}
/**
* Returns the tab size set for the document, defaulting to 5.
*
@@ -386,19 +356,17 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
int size = (i != null) ? i.intValue() : 5;
return size;
}
/**
* Returns a token list for the <i>physical</i> line above the physical
* line containing the specified offset into the document. Note that for
* this plain (non-wrapped) view, this is simply the token list for the
* logical line above the line containing <code>offset</code>, since lines
* are not wrapped.
* Returns a token list for the <i>physical</i> line above the physical line
* containing the specified offset into the document. Note that for this plain
* (non-wrapped) view, this is simply the token list for the logical line above
* the line containing <code>offset</code>, since lines are not wrapped.
*
* @param offset
* The offset in question.
* @return A token list for the physical (and in this view, logical) line
* before this one. If <code>offset</code> is in the first line in
* the document, <code>null</code> is returned.
* @param offset The offset in question.
* @return A token list for the physical (and in this view, logical) line before
* this one. If <code>offset</code> is in the first line in the
* document, <code>null</code> is returned.
*/
@Override
public Token getTokenListForPhysicalLineAbove(int offset) {
@@ -422,19 +390,17 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
// return document.getTokenListForLine(line);
return null;
}
/**
* Returns a token list for the <i>physical</i> line below the physical
* line containing the specified offset into the document. Note that for
* this plain (non-wrapped) view, this is simply the token list for the
* logical line below the line containing <code>offset</code>, since lines
* are not wrapped.
* Returns a token list for the <i>physical</i> line below the physical line
* containing the specified offset into the document. Note that for this plain
* (non-wrapped) view, this is simply the token list for the logical line below
* the line containing <code>offset</code>, since lines are not wrapped.
*
* @param offset
* The offset in question.
* @return A token list for the physical (and in this view, logical) line
* after this one. If <code>offset</code> is in the last physical
* line in the document, <code>null</code> is returned.
* @param offset The offset in question.
* @return A token list for the physical (and in this view, logical) line after
* this one. If <code>offset</code> is in the last physical line in the
* document, <code>null</code> is returned.
*/
@Override
public Token getTokenListForPhysicalLineBelow(int offset) {
@@ -459,31 +425,26 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
// return document.getTokenListForLine(line+1);
return null;
}
/**
* Gives notification that something was inserted into the document
* in a location that this view is responsible for.
* Gives notification that something was inserted into the document in a
* location that this view is responsible for.
*
* @param changes
* The change information from the associated document.
* @param a
* The current allocation of the view.
* @param f
* The factory to use to rebuild if the view has children.
* @param changes The change information from the associated document.
* @param a The current allocation of the view.
* @param f The factory to use to rebuild if the view has children.
*/
@Override
public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
updateDamage(changes, a, f);
}
/**
* Determine the rectangle that represents the given line.
*
* @param a
* The region allocated for the view to render into
* @param line
* The line number to find the region of. This must
* be a valid line number in the model.
* @param a The region allocated for the view to render into
* @param line The line number to find the region of. This must be a valid line
* number in the model.
*/
protected Rectangle lineToRect(Shape a, int line) {
Rectangle r = null;
@@ -503,19 +464,16 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
return r;
}
/**
* Provides a mapping from the document model coordinate space
* to the coordinate space of the view mapped to it.
* Provides a mapping from the document model coordinate space to the coordinate
* space of the view mapped to it.
*
* @param pos
* the position to convert &gt;= 0
* @param a
* the allocated region to render into
* @param pos the position to convert &gt;= 0
* @param a the allocated region to render into
* @return the bounding box of the given position
* @exception BadLocationException
* if the given position does not
* represent a valid location in the associated document
* @exception BadLocationException if the given position does not represent a
* valid location in the associated document
* @see View#modelToView
*/
@Override
@@ -535,48 +493,43 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
lineArea = tokenList.listOffsetToView((RSyntaxTextArea) getContainer(), this, pos, tabBase, lineArea);
return lineArea;
}
/**
* Provides a mapping, for a given region, from the document model
* coordinate space to the view coordinate space. The specified region is
* created as a union of the first and last character positions.
* Provides a mapping, for a given region, from the document model coordinate
* space to the view coordinate space. The specified region is created as a
* union of the first and last character positions.
* <p>
*
* This is implemented to subtract the width of the second character, as
* this view's <code>modelToView</code> actually returns the width of the
* character instead of "1" or "0" like the View implementations in
* <code>javax.swing.text</code>. Thus, if we don't override this method,
* the <code>View</code> implementation will return one character's width
* too much for its consumers (implementations of
* This is implemented to subtract the width of the second character, as this
* view's <code>modelToView</code> actually returns the width of the character
* instead of "1" or "0" like the View implementations in
* <code>javax.swing.text</code>. Thus, if we don't override this method, the
* <code>View</code> implementation will return one character's width too much
* for its consumers (implementations of
* <code>javax.swing.text.Highlighter</code>).
*
* @param p0
* the position of the first character (&gt;=0)
* @param b0
* The bias of the first character position, toward the previous
* character or the next character represented by the offset, in
* case the position is a boundary of two views; <code>b0</code>
* will have one of these values:
* <ul>
* <li><code>Position.Bias.Forward</code>
* <li><code>Position.Bias.Backward</code>
* </ul>
* @param p1
* the position of the last character (&gt;=0)
* @param b1
* the bias for the second character position, defined
* one of the legal values shown above
* @param a
* the area of the view, which encompasses the requested region
* @return the bounding box which is a union of the region specified
* by the first and last character positions
* @exception BadLocationException
* if the given position does
* not represent a valid location in the associated document
* @exception IllegalArgumentException
* if <code>b0</code> or
* <code>b1</code> are not one of the
* legal <code>Position.Bias</code> values listed above
* @param p0 the position of the first character (&gt;=0)
* @param b0 The bias of the first character position, toward the previous
* character or the next character represented by the offset, in case
* the position is a boundary of two views; <code>b0</code> will have
* one of these values:
* <ul>
* <li><code>Position.Bias.Forward</code>
* <li><code>Position.Bias.Backward</code>
* </ul>
* @param p1 the position of the last character (&gt;=0)
* @param b1 the bias for the second character position, defined one of the
* legal values shown above
* @param a the area of the view, which encompasses the requested region
* @return the bounding box which is a union of the region specified by the
* first and last character positions
* @exception BadLocationException if the given position does not represent
* a valid location in the associated
* document
* @exception IllegalArgumentException if <code>b0</code> or <code>b1</code> are
* not one of the legal
* <code>Position.Bias</code> values listed
* above
* @see View#viewToModel
*/
@Override
@@ -618,17 +571,15 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
return r0;
}
/**
* Returns the next tab stop position after a given reference position.
* This implementation does not support things like centering so it
* ignores the tabOffset argument.
* Returns the next tab stop position after a given reference position. This
* implementation does not support things like centering so it ignores the
* tabOffset argument.
*
* @param x
* the current position &gt;= 0
* @param tabOffset
* the position within the text stream
* that the tab occurred at &gt;= 0.
* @param x the current position &gt;= 0
* @param tabOffset the position within the text stream that the tab occurred at
* &gt;= 0.
* @return the tab stop, measured in points &gt;= 0
*/
@Override
@@ -639,15 +590,13 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
int ntabs = (((int) x) - tabBase) / tabSize;
return tabBase + ((ntabs + 1f) * tabSize);
}
/**
* Actually paints the text area. Only lines that have been damaged are
* repainted.
*
* @param g
* The graphics context with which to paint.
* @param a
* The allocated region in which to render.
* @param g The graphics context with which to paint.
* @param a The allocated region in which to render.
*/
@Override
public void paint(Graphics g, Shape a) {
@@ -726,15 +675,13 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
// System.out.println("SyntaxView: lines painted=" + count);
}
/**
* If the passed-in line is longer than the current longest line, then
* the longest line is updated.
* If the passed-in line is longer than the current longest line, then the
* longest line is updated.
*
* @param line
* The line to test against the current longest.
* @param lineNumber
* The line number of the passed-in line.
* @param line The line to test against the current longest.
* @param lineNumber The line number of the passed-in line.
* @return <code>true</code> iff the current longest line was updated.
*/
private boolean possiblyUpdateLongLine(Element line, int lineNumber) {
@@ -746,36 +693,31 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
return false;
}
/**
* Gives notification that something was removed from the document
* in a location that this view is responsible for.
* Gives notification that something was removed from the document in a location
* that this view is responsible for.
*
* @param changes
* the change information from the associated document
* @param a
* the current allocation of the view
* @param f
* the factory to use to rebuild if the view has children
* @param changes the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
*/
@Override
public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
updateDamage(changes, a, f);
}
@Override
public void setSize(float width, float height) {
super.setSize(width, height);
updateMetrics();
}
/**
* Repaint the region of change covered by the given document
* event. Damages the line that begins the range to cover
* the case when the insert/remove is only on one line.
* If lines are added or removed, damages the whole
* view. The longest line is checked to see if it has
* changed.
* Repaint the region of change covered by the given document event. Damages the
* line that begins the range to cover the case when the insert/remove is only
* on one line. If lines are added or removed, damages the whole view. The
* longest line is checked to see if it has changed.
*/
protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f) {
Component host = getContainer();
@@ -841,7 +783,7 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
}
}
/**
* Checks to see if the font metrics and longest line are up-to-date.
*/
@@ -854,19 +796,16 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
calculateLongestLine();
}
}
/**
* Provides a mapping from the view coordinate space to the logical
* coordinate space of the model.
* Provides a mapping from the view coordinate space to the logical coordinate
* space of the model.
*
* @param fx
* the X coordinate &gt;= 0
* @param fy
* the Y coordinate &gt;= 0
* @param a
* the allocated region to render into
* @return the location within the model that best represents the
* given point in the view &gt;= 0
* @param fx the X coordinate &gt;= 0
* @param fy the Y coordinate &gt;= 0
* @param a the allocated region to render into
* @return the location within the model that best represents the given point in
* the view &gt;= 0
*/
@Override
public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {
@@ -918,7 +857,7 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
} // End of else.
}
/**
* {@inheritDoc}
*/
@@ -941,7 +880,7 @@ public class SyntaxView extends View implements TabExpander, TokenOrientedView,
}
return -1;
}
/**
* {@inheritDoc}
*/
@@ -28,8 +28,8 @@ import org.fife.io.UnicodeWriter;
import org.fife.ui.rtextarea.RTextAreaEditorKit;
/**
* An extension of {@link org.fife.ui.rsyntaxtextarea.RSyntaxTextArea}
* that adds information about the file being edited, such as:
* An extension of {@link org.fife.ui.rsyntaxtextarea.RSyntaxTextArea} that adds
* information about the file being edited, such as:
*
* <ul>
* <li>Its name and location.
@@ -43,10 +43,10 @@ import org.fife.ui.rtextarea.RTextAreaEditorKit;
* Loading and saving is also built into the editor.
* <p>
*
* When saving UTF-8 files, whether or not a BOM is written is controlled by
* the {@link UnicodeWriter} class.
* Use {@link UnicodeWriter#setWriteUtf8BOM(boolean)} to toggle writing BOMs
* for UTF-8 files.
* When saving UTF-8 files, whether or not a BOM is written is controlled by the
* {@link UnicodeWriter} class. Use
* {@link UnicodeWriter#setWriteUtf8BOM(boolean)} to toggle writing BOMs for
* UTF-8 files.
* <p>
*
* Both local and remote files (e.g. ftp) are supported. See the
@@ -57,11 +57,11 @@ import org.fife.ui.rtextarea.RTextAreaEditorKit;
* @see FileLocation
*/
public class TextEditorPane extends RSyntaxTextArea implements DocumentListener {
private static final long serialVersionUID = 1L;
/**
* Property change event fired when the file path this text area references
* is updated.
* Property change event fired when the file path this text area references is
* updated.
*
* @see #load(FileLocation, String)
* @see #saveAs(FileLocation)
@@ -103,9 +103,8 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
*/
private boolean dirty;
/**
* The last time this file was modified on disk, for local files.
* For remote files, this value should always be
* {@link #LAST_MODIFIED_UNKNOWN}.
* The last time this file was modified on disk, for local files. For remote
* files, this value should always be {@link #LAST_MODIFIED_UNKNOWN}.
*/
private long lastSaveOrLoadTime;
/**
@@ -116,34 +115,31 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
* The default name given to files if none is specified in a constructor.
*/
private static final String DEFAULT_FILE_NAME = "Untitled.txt";
/**
* Constructor. The file will be given a default name.
*/
public TextEditorPane() {
this(INSERT_MODE);
}
/**
* Constructor. The file will be given a default name.
*
* @param textMode
* Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
* @param textMode Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
*/
public TextEditorPane(int textMode) {
this(textMode, false);
}
/**
* Creates a new <code>TextEditorPane</code>. The file will be given
* a default name.
* Creates a new <code>TextEditorPane</code>. The file will be given a default
* name.
*
* @param textMode
* Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
* @param wordWrapEnabled
* Whether or not to use word wrap in this pane.
* @param textMode Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
* @param wordWrapEnabled Whether or not to use word wrap in this pane.
*/
public TextEditorPane(int textMode, boolean wordWrapEnabled) {
super(textMode);
@@ -154,69 +150,58 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
ioe.printStackTrace();
}
}
/**
* Creates a new <code>TextEditorPane</code>.
*
* @param textMode
* Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
* @param wordWrapEnabled
* Whether or not to use word wrap in this pane.
* @param loc
* The location of the text file being edited. If this value
* is <code>null</code>, a file named "Untitled.txt" in the
* current
* directory is used.
* @throws IOException
* If an IO error occurs reading the file at
* <code>loc</code>. This of course won't happen if
* <code>loc</code> is <code>null</code>.
* @param textMode Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
* @param wordWrapEnabled Whether or not to use word wrap in this pane.
* @param loc The location of the text file being edited. If this
* value is <code>null</code>, a file named
* "Untitled.txt" in the current directory is used.
* @throws IOException If an IO error occurs reading the file at
* <code>loc</code>. This of course won't happen if
* <code>loc</code> is <code>null</code>.
*/
public TextEditorPane(int textMode, boolean wordWrapEnabled, FileLocation loc) throws IOException {
this(textMode, wordWrapEnabled, loc, null);
}
/**
* Creates a new <code>TextEditorPane</code>.
*
* @param textMode
* Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
* @param wordWrapEnabled
* Whether or not to use word wrap in this pane.
* @param loc
* The location of the text file being edited. If this value
* is <code>null</code>, a file named "Untitled.txt" in the
* current
* directory is used. This file is displayed as empty even if it
* actually exists.
* @param defaultEnc
* The default encoding to use when opening the file,
* if the file is not Unicode. If this value is
* <code>null</code>,
* a system default value is used.
* @throws IOException
* If an IO error occurs reading the file at
* <code>loc</code>. This of course won't happen if
* <code>loc</code> is <code>null</code>.
* @param textMode Either <code>INSERT_MODE</code> or
* <code>OVERWRITE_MODE</code>.
* @param wordWrapEnabled Whether or not to use word wrap in this pane.
* @param loc The location of the text file being edited. If this
* value is <code>null</code>, a file named
* "Untitled.txt" in the current directory is used. This
* file is displayed as empty even if it actually exists.
* @param defaultEnc The default encoding to use when opening the file, if
* the file is not Unicode. If this value is
* <code>null</code>, a system default value is used.
* @throws IOException If an IO error occurs reading the file at
* <code>loc</code>. This of course won't happen if
* <code>loc</code> is <code>null</code>.
*/
public TextEditorPane(int textMode, boolean wordWrapEnabled, FileLocation loc, String defaultEnc) throws IOException {
public TextEditorPane(int textMode, boolean wordWrapEnabled, FileLocation loc, String defaultEnc)
throws IOException {
super(textMode);
setLineWrap(wordWrapEnabled);
init(loc, defaultEnc);
}
/**
* Callback for when styles in the current document change.
* This method is never called.
* Callback for when styles in the current document change. This method is never
* called.
*
* @param e
* The document event.
* @param e The document event.
*/
@Override
public void changedUpdate(DocumentEvent e) {}
public void changedUpdate(DocumentEvent e) {
}
/**
* Returns the default encoding for this operating system.
*
@@ -239,7 +224,7 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
}
return encoding;
}
/**
* Returns the encoding to use when reading or writing this file.
*
@@ -249,7 +234,7 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
public String getEncoding() {
return charSet;
}
/**
* Returns the full path to this document.
*
@@ -258,7 +243,7 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
public String getFileFullPath() {
return loc == null ? null : loc.getFileFullPath();
}
/**
* Returns the file name of this document.
*
@@ -267,61 +252,58 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
public String getFileName() {
return loc == null ? null : loc.getFileName();
}
/**
* Returns the timestamp for when this file was last loaded or saved
* <em>by this editor pane</em>. If the file has been modified on disk by
* another process after it was loaded into this editor pane, this method
* will not return the actual file's last modified time.
* Returns the timestamp for when this file was last loaded or saved <em>by this
* editor pane</em>. If the file has been modified on disk by another process
* after it was loaded into this editor pane, this method will not return the
* actual file's last modified time.
* <p>
*
* For remote files, this method will always return
* {@link #LAST_MODIFIED_UNKNOWN}.
*
* @return The timestamp when this file was last loaded or saved by this
* editor pane, if it is a local file, or
* {@link #LAST_MODIFIED_UNKNOWN} if it is a remote file.
* @return The timestamp when this file was last loaded or saved by this editor
* pane, if it is a local file, or {@link #LAST_MODIFIED_UNKNOWN} if it
* is a remote file.
* @see #isModifiedOutsideEditor()
*/
public long getLastSaveOrLoadTime() {
return lastSaveOrLoadTime;
}
/**
* Returns the line separator used when writing this file (e.g.
* "<code>\n</code>", "<code>\r\n</code>", or "<code>\r</code>").
* <p>
*
* Note that this value is an <code>Object</code> and not a
* <code>String</code> as that is the way the {@link Document} interface
* defines its property values. If you always use
* {@link #setLineSeparator(String)} to modify this value, then the value
* returned from this method will always be a <code>String</code>.
* Note that this value is an <code>Object</code> and not a <code>String</code>
* as that is the way the {@link Document} interface defines its property
* values. If you always use {@link #setLineSeparator(String)} to modify this
* value, then the value returned from this method will always be a
* <code>String</code>.
*
* @return The line separator. If this value is <code>null</code>, then
* the system default line separator is used (usually the value
* of <code>System.getProperty("line.separator")</code>).
* @return The line separator. If this value is <code>null</code>, then the
* system default line separator is used (usually the value of
* <code>System.getProperty("line.separator")</code>).
* @see #setLineSeparator(String)
* @see #setLineSeparator(String, boolean)
*/
public Object getLineSeparator() {
return getDocument().getProperty(RTextAreaEditorKit.EndOfLineStringProperty);
}
/**
* Initializes this editor with the specified file location.
*
* @param loc
* The file location. If this is <code>null</code>, a default
* location is used and an empty file is displayed.
* @param defaultEnc
* The default encoding to use when opening the file,
* if the file is not Unicode. If this value is
* <code>null</code>,
* a system default value is used.
* @throws IOException
* If an IO error occurs reading from <code>loc</code>.
* If <code>loc</code> is <code>null</code>, this cannot happen.
* @param loc The file location. If this is <code>null</code>, a default
* location is used and an empty file is displayed.
* @param defaultEnc The default encoding to use when opening the file, if the
* file is not Unicode. If this value is <code>null</code>, a
* system default value is used.
* @throws IOException If an IO error occurs reading from <code>loc</code>. If
* <code>loc</code> is <code>null</code>, this cannot
* happen.
*/
private void init(FileLocation loc, String defaultEnc) throws IOException {
if (loc == null) {
@@ -347,12 +329,11 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
}
setDirty(false);
}
/**
* Callback for when text is inserted into the document.
*
* @param e
* Information on the insertion.
* @param e Information on the insertion.
*/
@Override
public void insertUpdate(DocumentEvent e) {
@@ -360,7 +341,7 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
setDirty(true);
}
}
/**
* Returns whether or not the text in this editor has unsaved changes.
*
@@ -370,7 +351,7 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
public boolean isDirty() {
return dirty;
}
/**
* Returns whether this file is a local file.
*
@@ -379,7 +360,7 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
public boolean isLocal() {
return loc.isLocal();
}
/**
* Returns whether this is a local file that already exists.
*
@@ -388,25 +369,24 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
public boolean isLocalAndExists() {
return loc.isLocalAndExists();
}
/**
* Returns whether the text file has been modified outside of this editor
* since the last load or save operation. Note that if this is a remote
* file, this method will always return <code>false</code>.
* Returns whether the text file has been modified outside of this editor since
* the last load or save operation. Note that if this is a remote file, this
* method will always return <code>false</code>.
* <p>
*
* This method may be used by applications to implement a reloading
* feature, where the user is prompted to reload a file if it has been
* modified since their last open or save.
* This method may be used by applications to implement a reloading feature,
* where the user is prompted to reload a file if it has been modified since
* their last open or save.
*
* @return Whether the text file has been modified outside of this
* editor.
* @return Whether the text file has been modified outside of this editor.
* @see #getLastSaveOrLoadTime()
*/
public boolean isModifiedOutsideEditor() {
return loc.getActualLastModified() > getLastSaveOrLoadTime();
}
/**
* Returns whether or not the text area should be treated as read-only.
*
@@ -416,22 +396,18 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
public boolean isReadOnly() {
return readOnly;
}
/**
* Loads the specified file in this editor. This method fires a property
* change event of type {@link #FULL_PATH_PROPERTY}.
* Loads the specified file in this editor. This method fires a property change
* event of type {@link #FULL_PATH_PROPERTY}.
*
* @param loc
* The location of the file to load. This cannot be
* <code>null</code>.
* @param defaultEnc
* The encoding to use when loading/saving the file.
* This encoding will only be used if the file is not Unicode.
* If this value is <code>null</code>, the system default
* encoding
* is used.
* @throws IOException
* If an IO error occurs.
* @param loc The location of the file to load. This cannot be
* <code>null</code>.
* @param defaultEnc The encoding to use when loading/saving the file. This
* encoding will only be used if the file is not Unicode. If
* this value is <code>null</code>, the system default
* encoding is used.
* @throws IOException If an IO error occurs.
* @see #save()
* @see #saveAs(FileLocation)
*/
@@ -468,25 +444,24 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
discardAllEdits();
firePropertyChange(FULL_PATH_PROPERTY, old, getFileFullPath());
}
/**
* Reloads this file from disk. The file must exist for this operation
* to not throw an exception.
* Reloads this file from disk. The file must exist for this operation to not
* throw an exception.
* <p>
*
* The file's "dirty" state will be set to <code>false</code> after this
* operation. If this is a local file, its "last modified" time is
* updated to reflect that of the actual file.
* operation. If this is a local file, its "last modified" time is updated to
* reflect that of the actual file.
* <p>
*
* Note that if the file has been modified on disk, and is now a Unicode
* encoding when before it wasn't (or if it is a different Unicode now),
* this will cause this {@link TextEditorPane}'s encoding to change.
* Otherwise, the file's encoding will stay the same.
* encoding when before it wasn't (or if it is a different Unicode now), this
* will cause this {@link TextEditorPane}'s encoding to change. Otherwise, the
* file's encoding will stay the same.
*
* @throws IOException
* If the file does not exist, or if an IO error
* occurs reading the file.
* @throws IOException If the file does not exist, or if an IO error occurs
* reading the file.
* @see #isLocalAndExists()
*/
public void reload() throws IOException {
@@ -504,12 +479,11 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
syncLastSaveOrLoadTimeToActualFile();
discardAllEdits(); // Prevent user from being able to undo the reload
}
/**
* Called whenever text is removed from this editor.
*
* @param e
* The document event.
* @param e The document event.
*/
@Override
public void removeUpdate(DocumentEvent e) {
@@ -517,16 +491,15 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
setDirty(true);
}
}
/**
* Saves the file in its current encoding.
* <p>
*
* The text area's "dirty" state is set to <code>false</code>, and if
* this is a local file, its "last modified" time is updated.
* The text area's "dirty" state is set to <code>false</code>, and if this is a
* local file, its "last modified" time is updated.
*
* @throws IOException
* If an IO error occurs.
* @throws IOException If an IO error occurs.
* @see #saveAs(FileLocation)
* @see #load(FileLocation, String)
*/
@@ -535,15 +508,13 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
setDirty(false);
syncLastSaveOrLoadTimeToActualFile();
}
/**
* Saves this file in a new local location. This method fires a property
* change event of type {@link #FULL_PATH_PROPERTY}.
* Saves this file in a new local location. This method fires a property change
* event of type {@link #FULL_PATH_PROPERTY}.
*
* @param loc
* The location to save to.
* @throws IOException
* If an IO error occurs.
* @param loc The location to save to.
* @throws IOException If an IO error occurs.
* @see #save()
* @see #load(FileLocation, String)
*/
@@ -556,14 +527,12 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
lastSaveOrLoadTime = loc.getActualLastModified();
firePropertyChange(FULL_PATH_PROPERTY, old, getFileFullPath());
}
/**
* Saves the text in this editor to the specified location.
*
* @param loc
* The location to save to.
* @throws IOException
* If an IO error occurs.
* @param loc The location to save to.
* @throws IOException If an IO error occurs.
*/
private void saveImpl(FileLocation loc) throws IOException {
OutputStream out = loc.getOutputStream();
@@ -574,23 +543,22 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
w.close();
}
}
/**
* Sets whether or not this text in this editor has unsaved changes.
* This fires a property change event of type {@link #DIRTY_PROPERTY}.
* Sets whether or not this text in this editor has unsaved changes. This fires
* a property change event of type {@link #DIRTY_PROPERTY}.
* <p>
*
* Applications will usually have no need to call this method directly; the
* only time you might have a need to call this method directly is if you
* have to initialize an instance of TextEditorPane with content that does
* not come from a file. <code>TextEditorPane</code> automatically sets its
* own dirty flag when its content is edited, when its encoding is changed,
* or when its line ending property is changed. It is cleared whenever
* <code>load()</code>, <code>reload()</code>, <code>save()</code>, or
* <code>saveAs()</code> are called.
* Applications will usually have no need to call this method directly; the only
* time you might have a need to call this method directly is if you have to
* initialize an instance of TextEditorPane with content that does not come from
* a file. <code>TextEditorPane</code> automatically sets its own dirty flag
* when its content is edited, when its encoding is changed, or when its line
* ending property is changed. It is cleared whenever <code>load()</code>,
* <code>reload()</code>, <code>save()</code>, or <code>saveAs()</code> are
* called.
*
* @param dirty
* Whether or not the text has been modified.
* @param dirty Whether or not the text has been modified.
* @see #isDirty()
*/
public void setDirty(boolean dirty) {
@@ -599,12 +567,11 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
firePropertyChange(DIRTY_PROPERTY, !dirty, dirty);
}
}
/**
* Sets the document for this editor.
*
* @param doc
* The new document.
* @param doc The new document.
*/
@Override
public void setDocument(Document doc) {
@@ -615,19 +582,16 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
super.setDocument(doc);
doc.addDocumentListener(this);
}
/**
* Sets the encoding to use when reading or writing this file. This
* method sets the editor's dirty flag when the encoding is changed, and
* fires a property change event of type {@link #ENCODING_PROPERTY}.
* Sets the encoding to use when reading or writing this file. This method sets
* the editor's dirty flag when the encoding is changed, and fires a property
* change event of type {@link #ENCODING_PROPERTY}.
*
* @param encoding
* The new encoding.
* @throws UnsupportedCharsetException
* If the encoding is not supported.
* @throws NullPointerException
* If <code>encoding</code> is
* <code>null</code>.
* @param encoding The new encoding.
* @throws UnsupportedCharsetException If the encoding is not supported.
* @throws NullPointerException If <code>encoding</code> is
* <code>null</code>.
* @see #getEncoding()
*/
public void setEncoding(String encoding) {
@@ -643,50 +607,43 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
setDirty(true);
}
}
/**
* Sets the line separator sequence to use when this file is saved (e.g.
* "<code>\n</code>", "<code>\r\n</code>" or "<code>\r</code>").
*
* Besides parameter checking, this method is preferred over
* <code>getDocument().putProperty()</code> because it sets the editor's
* dirty flag when the line separator is changed.
* <code>getDocument().putProperty()</code> because it sets the editor's dirty
* flag when the line separator is changed.
*
* @param separator
* The new line separator.
* @throws NullPointerException
* If <code>separator</code> is
* <code>null</code>.
* @throws IllegalArgumentException
* If <code>separator</code> is not one
* of "<code>\n</code>", "<code>\r\n</code>" or
* "<code>\r</code>".
* @param separator The new line separator.
* @throws NullPointerException If <code>separator</code> is
* <code>null</code>.
* @throws IllegalArgumentException If <code>separator</code> is not one of
* "<code>\n</code>", "<code>\r\n</code>" or
* "<code>\r</code>".
* @see #getLineSeparator()
*/
public void setLineSeparator(String separator) {
setLineSeparator(separator, true);
}
/**
* Sets the line separator sequence to use when this file is saved (e.g.
* "<code>\n</code>", "<code>\r\n</code>" or "<code>\r</code>").
*
* Besides parameter checking, this method is preferred over
* <code>getDocument().putProperty()</code> because can set the editor's
* dirty flag when the line separator is changed.
* <code>getDocument().putProperty()</code> because can set the editor's dirty
* flag when the line separator is changed.
*
* @param separator
* The new line separator.
* @param setDirty
* Whether the dirty flag should be set if the line
* separator is changed.
* @throws NullPointerException
* If <code>separator</code> is
* <code>null</code>.
* @throws IllegalArgumentException
* If <code>separator</code> is not one
* of "<code>\n</code>", "<code>\r\n</code>" or
* "<code>\r</code>".
* @param separator The new line separator.
* @param setDirty Whether the dirty flag should be set if the line separator
* is changed.
* @throws NullPointerException If <code>separator</code> is
* <code>null</code>.
* @throws IllegalArgumentException If <code>separator</code> is not one of
* "<code>\n</code>", "<code>\r\n</code>" or
* "<code>\r</code>".
* @see #getLineSeparator()
*/
public void setLineSeparator(String separator, boolean setDirty) {
@@ -705,13 +662,12 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
}
}
}
/**
* Sets whether or not this text area should be treated as read-only.
* This fires a property change event of type {@link #READ_ONLY_PROPERTY}.
* Sets whether or not this text area should be treated as read-only. This fires
* a property change event of type {@link #READ_ONLY_PROPERTY}.
*
* @param readOnly
* Whether or not the document is read-only.
* @param readOnly Whether or not the document is read-only.
* @see #isReadOnly()
*/
public void setReadOnly(boolean readOnly) {
@@ -720,16 +676,16 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
firePropertyChange(READ_ONLY_PROPERTY, !readOnly, readOnly);
}
}
/**
* Syncs this text area's "last saved or loaded" time to that of the file
* being edited, if that file is local and exists. If the file is
* remote or is local but does not yet exist, nothing happens.
* Syncs this text area's "last saved or loaded" time to that of the file being
* edited, if that file is local and exists. If the file is remote or is local
* but does not yet exist, nothing happens.
* <p>
*
* You normally do not have to call this method, as the "last saved or
* loaded" time for {@link TextEditorPane}s is kept up-to-date internally
* during such operations as {@link #save()}, {@link #reload()}, etc.
* You normally do not have to call this method, as the "last saved or loaded"
* time for {@link TextEditorPane}s is kept up-to-date internally during such
* operations as {@link #save()}, {@link #reload()}, etc.
*
* @see #getLastSaveOrLoadTime()
* @see #isModifiedOutsideEditor()
@@ -739,7 +695,7 @@ public class TextEditorPane extends RSyntaxTextArea implements DocumentListener
lastSaveOrLoadTime = loc.getActualLastModified();
}
}
public static void main(String[] args) throws Exception {
try {
TextEditorPane textArea = new TextEditorPane();
+191 -244
View File
@@ -38,195 +38,173 @@ import javax.swing.text.TabExpander;
* @version 0.3
*/
public interface Token extends TokenTypes {
/**
* Appends HTML code for painting this token, using the given text area's
* color scheme.
* Appends HTML code for painting this token, using the given text area's color
* scheme.
*
* @param sb
* The buffer to append to.
* @param textArea
* The text area whose color scheme to use.
* @param fontFamily
* Whether to include the font family in the HTML for
* this token. You can pass <code>false</code> for this parameter
* if, for example, you are making all your HTML be monospaced,
* and don't want any crazy fonts being used in the editor to be
* reflected in your HTML.
* @param sb The buffer to append to.
* @param textArea The text area whose color scheme to use.
* @param fontFamily Whether to include the font family in the HTML for this
* token. You can pass <code>false</code> for this parameter
* if, for example, you are making all your HTML be
* monospaced, and don't want any crazy fonts being used in
* the editor to be reflected in your HTML.
* @return The buffer appended to.
* @see #getHTMLRepresentation(RSyntaxTextArea)
*/
StringBuilder appendHTMLRepresentation(StringBuilder sb, RSyntaxTextArea textArea, boolean fontFamily);
/**
* Appends HTML code for painting this token, using the given text area's
* color scheme.
* Appends HTML code for painting this token, using the given text area's color
* scheme.
*
* @param sb
* The buffer to append to.
* @param textArea
* The text area whose color scheme to use.
* @param fontFamily
* Whether to include the font family in the HTML for
* this token. You can pass <code>false</code> for this parameter
* if, for example, you are making all your HTML be monospaced,
* and don't want any crazy fonts being used in the editor to be
* reflected in your HTML.
* @param tabsToSpaces
* Whether to convert tabs into spaces.
* @param sb The buffer to append to.
* @param textArea The text area whose color scheme to use.
* @param fontFamily Whether to include the font family in the HTML for this
* token. You can pass <code>false</code> for this parameter
* if, for example, you are making all your HTML be
* monospaced, and don't want any crazy fonts being used in
* the editor to be reflected in your HTML.
* @param tabsToSpaces Whether to convert tabs into spaces.
* @return The buffer appended to.
* @see #getHTMLRepresentation(RSyntaxTextArea)
*/
StringBuilder appendHTMLRepresentation(StringBuilder sb, RSyntaxTextArea textArea, boolean fontFamily, boolean tabsToSpaces);
StringBuilder appendHTMLRepresentation(StringBuilder sb, RSyntaxTextArea textArea, boolean fontFamily,
boolean tabsToSpaces);
/**
* Returns the character at the specified offset in the token.
*
* @param index
* The index. This should be in the range
* <code>0-({@link #length()}-1)</code>.
* @param index The index. This should be in the range
* <code>0-({@link #length()}-1)</code>.
* @return The character.
* @see #length()
*/
char charAt(int index);
/**
* Returns whether the token straddles the specified position in the
* document.
* Returns whether the token straddles the specified position in the document.
*
* @param pos
* The position in the document to check.
* @param pos The position in the document to check.
* @return Whether the specified position is straddled by this token.
*/
boolean containsPosition(int pos);
/**
* Returns the position in the token's internal char array corresponding
* to the specified document position.
* Returns the position in the token's internal char array corresponding to the
* specified document position.
* <p>
* Note that this method does NOT do any bounds checking; you can pass in
* a document position that does not correspond to a position in this
* token, and you will not receive an Exception or any other notification;
* it is up to the caller to ensure valid input.
* Note that this method does NOT do any bounds checking; you can pass in a
* document position that does not correspond to a position in this token, and
* you will not receive an Exception or any other notification; it is up to the
* caller to ensure valid input.
*
* @param pos
* A position in the document that is represented by this token.
* @return The corresponding token position &gt;= <code>textOffset</code>
* and &lt; <code>textOffset+textCount</code>.
* @param pos A position in the document that is represented by this token.
* @return The corresponding token position &gt;= <code>textOffset</code> and
* &lt; <code>textOffset+textCount</code>.
* @see #tokenToDocument
*/
int documentToToken(int pos);
/**
* Returns whether this token's lexeme ends with the specified characters.
*
* @param ch
* The characters.
* @param ch The characters.
* @return Whether this token's lexeme ends with the specified characters.
* @see #startsWith(char[])
*/
boolean endsWith(char[] ch);
/**
* Returns the end offset of this token in the document (exclusive). In
* other words, the token ranges from
* <code>[getOffset(), getEndOffset())</code>.
* Returns the end offset of this token in the document (exclusive). In other
* words, the token ranges from <code>[getOffset(), getEndOffset())</code>.
*
* @return The end offset of this token.
* @see #getOffset()
*/
int getEndOffset();
/**
* Returns a <code>String</code> containing HTML code for painting this
* token, using the given text area's color scheme.
* Returns a <code>String</code> containing HTML code for painting this token,
* using the given text area's color scheme.
*
* @param textArea
* The text area whose color scheme to use.
* @param textArea The text area whose color scheme to use.
* @return The HTML representation of the token.
* @see #appendHTMLRepresentation(StringBuilder, RSyntaxTextArea, boolean)
*/
String getHTMLRepresentation(RSyntaxTextArea textArea);
/**
* Returns the language index of this token.
*
* @return The language index. A value of <code>0</code> denotes the
* "main" language, any positive value denotes a specific secondary
* language.
* @return The language index. A value of <code>0</code> denotes the "main"
* language, any positive value denotes a specific secondary language.
* @see #setLanguageIndex(int)
*/
int getLanguageIndex();
/**
* Returns the last token in this list that is not whitespace or a
* comment.
* Returns the last token in this list that is not whitespace or a comment.
*
* @return The last non-comment, non-whitespace token, or <code>null</code>
* if there isn't one.
* @return The last non-comment, non-whitespace token, or <code>null</code> if
* there isn't one.
*/
Token getLastNonCommentNonWhitespaceToken();
/**
* Returns the last paintable token in this token list, or <code>null</code>
* if there is no paintable token.
* Returns the last paintable token in this token list, or <code>null</code> if
* there is no paintable token.
*
* @return The last paintable token in this token list.
*/
Token getLastPaintableToken();
/**
* Returns the text of this token, as a string.
* <p>
*
* Note that this method isn't used much by the
* <code>ryntaxtextarea</code> package internally, as it tries to limit
* memory allocation.
* Note that this method isn't used much by the <code>ryntaxtextarea</code>
* package internally, as it tries to limit memory allocation.
*
* @return The text of this token.
*/
String getLexeme();
/**
* Determines the offset into this token list (i.e., into the
* document) that covers pixel location <code>x</code> if the token list
* starts at pixel location <code>x0</code>
* Determines the offset into this token list (i.e., into the document) that
* covers pixel location <code>x</code> if the token list starts at pixel
* location <code>x0</code>
* <p>
* .
* This method will return the document position "closest" to the
* x-coordinate (i.e., if they click on the "right-half" of the
* <code>w</code> in <code>awe</code>, the caret will be placed in
* between the <code>w</code> and <code>e</code>; similarly, clicking on
* the left-half places the caret between the <code>a</code> and
* <code>w</code>). This makes it useful for methods such as
* <code>viewToModel</code> found in <code>javax.swing.text.View</code>
* . This method will return the document position "closest" to the x-coordinate
* (i.e., if they click on the "right-half" of the <code>w</code> in
* <code>awe</code>, the caret will be placed in between the <code>w</code> and
* <code>e</code>; similarly, clicking on the left-half places the caret between
* the <code>a</code> and <code>w</code>). This makes it useful for methods such
* as <code>viewToModel</code> found in <code>javax.swing.text.View</code>
* subclasses.
*
* @param textArea
* The text area from which the token list was derived.
* @param e
* How to expand tabs.
* @param x0
* The pixel x-location that is the beginning of
* <code>tokenList</code>.
* @param x
* The pixel-position for which you want to get the corresponding
* offset.
* @return The position (in the document, NOT into the token list!) that
* covers the pixel location. If <code>tokenList</code> is
* <code>null</code> or has type <code>Token.NULL</code>, then
* <code>-1</code> is returned; the caller should recognize this and
* return the actual end position of the (empty) line.
* @param textArea The text area from which the token list was derived.
* @param e How to expand tabs.
* @param x0 The pixel x-location that is the beginning of
* <code>tokenList</code>.
* @param x The pixel-position for which you want to get the
* corresponding offset.
* @return The position (in the document, NOT into the token list!) that covers
* the pixel location. If <code>tokenList</code> is <code>null</code> or
* has type <code>Token.NULL</code>, then <code>-1</code> is returned;
* the caller should recognize this and return the actual end position
* of the (empty) line.
*/
int getListOffset(RSyntaxTextArea textArea, TabExpander e, float x0, float x);
/**
* Returns the token after this one in the linked list.
*
* @return The next token.
*/
Token getNextToken();
/**
* Returns the offset into the document at which this token resides.
*
@@ -234,49 +212,43 @@ public interface Token extends TokenTypes {
* @see #getEndOffset()
*/
int getOffset();
/**
* Returns the position in the document that represents the last character
* in the token that will fit into <code>endBeforeX-startX</code> pixels.
* For example, if you're using a monospaced 8-pixel-per-character font,
* have the token "while" and <code>startX</code> is <code>0</code> and
* Returns the position in the document that represents the last character in
* the token that will fit into <code>endBeforeX-startX</code> pixels. For
* example, if you're using a monospaced 8-pixel-per-character font, have the
* token "while" and <code>startX</code> is <code>0</code> and
* <code>endBeforeX</code> is <code>30</code>, this method will return the
* document position of the "i" in "while", because the "i" ends at pixel
* <code>24</code>, while the "l" ends at <code>32</code>. If not even the
* first character fits in <code>endBeforeX-startX</code>, the first
* character's position is still returned so calling methods don't go into
* infinite loops.
* <code>24</code>, while the "l" ends at <code>32</code>. If not even the first
* character fits in <code>endBeforeX-startX</code>, the first character's
* position is still returned so calling methods don't go into infinite loops.
*
* @param textArea
* The text area in which this token is being painted.
* @param e
* How to expand tabs.
* @param startX
* The x-coordinate at which the token will be painted. This
* is needed because of tabs.
* @param endBeforeX
* The x-coordinate for which you want to find the last
* character of <code>t</code> which comes before it.
* @return The last document position that will fit in the specified amount
* of pixels.
* @param textArea The text area in which this token is being painted.
* @param e How to expand tabs.
* @param startX The x-coordinate at which the token will be painted. This
* is needed because of tabs.
* @param endBeforeX The x-coordinate for which you want to find the last
* character of <code>t</code> which comes before it.
* @return The last document position that will fit in the specified amount of
* pixels.
*/
/*
* @see #getTokenListOffsetBeforeX
* FIXME: This method does not compute correctly! It needs to be abstract
* and implemented by subclasses.
* @see #getTokenListOffsetBeforeX FIXME: This method does not compute
* correctly! It needs to be abstract and implemented by subclasses.
*/
int getOffsetBeforeX(RSyntaxTextArea textArea, TabExpander e, float startX, float endBeforeX);
/**
* Returns the character array backing the lexeme of this token. This
* value should be treated as read-only.
* Returns the character array backing the lexeme of this token. This value
* should be treated as read-only.
*
* @return A character array containing the lexeme of this token.
* @see #getTextOffset()
* @see #length()
*/
char[] getTextArray();
/**
* Returns the offset into the character array of the lexeme in
* {@link #getTextArray()}.
@@ -285,7 +257,7 @@ public interface Token extends TokenTypes {
* @see #getTextArray()
*/
int getTextOffset();
/**
* Returns the type of this token.
*
@@ -294,47 +266,39 @@ public interface Token extends TokenTypes {
* @see #setType(int)
*/
int getType();
/**
* Returns the width of this token given the specified parameters.
*
* @param textArea
* The text area in which the token is being painted.
* @param e
* Describes how to expand tabs. This parameter cannot be
* <code>null</code>.
* @param x0
* The pixel-location at which the token begins. This is needed
* because of tabs.
* @param textArea The text area in which the token is being painted.
* @param e Describes how to expand tabs. This parameter cannot be
* <code>null</code>.
* @param x0 The pixel-location at which the token begins. This is needed
* because of tabs.
* @return The width of the token, in pixels.
* @see #getWidthUpTo
*/
float getWidth(RSyntaxTextArea textArea, TabExpander e, float x0);
/**
* Returns the width of a specified number of characters in this token.
* For example, for the token "while", specifying a value of <code>3</code>
* here returns the width of the "whi" portion of the token.
* Returns the width of a specified number of characters in this token. For
* example, for the token "while", specifying a value of <code>3</code> here
* returns the width of the "whi" portion of the token.
*
* @param numChars
* The number of characters for which to get the width.
* @param textArea
* The text area in which the token is being painted.
* @param e
* How to expand tabs. This value cannot be <code>null</code>.
* @param x0
* The pixel-location at which this token begins. This is needed
* because of tabs.
* @param numChars The number of characters for which to get the width.
* @param textArea The text area in which the token is being painted.
* @param e How to expand tabs. This value cannot be <code>null</code>.
* @param x0 The pixel-location at which this token begins. This is needed
* because of tabs.
* @return The width of the specified number of characters in this token.
* @see #getWidth
*/
float getWidthUpTo(int numChars, RSyntaxTextArea textArea, TabExpander e, float x0);
/**
* Returns whether this token's lexeme matches a specific character array.
*
* @param lexeme
* The lexeme to check for.
* @param lexeme The lexeme to check for.
* @return Whether this token has that lexeme.
* @see #is(int, char[])
* @see #is(int, String)
@@ -342,19 +306,17 @@ public interface Token extends TokenTypes {
* @see #startsWith(char[])
*/
boolean is(char[] lexeme);
/**
* Returns whether this token is of the specified type, with the specified
* lexeme.
* <p>
* This method is preferred over the other overload in performance-critical
* code where this operation may be called frequently, since it does not
* involve any String allocations.
* This method is preferred over the other overload in performance-critical code
* where this operation may be called frequently, since it does not involve any
* String allocations.
*
* @param type
* The type to check for.
* @param lexeme
* The lexeme to check for.
* @param type The type to check for.
* @param lexeme The lexeme to check for.
* @return Whether this token has that type and lexeme.
* @see #is(int, String)
* @see #is(char[])
@@ -362,26 +324,24 @@ public interface Token extends TokenTypes {
* @see #startsWith(char[])
*/
boolean is(int type, char[] lexeme);
/**
* Returns whether this token is of the specified type, with the specified
* lexeme.
* <p>
* The other overload of this method is preferred over this one in
* performance-critical code, as this one involves a String allocation
* while the other does not.
* performance-critical code, as this one involves a String allocation while the
* other does not.
*
* @param type
* The type to check for.
* @param lexeme
* The lexeme to check for.
* @param type The type to check for.
* @param lexeme The lexeme to check for.
* @return Whether this token has that type and lexeme.
* @see #is(int, char[])
* @see #isSingleChar(int, char)
* @see #startsWith(char[])
*/
boolean is(int type, String lexeme);
/**
* Returns whether this token is a comment.
*
@@ -390,7 +350,7 @@ public interface Token extends TokenTypes {
* @see #isCommentOrWhitespace()
*/
boolean isComment();
/**
* Returns whether this token is a comment or whitespace.
*
@@ -399,7 +359,7 @@ public interface Token extends TokenTypes {
* @see #isWhitespace()
*/
boolean isCommentOrWhitespace();
/**
* Returns whether this token is a hyperlink.
*
@@ -407,23 +367,23 @@ public interface Token extends TokenTypes {
* @see #setHyperlink(boolean)
*/
boolean isHyperlink();
/**
* Returns whether this token is an identifier.
*
* @return Whether this token is an identifier.
*/
boolean isIdentifier();
/**
* Returns whether this token is a {@link #SEPARATOR} representing a single
* left curly brace.
* Returns whether this token is a {@link #SEPARATOR} representing a single left
* curly brace.
*
* @return Whether this token is a left curly brace.
* @see #isRightCurly()
*/
boolean isLeftCurly();
/**
* Returns whether this token is a {@link #SEPARATOR} representing a single
* right curly brace.
@@ -432,41 +392,38 @@ public interface Token extends TokenTypes {
* @see #isLeftCurly()
*/
boolean isRightCurly();
/**
* Returns whether or not this token is "paintable;" i.e., whether or not
* the type of this token is one such that it has an associated syntax
* style. What this boils down to is whether the token type is greater
* than <code>Token.NULL</code>.
* Returns whether or not this token is "paintable;" i.e., whether or not the
* type of this token is one such that it has an associated syntax style. What
* this boils down to is whether the token type is greater than
* <code>Token.NULL</code>.
*
* @return Whether or not this token is paintable.
*/
boolean isPaintable();
/**
* Returns whether this token is the specified single character.
*
* @param ch
* The character to check for.
* @param ch The character to check for.
* @return Whether this token's lexeme is the single character specified.
* @see #isSingleChar(int, char)
*/
boolean isSingleChar(char ch);
/**
* Returns whether this token is the specified single character, and of a
* specific type.
*
* @param type
* The token type.
* @param ch
* The character to check for.
* @param type The token type.
* @param ch The character to check for.
* @return Whether this token is of the specified type, and with a lexeme
* Equaling the single character specified.
* @see #isSingleChar(char)
*/
boolean isSingleChar(int type, char ch);
/**
* Returns whether or not this token is whitespace.
*
@@ -475,7 +432,7 @@ public interface Token extends TokenTypes {
* @see #isCommentOrWhitespace()
*/
boolean isWhitespace();
/**
* Returns the length of this token.
*
@@ -483,87 +440,77 @@ public interface Token extends TokenTypes {
* @see #getOffset()
*/
int length();
/**
* Returns the bounding box for the specified document location. The
* location must be in the specified token list; if it isn't,
* <code>null</code> is returned.
* Returns the bounding box for the specified document location. The location
* must be in the specified token list; if it isn't, <code>null</code> is
* returned.
*
* @param textArea
* The text area from which the token list was derived.
* @param e
* How to expand tabs.
* @param pos
* The position in the document for which to get the bounding
* box in the view.
* @param x0
* The pixel x-location that is the beginning of
* <code>tokenList</code>.
* @param rect
* The rectangle in which we'll be returning the results. This
* object is reused to keep from frequent memory allocations.
* @param textArea The text area from which the token list was derived.
* @param e How to expand tabs.
* @param pos The position in the document for which to get the bounding
* box in the view.
* @param x0 The pixel x-location that is the beginning of
* <code>tokenList</code>.
* @param rect The rectangle in which we'll be returning the results. This
* object is reused to keep from frequent memory allocations.
* @return The bounding box for the specified position in the model.
*/
Rectangle listOffsetToView(RSyntaxTextArea textArea, TabExpander e, int pos, int x0, Rectangle rect);
/**
* Sets whether this token is a hyperlink.
*
* @param hyperlink
* Whether this token is a hyperlink.
* @param hyperlink Whether this token is a hyperlink.
* @see #isHyperlink()
*/
void setHyperlink(boolean hyperlink);
/**
* Sets the language index for this token. If this value is positive, it
* denotes a specific "secondary" language this token represents (such as
* JavaScript code or CSS embedded in an HTML file). If this value is
* <code>0</code>, this token is in the "main" language being edited.
* Negative values are invalid and treated as <code>0</code>.
* Sets the language index for this token. If this value is positive, it denotes
* a specific "secondary" language this token represents (such as JavaScript
* code or CSS embedded in an HTML file). If this value is <code>0</code>, this
* token is in the "main" language being edited. Negative values are invalid and
* treated as <code>0</code>.
*
* @param languageIndex
* The new language index. A value of
* <code>0</code> denotes the "main" language, any positive value
* denotes a specific secondary language. Negative values will
* be treated as <code>0</code>.
* @param languageIndex The new language index. A value of <code>0</code>
* denotes the "main" language, any positive value denotes
* a specific secondary language. Negative values will be
* treated as <code>0</code>.
* @see #getLanguageIndex()
*/
void setLanguageIndex(int languageIndex);
/**
* Sets the type of this token.
*
* @param type
* The new token type.
* @param type The new token type.
* @see TokenTypes
* @see #getType()
*/
void setType(int type);
/**
* Returns whether this token starts with the specified characters.
*
* @param chars
* The characters.
* @param chars The characters.
* @return Whether this token starts with those characters.
* @see #endsWith(char[])
* @see #is(int, char[])
*/
boolean startsWith(char[] chars);
/**
* Returns the position in the document corresponding to the specified
* position in this token's internal char array (<code>textOffset</code> -
* Returns the position in the document corresponding to the specified position
* in this token's internal char array (<code>textOffset</code> -
* <code>textOffset+textCount-1</code>).
* <p>
* Note that this method does NOT do any bounds checking; you can pass in
* an invalid token position, and you will not receive an Exception or any
* other indication that the returned document position is invalid. It is
* up to the user to ensure valid input.
* Note that this method does NOT do any bounds checking; you can pass in an
* invalid token position, and you will not receive an Exception or any other
* indication that the returned document position is invalid. It is up to the
* user to ensure valid input.
*
* @param pos
* A position in the token's internal char array
* @param pos A position in the token's internal char array
* (<code>textOffset</code> - <code>textOffset+textCount</code>).
* @return The corresponding position in the document.
* @see #documentToToken(int)
@@ -15,52 +15,42 @@ import javax.swing.text.Segment;
* @version 0.1
*/
interface TokenFactory {
/**
* Returns a null token.
*
* @return A null token.
*/
TokenImpl createToken();
/**
* Returns a token.
*
* @param line
* The segment from which to get the token's text.
* @param beg
* The starting offset of the token's text in the segment.
* @param end
* The ending offset of the token's text in the segment.
* @param startOffset
* The offset in the document of the token.
* @param type
* The type of token.
* @param line The segment from which to get the token's text.
* @param beg The starting offset of the token's text in the segment.
* @param end The ending offset of the token's text in the segment.
* @param startOffset The offset in the document of the token.
* @param type The type of token.
* @return The token.
*/
TokenImpl createToken(final Segment line, final int beg, final int end, final int startOffset, final int type);
/**
* Returns a token.
*
* @param line
* The char array from which to get the token's text.
* @param beg
* The starting offset of the token's text in the char array.
* @param end
* The ending offset of the token's text in the char array.
* @param startOffset
* The offset in the document of the token.
* @param type
* The type of token.
* @param line The char array from which to get the token's text.
* @param beg The starting offset of the token's text in the char array.
* @param end The ending offset of the token's text in the char array.
* @param startOffset The offset in the document of the token.
* @param type The type of token.
* @return The token.
*/
TokenImpl createToken(final char[] line, final int beg, final int end, final int startOffset, final int type);
/**
* Resets the state of this token maker. This method should be called
* by the <code>TokenMaker</code> every time a token list is generated for
* a new line so the tokens can be reused.
* Resets the state of this token maker. This method should be called by the
* <code>TokenMaker</code> every time a token list is generated for a new line
* so the tokens can be reused.
*/
void resetAllTokens();
}
@@ -16,16 +16,15 @@ import java.util.Iterator;
* @version 1.0
*/
class TokenIterator implements Iterator<Token> {
private RSyntaxDocument doc;
private int curLine;
private Token token;
/**
* Constructor.
*
* @param doc
* The document whose tokens we should iterate over.
* @param doc The document whose tokens we should iterate over.
*/
TokenIterator(RSyntaxDocument doc) {
this.doc = doc;
@@ -36,11 +35,11 @@ class TokenIterator implements Iterator<Token> {
loadTokenListForCurLine();
}
}
private int getLineCount() {
return doc.getDefaultRootElement().getElementCount();
}
/**
* Returns whether any more paintable tokens are in the document.
*
@@ -51,7 +50,7 @@ class TokenIterator implements Iterator<Token> {
public boolean hasNext() {
return token != null;
}
private void loadTokenListForCurLine() {
token = doc.getTokenListForLine(curLine);
if (token != null && !token.isPaintable()) {
@@ -59,7 +58,7 @@ class TokenIterator implements Iterator<Token> {
token = null;
}
}
/**
* Returns the next paintable token in the document.
*
@@ -96,13 +95,12 @@ class TokenIterator implements Iterator<Token> {
}
return t;
}
/**
* Always throws {@link UnsupportedOperationException}, as
* <code>Token</code> removal is not supported.
* Always throws {@link UnsupportedOperationException}, as <code>Token</code>
* removal is not supported.
*
* @throws UnsupportedOperationException
* always.
* @throws UnsupportedOperationException always.
*/
@Override
public void remove() {
+84 -106
View File
@@ -12,8 +12,8 @@ import javax.swing.text.Segment;
/**
* An implementation of <code>TokenMaker</code> is a class that turns text into
* a linked list of <code>Token</code>s for syntax highlighting
* in a particular language.
* a linked list of <code>Token</code>s for syntax highlighting in a particular
* language.
*
* @see Token
* @see AbstractTokenMaker
@@ -22,164 +22,142 @@ import javax.swing.text.Segment;
* @version 0.2
*/
public interface TokenMaker {
/**
* Adds a null token to the end of the current linked list of tokens.
* This should be put at the end of the linked list whenever the last
* token on the current line is NOT a multi-line token.
* Adds a null token to the end of the current linked list of tokens. This
* should be put at the end of the linked list whenever the last token on the
* current line is NOT a multi-line token.
*/
public void addNullToken();
/**
* Adds the token specified to the current linked list of tokens.
*
* @param array
* The character array from which to get the text.
* @param start
* Start offset in <code>segment</code> of token.
* @param end
* End offset in <code>segment</code> of token.
* @param tokenType
* The token's type.
* @param startOffset
* The offset in the document at which this token
* occurs.
* @param array The character array from which to get the text.
* @param start Start offset in <code>segment</code> of token.
* @param end End offset in <code>segment</code> of token.
* @param tokenType The token's type.
* @param startOffset The offset in the document at which this token occurs.
*/
public void addToken(char[] array, int start, int end, int tokenType, int startOffset);
/**
* Returns the closest {@link TokenTypes "standard" token type} for a given
* "internal" token type (e.g. one whose value is <code>&lt; 0</code>).
*
* @param type
* The token type.
* @return The closest "standard" token type. If a mapping is not defined
* for this language, then <code>type</code> is returned.
* @param type The token type.
* @return The closest "standard" token type. If a mapping is not defined for
* this language, then <code>type</code> is returned.
*/
public int getClosestStandardTokenTypeForInternalType(int type);
/**
* Returns whether this programming language uses curly braces
* ('<code>{</code>' and '<code>}</code>') to denote code blocks.
* Returns whether this programming language uses curly braces ('<code>{</code>'
* and '<code>}</code>') to denote code blocks.
*
* @param languageIndex
* The language index at the offset in question.
* Since some <code>TokenMaker</code>s effectively have nested
* languages (such as JavaScript in HTML), this parameter tells
* the
* <code>TokenMaker</code> what sub-language to look at.
* @param languageIndex The language index at the offset in question. Since some
* <code>TokenMaker</code>s effectively have nested
* languages (such as JavaScript in HTML), this parameter
* tells the <code>TokenMaker</code> what sub-language to
* look at.
* @return Whether curly braces denote code blocks.
*/
public boolean getCurlyBracesDenoteCodeBlocks(int languageIndex);
/**
* Returns the last token on this line's type if the token is "unfinished",
* or {@link Token#NULL} if it was finished. For example, if C-style
* syntax highlighting is being implemented, and <code>text</code>
* contained a line of code that contained the beginning of a comment but
* no end-comment marker ("*\/"), then this method would return
* {@link Token#COMMENT_MULTILINE} for that line. This is useful
* for doing syntax highlighting.
* Returns the last token on this line's type if the token is "unfinished", or
* {@link Token#NULL} if it was finished. For example, if C-style syntax
* highlighting is being implemented, and <code>text</code> contained a line of
* code that contained the beginning of a comment but no end-comment marker
* ("*\/"), then this method would return {@link Token#COMMENT_MULTILINE} for
* that line. This is useful for doing syntax highlighting.
*
* @param text
* The line of tokens to examine.
* @param initialTokenType
* The token type to start with (i.e., the value
* of <code>getLastTokenTypeOnLine</code> for the line before
* <code>text</code>).
* @return The last token on this line's type, or {@link Token#NULL}
* if the line was completed.
* @param text The line of tokens to examine.
* @param initialTokenType The token type to start with (i.e., the value of
* <code>getLastTokenTypeOnLine</code> for the line
* before <code>text</code>).
* @return The last token on this line's type, or {@link Token#NULL} if the line
* was completed.
*/
public int getLastTokenTypeOnLine(Segment text, int initialTokenType);
/**
* Returns the text to place at the beginning and end of a
* line to "comment" it in this programming language.
* Returns the text to place at the beginning and end of a line to "comment" it
* in this programming language.
*
* @param languageIndex
* The language index at the offset in question.
* Since some <code>TokenMaker</code>s effectively have nested
* languages (such as JavaScript in HTML), this parameter tells
* the
* <code>TokenMaker</code> what sub-language to look at.
* @return The start and end strings to add to a line to "comment"
* it out. A <code>null</code> value for either means there
* is no string to add for that part. A value of
* <code>null</code> for the array means this language
* does not support commenting/uncommenting lines.
* @param languageIndex The language index at the offset in question. Since some
* <code>TokenMaker</code>s effectively have nested
* languages (such as JavaScript in HTML), this parameter
* tells the <code>TokenMaker</code> what sub-language to
* look at.
* @return The start and end strings to add to a line to "comment" it out. A
* <code>null</code> value for either means there is no string to add
* for that part. A value of <code>null</code> for the array means this
* language does not support commenting/uncommenting lines.
*/
public String[] getLineCommentStartAndEnd(int languageIndex);
/**
* Returns an action to handle "insert break" key presses (i.e. Enter).
*
* @return The action, or <code>null</code> if the default action should
* be used.
* @return The action, or <code>null</code> if the default action should be
* used.
*/
public Action getInsertBreakAction();
/**
* Returns whether tokens of the specified type should have "mark
* occurrences" enabled for the current programming language.
* Returns whether tokens of the specified type should have "mark occurrences"
* enabled for the current programming language.
*
* @param type
* The token type.
* @return Whether tokens of this type should have "mark occurrences"
* enabled.
* @param type The token type.
* @return Whether tokens of this type should have "mark occurrences" enabled.
*/
public boolean getMarkOccurrencesOfTokenType(int type);
/**
* Returns the object in charge of marking all occurrences of the token
* at the current caret position, if it is a relevant token. If
* <code>null</code> is returned, a default <code>OccurrenceMarker</code>
* is used.
* Returns the object in charge of marking all occurrences of the token at the
* current caret position, if it is a relevant token. If <code>null</code> is
* returned, a default <code>OccurrenceMarker</code> is used.
*
* @return The occurrence marker for this language, or <code>null</code>
* for none.
* @return The occurrence marker for this language, or <code>null</code> for
* none.
*/
public OccurrenceMarker getOccurrenceMarker();
/**
* If a line ends in the specified token, this method returns whether
* a new line inserted after that line should be indented.
* If a line ends in the specified token, this method returns whether a new line
* inserted after that line should be indented.
*
* @param token
* The token the previous line ends with.
* @param token The token the previous line ends with.
* @return Whether the next line should be indented.
*/
public boolean getShouldIndentNextLineAfter(Token token);
/**
* Returns the first token in the linked list of tokens generated
* from <code>text</code>. This method must be implemented by
* subclasses so they can correctly implement syntax highlighting.
* Returns the first token in the linked list of tokens generated from
* <code>text</code>. This method must be implemented by subclasses so they can
* correctly implement syntax highlighting.
*
* @param text
* The text from which to get tokens.
* @param initialTokenType
* The token type we should start with.
* @param startOffset
* The offset into the document at which
* <code>text</code> starts.
* @return The first <code>Token</code> in a linked list representing
* the syntax highlighted text.
* @param text The text from which to get tokens.
* @param initialTokenType The token type we should start with.
* @param startOffset The offset into the document at which
* <code>text</code> starts.
* @return The first <code>Token</code> in a linked list representing the syntax
* highlighted text.
*/
public Token getTokenList(Segment text, int initialTokenType, int startOffset);
/**
* Returns whether a character could be part of an "identifier" token
* in a specific language. This is used to identify such things as the
* bounds of the "word" to select on double-clicking.
* Returns whether a character could be part of an "identifier" token in a
* specific language. This is used to identify such things as the bounds of the
* "word" to select on double-clicking.
*
* @param languageIndex
* The language index the character was found in.
* @param ch
* The character.
* @param languageIndex The language index the character was found in.
* @param ch The character.
* @return Whether the character could be part of an "identifier" token.
*/
public boolean isIdentifierChar(int languageIndex, char ch);
/**
* Returns whether this language is a markup language.
*
@@ -16,7 +16,7 @@ import javax.swing.text.Segment;
* @version 1.0
*/
public abstract class TokenMakerBase implements TokenMaker {
/**
* The first token in the returned linked list.
*/
@@ -34,20 +34,18 @@ public abstract class TokenMakerBase implements TokenMaker {
*/
private TokenFactory tokenFactory;
/**
* Highlights occurrences of the current token in the editor, if it is
* relevant.
* Highlights occurrences of the current token in the editor, if it is relevant.
*/
private OccurrenceMarker occurrenceMarker;
/**
* "0" implies this is the "main" language being highlighted. Positive
* values imply various "secondary" or "embedded" languages, such as CSS
* or JavaScript in HTML. While this value is non-zero, tokens will be
* generated with this language index so they can (possibly) be painted
* differently, so "embedded" languages can be rendered with a special
* background.
* "0" implies this is the "main" language being highlighted. Positive values
* imply various "secondary" or "embedded" languages, such as CSS or JavaScript
* in HTML. While this value is non-zero, tokens will be generated with this
* language index so they can (possibly) be painted differently, so "embedded"
* languages can be rendered with a special background.
*/
private int languageIndex;
/**
* Constructor.
*/
@@ -55,7 +53,7 @@ public abstract class TokenMakerBase implements TokenMaker {
firstToken = currentToken = previousToken = null;
tokenFactory = new DefaultTokenFactory();
}
/**
* {@inheritDoc}
*/
@@ -72,26 +70,20 @@ public abstract class TokenMakerBase implements TokenMaker {
}
currentToken.setLanguageIndex(languageIndex);
}
/**
* Adds the token specified to the current linked list of tokens.
*
* @param segment
* <code>Segment</code> to get text from.
* @param start
* Start offset in <code>segment</code> of token.
* @param end
* End offset in <code>segment</code> of token.
* @param tokenType
* The token's type.
* @param startOffset
* The offset in the document at which this token
* occurs.
* @param segment <code>Segment</code> to get text from.
* @param start Start offset in <code>segment</code> of token.
* @param end End offset in <code>segment</code> of token.
* @param tokenType The token's type.
* @param startOffset The offset in the document at which this token occurs.
*/
public void addToken(Segment segment, int start, int end, int tokenType, int startOffset) {
addToken(segment.array, start, end, tokenType, startOffset);
}
/**
* {@inheritDoc}
*/
@@ -99,23 +91,16 @@ public abstract class TokenMakerBase implements TokenMaker {
public void addToken(char[] array, int start, int end, int tokenType, int startOffset) {
addToken(array, start, end, tokenType, startOffset, false);
}
/**
* Adds the token specified to the current linked list of tokens.
*
* @param array
* The character array.
* @param start
* The starting offset in the array.
* @param end
* The ending offset in the array.
* @param tokenType
* The token's type.
* @param startOffset
* The offset in the document at which this token
* occurs.
* @param hyperlink
* Whether this token is a hyperlink.
* @param array The character array.
* @param start The starting offset in the array.
* @param end The ending offset in the array.
* @param tokenType The token's type.
* @param startOffset The offset in the document at which this token occurs.
* @param hyperlink Whether this token is a hyperlink.
*/
public void addToken(char[] array, int start, int end, int tokenType, int startOffset, boolean hyperlink) {
if (firstToken == null) {
@@ -130,59 +115,56 @@ public abstract class TokenMakerBase implements TokenMaker {
currentToken.setLanguageIndex(languageIndex);
currentToken.setHyperlink(hyperlink);
}
/**
* Returns the occurrence marker to use for this token maker. Subclasses
* can override to use different implementations.
* Returns the occurrence marker to use for this token maker. Subclasses can
* override to use different implementations.
*
* @return The occurrence marker to use.
*/
protected OccurrenceMarker createOccurrenceMarker() {
return new DefaultOccurrenceMarker();
}
/**
* Returns the closest {@link TokenTypes "standard" token type} for a given
* "internal" token type (e.g. one whose value is <code>&lt; 0</code>).
* <p>
*
* The default implementation returns <code>type</code> always, which
* denotes that a mapping from internal token types to standard token types
* is not defined; subclasses can override.
* The default implementation returns <code>type</code> always, which denotes
* that a mapping from internal token types to standard token types is not
* defined; subclasses can override.
*
* @param type
* The token type.
* @param type The token type.
* @return The closest "standard" token type.
*/
@Override
public int getClosestStandardTokenTypeForInternalType(int type) {
return type;
}
/**
* Returns whether this programming language uses curly braces
* ('<code>{</code>' and '<code>}</code>') to denote code blocks.
* Returns whether this programming language uses curly braces ('<code>{</code>'
* and '<code>}</code>') to denote code blocks.
*
* The default implementation returns <code>false</code>; subclasses can
* override this method if necessary.
*
* @param languageIndex
* The language index at the offset in question.
* Since some <code>TokenMaker</code>s effectively have nested
* languages (such as JavaScript in HTML), this parameter tells
* the
* <code>TokenMaker</code> what sub-language to look at.
* @param languageIndex The language index at the offset in question. Since some
* <code>TokenMaker</code>s effectively have nested
* languages (such as JavaScript in HTML), this parameter
* tells the <code>TokenMaker</code> what sub-language to
* look at.
* @return Whether curly braces denote code blocks.
*/
@Override
public boolean getCurlyBracesDenoteCodeBlocks(int languageIndex) {
return false;
}
/**
* Returns an action to handle "insert break" key presses (i.e. Enter).
* The default implementation returns <code>null</code>. Subclasses
* can override.
* Returns an action to handle "insert break" key presses (i.e. Enter). The
* default implementation returns <code>null</code>. Subclasses can override.
*
* @return The default implementation always returns <code>null</code>.
*/
@@ -190,7 +172,7 @@ public abstract class TokenMakerBase implements TokenMaker {
public Action getInsertBreakAction() {
return null;
}
/**
* Returns the current language index.
*
@@ -200,7 +182,7 @@ public abstract class TokenMakerBase implements TokenMaker {
protected int getLanguageIndex() {
return languageIndex;
}
/**
* {@inheritDoc}
*/
@@ -213,7 +195,7 @@ public abstract class TokenMakerBase implements TokenMaker {
}
return t.getType();
}
/**
* {@inheritDoc}
*/
@@ -221,24 +203,22 @@ public abstract class TokenMakerBase implements TokenMaker {
public String[] getLineCommentStartAndEnd(int languageIndex) {
return null;
}
/**
* Returns whether tokens of the specified type should have "mark
* occurrences" enabled for the current programming language. The default
* implementation returns true if <tt>type</tt> is {@link Token#IDENTIFIER}.
* Subclasses can override this method to support other token types, such
* as {@link Token#VARIABLE}.
* Returns whether tokens of the specified type should have "mark occurrences"
* enabled for the current programming language. The default implementation
* returns true if <tt>type</tt> is {@link Token#IDENTIFIER}. Subclasses can
* override this method to support other token types, such as
* {@link Token#VARIABLE}.
*
* @param type
* The token type.
* @return Whether tokens of this type should have "mark occurrences"
* enabled.
* @param type The token type.
* @return Whether tokens of this type should have "mark occurrences" enabled.
*/
@Override
public boolean getMarkOccurrencesOfTokenType(int type) {
return type == Token.IDENTIFIER;
}
/**
* {@inheritDoc}
*/
@@ -249,34 +229,33 @@ public abstract class TokenMakerBase implements TokenMaker {
}
return occurrenceMarker;
}
/**
* The default implementation returns <code>false</code> always. Languages
* that wish to better support auto-indentation can override this method.
* The default implementation returns <code>false</code> always. Languages that
* wish to better support auto-indentation can override this method.
*
* @param token
* The token the previous line ends with.
* @param token The token the previous line ends with.
* @return Whether the next line should be indented.
*/
@Override
public boolean getShouldIndentNextLineAfter(Token token) {
return false;
}
/**
* Returns whether a character could be part of an "identifier" token
* in a specific language. The default implementation returns
* <code>true</code> for letters, numbers, and certain symbols.
* Returns whether a character could be part of an "identifier" token in a
* specific language. The default implementation returns <code>true</code> for
* letters, numbers, and certain symbols.
*/
@Override
public boolean isIdentifierChar(int languageIndex, char ch) {
return Character.isLetterOrDigit(ch) || ch == '_' || ch == '$';
}
/**
* The default implementation returns <code>false</code> always.
* Subclasses that are highlighting a markup language should override this
* method to return <code>true</code>.
* The default implementation returns <code>false</code> always. Subclasses that
* are highlighting a markup language should override this method to return
* <code>true</code>.
*
* @return <code>false</code> always.
*/
@@ -284,29 +263,27 @@ public abstract class TokenMakerBase implements TokenMaker {
public boolean isMarkupLanguage() {
return false;
}
/**
* Deletes the linked list of tokens so we can begin anew. This should
* never have to be called by the programmer, as it is automatically
* called whenever the user calls
* {@link #getLastTokenTypeOnLine(Segment, int)} or
* Deletes the linked list of tokens so we can begin anew. This should never
* have to be called by the programmer, as it is automatically called whenever
* the user calls {@link #getLastTokenTypeOnLine(Segment, int)} or
* {@link #getTokenList(Segment, int, int)}.
*/
protected void resetTokenList() {
firstToken = currentToken = previousToken = null;
tokenFactory.resetAllTokens();
}
/**
* Sets the language index to assign to tokens moving forward. This
* property is used to designate tokens as being in "secondary" languages
* (such as CSS or JavaScript in HTML).
* Sets the language index to assign to tokens moving forward. This property is
* used to designate tokens as being in "secondary" languages (such as CSS or
* JavaScript in HTML).
*
* @param languageIndex
* The new language index. A value of
* <code>0</code> denotes the "main" language, any positive value
* denotes a specific secondary language. Negative values will
* be treated as <code>0</code>.
* @param languageIndex The new language index. A value of <code>0</code>
* denotes the "main" language, any positive value denotes
* a specific secondary language. Negative values will be
* treated as <code>0</code>.
* @see #getLanguageIndex()
*/
protected void setLanguageIndex(int languageIndex) {
@@ -18,10 +18,9 @@ import org.fife.ui.rsyntaxtextarea.modes.PlainTextTokenMaker;
* @version 1.0
*/
public abstract class TokenMakerFactory {
/**
* If this system property is set, a custom <code>TokenMakerFactory</code>
* of
* If this system property is set, a custom <code>TokenMakerFactory</code> of
* the specified class will be used as the default token maker factory.
*/
public static final String PROPERTY_DEFAULT_TOKEN_MAKER_FACTORY = "TokenMakerFactory";
@@ -29,7 +28,7 @@ public abstract class TokenMakerFactory {
* The singleton default <code>TokenMakerFactory</code> instance.
*/
private static TokenMakerFactory DEFAULT_INSTANCE;
/**
* Returns the default <code>TokenMakerFactory</code> instance. This is the
* factory used by all {@link RSyntaxDocument}s by default.
@@ -59,12 +58,11 @@ public abstract class TokenMakerFactory {
}
return DEFAULT_INSTANCE;
}
/**
* Returns a {@link TokenMaker} for the specified key.
*
* @param key
* The key.
* @param key The key.
* @return The corresponding <code>TokenMaker</code>, or
* {@link PlainTextTokenMaker} if none matches the specified key.
*/
@@ -75,36 +73,31 @@ public abstract class TokenMakerFactory {
}
return tm;
}
/**
* Returns a {@link TokenMaker} for the specified key.
*
* @param key
* The key.
* @return The corresponding <code>TokenMaker</code>, or <code>null</code>
* if
* @param key The key.
* @return The corresponding <code>TokenMaker</code>, or <code>null</code> if
* none matches the specified key.
*/
protected abstract TokenMaker getTokenMakerImpl(String key);
/**
* Returns the set of keys that this factory maps to token makers.
*
* @return The set of keys.
*/
public abstract Set<String> keySet();
/**
* Sets the default <code>TokenMakerFactory</code> instance. This is the
* factory
* Sets the default <code>TokenMakerFactory</code> instance. This is the factory
* used by all future {@link RSyntaxDocument}s by default.
* <code>RSyntaxDocument</code>s that have already been created are not
* affected.
*
* @param tmf
* The factory.
* @throws IllegalArgumentException
* If <code>tmf</code> is <code>null</code>.
* @param tmf The factory.
* @throws IllegalArgumentException If <code>tmf</code> is <code>null</code>.
* @see #getDefaultInstance()
*/
public static synchronized void setDefaultInstance(TokenMakerFactory tmf) {
+65 -85
View File
@@ -10,8 +10,8 @@ package org.fife.ui.rsyntaxtextarea;
import javax.swing.text.Segment;
/**
* A hash table for reserved words, etc. defined by a {@link TokenMaker}.
* This class is designed for the quick lookup of tokens, as it can compare
* A hash table for reserved words, etc. defined by a {@link TokenMaker}. This
* class is designed for the quick lookup of tokens, as it can compare
* <code>Segment</code>s without the need to allocate a new string.
* <p>
*
@@ -27,98 +27,86 @@ import javax.swing.text.Segment;
* @version 0.6
*/
public class TokenMap {
private int size;
private TokenMapToken[] tokenMap;
private boolean ignoreCase;
private static final int DEFAULT_TOKEN_MAP_SIZE = 52;
/**
* Constructs a new token map that is case-sensitive.
*/
public TokenMap() {
this(DEFAULT_TOKEN_MAP_SIZE);
}
/**
* Constructs a new token map that is case-sensitive.
*
* @param size
* The size of the token map.
* @param size The size of the token map.
*/
public TokenMap(int size) {
this(size, false);
}
/**
* Constructs a new token map.
*
* @param ignoreCase
* Whether or not this token map should ignore case
* when comparing tokens.
* @param ignoreCase Whether or not this token map should ignore case when
* comparing tokens.
*/
public TokenMap(boolean ignoreCase) {
this(DEFAULT_TOKEN_MAP_SIZE, ignoreCase);
}
/**
* Constructs a new token map.
*
* @param size
* The size of the token map.
* @param ignoreCase
* Whether or not this token map should ignore case
* when comparing tokens.
* @param size The size of the token map.
* @param ignoreCase Whether or not this token map should ignore case when
* comparing tokens.
*/
public TokenMap(int size, boolean ignoreCase) {
this.size = size;
tokenMap = new TokenMapToken[size];
this.ignoreCase = ignoreCase;
}
/**
* Adds a token to a specified bucket in the token map.
*
* @param bucket
* The bucket in which to add the token.
* @param token
* The token to add.
* @param bucket The bucket in which to add the token.
* @param token The token to add.
*/
private void addTokenToBucket(int bucket, TokenMapToken token) {
TokenMapToken old = tokenMap[bucket];
token.nextToken = old;
tokenMap[bucket] = token;
}
/**
* Returns the token type associated with the given text, if the given
* text is in this token map. If it isn't, <code>-1</code> is returned.
* Returns the token type associated with the given text, if the given text is
* in this token map. If it isn't, <code>-1</code> is returned.
*
* @param text
* The segment from which to get the text to compare.
* @param start
* The starting index in the segment of the text.
* @param end
* The ending index in the segment of the text.
* @return The token type associated with the given text, or
* <code>-1</code> if this token was not specified in this map.
* @param text The segment from which to get the text to compare.
* @param start The starting index in the segment of the text.
* @param end The ending index in the segment of the text.
* @return The token type associated with the given text, or <code>-1</code> if
* this token was not specified in this map.
*/
public int get(Segment text, int start, int end) {
return get(text.array, start, end);
}
/**
* Returns the token type associated with the given text, if the given
* text is in this token map. If it isn't, <code>-1</code> is returned.
* Returns the token type associated with the given text, if the given text is
* in this token map. If it isn't, <code>-1</code> is returned.
*
* @param array1
* An array of characters containing the text.
* @param start
* The starting index in the array of the text.
* @param end
* The ending index in the array of the text.
* @return The token type associated with the given text, or
* <code>-1</code> if this token was not specified in this map.
* @param array1 An array of characters containing the text.
* @param start The starting index in the array of the text.
* @param end The ending index in the array of the text.
* @return The token type associated with the given text, or <code>-1</code> if
* this token was not specified in this map.
*/
public int get(char[] array1, int start, int end) {
int length1 = end - start + 1;
@@ -129,14 +117,13 @@ public class TokenMap {
int offset1;
int length;
/*
* We check whether or not to ignore case before doing any looping to
* minimize the number of extraneous comparisons we do. This makes
* for slightly redundant code, but it'll be a little more efficient.
* We check whether or not to ignore case before doing any looping to minimize
* the number of extraneous comparisons we do. This makes for slightly redundant
* code, but it'll be a little more efficient.
*/
// If matches are case-sensitive (C, C++, Java, etc.)...
if (!ignoreCase) {
mainLoop:
while (token != null) {
mainLoop: while (token != null) {
if (token.length == length1) {
array2 = token.text;
offset2 = token.offset;
@@ -157,8 +144,7 @@ public class TokenMap {
// Note that all tokens saved in this map were converted to
// lower-case already.
else {
mainLoop2:
while (token != null) {
mainLoop2: while (token != null) {
if (token.length == length1) {
array2 = token.text;
offset2 = token.offset;
@@ -178,40 +164,36 @@ public class TokenMap {
// Didn't match any of the tokens in the bucket.
return -1;
}
/**
* Returns the hash code for a given string.
*
* @param text
* The text to hash.
* @param offset
* The offset into the text at which to start hashing.
* @param length
* The last character in the text to hash.
* @param text The text to hash.
* @param offset The offset into the text at which to start hashing.
* @param length The last character in the text to hash.
* @return The hash code.
*/
private int getHashCode(char[] text, int offset, int length) {
return (RSyntaxUtilities.toLowerCase(text[offset]) + RSyntaxUtilities.toLowerCase(text[offset + length - 1])) % size;
return (RSyntaxUtilities.toLowerCase(text[offset]) + RSyntaxUtilities.toLowerCase(text[offset + length - 1]))
% size;
}
/**
* Returns whether this token map ignores case when checking for tokens.
* This property is set in the constructor and cannot be changed, as this
* is an intrinsic property of a particular programming language.
* Returns whether this token map ignores case when checking for tokens. This
* property is set in the constructor and cannot be changed, as this is an
* intrinsic property of a particular programming language.
*
* @return Whether or not this token maker is ignoring case.
*/
protected boolean isIgnoringCase() {
return ignoreCase;
}
/**
* Adds a string to this token map.
*
* @param string
* The string to add.
* @param tokenType
* The type of token the string is.
* @param string The string to add.
* @param tokenType The type of token the string is.
*/
public void put(final String string, final int tokenType) {
if (isIgnoringCase()) {
@@ -220,44 +202,42 @@ public class TokenMap {
put(string.toCharArray(), tokenType);
}
}
/**
* Adds a string to this token map. The char array passed-in will be used
* as the actual data for the token, so it may well be modified (such as
* lower-casing it if <code>ignoreCase</code> is <code>true</code>). This
* shouldn't be an issue though as this method is only called from the
* public <code>put</code> method, which allocates a new char array.
* Adds a string to this token map. The char array passed-in will be used as the
* actual data for the token, so it may well be modified (such as lower-casing
* it if <code>ignoreCase</code> is <code>true</code>). This shouldn't be an
* issue though as this method is only called from the public <code>put</code>
* method, which allocates a new char array.
*
* @param string
* The string to add.
* @param tokenType
* The type of token the string is.
* @param string The string to add.
* @param tokenType The type of token the string is.
*/
private void put(char[] string, int tokenType) {
int hashCode = getHashCode(string, 0, string.length);
addTokenToBucket(hashCode, new TokenMapToken(string, tokenType));
}
/**
* The "token" used by a token map. Note that this isn't the same thing
* as the {@link Token} class, but it's basically a 1-1 correspondence
* for reserved words, etc.
* The "token" used by a token map. Note that this isn't the same thing as the
* {@link Token} class, but it's basically a 1-1 correspondence for reserved
* words, etc.
*/
private static final class TokenMapToken {
private char[] text;
private int offset;
private int length;
private int tokenType;
private TokenMapToken nextToken;
private TokenMapToken(char[] text, int tokenType) {
this.text = text;
this.offset = 0;
this.length = text.length;
this.tokenType = tokenType;
}
@Override
public String toString() {
return "[TokenMapToken: " + new String(text, offset, length) + "]";
@@ -22,36 +22,32 @@ package org.fife.ui.rsyntaxtextarea;
* @version 0.1
*/
public interface TokenOrientedView {
/**
* Returns a token list for the <i>physical</i> line above the physical
* line containing the specified offset into the document. Note that for
* a plain (non-wrapped) view, this is simply the token list for the
* logical line above the line containing <code>offset</code>, since lines
* are not wrapped. For a wrapped view, this may or may not be tokens from
* the same line.
* Returns a token list for the <i>physical</i> line above the physical line
* containing the specified offset into the document. Note that for a plain
* (non-wrapped) view, this is simply the token list for the logical line above
* the line containing <code>offset</code>, since lines are not wrapped. For a
* wrapped view, this may or may not be tokens from the same line.
*
* @param offset
* The offset in question.
* @return A token list for the physical (and in this view, logical) line
* before this one. If no physical line is above the one
* containing <code>offset</code>, <code>null</code> is returned.
* @param offset The offset in question.
* @return A token list for the physical (and in this view, logical) line before
* this one. If no physical line is above the one containing
* <code>offset</code>, <code>null</code> is returned.
*/
Token getTokenListForPhysicalLineAbove(int offset);
/**
* Returns a token list for the <i>physical</i> line below the physical
* line containing the specified offset into the document. Note that for
* a plain (non-wrapped) view, this is simply the token list for the
* logical line below the line containing <code>offset</code>, since lines
* are not wrapped. For a wrapped view, this may or may not be tokens from
* the same line.
* Returns a token list for the <i>physical</i> line below the physical line
* containing the specified offset into the document. Note that for a plain
* (non-wrapped) view, this is simply the token list for the logical line below
* the line containing <code>offset</code>, since lines are not wrapped. For a
* wrapped view, this may or may not be tokens from the same line.
*
* @param offset
* The offset in question.
* @return A token list for the physical (and in this view, logical) line
* after this one. If no physical line is after the one
* containing <code>offset</code>, <code>null</code> is returned.
* @param offset The offset in question.
* @return A token list for the physical (and in this view, logical) line after
* this one. If no physical line is after the one containing
* <code>offset</code>, <code>null</code> is returned.
*/
Token getTokenListForPhysicalLineBelow(int offset);
}
@@ -11,129 +11,99 @@ import java.awt.Graphics2D;
import javax.swing.text.TabExpander;
/**
* Renders tokens in an instance of {@link RSyntaxTextArea}. One instance
* may render tokens "regularly," another may render visible whitespace, for
* Renders tokens in an instance of {@link RSyntaxTextArea}. One instance may
* render tokens "regularly," another may render visible whitespace, for
* example.
*
* @author Robert Futrell
* @version 1.0
*/
interface TokenPainter {
/**
* Paints this token.
*
* @param token
* The token to render.
* @param g
* The graphics context in which to paint.
* @param x
* The x-coordinate at which to paint.
* @param y
* The y-coordinate at which to paint.
* @param host
* The text area this token is in.
* @param e
* How to expand tabs.
* @param token The token to render.
* @param g The graphics context in which to paint.
* @param x The x-coordinate at which to paint.
* @param y The y-coordinate at which to paint.
* @param host The text area this token is in.
* @param e How to expand tabs.
* @return The x-coordinate representing the end of the painted text.
*/
float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e);
/**
* Paints this token.
*
* @param token
* The token to render.
* @param g
* The graphics context in which to paint.
* @param x
* The x-coordinate at which to paint.
* @param y
* The y-coordinate at which to paint.
* @param host
* The text area this token is in.
* @param e
* How to expand tabs.
* @param clipStart
* The left boundary of the clip rectangle in which we're
* painting. This optimizes painting by allowing us to not paint
* paint when this token is "to the left" of the clip rectangle.
* @param token The token to render.
* @param g The graphics context in which to paint.
* @param x The x-coordinate at which to paint.
* @param y The y-coordinate at which to paint.
* @param host The text area this token is in.
* @param e How to expand tabs.
* @param clipStart The left boundary of the clip rectangle in which we're
* painting. This optimizes painting by allowing us to not
* paint paint when this token is "to the left" of the clip
* rectangle.
* @return The x-coordinate representing the end of the painted text.
*/
float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart);
/**
* Paints this token.
*
* @param token
* The token to render.
* @param g
* The graphics context in which to paint.
* @param x
* The x-coordinate at which to paint.
* @param y
* The y-coordinate at which to paint.
* @param host
* The text area this token is in.
* @param e
* How to expand tabs.
* @param clipStart
* The left boundary of the clip rectangle in which we're
* painting. This optimizes painting by allowing us to not paint
* paint when this token is "to the left" of the clip rectangle.
* @param paintBG
* Whether to paint the background.
* @param token The token to render.
* @param g The graphics context in which to paint.
* @param x The x-coordinate at which to paint.
* @param y The y-coordinate at which to paint.
* @param host The text area this token is in.
* @param e How to expand tabs.
* @param clipStart The left boundary of the clip rectangle in which we're
* painting. This optimizes painting by allowing us to not
* paint paint when this token is "to the left" of the clip
* rectangle.
* @param paintBG Whether to paint the background.
* @return The x-coordinate representing the end of the painted text.
*/
float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart, boolean paintBG);
float paint(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart,
boolean paintBG);
/**
* Paints this token as it should appear in a selected region of text
* (assuming painting with a selection-foreground color is enabled in the
* parent <code>RSyntaxTextArea</code>).
* Paints this token as it should appear in a selected region of text (assuming
* painting with a selection-foreground color is enabled in the parent
* <code>RSyntaxTextArea</code>).
*
* @param token
* The token to render.
* @param g
* The graphics context in which to paint.
* @param x
* The x-coordinate at which to paint.
* @param y
* The y-coordinate at which to paint.
* @param host
* The text area this token is in.
* @param e
* How to expand tabs.
* @param useSTC
* Whether to use the text area's "selected text color."
* @param token The token to render.
* @param g The graphics context in which to paint.
* @param x The x-coordinate at which to paint.
* @param y The y-coordinate at which to paint.
* @param host The text area this token is in.
* @param e How to expand tabs.
* @param useSTC Whether to use the text area's "selected text color."
* @return The x-coordinate representing the end of the painted text.
*/
float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, boolean useSTC);
float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
boolean useSTC);
/**
* Paints this token as it should appear in a selected region of text
* (assuming painting with a selection-foreground color is enabled in the
* parent <code>RSyntaxTextArea</code>).
* Paints this token as it should appear in a selected region of text (assuming
* painting with a selection-foreground color is enabled in the parent
* <code>RSyntaxTextArea</code>).
*
* @param token
* The token to render.
* @param g
* The graphics context in which to paint.
* @param x
* The x-coordinate at which to paint.
* @param y
* The y-coordinate at which to paint.
* @param host
* The text area this token is in.
* @param e
* How to expand tabs.
* @param clipStart
* The left boundary of the clip rectangle in which we're
* painting. This optimizes painting by allowing us to not paint
* paint when this token is "to the left" of the clip rectangle.
* @param useSTC
* Whether to use the text area's "selected text color."
* @param token The token to render.
* @param g The graphics context in which to paint.
* @param x The x-coordinate at which to paint.
* @param y The y-coordinate at which to paint.
* @param host The text area this token is in.
* @param e How to expand tabs.
* @param clipStart The left boundary of the clip rectangle in which we're
* painting. This optimizes painting by allowing us to not
* paint paint when this token is "to the left" of the clip
* rectangle.
* @param useSTC Whether to use the text area's "selected text color."
* @return The x-coordinate representing the end of the painted text.
*/
float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart, boolean useSTC);
float paintSelected(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
float clipStart, boolean useSTC);
}
@@ -11,17 +11,17 @@ package org.fife.ui.rsyntaxtextarea;
* <p>
*
* Note that all valid token types are &gt;= 0, so extensions of the TokenMaker
* class are free to internally use all ints &lt; 0 ONLY for "end-of-line"
* style markers; they are ignored by painting implementations.
* class are free to internally use all ints &lt; 0 ONLY for "end-of-line" style
* markers; they are ignored by painting implementations.
*
* @author Robert Futrell
* @version 1.0
*/
public interface TokenTypes {
/**
* Tokens of type <code>NULL</code> mark the end of lines with no
* multi-line token at the end (such as a block comment in C++).
* Tokens of type <code>NULL</code> mark the end of lines with no multi-line
* token at the end (such as a block comment in C++).
*/
int NULL = 0;
int COMMENT_EOL = 1;
@@ -18,7 +18,7 @@ import java.net.URL;
* @version 1.0
*/
class URLFileLocation extends FileLocation {
/**
* URL of the remote file.
*/
@@ -32,22 +32,21 @@ class URLFileLocation extends FileLocation {
* removed).
*/
private String fileName;
/**
* Constructor.
*
* @param url
* The URL of the file.
* @param url The URL of the file.
*/
URLFileLocation(URL url) {
this.url = url;
fileFullPath = createFileFullPath();
fileName = createFileName();
}
/**
* Creates a "prettied-up" URL to use. This will be stripped of
* sensitive information such as passwords.
* Creates a "prettied-up" URL to use. This will be stripped of sensitive
* information such as passwords.
*
* @return The full path to use.
*/
@@ -56,7 +55,7 @@ class URLFileLocation extends FileLocation {
fullPath = fullPath.replaceFirst("://([^:]+)(?:.+)@", "://$1@");
return fullPath;
}
/**
* Creates the "prettied-up" filename to use.
*
@@ -71,11 +70,11 @@ class URLFileLocation extends FileLocation {
}
return fileName;
}
/**
* Returns the last time this file was modified, or
* {@link TextEditorPane#LAST_MODIFIED_UNKNOWN} if this value cannot be
* computed (such as for a remote file).
* {@link TextEditorPane#LAST_MODIFIED_UNKNOWN} if this value cannot be computed
* (such as for a remote file).
*
* @return The last time this file was modified. This will always be
* {@link TextEditorPane#LAST_MODIFIED_UNKNOWN} for URL's.
@@ -84,7 +83,7 @@ class URLFileLocation extends FileLocation {
protected long getActualLastModified() {
return TextEditorPane.LAST_MODIFIED_UNKNOWN;
}
/**
* {@inheritDoc}
*/
@@ -92,7 +91,7 @@ class URLFileLocation extends FileLocation {
public String getFileFullPath() {
return fileFullPath;
}
/**
* {@inheritDoc}
*/
@@ -100,7 +99,7 @@ class URLFileLocation extends FileLocation {
public String getFileName() {
return fileName;
}
/**
* {@inheritDoc}
*/
@@ -108,7 +107,7 @@ class URLFileLocation extends FileLocation {
protected InputStream getInputStream() throws IOException {
return url.openStream();
}
/**
* {@inheritDoc}
*/
@@ -116,7 +115,7 @@ class URLFileLocation extends FileLocation {
protected OutputStream getOutputStream() throws IOException {
return url.openConnection().getOutputStream();
}
/**
* Returns whether this file location is a local file.
*
@@ -127,11 +126,11 @@ class URLFileLocation extends FileLocation {
public boolean isLocal() {
return "file".equalsIgnoreCase(url.getProtocol());
}
/**
* Returns whether this file location is a local file and already
* exists. This method always returns <code>false</code> since we
* cannot check this value easily.
* Returns whether this file location is a local file and already exists. This
* method always returns <code>false</code> since we cannot check this value
* easily.
*
* @return <code>false</code> always.
* @see #isLocal()
@@ -20,13 +20,11 @@ import javax.swing.text.TabExpander;
* The current implementation paints as follows:
* <ul>
* <li>The first tab or space, if any, is found in the token.</li>
* <li>If a tab was found, all characters up to it are painted as a
* group.</li>
* <li>If a space was found, all characters up to and including it are
* painted (it is painted with a special symbol to denote it as
* a space).</li>
* <li>If neither a tab nor a whitespace was found, all characters in the
* token are painted.</li>
* <li>If a tab was found, all characters up to it are painted as a group.</li>
* <li>If a space was found, all characters up to and including it are painted
* (it is painted with a special symbol to denote it as a space).</li>
* <li>If neither a tab nor a whitespace was found, all characters in the token
* are painted.</li>
* <li>Repeat until all characters are painted.</li>
* </ul>
* This means that rendering hints are applied to all groups of characters
@@ -46,13 +44,13 @@ import javax.swing.text.TabExpander;
* @version 1.0
*/
class VisibleWhitespaceTokenPainter extends DefaultTokenPainter {
/**
* {@inheritDoc}
*/
@Override
protected float paintImpl(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e, float clipStart,
boolean selected, boolean useSTC) {
protected float paintImpl(Token token, Graphics2D g, float x, float y, RSyntaxTextArea host, TabExpander e,
float clipStart, boolean selected, boolean useSTC) {
int origX = (int) x;
int textOffs = token.getTextOffset();
char[] text = token.getTextArray();
@@ -68,65 +66,65 @@ class VisibleWhitespaceTokenPainter extends DefaultTokenPainter {
int height = fm.getHeight();
for (int i = textOffs; i < end; i++) {
switch (text[i]) {
case '\t':
// Fill in background.
nextX = x + fm.charsWidth(text, flushIndex, flushLen);
float nextNextX = e.nextTabStop(nextX, 0);
if (bg != null) {
paintBackground(x, y, nextNextX - x, height, g, ascent, host, bg);
}
g.setColor(fg);
// Paint chars cached before the tab.
if (flushLen > 0) {
g.drawChars(text, flushIndex, flushLen, (int) x, (int) y);
flushLen = 0;
}
flushIndex = i + 1;
// Draw an arrow representing the tab.
int halfHeight = height / 2;
int quarterHeight = halfHeight / 2;
int ymid = (int) y - ascent + halfHeight;
g.drawLine((int) nextX, ymid, (int) nextNextX, ymid);
g.drawLine((int) nextNextX, ymid, (int) nextNextX - 4, ymid - quarterHeight);
g.drawLine((int) nextNextX, ymid, (int) nextNextX - 4, ymid + quarterHeight);
x = nextNextX;
break;
case ' ':
// NOTE: There is a little bit of a "fudge factor"
// here when "smooth text" is enabled, as "width"
// below may well not be the width given to the space
// by fm.charsWidth() (it depends on how it places the
// space with respect to the preceding character).
// But, we assume the approximation is close enough for
// our drawing a dot for the space.
// "flushLen+1" ensures text is aligned correctly (or,
// aligned the same as in getWidth()).
nextX = x + fm.charsWidth(text, flushIndex, flushLen + 1);
int width = fm.charWidth(' ');
// Paint background.
if (bg != null) {
paintBackground(x, y, nextX - x, height, g, ascent, host, bg);
}
g.setColor(fg);
// Paint chars before space.
if (flushLen > 0) {
g.drawChars(text, flushIndex, flushLen, (int) x, (int) y);
flushLen = 0;
}
// Paint a dot representing the space.
int dotX = (int) (nextX - width / 2f); // "2.0f" for
// FindBugs
int dotY = (int) (y - ascent + height / 2f); // Ditto
g.drawLine(dotX, dotY, dotX, dotY);
flushIndex = i + 1;
x = nextX;
break;
case '\f':
// ???
// fall-through for now.
default:
flushLen += 1;
break;
case '\t':
// Fill in background.
nextX = x + fm.charsWidth(text, flushIndex, flushLen);
float nextNextX = e.nextTabStop(nextX, 0);
if (bg != null) {
paintBackground(x, y, nextNextX - x, height, g, ascent, host, bg);
}
g.setColor(fg);
// Paint chars cached before the tab.
if (flushLen > 0) {
g.drawChars(text, flushIndex, flushLen, (int) x, (int) y);
flushLen = 0;
}
flushIndex = i + 1;
// Draw an arrow representing the tab.
int halfHeight = height / 2;
int quarterHeight = halfHeight / 2;
int ymid = (int) y - ascent + halfHeight;
g.drawLine((int) nextX, ymid, (int) nextNextX, ymid);
g.drawLine((int) nextNextX, ymid, (int) nextNextX - 4, ymid - quarterHeight);
g.drawLine((int) nextNextX, ymid, (int) nextNextX - 4, ymid + quarterHeight);
x = nextNextX;
break;
case ' ':
// NOTE: There is a little bit of a "fudge factor"
// here when "smooth text" is enabled, as "width"
// below may well not be the width given to the space
// by fm.charsWidth() (it depends on how it places the
// space with respect to the preceding character).
// But, we assume the approximation is close enough for
// our drawing a dot for the space.
// "flushLen+1" ensures text is aligned correctly (or,
// aligned the same as in getWidth()).
nextX = x + fm.charsWidth(text, flushIndex, flushLen + 1);
int width = fm.charWidth(' ');
// Paint background.
if (bg != null) {
paintBackground(x, y, nextX - x, height, g, ascent, host, bg);
}
g.setColor(fg);
// Paint chars before space.
if (flushLen > 0) {
g.drawChars(text, flushIndex, flushLen, (int) x, (int) y);
flushLen = 0;
}
// Paint a dot representing the space.
int dotX = (int) (nextX - width / 2f); // "2.0f" for
// FindBugs
int dotY = (int) (y - ascent + height / 2f); // Ditto
g.drawLine(dotX, dotY, dotX, dotY);
flushIndex = i + 1;
x = nextX;
break;
case '\f':
// ???
// fall-through for now.
default:
flushLen += 1;
break;
}
}
nextX = x + fm.charsWidth(text, flushIndex, flushLen);
@@ -43,7 +43,7 @@ import org.fife.ui.rtextarea.Gutter;
* @version 0.2
*/
public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView {
private boolean widthChanging;
private int tabBase;
private int tabSize;
@@ -67,17 +67,16 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
// */
// private static final char[] eolMarker = { '.' };
/**
* The width of this view cannot be below this amount, as if the width
* is ever 0 (really a bug), we'll go into an infinite loop.
* The width of this view cannot be below this amount, as if the width is ever 0
* (really a bug), we'll go into an infinite loop.
*/
private static final int MIN_WIDTH = 20;
/**
* Creates a new WrappedSyntaxView. Lines will be wrapped
* on character boundaries.
* Creates a new WrappedSyntaxView. Lines will be wrapped on character
* boundaries.
*
* @param elem
* the element underlying the view
* @param elem the element underlying the view
*/
public WrappedSyntaxView(Element elem) {
super(elem, Y_AXIS);
@@ -87,14 +86,12 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
tempRect = new Rectangle();
lineCountTempToken = new TokenImpl();
}
/**
* This is called by the nested wrapped line
* views to determine the break location. This can
* be reimplemented to alter the breaking behavior.
* It will either break at word or character boundaries
* depending upon the break argument given at
* construction.
* This is called by the nested wrapped line views to determine the break
* location. This can be reimplemented to alter the breaking behavior. It will
* either break at word or character boundaries depending upon the break
* argument given at construction.
*/
protected int calculateBreakPosition(int p0, Token tokenList, float x0) {
// System.err.println("------ beginning calculateBreakPosition()
@@ -143,7 +140,7 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
// return p;
return p + 1;
}
// private int getBreakLocation(Token t, FontMetrics fm, int x0, int x,
// TabExpander e) {
// Segment s = new Segment();
@@ -153,27 +150,24 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
// return t.offset + Utilities.getBreakLocation(s, fm, x0, x, e, t.offset);
// }
/**
* Gives notification from the document that attributes were changed
* in a location that this view is responsible for.
* Gives notification from the document that attributes were changed in a
* location that this view is responsible for.
*
* @param e
* the change information from the associated document
* @param a
* the current allocation of the view
* @param f
* the factory to use to rebuild if the view has children
* @param e the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see View#changedUpdate
*/
@Override
public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
updateChildren(e, a);
}
/**
* Sets the allocation rectangle for a given line's view, but sets the
* y value to the passed-in value. This should be used instead of
* {@link #childAllocation(int, Rectangle)} since it allows you to account
* for hidden lines in collapsed fold regions.
* Sets the allocation rectangle for a given line's view, but sets the y value
* to the passed-in value. This should be used instead of
* {@link #childAllocation(int, Rectangle)} since it allows you to account for
* hidden lines in collapsed fold regions.
*
* @param line
* @param y
@@ -192,25 +186,20 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
alloc.y -= margin.top;
}
}
/**
* Draws a single view (i.e., a line of text for a wrapped view),
* wrapping the text onto multiple lines if necessary.
* Draws a single view (i.e., a line of text for a wrapped view), wrapping the
* text onto multiple lines if necessary.
*
* @param painter
* The painter to use to render tokens.
* @param g
* The graphics context in which to paint.
* @param r
* The rectangle in which to paint.
* @param view
* The <code>View</code> to paint.
* @param fontHeight
* The height of the font being used.
* @param y
* The y-coordinate at which to begin painting.
* @param painter The painter to use to render tokens.
* @param g The graphics context in which to paint.
* @param r The rectangle in which to paint.
* @param view The <code>View</code> to paint.
* @param fontHeight The height of the font being used.
* @param y The y-coordinate at which to begin painting.
*/
protected void drawView(TokenPainter painter, Graphics2D g, Rectangle r, View view, int fontHeight, int y, int line) {
protected void drawView(TokenPainter painter, Graphics2D g, Rectangle r, View view, int fontHeight, int y,
int line) {
float x = r.x;
LayeredHighlighter h = (LayeredHighlighter) host.getHighlighter();
RSyntaxDocument document = (RSyntaxDocument) getDocument();
@@ -262,31 +251,23 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
g.drawString("\u00B6", x, (float) y - fontHeight);
}
}
/**
* Draws a single view (i.e., a line of text for a wrapped view), wrapping
* the text onto multiple lines if necessary. Any selected text is
* rendered with the editor's "selected text" color.
* Draws a single view (i.e., a line of text for a wrapped view), wrapping the
* text onto multiple lines if necessary. Any selected text is rendered with the
* editor's "selected text" color.
*
* @param painter
* The painter to use to render tokens.
* @param g
* The graphics context in which to paint.
* @param r
* The rectangle in which to paint.
* @param view
* The <code>View</code> to paint.
* @param fontHeight
* The height of the font being used.
* @param y
* The y-coordinate at which to begin painting.
* @param selStart
* The start of the selection.
* @param selEnd
* The end of the selection.
* @param painter The painter to use to render tokens.
* @param g The graphics context in which to paint.
* @param r The rectangle in which to paint.
* @param view The <code>View</code> to paint.
* @param fontHeight The height of the font being used.
* @param y The y-coordinate at which to begin painting.
* @param selStart The start of the selection.
* @param selEnd The end of the selection.
*/
protected void drawViewWithSelection(TokenPainter painter, Graphics2D g, Rectangle r, View view, int fontHeight, int y, int selStart,
int selEnd) {
protected void drawViewWithSelection(TokenPainter painter, Graphics2D g, Rectangle r, View view, int fontHeight,
int y, int selStart, int selEnd) {
float x = r.x;
boolean useSTC = host.getUseSelectedTextColor();
LayeredHighlighter h = (LayeredHighlighter) host.getHighlighter();
@@ -363,7 +344,8 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
if (token != null && token.isPaintable() && token.getOffset() < p) {
int tokenOffset = token.getOffset();
Token orig = token;
token = new TokenImpl(drawSeg, tokenOffset - start, p - 1 - start, tokenOffset, token.getType(), token.getLanguageIndex());
token = new TokenImpl(drawSeg, tokenOffset - start, p - 1 - start, tokenOffset, token.getType(),
token.getLanguageIndex());
token.setLanguageIndex(token.getLanguageIndex());
// Selection starts in this token
if (token.containsPosition(selStart)) {
@@ -422,19 +404,16 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
g.drawString("\u00B6", x, (float) y - fontHeight);
}
}
/**
* Fetches the allocation for the given child view.
* <p>
* Overridden to account for code folding.
*
* @param index
* The index of the child, &gt;= 0 &amp;&amp;&lt; getViewCount().
* @param a
* The allocation to this view
* @return The allocation to the child; or <code>null</code> if
* <code>a</code> is <code>null</code>; or <code>null</code> if the
* layout is invalid
* @param index The index of the child, &gt;= 0 &amp;&amp;&lt; getViewCount().
* @param a The allocation to this view
* @return The allocation to the child; or <code>null</code> if <code>a</code>
* is <code>null</code>; or <code>null</code> if the layout is invalid
*/
@Override
public Shape getChildAllocation(int index, Shape a) {
@@ -451,16 +430,14 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
return null;
}
/**
* Fetches the allocation for the given child view to render into.
* <p>
* Overridden to account for lines hidden by collapsed folded regions.
*
* @param line
* The index of the child, &gt;= 0 &amp;&amp;&lt; getViewCount()
* @param a
* The allocation to this view
* @param line The index of the child, &gt;= 0 &amp;&amp;&lt; getViewCount()
* @param a The allocation to this view
* @return The allocation to the child
*/
public Shape getChildAllocationImpl(int line, Shape a) {
@@ -480,21 +457,17 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
childAllocation2(line, y, alloc);
return alloc;
}
/**
* Determines the maximum span for this view along an
* axis. This is implemented to provide the superclass
* behavior after first making sure that the current font
* metrics are cached (for the nested lines which use
* the metrics to determine the height of the potentially
* wrapped lines).
* Determines the maximum span for this view along an axis. This is implemented
* to provide the superclass behavior after first making sure that the current
* font metrics are cached (for the nested lines which use the metrics to
* determine the height of the potentially wrapped lines).
*
* @param axis
* may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
* @param axis may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into. Typically the view
* is told to render into the span that is returned, although there is
* no guarantee. The parent may choose to resize or break the view.
* @see View#getMaximumSpan
*/
@Override
@@ -506,21 +479,17 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
return span;
}
/**
* Determines the minimum span for this view along an
* axis. This is implemented to provide the superclass
* behavior after first making sure that the current font
* metrics are cached (for the nested lines which use
* the metrics to determine the height of the potentially
* wrapped lines).
* Determines the minimum span for this view along an axis. This is implemented
* to provide the superclass behavior after first making sure that the current
* font metrics are cached (for the nested lines which use the metrics to
* determine the height of the potentially wrapped lines).
*
* @param axis
* may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
* @param axis may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into. Typically the view
* is told to render into the span that is returned, although there is
* no guarantee. The parent may choose to resize or break the view.
* @see View#getMinimumSpan
*/
@Override
@@ -532,21 +501,17 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
return span;
}
/**
* Determines the preferred span for this view along an
* axis. This is implemented to provide the superclass
* behavior after first making sure that the current font
* metrics are cached (for the nested lines which use
* the metrics to determine the height of the potentially
* wrapped lines).
* Determines the preferred span for this view along an axis. This is
* implemented to provide the superclass behavior after first making sure that
* the current font metrics are cached (for the nested lines which use the
* metrics to determine the height of the potentially wrapped lines).
*
* @param axis
* may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
* @param axis may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into. Typically the view
* is told to render into the span that is returned, although there is
* no guarantee. The parent may choose to resize or break the view.
* @see View#getPreferredSpan
*/
@Override
@@ -573,7 +538,7 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
return span;
}
/**
* Returns the tab size set for the document, defaulting to 5.
*
@@ -584,7 +549,7 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
int size = (i != null) ? i.intValue() : 5;
return size;
}
/**
* Overridden to allow for folded regions.
*/
@@ -610,18 +575,15 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
childAllocation2(lineCount - 1, curY, alloc);
return getView(lineCount - 1);
}
/**
* Gives notification that something was inserted into the
* document in a location that this view is responsible for.
* This is implemented to simply update the children.
* Gives notification that something was inserted into the document in a
* location that this view is responsible for. This is implemented to simply
* update the children.
*
* @param changes
* The change information from the associated document.
* @param a
* the current allocation of the view
* @param f
* the factory to use to rebuild if the view has children
* @param changes The change information from the associated document.
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see View#insertUpdate
*/
@Override
@@ -634,17 +596,14 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
v.insertUpdate(changes, alloc, f);
}
}
/**
* Loads all of the children to initialize the view.
* This is called by the <code>setParent</code> method.
* Subclasses can re-implement this to initialize their
* child views in a different manner. The default
* implementation creates a child view for each
* child element.
* Loads all of the children to initialize the view. This is called by the
* <code>setParent</code> method. Subclasses can re-implement this to initialize
* their child views in a different manner. The default implementation creates a
* child view for each child element.
*
* @param f
* the view factory
* @param f the view factory
*/
@Override
protected void loadChildren(ViewFactory f) {
@@ -658,7 +617,7 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
replace(0, 0, added);
}
}
@Override
public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
if (!isAllocationValid()) {
@@ -691,48 +650,43 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
throw new BadLocationException("Position not represented by view", pos);
}
/**
* Provides a mapping, for a given region, from the document model
* coordinate space to the view coordinate space. The specified region is
* created as a union of the first and last character positions.
* Provides a mapping, for a given region, from the document model coordinate
* space to the view coordinate space. The specified region is created as a
* union of the first and last character positions.
* <p>
*
* This is implemented to subtract the width of the second character, as
* this view's <code>modelToView</code> actually returns the width of the
* character instead of "1" or "0" like the View implementations in
* <code>javax.swing.text</code>. Thus, if we don't override this method,
* the <code>View</code> implementation will return one character's width
* too much for its consumers (implementations of
* This is implemented to subtract the width of the second character, as this
* view's <code>modelToView</code> actually returns the width of the character
* instead of "1" or "0" like the View implementations in
* <code>javax.swing.text</code>. Thus, if we don't override this method, the
* <code>View</code> implementation will return one character's width too much
* for its consumers (implementations of
* <code>javax.swing.text.Highlighter</code>).
*
* @param p0
* the position of the first character (&gt;=0)
* @param b0
* The bias of the first character position, toward the previous
* character or the next character represented by the offset, in
* case the position is a boundary of two views; <code>b0</code>
* will have one of these values:
* <ul>
* <li><code>Position.Bias.Forward</code>
* <li><code>Position.Bias.Backward</code>
* </ul>
* @param p1
* the position of the last character (&gt;=0)
* @param b1
* the bias for the second character position, defined
* one of the legal values shown above
* @param a
* the area of the view, which encompasses the requested region
* @return the bounding box which is a union of the region specified
* by the first and last character positions
* @exception BadLocationException
* if the given position does
* not represent a valid location in the associated document
* @exception IllegalArgumentException
* if <code>b0</code> or
* <code>b1</code> are not one of the
* legal <code>Position.Bias</code> values listed above
* @param p0 the position of the first character (&gt;=0)
* @param b0 The bias of the first character position, toward the previous
* character or the next character represented by the offset, in case
* the position is a boundary of two views; <code>b0</code> will have
* one of these values:
* <ul>
* <li><code>Position.Bias.Forward</code>
* <li><code>Position.Bias.Backward</code>
* </ul>
* @param p1 the position of the last character (&gt;=0)
* @param b1 the bias for the second character position, defined one of the
* legal values shown above
* @param a the area of the view, which encompasses the requested region
* @return the bounding box which is a union of the region specified by the
* first and last character positions
* @exception BadLocationException if the given position does not represent
* a valid location in the associated
* document
* @exception IllegalArgumentException if <code>b0</code> or <code>b1</code> are
* not one of the legal
* <code>Position.Bias</code> values listed
* above
* @see View#viewToModel
*/
@Override
@@ -774,17 +728,15 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
return r0;
}
/**
* Returns the next tab stop position after a given reference position.
* This implementation does not support things like centering so it
* ignores the tabOffset argument.
* Returns the next tab stop position after a given reference position. This
* implementation does not support things like centering so it ignores the
* tabOffset argument.
*
* @param x
* the current position &gt;= 0
* @param tabOffset
* the position within the text stream
* that the tab occurred at &gt;= 0.
* @param x the current position &gt;= 0
* @param tabOffset the position within the text stream that the tab occurred at
* &gt;= 0.
* @return the tab stop, measured in points &gt;= 0
*/
@Override
@@ -795,14 +747,12 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
int ntabs = ((int) x - tabBase) / tabSize;
return tabBase + ((ntabs + 1f) * tabSize);
}
/**
* Paints the word-wrapped text.
*
* @param g
* The graphics context in which to paint.
* @param a
* The shape (usually a rectangle) in which to paint.
* @param g The graphics context in which to paint.
* @param a The shape (usually a rectangle) in which to paint.
*/
@Override
public void paint(Graphics g, Shape a) {
@@ -854,18 +804,15 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
}
}
/**
* Gives notification that something was removed from the
* document in a location that this view is responsible for.
* This is implemented to simply update the children.
* Gives notification that something was removed from the document in a location
* that this view is responsible for. This is implemented to simply update the
* children.
*
* @param changes
* The change information from the associated document.
* @param a
* the current allocation of the view
* @param f
* the factory to use to rebuild if the view has children
* @param changes The change information from the associated document.
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see View#removeUpdate
*/
@Override
@@ -878,20 +825,16 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
v.removeUpdate(changes, alloc, f);
}
}
/**
* Makes a <code>Segment</code> point to the text in our
* document between the given positions. Note that the positions MUST be
* valid positions in the document.
* Makes a <code>Segment</code> point to the text in our document between the
* given positions. Note that the positions MUST be valid positions in the
* document.
*
* @param p0
* The first position in the document.
* @param p1
* The second position in the document.
* @param document
* The document from which you want to get the text.
* @param seg
* The segment in which to load the text.
* @param p0 The first position in the document.
* @param p1 The second position in the document.
* @param document The document from which you want to get the text.
* @param seg The segment in which to load the text.
*/
private void setSegment(int p0, int p1, Document document, Segment seg) {
try {
@@ -904,15 +847,13 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
ble.printStackTrace();
}
}
/**
* Sets the size of the view. This should cause layout of the view along
* the given axis, if it has any layout duties.
* Sets the size of the view. This should cause layout of the view along the
* given axis, if it has any layout duties.
*
* @param width
* the width &gt;= 0
* @param height
* the height &gt;= 0
* @param width the width &gt;= 0
* @param height the height &gt;= 0
*/
@Override
public void setSize(float width, float height) {
@@ -926,10 +867,9 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
super.setSize(width, height);
widthChanging = false;
}
/**
* Update the child views in response to a
* document event.
* Update the child views in response to a document event.
*/
void updateChildren(DocumentEvent e, Shape a) {
Element elem = getElement();
@@ -962,14 +902,14 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
// update font metrics which may be used by the child views
updateMetrics();
}
final void updateMetrics() {
Component host = getContainer();
Font f = host.getFont();
metrics = host.getFontMetrics(f); // Metrics for the default font.
tabSize = getTabSize() * metrics.charWidth('m');
}
@Override
public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
int offs = -1;
@@ -992,7 +932,7 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
return offs;
}
/**
* {@inheritDoc}
*/
@@ -1001,7 +941,7 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
return yForLineContaining(alloc, getElement().getElement(line).getStartOffset());
// return alloc.y + getOffset(Y_AXIS, line);
}
/**
* {@inheritDoc}
*/
@@ -1024,25 +964,23 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
return -1;
}
/**
* Simple view of a line that wraps if it doesn't
* fit within the horizontal space allocated.
* This class tries to be lightweight by carrying little
* state of it's own and sharing the state of the outer class
* with it's siblings.
* Simple view of a line that wraps if it doesn't fit within the horizontal
* space allocated. This class tries to be lightweight by carrying little state
* of it's own and sharing the state of the outer class with it's siblings.
*/
class WrappedLine extends View {
private int nlines;
WrappedLine(Element elem) {
super(elem);
}
/**
* Calculate the number of lines that will be rendered
* by logical line when it is wrapped.
* Calculate the number of lines that will be rendered by logical line when it
* is wrapped.
*/
final int calculateLineCount() {
int nlines = 0;
@@ -1062,7 +1000,8 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
for (int p0 = startOffset; p0 < p1;) {
// System.err.println("... ... " + p0 + ", " + p1);
nlines += 1;
TokenSubList subList = TokenUtils.getSubTokenList(tokenList, p0, WrappedSyntaxView.this, textArea, x0, lineCountTempToken);
TokenSubList subList = TokenUtils.getSubTokenList(tokenList, p0, WrappedSyntaxView.this, textArea, x0,
lineCountTempToken);
x0 = subList != null ? subList.x : x0;
tokenList = subList != null ? subList.tokenList : null;
int p = calculateBreakPosition(p0, tokenList, x0);
@@ -1075,81 +1014,68 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
// System.err.println("... ... ... new p0==" + p0);
}
/*
* int numLines = 0;
* try {
* numLines = textArea.getLineCount();
* } catch (BadLocationException ble) {
* ble.printStackTrace();
* }
* System.err.
* println(">>> >>> calculated number of lines for this view (line "
* + line + "/" + numLines + ": " + nlines);
* int numLines = 0; try { numLines = textArea.getLineCount(); } catch
* (BadLocationException ble) { ble.printStackTrace(); } System.err.
* println(">>> >>> calculated number of lines for this view (line " + line +
* "/" + numLines + ": " + nlines);
*/
return nlines;
}
/**
* Determines the preferred span for this view along an
* axis.
* Determines the preferred span for this view along an axis.
*
* @param axis
* may be either X_AXIS or Y_AXIS
* @return the span the view would like to be rendered into.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
* @param axis may be either X_AXIS or Y_AXIS
* @return the span the view would like to be rendered into. Typically the view
* is told to render into the span that is returned, although there is
* no guarantee. The parent may choose to resize or break the view.
* @see View#getPreferredSpan
*/
@Override
public float getPreferredSpan(int axis) {
switch (axis) {
case View.X_AXIS:
float width = getWidth();
if (width == Integer.MAX_VALUE) {
// We have been initially set to MAX_VALUE, but we don't
// want this as our preferred.
return 100f;
}
return width;
case View.Y_AXIS:
if (nlines == 0 || widthChanging) {
nlines = calculateLineCount();
}
int h = nlines * ((RSyntaxTextArea) getContainer()).getLineHeight();
return h;
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
case View.X_AXIS:
float width = getWidth();
if (width == Integer.MAX_VALUE) {
// We have been initially set to MAX_VALUE, but we don't
// want this as our preferred.
return 100f;
}
return width;
case View.Y_AXIS:
if (nlines == 0 || widthChanging) {
nlines = calculateLineCount();
}
int h = nlines * ((RSyntaxTextArea) getContainer()).getLineHeight();
return h;
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
}
/**
* Renders using the given rendering surface and area on that
* surface. The view may need to do layout and create child
* views to enable itself to render into the given allocation.
* Renders using the given rendering surface and area on that surface. The view
* may need to do layout and create child views to enable itself to render into
* the given allocation.
*
* @param g
* the rendering surface to use
* @param a
* the allocated region to render into
* @param g the rendering surface to use
* @param a the allocated region to render into
* @see View#paint
*/
@Override
public void paint(Graphics g, Shape a) {
// This is done by drawView() above.
}
/**
* Provides a mapping from the document model coordinate space
* to the coordinate space of the view mapped to it.
* Provides a mapping from the document model coordinate space to the coordinate
* space of the view mapped to it.
*
* @param pos
* the position to convert
* @param a
* the allocated region to render into
* @param pos the position to convert
* @param a the allocated region to render into
* @return the bounding box of the given position is returned
* @exception BadLocationException
* if the given position does not
* represent a valid location in the associated document.
* @exception BadLocationException if the given position does not represent a
* valid location in the associated document.
*/
@Override
public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
@@ -1170,13 +1096,15 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
Token tokenList = doc.getTokenListForLine(line);
float x0 = alloc.x;// 0;
while (p0 < p1) {
TokenSubList subList = TokenUtils.getSubTokenList(tokenList, p0, WrappedSyntaxView.this, textArea, x0, lineCountTempToken);
TokenSubList subList = TokenUtils.getSubTokenList(tokenList, p0, WrappedSyntaxView.this, textArea, x0,
lineCountTempToken);
x0 = subList != null ? subList.x : x0;
tokenList = subList != null ? subList.tokenList : null;
int p = calculateBreakPosition(p0, tokenList, x0);
if ((pos >= p0) && (testP < p)) {// pos < p)) {
// it's in this line
alloc = RSyntaxUtilities.getLineWidthUpTo(textArea, s, p0, pos, WrappedSyntaxView.this, alloc, alloc.x);
alloc = RSyntaxUtilities.getLineWidthUpTo(textArea, s, p0, pos, WrappedSyntaxView.this, alloc,
alloc.x);
// System.err.println("--- end modelToView ---");
return alloc;
}
@@ -1184,7 +1112,8 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
if (p == p1 - 1 && pos == p1 - 1) {
// Wants end.
if (pos > p0) {
alloc = RSyntaxUtilities.getLineWidthUpTo(textArea, s, p0, pos, WrappedSyntaxView.this, alloc, alloc.x);
alloc = RSyntaxUtilities.getLineWidthUpTo(textArea, s, p0, pos, WrappedSyntaxView.this, alloc,
alloc.x);
}
// System.err.println("--- end modelToView ---");
return alloc;
@@ -1195,19 +1124,16 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
}
throw new BadLocationException(null, pos);
}
/**
* Provides a mapping from the view coordinate space to the logical
* coordinate space of the model.
* Provides a mapping from the view coordinate space to the logical coordinate
* space of the model.
*
* @param fx
* the X coordinate
* @param fy
* the Y coordinate
* @param a
* the allocated region to render into
* @return the location within the model that best represents the
* given point in the view
* @param fx the X coordinate
* @param fy the Y coordinate
* @param a the allocated region to render into
* @return the location within the model that best represents the given point in
* the view
* @see View#viewToModel
*/
@Override
@@ -1247,8 +1173,8 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
// We can always use alloc.x since we always break
// lines so they start at the beginning of a physical
// line.
TokenSubList subList = TokenUtils.getSubTokenList(tlist, p0, WrappedSyntaxView.this, textArea, alloc.x,
lineCountTempToken);
TokenSubList subList = TokenUtils.getSubTokenList(tlist, p0, WrappedSyntaxView.this, textArea,
alloc.x, lineCountTempToken);
tlist = subList != null ? subList.tokenList : null;
int p = calculateBreakPosition(p0, tlist, alloc.x);
// If desired view position is in this physical chunk.
@@ -1281,7 +1207,7 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
return getEndOffset() - 1;
} // End of else.
}
private void handleDocumentEvent(DocumentEvent e, Shape a, ViewFactory f) {
int n = calculateLineCount();
if (this.nlines != n) {
@@ -1303,12 +1229,12 @@ public class WrappedSyntaxView extends BoxView implements TabExpander, RSTAView
c.repaint(alloc.x, alloc.y, alloc.width, alloc.height);
}
}
@Override
public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) {
handleDocumentEvent(e, a, f);
}
@Override
public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) {
handleDocumentEvent(e, a, f);
@@ -9,8 +9,8 @@ import javax.swing.text.Element;
// import javax.swing.text.View;
/**
* Replacement for the old <code>WrappedSyntaxView</code> class, designed to
* be faster with large wrapped documents. Heavily based off of
* Replacement for the old <code>WrappedSyntaxView</code> class, designed to be
* faster with large wrapped documents. Heavily based off of
* <code>BoxView</code>, but streamlined to only care about the y-axis, and
* takes code folding into account.
* <p>
@@ -25,7 +25,7 @@ public class WrappedSyntaxView2 {// extends CompositeView {
// private int[] cachedOffsets;
// private int[] cachedSpans;
// private boolean sizeRequirementsValid;
public WrappedSyntaxView2(Element root) {
// super(root);
// tempRect = new Rectangle();
@@ -21,10 +21,10 @@ import org.fife.ui.rtextarea.SmartHighlightPainter;
* @version 1.0
*/
public class XmlOccurrenceMarker implements OccurrenceMarker {
private static final char[] CLOSE_TAG_START = { '<', '/' };
private static final char[] TAG_SELF_CLOSE = { '/', '>' };
/**
* {@inheritDoc}
*/
@@ -32,7 +32,7 @@ public class XmlOccurrenceMarker implements OccurrenceMarker {
public Token getTokenToMark(RSyntaxTextArea textArea) {
return HtmlOccurrenceMarker.getTagNameTokenForCaretOffset(textArea, this);
}
/**
* {@inheritDoc}
*/
@@ -40,7 +40,7 @@ public class XmlOccurrenceMarker implements OccurrenceMarker {
public boolean isValidType(RSyntaxTextArea textArea, Token t) {
return textArea.getMarkOccurrencesOfTokenType(t.getType());
}
/**
* {@inheritDoc}
*/
@@ -173,15 +173,15 @@ public class XmlOccurrenceMarker implements OccurrenceMarker {
} while (curLine >= 0);
}
}
/**
* Used internally when searching backward for a matching "open" tag.
*/
private static class Entry {
private boolean open;
private Token t;
Entry(boolean open, Token t) {
this.open = open;
this.t = t;
@@ -33,14 +33,14 @@ import javax.swing.event.MouseInputAdapter;
import org.fife.ui.rsyntaxtextarea.PopupWindowDecorator;
/**
* A focusable tool tip, similar to those found in Eclipse. The user
* can click in the tip and it becomes a "real," resizable window.
* A focusable tool tip, similar to those found in Eclipse. The user can click
* in the tip and it becomes a "real," resizable window.
*
* @author Robert Futrell
* @version 1.0
*/
public class FocusableTip {
private JTextArea textArea;
private TipWindow tipWindow;
private URL imageBase;
@@ -49,8 +49,8 @@ public class FocusableTip {
private String lastText;
private Dimension maxSize; // null to automatic.
/**
* The screen bounds in which the mouse has to stay for the currently
* displayed tip to stay visible.
* The screen bounds in which the mouse has to stay for the currently displayed
* tip to stay visible.
*/
private Rectangle tipVisibleBounds;
/**
@@ -61,18 +61,19 @@ public class FocusableTip {
* Margin from mouse cursor at which to draw focusable tip.
*/
private static final int Y_MARGIN = 12;
private static final ResourceBundle MSG = ResourceBundle.getBundle("org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip");
private static final ResourceBundle MSG = ResourceBundle
.getBundle("org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip");
public FocusableTip(JTextArea textArea, HyperlinkListener listener) {
setTextArea(textArea);
this.hyperlinkListener = listener;
textAreaListener = new TextAreaListener();
tipVisibleBounds = new Rectangle();
}
/**
* Compute the bounds in which the user can move the mouse without the
* tip window disappearing.
* Compute the bounds in which the user can move the mouse without the tip
* window disappearing.
*/
private void computeTipVisibleBounds() {
// Compute area that the mouse can move in without hiding the
@@ -84,7 +85,7 @@ public class FocusableTip {
r.setLocation(p);
tipVisibleBounds.setBounds(r.x, r.y - 15, r.width, r.height + 15 * 2);
}
private void createAndShowTipWindow(final MouseEvent e, final String text) {
Window owner = SwingUtilities.getWindowAncestor(textArea);
tipWindow = new TipWindow(owner, this, text);
@@ -100,7 +101,7 @@ public class FocusableTip {
// See http://forums.sun.com/thread.jspa?forumID=57&threadID=574810
// for a discussion.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// If a new FocusableTip is requested while another one is
@@ -148,7 +149,7 @@ public class FocusableTip {
}
});
}
/**
* Returns the base URL to use when loading images in this focusable tip.
*
@@ -158,7 +159,7 @@ public class FocusableTip {
public URL getImageBase() {
return imageBase;
}
/**
* The maximum size for unfocused tool tips.
*
@@ -169,18 +170,17 @@ public class FocusableTip {
public Dimension getMaxSize() {
return maxSize;
}
/**
* Returns localized text for the given key.
*
* @param key
* The key into the resource bundle.
* @param key The key into the resource bundle.
* @return The localized text.
*/
static String getString(String key) {
return MSG.getString(key);
}
/**
* Disposes of the focusable tip currently displayed, if any.
*/
@@ -194,41 +194,39 @@ public class FocusableTip {
textArea.requestFocus();
}
}
void removeListeners() {
// System.out.println("DEBUG: Removing text area listeners");
textAreaListener.uninstall();
}
/**
* Sets the base URL to use when loading images in this focusable tip.
*
* @param url
* The base URL to use.
* @param url The base URL to use.
* @see #getImageBase()
*/
public void setImageBase(URL url) {
imageBase = url;
}
/**
* Sets the maximum size for unfocused tool tips.
*
* @param maxSize
* The new maximum size. A value of <code>null</code> will
* cause a default size to be used.
* @param maxSize The new maximum size. A value of <code>null</code> will cause
* a default size to be used.
* @see #getMaxSize()
*/
public void setMaxSize(Dimension maxSize) {
this.maxSize = maxSize;
}
private void setTextArea(JTextArea textArea) {
this.textArea = textArea;
// Is okay to do multiple times.
ToolTipManager.sharedInstance().registerComponent(textArea);
}
public void toolTipRequested(MouseEvent e, String text) {
if (text == null || text.length() == 0) {
possiblyDisposeOfTipWindow();
@@ -240,12 +238,13 @@ public class FocusableTip {
createAndShowTipWindow(e, text);
}
}
/**
* Listens for events in a text area.
*/
private class TextAreaListener extends MouseInputAdapter implements CaretListener, ComponentListener, FocusListener, KeyListener {
private class TextAreaListener extends MouseInputAdapter
implements CaretListener, ComponentListener, FocusListener, KeyListener {
@Override
public void caretUpdate(CaretEvent e) {
Object source = e.getSource();
@@ -253,30 +252,31 @@ public class FocusableTip {
possiblyDisposeOfTipWindow();
}
}
@Override
public void componentHidden(ComponentEvent e) {
handleComponentEvent(e);
}
@Override
public void componentMoved(ComponentEvent e) {
handleComponentEvent(e);
}
@Override
public void componentResized(ComponentEvent e) {
handleComponentEvent(e);
}
@Override
public void componentShown(ComponentEvent e) {
handleComponentEvent(e);
}
@Override
public void focusGained(FocusEvent e) {}
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
// Only dispose of tip if it wasn't the TipWindow that was clicked
@@ -284,16 +284,17 @@ public class FocusableTip {
// calling SwingUtilities.getWindowAncestor() to guard against an
// NPE.
Component c = e.getOppositeComponent();
boolean tipClicked = (c instanceof TipWindow) || (c != null && SwingUtilities.getWindowAncestor(c) instanceof TipWindow);
boolean tipClicked = (c instanceof TipWindow)
|| (c != null && SwingUtilities.getWindowAncestor(c) instanceof TipWindow);
if (!tipClicked) {
possiblyDisposeOfTipWindow();
}
}
private void handleComponentEvent(ComponentEvent e) {
possiblyDisposeOfTipWindow();
}
public void install(JTextArea textArea) {
textArea.addCaretListener(this);
textArea.addComponentListener(this);
@@ -302,7 +303,7 @@ public class FocusableTip {
textArea.addMouseListener(this);
textArea.addMouseMotionListener(this);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
@@ -314,25 +315,27 @@ public class FocusableTip {
}
}
}
@Override
public void keyReleased(KeyEvent e) {}
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {}
public void keyTyped(KeyEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
// possiblyDisposeOfTipWindow();
}
@Override
public void mouseMoved(MouseEvent e) {
if (tipVisibleBounds == null || !tipVisibleBounds.contains(e.getPoint())) {
possiblyDisposeOfTipWindow();
}
}
public void uninstall() {
textArea.removeCaretListener(this);
textArea.removeComponentListener(this);
@@ -30,16 +30,16 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
* @version 1.0
*/
public final class TipUtil {
private TipUtil() {}
private TipUtil() {
}
/**
* Returns a hex string for the specified color, suitable for HTML.
*
* @param c
* The color.
* @return The string representation, in the form "<code>#rrggbb</code>",
* or <code>null</code> if <code>c</code> is <code>null</code>.
* @param c The color.
* @return The string representation, in the form "<code>#rrggbb</code>", or
* <code>null</code> if <code>c</code> is <code>null</code>.
*/
private static String getHexString(Color c) {
if (c == null) {
@@ -63,16 +63,14 @@ public final class TipUtil {
sb.append(Integer.toHexString(b));
return sb.toString();
}
/**
* Returns the screen coordinates for the monitor that contains the
* specified point. This is useful for setups with multiple monitors,
* to ensure that popup windows are positioned properly.
* Returns the screen coordinates for the monitor that contains the specified
* point. This is useful for setups with multiple monitors, to ensure that popup
* windows are positioned properly.
*
* @param x
* The x-coordinate, in screen coordinates.
* @param y
* The y-coordinate, in screen coordinates.
* @param x The x-coordinate, in screen coordinates.
* @param y The y-coordinate, in screen coordinates.
* @return The bounds of the monitor that contains the specified point.
*/
public static Rectangle getScreenBoundsForPoint(int x, int y) {
@@ -90,7 +88,7 @@ public final class TipUtil {
// If point is outside all monitors, default to default monitor (?)
return env.getMaximumWindowBounds();
}
/**
* Returns the default background color to use for tool tip windows.
*
@@ -113,7 +111,7 @@ public final class TipUtil {
}
return c;
}
/**
* Returns the border used by tool tips in this look and feel.
*
@@ -129,20 +127,19 @@ public final class TipUtil {
}
return border;
}
/**
* Returns whether a color is a Nimbus DerivedColor, which is troublesome
* in that it doesn't use its RGB values (uses HSB instead?) and so
* querying them is useless.
* Returns whether a color is a Nimbus DerivedColor, which is troublesome in
* that it doesn't use its RGB values (uses HSB instead?) and so querying them
* is useless.
*
* @param c
* The color to check.
* @param c The color to check.
* @return Whether it is a DerivedColor
*/
private static boolean isDerivedColor(Color c) {
return c != null && c.getClass().getName().endsWith(".DerivedColor");
}
/**
* Returns whether the Nimbus Look and Feel is installed.
*
@@ -151,14 +148,13 @@ public final class TipUtil {
private static boolean isNimbusLookAndFeel() {
return UIManager.getLookAndFeel().getName().equals("Nimbus");
}
/**
* Tweaks a <code>JEditorPane</code> so it can be used to render the
* content in a focusable pseudo-tool tip. It is assumed that the editor
* pane is using an <code>HTMLDocument</code>.
* Tweaks a <code>JEditorPane</code> so it can be used to render the content in
* a focusable pseudo-tool tip. It is assumed that the editor pane is using an
* <code>HTMLDocument</code>.
*
* @param textArea
* The editor pane to tweak.
* @param textArea The editor pane to tweak.
*/
public static void tweakTipEditorPane(JEditorPane textArea) {
// Jump through a few hoops to get things looking nice in Nimbus
@@ -198,21 +194,18 @@ public final class TipUtil {
Color linkFG = RSyntaxUtilities.getHyperlinkForeground();
doc.getStyleSheet().addRule("a { color: " + getHexString(linkFG) + "; }");
}
/**
* Sets the default font for an HTML document (e.g., in a tool tip
* displaying HTML). This is here because when rendering HTML,
* {@code setFont()} is not honored.
* Sets the default font for an HTML document (e.g., in a tool tip displaying
* HTML). This is here because when rendering HTML, {@code setFont()} is not
* honored.
*
* @param doc
* The document to modify.
* @param font
* The font to use.
* @param fg
* The default foreground color.
* @param doc The document to modify.
* @param font The font to use.
* @param fg The default foreground color.
*/
public static void setFont(HTMLDocument doc, Font font, Color fg) {
doc.getStyleSheet().addRule("body { font-family: " + font.getFamily() + "; font-size: " + font.getSize() + "pt" + "; color: "
+ getHexString(fg) + "; }");
doc.getStyleSheet().addRule("body { font-family: " + font.getFamily() + "; font-size: " + font.getSize() + "pt"
+ "; color: " + getHexString(fg) + "; }");
}
}
@@ -50,21 +50,19 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
* @version 1.0
*/
class TipWindow extends JWindow implements ActionListener {
private FocusableTip ft;
private JEditorPane textArea;
private String text;
private transient TipListener tipListener;
private transient HyperlinkListener userHyperlinkListener;
private static TipWindow visibleInstance;
/**
* Constructor.
*
* @param owner
* The parent window.
* @param msg
* The text of the tool tip. This can be HTML.
* @param owner The parent window.
* @param msg The text of the tool tip. This can be HTML.
*/
TipWindow(Window owner, FocusableTip ft, String msg) {
super(owner);
@@ -85,7 +83,7 @@ class TipWindow extends JWindow implements ActionListener {
}
textArea.addMouseListener(tipListener);
textArea.addHyperlinkListener(new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
@@ -101,7 +99,7 @@ class TipWindow extends JWindow implements ActionListener {
// InputMap/ActionMap combo doesn't work for JWindows (even when
// using the JWindow's JRootPane), so we'll resort to KeyListener
KeyAdapter ka = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
@@ -121,7 +119,7 @@ class TipWindow extends JWindow implements ActionListener {
visibleInstance = this;
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (!getFocusableWindowState()) {
@@ -130,7 +128,7 @@ class TipWindow extends JWindow implements ActionListener {
textArea.removeMouseListener(tipListener);
pack();
addWindowFocusListener(new WindowAdapter() {
@Override
public void windowLostFocus(WindowEvent e) {
ft.possiblyDisposeOfTipWindow();
@@ -142,7 +140,7 @@ class TipWindow extends JWindow implements ActionListener {
}
}
}
/**
* Disposes of this window.
*/
@@ -157,10 +155,10 @@ class TipWindow extends JWindow implements ActionListener {
ft.removeListeners();
super.dispose();
}
/**
* Workaround for JEditorPane not returning its proper preferred size
* when rendering HTML until after layout already done. See
* Workaround for JEditorPane not returning its proper preferred size when
* rendering HTML until after layout already done. See
* http://forums.sun.com/thread.jspa?forumID=57&threadID=574810 for a
* discussion.
*/
@@ -195,11 +193,11 @@ class TipWindow extends JWindow implements ActionListener {
}
pack(); // Must re-pack to calculate proper size.
}
public String getText() {
return text;
}
private void setBottomPanel() {
final JPanel panel = new JPanel(new BorderLayout());
panel.add(new JSeparator(), BorderLayout.NORTH);
@@ -209,9 +207,9 @@ class TipWindow extends JWindow implements ActionListener {
sg.applyComponentOrientation(sg.getComponentOrientation()); // Workaround
panel.add(sg, BorderLayout.LINE_END);
MouseInputAdapter adapter = new MouseInputAdapter() {
private Point lastPoint;
@Override
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
@@ -225,7 +223,7 @@ class TipWindow extends JWindow implements ActionListener {
lastPoint = p;
}
}
@Override
public void mousePressed(MouseEvent e) {
lastPoint = e.getPoint();
@@ -272,13 +270,12 @@ class TipWindow extends JWindow implements ActionListener {
}
cp.add(panel, BorderLayout.SOUTH);
}
/**
* Sets the listener for hyperlink events in this tip window.
*
* @param listener
* The new listener. The old listener (if any) is
* removed. A value of <code>null</code> means "no listener."
* @param listener The new listener. The old listener (if any) is removed. A
* value of <code>null</code> means "no listener."
*/
public void setHyperlinkListener(HyperlinkListener listener) {
// We've added a separate listener, so remove only the user's.
@@ -290,19 +287,20 @@ class TipWindow extends JWindow implements ActionListener {
textArea.addHyperlinkListener(userHyperlinkListener);
}
}
/**
* Listens for events in this window.
*/
private final class TipListener extends MouseAdapter {
private TipListener() {}
private TipListener() {
}
@Override
public void mousePressed(MouseEvent e) {
actionPerformed(null); // Manually create "real" window
}
@Override
public void mouseExited(MouseEvent e) {
// Since we registered this listener on the child components of
Loaded 100 of 211 files, more files were not shown because too many files have changed in this diff. Show more