public void addToUses(String strType, boolean bTemplate, boolean bProgram) { if (isTypeUsed(strType)) { return; } Document doc = _gsEditor.getEditor().getDocument(); int iPos = findUsesInsertionPosition(bProgram); int iIndex = doc.getDefaultRootElement().getElementIndex(iPos); int iInsertionPt; String strUsesStmt = Keyword.KW_uses + " " + strType; if (bTemplate) { strUsesStmt = "<% " + strUsesStmt + " %>"; } strUsesStmt += "\n"; if (iPos == 0) { iInsertionPt = iPos; if (!bTemplate) { strUsesStmt = strUsesStmt + "\n"; } } else { iInsertionPt = doc.getDefaultRootElement().getElement(iIndex).getEndOffset(); } try { doc.insertString(iInsertionPt, strUsesStmt, null); } catch (BadLocationException e) { throw new RuntimeException(e); } }
/** * Replace the path component under the caret with the file selected from the completion list. * * @param file the selected file. * @param caretPos * @param start the start offset of the path component under the caret. * @param end the end offset of the path component under the caret. * @throws BadLocationException */ private void replacePathComponent(LookupFile file, int caretPos, int start, int end) throws BadLocationException { final Document doc = myPathTextField.getDocument(); myPathTextField.setSelectionStart(0); myPathTextField.setSelectionEnd(0); final String name = file.getName(); boolean toRemoveExistingName; String prefix = ""; if (caretPos >= start) { prefix = doc.getText(start, caretPos - start); if (prefix.length() == 0) { prefix = doc.getText(start, end - start); } if (SystemInfo.isFileSystemCaseSensitive) { toRemoveExistingName = name.startsWith(prefix) && prefix.length() > 0; } else { toRemoveExistingName = name.toUpperCase().startsWith(prefix.toUpperCase()) && prefix.length() > 0; } } else { toRemoveExistingName = true; } int newPos; if (toRemoveExistingName) { doc.remove(start, end - start); doc.insertString(start, name, doc.getDefaultRootElement().getAttributes()); newPos = start + name.length(); } else { doc.insertString(caretPos, name, doc.getDefaultRootElement().getAttributes()); newPos = caretPos + name.length(); } if (file.isDirectory()) { if (!myFinder.getSeparator().equals(doc.getText(newPos, 1))) { doc.insertString( newPos, myFinder.getSeparator(), doc.getDefaultRootElement().getAttributes()); newPos++; } } if (newPos < doc.getLength()) { if (myFinder.getSeparator().equals(doc.getText(newPos, 1))) { newPos++; } } myPathTextField.setCaretPosition(newPos); }
/** * Attach a {@link Document} to enable line number tracking when editing. The position to track is * before the first non-whitespace character on the line. Edits happening before that position * will cause the line number to update accordingly. Multiple {@link #startTracking} calls will * replace the tracked document. Whoever wants a tracked line should track it and add itself as * listener if necessary. ({@link LineHighlight}, {@link LineBreakpoint}) * * @param doc the {@link Document} to use for line number tracking */ public synchronized void startTracking(Document doc) { // System.out.println("tracking: " + this); if (doc == null) { return; // null arg } if (doc == this.doc) { return; // already tracking that doc } try { Element line = doc.getDefaultRootElement().getElement(lineIdx); if (line == null) { return; // line doesn't exist } String lineText = doc.getText(line.getStartOffset(), line.getEndOffset() - line.getStartOffset()); // set tracking position at (=before) first non-white space character on line pos = doc.createPosition(line.getStartOffset() + nonWhiteSpaceOffset(lineText)); this.doc = doc; doc.addDocumentListener(this); } catch (BadLocationException ex) { Logger.getLogger(LineID.class.getName()).log(Level.SEVERE, null, ex); pos = null; this.doc = null; } }
private void analyseDocument(Document document, int lineNum, PythonIndentation indentationLogic) throws BadLocationException { Element map = document.getDefaultRootElement(); int endPos = map.getElement(lineNum).getEndOffset(); indentationLogic.reset(); indentationLogic.addText(document.getText(0, endPos)); }
/** return indent for nearest non-ws line */ private static int getIndent(final Document document, int elementIndex) throws BadLocationException { Element rootElement = document.getDefaultRootElement(); boolean isTextWSOnly; int eso = rootElement.getStartOffset(); boolean extendIndent = false; do { if (elementIndex < 1) { break; } Element element = rootElement.getElement(elementIndex--); eso = element.getStartOffset(); String elementText = document.getText(eso, element.getEndOffset() - eso); isTextWSOnly = elementText.matches("\\s+"); // NOI18N if (!isTextWSOnly) { final String ett = elementText.trim(); extendIndent = ett.endsWith("{") || ett.endsWith("["); // NOI18N } } while (isTextWSOnly); int indent = IndentUtils.lineIndent(document, eso); if (extendIndent) { indent += IndentUtils.tabSize(document); } return indent; }
// </editor-fold> // <editor-fold defaultstate="collapsed" desc="fill pane content"> @Override public void read(Reader in, Object desc) throws IOException { super.read(in, desc); Document doc = getDocument(); Element root = doc.getDefaultRootElement(); parse(root); setCaretPosition(0); }
private static final Element getLineElem(Document d, int offs) { Element map = d.getDefaultRootElement(); int index = map.getElementIndex(offs); Element elem = map.getElement(index); if ((offs >= elem.getStartOffset()) && (offs < elem.getEndOffset())) { return elem; } return null; }
/** * Gets the Line Number at the give position of the editor component. The first line number is * ZERO * * @return line number * @throws javax.swing.text.BadLocationException */ public static int getLineNumber(JTextComponent editor, int pos) throws BadLocationException { if (getSyntaxDocument(editor) != null) { SyntaxDocument sdoc = getSyntaxDocument(editor); return sdoc.getLineNumberAt(pos); } else { Document doc = editor.getDocument(); return doc.getDefaultRootElement().getElementIndex(pos); } }
private void removeLines(DocumentEvent e) { // The root Element of the Document will tell us the total number // of line in the Document. Document document = e.getDocument(); Element root = document.getDefaultRootElement(); while (root.getElementCount() > maximumLines) { if (isRemoveFromStart) { removeFromStart(document, root); } else { removeFromEnd(document, root); } } }
private void doError(SAXParseException e, ParserNotice.Level level) { int line = e.getLineNumber() - 1; Element root = doc.getDefaultRootElement(); Element elem = root.getElement(line); int offs = elem.getStartOffset(); int len = elem.getEndOffset() - offs; if (line == root.getElementCount() - 1) { len++; } DefaultParserNotice pn = new DefaultParserNotice(XmlParser.this, e.getMessage(), line, offs, len); pn.setLevel(level); result.addNotice(pn); }
/** * DOCUMENT ME! * * @param lineNumber DOCUMENT ME! * @return DOCUMENT ME! */ private Element init(int lineNumber) { Document doc = buffer.getDocument(); Element line = doc.getDefaultRootElement().getElement(lineNumber); try { int options = Pattern.DOTALL; String find = PreferenceManager.getString("snr.find", ""); if ((find != null) && !find.equals("")) { if (PreferenceManager.getBoolean("snr.case", false)) { find = find.toLowerCase(); options |= Pattern.CASE_INSENSITIVE; } if (PreferenceManager.getBoolean("snr.whole", false)) { find = "\\b" + find + "\\b"; } int offset = line.getStartOffset(); int length = line.getEndOffset() - offset; if (PreferenceManager.getInt("snr.direction", FORWARD) == FORWARD) { if ((buffer.getSelectionEnd() > line.getStartOffset()) && (buffer.getSelectionEnd() <= line.getEndOffset())) { offset = buffer.getSelectionEnd(); length = line.getEndOffset() - offset; } } else { if ((buffer.getSelectionStart() > line.getStartOffset()) && (buffer.getSelectionStart() <= line.getEndOffset())) { length = buffer.getSelectionStart() - offset; } } String text = doc.getText(offset, length); Pattern pattern = Pattern.compile(find, options); this.matcher = pattern.matcher(text); } } catch (BadLocationException e) { log.error(e.getMessage(), e); } return line; }
public Object convert(final ReportElement source, final Object value) { try { final Document doc = RichTextConverterUtilities.parseDocument(editorKit, value); if (doc == null) { return value; } final Element element = process(doc.getDefaultRootElement()); final Band band = RichTextConverterUtilities.convertToBand(StyleKey.getDefinedStyleKeys(), source, element); band.getStyle().setStyleProperty(BandStyleKeys.LAYOUT, "inline"); return band; } catch (Exception e) { return value; } }
private String addWhiteSpace(Document doc, int offset) throws BadLocationException { StringBuilder whiteSpace = new StringBuilder("\n"); Element rootElement = doc.getDefaultRootElement(); int line = rootElement.getElementIndex(offset); int i = rootElement.getElement(line).getStartOffset(); while (true) { String temp = doc.getText(i, 1); if (temp.equals(" ") || temp.equals("\t")) { whiteSpace.append(temp); i++; } else break; } return whiteSpace.toString(); }
private void checkCompletion(java.awt.event.KeyEvent ke) throws BadLocationException { Document doc = getDocument(); Element root = doc.getDefaultRootElement(); int pos = getCaretPosition(); int lineIdx = root.getElementIndex(pos); Element line = root.getElement(lineIdx); int start = line.getStartOffset(), len = line.getEndOffset() - start; String strLine = doc.getText(start, len - 1); Debug.log(9, "[" + strLine + "]"); if (strLine.endsWith("find") && ke.getKeyChar() == '(') { ke.consume(); doc.insertString(pos, "(", null); ButtonCapture btnCapture = new ButtonCapture(this, line); insertComponent(btnCapture); doc.insertString(pos + 2, ")", null); } }
/** Update the tracked position. Will notify listeners if line number has changed. */ protected synchronized void updatePosition() { if (doc != null && pos != null) { // track position int offset = pos.getOffset(); int oldLineIdx = lineIdx; lineIdx = doc.getDefaultRootElement().getElementIndex(offset); // offset to lineNo if (lineIdx != oldLineIdx) { for (LineListener l : listeners) { if (l != null) { l.lineChanged(this, oldLineIdx, lineIdx); } else { listeners.remove(l); // remove null listener } } } } }
public void actionPerformed(JTextComponent text) { indentationLogic = ((EditorPane) text).getIndentationLogic(); boolean indentError = false; Document doc = text.getDocument(); Element map = doc.getDefaultRootElement(); String tabWhitespace = PreferencesUser.getInstance().getTabWhitespace(); Caret c = text.getCaret(); int dot = c.getDot(); int mark = c.getMark(); int dotLine = map.getElementIndex(dot); int markLine = map.getElementIndex(mark); if (dotLine != markLine) { int first = Math.min(dotLine, markLine); int last = Math.max(dotLine, markLine); Element elem; int start; try { for (int i = first; i < last; i++) { elem = map.getElement(i); start = elem.getStartOffset(); doc.insertString(start, tabWhitespace, null); } elem = map.getElement(last); start = elem.getStartOffset(); if (Math.max(c.getDot(), c.getMark()) != start) { doc.insertString(start, tabWhitespace, null); } } catch (BadLocationException ble) { Debug.error(me + "Problem while indenting line\n%s", ble.getMessage()); UIManager.getLookAndFeel().provideErrorFeedback(text); } } else { text.replaceSelection(tabWhitespace); } }
/** * 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. */ 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()); // Initialize our static variables (these are used by our tab expander below). tabSizeInSpaces = tabSize; fm = g.getFontMetrics(); int fontHeight = fm.getHeight(); final int LINE_LENGTH_IN_PIXELS = (int) pageFormat.getImageableWidth(); final int MAX_LINES_PER_PAGE = (int) pageFormat.getImageableHeight() / fontHeight; final int STARTING_LINE_NUMBER = MAX_LINES_PER_PAGE * pageIndex; // Create our tab expander. RPrintTabExpander tabExpander = new RPrintTabExpander(); // The (x,y) coordinate to print at (in pixels, not characters). // Since y is the baseline of where we'll start printing (not the top-left // corner), we offset it by the font's ascent ( + 1 just for good measure). xOffset = (int) pageFormat.getImageableX(); int y = (int) pageFormat.getImageableY() + fm.getAscent() + 1; // A counter to keep track of the number of lines that WOULD HAVE been // printed if we were printing all lines. int numPrintedLines = 0; // Keep going while there are more lines in the document. Document doc = textComponent.getDocument(); rootElement = doc.getDefaultRootElement(); numDocLines = rootElement.getElementCount(); // The number of lines in our document. currentDocLineNumber = 0; // The line number of the document we're currently on. int startingOffset = 0; // Used when a line is so long it has to be wrapped. while (currentDocLineNumber < numDocLines) { Segment currentLineSeg = new Segment(); // Get the current line (as an Element), and its starting and ending offset in doc. Element currentLine = rootElement.getElement(currentDocLineNumber); int currentLineStart = currentLine.getStartOffset(); int currentLineEnd = currentLine.getEndOffset(); // Put the chars of this line in currentLineSeg, but only starting at our desired offset // (because this line may be the second part of a wrapped line, so we'd start after the part // that has already been printed). try { 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; } // Remove any spaces and/or tabs from the end of the segment (would cause problems if you left // 'em). currentLineSeg = removeEndingWhitespace(currentLineSeg); // Figger out how long the line is, in pixels. int currentLineLengthInPixels = Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0); // System.err.println("'" + currentLineSeg + "' - " + currentLineLengthInPixels + "/" + // LINE_LENGTH_IN_PIXELS); // If it'll fit by itself on a printed line, great. if (currentLineLengthInPixels <= LINE_LENGTH_IN_PIXELS) { currentDocLineNumber += 1; // We (will) have printed one more line from the document. startingOffset = 0; // Start at the first character in the new document line. } // If it won't fit on a printed line by itself (i.e., it needs to be wrapped)... else { // Loop while the current line is too long to fit on a printed line. int currentPos = -1; while (currentLineLengthInPixels > LINE_LENGTH_IN_PIXELS) { // System.err.println("'" + currentLineSeg + "' - " + currentLineLengthInPixels + "/" + // LINE_LENGTH_IN_PIXELS); // Remove any spaces and/or tabs from the end of the segment (would cause problems if you // left 'em). currentLineSeg = removeEndingWhitespace(currentLineSeg); // currentPos will be the last position in the current text of a "line break character." currentPos = -1; String currentLineString = currentLineSeg.toString(); for (int i = 0; i < breakChars.length; i++) { // "+1" below so we include the character on the line. int pos = currentLineString.lastIndexOf(breakChars[i]) + 1; // if (pos>-1 && pos>currentPos) // currentPos = pos; if (pos > 0 && pos > currentPos & pos != currentLineString.length()) currentPos = pos; } // If we didn't find a line break character, we'll simply break the line at // the last character that fits on a printed line. // So here, we set currentPos to be the position of the last character that fits // on the current printed line. if (currentPos == -1) { // Fix currentLineSeg so that it contains exactly enough text to fit in // LINE_LENGTH_IN_PIXELS pixels... currentPos = 0; do { currentPos++; try { doc.getText(currentLineStart + startingOffset, currentPos, currentLineSeg); } catch (BadLocationException ble) { System.err.println(ble); return Printable.NO_SUCH_PAGE; } currentLineLengthInPixels = Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0); } while (currentLineLengthInPixels <= LINE_LENGTH_IN_PIXELS); currentPos--; } try { 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( "==> Range: " + (currentLineStart + startingOffset) + " - " + (currentLineStart + startingOffset + currentPos)); ble.printStackTrace(); return Printable.NO_SUCH_PAGE; } currentLineLengthInPixels = Utilities.getTabbedTextWidth(currentLineSeg, fm, 0, tabExpander, 0); } // End of while (currentLineLengthInPixels > LINE_LENGTH_IN_PIXELS). startingOffset += currentPos; // Where to start (offset from line's start), since this line wraps. } // End of else. numPrintedLines++; if (numPrintedLines > STARTING_LINE_NUMBER) { // g.drawString(currentLineSeg.toString(), xOffset,y); Utilities.drawTabbedText(currentLineSeg, xOffset, y, g, tabExpander, 0); y += fontHeight; if (numPrintedLines == STARTING_LINE_NUMBER + MAX_LINES_PER_PAGE) return Printable.PAGE_EXISTS; } } // Now, the whole document has been "printed." Decide if this page had any text on it or not. if (numPrintedLines > STARTING_LINE_NUMBER) return Printable.PAGE_EXISTS; return Printable.NO_SUCH_PAGE; }
public synchronized Element insertLine( String command, boolean replaceLast, boolean insertPrecedingWait, boolean removePrecedingWait) { // System.out.println("insertLine(\"" + command + "\")"); EditorPnl editor = getEditorPnl(); if (editor != null) { try { Document doc = editor.getEditor().getDocument(); int caretPos = editor.getEditor().getCaretPosition(); // System.out.println(" -->Initial caret position: " + caretPos); int elemIndex = doc.getDefaultRootElement().getElementIndex(caretPos); boolean insertNewLine = true; Element ce = doc.getDefaultRootElement().getElement(elemIndex); String txt = DocumentUtils.getElementText(ce).trim(); if (!replaceLast && caretPos == 0 && elemIndex == 0 && !"".equals(txt)) { doc.insertString(0, "\n", null); txt = ""; insertNewLine = false; } // The following code finds out if we are in an empty line or not. // If the current line contains some text, a new line is inserted // and the caret is moved there. if (!txt.equals("")) { Element next = doc.getDefaultRootElement().getElement(elemIndex + 1); if (next == null || !DocumentUtils.getElementText(next).trim().equals("")) { // DocumentUtils.analyzeEditorDocument(editor.getEditor(), // false); // System.out.println("Inserting an empty line to offset " + // ce.getEndOffset()); doc.insertString(ce.getEndOffset() - 1, "\n", null); // DocumentUtils.analyzeEditorDocument(editor.getEditor(), // false); next = doc.getDefaultRootElement() .getElement(doc.getDefaultRootElement().getElementIndex(ce.getEndOffset() + 1)); } // caretPos = next.getEndOffset()-1; caretPos = ce.getEndOffset(); // System.out.println("Setting caret position to "+caretPos); // System.out.println(" -->1. Setting caret position to: " + // caretPos); editor.getEditor().setCaretPosition(caretPos); } Element e = DocumentUtils.getCommandElementPriorTo(doc, caretPos); // System.out.println(" --> Element prior: " + // DocumentUtils.getElementText(e)); // First look if we should insert a Wait command if (!replaceLast && (insertPrecedingWait || removePrecedingWait) && (!firstRecord && !removePrecedingWait) && e != null) { String prevCmd = DocumentUtils.getElementText(e); int pos = prevCmd.indexOf(" "); String cmd = pos >= 0 ? prevCmd.substring(0, pos) : prevCmd; String time = convertTime(System.currentTimeMillis() - lastInsertTime); CommandHandler h = (CommandHandler) scriptManager.getCommandHandlers().get(cmd.toUpperCase()); if (!"waitfor".equalsIgnoreCase(cmd) && !"screenshot".equalsIgnoreCase(cmd)) { if (h != null && h.getContextAttributes() != null && h.getContextAttributes().containsKey("wait")) { doc.remove(e.getStartOffset(), prevCmd.length()); String replaceStr = insertPrecedingWait ? " wait=" + time : ""; String s = prevCmd .replaceAll("\\n", "") .replaceAll("\\swait=[\"]*[0-9]*[sSmMhHdD]*[\"]*", "") + replaceStr; doc.insertString(e.getStartOffset(), s, null); caretPos = e.getEndOffset(); // System.out.println(" -->2. Setting caret position to: " // + caretPos); } else { String waitCmd = "Wait " + time + '\n'; doc.insertString(caretPos, waitCmd, null); caretPos += waitCmd.length(); // System.out.println(" -->3. Setting caret position to: " // + caretPos); } } } firstRecord = false; if (replaceLast && e != null) { int length = e.getEndOffset() - e.getStartOffset(); doc.remove(e.getStartOffset(), length); caretPos = e.getStartOffset(); } command = insertNewLine && !replaceLast ? command + "\n" : command; doc.insertString(caretPos, command, null); editor.getEditor().setCaretPosition(caretPos + 1); // System.out.println(" --> Inserted, caretPos = " + // editor.getEditor().getCaretPosition()); // DocumentUtils.analyzeEditorDocument(editor.getEditor(), true); lastElement = doc.getDefaultRootElement() .getElement(doc.getDefaultRootElement().getElementIndex(caretPos)); lastInsertTime = System.currentTimeMillis(); filterRfbEvents(); } catch (Exception ex) { ex.printStackTrace(); } } return lastElement; }
/** * Paints folding icons when line wrapping is enabled. * * @param g The graphics context. */ private void paintComponentWrapped(Graphics g) { // The variables we use are as follows: // - visibleRect is the "visible" area of the text area; e.g. // [0,100, 300,100+(lineCount*cellHeight)-1]. // actualTop.y is the topmost-pixel in the first logical line we // paint. Note that we may well not paint this part of the logical // line, as it may be broken into many physical lines, with the first // few physical lines scrolled past. Note also that this is NOT the // visible rect of this line number list; this line number list has // visible rect == [0,0, insets.left-1,visibleRect.height-1]. // - offset (<=0) is the y-coordinate at which we begin painting when // we begin painting with the first logical line. This can be // negative, signifying that we've scrolled past the actual topmost // part of this line. // The algorithm is as follows: // - Get the starting y-coordinate at which to paint. This may be // above the first visible y-coordinate as we're in line-wrapping // mode, but we always paint entire logical lines. // - Paint that line's indicator, if appropriate. Increment y to be // just below the are we just painted (i.e., the beginning of the // next logical line's view area). // - Get the ending visual position for that line. We can now loop // back, paint this line, and continue until our y-coordinate is // past the last visible y-value. // We avoid using modelToView/viewToModel where possible, as these // methods trigger a parsing of the line into syntax tokens, which is // costly. It's cheaper to just grab the child views' bounds. // Some variables we'll be using. int width = getWidth(); RTextAreaUI ui = (RTextAreaUI) textArea.getUI(); View v = ui.getRootView(textArea).getView(0); Document doc = textArea.getDocument(); Element root = doc.getDefaultRootElement(); int topPosition = textArea.viewToModel(new Point(visibleRect.x, visibleRect.y)); int topLine = root.getElementIndex(topPosition); int cellHeight = textArea.getLineHeight(); FoldManager fm = ((RSyntaxTextArea) textArea).getFoldManager(); // Compute the y at which to begin painting text, taking into account // that 1 logical line => at least 1 physical line, so it may be that // y<0. The computed y-value is the y-value of the top of the first // (possibly) partially-visible view. Rectangle visibleEditorRect = ui.getVisibleEditorRect(); Rectangle r = LineNumberList.getChildViewBounds(v, topLine, visibleEditorRect); int y = r.y; y += (cellHeight - collapsedFoldIcon.getIconHeight()) / 2; int visibleBottom = visibleRect.y + visibleRect.height; int x = width - 10; int line = topLine; boolean paintingOutlineLine = foldWithOutlineShowing != null && foldWithOutlineShowing.containsLine(line); int lineCount = root.getElementCount(); while (y < visibleBottom && line < lineCount) { int curLineH = LineNumberList.getChildViewBounds(v, line, visibleEditorRect).height; if (paintingOutlineLine) { g.setColor(getForeground()); int w2 = width / 2; if (line == foldWithOutlineShowing.getEndLine()) { int y2 = y + curLineH - cellHeight / 2; g.drawLine(w2, y, w2, y2); g.drawLine(w2, y2, width - 2, y2); paintingOutlineLine = false; } else { g.drawLine(w2, y, w2, y + curLineH); } } Fold fold = fm.getFoldForLine(line); if (fold != null) { if (fold == foldWithOutlineShowing && !fold.isCollapsed()) { g.setColor(getForeground()); int w2 = width / 2; g.drawLine(w2, y + cellHeight / 2, w2, y + curLineH); paintingOutlineLine = true; } if (fold.isCollapsed()) { collapsedFoldIcon.paintIcon(this, g, x, y); y += LineNumberList.getChildViewBounds(v, line, visibleEditorRect).height; line += fold.getLineCount() + 1; } else { expandedFoldIcon.paintIcon(this, g, x, y); y += curLineH; line++; } } else { y += curLineH; line++; } } }
/** * 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. * * @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) { g.setColor(Color.BLACK); g.setFont(new Font("Monospaced", Font.PLAIN, fontSize)); // Initialize our static variables (these are used by our tab expander below). tabSizeInSpaces = tabSize; fm = g.getFontMetrics(); // Create our tab expander. // RPrintTabExpander tabExpander = new RPrintTabExpander(); // Get width and height of characters in this monospaced font. int fontWidth = fm.charWidth('w'); // Any character will do as font is monospaced. int fontHeight = fm.getHeight(); int MAX_CHARS_PER_LINE = (int) pageFormat.getImageableWidth() / fontWidth; int MAX_LINES_PER_PAGE = (int) pageFormat.getImageableHeight() / fontHeight; final int STARTING_LINE_NUMBER = MAX_LINES_PER_PAGE * pageIndex; // The (x,y) coordinate to print at (in pixels, not characters). // Since y is the baseline of where we'll start printing (not the top-left // corner), we offset it by the font's ascent ( + 1 just for good measure). xOffset = (int) pageFormat.getImageableX(); int y = (int) pageFormat.getImageableY() + fm.getAscent() + 1; // A counter to keep track of the number of lines that WOULD HAVE been // printed if we were printing all lines. int numPrintedLines = 0; // Keep going while there are more lines in the document. currentDocLineNumber = 0; // The line number of the document we're currently on. rootElement = doc.getDefaultRootElement(); // To shorten accesses in our loop. numDocLines = rootElement.getElementCount(); // The number of lines in our document. while (currentDocLineNumber < numDocLines) { // Get the line we are going to print. String curLineString; Element currentLine = rootElement.getElement(currentDocLineNumber); int startOffs = currentLine.getStartOffset(); try { curLineString = doc.getText(startOffs, currentLine.getEndOffset() - startOffs); } catch (BadLocationException ble) { // Never happens ble.printStackTrace(); return Printable.NO_SUCH_PAGE; } // Get rid of newlines, because they end up as boxes if you don't; this is a monospaced font. curLineString = curLineString.replaceAll("\n", ""); // Replace tabs with how many spaces they should be. if (tabSizeInSpaces == 0) { curLineString = curLineString.replaceAll("\t", ""); } else { int tabIndex = curLineString.indexOf('\t'); while (tabIndex > -1) { int spacesNeeded = tabSizeInSpaces - (tabIndex % tabSizeInSpaces); String replacementString = ""; for (int i = 0; i < spacesNeeded; i++) replacementString += ' '; // Note that "\t" is actually a regex for this method. curLineString = curLineString.replaceFirst("\t", replacementString); tabIndex = curLineString.indexOf('\t'); } } // If this document line is too long to fit on one printed line on the page, // break it up into multpile lines. while (curLineString.length() > MAX_CHARS_PER_LINE) { numPrintedLines++; if (numPrintedLines > STARTING_LINE_NUMBER) { g.drawString(curLineString.substring(0, MAX_CHARS_PER_LINE), xOffset, y); y += fontHeight; if (numPrintedLines == STARTING_LINE_NUMBER + MAX_LINES_PER_PAGE) return Printable.PAGE_EXISTS; } curLineString = curLineString.substring(MAX_CHARS_PER_LINE, curLineString.length()); } currentDocLineNumber += 1; // We have printed one more line from the document. numPrintedLines++; if (numPrintedLines > STARTING_LINE_NUMBER) { g.drawString(curLineString, xOffset, y); y += fontHeight; if (numPrintedLines == STARTING_LINE_NUMBER + MAX_LINES_PER_PAGE) return Printable.PAGE_EXISTS; } } // Now, the whole document has been "printed." Decide if this page had any text on it or not. if (numPrintedLines > STARTING_LINE_NUMBER) return Printable.PAGE_EXISTS; return Printable.NO_SUCH_PAGE; }
@Override public void setDocument(Document doc) { this.doc = doc; this.elem = doc.getDefaultRootElement(); }
@Override protected int drawUnselectedText(java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException { Document doc = getDocument(); Segment segment = new Segment(); Segment token = getLineBuffer(); doc.getText(p0, p1 - p0, segment); int count = p1 - p0; int left = 0; int state = TEXT; int elementIndex = doc.getDefaultRootElement().getElementIndex(p0); AttributeSet lineAttributes = doc.getDefaultRootElement().getElement(elementIndex).getAttributes(); if (lineAttributes.isDefined("inComment")) { state = MULTILINECOMMENT; } for (int i = 0; i < count; i++) { // Starting in default text state. if (state == TEXT) { if (Character.isLetter(segment.array[i + segment.offset]) && Character.isLowerCase(segment.array[i + segment.offset])) { // flush now g.setColor(textColor); doc.getText(p0 + left, i - left, token); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = KEYWORD; } // Do nothing else { if (segment.array[i + segment.offset] == '/') { // flush now g.setColor(textColor); doc.getText(p0 + left, i - left, token); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = COMMENT; } else if (segment.array[i + segment.offset] == '"') { // flush now g.setColor(textColor); doc.getText(p0 + left, i - left, token); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = STRING; } } } else if (state == KEYWORD) { // Still if (Character.isLetter( segment .array[ i + segment .offset])) { // && Character.isLowerCase(segment.array[i+segment.offset])) } else { // flush now doc.getText(p0 + left, i - left, token); if (Keywords.isKeyword(token)) { g.setColor(keywordColor); } else { g.setColor(textColor); } x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i; state = TEXT; if (segment.array[i + segment.offset] == '/') { state = COMMENT; } else if (segment.array[i + segment.offset] == '"') { state = STRING; } } } else if (state == COMMENT) { if (segment.array[i + segment.offset] == '/') { break; } else if (segment.array[i + segment.offset] == '*') { state = MULTILINECOMMENT; } else { state = TEXT; } } else if (state == MULTILINECOMMENT) { if (i > 0 && segment.array[i + segment.offset] == '/' && segment.array[i + segment.offset - 1] == '*') { // flush now doc.getText(p0 + left, i + 1 - left, token); g.setColor(commentColor); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i + 1; state = TEXT; } } else if (state == STRING) { if (segment.array[i + segment.offset] == '"') { // flush now doc.getText(p0 + left, i + 1 - left, token); g.setColor(stringColor); x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); left = i + 1; state = TEXT; } } // Starting not in token } // end loop // Flush last doc.getText(p0 + left, p1 - p0 - left, token); if (state == KEYWORD) { if (Keywords.isKeyword(token)) { g.setColor(keywordColor); } else { g.setColor(textColor); } } else if (state == STRING) { g.setColor(stringColor); } else if (state == COMMENT && ((p1 - p0 - left) > 1)) { g.setColor(commentColor); } else if (state == MULTILINECOMMENT) { g.setColor(commentColor); } else { g.setColor(textColor); } x = Utilities.drawTabbedText(token, x, y, g, this, p0 + left); return x; }