0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: /**
0018: * @author Evgeniya G. Maenkova
0019: * @version $Revision$
0020: */package javax.swing.text;
0021:
0022: import java.awt.Color;
0023: import java.awt.Component;
0024: import java.awt.ComponentOrientation;
0025: import java.awt.Container;
0026: import java.awt.Cursor;
0027: import java.awt.Dimension;
0028: import java.awt.Graphics;
0029: import java.awt.GraphicsEnvironment;
0030: import java.awt.HeadlessException;
0031: import java.awt.Insets;
0032: import java.awt.Point;
0033: import java.awt.Rectangle;
0034: import java.awt.Shape;
0035: import java.awt.event.FocusAdapter;
0036: import java.awt.event.FocusEvent;
0037: import java.awt.event.InputEvent;
0038: import java.awt.event.InputMethodEvent;
0039: import java.awt.event.KeyEvent;
0040: import java.awt.event.MouseEvent;
0041: import java.awt.font.TextAttribute;
0042: import java.awt.im.InputContext;
0043: import java.awt.im.InputMethodRequests;
0044: import java.beans.PropertyChangeEvent;
0045: import java.beans.PropertyChangeListener;
0046: import java.io.IOException;
0047: import java.io.ObjectInputStream;
0048: import java.io.Reader;
0049: import java.io.Serializable;
0050: import java.io.Writer;
0051: import java.util.ArrayList;
0052: import java.util.EventListener;
0053: import java.util.HashMap;
0054:
0055: import javax.accessibility.Accessible;
0056: import javax.accessibility.AccessibleAction;
0057: import javax.accessibility.AccessibleContext;
0058: import javax.accessibility.AccessibleEditableText;
0059: import javax.accessibility.AccessibleRole;
0060: import javax.accessibility.AccessibleState;
0061: import javax.accessibility.AccessibleStateSet;
0062: import javax.accessibility.AccessibleText;
0063: import javax.swing.Action;
0064: import javax.swing.ActionMap;
0065: import javax.swing.InputMap;
0066: import javax.swing.JComponent;
0067: import javax.swing.JViewport;
0068: import javax.swing.KeyStroke;
0069: import javax.swing.Scrollable;
0070: import javax.swing.SwingConstants;
0071: import javax.swing.SwingUtilities;
0072: import javax.swing.TransferHandler;
0073: import javax.swing.UIManager;
0074: import javax.swing.event.CaretEvent;
0075: import javax.swing.event.CaretListener;
0076: import javax.swing.event.ChangeEvent;
0077: import javax.swing.event.ChangeListener;
0078: import javax.swing.event.DocumentEvent;
0079: import javax.swing.event.DocumentListener;
0080: import javax.swing.plaf.TextUI;
0081: import javax.swing.plaf.basic.BasicTextUI;
0082:
0083: import org.apache.harmony.awt.ComponentInternals;
0084: import org.apache.harmony.awt.text.AWTHighlighter;
0085: import org.apache.harmony.awt.text.ComposedTextParams;
0086: import org.apache.harmony.awt.text.InputMethodListenerImpl;
0087: import org.apache.harmony.awt.text.InputMethodRequestsImpl;
0088: import org.apache.harmony.awt.text.PropertyNames;
0089: import org.apache.harmony.awt.text.TextCaret;
0090: import org.apache.harmony.awt.text.TextKit;
0091: import org.apache.harmony.awt.text.TextUtils;
0092: import org.apache.harmony.x.swing.StringConstants;
0093:
0094: import org.apache.harmony.x.swing.internal.nls.Messages;
0095:
0096: public abstract class JTextComponent extends JComponent implements
0097: Scrollable, Accessible {
0098:
0099: public class AccessibleJTextComponent extends
0100: JComponent.AccessibleJComponent implements AccessibleText,
0101: CaretListener, DocumentListener, AccessibleAction,
0102: AccessibleEditableText {
0103:
0104: //current caretPosition, it is changed only by method caretUpdate
0105: private int caretPosition;
0106:
0107: /**
0108: * If new document is installed to text component, accessible should to
0109: * remove itself (as DocumentListener) from old document, and add to
0110: * new document.
0111: */
0112: private class DocumentPropertyChangeListener implements
0113: PropertyChangeListener {
0114: public void propertyChange(final PropertyChangeEvent e) {
0115: Object oldValue = e.getOldValue();
0116: Object newValue = e.getNewValue();
0117: if (oldValue != null) {
0118: ((Document) oldValue)
0119: .removeDocumentListener((AccessibleJTextComponent) getAccessibleContext());
0120: }
0121: if (e.getNewValue() != null) {
0122: ((Document) newValue)
0123: .addDocumentListener((AccessibleJTextComponent) getAccessibleContext());
0124: }
0125: }
0126: }
0127:
0128: /**
0129: * Adds PropertyChangeListener to text component. If possible,
0130: * adds document listener. Initializes variable, which watch the current
0131: * caret position.
0132: */
0133: public AccessibleJTextComponent() {
0134: addCaretListener(this );
0135: JTextComponent.this .addPropertyChangeListener(
0136: StringConstants.TEXT_COMPONENT_DOCUMENT_PROPERTY,
0137: new DocumentPropertyChangeListener());
0138: if (document != null) {
0139: document.addDocumentListener(this );
0140: }
0141: if (caret != null) {
0142: caretPosition = getCaretPosition();
0143: }
0144: caretPosition = 0;
0145: }
0146:
0147: /**
0148: * If current document is instanceof Plain document, it does nothing.
0149: */
0150: public void setAttributes(final int i1, final int i2,
0151: final AttributeSet as) {
0152: checkPositions(i1, i2, document.getLength());
0153: if (document instanceof DefaultStyledDocument) {
0154: ((DefaultStyledDocument) document)
0155: .setCharacterAttributes(i1, i2 - i1, as, true);
0156: }
0157: }
0158:
0159: private void checkPositions(final int i1, final int i2,
0160: final int length) {
0161: if (i1 < 0 || i2 < i1 || i2 > length) {
0162: throw new IllegalArgumentException(Messages.getString(
0163: "swing.90", i1, i2)); //$NON-NLS-1$
0164: }
0165: }
0166:
0167: public AttributeSet getCharacterAttribute(final int offset) {
0168: Element elem = document.getDefaultRootElement();
0169: while (elem.getElementCount() > 0) {
0170: elem = elem.getElement(elem.getElementIndex(offset));
0171: }
0172: return elem.getAttributes();
0173: }
0174:
0175: public void removeUpdate(final DocumentEvent e) {
0176: documentUpdate(e);
0177: }
0178:
0179: private void documentUpdate(final DocumentEvent e) {
0180: firePropertyChange(
0181: AccessibleContext.ACCESSIBLE_TEXT_PROPERTY, null,
0182: new Integer(e.getOffset()));
0183: }
0184:
0185: public void insertUpdate(final DocumentEvent e) {
0186: documentUpdate(e);
0187: }
0188:
0189: public void changedUpdate(final DocumentEvent e) {
0190: documentUpdate(e);
0191: }
0192:
0193: /**
0194: * If e.getDot() equals to e.getMark, there is only one
0195: * PropertyChangeEvent.
0196: */
0197: public void caretUpdate(final CaretEvent e) {
0198: int dot = e.getDot();
0199: int mark = e.getMark();
0200: firePropertyChange(
0201: AccessibleContext.ACCESSIBLE_CARET_PROPERTY,
0202: new Integer(caretPosition), new Integer(dot));
0203: if (dot != mark) {
0204: firePropertyChange(
0205: AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
0206: null, getSelectedText());
0207: }
0208: }
0209:
0210: public AccessibleText getAccessibleText() {
0211: return this ;
0212: }
0213:
0214: public AccessibleStateSet getAccessibleStateSet() {
0215: AccessibleStateSet result = super .getAccessibleStateSet();
0216: if (isEditable) {
0217: result.add(AccessibleState.EDITABLE);
0218: }
0219: return result;
0220: }
0221:
0222: /**
0223: * Returns AccessibleRole.TEXT.
0224: */
0225: public AccessibleRole getAccessibleRole() {
0226: return AccessibleRole.TEXT;
0227: }
0228:
0229: public AccessibleEditableText getAccessibleEditableText() {
0230: return this ;
0231: }
0232:
0233: public AccessibleAction getAccessibleAction() {
0234: return this ;
0235: }
0236:
0237: public void setTextContents(final String s) {
0238: JTextComponent.this .setText(s);
0239: }
0240:
0241: public void insertTextAtIndex(final int i, final String s) {
0242: try {
0243: document.insertString(i, s, null);
0244: } catch (final BadLocationException e) {
0245: }
0246: }
0247:
0248: public void replaceText(final int i1, final int i2,
0249: final String s) {
0250: checkPositions(i1, i2, document.getLength());
0251: try {
0252: replaceString(i1, i2 - i1, s, null);
0253: } catch (final BadLocationException e) {
0254: }
0255: }
0256:
0257: public String getTextRange(final int p0, final int p1) {
0258: String result = null;
0259: try {
0260: result = JTextComponent.this .getText(p0, p1 - p0);
0261: } catch (final BadLocationException e) {
0262: }
0263: return result;
0264: }
0265:
0266: public String getBeforeIndex(final int part, final int index) {
0267: int offset = 0;
0268: switch (part) {
0269: case AccessibleText.CHARACTER:
0270: return (index == 0) ? null : getCharacter(index - 1);
0271: case AccessibleText.WORD:
0272: try {
0273: offset = TextUtils.getWordStart(textKit, index) - 1;
0274: } catch (final BadLocationException e) {
0275: return null;
0276: }
0277: return (offset < 0) ? null : getWord(offset);
0278: case AccessibleText.SENTENCE:
0279: Element elem = TextUtils.getParagraphElement(document,
0280: index);
0281: offset = elem.getStartOffset() - 1;
0282: return (offset < 0) ? null : getLine(offset);
0283: default:
0284: return null;
0285: }
0286: }
0287:
0288: public String getAtIndex(final int part, final int index) {
0289: switch (part) {
0290: case AccessibleText.CHARACTER:
0291: return getCharacter(index);
0292: case AccessibleText.WORD:
0293: return getWord(index);
0294: case AccessibleText.SENTENCE:
0295: return getLine(index);
0296: default:
0297: return null;
0298: }
0299: }
0300:
0301: /**
0302: * Returns char by index.
0303: */
0304: private String getCharacter(final int index) {
0305: String s = null;
0306: try {
0307: s = document.getText(index, 1);
0308: } catch (final BadLocationException e) {
0309: }
0310: return s;
0311: }
0312:
0313: /**
0314: * Returns word by index.
0315: */
0316: private String getWord(final int index) {
0317: int start = 0;
0318: int length = 0;
0319: String result = null;
0320: try {
0321: start = TextUtils.getWordStart(textKit, index);
0322: length = TextUtils.getWordEnd(textKit, index) - start;
0323: result = document.getText(start, length);
0324: } catch (final BadLocationException e) {
0325: }
0326:
0327: return result;
0328: }
0329:
0330: /**
0331: * Returns line by index.
0332: */
0333: private String getLine(final int index) {
0334: Element elem = TextUtils.getParagraphElement(document,
0335: index);
0336: if (elem == null) {
0337: return null;
0338: }
0339: int start = elem.getStartOffset();
0340: int length = elem.getEndOffset() - start;
0341: String result = null;
0342: try {
0343: result = document.getText(start, length);
0344: } catch (final BadLocationException e) {
0345: }
0346: return result;
0347: }
0348:
0349: public String getAfterIndex(final int part, final int index) {
0350: int offset = 0;
0351: switch (part) {
0352: case AccessibleText.CHARACTER:
0353: return (index == document.getLength()) ? null
0354: : getCharacter(index + 1);
0355: case AccessibleText.WORD:
0356: try {
0357: offset = TextUtils.getWordEnd(textKit, index) + 1;
0358: } catch (final BadLocationException e) {
0359: return null;
0360: }
0361:
0362: return getWord(offset);
0363: case AccessibleText.SENTENCE:
0364: Element elem = TextUtils.getParagraphElement(document,
0365: index);
0366: offset = elem.getEndOffset() + 1;
0367: return (offset < 0) ? null : getLine(offset);
0368: default:
0369: return null;
0370: }
0371: }
0372:
0373: public String getAccessibleActionDescription(final int index) {
0374: return (String) getActions()[index].getValue(Action.NAME);
0375: }
0376:
0377: public String getSelectedText() {
0378: return JTextComponent.this .getSelectedText();
0379: }
0380:
0381: public Rectangle getCharacterBounds(final int i) {
0382: Rectangle forward = null;
0383: Rectangle backward = null;
0384: try {
0385: forward = ((BasicTextUI) ui).modelToView(
0386: JTextComponent.this , i, Position.Bias.Forward);
0387: backward = ((BasicTextUI) ui).modelToView(
0388: JTextComponent.this , Math.min(document
0389: .getLength(), i + 1),
0390: Position.Bias.Backward);
0391: } catch (final BadLocationException e) {
0392: }
0393: if (forward == null || backward == null) {
0394: return null;
0395: }
0396: forward.width = Math.abs(forward.x - backward.x) + 1;
0397: forward.x = Math.min(forward.x, backward.x);
0398: return forward;
0399: }
0400:
0401: public int getIndexAtPoint(final Point p) {
0402: return JTextComponent.this .viewToModel(p);
0403: }
0404:
0405: public void selectText(final int p0, final int p1) {
0406: JTextComponent.this .select(p0, p1);
0407: }
0408:
0409: public void delete(final int i1, final int i2) {
0410: checkPositions(i1, i2, document.getLength());
0411: try {
0412: document.remove(i1, i2 - i1);
0413: } catch (final BadLocationException e) {
0414: }
0415: }
0416:
0417: /**
0418: * This operations performs by setCaretPosition and moveCaretPosition
0419: * methods of JTextComponent.
0420: */
0421: public void cut(final int p0, final int p1) {
0422: setCaretPosition(p0);
0423: moveCaretPosition(Math.max(p1, p0));
0424: JTextComponent.this .cut();
0425: }
0426:
0427: public boolean doAccessibleAction(final int index) {
0428: getActions()[index].actionPerformed(null);
0429: return true;
0430: }
0431:
0432: public void paste(final int p) {
0433: setCaretPosition(p);
0434: JTextComponent.this .paste();
0435: }
0436:
0437: public int getSelectionStart() {
0438: return JTextComponent.this .getSelectionStart();
0439: }
0440:
0441: public int getSelectionEnd() {
0442: return JTextComponent.this .getSelectionEnd();
0443: }
0444:
0445: public int getCharCount() {
0446: return document.getLength();
0447: }
0448:
0449: public int getCaretPosition() {
0450: return JTextComponent.this .getCaretPosition();
0451: }
0452:
0453: public int getAccessibleActionCount() {
0454: return getActions().length;
0455: }
0456:
0457: }
0458:
0459: public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
0460: /**
0461: * Name of default keymap, which is parent to keymap installed by UI.
0462: * Default keymap has not key binding. It has only default action
0463: * (DefaultEditorKit.DefaultKeyTypedAction)
0464: */
0465: public static final String DEFAULT_KEYMAP = "default";
0466:
0467: private static final Object DEFAULT_ACTION_KEY = new Object(); //$NON-LOCK-1$
0468: // last focused text component
0469: private static JTextComponent focusedComponent;
0470: // class to store all keymaps,which were added to JTextComponent
0471: private static HashMap keymaps;
0472: // current caret
0473: private Caret caret;
0474: // curent highlighter
0475: private transient Highlighter highlighter;
0476: // defines, whether drag is enabled
0477: private boolean isDragEnabled;
0478: // defines, whether component is editable
0479: private boolean isEditable;
0480: // current caret color
0481: private Color caretColor;
0482: // current disabled text color
0483: private Color disabledTextColor;
0484: // current selected text color
0485: private Color selectedTextColor;
0486: // current selection color
0487: private Color selectionColor;
0488: // current margin
0489: private Insets margin;
0490: // current model
0491: private Document document;
0492: // current navigation filter
0493: private transient NavigationFilter navigationFilter;
0494: // current focus accelerator
0495: private char focusAccelerator = '\0';
0496: // current keymap
0497: private transient Keymap currentKeyMap;
0498: // current component Orientation
0499: private boolean componentOrientation;
0500: // ChangeCaretListener, which was added to current caret (an removed from
0501: // old caret)
0502: private final CaretListenerImpl changeCaretListener = new CaretListenerImpl();
0503:
0504: // TransferHandler class used by cut, copy, paste methods, DnD support.
0505: private final transient TransferHandler transferHandler = new TransferHandler(
0506: null);
0507: // InputMethodListsner to receive InputMethodEvent and make appropriate
0508: // document insert
0509: private transient InputMethodListenerImpl inputMethodListener;
0510: // InputMethodRequest for method getInputRequest
0511: private transient InputMethodRequests inputMethodRequests;
0512: // CaretEvent realization, used by ChangeCaretListener
0513: private final transient CaretEventImpl caretEvent = new CaretEventImpl();
0514:
0515: private TextKitImpl textKit = new TextKitImpl();
0516:
0517: /**
0518: * Initializes default keymap. Adds default keymap to JTextComponent
0519: * Sets to null variable, that indicate last focused component
0520: */
0521: static {
0522: keymaps = new HashMap();
0523: addKeymap(DEFAULT_KEYMAP, null);
0524: getKeymap(DEFAULT_KEYMAP).setDefaultAction(
0525: new DefaultEditorKit.DefaultKeyTypedAction());
0526: focusedComponent = null;
0527: }
0528:
0529: public static class KeyBinding {
0530: public KeyStroke key;
0531: public String actionName;
0532:
0533: public KeyBinding(final KeyStroke k, final String s) {
0534: key = k;
0535: actionName = s;
0536: }
0537: }
0538:
0539: /**
0540: * Keymap interface implementation to store keymap, which was added to
0541: * JTextComponent. There are used two vectors: actions and keystrokes.
0542: * actions.get(i) is action for keystroke.get(i), for any i between 0 and
0543: * actions.size().
0544: * Also this class provides possibility to create ActionMap and InputMap
0545: * by this KeyMap (see method setKeymap).
0546: */
0547: private static class KeyMap implements Keymap {
0548: private final String name;
0549: private Keymap parent;
0550:
0551: KeyMap(final String s, final Keymap k) {
0552: name = s;
0553: parent = k;
0554: }
0555:
0556: Action defaultAction;
0557: // vector to store actions
0558: ArrayList actions = new ArrayList();
0559: // vector to store keystrokes
0560: ArrayList keystrokes = new ArrayList();
0561:
0562: public void addActionForKeyStroke(final KeyStroke key,
0563: final Action a) {
0564: actions.add(0, a);
0565: keystrokes.add(0, key);
0566: }
0567:
0568: public Action getAction(final KeyStroke key) {
0569: int index = keystrokes.lastIndexOf(key);
0570: if (index >= 0) {
0571: return (Action) actions.get(index);
0572: }
0573: return (parent != null) ? parent.getAction(key) : null;
0574: }
0575:
0576: public Action[] getBoundActions() {
0577: return (Action[]) actions
0578: .toArray(new Action[actions.size()]);
0579: }
0580:
0581: public KeyStroke[] getBoundKeyStrokes() {
0582: return (KeyStroke[]) keystrokes
0583: .toArray(new KeyStroke[keystrokes.size()]);
0584: }
0585:
0586: public Action getDefaultAction() {
0587: return (defaultAction == null && parent != null) ? parent
0588: .getDefaultAction() : defaultAction;
0589: }
0590:
0591: public KeyStroke[] getKeyStrokesForAction(final Action a) {
0592: ArrayList keys = new ArrayList();
0593: int size = actions.size();
0594: int i = actions.indexOf(a);
0595: while (i >= 0) {
0596: keys.add(0, keystrokes.get(i++));
0597: if (i == size) {
0598: break;
0599: }
0600: int tmpIndex = actions.subList(i, size).indexOf(a);
0601: i = (tmpIndex >= 0) ? tmpIndex + i : -1;
0602: }
0603: return keys.size() == 0 ? null : (KeyStroke[]) keys
0604: .toArray(new KeyStroke[keys.size()]);
0605: }
0606:
0607: public String getName() {
0608: return name;
0609: }
0610:
0611: public Keymap getResolveParent() {
0612: return parent;
0613: }
0614:
0615: public boolean isLocallyDefined(final KeyStroke key) {
0616: return keystrokes.contains(key);
0617: }
0618:
0619: public void removeBindings() {
0620: actions.clear();
0621: keystrokes.clear();
0622: }
0623:
0624: public void removeKeyStrokeBinding(final KeyStroke key) {
0625: for (int index = keystrokes.lastIndexOf(key); index >= 0; index = keystrokes
0626: .lastIndexOf(key)) {
0627:
0628: keystrokes.remove(index);
0629: actions.remove(index);
0630: }
0631: }
0632:
0633: public void setDefaultAction(final Action a) {
0634: defaultAction = a;
0635: }
0636:
0637: public void setResolveParent(final Keymap k) {
0638: parent = k;
0639: }
0640:
0641: /*
0642: * The format of the string is based on 1.5 release behavior
0643: * which can be revealed using the following code:
0644: *
0645: * KeyStroke keyStrokeX = KeyStroke.getKeyStroke(KeyEvent.VK_X,
0646: * InputEvent.CTRL_MASK);
0647: * JTextArea jtc = new JTextArea();
0648: * jtc.getKeymap().addActionForKeyStroke(keyStrokeX, new TextAction("x") {
0649: * public void actionPerformed(ActionEvent e) {
0650: * }
0651: * public String toString() {
0652: * return "Text action";
0653: * }
0654: * });
0655: * System.out.println(jtc.getKeymap());
0656: */
0657: public String toString() {
0658: String s = "Keymap[" + getName() + "]{";
0659: for (int i = 0; i < keystrokes.size(); i++) {
0660: if (i > 0) {
0661: s += ", ";
0662: }
0663: s += keystrokes.get(i) + "=" + actions.get(i);
0664: }
0665: s += "}";
0666: return s;
0667: }
0668:
0669: }
0670:
0671: public static Keymap addKeymap(final String s, final Keymap parent) {
0672: KeyMap keyMap = new KeyMap(s, parent);
0673: Object key = s == null ? keyMap : (Object) s;
0674: keymaps.put(key, keyMap);
0675: return keyMap;
0676: }
0677:
0678: /**
0679: * This method used by TextAction (TextAction.getLastFocusedTextComponent)
0680: * to get last focused component
0681: * @return last focused text component
0682: */
0683: static final JTextComponent getLastFocusedTextComponent() {
0684: return focusedComponent;
0685: }
0686:
0687: public static Keymap getKeymap(final String name) {
0688: Object result = keymaps.get(name);
0689: return result == null ? null : (Keymap) result;
0690: }
0691:
0692: public static void loadKeymap(final Keymap keymap,
0693: final JTextComponent.KeyBinding[] keys,
0694: final Action[] actions) {
0695: for (int i = 0; i < keys.length; i++) {
0696: int index = -1;
0697: for (int j = 0; j < actions.length; j++) {
0698: if (actions[j].getValue(Action.NAME).equals(
0699: keys[i].actionName)) {
0700: index = j;
0701: break;
0702: }
0703: }
0704: if (index >= 0) {
0705: keymap.addActionForKeyStroke(keys[i].key,
0706: actions[index]);
0707: }
0708: }
0709: }
0710:
0711: public static Keymap removeKeymap(final String name) {
0712: return (Keymap) keymaps.remove(name);
0713: }
0714:
0715: public JTextComponent() {
0716: ComponentInternals.getComponentInternals().setTextKit(this ,
0717: textKit);
0718: inputMethodListener = new InputMethodListenerImpl(textKit);
0719: updateUI();
0720: enableEvents(InputEvent.INPUT_METHOD_EVENT_MASK);
0721: addFocusListener(new FocusListenerImpl());
0722: setEditable(true);
0723: }
0724:
0725: private class TextKitImpl implements TextKit {
0726: TextCaret textCaret = new TextCaret() {
0727: public AWTHighlighter getHighlighter() {
0728: return null;
0729: }
0730:
0731: public void setComponent(final Component c) {
0732: }
0733:
0734: public void paint(final Graphics g) {
0735:
0736: }
0737:
0738: public void setMagicCaretPosition(final int pos,
0739: final int direction, final Point oldPoint) {
0740: try {
0741: Point newPoint = null;
0742: if (direction == SwingConstants.SOUTH
0743: || direction == SwingConstants.NORTH) {
0744: View view = getUI().getRootView(
0745: JTextComponent.this );
0746: Shape shape = getVisibleRect();
0747: if (oldPoint == null) {
0748: Rectangle r = view.modelToView(pos, shape,
0749: Position.Bias.Forward).getBounds();
0750: newPoint = new Point(r.x, r.y);
0751: } else {
0752: newPoint = oldPoint;
0753: }
0754: }
0755: JTextComponent.this .getCaret()
0756: .setMagicCaretPosition(newPoint);
0757: } catch (BadLocationException e) {
0758: e.printStackTrace();
0759: }
0760: }
0761:
0762: public int getDot() {
0763: return JTextComponent.this .getCaret().getDot();
0764: }
0765:
0766: public int getMark() {
0767: return JTextComponent.this .getCaret().getMark();
0768: }
0769:
0770: public void setDot(final int pos, final Position.Bias b) {
0771: Caret caret = JTextComponent.this .getCaret();
0772: if (caret instanceof DefaultCaret) {
0773: ((DefaultCaret) caret).setDot(pos, b);
0774: } else {
0775: caret.setDot(pos);
0776: }
0777: }
0778:
0779: public Point getMagicCaretPosition() {
0780: return JTextComponent.this .getCaret()
0781: .getMagicCaretPosition();
0782: }
0783:
0784: public void moveCaretPosition(final int pos) {
0785: JTextComponent.this .moveCaretPosition(pos);
0786: }
0787:
0788: public void setMagicCaretPosition(final Point pt) {
0789: JTextComponent.this .getCaret()
0790: .setMagicCaretPosition(pt);
0791: }
0792:
0793: public void moveDot(final int pos, final Position.Bias b) {
0794: Caret caret = JTextComponent.this .getCaret();
0795: if (caret instanceof DefaultCaret) {
0796: ((DefaultCaret) caret).moveDot(pos, b);
0797: } else {
0798: caret.moveDot(pos);
0799: }
0800: }
0801:
0802: public Position.Bias getDotBias() {
0803: if (caret instanceof DefaultCaret) {
0804: return ((DefaultCaret) caret).getDotBias();
0805: } else {
0806: return Position.Bias.Forward;
0807: }
0808: }
0809: };
0810:
0811: public boolean isEditable() {
0812: return JTextComponent.this .isEditable();
0813: }
0814:
0815: public void scrollRectToVisible(final Rectangle rect) {
0816: JTextComponent.this .scrollRectToVisible(rect);
0817: }
0818:
0819: public int viewToModel(final Point p,
0820: final Position.Bias[] biasRet) {
0821: return ((BasicTextUI) ui).viewToModel(JTextComponent.this ,
0822: p, biasRet);
0823: }
0824:
0825: public Rectangle modelToView(final int p)
0826: throws BadLocationException {
0827: return JTextComponent.this .modelToView(p);
0828:
0829: }
0830:
0831: public Rectangle modelToView(final int pos,
0832: final Position.Bias bias) throws BadLocationException {
0833: return ((BasicTextUI) ui).modelToView(JTextComponent.this ,
0834: pos, bias);
0835: }
0836:
0837: public Component getComponent() {
0838: return JTextComponent.this ;
0839: }
0840:
0841: public void revalidate() {
0842: JTextComponent.this .revalidate();
0843: }
0844:
0845: public Document getDocument() {
0846: return document;
0847: }
0848:
0849: public int getSelectionStart() {
0850: return JTextComponent.this .getSelectionStart();
0851: }
0852:
0853: public int getSelectionEnd() {
0854: return JTextComponent.this .getSelectionEnd();
0855: }
0856:
0857: public Color getDisabledTextColor() {
0858: return JTextComponent.this .getDisabledTextColor();
0859: }
0860:
0861: public Color getSelectedTextColor() {
0862: return JTextComponent.this .getSelectedTextColor();
0863: }
0864:
0865: public void replaceSelectedText(final String str) {
0866: JTextComponent.this .replaceSelection(str);
0867: }
0868:
0869: public TextCaret getCaret() {
0870: return textCaret;
0871: }
0872:
0873: public String getSelectedText() {
0874: return JTextComponent.this .getSelectedText();
0875: }
0876:
0877: public Rectangle getVisibleRect() {
0878: return JTextComponent.this .getVisibleRect();
0879: }
0880:
0881: public View getRootView() {
0882: return JTextComponent.this .getUI().getRootView(
0883: JTextComponent.this );
0884: }
0885:
0886: public boolean isScrollBarArea(final int x, final int y) {
0887: return false;
0888: }
0889:
0890: public void addCaretListeners(final EventListener listener) {
0891: }
0892:
0893: public void paintLayeredHighlights(final Graphics g,
0894: final int p0, final int p1, final Shape viewBounds,
0895: final View v) {
0896: if (highlighter instanceof LayeredHighlighter) {
0897: ((LayeredHighlighter) highlighter)
0898: .paintLayeredHighlights(g, p0, p1, viewBounds,
0899: JTextComponent.this , v);
0900: }
0901:
0902: }
0903: }
0904:
0905: private static class KeyMapWrapper {
0906: private class ActionMapWrapper extends ActionMap {
0907: public Action get(final Object key) {
0908: if (key == DEFAULT_ACTION_KEY) {
0909: return keymap.getDefaultAction();
0910: }
0911:
0912: if (lastAccessedAction != null) {
0913: if (checkAction(lastAccessedAction, key)) {
0914: return lastAccessedAction;
0915: }
0916: }
0917: final Action[] boundActions = keymap.getBoundActions();
0918: if (boundActions != null) {
0919: for (int i = 0; i < boundActions.length; i++) {
0920: final Action action = boundActions[i];
0921: if (checkAction(action, key)) {
0922: lastAccessedAction = action;
0923: return action;
0924: }
0925: }
0926: }
0927:
0928: return super .get(key);
0929: }
0930:
0931: public int size() {
0932: final Action[] boundActions = keymap.getBoundActions();
0933: int result = 1 + ((boundActions != null) ? boundActions.length
0934: : 0);
0935: return result + super .size();
0936: }
0937:
0938: private boolean checkAction(final Action action,
0939: final Object key) {
0940: if (action == key) {
0941: return true;
0942: }
0943: final Object curKey = action.getValue(Action.NAME);
0944: return (curKey != null && curKey.equals(key));
0945: }
0946: }
0947:
0948: private class InputMapWrapper extends InputMap {
0949: public Object get(final KeyStroke keystroke) {
0950: Object key = null;
0951: final Action action = keymap.getAction(keystroke);
0952: lastAccessedAction = action;
0953: if (action != null) {
0954: key = action.getValue(Action.NAME);
0955: if (key == null) {
0956: return action;
0957: }
0958: }
0959: if (key == null) {
0960: key = super .get(keystroke);
0961: }
0962: return key == null
0963: && isKeyStrokeForDefaultAction(keystroke) ? DEFAULT_ACTION_KEY
0964: : key;
0965: }
0966:
0967: public int size() {
0968: final KeyStroke[] boundKeyStrokes = keymap
0969: .getBoundKeyStrokes();
0970: int result = (boundKeyStrokes != null) ? boundKeyStrokes.length
0971: : 0;
0972: return result + super .size();
0973: }
0974:
0975: private boolean isKeyStrokeForDefaultAction(
0976: final KeyStroke keystroke) {
0977: return (keystroke.getKeyEventType() == KeyEvent.KEY_TYPED)
0978: && ((keystroke.getModifiers() & InputEvent.ALT_DOWN_MASK) == 0)
0979: && ((keystroke.getModifiers() & InputEvent.CTRL_DOWN_MASK) == 0);
0980: }
0981: }
0982:
0983: private final Keymap keymap;
0984: private final ActionMapWrapper actionMap;
0985: private final InputMapWrapper inputMap;
0986: private Action lastAccessedAction;
0987:
0988: public KeyMapWrapper(final Keymap k) {
0989: keymap = k;
0990: actionMap = new ActionMapWrapper();
0991: inputMap = new InputMapWrapper();
0992: }
0993:
0994: public ActionMap getActionMap() {
0995: return actionMap;
0996: }
0997:
0998: public InputMap getInputMap() {
0999: return inputMap;
1000: }
1001: }
1002:
1003: // ChangeListener implementation. In state Changed call fireCaretUpdate.
1004: private class CaretListenerImpl implements ChangeListener,
1005: Serializable {
1006:
1007: public void stateChanged(final ChangeEvent ce) {
1008: if (caret != null) {
1009: fireCaretUpdate(caretEvent);
1010: }
1011: }
1012:
1013: public String toString() {
1014: return "dot=" + caret.getDot() + ",mark=" + caret.getMark();
1015: }
1016: }
1017:
1018: /** CaretEvent implementation.
1019: */
1020: private class CaretEventImpl extends CaretEvent {
1021: public CaretEventImpl() {
1022: super (JTextComponent.this );
1023: }
1024:
1025: public int getDot() {
1026: return caret.getDot();
1027: }
1028:
1029: public int getMark() {
1030: return caret.getMark();
1031: }
1032: }
1033:
1034: /**
1035: * FocusListener implementation to set variable, which indicates last
1036: * focused text component.
1037: */
1038: final class FocusListenerImpl extends FocusAdapter {
1039: public void focusGained(final FocusEvent fe) {
1040: focusedComponent = JTextComponent.this ;
1041: }
1042: }
1043:
1044: public void addCaretListener(final CaretListener listener) {
1045: listenerList.add(CaretListener.class, listener);
1046: }
1047:
1048: public void copy() {
1049: TextUtils.copy(textKit);
1050: }
1051:
1052: public void cut() {
1053: TextUtils.cut(textKit);
1054: }
1055:
1056: protected void fireCaretUpdate(final CaretEvent ce) {
1057: CaretListener[] listeners = getCaretListeners();
1058: for (int i = 0; i < listeners.length; i++) {
1059: listeners[i].caretUpdate(ce);
1060: }
1061: if (ce != null) {
1062: handleComposedText(ce.getDot());
1063: }
1064: }
1065:
1066: private void handleComposedText(final int dot) {
1067: ComposedTextParams composedTextParams = getComposedTextParams();
1068: int lastInsertPosition = composedTextParams
1069: .getComposedTextStart();
1070: int composedTextLength = composedTextParams
1071: .getComposedTextLength();
1072: if (composedTextLength > 0
1073: && (dot < lastInsertPosition || dot > lastInsertPosition
1074: + composedTextLength)) {
1075: // TODO: Uncomment when InputContext is fully supported by awt
1076: // SwingUtilities.invokeLater(new Runnable() {
1077: // public void run() {
1078: // getInputContext().endComposition();
1079: // }
1080: // });
1081: }
1082: }
1083:
1084: public AccessibleContext getAccessibleContext() {
1085: if (accessibleContext == null) {
1086: accessibleContext = new AccessibleJTextComponent();
1087: }
1088: return accessibleContext;
1089:
1090: }
1091:
1092: public Action[] getActions() {
1093: return ((TextUI) ui).getEditorKit(this ).getActions();
1094: }
1095:
1096: public Caret getCaret() {
1097: return caret;
1098: }
1099:
1100: public Color getCaretColor() {
1101: return caretColor;
1102: }
1103:
1104: public CaretListener[] getCaretListeners() {
1105: return (CaretListener[]) listenerList
1106: .getListeners(CaretListener.class);
1107: }
1108:
1109: public int getCaretPosition() {
1110: return caret.getDot();
1111: }
1112:
1113: public Color getDisabledTextColor() {
1114: return disabledTextColor;
1115: }
1116:
1117: public Document getDocument() {
1118: return document;
1119: }
1120:
1121: public boolean getDragEnabled() {
1122: return isDragEnabled;
1123: }
1124:
1125: public char getFocusAccelerator() {
1126: return focusAccelerator;
1127: }
1128:
1129: public Highlighter getHighlighter() {
1130: return highlighter;
1131: }
1132:
1133: public InputMethodRequests getInputMethodRequests() {
1134: if (inputMethodRequests == null) {
1135: inputMethodRequests = new InputMethodRequestsImpl(textKit);
1136: }
1137: return inputMethodRequests;
1138: }
1139:
1140: public Keymap getKeymap() {
1141: return currentKeyMap;
1142: }
1143:
1144: public Insets getMargin() {
1145: return margin;
1146: }
1147:
1148: public NavigationFilter getNavigationFilter() {
1149: return navigationFilter;
1150: }
1151:
1152: public Dimension getPreferredScrollableViewportSize() {
1153: return getPreferredSize();
1154: }
1155:
1156: public int getScrollableBlockIncrement(final Rectangle rect,
1157: final int orientation, final int direction) {
1158: if (orientation == SwingConstants.HORIZONTAL) {
1159: return rect.width;
1160: } else if (orientation == SwingConstants.VERTICAL) {
1161: return rect.height;
1162: } else {
1163: throw new IllegalArgumentException(Messages.getString(
1164: "swing.41", orientation)); //$NON-NLS-1$
1165: }
1166: }
1167:
1168: public boolean getScrollableTracksViewportHeight() {
1169: Container c = getParent();
1170: if (c instanceof JViewport) {
1171: int height = getPreferredSize().height;
1172: return height < ((JViewport) c).getExtentSize().height;
1173: }
1174: return false;
1175: }
1176:
1177: public boolean getScrollableTracksViewportWidth() {
1178: Container c = getParent();
1179: if (c instanceof JViewport) {
1180: int width = getPreferredSize().width;
1181: return width < ((JViewport) c).getExtentSize().width;
1182: }
1183: return false;
1184: }
1185:
1186: public int getScrollableUnitIncrement(final Rectangle rect,
1187: final int orientation, final int direction) {
1188: final int DEFAULT_UNIT_NUMBER = 10;
1189: if (orientation == SwingConstants.HORIZONTAL) {
1190: return rect.width / DEFAULT_UNIT_NUMBER;
1191: } else if (orientation == SwingConstants.VERTICAL) {
1192: return rect.height / DEFAULT_UNIT_NUMBER;
1193: } else {
1194: throw new IllegalArgumentException(Messages.getString(
1195: "swing.41", orientation)); //$NON-NLS-1$
1196: }
1197: }
1198:
1199: public String getSelectedText() {
1200: String s = null;
1201: int dot = caret.getDot();
1202: int mark = caret.getMark();
1203: if (dot == mark) {
1204: return null;
1205: }
1206: try {
1207: s = document.getText(Math.min(dot, mark), Math.abs(dot
1208: - mark));
1209: } catch (final BadLocationException e) {
1210: }
1211: return s;
1212: }
1213:
1214: public Color getSelectedTextColor() {
1215: return selectedTextColor;
1216: }
1217:
1218: public Color getSelectionColor() {
1219: return selectionColor;
1220: }
1221:
1222: public int getSelectionEnd() {
1223: return Math.max(caret.getDot(), caret.getMark());
1224: }
1225:
1226: public int getSelectionStart() {
1227: return Math.min(caret.getDot(), caret.getMark());
1228: }
1229:
1230: public String getText() {
1231: String s = null;
1232: try {
1233: s = getText(0, document.getLength());
1234: } catch (final BadLocationException e) {
1235: }
1236: return s;
1237: }
1238:
1239: public String getText(final int pos, final int length)
1240: throws BadLocationException {
1241: return document.getText(pos, length);
1242: }
1243:
1244: public String getToolTipText(final MouseEvent me) {
1245: String toolTipText = super .getToolTipText();
1246: return (toolTipText != null) ? toolTipText : ((BasicTextUI) ui)
1247: .getToolTipText(this , new Point(me.getX(), me.getY()));
1248: }
1249:
1250: public TextUI getUI() {
1251: return (TextUI) ui;
1252: }
1253:
1254: public boolean isEditable() {
1255: return isEditable;
1256: }
1257:
1258: public Rectangle modelToView(final int a0)
1259: throws BadLocationException {
1260: return ((TextUI) ui).modelToView(this , a0);
1261: }
1262:
1263: public void moveCaretPosition(final int pos) {
1264: if (document == null) {
1265: return;
1266: }
1267: if (pos < 0 || pos > document.getLength()) {
1268: throw new IllegalArgumentException(Messages.getString(
1269: "swing.91", pos)); //$NON-NLS-1$
1270: }
1271: caret.moveDot(pos);
1272: }
1273:
1274: /*
1275: * The format of the string is based on 1.5 release behavior
1276: * of JTextArea class which can be revealed using the following code:
1277: *
1278: * System.out.println(new JTextArea().toString());
1279: */
1280: protected String paramString() {
1281: return super .paramString() + "," + "caretColor=" + caretColor
1282: + "," + "disabledTextColor=" + disabledTextColor + ","
1283: + "editable=" + isEditable + "," + "margin=" + margin
1284: + "," + "selectedTextColor=" + selectedTextColor + ","
1285: + "selectionColor=" + selectionColor;
1286:
1287: }
1288:
1289: public void paste() {
1290: TextUtils.paste(textKit);
1291: }
1292:
1293: /**
1294: * First, event is handlede by component's input method listener.
1295: * Second, events is handles by others input method listsners.
1296: *
1297: */
1298: protected void processInputMethodEvent(final InputMethodEvent e) {
1299: TextUtils.processIMEvent(inputMethodListener, e);
1300: super .processInputMethodEvent(e);
1301: }
1302:
1303: public void removeNotify() {
1304: super .removeNotify();
1305: if (focusedComponent == this ) {
1306: focusedComponent = null;
1307: }
1308: }
1309:
1310: public void read(final Reader reader, final Object property)
1311: throws IOException {
1312: try {
1313: document.remove(0, document.getLength());
1314: ((TextUI) ui).getEditorKit(this ).read(reader, document, 0);
1315: } catch (final BadLocationException e) {
1316: }
1317: document.putProperty(Document.StreamDescriptionProperty,
1318: property);
1319: }
1320:
1321: private void readObject(final ObjectInputStream s)
1322: throws IOException, ClassNotFoundException {
1323: s.defaultReadObject();
1324: }
1325:
1326: public void removeCaretListener(final CaretListener listener) {
1327: listenerList.remove(CaretListener.class, listener);
1328: }
1329:
1330: //See comments to setText method.
1331: public synchronized void replaceSelection(final String text) {
1332: int dot = caret.getDot();
1333: int mark = caret.getMark();
1334: try {
1335: int start = Math.min(dot, mark);
1336: int length = Math.abs(dot - mark);
1337: if (document instanceof AbstractDocument) {
1338: ((AbstractDocument) document).replace(start, length,
1339: text, null);
1340: } else {
1341: replaceString(start, length, text, null);
1342: }
1343: } catch (final BadLocationException e) {
1344: }
1345: }
1346:
1347: private void replaceString(final int offset, final int length,
1348: final String text, final AttributeSet as)
1349: throws BadLocationException {
1350: document.remove(offset, length);
1351: document.insertString(offset, text, as);
1352: }
1353:
1354: public void select(final int p0, final int p1) {
1355: int length = document.getLength();
1356: int start = Math.max(Math.min(p0, length), 0);
1357: int end = Math.max(start, Math.min(p1, length));
1358: caret.setDot(start);
1359: caret.moveDot(end);
1360: }
1361:
1362: public void selectAll() {
1363: caret.setDot(0); //TODO bias
1364: int length = document.getLength();
1365: if (caret instanceof DefaultCaret) {
1366: ((DefaultCaret) caret).moveDot(length,
1367: Position.Bias.Backward);
1368: } else {
1369: caret.moveDot(length);
1370: }
1371: }
1372:
1373: public void setCaret(final Caret c) {
1374: if (caret == c) {
1375: return;
1376: }
1377: if (caret != null) {
1378: caret.removeChangeListener(changeCaretListener);
1379: caret.deinstall(this );
1380: }
1381: if (c != null) {
1382: c.install(this );
1383: c.addChangeListener(changeCaretListener);
1384: }
1385: Caret old = caret;
1386: caret = c;
1387: firePropertyChange("caret", old, c);
1388: }
1389:
1390: public void setCaretColor(final Color c) {
1391: firePropertyChange(
1392: StringConstants.TEXT_COMPONENT_CARET_COLOR_PROPERTY,
1393: caretColor, c);
1394: caretColor = c;
1395: }
1396:
1397: public void setCaretPosition(final int pos) {
1398: if (document == null) {
1399: return;
1400: }
1401: if (pos < 0 || pos > document.getLength()) {
1402: throw new IllegalArgumentException(Messages.getString(
1403: "swing.91", pos)); //$NON-NLS-1$
1404: }
1405: caret.setDot(pos);
1406: }
1407:
1408: /**
1409: * Sets documents property java.awt.font.RUN_DIRECTION according to
1410: * direction.
1411: */
1412: public void setComponentOrientation(
1413: final ComponentOrientation direction) {
1414: componentOrientation = direction == ComponentOrientation.RIGHT_TO_LEFT;
1415: setDocumentDirection();
1416: super .setComponentOrientation(direction);
1417: }
1418:
1419: public void setDisabledTextColor(final Color c) {
1420: Color old = disabledTextColor;
1421: disabledTextColor = c;
1422: firePropertyChange(
1423: StringConstants.TEXT_COMPONENT_DISABLED_TEXT_COLOR,
1424: old, c);
1425: }
1426:
1427: /**
1428: * Sets Document Property java.awt.font.RUN_DIRECTION to
1429: * false. Removes all highlights if doc isn't current document.
1430: */
1431: public void setDocument(final Document doc) {
1432: Document old = document;
1433: if (doc != document && highlighter != null) {
1434: highlighter.removeAllHighlights();
1435: }
1436: document = doc;
1437: firePropertyChange(
1438: StringConstants.TEXT_COMPONENT_DOCUMENT_PROPERTY, old,
1439: doc);
1440: setDocumentDirection();
1441: }
1442:
1443: /**
1444: * Sets documents property java.awt.font.RUN_DIRECTION according to
1445: * direction.
1446: */
1447: private void setDocumentDirection() {
1448: if (document != null) {
1449: document.putProperty(TextAttribute.RUN_DIRECTION,
1450: new Boolean(componentOrientation));
1451: }
1452: }
1453:
1454: public void setDragEnabled(final boolean b) {
1455: if (GraphicsEnvironment.isHeadless()) {
1456: throw new HeadlessException();
1457: }
1458: isDragEnabled = b; //TODO it may be no enought(some L&F)
1459: //TODO Really it will not work, because javax.swing.Transfer doesn't
1460: //provide enough functionality. Appropriate TransferHandler sets by
1461: // BasicTextUI. But I don't know now, what should I do, if it
1462: // TransferHandler null here....
1463: if (b & (getTransferHandler() == null)) {
1464: setTransferHandler(transferHandler);
1465: }
1466: }
1467:
1468: public void setEditable(final boolean isEditable) {
1469: boolean old = this .isEditable;
1470: this .isEditable = isEditable;
1471: if (isEditable) {
1472: setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
1473: } else {
1474: setCursor(Cursor.getDefaultCursor());
1475: }
1476: firePropertyChange(StringConstants.EDITABLE_PROPERTY_CHANGED,
1477: old, isEditable);
1478: }
1479:
1480: public void setFocusAccelerator(final char accelerator) {
1481: char c = Character.toUpperCase(accelerator);
1482: char old = focusAccelerator;
1483: focusAccelerator = c;
1484: // 1.4.2
1485: firePropertyChange(FOCUS_ACCELERATOR_KEY, old, c);
1486: //1.5.0
1487: //firePropertyChange("focusAccelerator", old, c);
1488: }
1489:
1490: public void setHighlighter(final Highlighter h) {
1491: Highlighter old = highlighter;
1492: if ((h == null) && (highlighter != null)) {
1493: highlighter.deinstall(this );
1494: } else if (h != null) {
1495: h.install(this );
1496: }
1497: highlighter = h;
1498: firePropertyChange(
1499: StringConstants.TEXT_COMPONENT_HIGHLIGHTER_PROPERTY,
1500: old, h);
1501: }
1502:
1503: /**
1504: * Performs modification in ActionMap/InputMap structure.
1505: * If keymap is not null, getAction/InputMap().getParent() corresponds
1506: * to current keymap.
1507: * Keymap may be previously added to JTextComponent, then all keymap
1508: * changes will be reflected on appropriate ActionMap/InputMap.
1509: */
1510: public void setKeymap(final Keymap k) {
1511: Keymap old = currentKeyMap;
1512: if (currentKeyMap != null) {
1513: getActionMap().setParent(
1514: getActionMap().getParent().getParent());
1515: getInputMap().setParent(
1516: getInputMap().getParent().getParent());
1517: }
1518:
1519: currentKeyMap = k;
1520:
1521: if (k != null) {
1522: KeyMapWrapper wrapper = new KeyMapWrapper(k);
1523: InputMap im = wrapper.getInputMap();
1524: ActionMap am = wrapper.getActionMap();
1525: am.setParent(getActionMap().getParent());
1526: im.setParent(getInputMap().getParent());
1527: getActionMap().setParent(am);
1528: getInputMap().setParent(im);
1529: }
1530: firePropertyChange(
1531: StringConstants.TEXT_COMPONENR_KEYMAP_PROPERTY, old, k);
1532: }
1533:
1534: public void setMargin(final Insets insets) {
1535: Insets old = margin;
1536: margin = insets;
1537: firePropertyChange(
1538: StringConstants.TEXT_COMPONENT_MARGIN_PROPERTY, old,
1539: insets);
1540: }
1541:
1542: public void setNavigationFilter(final NavigationFilter filter) {
1543: NavigationFilter old = navigationFilter;
1544: navigationFilter = filter;
1545: firePropertyChange(
1546: StringConstants.TEXT_COMPONENT_NAV_FILTER_NAME, old,
1547: filter);
1548: }
1549:
1550: public void setSelectedTextColor(final Color c) {
1551: Color old = selectedTextColor;
1552: selectedTextColor = c;
1553: firePropertyChange(
1554: StringConstants.TEXT_COMPONENT_SELECTED_TEXT_COLOR,
1555: old, c);
1556: }
1557:
1558: public void setSelectionColor(final Color c) {
1559: Color old = selectionColor;
1560: selectionColor = c;
1561: firePropertyChange(
1562: StringConstants.TEXT_COMPONENT_SELECTION_COLOR_PROPERTY,
1563: old, c);
1564: }
1565:
1566: public void setSelectionEnd(final int pos) {
1567: int start = getSelectionStart();
1568: if (pos < start) {
1569: caret.setDot(pos);
1570: } else {
1571: caret.setDot(start);
1572: caret.moveDot(Math.max(start, pos));
1573: }
1574: }
1575:
1576: public void setSelectionStart(final int pos) {
1577: int end = getSelectionEnd();
1578: if (pos > end) {
1579: caret.setDot(pos);
1580: } else {
1581: caret.setDot(end);
1582: caret.moveDot(Math.min(pos, end));
1583: }
1584: }
1585:
1586: // Some clarification why (replace) differs from (remove, insert).
1587: // Replace is implemented is single transaction, so document filter
1588: // either permit this operation or not.
1589: // In the case of (remove, insert) document filter can permit remove
1590: // and forbid insert, for example. That'll be incorrectly.
1591: // If document isn't instance of AbstractDocument, document filter
1592: // cann't be installed. So such problem doesn't appears.
1593:
1594: public synchronized void setText(final String text) {
1595: try {
1596: int length = document.getLength();
1597: if (document instanceof AbstractDocument) {
1598: ((AbstractDocument) document).replace(0, length, text,
1599: null);
1600: } else {
1601: document.remove(0, length);
1602: document.insertString(0, text, null);
1603: }
1604: } catch (final BadLocationException e) {
1605: }
1606: }
1607:
1608: /**
1609: * If textUI is not null, keymap was added to JTextComponent with name
1610: * equals textUI class name.
1611: */
1612: public void setUI(final TextUI textUI) {
1613: if (textUI != null) {
1614: addKeymap(textUI.getClass().getName(), JTextComponent
1615: .getKeymap(JTextComponent.DEFAULT_KEYMAP));
1616: }
1617: super .setUI(textUI);
1618: }
1619:
1620: /**
1621: * If current UI is not null, keymap is removed (keymap, which has got name
1622: * as UI class name).
1623: */
1624: public void updateUI() {
1625: if (ui != null) {
1626: removeKeymap(ui.getClass().getName());
1627: }
1628: setUI(UIManager.getUI(this ));
1629: }
1630:
1631: public int viewToModel(final Point p) {
1632: return ((TextUI) ui).viewToModel(this , p);
1633: }
1634:
1635: public void write(final Writer writer) throws IOException {
1636: try {
1637: ((TextUI) ui).getEditorKit(this ).write(writer, document, 0,
1638: document.getLength());
1639: } catch (final BadLocationException e) {
1640: }
1641: }
1642:
1643: private ComposedTextParams getComposedTextParams() {
1644: Object currentProperty = document
1645: .getProperty(PropertyNames.COMPOSED_TEXT_PROPERTY);
1646: if (!(currentProperty instanceof ComposedTextParams)) {
1647: ComposedTextParams result = new ComposedTextParams(document);
1648: int caretPosition = getCaretPosition();
1649: result.setComposedTextStart(caretPosition);
1650: result.setLastCommittedTextStart(caretPosition);
1651: return result;
1652: }
1653: return (ComposedTextParams) currentProperty;
1654: }
1655: }
|