/** * Returns the end of the word at the given offset. * * @param textArea The text area. * @param offs The offset into the text area's content. * @return The end offset of the word. * @throws BadLocationException If <code>offs</code> is invalid. * @see #getWordStart(RSyntaxTextArea, int) */ public static int getWordEnd(RSyntaxTextArea textArea, int offs) throws BadLocationException { Document doc = textArea.getDocument(); int endOffs = textArea.getLineEndOffsetOfCurrentLine(); int lineEnd = Math.min(endOffs, doc.getLength()); if (offs == lineEnd) { // End of the line. return offs; } String s = doc.getText(offs, lineEnd - offs - 1); if (s != null && s.length() > 0) { // Should always be true int i = 0; int count = s.length(); char ch = s.charAt(i); if (Character.isWhitespace(ch)) { while (i < count && Character.isWhitespace(s.charAt(i++))) ; } else if (Character.isLetterOrDigit(ch)) { while (i < count && Character.isLetterOrDigit(s.charAt(i++))) ; } else { i = 2; } offs += i - 1; } return offs; }
public static void setFont(RSyntaxTextArea textArea, Font font) { if (font != null) { SyntaxScheme ss = textArea.getSyntaxScheme(); ss = (SyntaxScheme) ss.clone(); for (int i = 0; i < ss.getStyleCount(); i++) { if (ss.getStyle(i) != null) { ss.getStyle(i).font = font; } } textArea.setSyntaxScheme(ss); textArea.setFont(font); } }
/** * Determines the position in the model that is closest to the given view location in the row * below. The component given must have a size to compute the result. If the component doesn't * have a size a value of -1 will be returned. * * @param c the editor * @param offs the offset in the document >= 0 * @param x the X coordinate >= 0 * @return the position >= 0 if the request can be computed, otherwise a value of -1 will be * returned. * @exception BadLocationException if the offset is out of range */ public static final int getPositionBelow(RSyntaxTextArea c, int offs, float x, TabExpander e) throws BadLocationException { TokenOrientedView tov = (TokenOrientedView) e; Token token = tov.getTokenListForPhysicalLineBelow(offs); if (token == null) return -1; // A line containing only Token.NULL is an empty line. else if (token.type == Token.NULL) { int line = c.getLineOfOffset(offs); // Sure to be > c.getLineCount()-1 ?? return c.getLineStartOffset(line + 1); } else { return token.getListOffset(c, e, 0, x); } }
/** * Provides a way to determine the next visually represented model location at which 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. * * <p>NOTE: You should only call this method if the passed-in <code>javax.swing.text.View</code> * is an instance of {@link TokenOrientedView} and <code>javax.swing.text.TabExpander</code>; * otherwise, a <code>ClassCastException</code> could be thrown. * * @param pos the position to convert >= 0 * @param a the allocated region in which to render * @param direction the direction from the current position that can be thought of as the arrow * keys typically found on a keyboard. This will be one of the following values: * <ul> * <li>SwingConstants.WEST * <li>SwingConstants.EAST * <li>SwingConstants.NORTH * <li>SwingConstants.SOUTH * </ul> * * @return the location within the model that best represents the next location visual position * @exception BadLocationException * @exception IllegalArgumentException if <code>direction</code> doesn't have one of the legal * values above */ public static int getNextVisualPositionFrom( int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet, View view) throws BadLocationException { biasRet[0] = Position.Bias.Forward; // Do we want the "next position" above, below, to the left or right? switch (direction) { case NORTH: case SOUTH: if (pos == -1) { pos = (direction == NORTH) ? Math.max(0, view.getEndOffset() - 1) : view.getStartOffset(); break; } RSyntaxTextArea target = (RSyntaxTextArea) view.getContainer(); Caret c = (target != null) ? target.getCaret() : null; // YECK! Ideally, the x location from the magic caret // position would be passed in. Point mcp; if (c != null) mcp = c.getMagicCaretPosition(); else mcp = null; int x; if (mcp == null) { Rectangle loc = target.modelToView(pos); x = (loc == null) ? 0 : loc.x; } else { x = mcp.x; } if (direction == NORTH) pos = getPositionAbove(target, pos, x, (TabExpander) view); else pos = getPositionBelow(target, pos, x, (TabExpander) view); break; case WEST: if (pos == -1) pos = Math.max(0, view.getEndOffset() - 1); else pos = Math.max(0, pos - 1); break; case EAST: if (pos == -1) pos = view.getStartOffset(); else pos = Math.min(pos + 1, view.getDocument().getLength()); break; default: throw new IllegalArgumentException("Bad direction: " + direction); } return pos; }
/** * Returns the start of the word at the given offset. * * @param textArea The text area. * @param offs The offset into the text area's content. * @return The start offset of the word. * @throws BadLocationException If <code>offs</code> is invalid. * @see #getWordEnd(RSyntaxTextArea, int) */ public static int getWordStart(RSyntaxTextArea textArea, int offs) throws BadLocationException { Document doc = textArea.getDocument(); Element line = getLineElem(doc, offs); if (line == null) { throw new BadLocationException("No word at " + offs, offs); } int lineStart = line.getStartOffset(); if (offs == lineStart) { // Start of the line. return offs; } int endOffs = Math.min(offs + 1, doc.getLength()); String s = doc.getText(lineStart, endOffs - lineStart); if (s != null && s.length() > 0) { int i = s.length() - 1; char ch = s.charAt(i); if (Character.isWhitespace(ch)) { while (i > 0 && Character.isWhitespace(s.charAt(i - 1))) { i--; } offs = lineStart + i; } else if (Character.isLetterOrDigit(ch)) { while (i > 0 && Character.isLetterOrDigit(s.charAt(i - 1))) { i--; } offs = lineStart + i; } } return offs; }
/** * Returns the bounding box (in the current view) of a specified position in the model. This * method is designed for line-wrapped views to use, as it allows you to specify a "starting * position" in the line, from which the x-value is assumed to be zero. The idea is that you * specify the first character in a physical line as <code>p0</code>, as this is the character * where the x-pixel value is 0. * * @param textArea The text area containing the text. * @param s A segment in which to load the line. This is passed in so we don't have to reallocate * a new <code>Segment</code> for each call. * @param p0 The starting position in the physical line in the document. * @param p1 The position for which to get the bounding box in the view. * @param e How to expand tabs. * @param rect The rectangle whose x- and width-values are changed to represent the bounding box * of <code>p1</code>. This is reused to keep from needlessly reallocating Rectangles. * @param x0 The x-coordinate (pixel) marking the left-hand border of the text. This is useful if * the text area has a border, for example. * @return The bounding box in the view of the character <code>p1</code>. * @throws BadLocationException If <code>p0</code> or <code>p1</code> is not a valid location in * the specified text area's document. * @throws IllegalArgumentException If <code>p0</code> and <code>p1</code> are not on the same * line. */ public static Rectangle getLineWidthUpTo( RSyntaxTextArea textArea, Segment s, int p0, int p1, TabExpander e, Rectangle rect, int x0) throws BadLocationException { RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument(); // Ensure p0 and p1 are valid document positions. if (p0 < 0) throw new BadLocationException("Invalid document position", p0); else if (p1 > doc.getLength()) throw new BadLocationException("Invalid document position", p1); // Ensure p0 and p1 are in the same line, and get the start/end // offsets for that line. Element map = doc.getDefaultRootElement(); int lineNum = map.getElementIndex(p0); // We do ">1" because p1 might be the first position on the next line // or the last position on the previous one. // if (lineNum!=map.getElementIndex(p1)) if (Math.abs(lineNum - map.getElementIndex(p1)) > 1) throw new IllegalArgumentException( "p0 and p1 are not on the " + "same line (" + p0 + ", " + p1 + ")."); // Get the token list. Token t = doc.getTokenListForLine(lineNum); // Modify the token list 't' to begin at p0 (but still have correct // token types, etc.), and get the x-location (in pixels) of the // beginning of this new token list. makeTokenListStartAt(t, p0, e, textArea, 0); rect = t.listOffsetToView(textArea, e, p1, x0, rect); return rect; }
@Override public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, final int offs) { Token token = textArea.modelToToken(offs); if (token == null) { return null; } String reference = pdeKeywords.getReference(token.getLexeme()); if (reference != null || (token.getType() == TokenTypes.DATA_TYPE || token.getType() == TokenTypes.VARIABLE || token.getType() == TokenTypes.FUNCTION)) { return new LinkGeneratorResult() { @Override public int getSourceOffset() { return offs; } @Override public HyperlinkEvent execute() { LOG.fine("Open Reference: " + reference); Base.showReference("Reference/" + reference); return null; } }; } return null; }
private void changeStyleProgrammatically() { // Set the font for all token types. setFont(textArea, new Font("Courier New", Font.PLAIN, 12)); // Change a few things here and there. SyntaxScheme scheme = textArea.getSyntaxScheme(); scheme.getStyle(Token.RESERVED_WORD).background = Color.white; scheme.getStyle(Token.RESERVED_WORD).foreground = Color.MAGENTA.darker().darker(); scheme.getStyle(Token.DATA_TYPE).foreground = Color.blue; scheme.getStyle(Token.LITERAL_STRING_DOUBLE_QUOTE).underline = true; scheme.getStyle(Token.LITERAL_NUMBER_HEXADECIMAL).underline = true; scheme.getStyle(Token.LITERAL_NUMBER_HEXADECIMAL).background = Color.pink; scheme.getStyle(Token.COMMENT_EOL).font = new Font("Georgia", Font.ITALIC, 10); textArea.revalidate(); }
public void switchDocument(Document document, UndoManager newUndo) { // HACK: Dont discard changes on curret UndoManager. // BUG: https://github.com/bobbylight/RSyntaxTextArea/issues/84 setUndoManager(null); // bypass reset current undo manager... super.setDocument(document); setUndoManager((RUndoManager) newUndo); // HACK: Complement previous hack (hide code folding on switch) | Drawback: Lose folding state // if(sketch.getCodeCount() > 1 && textarea.isCodeFoldingEnabled()){ // textarea.setCodeFoldingEnabled(false); // textarea.setCodeFoldingEnabled(true); // } }
public void processKeyEvent(KeyEvent evt) { // this had to be added because the menu key events weren't making it up to the frame. switch (evt.getID()) { case KeyEvent.KEY_TYPED: if (editorListener != null) editorListener.keyTyped(evt); break; case KeyEvent.KEY_PRESSED: if (editorListener != null) editorListener.keyPressed(evt); break; case KeyEvent.KEY_RELEASED: // inputHandler.keyReleased(evt); break; } if (!evt.isConsumed()) { super.processKeyEvent(evt); } }
/** * ERROR (exceptions) WARN (when something happens that's not supposed to) INFO (wire output) * DEBUG (test/displaying intermediate values), TRACE (start/end method) */ public ConnectionConsoleWindow(ToolBar toolBar) { final ConnectionConsoleWindow thisConsole = this; this.toolBar = toolBar; java.net.URL url = ClassLoader.getSystemResource("ethereum-icon.png"); Toolkit kit = Toolkit.getDefaultToolkit(); Image img = kit.createImage(url); this.setIconImage(img); addCloseAction(); JPanel cp = new JPanel(new BorderLayout()); AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory) TokenMakerFactory.getDefaultInstance(); atmf.putMapping("text/console", "org.ethereum.gui.ConsoleTokenMaker"); textArea = new RSyntaxTextArea(16, 44); textArea.setSyntaxEditingStyle("text/console"); // textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_LISP); textArea.setCodeFoldingEnabled(true); textArea.setAntiAliasingEnabled(true); changeStyleProgrammatically(); RTextScrollPane sp = new RTextScrollPane(textArea); cp.add(sp); setContentPane(cp); setTitle("Connection Console"); // setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); setLocation(802, 460); if (CONFIG.peerDiscovery()) UIEthereumManager.ethereum.startPeerDiscovery(); Thread t = new Thread() { public void run() { UIEthereumManager.ethereum.connect( SystemProperties.CONFIG.activePeerIP(), SystemProperties.CONFIG.activePeerPort()); } }; UIEthereumManager.ethereum.addListener( new EthereumListenerAdapter() { @Override public void trace(final String output) { SwingUtilities.invokeLater( new Runnable() { public void run() { textArea.append(output); textArea.append("\n"); if (autoScroll) textArea.setCaretPosition(textArea.getText().length()); } }); } }); t.start(); }
public static int getMatchingBracketPosition(RSyntaxTextArea textArea) { try { // Actually position just BEFORE caret. int caretPosition = textArea.getCaretPosition() - 1; if (caretPosition > -1) { // Some variables that will be used later. Token token; Element map; int curLine; Element line; int start, end; RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument(); char bracket = doc.charAt(caretPosition); // First, see if the previous char was a bracket // ('{', '}', '(', ')', '[', ']'). // If it was, then make sure this bracket isn't sitting in // the middle of a comment or string. If it isn't, then // initialize some stuff so we can continue on. char bracketMatch; boolean goForward; switch (bracket) { case '{': case '(': case '[': // Ensure this bracket isn't in a comment. map = doc.getDefaultRootElement(); curLine = map.getElementIndex(caretPosition); line = map.getElement(curLine); start = line.getStartOffset(); end = line.getEndOffset(); token = doc.getTokenListForLine(curLine); token = RSyntaxUtilities.getTokenAtOffset(token, caretPosition); // All brackets are always returned as "separators." if (token.type != Token.SEPARATOR) { return -1; } bracketMatch = bracket == '{' ? '}' : (bracket == '(' ? ')' : ']'); goForward = true; break; case '}': case ')': case ']': // Ensure this bracket isn't in a comment. map = doc.getDefaultRootElement(); curLine = map.getElementIndex(caretPosition); line = map.getElement(curLine); start = line.getStartOffset(); end = line.getEndOffset(); token = doc.getTokenListForLine(curLine); token = RSyntaxUtilities.getTokenAtOffset(token, caretPosition); // All brackets are always returned as "separators." if (token.type != Token.SEPARATOR) { return -1; } bracketMatch = bracket == '}' ? '{' : (bracket == ')' ? '(' : '['); goForward = false; break; default: return -1; } if (goForward) { int lastLine = map.getElementCount(); // Start just after the found bracket since we're sure // we're not in a comment. start = caretPosition + 1; int numEmbedded = 0; boolean haveTokenList = false; while (true) { doc.getText(start, end - start, charSegment); int segOffset = charSegment.offset; for (int i = segOffset; i < segOffset + charSegment.count; i++) { char ch = charSegment.array[i]; if (ch == bracket) { if (haveTokenList == false) { token = doc.getTokenListForLine(curLine); haveTokenList = true; } int offset = start + (i - segOffset); token = RSyntaxUtilities.getTokenAtOffset(token, offset); if (token.type == Token.SEPARATOR) numEmbedded++; } else if (ch == bracketMatch) { if (haveTokenList == false) { token = doc.getTokenListForLine(curLine); haveTokenList = true; } int offset = start + (i - segOffset); token = RSyntaxUtilities.getTokenAtOffset(token, offset); if (token.type == Token.SEPARATOR) { if (numEmbedded == 0) return offset; numEmbedded--; } } } // End of for (int i=segOffset; i<segOffset+charSegment.count; i++). // Bail out if we've gone through all lines and // haven't found the match. if (++curLine == lastLine) return -1; // Otherwise, go through the next line. haveTokenList = false; line = map.getElement(curLine); start = line.getStartOffset(); end = line.getEndOffset(); } // End of while (true). } // End of if (goForward). // Otherwise, we're going backward through the file // (since we found '}', ')' or ']'). else { // goForward==false // End just before the found bracket since we're sure // we're not in a comment. end = caretPosition; // - 1; int numEmbedded = 0; boolean haveTokenList = false; Token t2; while (true) { doc.getText(start, end - start, charSegment); int segOffset = charSegment.offset; int iStart = segOffset + charSegment.count - 1; for (int i = iStart; i >= segOffset; i--) { char ch = charSegment.array[i]; if (ch == bracket) { if (haveTokenList == false) { token = doc.getTokenListForLine(curLine); haveTokenList = true; } int offset = start + (i - segOffset); t2 = RSyntaxUtilities.getTokenAtOffset(token, offset); if (t2.type == Token.SEPARATOR) numEmbedded++; } else if (ch == bracketMatch) { if (haveTokenList == false) { token = doc.getTokenListForLine(curLine); haveTokenList = true; } int offset = start + (i - segOffset); t2 = RSyntaxUtilities.getTokenAtOffset(token, offset); if (t2.type == Token.SEPARATOR) { if (numEmbedded == 0) return offset; numEmbedded--; } } } // End of for (int i=segOffset; i<segOffset+charSegment.count; i++). // Bail out if we've gone through all lines and // haven't found the match. if (--curLine == -1) return -1; // Otherwise, get ready for going through the // next line. haveTokenList = false; line = map.getElement(curLine); start = line.getStartOffset(); end = line.getEndOffset(); } // End of while (true). } // End of else. } // End of if (caretPosition>-1). } catch (BadLocationException ble) { // Shouldn't ever happen. ble.printStackTrace(); } // Something went wrong... return -1; }