Merge from the pain train
[official-gcc.git] / libjava / javax / swing / JTextArea.java
blob3510e6dead69b0eedda705544dea2f144189dc4c
1 /* JTextArea.java --
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import java.awt.FontMetrics;
43 import javax.swing.text.BadLocationException;
44 import javax.swing.text.Document;
45 import javax.swing.text.Element;
46 import javax.swing.text.JTextComponent;
47 import javax.swing.text.PlainDocument;
49 /**
50 * The <code>JTextArea</code> component provides a multi-line area for displaying
51 * and editing plain text. The component is designed to act as a lightweight
52 * replacement for the heavyweight <code>java.awt.TextArea</code> component,
53 * which provides similar functionality using native widgets.
54 * <p>
56 * This component has additional functionality to the AWT class. It follows
57 * the same design pattern as seen in other text components, such as
58 * <code>JTextField</code>, <code>JTextPane</code> and <code>JEditorPane</code>,
59 * and embodied in <code>JTextComponent</code>. These classes separate the text
60 * (the model) from its appearance within the onscreen component (the view). The
61 * text is held within a <code>javax.swing.text.Document</code> object, which can
62 * also maintain relevant style information where necessary. As a result, it is the
63 * document that should be monitored for textual changes, via
64 * <code>DocumentEvent</code>s delivered to registered
65 * <code>DocumentListener</code>s, rather than this component.
66 * <p>
68 * Unlike <code>java.awt.TextArea</code>, <code>JTextArea</code> does not
69 * handle scrolling. Instead, this functionality is delegated to a
70 * <code>JScrollPane</code>, which can contain the text area and handle
71 * scrolling when required. Likewise, the word wrapping functionality
72 * of the AWT component is converted to a property of this component
73 * and the <code>rows</code> and <code>columns</code> properties
74 * are used in calculating the preferred size of the scroll pane's
75 * view port.
77 * @author Michael Koch (konqueror@gmx.de)
78 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
79 * @see java.awt.TextArea
80 * @see javax.swing.JTextComponent
81 * @see javax.swing.JTextField
82 * @see javax.swing.JTextPane
83 * @see javax.swing.JEditorPane
84 * @see javax.swing.text.Document
85 * @see javax.swing.text.DocumentEvent
86 * @see javax.swing.text.DocumentListener
89 public class JTextArea extends JTextComponent
91 /**
92 * Compatible with Sun's JDK
94 private static final long serialVersionUID = -6141680179310439825L;
96 /**
97 * The number of rows used by the component.
99 private int rows;
102 * The number of columns used by the component.
104 private int columns;
107 * Whether line wrapping is enabled or not.
109 private boolean lineWrap;
112 * The number of characters equal to a tab within the text.
114 private int tabSize = 8;
116 private boolean wrapStyleWord;
119 * Creates a new <code>JTextArea</code> object.
121 public JTextArea()
123 this(null, null, 0, 0);
127 * Creates a new <code>JTextArea</code> object.
129 * @param text the initial text
131 public JTextArea(String text)
133 this(null, text, 0, 0);
137 * Creates a new <code>JTextArea</code> object.
139 * @param rows the number of rows
140 * @param columns the number of cols
142 * @exception IllegalArgumentException if rows or columns are negative
144 public JTextArea(int rows, int columns)
146 this(null, null, rows, columns);
150 * Creates a new <code>JTextArea</code> object.
152 * @param text the initial text
153 * @param rows the number of rows
154 * @param columns the number of cols
156 * @exception IllegalArgumentException if rows or columns are negative
158 public JTextArea(String text, int rows, int columns)
160 this(null, text, rows, columns);
164 * Creates a new <code>JTextArea</code> object.
166 * @param the document model to use
168 public JTextArea(Document doc)
170 this(doc, null, 0, 0);
174 * Creates a new <code>JTextArea</code> object.
176 * @param the document model to use
177 * @param text the initial text
178 * @param rows the number of rows
179 * @param columns the number of cols
181 * @exception IllegalArgumentException if rows or columns are negative
183 public JTextArea(Document doc, String text, int rows, int columns)
185 setDocument(doc == null ? createDefaultModel() : doc);
186 setText(text);
187 setRows(rows);
188 setColumns(columns);
192 * Appends the supplied text to the current contents
193 * of the document model.
195 * @param toAppend the text to append
197 public void append(String toAppend)
201 getDocument().insertString(getText().length(), toAppend, null);
203 catch (BadLocationException exception)
205 /* This shouldn't happen in theory -- but, if it does... */
206 throw new RuntimeException("Unexpected exception occurred.", exception);
211 * Creates the default document model.
213 * @return a new default model
215 protected Document createDefaultModel()
217 return new PlainDocument();
221 * Returns true if the width of this component should be forced
222 * to match the width of a surrounding view port. When line wrapping
223 * is turned on, this method returns true.
225 * @return true if lines are wrapped.
227 public boolean getScrollableTracksViewportWidth()
229 return lineWrap ? true : super.getScrollableTracksViewportWidth();
233 * Returns the UI class ID string.
235 * @return the string "TextAreaUI"
237 public String getUIClassID()
239 return "TextAreaUI";
243 * Returns the current number of columns.
245 * @return number of columns
247 public int getColumns()
249 return columns;
253 * Sets the number of rows.
255 * @param columns number of columns
257 * @exception IllegalArgumentException if columns is negative
259 public void setColumns(int columns)
261 if (columns < 0)
262 throw new IllegalArgumentException();
264 this.columns = columns;
268 * Returns the current number of rows.
270 * @return number of rows
272 public int getRows()
274 return rows;
278 * Sets the number of rows.
280 * @param columns number of columns
282 * @exception IllegalArgumentException if rows is negative
284 public void setRows(int rows)
286 if (rows < 0)
287 throw new IllegalArgumentException();
289 this.rows = rows;
293 * Checks whether line wrapping is enabled.
295 * @return <code>true</code> if line wrapping is enabled,
296 * <code>false</code> otherwise
298 public boolean getLineWrap()
300 return lineWrap;
304 * Enables/disables line wrapping.
306 * @param wrapping <code>true</code> to enable line wrapping,
307 * <code>false</code> otherwise
309 public void setLineWrap(boolean flag)
311 if (lineWrap == flag)
312 return;
314 boolean oldValue = lineWrap;
315 lineWrap = flag;
316 firePropertyChange("lineWrap", oldValue, lineWrap);
320 * Checks whether word style wrapping is enabled.
322 * @return <code>true</code> if word style wrapping is enabled,
323 * <code>false</code> otherwise
325 public boolean getWrapStyleWord()
327 return wrapStyleWord;
331 * Enables/Disables word style wrapping.
333 * @param flag <code>true</code> to enable word style wrapping,
334 * <code>false</code> otherwise
336 public void setWrapStyleWord(boolean flag)
338 if (wrapStyleWord == flag)
339 return;
341 boolean oldValue = wrapStyleWord;
342 wrapStyleWord = flag;
343 firePropertyChange("wrapStyleWord", oldValue, wrapStyleWord);
347 * Returns the number of characters used for a tab.
348 * This defaults to 8.
350 * @return the current number of spaces used for a tab.
352 public int getTabSize()
354 return tabSize;
358 * Sets the number of characters used for a tab to the
359 * supplied value. If a change to the tab size property
360 * occurs (i.e. newSize != tabSize), a property change event
361 * is fired.
363 * @param newSize The new number of characters to use for a tab.
365 public void setTabSize(int newSize)
367 if (tabSize == newSize)
368 return;
370 int oldValue = tabSize;
371 tabSize = newSize;
372 firePropertyChange("tabSize", oldValue, tabSize);
375 protected int getColumnWidth()
377 FontMetrics metrics = getToolkit().getFontMetrics(getFont());
378 return metrics.charWidth('m');
381 public int getLineCount()
383 return getDocument().getDefaultRootElement().getElementCount();
386 public int getLineStartOffset(int line)
387 throws BadLocationException
389 int lineCount = getLineCount();
391 if (line < 0 || line > lineCount)
392 throw new BadLocationException("Non-existing line number", line);
394 Element lineElem = getDocument().getDefaultRootElement().getElement(line);
395 return lineElem.getStartOffset();
398 public int getLineEndOffset(int line)
399 throws BadLocationException
401 int lineCount = getLineCount();
403 if (line < 0 || line > lineCount)
404 throw new BadLocationException("Non-existing line number", line);
406 Element lineElem = getDocument().getDefaultRootElement().getElement(line);
407 return lineElem.getEndOffset();
410 public int getLineOfOffset(int offset)
411 throws BadLocationException
413 Document doc = getDocument();
415 if (offset < doc.getStartPosition().getOffset()
416 || offset >= doc.getEndPosition().getOffset())
417 throw new BadLocationException("offset outside of document", offset);
419 return doc.getDefaultRootElement().getElementIndex(offset);
422 protected int getRowHeight()
424 FontMetrics metrics = getToolkit().getFontMetrics(getFont());
425 return metrics.getHeight();
429 * Inserts the supplied text at the specified position. Nothing
430 * happens in the case that the model or the supplied string is null
431 * or of zero length.
433 * @param string The string of text to insert.
434 * @param position The position at which to insert the supplied text.
435 * @throws IllegalArgumentException if the position is &lt; 0 or greater
436 * than the length of the current text.
438 public void insert(String string, int position)
440 // Retrieve the document model.
441 Document doc = getDocument();
443 // Check the model and string for validity.
444 if (doc == null
445 || string == null
446 || string.length() == 0)
447 return;
449 // Insert the text into the model.
452 doc.insertString(position, string, null);
454 catch (BadLocationException e)
456 throw new IllegalArgumentException("The supplied position, "
457 + position + ", was invalid.");
461 public void replaceRange(String text, int start, int end)
463 Document doc = getDocument();
465 if (start > end
466 || start < doc.getStartPosition().getOffset()
467 || end >= doc.getEndPosition().getOffset())
468 throw new IllegalArgumentException();
472 doc.remove(start, end);
473 doc.insertString(start, text, null);
475 catch (BadLocationException e)
477 // This cannot happen as we check offset above.