History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/JTextArea.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/JTextArea.java+815−0
@@ -0,0 +1,815 @@
1+/*
2+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package javax.swing;
26+
27+import java.awt.*;
28+import java.awt.event.*;
29+import javax.swing.text.*;
30+import javax.swing.plaf.*;
31+import javax.accessibility.*;
32+
33+import java.util.Collections;
34+import java.util.Set;
35+import java.util.StringTokenizer;
36+
37+import java.io.ObjectOutputStream;
38+import java.io.ObjectInputStream;
39+import java.io.IOException;
40+
41+/**
42+ * A <code>JTextArea</code> is a multi-line area that displays plain text.
43+ * It is intended to be a lightweight component that provides source
44+ * compatibility with the <code>java.awt.TextArea</code> class where it can
45+ * reasonably do so.
46+ * You can find information and examples of using all the text components in
47+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/text.html">Using Text Components</a>,
48+ * a section in <em>The Java Tutorial.</em>
49+ *
50+ * <p>
51+ * This component has capabilities not found in the
52+ * <code>java.awt.TextArea</code> class. The superclass should be
53+ * consulted for additional capabilities.
54+ * Alternative multi-line text classes with
55+ * more capabilities are <code>JTextPane</code> and <code>JEditorPane</code>.
56+ * <p>
57+ * The <code>java.awt.TextArea</code> internally handles scrolling.
58+ * <code>JTextArea</code> is different in that it doesn't manage scrolling,
59+ * but implements the swing <code>Scrollable</code> interface. This allows it
60+ * to be placed inside a <code>JScrollPane</code> if scrolling
61+ * behavior is desired, and used directly if scrolling is not desired.
62+ * <p>
63+ * The <code>java.awt.TextArea</code> has the ability to do line wrapping.
64+ * This was controlled by the horizontal scrolling policy. Since
65+ * scrolling is not done by <code>JTextArea</code> directly, backward
66+ * compatibility must be provided another way. <code>JTextArea</code> has
67+ * a bound property for line wrapping that controls whether or
68+ * not it will wrap lines. By default, the line wrapping property
69+ * is set to false (not wrapped).
70+ * <p>
71+ * <code>java.awt.TextArea</code> has two properties <code>rows</code>
72+ * and <code>columns</code> that are used to determine the preferred size.
73+ * <code>JTextArea</code> uses these properties to indicate the
74+ * preferred size of the viewport when placed inside a <code>JScrollPane</code>
75+ * to match the functionality provided by <code>java.awt.TextArea</code>.
76+ * <code>JTextArea</code> has a preferred size of what is needed to
77+ * display all of the text, so that it functions properly inside of
78+ * a <code>JScrollPane</code>. If the value for <code>rows</code>
79+ * or <code>columns</code> is equal to zero,
80+ * the preferred size along that axis is used for
81+ * the viewport preferred size along the same axis.
82+ * <p>
83+ * The <code>java.awt.TextArea</code> could be monitored for changes by adding
84+ * a <code>TextListener</code> for <code>TextEvent</code>s.
85+ * In the <code>JTextComponent</code> based
86+ * components, changes are broadcasted from the model via a
87+ * <code>DocumentEvent</code> to <code>DocumentListeners</code>.
88+ * The <code>DocumentEvent</code> gives
89+ * the location of the change and the kind of change if desired.
90+ * The code fragment might look something like:
91+ * <pre>
92+ * DocumentListener myListener = ??;
93+ * JTextArea myArea = ??;
94+ * myArea.getDocument().addDocumentListener(myListener);
95+ * </pre>
96+ * <p>
97+ * <dl>
98+ * <dt><b><font size=+1>Newlines</font></b>
99+ * <dd>
100+ * For a discussion on how newlines are handled, see
101+ * <a href="text/DefaultEditorKit.html">DefaultEditorKit</a>.
102+ * </dl>
103+ *
104+ * <p>
105+ * <strong>Warning:</strong> Swing is not thread safe. For more
106+ * information see <a
107+ * href="package-summary.html#threading">Swing's Threading
108+ * Policy</a>.
109+ * <p>
110+ * <strong>Warning:</strong>
111+ * Serialized objects of this class will not be compatible with
112+ * future Swing releases. The current serialization support is
113+ * appropriate for short term storage or RMI between applications running
114+ * the same version of Swing. As of 1.4, support for long term storage
115+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
116+ * has been added to the <code>java.beans</code> package.
117+ * Please see {@link java.beans.XMLEncoder}.
118+ *
119+ * @beaninfo
120+ * attribute: isContainer false
121+ * description: A multi-line area that displays plain text.
122+ *
123+ * @author Timothy Prinzing
124+ * @see JTextPane
125+ * @see JEditorPane
126+ */
127+public class JTextArea extends JTextComponent {
128+
129+ /**
130+ * @see #getUIClassID
131+ * @see #readObject
132+ */
133+ private static final String uiClassID = "TextAreaUI";
134+
135+ /**
136+ * Constructs a new TextArea. A default model is set, the initial string
137+ * is null, and rows/columns are set to 0.
138+ */
139+ public JTextArea() {
140+ this(null, null, 0, 0);
141+ }
142+
143+ /**
144+ * Constructs a new TextArea with the specified text displayed.
145+ * A default model is created and rows/columns are set to 0.
146+ *
147+ * @param text the text to be displayed, or null
148+ */
149+ public JTextArea(String text) {
150+ this(null, text, 0, 0);
151+ }
152+
153+ /**
154+ * Constructs a new empty TextArea with the specified number of
155+ * rows and columns. A default model is created, and the initial
156+ * string is null.
157+ *
158+ * @param rows the number of rows >= 0
159+ * @param columns the number of columns >= 0
160+ * @exception IllegalArgumentException if the rows or columns
161+ * arguments are negative.
162+ */
163+ public JTextArea(int rows, int columns) {
164+ this(null, null, rows, columns);
165+ }
166+
167+ /**
168+ * Constructs a new TextArea with the specified text and number
169+ * of rows and columns. A default model is created.
170+ *
171+ * @param text the text to be displayed, or null
172+ * @param rows the number of rows >= 0
173+ * @param columns the number of columns >= 0
174+ * @exception IllegalArgumentException if the rows or columns
175+ * arguments are negative.
176+ */
177+ public JTextArea(String text, int rows, int columns) {
178+ this(null, text, rows, columns);
179+ }
180+
181+ /**
182+ * Constructs a new JTextArea with the given document model, and defaults
183+ * for all of the other arguments (null, 0, 0).
184+ *
185+ * @param doc the model to use
186+ */
187+ public JTextArea(Document doc) {
188+ this(doc, null, 0, 0);
189+ }
190+
191+ /**
192+ * Constructs a new JTextArea with the specified number of rows
193+ * and columns, and the given model. All of the constructors
194+ * feed through this constructor.
195+ *
196+ * @param doc the model to use, or create a default one if null
197+ * @param text the text to be displayed, null if none
198+ * @param rows the number of rows >= 0
199+ * @param columns the number of columns >= 0
200+ * @exception IllegalArgumentException if the rows or columns
201+ * arguments are negative.
202+ */
203+ public JTextArea(Document doc, String text, int rows, int columns) {
204+ super();
205+ this.rows = rows;
206+ this.columns = columns;
207+ if (doc == null) {
208+ doc = createDefaultModel();
209+ }
210+ setDocument(doc);
211+ if (text != null) {
212+ setText(text);
213+ select(0, 0);
214+ }
215+ if (rows < 0) {
216+ throw new IllegalArgumentException("rows: " + rows);
217+ }
218+ if (columns < 0) {
219+ throw new IllegalArgumentException("columns: " + columns);
220+ }
221+ LookAndFeel.installProperty(this,
222+ "focusTraversalKeysForward",
223+ JComponent.
224+ getManagingFocusForwardTraversalKeys());
225+ LookAndFeel.installProperty(this,
226+ "focusTraversalKeysBackward",
227+ JComponent.
228+ getManagingFocusBackwardTraversalKeys());
229+ }
230+
231+ /**
232+ * Returns the class ID for the UI.
233+ *
234+ * @return the ID ("TextAreaUI")
235+ * @see JComponent#getUIClassID
236+ * @see UIDefaults#getUI
237+ */
238+ public String getUIClassID() {
239+ return uiClassID;
240+ }
241+
242+ /**
243+ * Creates the default implementation of the model
244+ * to be used at construction if one isn't explicitly
245+ * given. A new instance of PlainDocument is returned.
246+ *
247+ * @return the default document model
248+ */
249+ protected Document createDefaultModel() {
250+ return new PlainDocument();
251+ }
252+
253+ /**
254+ * Sets the number of characters to expand tabs to.
255+ * This will be multiplied by the maximum advance for
256+ * variable width fonts. A PropertyChange event ("tabSize") is fired
257+ * when the tab size changes.
258+ *
259+ * @param size number of characters to expand to
260+ * @see #getTabSize
261+ * @beaninfo
262+ * preferred: true
263+ * bound: true
264+ * description: the number of characters to expand tabs to
265+ */
266+ public void setTabSize(int size) {
267+ Document doc = getDocument();
268+ if (doc != null) {
269+ int old = getTabSize();
270+ doc.putProperty(PlainDocument.tabSizeAttribute, Integer.valueOf(size));
271+ firePropertyChange("tabSize", old, size);
272+ }
273+ }
274+
275+ /**
276+ * Gets the number of characters used to expand tabs. If the document is
277+ * null or doesn't have a tab setting, return a default of 8.
278+ *
279+ * @return the number of characters
280+ */
281+ public int getTabSize() {
282+ int size = 8;
283+ Document doc = getDocument();
284+ if (doc != null) {
285+ Integer i = (Integer) doc.getProperty(PlainDocument.tabSizeAttribute);
286+ if (i != null) {
287+ size = i.intValue();
288+ }
289+ }
290+ return size;
291+ }
292+
293+ /**
294+ * Sets the line-wrapping policy of the text area. If set
295+ * to true the lines will be wrapped if they are too long
296+ * to fit within the allocated width. If set to false,
297+ * the lines will always be unwrapped. A <code>PropertyChange</code>
298+ * event ("lineWrap") is fired when the policy is changed.
299+ * By default this property is false.
300+ *
301+ * @param wrap indicates if lines should be wrapped
302+ * @see #getLineWrap
303+ * @beaninfo
304+ * preferred: true
305+ * bound: true
306+ * description: should lines be wrapped
307+ */
308+ public void setLineWrap(boolean wrap) {
309+ boolean old = this.wrap;
310+ this.wrap = wrap;
311+ firePropertyChange("lineWrap", old, wrap);
312+ }
313+
314+ /**
315+ * Gets the line-wrapping policy of the text area. If set
316+ * to true the lines will be wrapped if they are too long
317+ * to fit within the allocated width. If set to false,
318+ * the lines will always be unwrapped.
319+ *
320+ * @return if lines will be wrapped
321+ */
322+ public boolean getLineWrap() {
323+ return wrap;
324+ }
325+
326+ /**
327+ * Sets the style of wrapping used if the text area is wrapping
328+ * lines. If set to true the lines will be wrapped at word
329+ * boundaries (whitespace) if they are too long
330+ * to fit within the allocated width. If set to false,
331+ * the lines will be wrapped at character boundaries.
332+ * By default this property is false.
333+ *
334+ * @param word indicates if word boundaries should be used
335+ * for line wrapping
336+ * @see #getWrapStyleWord
337+ * @beaninfo
338+ * preferred: false
339+ * bound: true
340+ * description: should wrapping occur at word boundaries
341+ */
342+ public void setWrapStyleWord(boolean word) {
343+ boolean old = this.word;
344+ this.word = word;
345+ firePropertyChange("wrapStyleWord", old, word);
346+ }
347+
348+ /**
349+ * Gets the style of wrapping used if the text area is wrapping
350+ * lines. If set to true the lines will be wrapped at word
351+ * boundaries (ie whitespace) if they are too long
352+ * to fit within the allocated width. If set to false,
353+ * the lines will be wrapped at character boundaries.
354+ *
355+ * @return if the wrap style should be word boundaries
356+ * instead of character boundaries
357+ * @see #setWrapStyleWord
358+ */
359+ public boolean getWrapStyleWord() {
360+ return word;
361+ }
362+
363+ /**
364+ * Translates an offset into the components text to a
365+ * line number.
366+ *
367+ * @param offset the offset >= 0
368+ * @return the line number >= 0
369+ * @exception BadLocationException thrown if the offset is
370+ * less than zero or greater than the document length.
371+ */
372+ public int getLineOfOffset(int offset) throws BadLocationException {
373+ Document doc = getDocument();
374+ if (offset < 0) {
375+ throw new BadLocationException("Can't translate offset to line", -1);
376+ } else if (offset > doc.getLength()) {
377+ throw new BadLocationException("Can't translate offset to line", doc.getLength()+1);
378+ } else {
379+ Element map = getDocument().getDefaultRootElement();
380+ return map.getElementIndex(offset);
381+ }
382+ }
383+
384+ /**
385+ * Determines the number of lines contained in the area.
386+ *
387+ * @return the number of lines > 0
388+ */
389+ public int getLineCount() {
390+ Element map = getDocument().getDefaultRootElement();
391+ return map.getElementCount();
392+ }
393+
394+ /**
395+ * Determines the offset of the start of the given line.
396+ *
397+ * @param line the line number to translate >= 0
398+ * @return the offset >= 0
399+ * @exception BadLocationException thrown if the line is
400+ * less than zero or greater or equal to the number of
401+ * lines contained in the document (as reported by
402+ * getLineCount).
403+ */
404+ public int getLineStartOffset(int line) throws BadLocationException {
405+ int lineCount = getLineCount();
406+ if (line < 0) {
407+ throw new BadLocationException("Negative line", -1);
408+ } else if (line >= lineCount) {
409+ throw new BadLocationException("No such line", getDocument().getLength()+1);
410+ } else {
411+ Element map = getDocument().getDefaultRootElement();
412+ Element lineElem = map.getElement(line);
413+ return lineElem.getStartOffset();
414+ }
415+ }
416+
417+ /**
418+ * Determines the offset of the end of the given line.
419+ *
420+ * @param line the line >= 0
421+ * @return the offset >= 0
422+ * @exception BadLocationException Thrown if the line is
423+ * less than zero or greater or equal to the number of
424+ * lines contained in the document (as reported by
425+ * getLineCount).
426+ */
427+ public int getLineEndOffset(int line) throws BadLocationException {
428+ int lineCount = getLineCount();
429+ if (line < 0) {
430+ throw new BadLocationException("Negative line", -1);
431+ } else if (line >= lineCount) {
432+ throw new BadLocationException("No such line", getDocument().getLength()+1);
433+ } else {
434+ Element map = getDocument().getDefaultRootElement();
435+ Element lineElem = map.getElement(line);
436+ int endOffset = lineElem.getEndOffset();
437+ // hide the implicit break at the end of the document
438+ return ((line == lineCount - 1) ? (endOffset - 1) : endOffset);
439+ }
440+ }
441+
442+ // --- java.awt.TextArea methods ---------------------------------
443+
444+ /**
445+ * Inserts the specified text at the specified position. Does nothing
446+ * if the model is null or if the text is null or empty.
447+ *
448+ * @param str the text to insert
449+ * @param pos the position at which to insert >= 0
450+ * @exception IllegalArgumentException if pos is an
451+ * invalid position in the model
452+ * @see TextComponent#setText
453+ * @see #replaceRange
454+ */
455+ public void insert(String str, int pos) {
456+ Document doc = getDocument();
457+ if (doc != null) {
458+ try {
459+ doc.insertString(pos, str, null);
460+ } catch (BadLocationException e) {
461+ throw new IllegalArgumentException(e.getMessage());
462+ }
463+ }
464+ }
465+
466+ /**
467+ * Appends the given text to the end of the document. Does nothing if
468+ * the model is null or the string is null or empty.
469+ *
470+ * @param str the text to insert
471+ * @see #insert
472+ */
473+ public void append(String str) {
474+ Document doc = getDocument();
475+ if (doc != null) {
476+ try {
477+ doc.insertString(doc.getLength(), str, null);
478+ } catch (BadLocationException e) {
479+ }
480+ }
481+ }
482+
483+ /**
484+ * Replaces text from the indicated start to end position with the
485+ * new text specified. Does nothing if the model is null. Simply
486+ * does a delete if the new string is null or empty.
487+ *
488+ * @param str the text to use as the replacement
489+ * @param start the start position >= 0
490+ * @param end the end position >= start
491+ * @exception IllegalArgumentException if part of the range is an
492+ * invalid position in the model
493+ * @see #insert
494+ * @see #replaceRange
495+ */
496+ public void replaceRange(String str, int start, int end) {
497+ if (end < start) {
498+ throw new IllegalArgumentException("end before start");
499+ }
500+ Document doc = getDocument();
501+ if (doc != null) {
502+ try {
503+ if (doc instanceof AbstractDocument) {
504+ ((AbstractDocument)doc).replace(start, end - start, str,
505+ null);
506+ }
507+ else {
508+ doc.remove(start, end - start);
509+ doc.insertString(start, str, null);
510+ }
511+ } catch (BadLocationException e) {
512+ throw new IllegalArgumentException(e.getMessage());
513+ }
514+ }
515+ }
516+
517+ /**
518+ * Returns the number of rows in the TextArea.
519+ *
520+ * @return the number of rows >= 0
521+ */
522+ public int getRows() {
523+ return rows;
524+ }
525+
526+ /**
527+ * Sets the number of rows for this TextArea. Calls invalidate() after
528+ * setting the new value.
529+ *
530+ * @param rows the number of rows >= 0
531+ * @exception IllegalArgumentException if rows is less than 0
532+ * @see #getRows
533+ * @beaninfo
534+ * description: the number of rows preferred for display
535+ */
536+ public void setRows(int rows) {
537+ int oldVal = this.rows;
538+ if (rows < 0) {
539+ throw new IllegalArgumentException("rows less than zero.");
540+ }
541+ if (rows != oldVal) {
542+ this.rows = rows;
543+ invalidate();
544+ }
545+ }
546+
547+ /**
548+ * Defines the meaning of the height of a row. This defaults to
549+ * the height of the font.
550+ *
551+ * @return the height >= 1
552+ */
553+ protected int getRowHeight() {
554+ if (rowHeight == 0) {
555+ FontMetrics metrics = getFontMetrics(getFont());
556+ rowHeight = metrics.getHeight();
557+ }
558+ return rowHeight;
559+ }
560+
561+ /**
562+ * Returns the number of columns in the TextArea.
563+ *
564+ * @return number of columns >= 0
565+ */
566+ public int getColumns() {
567+ return columns;
568+ }
569+
570+ /**
571+ * Sets the number of columns for this TextArea. Does an invalidate()
572+ * after setting the new value.
573+ *
574+ * @param columns the number of columns >= 0
575+ * @exception IllegalArgumentException if columns is less than 0
576+ * @see #getColumns
577+ * @beaninfo
578+ * description: the number of columns preferred for display
579+ */
580+ public void setColumns(int columns) {
581+ int oldVal = this.columns;
582+ if (columns < 0) {
583+ throw new IllegalArgumentException("columns less than zero.");
584+ }
585+ if (columns != oldVal) {
586+ this.columns = columns;
587+ invalidate();
588+ }
589+ }
590+
591+ /**
592+ * Gets column width.
593+ * The meaning of what a column is can be considered a fairly weak
594+ * notion for some fonts. This method is used to define the width
595+ * of a column. By default this is defined to be the width of the
596+ * character <em>m</em> for the font used. This method can be
597+ * redefined to be some alternative amount.
598+ *
599+ * @return the column width >= 1
600+ */
601+ protected int getColumnWidth() {
602+ if (columnWidth == 0) {
603+ FontMetrics metrics = getFontMetrics(getFont());
604+ columnWidth = metrics.charWidth('m');
605+ }
606+ return columnWidth;
607+ }
608+
609+ // --- Component methods -----------------------------------------
610+
611+ /**
612+ * Returns the preferred size of the TextArea. This is the
613+ * maximum of the size needed to display the text and the
614+ * size requested for the viewport.
615+ *
616+ * @return the size
617+ */
618+ public Dimension getPreferredSize() {
619+ Dimension d = super.getPreferredSize();
620+ d = (d == null) ? new Dimension(400,400) : d;
621+ Insets insets = getInsets();
622+
623+ if (columns != 0) {
624+ d.width = Math.max(d.width, columns * getColumnWidth() +
625+ insets.left + insets.right);
626+ }
627+ if (rows != 0) {
628+ d.height = Math.max(d.height, rows * getRowHeight() +
629+ insets.top + insets.bottom);
630+ }
631+ return d;
632+ }
633+
634+ /**
635+ * Sets the current font. This removes cached row height and column
636+ * width so the new font will be reflected, and calls revalidate().
637+ *
638+ * @param f the font to use as the current font
639+ */
640+ public void setFont(Font f) {
641+ super.setFont(f);
642+ rowHeight = 0;
643+ columnWidth = 0;
644+ }
645+
646+
647+ /**
648+ * Returns a string representation of this JTextArea. This method
649+ * is intended to be used only for debugging purposes, and the
650+ * content and format of the returned string may vary between
651+ * implementations. The returned string may be empty but may not
652+ * be <code>null</code>.
653+ *
654+ * @return a string representation of this JTextArea.
655+ */
656+ protected String paramString() {
657+ String wrapString = (wrap ?
658+ "true" : "false");
659+ String wordString = (word ?
660+ "true" : "false");
661+
662+ return super.paramString() +
663+ ",colums=" + columns +
664+ ",columWidth=" + columnWidth +
665+ ",rows=" + rows +
666+ ",rowHeight=" + rowHeight +
667+ ",word=" + wordString +
668+ ",wrap=" + wrapString;
669+ }
670+
671+ // --- Scrollable methods ----------------------------------------
672+
673+ /**
674+ * Returns true if a viewport should always force the width of this
675+ * Scrollable to match the width of the viewport. This is implemented
676+ * to return true if the line wrapping policy is true, and false
677+ * if lines are not being wrapped.
678+ *
679+ * @return true if a viewport should force the Scrollables width
680+ * to match its own.
681+ */
682+ public boolean getScrollableTracksViewportWidth() {
683+ return (wrap) ? true : super.getScrollableTracksViewportWidth();
684+ }
685+
686+ /**
687+ * Returns the preferred size of the viewport if this component
688+ * is embedded in a JScrollPane. This uses the desired column
689+ * and row settings if they have been set, otherwise the superclass
690+ * behavior is used.
691+ *
692+ * @return The preferredSize of a JViewport whose view is this Scrollable.
693+ * @see JViewport#getPreferredSize
694+ */
695+ public Dimension getPreferredScrollableViewportSize() {
696+ Dimension size = super.getPreferredScrollableViewportSize();
697+ size = (size == null) ? new Dimension(400,400) : size;
698+ Insets insets = getInsets();
699+
700+ size.width = (columns == 0) ? size.width :
701+ columns * getColumnWidth() + insets.left + insets.right;
702+ size.height = (rows == 0) ? size.height :
703+ rows * getRowHeight() + insets.top + insets.bottom;
704+ return size;
705+ }
706+
707+ /**
708+ * Components that display logical rows or columns should compute
709+ * the scroll increment that will completely expose one new row
710+ * or column, depending on the value of orientation. This is implemented
711+ * to use the values returned by the <code>getRowHeight</code> and
712+ * <code>getColumnWidth</code> methods.
713+ * <p>
714+ * Scrolling containers, like JScrollPane, will use this method
715+ * each time the user requests a unit scroll.
716+ *
717+ * @param visibleRect the view area visible within the viewport
718+ * @param orientation Either SwingConstants.VERTICAL or
719+ * SwingConstants.HORIZONTAL.
720+ * @param direction Less than zero to scroll up/left,
721+ * greater than zero for down/right.
722+ * @return The "unit" increment for scrolling in the specified direction
723+ * @exception IllegalArgumentException for an invalid orientation
724+ * @see JScrollBar#setUnitIncrement
725+ * @see #getRowHeight
726+ * @see #getColumnWidth
727+ */
728+ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
729+ switch (orientation) {
730+ case SwingConstants.VERTICAL:
731+ return getRowHeight();
732+ case SwingConstants.HORIZONTAL:
733+ return getColumnWidth();
734+ default:
735+ throw new IllegalArgumentException("Invalid orientation: " + orientation);
736+ }
737+ }
738+
739+ /**
740+ * See readObject() and writeObject() in JComponent for more
741+ * information about serialization in Swing.
742+ */
743+ private void writeObject(ObjectOutputStream s) throws IOException {
744+ s.defaultWriteObject();
745+ if (getUIClassID().equals(uiClassID)) {
746+ byte count = JComponent.getWriteObjCounter(this);
747+ JComponent.setWriteObjCounter(this, --count);
748+ if (count == 0 && ui != null) {
749+ ui.installUI(this);
750+ }
751+ }
752+ }
753+
754+/////////////////
755+// Accessibility support
756+////////////////
757+
758+
759+ /**
760+ * Gets the AccessibleContext associated with this JTextArea.
761+ * For JTextAreas, the AccessibleContext takes the form of an
762+ * AccessibleJTextArea.
763+ * A new AccessibleJTextArea instance is created if necessary.
764+ *
765+ * @return an AccessibleJTextArea that serves as the
766+ * AccessibleContext of this JTextArea
767+ */
768+ public AccessibleContext getAccessibleContext() {
769+ if (accessibleContext == null) {
770+ accessibleContext = new AccessibleJTextArea();
771+ }
772+ return accessibleContext;
773+ }
774+
775+ /**
776+ * This class implements accessibility support for the
777+ * <code>JTextArea</code> class. It provides an implementation of the
778+ * Java Accessibility API appropriate to text area user-interface
779+ * elements.
780+ * <p>
781+ * <strong>Warning:</strong>
782+ * Serialized objects of this class will not be compatible with
783+ * future Swing releases. The current serialization support is
784+ * appropriate for short term storage or RMI between applications running
785+ * the same version of Swing. As of 1.4, support for long term storage
786+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
787+ * has been added to the <code>java.beans</code> package.
788+ * Please see {@link java.beans.XMLEncoder}.
789+ */
790+ protected class AccessibleJTextArea extends AccessibleJTextComponent {
791+
792+ /**
793+ * Gets the state set of this object.
794+ *
795+ * @return an instance of AccessibleStateSet describing the states
796+ * of the object
797+ * @see AccessibleStateSet
798+ */
799+ public AccessibleStateSet getAccessibleStateSet() {
800+ AccessibleStateSet states = super.getAccessibleStateSet();
801+ states.add(AccessibleState.MULTI_LINE);
802+ return states;
803+ }
804+ }
805+
806+ // --- variables -------------------------------------------------
807+
808+ private int rows;
809+ private int columns;
810+ private int columnWidth;
811+ private int rowHeight;
812+ private boolean wrap;
813+ private boolean word;
814+
815+}