1. /*
  2. * @(#)DefaultEditorKit.java 1.50 00/02/02
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.text;
  11. import java.io.*;
  12. import java.awt.*;
  13. import java.awt.event.ActionEvent;
  14. import java.text.*;
  15. import javax.swing.Action;
  16. import javax.swing.KeyStroke;
  17. import javax.swing.SwingConstants;
  18. /**
  19. * This is the set of things needed by a text component
  20. * to be a reasonably functioning editor for some <em>type</em>
  21. * of text document. This implementation provides a default
  22. * implementation which treats text as plain text and
  23. * provides a minimal set of actions for a simple editor.
  24. *
  25. * @author Timothy Prinzing
  26. * @version 1.50 02/02/00
  27. */
  28. public class DefaultEditorKit extends EditorKit {
  29. /**
  30. * default constructor for DefaultEditorKit
  31. */
  32. public DefaultEditorKit() {
  33. }
  34. /**
  35. * Gets the MIME type of the data that this
  36. * kit represents support for. The default
  37. * is <code>text/plain</code>.
  38. *
  39. * @return the type
  40. */
  41. public String getContentType() {
  42. return "text/plain";
  43. }
  44. /**
  45. * Fetches a factory that is suitable for producing
  46. * views of any models that are produced by this
  47. * kit. The default is to have the UI produce the
  48. * factory, so this method has no implementation.
  49. *
  50. * @return the view factory
  51. */
  52. public ViewFactory getViewFactory() {
  53. return null;
  54. }
  55. /**
  56. * Fetches the set of commands that can be used
  57. * on a text component that is using a model and
  58. * view produced by this kit.
  59. *
  60. * @return the command list
  61. */
  62. public Action[] getActions() {
  63. return defaultActions;
  64. }
  65. /**
  66. * Fetches a caret that can navigate through views
  67. * produced by the associated ViewFactory.
  68. *
  69. * @return the caret
  70. */
  71. public Caret createCaret() {
  72. return null;
  73. }
  74. /**
  75. * Creates an uninitialized text storage model (PlainDocument)
  76. * that is appropriate for this type of editor.
  77. *
  78. * @return the model
  79. */
  80. public Document createDefaultDocument() {
  81. return new PlainDocument();
  82. }
  83. /**
  84. * Inserts content from the given stream which is expected
  85. * to be in a format appropriate for this kind of content
  86. * handler.
  87. *
  88. * @param in The stream to read from
  89. * @param doc The destination for the insertion.
  90. * @param pos The location in the document to place the
  91. * content >= 0.
  92. * @exception IOException on any I/O error
  93. * @exception BadLocationException if pos represents an invalid
  94. * location within the document.
  95. */
  96. public void read(InputStream in, Document doc, int pos)
  97. throws IOException, BadLocationException {
  98. read(new InputStreamReader(in), doc, pos);
  99. }
  100. /**
  101. * Writes content from a document to the given stream
  102. * in a format appropriate for this kind of content handler.
  103. *
  104. * @param out The stream to write to
  105. * @param doc The source for the write.
  106. * @param pos The location in the document to fetch the
  107. * content >= 0.
  108. * @param len The amount to write out >= 0.
  109. * @exception IOException on any I/O error
  110. * @exception BadLocationException if pos represents an invalid
  111. * location within the document.
  112. */
  113. public void write(OutputStream out, Document doc, int pos, int len)
  114. throws IOException, BadLocationException {
  115. OutputStreamWriter osw = new OutputStreamWriter(out);
  116. write(osw, doc, pos, len);
  117. osw.flush();
  118. }
  119. /**
  120. * Inserts content from the given stream, which will be
  121. * treated as plain text.
  122. *
  123. * @param in The stream to read from
  124. * @param doc The destination for the insertion.
  125. * @param pos The location in the document to place the
  126. * content >= 0.
  127. * @exception IOException on any I/O error
  128. * @exception BadLocationException if pos represents an invalid
  129. * location within the document.
  130. */
  131. public void read(Reader in, Document doc, int pos)
  132. throws IOException, BadLocationException {
  133. char[] buff = new char[4096];
  134. int nch;
  135. boolean lastWasCR = false;
  136. boolean isCRLF = false;
  137. boolean isCR = false;
  138. int last;
  139. boolean wasEmpty = (doc.getLength() == 0);
  140. // Read in a block at a time, mapping \r\n to \n, as well as single
  141. // \r's to \n's. If a \r\n is encountered, \r\n will be set as the
  142. // newline string for the document, if \r is encountered it will
  143. // be set as the newline character, otherwise the newline property
  144. // for the document will be removed.
  145. while ((nch = in.read(buff, 0, buff.length)) != -1) {
  146. last = 0;
  147. for(int counter = 0; counter < nch; counter++) {
  148. switch(buff[counter]) {
  149. case '\r':
  150. if (lastWasCR) {
  151. isCR = true;
  152. if (counter == 0) {
  153. doc.insertString(pos, "\n", null);
  154. pos++;
  155. }
  156. else {
  157. buff[counter - 1] = '\n';
  158. }
  159. }
  160. else {
  161. lastWasCR = true;
  162. }
  163. break;
  164. case '\n':
  165. if (lastWasCR) {
  166. if (counter > (last + 1)) {
  167. doc.insertString(pos, new String(buff, last,
  168. counter - last - 1), null);
  169. pos += (counter - last - 1);
  170. }
  171. // else nothing to do, can skip \r, next write will
  172. // write \n
  173. lastWasCR = false;
  174. last = counter;
  175. isCRLF = true;
  176. }
  177. break;
  178. default:
  179. if (lastWasCR) {
  180. isCR = true;
  181. if (counter == 0) {
  182. doc.insertString(pos, "\n", null);
  183. pos++;
  184. }
  185. else {
  186. buff[counter - 1] = '\n';
  187. }
  188. lastWasCR = false;
  189. }
  190. break;
  191. }
  192. }
  193. if (last < nch) {
  194. if(lastWasCR) {
  195. if (last < (nch - 1)) {
  196. doc.insertString(pos, new String(buff, last,
  197. nch - last - 1), null);
  198. pos += (nch - last - 1);
  199. }
  200. }
  201. else {
  202. doc.insertString(pos, new String(buff, last,
  203. nch - last), null);
  204. pos += (nch - last);
  205. }
  206. }
  207. }
  208. if (lastWasCR) {
  209. doc.insertString(pos, "\n", null);
  210. isCR = true;
  211. }
  212. if (wasEmpty) {
  213. if (isCRLF) {
  214. doc.putProperty(EndOfLineStringProperty, "\r\n");
  215. }
  216. else if (isCR) {
  217. doc.putProperty(EndOfLineStringProperty, "\r");
  218. }
  219. else {
  220. doc.putProperty(EndOfLineStringProperty, "\n");
  221. }
  222. }
  223. }
  224. /**
  225. * Writes content from a document to the given stream
  226. * as plain text.
  227. *
  228. * @param out The stream to write to
  229. * @param doc The source for the write.
  230. * @param pos The location in the document to fetch the
  231. * content from >= 0.
  232. * @param len The amount to write out >= 0.
  233. * @exception IOException on any I/O error
  234. * @exception BadLocationException if pos is not within 0 and
  235. * the length of the document.
  236. */
  237. public void write(Writer out, Document doc, int pos, int len)
  238. throws IOException, BadLocationException {
  239. if ((pos < 0) || ((pos + len) > doc.getLength())) {
  240. throw new BadLocationException("DefaultEditorKit.write", pos);
  241. }
  242. Segment data = new Segment();
  243. int nleft = len;
  244. int offs = pos;
  245. Object endOfLineProperty = doc.getProperty(EndOfLineStringProperty);
  246. if (endOfLineProperty == null) {
  247. try {
  248. endOfLineProperty = System.getProperty("line.separator");
  249. } catch (SecurityException se) { }
  250. }
  251. String endOfLine;
  252. if (endOfLineProperty instanceof String) {
  253. endOfLine = (String)endOfLineProperty;
  254. }
  255. else {
  256. endOfLine = null;
  257. }
  258. if (endOfLineProperty != null && !endOfLine.equals("\n")) {
  259. // There is an end of line string that isn't \n, have to iterate
  260. // through and find all \n's and translate to end of line string.
  261. while (nleft > 0) {
  262. int n = Math.min(nleft, 4096);
  263. doc.getText(offs, n, data);
  264. int last = data.offset;
  265. char[] array = data.array;
  266. int maxCounter = last + data.count;
  267. for (int counter = last; counter < maxCounter; counter++) {
  268. if (array[counter] == '\n') {
  269. if (counter > last) {
  270. out.write(array, last, counter - last);
  271. }
  272. out.write(endOfLine);
  273. last = counter + 1;
  274. }
  275. }
  276. if (maxCounter > last) {
  277. out.write(array, last, maxCounter - last);
  278. }
  279. offs += n;
  280. nleft -= n;
  281. }
  282. }
  283. else {
  284. // Just write out text, will already have \n, no mapping to
  285. // do.
  286. while (nleft > 0) {
  287. int n = Math.min(nleft, 4096);
  288. doc.getText(offs, n, data);
  289. out.write(data.array, data.offset, data.count);
  290. offs += n;
  291. nleft -= n;
  292. }
  293. }
  294. out.flush();
  295. }
  296. /**
  297. * When reading a document if a CRLF is encountered a property
  298. * with this name is added and the value will be "\r\n".
  299. */
  300. public static final String EndOfLineStringProperty = "__EndOfLine__";
  301. // --- names of well-known actions ---------------------------
  302. /**
  303. * Name of the action to place content into the associated
  304. * document. If there is a selection, it is removed before
  305. * the new content is added.
  306. * @see #getActions
  307. */
  308. public static final String insertContentAction = "insert-content";
  309. /**
  310. * Name of the action to place a line/paragraph break into
  311. * the document. If there is a selection, it is removed before
  312. * the break is added.
  313. * @see #getActions
  314. */
  315. public static final String insertBreakAction = "insert-break";
  316. /**
  317. * Name of the action to place a tab character into
  318. * the document. If there is a selection, it is removed before
  319. * the tab is added.
  320. * @see #getActions
  321. */
  322. public static final String insertTabAction = "insert-tab";
  323. /**
  324. * Name of the action to delete the character of content that
  325. * precedes the current caret position.
  326. * @see #getActions
  327. */
  328. public static final String deletePrevCharAction = "delete-previous";
  329. /**
  330. * Name of the action to delete the character of content that
  331. * follows the current caret position.
  332. * @see #getActions
  333. */
  334. public static final String deleteNextCharAction = "delete-next";
  335. /**
  336. * Name of the action to set the editor into read-only
  337. * mode.
  338. * @see #getActions
  339. */
  340. public static final String readOnlyAction = "set-read-only";
  341. /**
  342. * Name of the action to set the editor into writeable
  343. * mode.
  344. * @see #getActions
  345. */
  346. public static final String writableAction = "set-writable";
  347. /**
  348. * Name of the action to cut the selected region
  349. * and place the contents into the system clipboard.
  350. * @see JTextComponent#cut
  351. * @see #getActions
  352. */
  353. public static final String cutAction = "cut-to-clipboard";
  354. /**
  355. * Name of the action to copy the selected region
  356. * and place the contents into the system clipboard.
  357. * @see JTextComponent#copy
  358. * @see #getActions
  359. */
  360. public static final String copyAction = "copy-to-clipboard";
  361. /**
  362. * Name of the action to paste the contents of the
  363. * system clipboard into the selected region, or before the
  364. * caret if nothing is selected.
  365. * @see JTextComponent#paste
  366. * @see #getActions
  367. */
  368. public static final String pasteAction = "paste-from-clipboard";
  369. /**
  370. * Name of the action to create a beep.
  371. * @see #getActions
  372. */
  373. public static final String beepAction = "beep";
  374. /**
  375. * Name of the action to page up vertically.
  376. * @see #getActions
  377. */
  378. public static final String pageUpAction = "page-up";
  379. /**
  380. * Name of the action to page down vertically.
  381. * @see #getActions
  382. */
  383. public static final String pageDownAction = "page-down";
  384. /**
  385. * Name of the action to page up vertically, and move the
  386. * selection.
  387. * @see #getActions
  388. */
  389. /*public*/ static final String selectionPageUpAction = "selection-page-up";
  390. /**
  391. * Name of the action to page down vertically, and move the
  392. * selection.
  393. * @see #getActions
  394. */
  395. /*public*/ static final String selectionPageDownAction = "selection-page-down";
  396. /**
  397. * Name of the action to page left horizontally, and move the
  398. * selection.
  399. * @see #getActions
  400. */
  401. /*public*/ static final String selectionPageLeftAction = "selection-page-left";
  402. /**
  403. * Name of the action to page right horizontally, and move the
  404. * selection.
  405. * @see #getActions
  406. */
  407. /*public*/ static final String selectionPageRightAction = "selection-page-right";
  408. /**
  409. * Name of the Action for moving the caret
  410. * logically forward one position.
  411. * @see #getActions
  412. */
  413. public static final String forwardAction = "caret-forward";
  414. /**
  415. * Name of the Action for moving the caret
  416. * logically backward one position.
  417. * @see #getActions
  418. */
  419. public static final String backwardAction = "caret-backward";
  420. /**
  421. * Name of the Action for extending the selection
  422. * by moving the caret logically forward one position.
  423. * @see #getActions
  424. */
  425. public static final String selectionForwardAction = "selection-forward";
  426. /**
  427. * Name of the Action for extending the selection
  428. * by moving the caret logically backward one position.
  429. * @see #getActions
  430. */
  431. public static final String selectionBackwardAction = "selection-backward";
  432. /**
  433. * Name of the Action for moving the caret
  434. * logically upward one position.
  435. * @see #getActions
  436. */
  437. public static final String upAction = "caret-up";
  438. /**
  439. * Name of the Action for moving the caret
  440. * logically downward one position.
  441. * @see #getActions
  442. */
  443. public static final String downAction = "caret-down";
  444. /**
  445. * Name of the Action for moving the caret
  446. * logically upward one position, extending the selection.
  447. * @see #getActions
  448. */
  449. public static final String selectionUpAction = "selection-up";
  450. /**
  451. * Name of the Action for moving the caret
  452. * logically downward one position, extending the selection.
  453. * @see #getActions
  454. */
  455. public static final String selectionDownAction = "selection-down";
  456. /**
  457. * Name of the Action for moving the caret
  458. * to the begining of a word.
  459. * @see #getActions
  460. */
  461. public static final String beginWordAction = "caret-begin-word";
  462. /**
  463. * Name of the Action for moving the caret
  464. * to the end of a word.
  465. * @see #getActions
  466. */
  467. public static final String endWordAction = "caret-end-word";
  468. /**
  469. * Name of the Action for moving the caret
  470. * to the begining of a word, extending the selection.
  471. * @see #getActions
  472. */
  473. public static final String selectionBeginWordAction = "selection-begin-word";
  474. /**
  475. * Name of the Action for moving the caret
  476. * to the end of a word, extending the selection.
  477. * @see #getActions
  478. */
  479. public static final String selectionEndWordAction = "selection-end-word";
  480. /**
  481. * Name of the Action for moving the caret to the begining of the
  482. * previous word.
  483. * @see #getActions
  484. */
  485. public static final String previousWordAction = "caret-previous-word";
  486. /**
  487. * Name of the Action for moving the caret to the begining of the
  488. * next word.
  489. * to the next of the document.
  490. * @see #getActions
  491. */
  492. public static final String nextWordAction = "caret-next-word";
  493. /**
  494. * Name of the Action for moving the selection to the begining of the
  495. * previous word, extending the selection.
  496. * @see #getActions
  497. */
  498. public static final String selectionPreviousWordAction = "selection-previous-word";
  499. /**
  500. * Name of the Action for moving the selection to the begining of the
  501. * next word, extending the selection.
  502. * @see #getActions
  503. */
  504. public static final String selectionNextWordAction = "selection-next-word";
  505. /**
  506. * Name of the Action for moving the caret
  507. * to the begining of a line.
  508. * @see #getActions
  509. */
  510. public static final String beginLineAction = "caret-begin-line";
  511. /**
  512. * Name of the Action for moving the caret
  513. * to the end of a line.
  514. * @see #getActions
  515. */
  516. public static final String endLineAction = "caret-end-line";
  517. /**
  518. * Name of the Action for moving the caret
  519. * to the begining of a line, extending the selection.
  520. * @see #getActions
  521. */
  522. public static final String selectionBeginLineAction = "selection-begin-line";
  523. /**
  524. * Name of the Action for moving the caret
  525. * to the end of a line, extending the selection.
  526. * @see #getActions
  527. */
  528. public static final String selectionEndLineAction = "selection-end-line";
  529. /**
  530. * Name of the Action for moving the caret
  531. * to the begining of a paragraph.
  532. * @see #getActions
  533. */
  534. public static final String beginParagraphAction = "caret-begin-paragraph";
  535. /**
  536. * Name of the Action for moving the caret
  537. * to the end of a paragraph.
  538. * @see #getActions
  539. */
  540. public static final String endParagraphAction = "caret-end-paragraph";
  541. /**
  542. * Name of the Action for moving the caret
  543. * to the begining of a paragraph, extending the selection.
  544. * @see #getActions
  545. */
  546. public static final String selectionBeginParagraphAction = "selection-begin-paragraph";
  547. /**
  548. * Name of the Action for moving the caret
  549. * to the end of a paragraph, extending the selection.
  550. * @see #getActions
  551. */
  552. public static final String selectionEndParagraphAction = "selection-end-paragraph";
  553. /**
  554. * Name of the Action for moving the caret
  555. * to the begining of the document.
  556. * @see #getActions
  557. */
  558. public static final String beginAction = "caret-begin";
  559. /**
  560. * Name of the Action for moving the caret
  561. * to the end of the document.
  562. * @see #getActions
  563. */
  564. public static final String endAction = "caret-end";
  565. /**
  566. * Name of the Action for moving the caret
  567. * to the begining of the document.
  568. * @see #getActions
  569. */
  570. public static final String selectionBeginAction = "selection-begin";
  571. /**
  572. * Name of the Action for moving the caret
  573. * to the end of the document.
  574. * @see #getActions
  575. */
  576. public static final String selectionEndAction = "selection-end";
  577. /**
  578. * Name of the Action for selecting a word around the caret.
  579. * @see #getActions
  580. */
  581. public static final String selectWordAction = "select-word";
  582. /**
  583. * Name of the Action for selecting a line around the caret.
  584. * @see #getActions
  585. */
  586. public static final String selectLineAction = "select-line";
  587. /**
  588. * Name of the Action for selecting a paragraph around the caret.
  589. * @see #getActions
  590. */
  591. public static final String selectParagraphAction = "select-paragraph";
  592. /**
  593. * Name of the Action for selecting the entire document
  594. * @see #getActions
  595. */
  596. public static final String selectAllAction = "select-all";
  597. /**
  598. * Name of the Action for removing selection
  599. * @see #getActions
  600. */
  601. /*public*/ static final String unselectAction = "unselect";
  602. /**
  603. * Name of the Action for toggling the component's orientation.
  604. * @see #getActions
  605. */
  606. /*public*/ static final String toggleComponentOrientationAction
  607. = "toggle-componentOrientation";
  608. /**
  609. * Name of the action that is executed by default if
  610. * a <em>key typed event</em> is received and there
  611. * is no keymap entry.
  612. * @see #getActions
  613. */
  614. public static final String defaultKeyTypedAction = "default-typed";
  615. // --- Action implementations ---------------------------------
  616. private static final Action[] defaultActions = {
  617. new InsertContentAction(), new DeletePrevCharAction(),
  618. new DeleteNextCharAction(), new ReadOnlyAction(),
  619. new WritableAction(), new CutAction(),
  620. new CopyAction(), new PasteAction(),
  621. new PageUpAction(pageUpAction, false),
  622. new PageDownAction(pageDownAction, false),
  623. new PageUpAction(selectionPageUpAction, true),
  624. new PageDownAction(selectionPageDownAction, true),
  625. new PageAction(selectionPageLeftAction, true, true),
  626. new PageAction(selectionPageRightAction, false, true),
  627. new InsertBreakAction(), new BeepAction(),
  628. new NextVisualPositionAction(forwardAction, false,
  629. SwingConstants.EAST),
  630. new NextVisualPositionAction(backwardAction, false,
  631. SwingConstants.WEST),
  632. new NextVisualPositionAction(selectionForwardAction, true,
  633. SwingConstants.EAST),
  634. new NextVisualPositionAction(selectionBackwardAction, true,
  635. SwingConstants.WEST),
  636. new NextVisualPositionAction(upAction, false,
  637. SwingConstants.NORTH),
  638. new NextVisualPositionAction(downAction, false,
  639. SwingConstants.SOUTH),
  640. new NextVisualPositionAction(selectionUpAction, true,
  641. SwingConstants.NORTH),
  642. new NextVisualPositionAction(selectionDownAction, true,
  643. SwingConstants.SOUTH),
  644. new BeginWordAction(beginWordAction, false),
  645. new EndWordAction(endWordAction, false),
  646. new BeginWordAction(selectionBeginWordAction, true),
  647. new EndWordAction(selectionEndWordAction, true),
  648. new PreviousWordAction(previousWordAction, false),
  649. new NextWordAction(nextWordAction, false),
  650. new PreviousWordAction(selectionPreviousWordAction, true),
  651. new NextWordAction(selectionNextWordAction, true),
  652. new BeginLineAction(beginLineAction, false),
  653. new EndLineAction(endLineAction, false),
  654. new BeginLineAction(selectionBeginLineAction, true),
  655. new EndLineAction(selectionEndLineAction, true),
  656. new BeginParagraphAction(beginParagraphAction, false),
  657. new EndParagraphAction(endParagraphAction, false),
  658. new BeginParagraphAction(selectionBeginParagraphAction, true),
  659. new EndParagraphAction(selectionEndParagraphAction, true),
  660. new BeginAction(beginAction, false),
  661. new EndAction(endAction, false),
  662. new BeginAction(selectionBeginAction, true),
  663. new EndAction(selectionEndAction, true),
  664. new DefaultKeyTypedAction(), new InsertTabAction(),
  665. new SelectWordAction(), new SelectLineAction(),
  666. new SelectParagraphAction(), new SelectAllAction(),
  667. new UnselectAction(), new ToggleComponentOrientationAction(),
  668. new DumpModelAction()
  669. };
  670. /**
  671. * The action that is executed by default if
  672. * a <em>key typed event</em> is received and there
  673. * is no keymap entry. There is a variation across
  674. * different VM's in what gets sent as a <em>key typed</em>
  675. * event, and this action tries to filter out the undesired
  676. * events. This filters the control characters and those
  677. * with the ALT modifier. It allows Control-Alt sequences
  678. * through as these form legitimate unicode characters on
  679. * some PC keyboards.
  680. * <p>
  681. * If the event doesn't get filtered, it will try to insert
  682. * content into the text editor. The content is fetched
  683. * from the command string of the ActionEvent. The text
  684. * entry is done through the <code>replaceSelection</code>
  685. * method on the target text component. This is the
  686. * action that will be fired for most text entry tasks.
  687. * <p>
  688. * <strong>Warning:</strong>
  689. * Serialized objects of this class will not be compatible with
  690. * future Swing releases. The current serialization support is appropriate
  691. * for short term storage or RMI between applications running the same
  692. * version of Swing. A future release of Swing will provide support for
  693. * long term persistence.
  694. *
  695. * @see DefaultEditorKit#defaultKeyTypedAction
  696. * @see DefaultEditorKit#getActions
  697. * @see Keymap#setDefaultAction
  698. * @see Keymap#getDefaultAction
  699. */
  700. public static class DefaultKeyTypedAction extends TextAction {
  701. /**
  702. * Creates this object with the appropriate identifier.
  703. */
  704. public DefaultKeyTypedAction() {
  705. super(defaultKeyTypedAction);
  706. }
  707. /**
  708. * The operation to perform when this action is triggered.
  709. *
  710. * @param e the action event
  711. */
  712. public void actionPerformed(ActionEvent e) {
  713. JTextComponent target = getTextComponent(e);
  714. if ((target != null) && (e != null)) {
  715. if ((! target.isEditable()) || (! target.isEnabled())) {
  716. return;
  717. }
  718. String content = e.getActionCommand();
  719. int mod = e.getModifiers();
  720. if ((content != null) && (content.length() > 0) &&
  721. ((mod & ActionEvent.ALT_MASK) == (mod & ActionEvent.CTRL_MASK))) {
  722. char c = content.charAt(0);
  723. if ((c >= 0x20) && (c != 0x7F)) {
  724. target.replaceSelection(content);
  725. }
  726. }
  727. }
  728. }
  729. }
  730. /**
  731. * Places content into the associated document.
  732. * If there is a selection, it is removed before
  733. * the new content is added.
  734. * <p>
  735. * <strong>Warning:</strong>
  736. * Serialized objects of this class will not be compatible with
  737. * future Swing releases. The current serialization support is appropriate
  738. * for short term storage or RMI between applications running the same
  739. * version of Swing. A future release of Swing will provide support for
  740. * long term persistence.
  741. *
  742. * @see DefaultEditorKit#insertContentAction
  743. * @see DefaultEditorKit#getActions
  744. */
  745. public static class InsertContentAction extends TextAction {
  746. /**
  747. * Creates this object with the appropriate identifier.
  748. */
  749. public InsertContentAction() {
  750. super(insertContentAction);
  751. }
  752. /**
  753. * The operation to perform when this action is triggered.
  754. *
  755. * @param e the action event
  756. */
  757. public void actionPerformed(ActionEvent e) {
  758. JTextComponent target = getTextComponent(e);
  759. if ((target != null) && (e != null)) {
  760. if ((! target.isEditable()) || (! target.isEnabled())) {
  761. target.getToolkit().beep();
  762. return;
  763. }
  764. String content = e.getActionCommand();
  765. if (content != null) {
  766. target.replaceSelection(content);
  767. } else {
  768. target.getToolkit().beep();
  769. }
  770. }
  771. }
  772. }
  773. /**
  774. * Places a line/paragraph break into the document.
  775. * If there is a selection, it is removed before
  776. * the break is added.
  777. * <p>
  778. * <strong>Warning:</strong>
  779. * Serialized objects of this class will not be compatible with
  780. * future Swing releases. The current serialization support is appropriate
  781. * for short term storage or RMI between applications running the same
  782. * version of Swing. A future release of Swing will provide support for
  783. * long term persistence.
  784. *
  785. * @see DefaultEditorKit#insertBreakAction
  786. * @see DefaultEditorKit#getActions
  787. */
  788. public static class InsertBreakAction extends TextAction {
  789. /**
  790. * Creates this object with the appropriate identifier.
  791. */
  792. public InsertBreakAction() {
  793. super(insertBreakAction);
  794. }
  795. /**
  796. * The operation to perform when this action is triggered.
  797. *
  798. * @param e the action event
  799. */
  800. public void actionPerformed(ActionEvent e) {
  801. JTextComponent target = getTextComponent(e);
  802. if (target != null) {
  803. if ((! target.isEditable()) || (! target.isEnabled())) {
  804. target.getToolkit().beep();
  805. return;
  806. }
  807. target.replaceSelection("\n");
  808. }
  809. }
  810. }
  811. /**
  812. * Places a tab character into the document. If there
  813. * is a selection, it is removed before the tab is added.
  814. * <p>
  815. * <strong>Warning:</strong>
  816. * Serialized objects of this class will not be compatible with
  817. * future Swing releases. The current serialization support is appropriate
  818. * for short term storage or RMI between applications running the same
  819. * version of Swing. A future release of Swing will provide support for
  820. * long term persistence.
  821. *
  822. * @see DefaultEditorKit#insertTabAction
  823. * @see DefaultEditorKit#getActions
  824. */
  825. public static class InsertTabAction extends TextAction {
  826. /**
  827. * Creates this object with the appropriate identifier.
  828. */
  829. public InsertTabAction() {
  830. super(insertTabAction);
  831. }
  832. /**
  833. * The operation to perform when this action is triggered.
  834. *
  835. * @param e the action event
  836. */
  837. public void actionPerformed(ActionEvent e) {
  838. JTextComponent target = getTextComponent(e);
  839. if (target != null) {
  840. if ((! target.isEditable()) || (! target.isEnabled())) {
  841. target.getToolkit().beep();
  842. return;
  843. }
  844. target.replaceSelection("\t");
  845. }
  846. }
  847. }
  848. /*
  849. * Deletes the character of content that precedes the
  850. * current caret position.
  851. * @see DefaultEditorKit#deletePrevCharAction
  852. * @see DefaultEditorKit#getActions
  853. */
  854. static class DeletePrevCharAction extends TextAction {
  855. /**
  856. * Creates this object with the appropriate identifier.
  857. */
  858. DeletePrevCharAction() {
  859. super(deletePrevCharAction);
  860. }
  861. /**
  862. * The operation to perform when this action is triggered.
  863. *
  864. * @param e the action event
  865. */
  866. public void actionPerformed(ActionEvent e) {
  867. JTextComponent target = getTextComponent(e);
  868. boolean beep = true;
  869. if ((target != null) && (target.isEditable())) {
  870. try {
  871. Document doc = target.getDocument();
  872. Caret caret = target.getCaret();
  873. int dot = caret.getDot();
  874. int mark = caret.getMark();
  875. if (dot != mark) {
  876. doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
  877. beep = false;
  878. } else if (dot > 0) {
  879. doc.remove(dot - 1, 1);
  880. beep = false;
  881. }
  882. } catch (BadLocationException bl) {
  883. }
  884. }
  885. if (beep) {
  886. Toolkit.getDefaultToolkit().beep();
  887. }
  888. }
  889. }
  890. /*
  891. * Deletes the character of content that follows the
  892. * current caret position.
  893. * @see DefaultEditorKit#deleteNextCharAction
  894. * @see DefaultEditorKit#getActions
  895. */
  896. static class DeleteNextCharAction extends TextAction {
  897. /* Create this object with the appropriate identifier. */
  898. DeleteNextCharAction() {
  899. super(deleteNextCharAction);
  900. }
  901. /** The operation to perform when this action is triggered. */
  902. public void actionPerformed(ActionEvent e) {
  903. JTextComponent target = getTextComponent(e);
  904. boolean beep = true;
  905. if ((target != null) && (target.isEditable())) {
  906. try {
  907. Document doc = target.getDocument();
  908. Caret caret = target.getCaret();
  909. int dot = caret.getDot();
  910. int mark = caret.getMark();
  911. if (dot != mark) {
  912. doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
  913. beep = false;
  914. } else if (dot < doc.getLength()) {
  915. doc.remove(dot, 1);
  916. beep = false;
  917. }
  918. } catch (BadLocationException bl) {
  919. }
  920. }
  921. if (beep) {
  922. Toolkit.getDefaultToolkit().beep();
  923. }
  924. }
  925. }
  926. /*
  927. * Sets the editor into read-only mode.
  928. * @see DefaultEditorKit#readOnlyAction
  929. * @see DefaultEditorKit#getActions
  930. */
  931. static class ReadOnlyAction extends TextAction {
  932. /* Create this object with the appropriate identifier. */
  933. ReadOnlyAction() {
  934. super(readOnlyAction);
  935. }
  936. /**
  937. * The operation to perform when this action is triggered.
  938. *
  939. * @param e the action event
  940. */
  941. public void actionPerformed(ActionEvent e) {
  942. JTextComponent target = getTextComponent(e);
  943. if (target != null) {
  944. target.setEditable(false);
  945. }
  946. }
  947. }
  948. /*
  949. * Sets the editor into writeable mode.
  950. * @see DefaultEditorKit#writableAction
  951. * @see DefaultEditorKit#getActions
  952. */
  953. static class WritableAction extends TextAction {
  954. /* Create this object with the appropriate identifier. */
  955. WritableAction() {
  956. super(writableAction);
  957. }
  958. /**
  959. * The operation to perform when this action is triggered.
  960. *
  961. * @param e the action event
  962. */
  963. public void actionPerformed(ActionEvent e) {
  964. JTextComponent target = getTextComponent(e);
  965. if (target != null) {
  966. target.setEditable(true);
  967. }
  968. }
  969. }
  970. /**
  971. * Cuts the selected region and place its contents
  972. * into the system clipboard.
  973. * <p>
  974. * <strong>Warning:</strong>
  975. * Serialized objects of this class will not be compatible with
  976. * future Swing releases. The current serialization support is appropriate
  977. * for short term storage or RMI between applications running the same
  978. * version of Swing. A future release of Swing will provide support for
  979. * long term persistence.
  980. *
  981. * @see DefaultEditorKit#cutAction
  982. * @see DefaultEditorKit#getActions
  983. */
  984. public static class CutAction extends TextAction {
  985. /** Create this object with the appropriate identifier. */
  986. public CutAction() {
  987. super(cutAction);
  988. }
  989. /**
  990. * The operation to perform when this action is triggered.
  991. *
  992. * @param e the action event
  993. */
  994. public void actionPerformed(ActionEvent e) {
  995. JTextComponent target = getTextComponent(e);
  996. if (target != null) {
  997. target.cut();
  998. }
  999. }
  1000. }
  1001. /**
  1002. * Coies the selected region and place its contents
  1003. * into the system clipboard.
  1004. * <p>
  1005. * <strong>Warning:</strong>
  1006. * Serialized objects of this class will not be compatible with
  1007. * future Swing releases. The current serialization support is appropriate
  1008. * for short term storage or RMI between applications running the same
  1009. * version of Swing. A future release of Swing will provide support for
  1010. * long term persistence.
  1011. *
  1012. * @see DefaultEditorKit#copyAction
  1013. * @see DefaultEditorKit#getActions
  1014. */
  1015. public static class CopyAction extends TextAction {
  1016. /** Create this object with the appropriate identifier. */
  1017. public CopyAction() {
  1018. super(copyAction);
  1019. }
  1020. /**
  1021. * The operation to perform when this action is triggered.
  1022. *
  1023. * @param e the action event
  1024. */
  1025. public void actionPerformed(ActionEvent e) {
  1026. JTextComponent target = getTextComponent(e);
  1027. if (target != null) {
  1028. target.copy();
  1029. }
  1030. }
  1031. }
  1032. /**
  1033. * Pastes the contents of the system clipboard into the
  1034. * selected region, or before the caret if nothing is
  1035. * selected.
  1036. * <p>
  1037. * <strong>Warning:</strong>
  1038. * Serialized objects of this class will not be compatible with
  1039. * future Swing releases. The current serialization support is appropriate
  1040. * for short term storage or RMI between applications running the same
  1041. * version of Swing. A future release of Swing will provide support for
  1042. * long term persistence.
  1043. *
  1044. * @see DefaultEditorKit#pasteAction
  1045. * @see DefaultEditorKit#getActions
  1046. */
  1047. public static class PasteAction extends TextAction {
  1048. /** Create this object with the appropriate identifier. */
  1049. public PasteAction() {
  1050. super(pasteAction);
  1051. }
  1052. /**
  1053. * The operation to perform when this action is triggered.
  1054. *
  1055. * @param e the action event
  1056. */
  1057. public void actionPerformed(ActionEvent e) {
  1058. JTextComponent target = getTextComponent(e);
  1059. if (target != null) {
  1060. target.paste();
  1061. }
  1062. }
  1063. }
  1064. /**
  1065. * Creates a beep.
  1066. * <p>
  1067. * <strong>Warning:</strong>
  1068. * Serialized objects of this class will not be compatible with
  1069. * future Swing releases. The current serialization support is appropriate
  1070. * for short term storage or RMI between applications running the same
  1071. * version of Swing. A future release of Swing will provide support for
  1072. * long term persistence.
  1073. *
  1074. * @see DefaultEditorKit#beepAction
  1075. * @see DefaultEditorKit#getActions
  1076. */
  1077. public static class BeepAction extends TextAction {
  1078. /** Create this object with the appropriate identifier. */
  1079. public BeepAction() {
  1080. super(beepAction);
  1081. }
  1082. /**
  1083. * The operation to perform when this action is triggered.
  1084. *
  1085. * @param e the action event
  1086. */
  1087. public void actionPerformed(ActionEvent e) {
  1088. Toolkit.getDefaultToolkit().beep();
  1089. }
  1090. }
  1091. /**
  1092. * Pages up vertically. The select version of this action extends
  1093. * the selection, instead of simply moving the caret.
  1094. *
  1095. * @see DefaultEditorKit#pageUpAction
  1096. * @see DefaultEditorKit#selectPageUpAction
  1097. * @see DefaultEditorKit#getActions
  1098. */
  1099. static class PageUpAction extends TextAction {
  1100. /** Create this object with the appropriate identifier. */
  1101. public PageUpAction(String nm, boolean select) {
  1102. super(nm);
  1103. this.select = select;
  1104. }
  1105. /** The operation to perform when this action is triggered. */
  1106. public void actionPerformed(ActionEvent e) {
  1107. JTextComponent target = getTextComponent(e);
  1108. if (target != null) {
  1109. int scrollOffset;
  1110. int selectedIndex;
  1111. Rectangle visible = new Rectangle();
  1112. Rectangle r;
  1113. target.computeVisibleRect(visible);
  1114. scrollOffset = visible.y;
  1115. visible.y -= visible.height;
  1116. if(visible.y < 0)
  1117. visible.y = 0;
  1118. scrollOffset = scrollOffset - visible.y;
  1119. target.scrollRectToVisible(visible);
  1120. selectedIndex = target.getCaretPosition();
  1121. try {
  1122. if(selectedIndex != -1) {
  1123. r = target.modelToView(selectedIndex);
  1124. if (scrollOffset == 0 && visible.y == 0 && r.y > 0) {
  1125. r.y = 0;
  1126. }
  1127. else {
  1128. r.y -= scrollOffset;
  1129. }
  1130. selectedIndex = target.viewToModel(new Point(r.x,r.y));
  1131. Document doc = target.getDocument();
  1132. if ((selectedIndex != 0) &&
  1133. (selectedIndex > (doc.getLength()-1))) {
  1134. selectedIndex = doc.getLength()-1;
  1135. }
  1136. if(selectedIndex < 0) {
  1137. selectedIndex = 0;
  1138. }
  1139. if (select)
  1140. target.moveCaretPosition(selectedIndex);
  1141. else
  1142. target.setCaretPosition(selectedIndex);
  1143. }
  1144. } catch(BadLocationException bl) {
  1145. target.getToolkit().beep();
  1146. }
  1147. }
  1148. }
  1149. private boolean select;
  1150. }
  1151. /**
  1152. * Pages down vertically. The select version of this action extends
  1153. * the selection, instead of simply moving the caret.
  1154. *
  1155. * @see DefaultEditorKit#pageDownAction
  1156. * @see DefaultEditorKit#selectPageDownAction
  1157. * @see DefaultEditorKit#getActions
  1158. */
  1159. static class PageDownAction extends TextAction {
  1160. /* Create this object with the appropriate identifier. */
  1161. PageDownAction(String nm, boolean select) {
  1162. super(nm);
  1163. this.select = select;
  1164. }
  1165. /** The operation to perform when this action is triggered. */
  1166. public void actionPerformed(ActionEvent e) {
  1167. JTextComponent target = getTextComponent(e);
  1168. if (target != null) {
  1169. int scrollOffset;
  1170. int selectedIndex;
  1171. Rectangle visible = new Rectangle();
  1172. Rectangle r;
  1173. target.computeVisibleRect(visible);
  1174. scrollOffset = visible.y;
  1175. visible.y += visible.height;
  1176. int maxHeight = target.getHeight();
  1177. if((visible.y+visible.height) > maxHeight)
  1178. visible.y = (maxHeight - visible.height);
  1179. scrollOffset = visible.y - scrollOffset;
  1180. target.scrollRectToVisible(visible);
  1181. selectedIndex = target.getCaretPosition();
  1182. try {
  1183. if(selectedIndex != -1) {
  1184. r = target.modelToView(selectedIndex);
  1185. r.y += scrollOffset;
  1186. if (scrollOffset == 0 &&
  1187. (visible.y + visible.height == maxHeight)) {
  1188. r.y = visible.y + visible.height;
  1189. }
  1190. selectedIndex = target.viewToModel(new Point(r.x,r.y));
  1191. Document doc = target.getDocument();
  1192. if ((selectedIndex != 0) &&
  1193. (selectedIndex > (doc.getLength()-1))) {
  1194. selectedIndex = doc.getLength()-1;
  1195. }
  1196. if (selectedIndex < 0) {
  1197. selectedIndex = 0;
  1198. }
  1199. if (select)
  1200. target.moveCaretPosition(selectedIndex);
  1201. else
  1202. target.setCaretPosition(selectedIndex);
  1203. }
  1204. } catch(BadLocationException bl) {
  1205. target.getToolkit().beep();
  1206. }
  1207. }
  1208. }
  1209. private boolean select;
  1210. }
  1211. /**
  1212. * Pages one view to the left or right.
  1213. */
  1214. static class PageAction extends TextAction {
  1215. /** Create this object with the appropriate identifier. */
  1216. public PageAction(String nm, boolean left, boolean select) {
  1217. super(nm);
  1218. this.select = select;
  1219. this.left = left;
  1220. }
  1221. /** The operation to perform when this action is triggered. */
  1222. public void actionPerformed(ActionEvent e) {
  1223. JTextComponent target = getTextComponent(e);
  1224. if (target != null) {
  1225. int selectedIndex;
  1226. Rectangle visible = new Rectangle();
  1227. target.computeVisibleRect(visible);
  1228. if (left) {
  1229. visible.x = Math.max(0, visible.x - visible.width);
  1230. }
  1231. else {
  1232. visible.x += visible.width;
  1233. }
  1234. target.scrollRectToVisible(visible);
  1235. selectedIndex = target.getCaretPosition();
  1236. if(selectedIndex != -1) {
  1237. if (left) {
  1238. selectedIndex = target.viewToModel
  1239. (new Point(visible.x, visible.y));
  1240. }
  1241. else {
  1242. selectedIndex = target.viewToModel
  1243. (new Point(visible.x + visible.width - 1,
  1244. visible.y + visible.height - 1));
  1245. }
  1246. Document doc = target.getDocument();
  1247. if ((selectedIndex != 0) &&
  1248. (selectedIndex > (doc.getLength()-1))) {
  1249. selectedIndex = doc.getLength()-1;
  1250. }
  1251. else if(selectedIndex < 0) {
  1252. selectedIndex = 0;
  1253. }
  1254. if (select)
  1255. target.moveCaretPosition(selectedIndex);
  1256. else
  1257. target.setCaretPosition(selectedIndex);
  1258. }
  1259. }
  1260. }
  1261. private boolean select;
  1262. private boolean left;
  1263. }
  1264. static class DumpModelAction extends TextAction {
  1265. DumpModelAction() {
  1266. super("dump-model");
  1267. }
  1268. public void actionPerformed(ActionEvent e) {
  1269. JTextComponent target = getTextComponent(e);
  1270. if (target != null) {
  1271. Document d = target.getDocument();
  1272. if (d instanceof AbstractDocument) {
  1273. ((AbstractDocument) d).dump(System.err);
  1274. }
  1275. }
  1276. }
  1277. }
  1278. /*
  1279. * Action to move the selection by way of the
  1280. * getNextVisualPositionFrom method. Constructor indicates direction
  1281. * to use.
  1282. */
  1283. static class NextVisualPositionAction extends TextAction {
  1284. /**
  1285. * Create this action with the appropriate identifier.
  1286. * @param nm the name of the action, Action.NAME.
  1287. * @param select whether to extend the selection when
  1288. * changing the caret position.
  1289. */
  1290. NextVisualPositionAction(String nm, boolean select, int direction) {
  1291. super(nm);
  1292. this.select = select;
  1293. this.direction = direction;
  1294. }
  1295. /** The operation to perform when this action is triggered. */
  1296. public void actionPerformed(ActionEvent e) {
  1297. JTextComponent target = getTextComponent(e);
  1298. if (target != null) {
  1299. Caret caret = target.getCaret();
  1300. DefaultCaret bidiCaret = (caret instanceof DefaultCaret) ?
  1301. (DefaultCaret)caret : null;
  1302. int dot = caret.getDot();
  1303. Position.Bias[] bias = new Position.Bias[1];
  1304. Point magicPosition = caret.getMagicCaretPosition();
  1305. try {
  1306. if(magicPosition == null &&
  1307. (direction == SwingConstants.NORTH ||
  1308. direction == SwingConstants.SOUTH)) {
  1309. Rectangle r = (bidiCaret != null) ?
  1310. target.getUI().modelToView(target, dot,
  1311. bidiCaret.getDotBias()) :
  1312. target.modelToView(dot);
  1313. magicPosition = new Point(r.x, r.y);
  1314. }
  1315. dot = target.getUI().getNextVisualPositionFrom(target, dot,
  1316. (bidiCaret != null) ? bidiCaret.getDotBias() :
  1317. Position.Bias.Forward, direction, bias);
  1318. if(bias[0] == null) {
  1319. bias[0] = Position.Bias.Forward;
  1320. }
  1321. if(bidiCaret != null) {
  1322. if (select) {
  1323. bidiCaret.moveDot(dot, bias[0]);
  1324. } else {
  1325. bidiCaret.setDot(dot, bias[0]);
  1326. }
  1327. }
  1328. else {
  1329. if (select) {
  1330. caret.moveDot(dot);
  1331. } else {
  1332. caret.setDot(dot);
  1333. }
  1334. }
  1335. if(magicPosition != null &&
  1336. (direction == SwingConstants.NORTH ||
  1337. direction == SwingConstants.SOUTH)) {
  1338. target.getCaret().setMagicCaretPosition(magicPosition);
  1339. }
  1340. } catch (BadLocationException ex) {
  1341. }
  1342. }
  1343. }
  1344. private boolean select;
  1345. private int direction;
  1346. }
  1347. /*
  1348. * Position the caret to the beginning of the word.
  1349. * @see DefaultEditorKit#beginWordAction
  1350. * @see DefaultEditorKit#selectBeginWordAction
  1351. * @see DefaultEditorKit#getActions
  1352. */
  1353. static class BeginWordAction extends TextAction {
  1354. /**
  1355. * Create this action with the appropriate identifier.
  1356. * @param nm the name of the action, Action.NAME.
  1357. * @param select whether to extend the selection when
  1358. * changing the caret position.
  1359. */
  1360. BeginWordAction(String nm, boolean select) {
  1361. super(nm);
  1362. this.select = select;
  1363. }
  1364. /** The operation to perform when this action is triggered. */
  1365. public void actionPerformed(ActionEvent e) {
  1366. JTextComponent target = getTextComponent(e);
  1367. if (target != null) {
  1368. try {
  1369. int offs = target.getCaretPosition();
  1370. int begOffs = Utilities.getWordStart(target, offs);
  1371. if (select) {
  1372. target.moveCaretPosition(begOffs);
  1373. } else {
  1374. target.setCaretPosition(begOffs);
  1375. }
  1376. } catch (BadLocationException bl) {
  1377. target.getToolkit().beep();
  1378. }
  1379. }
  1380. }
  1381. private boolean select;
  1382. }
  1383. /*
  1384. * Position the caret to the end of the word.
  1385. * @see DefaultEditorKit#endWordAction
  1386. * @see DefaultEditorKit#selectEndWordAction
  1387. * @see DefaultEditorKit#getActions
  1388. */
  1389. static class EndWordAction extends TextAction {
  1390. /**
  1391. * Create this action with the appropriate identifier.
  1392. * @param nm the name of the action, Action.NAME.
  1393. * @param select whether to extend the selection when
  1394. * changing the caret position.
  1395. */
  1396. EndWordAction(String nm, boolean select) {
  1397. super(nm);
  1398. this.select = select;
  1399. }
  1400. /** The operation to perform when this action is triggered. */
  1401. public void actionPerformed(ActionEvent e) {
  1402. JTextComponent target = getTextComponent(e);
  1403. if (target != null) {
  1404. try {
  1405. int offs = target.getCaretPosition();
  1406. int endOffs = Utilities.getWordEnd(target, offs);
  1407. if (select) {
  1408. target.moveCaretPosition(endOffs);
  1409. } else {
  1410. target.setCaretPosition(endOffs);
  1411. }
  1412. } catch (BadLocationException bl) {
  1413. target.getToolkit().beep();
  1414. }
  1415. }
  1416. }
  1417. private boolean select;
  1418. }
  1419. /*
  1420. * Position the caret to the previousning of the word.
  1421. * @see DefaultEditorKit#previousWordAction
  1422. * @see DefaultEditorKit#selectPreviousWordAction
  1423. * @see DefaultEditorKit#getActions
  1424. */
  1425. static class PreviousWordAction extends TextAction {
  1426. /**
  1427. * Create this action with the appropriate identifier.
  1428. * @param nm the name of the action, Action.NAME.
  1429. * @param select whether to extend the selection when
  1430. * changing the caret position.
  1431. */
  1432. PreviousWordAction(String nm, boolean select) {
  1433. super(nm);
  1434. this.select = select;
  1435. }
  1436. /** The operation to perform when this action is triggered. */
  1437. public void actionPerformed(ActionEvent e) {
  1438. JTextComponent target = getTextComponent(e);
  1439. if (target != null) {
  1440. try {
  1441. int offs = target.getCaretPosition();
  1442. offs = Utilities.getPreviousWord(target, offs);
  1443. if (select) {
  1444. target.moveCaretPosition(offs);
  1445. } else {
  1446. target.setCaretPosition(offs);
  1447. }
  1448. } catch (BadLocationException bl) {
  1449. target.getToolkit().beep();
  1450. }
  1451. }
  1452. }
  1453. private boolean select;
  1454. }
  1455. /*
  1456. * Position the caret to the next of the word.
  1457. * @see DefaultEditorKit#nextWordAction
  1458. * @see DefaultEditorKit#selectNextWordAction
  1459. * @see DefaultEditorKit#getActions
  1460. */
  1461. static class NextWordAction extends TextAction {
  1462. /**
  1463. * Create this action with the appropriate identifier.
  1464. * @param nm the name of the action, Action.NAME.
  1465. * @param select whether to extend the selection when
  1466. * changing the caret position.
  1467. */
  1468. NextWordAction(String nm, boolean select) {
  1469. super(nm);
  1470. this.select = select;
  1471. }
  1472. /** The operation to perform when this action is triggered. */
  1473. public void actionPerformed(ActionEvent e) {
  1474. JTextComponent target = getTextComponent(e);
  1475. if (target != null) {
  1476. try {
  1477. int offs = target.getCaretPosition();
  1478. offs = Utilities.getNextWord(target, offs);
  1479. if (select) {
  1480. target.moveCaretPosition(offs);
  1481. } else {
  1482. target.setCaretPosition(offs);
  1483. }
  1484. } catch (BadLocationException bl) {
  1485. target.getToolkit().beep();
  1486. }
  1487. }
  1488. }
  1489. private boolean select;
  1490. }
  1491. /*
  1492. * Position the caret to the beginning of the line.
  1493. * @see DefaultEditorKit#beginLineAction
  1494. * @see DefaultEditorKit#selectBeginLineAction
  1495. * @see DefaultEditorKit#getActions
  1496. */
  1497. static class BeginLineAction extends TextAction {
  1498. /**
  1499. * Create this action with the appropriate identifier.
  1500. * @param nm the name of the action, Action.NAME.
  1501. * @param select whether to extend the selection when
  1502. * changing the caret position.
  1503. */
  1504. BeginLineAction(String nm, boolean select) {
  1505. super(nm);
  1506. this.select = select;
  1507. }
  1508. /** The operation to perform when this action is triggered. */
  1509. public void actionPerformed(ActionEvent e) {
  1510. JTextComponent target = getTextComponent(e);
  1511. if (target != null) {
  1512. try {
  1513. int offs = target.getCaretPosition();
  1514. int begOffs = Utilities.getRowStart(target, offs);
  1515. if (select) {
  1516. target.moveCaretPosition(begOffs);
  1517. } else {
  1518. target.setCaretPosition(begOffs);
  1519. }
  1520. } catch (BadLocationException bl) {
  1521. target.getToolkit().beep();
  1522. }
  1523. }
  1524. }
  1525. private boolean select;
  1526. }
  1527. /*
  1528. * Position the caret to the end of the line.
  1529. * @see DefaultEditorKit#endLineAction
  1530. * @see DefaultEditorKit#selectEndLineAction
  1531. * @see DefaultEditorKit#getActions
  1532. */
  1533. static class EndLineAction extends TextAction {
  1534. /**
  1535. * Create this action with the appropriate identifier.
  1536. * @param nm the name of the action, Action.NAME.
  1537. * @param select whether to extend the selection when
  1538. * changing the caret position.
  1539. */
  1540. EndLineAction(String nm, boolean select) {
  1541. super(nm);
  1542. this.select = select;
  1543. }
  1544. /** The operation to perform when this action is triggered. */
  1545. public void actionPerformed(ActionEvent e) {
  1546. JTextComponent target = getTextComponent(e);
  1547. if (target != null) {
  1548. try {
  1549. int offs = target.getCaretPosition();
  1550. int endOffs = Utilities.getRowEnd(target, offs);
  1551. if (select) {
  1552. target.moveCaretPosition(endOffs);
  1553. } else {
  1554. target.setCaretPosition(endOffs);
  1555. }
  1556. } catch (BadLocationException bl) {
  1557. target.getToolkit().beep();
  1558. }
  1559. }
  1560. }
  1561. private boolean select;
  1562. }
  1563. /*
  1564. * Position the caret to the beginning of the paragraph.
  1565. * @see DefaultEditorKit#beginParagraphAction
  1566. * @see DefaultEditorKit#selectBeginParagraphAction
  1567. * @see DefaultEditorKit#getActions
  1568. */
  1569. static class BeginParagraphAction extends TextAction {
  1570. /**
  1571. * Create this action with the appropriate identifier.
  1572. * @param nm the name of the action, Action.NAME.
  1573. * @param select whether to extend the selection when
  1574. * changing the caret position.
  1575. */
  1576. BeginParagraphAction(String nm, boolean select) {
  1577. super(nm);
  1578. this.select = select;
  1579. }
  1580. /** The operation to perform when this action is triggered. */
  1581. public void actionPerformed(ActionEvent e) {
  1582. JTextComponent target = getTextComponent(e);
  1583. if (target != null) {
  1584. int offs = target.getCaretPosition();
  1585. Element elem = Utilities.getParagraphElement(target, offs);
  1586. offs = elem.getStartOffset();
  1587. if (select) {
  1588. target.moveCaretPosition(offs);
  1589. } else {
  1590. target.setCaretPosition(offs);
  1591. }
  1592. }
  1593. }
  1594. private boolean select;
  1595. }
  1596. /*
  1597. * Position the caret to the end of the paragraph.
  1598. * @see DefaultEditorKit#endParagraphAction
  1599. * @see DefaultEditorKit#selectEndParagraphAction
  1600. * @see DefaultEditorKit#getActions
  1601. */
  1602. static class EndParagraphAction extends TextAction {
  1603. /**
  1604. * Create this action with the appropriate identifier.
  1605. * @param nm the name of the action, Action.NAME.
  1606. * @param select whether to extend the selection when
  1607. * changing the caret position.
  1608. */
  1609. EndParagraphAction(String nm, boolean select) {
  1610. super(nm);
  1611. this.select = select;
  1612. }
  1613. /** The operation to perform when this action is triggered. */
  1614. public void actionPerformed(ActionEvent e) {
  1615. JTextComponent target = getTextComponent(e);
  1616. if (target != null) {
  1617. int offs = target.getCaretPosition();
  1618. Element elem = Utilities.getParagraphElement(target, offs);
  1619. offs = Math.min(target.getDocument().getLength(),
  1620. elem.getEndOffset());
  1621. if (select) {
  1622. target.moveCaretPosition(offs);
  1623. } else {
  1624. target.setCaretPosition(offs);
  1625. }
  1626. }
  1627. }
  1628. private boolean select;
  1629. }
  1630. /*
  1631. * Move the caret to the begining of the document.
  1632. * @see DefaultEditorKit#beginAction
  1633. * @see DefaultEditorKit#getActions
  1634. */
  1635. static class BeginAction extends TextAction {
  1636. /* Create this object with the appropriate identifier. */
  1637. BeginAction(String nm, boolean select) {
  1638. super(nm);
  1639. this.select = select;
  1640. }
  1641. /** The operation to perform when this action is triggered. */
  1642. public void actionPerformed(ActionEvent e) {
  1643. JTextComponent target = getTextComponent(e);
  1644. if (target != null) {
  1645. if (select) {
  1646. target.moveCaretPosition(0);
  1647. } else {
  1648. target.setCaretPosition(0);
  1649. }
  1650. }
  1651. }
  1652. private boolean select;
  1653. }
  1654. /*
  1655. * Move the caret to the end of the document.
  1656. * @see DefaultEditorKit#endAction
  1657. * @see DefaultEditorKit#getActions
  1658. */
  1659. static class EndAction extends TextAction {
  1660. /* Create this object with the appropriate identifier. */
  1661. EndAction(String nm, boolean select) {
  1662. super(nm);
  1663. this.select = select;
  1664. }
  1665. /** The operation to perform when this action is triggered. */
  1666. public void actionPerformed(ActionEvent e) {
  1667. JTextComponent target = getTextComponent(e);
  1668. if (target != null) {
  1669. Document doc = target.getDocument();
  1670. int dot = doc.getLength();
  1671. if (select) {
  1672. target.moveCaretPosition(dot);
  1673. } else {
  1674. target.setCaretPosition(dot);
  1675. }
  1676. }
  1677. }
  1678. private boolean select;
  1679. }
  1680. /*
  1681. * Select the word around the caret
  1682. * @see DefaultEditorKit#endAction
  1683. * @see DefaultEditorKit#getActions
  1684. */
  1685. static class SelectWordAction extends TextAction {
  1686. /**
  1687. * Create this action with the appropriate identifier.
  1688. * @param nm the name of the action, Action.NAME.
  1689. * @param select whether to extend the selection when
  1690. * changing the caret position.
  1691. */
  1692. SelectWordAction() {
  1693. super(selectWordAction);
  1694. start = new BeginWordAction("pigdog", false);
  1695. end = new EndWordAction("pigdog", true);
  1696. }
  1697. /** The operation to perform when this action is triggered. */
  1698. public void actionPerformed(ActionEvent e) {
  1699. start.actionPerformed(e);
  1700. end.actionPerformed(e);
  1701. }
  1702. private Action start;
  1703. private Action end;
  1704. }
  1705. /*
  1706. * Select the line around the caret
  1707. * @see DefaultEditorKit#endAction
  1708. * @see DefaultEditorKit#getActions
  1709. */
  1710. static class SelectLineAction extends TextAction {
  1711. /**
  1712. * Create this action with the appropriate identifier.
  1713. * @param nm the name of the action, Action.NAME.
  1714. * @param select whether to extend the selection when
  1715. * changing the caret position.
  1716. */
  1717. SelectLineAction() {
  1718. super(selectLineAction);
  1719. start = new BeginLineAction("pigdog", false);
  1720. end = new EndLineAction("pigdog", true);
  1721. }
  1722. /** The operation to perform when this action is triggered. */
  1723. public void actionPerformed(ActionEvent e) {
  1724. start.actionPerformed(e);
  1725. end.actionPerformed(e);
  1726. }
  1727. private Action start;
  1728. private Action end;
  1729. }
  1730. /*
  1731. * Select the paragraph around the caret
  1732. * @see DefaultEditorKit#endAction
  1733. * @see DefaultEditorKit#getActions
  1734. */
  1735. static class SelectParagraphAction extends TextAction {
  1736. /**
  1737. * Create this action with the appropriate identifier.
  1738. * @param nm the name of the action, Action.NAME.
  1739. * @param select whether to extend the selection when
  1740. * changing the caret position.
  1741. */
  1742. SelectParagraphAction() {
  1743. super(selectParagraphAction);
  1744. start = new BeginParagraphAction("pigdog", false);
  1745. end = new EndParagraphAction("pigdog", true);
  1746. }
  1747. /** The operation to perform when this action is triggered. */
  1748. public void actionPerformed(ActionEvent e) {
  1749. start.actionPerformed(e);
  1750. end.actionPerformed(e);
  1751. }
  1752. private Action start;
  1753. private Action end;
  1754. }
  1755. /*
  1756. * Select the entire document
  1757. * @see DefaultEditorKit#endAction
  1758. * @see DefaultEditorKit#getActions
  1759. */
  1760. static class SelectAllAction extends TextAction {
  1761. /**
  1762. * Create this action with the appropriate identifier.
  1763. * @param nm the name of the action, Action.NAME.
  1764. * @param select whether to extend the selection when
  1765. * changing the caret position.
  1766. */
  1767. SelectAllAction() {
  1768. super(selectAllAction);
  1769. }
  1770. /** The operation to perform when this action is triggered. */
  1771. public void actionPerformed(ActionEvent e) {
  1772. JTextComponent target = getTextComponent(e);
  1773. if (target != null) {
  1774. Document doc = target.getDocument();
  1775. target.setCaretPosition(0);
  1776. target.moveCaretPosition(doc.getLength());
  1777. }
  1778. }
  1779. }
  1780. /*
  1781. * Remove the selection, if any.
  1782. * @see DefaultEditorKit#unselectAction
  1783. * @see DefaultEditorKit#getActions
  1784. */
  1785. static class UnselectAction extends TextAction {
  1786. /**
  1787. * Create this action with the appropriate identifier.
  1788. */
  1789. UnselectAction() {
  1790. super(unselectAction);
  1791. }
  1792. /** The operation to perform when this action is triggered. */
  1793. public void actionPerformed(ActionEvent e) {
  1794. JTextComponent target = getTextComponent(e);
  1795. if (target != null) {
  1796. target.setCaretPosition(target.getCaretPosition());
  1797. }
  1798. }
  1799. }
  1800. /*
  1801. * Toggles the ComponentOrientation of the text component.
  1802. * @see DefaultEditorKit#toggleComponentOrientationAction
  1803. * @see DefaultEditorKit#getActions
  1804. */
  1805. static class ToggleComponentOrientationAction extends TextAction {
  1806. /**
  1807. * Create this action with the appropriate identifier.
  1808. */
  1809. ToggleComponentOrientationAction() {
  1810. super(toggleComponentOrientationAction);
  1811. }
  1812. /** The operation to perform when this action is triggered. */
  1813. public void actionPerformed(ActionEvent e) {
  1814. JTextComponent target = getTextComponent(e);
  1815. if (target != null) {
  1816. ComponentOrientation last = target.getComponentOrientation();
  1817. ComponentOrientation next;
  1818. if( last == ComponentOrientation.RIGHT_TO_LEFT )
  1819. next = ComponentOrientation.LEFT_TO_RIGHT;
  1820. else
  1821. next = ComponentOrientation.RIGHT_TO_LEFT;
  1822. target.setComponentOrientation(next);
  1823. target.repaint();
  1824. }
  1825. }
  1826. }
  1827. }