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