Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / javax / swing / JTextArea.java
blob2fa185b620790927867373d1871294cfa4bf00e3
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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.Dimension;
42 import java.awt.FontMetrics;
43 import java.awt.Rectangle;
45 import javax.accessibility.AccessibleContext;
46 import javax.accessibility.AccessibleStateSet;
47 import javax.swing.text.BadLocationException;
48 import javax.swing.text.Document;
49 import javax.swing.text.Element;
50 import javax.swing.text.JTextComponent;
51 import javax.swing.text.PlainDocument;
52 import javax.swing.text.View;
54 /**
55 * The <code>JTextArea</code> component provides a multi-line area for displaying
56 * and editing plain text. The component is designed to act as a lightweight
57 * replacement for the heavyweight <code>java.awt.TextArea</code> component,
58 * which provides similar functionality using native widgets.
59 * <p>
61 * This component has additional functionality to the AWT class. It follows
62 * the same design pattern as seen in other text components, such as
63 * <code>JTextField</code>, <code>JTextPane</code> and <code>JEditorPane</code>,
64 * and embodied in <code>JTextComponent</code>. These classes separate the text
65 * (the model) from its appearance within the onscreen component (the view). The
66 * text is held within a <code>javax.swing.text.Document</code> object, which can
67 * also maintain relevant style information where necessary. As a result, it is the
68 * document that should be monitored for textual changes, via
69 * <code>DocumentEvent</code>s delivered to registered
70 * <code>DocumentListener</code>s, rather than this component.
71 * <p>
73 * Unlike <code>java.awt.TextArea</code>, <code>JTextArea</code> does not
74 * handle scrolling. Instead, this functionality is delegated to a
75 * <code>JScrollPane</code>, which can contain the text area and handle
76 * scrolling when required. Likewise, the word wrapping functionality
77 * of the AWT component is converted to a property of this component
78 * and the <code>rows</code> and <code>columns</code> properties
79 * are used in calculating the preferred size of the scroll pane's
80 * view port.
82 * @author Michael Koch (konqueror@gmx.de)
83 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
84 * @see java.awt.TextArea
85 * @see javax.swing.text.JTextComponent
86 * @see javax.swing.JTextField
87 * @see javax.swing.JTextPane
88 * @see javax.swing.JEditorPane
89 * @see javax.swing.text.Document
90 * @see javax.swing.event.DocumentEvent
91 * @see javax.swing.event.DocumentListener
94 public class JTextArea extends JTextComponent
96 /**
97 * Provides accessibility support for <code>JTextArea</code>.
99 * @author Roman Kennke (kennke@aicas.com)
101 protected class AccessibleJTextArea extends AccessibleJTextComponent
105 * Creates a new <code>AccessibleJTextArea</code> object.
107 protected AccessibleJTextArea()
109 super();
113 * Returns the accessible state of this <code>AccessibleJTextArea</code>.
115 * @return the accessible state of this <code>AccessibleJTextArea</code>
117 public AccessibleStateSet getAccessibleStateSet()
119 AccessibleStateSet state = super.getAccessibleStateSet();
120 // TODO: Figure out what state must be added here to the super's state.
121 return state;
126 * Compatible with Sun's JDK
128 private static final long serialVersionUID = -6141680179310439825L;
131 * The number of rows used by the component.
133 private int rows;
136 * The number of columns used by the component.
138 private int columns;
141 * Whether line wrapping is enabled or not.
143 private boolean lineWrap;
146 * The number of characters equal to a tab within the text.
148 private int tabSize = 8;
150 private boolean wrapStyleWord;
153 * Creates a new <code>JTextArea</code> object.
155 public JTextArea()
157 this(null, null, 0, 0);
161 * Creates a new <code>JTextArea</code> object.
163 * @param text the initial text
165 public JTextArea(String text)
167 this(null, text, 0, 0);
171 * Creates a new <code>JTextArea</code> object.
173 * @param rows the number of rows
174 * @param columns the number of cols
176 * @exception IllegalArgumentException if rows or columns are negative
178 public JTextArea(int rows, int columns)
180 this(null, null, rows, columns);
184 * Creates a new <code>JTextArea</code> object.
186 * @param text the initial text
187 * @param rows the number of rows
188 * @param columns the number of cols
190 * @exception IllegalArgumentException if rows or columns are negative
192 public JTextArea(String text, int rows, int columns)
194 this(null, text, rows, columns);
198 * Creates a new <code>JTextArea</code> object.
200 * @param doc the document model to use
202 public JTextArea(Document doc)
204 this(doc, null, 0, 0);
208 * Creates a new <code>JTextArea</code> object.
210 * @param doc the document model to use
211 * @param text the initial text
212 * @param rows the number of rows
213 * @param columns the number of cols
215 * @exception IllegalArgumentException if rows or columns are negative
217 public JTextArea(Document doc, String text, int rows, int columns)
219 setDocument(doc == null ? createDefaultModel() : doc);
220 setText(text);
221 setRows(rows);
222 setColumns(columns);
226 * Appends the supplied text to the current contents
227 * of the document model.
229 * @param toAppend the text to append
231 public void append(String toAppend)
235 getDocument().insertString(getText().length(), toAppend, null);
237 catch (BadLocationException exception)
239 /* This shouldn't happen in theory -- but, if it does... */
240 throw new RuntimeException("Unexpected exception occurred.", exception);
242 if (toAppend != null && toAppend.length() > 0)
243 revalidate();
247 * Creates the default document model.
249 * @return a new default model
251 protected Document createDefaultModel()
253 return new PlainDocument();
257 * Returns true if the width of this component should be forced
258 * to match the width of a surrounding view port. When line wrapping
259 * is turned on, this method returns true.
261 * @return true if lines are wrapped.
263 public boolean getScrollableTracksViewportWidth()
265 return lineWrap ? true : super.getScrollableTracksViewportWidth();
269 * Returns the increment that is needed to expose exactly one new line
270 * of text. This is implemented here to return the values of
271 * {@link #getRowHeight} and {@link #getColumnWidth}, depending on
272 * the value of the argument <code>direction</code>.
274 * @param visibleRect the view area that is visible in the viewport
275 * @param orientation either {@link SwingConstants#VERTICAL} or
276 * {@link SwingConstants#HORIZONTAL}
277 * @param direction less than zero for up/left scrolling, greater
278 * than zero for down/right scrolling
280 * @return the increment that is needed to expose exactly one new row
281 * or column of text
283 * @throws IllegalArgumentException if <code>orientation</code> is invalid
285 public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
286 int direction)
288 if (orientation == SwingConstants.VERTICAL)
289 return getRowHeight();
290 else if (orientation == SwingConstants.HORIZONTAL)
291 return getColumnWidth();
292 else
293 throw new IllegalArgumentException("orientation must be either "
294 + "javax.swing.SwingConstants.VERTICAL "
295 + "or "
296 + "javax.swing.SwingConstants.HORIZONTAL"
301 * Returns the preferred size of that text component in the case
302 * it is embedded within a JScrollPane. This uses the column and
303 * row settings if they are explicitly set, or fall back to
304 * the superclass's behaviour.
306 * @return the preferred size of that text component in the case
307 * it is embedded within a JScrollPane
309 public Dimension getPreferredScrollableViewportSize()
311 if ((rows > 0) && (columns > 0))
312 return new Dimension(columns * getColumnWidth(), rows * getRowHeight());
313 else
314 return super.getPreferredScrollableViewportSize();
318 * Returns the UI class ID string.
320 * @return the string "TextAreaUI"
322 public String getUIClassID()
324 return "TextAreaUI";
328 * Returns the current number of columns.
330 * @return number of columns
332 public int getColumns()
334 return columns;
338 * Sets the number of rows.
340 * @param columns number of columns
342 * @exception IllegalArgumentException if columns is negative
344 public void setColumns(int columns)
346 if (columns < 0)
347 throw new IllegalArgumentException();
349 if (columns != this.columns)
351 this.columns = columns;
352 revalidate();
357 * Returns the current number of rows.
359 * @return number of rows
361 public int getRows()
363 return rows;
367 * Sets the number of rows.
369 * @param rows number of rows
371 * @exception IllegalArgumentException if rows is negative
373 public void setRows(int rows)
375 if (rows < 0)
376 throw new IllegalArgumentException();
378 if (rows != this.rows)
380 this.rows = rows;
381 revalidate();
386 * Checks whether line wrapping is enabled.
388 * @return <code>true</code> if line wrapping is enabled,
389 * <code>false</code> otherwise
391 public boolean getLineWrap()
393 return lineWrap;
397 * Enables/disables line wrapping.
399 * @param flag <code>true</code> to enable line wrapping,
400 * <code>false</code> otherwise
402 public void setLineWrap(boolean flag)
404 if (lineWrap == flag)
405 return;
407 boolean oldValue = lineWrap;
408 lineWrap = flag;
409 firePropertyChange("lineWrap", oldValue, lineWrap);
413 * Checks whether word style wrapping is enabled.
415 * @return <code>true</code> if word style wrapping is enabled,
416 * <code>false</code> otherwise
418 public boolean getWrapStyleWord()
420 return wrapStyleWord;
424 * Enables/Disables word style wrapping.
426 * @param flag <code>true</code> to enable word style wrapping,
427 * <code>false</code> otherwise
429 public void setWrapStyleWord(boolean flag)
431 if (wrapStyleWord == flag)
432 return;
434 boolean oldValue = wrapStyleWord;
435 wrapStyleWord = flag;
436 firePropertyChange("wrapStyleWord", oldValue, wrapStyleWord);
440 * Returns the number of characters used for a tab.
441 * This defaults to 8.
443 * @return the current number of spaces used for a tab.
445 public int getTabSize()
447 return tabSize;
451 * Sets the number of characters used for a tab to the
452 * supplied value. If a change to the tab size property
453 * occurs (i.e. newSize != tabSize), a property change event
454 * is fired.
456 * @param newSize The new number of characters to use for a tab.
458 public void setTabSize(int newSize)
460 if (tabSize == newSize)
461 return;
463 int oldValue = tabSize;
464 tabSize = newSize;
465 firePropertyChange("tabSize", oldValue, tabSize);
468 protected int getColumnWidth()
470 FontMetrics metrics = getToolkit().getFontMetrics(getFont());
471 return metrics.charWidth('m');
474 public int getLineCount()
476 return getDocument().getDefaultRootElement().getElementCount();
479 public int getLineStartOffset(int line)
480 throws BadLocationException
482 int lineCount = getLineCount();
484 if (line < 0 || line > lineCount)
485 throw new BadLocationException("Non-existing line number", line);
487 Element lineElem = getDocument().getDefaultRootElement().getElement(line);
488 return lineElem.getStartOffset();
491 public int getLineEndOffset(int line)
492 throws BadLocationException
494 int lineCount = getLineCount();
496 if (line < 0 || line > lineCount)
497 throw new BadLocationException("Non-existing line number", line);
499 Element lineElem = getDocument().getDefaultRootElement().getElement(line);
500 return lineElem.getEndOffset();
503 public int getLineOfOffset(int offset)
504 throws BadLocationException
506 Document doc = getDocument();
508 if (offset < doc.getStartPosition().getOffset()
509 || offset >= doc.getEndPosition().getOffset())
510 throw new BadLocationException("offset outside of document", offset);
512 return doc.getDefaultRootElement().getElementIndex(offset);
515 protected int getRowHeight()
517 FontMetrics metrics = getToolkit().getFontMetrics(getFont());
518 return metrics.getHeight();
522 * Inserts the supplied text at the specified position. Nothing
523 * happens in the case that the model or the supplied string is null
524 * or of zero length.
526 * @param string The string of text to insert.
527 * @param position The position at which to insert the supplied text.
528 * @throws IllegalArgumentException if the position is &lt; 0 or greater
529 * than the length of the current text.
531 public void insert(String string, int position)
533 // Retrieve the document model.
534 Document doc = getDocument();
536 // Check the model and string for validity.
537 if (doc == null
538 || string == null
539 || string.length() == 0)
540 return;
542 // Insert the text into the model.
545 doc.insertString(position, string, null);
547 catch (BadLocationException e)
549 throw new IllegalArgumentException("The supplied position, "
550 + position + ", was invalid.");
554 public void replaceRange(String text, int start, int end)
556 Document doc = getDocument();
558 if (start > end
559 || start < doc.getStartPosition().getOffset()
560 || end >= doc.getEndPosition().getOffset())
561 throw new IllegalArgumentException();
565 doc.remove(start, end - start);
566 doc.insertString(start, text, null);
568 catch (BadLocationException e)
570 // This cannot happen as we check offset above.
575 * Returns the preferred size for the JTextArea. This is the maximum of
576 * the size that is needed to display the content and the requested size
577 * as per {@link #getColumns} and {@link #getRows}.
579 * @return the preferred size of the JTextArea
581 public Dimension getPreferredSize()
583 int reqWidth = getColumns() * getColumnWidth();
584 int reqHeight = getRows() * getRowHeight();
585 View view = getUI().getRootView(this);
586 int neededWidth = (int) view.getPreferredSpan(View.HORIZONTAL);
587 int neededHeight = (int) view.getPreferredSpan(View.VERTICAL);
588 return new Dimension(Math.max(reqWidth, neededWidth),
589 Math.max(reqHeight, neededHeight));
593 * Returns the accessible context associated with the <code>JTextArea</code>.
595 * @return the accessible context associated with the <code>JTextArea</code>
597 public AccessibleContext getAccessibleContext()
599 if (accessibleContext == null)
600 accessibleContext = new AccessibleJTextArea();
601 return accessibleContext;