Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / java / awt / TextComponent.java
blobf08e59c9fc9326872cdba991b46d9d2dafcd2d82
1 /* TextComponent.java -- Widgets for entering text
2 Copyright (C) 1999, 2002, 2003 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 java.awt;
41 import java.awt.event.TextEvent;
42 import java.awt.event.TextListener;
43 import java.awt.peer.TextComponentPeer;
44 import java.io.Serializable;
45 import java.text.BreakIterator;
46 import java.util.EventListener;
48 import javax.accessibility.Accessible;
49 import javax.accessibility.AccessibleContext;
50 import javax.accessibility.AccessibleRole;
51 import javax.accessibility.AccessibleState;
52 import javax.accessibility.AccessibleStateSet;
53 import javax.accessibility.AccessibleText;
54 import javax.swing.text.AttributeSet;
56 /**
57 * This class provides common functionality for widgets than
58 * contain text.
60 * @author Aaron M. Renn (arenn@urbanophile.com)
62 public class TextComponent extends Component
63 implements Serializable, Accessible
67 * Static Variables
70 // Constant for serialization
71 private static final long serialVersionUID = -2214773872412987419L;
74 * Instance Variables
77 /**
78 * @serial Indicates whether or not this component is editable.
79 * This is package-private to avoid an accessor method.
81 boolean editable;
83 /**
84 * @serial The starting position of the selected text region.
85 * This is package-private to avoid an accessor method.
87 int selectionStart;
89 /**
90 * @serial The ending position of the selected text region.
91 * This is package-private to avoid an accessor method.
93 int selectionEnd;
95 /**
96 * @serial The text in the component
97 * This is package-private to avoid an accessor method.
99 String text;
102 * A list of listeners that will receive events from this object.
104 protected transient TextListener textListener;
106 protected class AccessibleAWTTextComponent
107 extends AccessibleAWTComponent
108 implements AccessibleText, TextListener
110 private static final long serialVersionUID = 3631432373506317811L;
112 // Constructor
113 // Adds a listener for tracking caret changes
114 public AccessibleAWTTextComponent()
116 TextComponent.this.addTextListener(this);
119 public AccessibleRole getAccessibleRole()
121 return AccessibleRole.TEXT;
124 public AccessibleStateSet getAccessibleStateSet()
126 // TODO: Docs say PropertyChangeEvent will fire if this state changes.
127 // That means that the event has to fire when editable changes.
128 AccessibleStateSet ss = super.getAccessibleStateSet();
129 if (editable)
130 ss.add(AccessibleState.EDITABLE);
131 return ss;
134 public AccessibleText getAccessibleText()
136 return this;
139 /* (non-Javadoc)
140 * @see javax.accessibility.AccessibleText#getIndexAtPoint(java.awt.Point)
142 public int getIndexAtPoint(Point point)
144 return TextComponent.this.getIndexAtPoint(point);
147 /* (non-Javadoc)
148 * @see javax.accessibility.AccessibleText#getCharacterBounds(int)
150 public Rectangle getCharacterBounds(int index)
152 return TextComponent.this.getCharacterBounds(index);
155 /* (non-Javadoc)
156 * @see javax.accessibility.AccessibleText#getCharCount()
158 public int getCharCount()
160 return text.length();
163 /* (non-Javadoc)
164 * @see javax.accessibility.AccessibleText#getCaretPosition()
166 public int getCaretPosition()
168 return TextComponent.this.getCaretPosition();
171 /* (non-Javadoc)
172 * @see javax.accessibility.AccessibleText#getAtIndex(int, int)
174 public String getAtIndex(int part, int index)
176 if (index < 0 || index >= text.length())
177 return null;
178 BreakIterator it = null;
179 switch (part)
181 case CHARACTER:
182 return text.substring(index, index + 1);
183 case WORD:
184 it = BreakIterator.getWordInstance();
185 break;
186 case SENTENCE:
187 it = BreakIterator.getSentenceInstance();
188 break;
189 default:
190 return null;
192 it.setText(text);
193 int start = index;
194 if (!it.isBoundary(index))
195 start = it.preceding(index);
196 int end = it.following(index);
197 if (end == -1)
198 return text.substring(index);
199 else
200 return text.substring(index, end);
203 /* (non-Javadoc)
204 * @see javax.accessibility.AccessibleText#getAfterIndex(int, int)
206 public String getAfterIndex(int part, int index) {
207 if (index < 0 || index >= text.length())
208 return null;
209 BreakIterator it = null;
210 switch (part)
212 case CHARACTER:
213 return text.substring(index, index + 1);
214 case WORD:
215 it = BreakIterator.getWordInstance();
216 break;
217 case SENTENCE:
218 it = BreakIterator.getSentenceInstance();
219 break;
220 default:
221 return null;
223 it.setText(text);
224 int start = index;
225 if (!it.isBoundary(index))
226 start = it.following(index);
227 // Make sure there was a complete unit. I.e. if index is in the middle
228 // of a word, return null if there is no word after the that one.
229 if (start == -1)
230 return null;
231 int end = it.following(start);
232 if (end == -1)
233 return text.substring(index);
234 else
235 return text.substring(index, end);
238 /* (non-Javadoc)
239 * @see javax.accessibility.AccessibleText#getBeforeIndex(int, int)
241 public String getBeforeIndex(int part, int index)
243 if (index < 1 || index >= text.length())
244 return null;
245 BreakIterator it = null;
246 switch (part)
248 case CHARACTER:
249 return text.substring(index - 1, index);
250 case WORD:
251 it = BreakIterator.getWordInstance();
252 break;
253 case SENTENCE:
254 it = BreakIterator.getSentenceInstance();
255 break;
256 default:
257 return null;
259 it.setText(text);
260 int end = index;
261 if (!it.isBoundary(index))
262 end = it.preceding(index);
263 // Make sure there was a complete unit. I.e. if index is in the middle
264 // of a word, return null if there is no word before that one.
265 if (end == -1)
266 return null;
267 int start = it.preceding(end);
268 if (start == -1)
269 return text.substring(0, end);
270 else
271 return text.substring(start, end);
274 /* (non-Javadoc)
275 * @see javax.accessibility.AccessibleText#getCharacterAttribute(int)
277 public AttributeSet getCharacterAttribute(int index)
279 // FIXME: I suspect this really gets filled in by subclasses.
280 return null;
283 /* (non-Javadoc)
284 * @see javax.accessibility.AccessibleText#getSelectionStart()
286 public int getSelectionStart() {
287 // TODO Auto-generated method stub
288 return selectionStart;
291 /* (non-Javadoc)
292 * @see javax.accessibility.AccessibleText#getSelectionEnd()
294 public int getSelectionEnd()
296 return selectionEnd;
299 /* (non-Javadoc)
300 * @see javax.accessibility.AccessibleText#getSelectedText()
302 public String getSelectedText()
304 if (selectionEnd - selectionStart > 0)
305 return text.substring(selectionStart, selectionEnd);
306 else
307 return null;
310 /* (non-Javadoc)
311 * @see java.awt.event.TextListener#textValueChanged(java.awt.event.TextEvent)
313 public void textValueChanged(TextEvent event)
315 // TODO Auto-generated method stub
321 /*************************************************************************/
324 * Constructors
327 TextComponent(String text)
329 this.text = text;
330 this.editable = true;
333 /*************************************************************************/
336 * Instance Methods
340 * Returns the text in this component
342 * @return The text in this component.
344 public synchronized String
345 getText()
347 TextComponentPeer tcp = (TextComponentPeer)getPeer();
348 if (tcp != null)
349 text = tcp.getText();
351 return(text);
354 /*************************************************************************/
357 * Sets the text in this component to the specified string.
359 * @param text The new text for this component.
361 public synchronized void
362 setText(String text)
364 if (text == null)
365 text = "";
367 this.text = text;
369 TextComponentPeer tcp = (TextComponentPeer)getPeer();
370 if (tcp != null)
371 tcp.setText(text);
372 setCaretPosition(0);
375 /*************************************************************************/
378 * Returns a string that contains the text that is currently selected.
380 * @return The currently selected text region.
382 public synchronized String
383 getSelectedText()
385 String alltext = getText();
386 int start = getSelectionStart();
387 int end = getSelectionEnd();
389 return(alltext.substring(start, end));
392 /*************************************************************************/
395 * Returns the starting position of the selected text region.
396 * If the text is not selected then caret position is returned.
398 * @return The starting position of the selected text region.
400 public synchronized int
401 getSelectionStart()
403 TextComponentPeer tcp = (TextComponentPeer)getPeer();
404 if (tcp != null)
405 selectionStart = tcp.getSelectionStart();
407 return(selectionStart);
410 /*************************************************************************/
413 * Sets the starting position of the selected region to the
414 * specified value. If the specified value is out of range, then it
415 * will be silently changed to the nearest legal value.
417 * @param selectionStart The new start position for selected text.
419 public synchronized void
420 setSelectionStart(int selectionStart)
422 select(selectionStart, getSelectionEnd());
425 /*************************************************************************/
428 * Returns the ending position of the selected text region.
429 * If the text is not selected, then caret position is returned
431 * @return The ending position of the selected text region.
433 public synchronized int
434 getSelectionEnd()
436 TextComponentPeer tcp = (TextComponentPeer)getPeer();
437 if (tcp != null)
438 selectionEnd = tcp.getSelectionEnd();
440 return(selectionEnd);
443 /*************************************************************************/
446 * Sets the ending position of the selected region to the
447 * specified value. If the specified value is out of range, then it
448 * will be silently changed to the nearest legal value.
450 * @param selectionEnd The new start position for selected text.
452 public synchronized void
453 setSelectionEnd(int selectionEnd)
455 select(getSelectionStart(), selectionEnd);
458 /*************************************************************************/
461 * This method sets the selected text range to the text between the
462 * specified start and end positions. Illegal values for these
463 * positions are silently fixed.
465 * @param selectionStart The new start position for the selected text.
466 * @param selectionEnd The new end position for the selected text.
468 public synchronized void
469 select(int selectionStart, int selectionEnd)
471 if (selectionStart < 0)
472 selectionStart = 0;
474 if (selectionStart > getText().length())
475 selectionStart = text.length();
477 if (selectionEnd > text.length())
478 selectionEnd = text.length();
480 if (selectionStart > selectionEnd)
481 selectionStart = selectionEnd;
483 this.selectionStart = selectionStart;
484 this.selectionEnd = selectionEnd;
486 TextComponentPeer tcp = (TextComponentPeer)getPeer();
487 if (tcp != null)
488 tcp.select(selectionStart, selectionEnd);
491 /*************************************************************************/
494 * Selects all of the text in the component.
496 public synchronized void
497 selectAll()
499 select(0, getText().length());
502 /*************************************************************************/
505 * Returns the current caret position in the text.
507 * @return The caret position in the text.
509 public synchronized int
510 getCaretPosition()
512 TextComponentPeer tcp = (TextComponentPeer)getPeer();
513 if (tcp != null)
514 return(tcp.getCaretPosition());
515 else
516 return(0);
519 /*************************************************************************/
522 * Sets the caret position to the specified value.
524 * @param caretPosition The new caret position.
526 * @exception IllegalArgumentException If the value supplied for position
527 * is less than zero.
529 * @since 1.1
531 public synchronized void
532 setCaretPosition(int caretPosition)
534 if (caretPosition < 0)
535 throw new IllegalArgumentException ();
537 TextComponentPeer tcp = (TextComponentPeer)getPeer();
538 if (tcp != null)
539 tcp.setCaretPosition(caretPosition);
542 /*************************************************************************/
545 * Tests whether or not this component's text can be edited.
547 * @return <code>true</code> if the text can be edited, <code>false</code>
548 * otherwise.
550 public boolean
551 isEditable()
553 return(editable);
556 /*************************************************************************/
559 * Sets whether or not this component's text can be edited.
561 * @param editable <code>true</code> to enable editing of the text,
562 * <code>false</code> to disable it.
564 public synchronized void
565 setEditable(boolean editable)
567 this.editable = editable;
569 TextComponentPeer tcp = (TextComponentPeer)getPeer();
570 if (tcp != null)
571 tcp.setEditable(editable);
574 /*************************************************************************/
577 * Notifies the component that it should destroy its native peer.
579 public void
580 removeNotify()
582 super.removeNotify();
585 /*************************************************************************/
588 * Adds a new listener to the list of text listeners for this
589 * component.
591 * @param listener The listener to be added.
593 public synchronized void
594 addTextListener(TextListener listener)
596 textListener = AWTEventMulticaster.add(textListener, listener);
598 enableEvents(AWTEvent.TEXT_EVENT_MASK);
601 /*************************************************************************/
604 * Removes the specified listener from the list of listeners
605 * for this component.
607 * @param listener The listener to remove.
609 public synchronized void
610 removeTextListener(TextListener listener)
612 textListener = AWTEventMulticaster.remove(textListener, listener);
615 /*************************************************************************/
618 * Processes the specified event for this component. Text events are
619 * processed by calling the <code>processTextEvent()</code> method.
620 * All other events are passed to the superclass method.
622 * @param event The event to process.
624 protected void
625 processEvent(AWTEvent event)
627 if (event instanceof TextEvent)
628 processTextEvent((TextEvent)event);
629 else
630 super.processEvent(event);
633 /*************************************************************************/
636 * Processes the specified text event by dispatching it to any listeners
637 * that are registered. Note that this method will only be called
638 * if text event's are enabled. This will be true if there are any
639 * registered listeners, or if the event has been specifically
640 * enabled using <code>enableEvents()</code>.
642 * @param event The text event to process.
644 protected void
645 processTextEvent(TextEvent event)
647 if (textListener != null)
648 textListener.textValueChanged(event);
651 void
652 dispatchEventImpl(AWTEvent e)
654 if (e.id <= TextEvent.TEXT_LAST
655 && e.id >= TextEvent.TEXT_FIRST
656 && (textListener != null
657 || (eventMask & AWTEvent.TEXT_EVENT_MASK) != 0))
658 processEvent(e);
659 else
660 super.dispatchEventImpl(e);
663 /*************************************************************************/
666 * Returns a debugging string.
668 * @return A debugging string.
670 protected String
671 paramString()
673 return(getClass().getName() + "(text=" + getText() + ")");
677 * Returns an array of all the objects currently registered as FooListeners
678 * upon this <code>TextComponent</code>. FooListeners are registered using
679 * the addFooListener method.
681 * @exception ClassCastException If listenerType doesn't specify a class or
682 * interface that implements java.util.EventListener.
684 public EventListener[] getListeners (Class listenerType)
686 if (listenerType == TextListener.class)
687 return AWTEventMulticaster.getListeners (textListener, listenerType);
689 return super.getListeners (listenerType);
693 * Returns all text listeners registered to this object.
695 public TextListener[] getTextListeners ()
697 return (TextListener[]) getListeners (TextListener.class);
701 * Gets the AccessibleContext associated with this <code>TextComponent</code>.
702 * The context is created, if necessary.
704 * @return the associated context
706 public AccessibleContext getAccessibleContext()
708 /* Create the context if this is the first request */
709 if (accessibleContext == null)
710 accessibleContext = new AccessibleAWTTextComponent();
711 return accessibleContext;
715 /*******************************/
716 // Provide AccessibleAWTTextComponent access to several peer functions that
717 // aren't publicly exposed. This is package-private to avoid an accessor
718 // method.
719 synchronized int
720 getIndexAtPoint(Point p)
722 TextComponentPeer tcp = (TextComponentPeer)getPeer();
723 if (tcp != null)
724 return tcp.getIndexAtPoint(p.x, p.y);
725 return -1;
728 synchronized Rectangle
729 getCharacterBounds(int i)
731 TextComponentPeer tcp = (TextComponentPeer)getPeer();
732 if (tcp != null)
733 return tcp.getCharacterBounds(i);
734 return null;
740 } // class TextComponent