/* * @(#)JEditorArea.java * * Copyright (c) 2006 The authors and contributors of JHotDraw. * You may not use, copy or modify this file, except in compliance with the * accompanying license terms. */ package org.jhotdraw.samples.teddy; import javax.swing.*; import javax.swing.text.*; /** * A happy marriage between JTextArea and JEditorPane. * * @author Werner Randelshofer * @version $Id$ */ public class JEditorArea extends JEditorPane { private static final long serialVersionUID = 1L; private boolean wrap; /** Creates a new instance. */ public JEditorArea() { setEditorKit(new StyledEditorKit()); initComponents(); } public StyledEditorKit getStyledEditorKit() { return (StyledEditorKit) getEditorKit(); } /** * Sets the line-wrapping policy of the text area. If set * to true the lines will be wrapped if they are too long * to fit within the allocated width. If set to false, * the lines will always be unwrapped. A {@code PropertyChange} * event ("lineWrap") is fired when the policy is changed. * By default this property is false. * * @param newValue indicates if lines should be wrapped * @see #getLineWrap */ public void setLineWrap(boolean newValue) { boolean oldValue = wrap; if (oldValue != newValue) { this.wrap = newValue; firePropertyChange("lineWrap", oldValue, newValue); rebuildView(); } } /** * Gets the line-wrapping policy of the text area. If set * to true the lines will be wrapped if they are too long * to fit within the allocated width. If set to false, * the lines will always be unwrapped. * * @return if lines will be wrapped */ public boolean getLineWrap() { return wrap; } /** * Returns true if a viewport should always force the width of this * Scrollable to match the width of the viewport. This is implemented * to return true if the line wrapping policy is true, and false * if lines are not being wrapped. * * @return true if a viewport should force the Scrollables width * to match its own. */ @Override public boolean getScrollableTracksViewportWidth() { return wrap; } public void rebuildView() { revalidate(); repaint(); } /** * Replaces text from the indicated start to end position with the * new text specified. Does nothing if the model is null. Simply * does a delete if the new string is null or empty. * <p> * This method is thread safe, although most Swing methods * are not. Please see * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads * and Swing</A> for more information. * * @param str the text to use as the replacement * @param start the start position >= 0 * @param end the end position >= start * @exception IllegalArgumentException if part of the range is an * invalid position in the model */ public void replaceRange(String str, int start, int end) { if (end < start) { throw new IllegalArgumentException("end before start"); } Document doc = getDocument(); if (doc != null) { try { if (doc instanceof AbstractDocument) { ((AbstractDocument)doc).replace(start, end - start, str, null); } else { doc.remove(start, end - start); doc.insertString(start, str, null); } } catch (BadLocationException e) { throw new IllegalArgumentException(e.getMessage()); } } } /** * Translates an offset into the components text to a * line number. * * @param offset the offset >= 0 * @return the line number >= 0 * @exception BadLocationException thrown if the offset is * less than zero or greater than the document length. */ public int getLineOfOffset(int offset) throws BadLocationException { Document doc = getDocument(); if (offset < 0) { throw new BadLocationException("Can't translate offset to line", -1); } else if (offset > doc.getLength()) { throw new BadLocationException("Can't translate offset to line", doc.getLength()+1); } else { Element map = getDocument().getDefaultRootElement(); return map.getElementIndex(offset); } } /** * Determines the offset of the start of the given line. * * @param line the line number to translate >= 0 * @return the offset >= 0 * @exception BadLocationException thrown if the line is * less than zero or greater or equal to the number of * lines contained in the document (as reported by * getLineCount). */ public int getLineStartOffset(int line) throws BadLocationException { Document doc = getDocument(); Element map = doc.getDefaultRootElement(); int lineCount = map.getElementCount(); //int lineCount = getLineCount(); if (line < 0) { throw new BadLocationException("Negative line", -1); } else if (line >= lineCount) { throw new BadLocationException("No such line", doc.getLength()+1); } else { Element lineElem = map.getElement(line); return lineElem.getStartOffset(); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents private void initComponents() { } // </editor-fold>//GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables // End of variables declaration//GEN-END:variables }