PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/www/tags/NOV_07_2009/htdocs/42docs/users-guide/macro-tips-input.html

#
HTML | 315 lines | 293 code | 22 blank | 0 comment | 0 complexity | cc6b70282496d8a16e1eb0b0a76f5373 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Getting Input for a Macro</title><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><link rel="home" href="index.html" title="jEdit 4.2 User's Guide"><link rel="up" href="macro-tips.html" title="Chapter 15. Macro Tips and Techniques"><link rel="previous" href="macro-tips.html" title="Chapter 15. Macro Tips and Techniques"><link rel="next" href="startup-scripts.html" title="Startup Scripts"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Getting Input for a Macro</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="macro-tips.html">Prev</a> </td><th width="60%" align="center">Chapter 15. Macro Tips and Techniques</th><td width="20%" align="right"> <a accesskey="n" href="startup-scripts.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="macro-tips-input"></a>Getting Input for a Macro</h2></div></div><div></div></div><p>
  2. The dialog-based macro discussed in <a href="dialog-macro.html" title="Chapter 14. A Dialog-Based Macro">Chapter 14, <i>A Dialog-Based Macro</i></a>
  3. reflects a conventional approach to obtaining input in a Java program.
  4. Nevertheless, it can be too lengthy or tedious for someone
  5. trying to write a macro quickly. Not every macro needs a user interface
  6. specified in such detail; some macros require only a single keystroke or
  7. no input at all. In this section we outline some other techniques for
  8. obtaining input that will help you write macros quickly.
  9. </p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="macro-tips-input-single-line"></a>Getting a Single Line of Text</h3></div></div><div></div></div><p>
  10. As mentioned earlier in <a href="helpful-methods.html" title="Helpful Methods in the
  11. Macros Class">the section called &#8220;Helpful Methods in the
  12. Macros Class&#8221;</a>, the method
  13. <tt class="function">Macros.input()</tt> offers a convenient way to obtain
  14. a single line of text input. Here is an example that inserts a pair
  15. of HTML markup tags specified by the user.
  16. </p><div class="informalexample"><table border="0" bgcolor="#E0E0E0"><tr><td><pre class="programlisting">// Insert_Tag.bsh
  17. void insertTag()
  18. {
  19. caret = textArea.getCaretPosition();
  20. tag = Macros.input(view, &#8220;<span class="quote">Enter name of tag:</span>&#8221;);
  21. if( tag == null || tag.length() == 0) return;
  22. text = textArea.getSelectedText();
  23. if(text == null) text = &#8220;<span class="quote"></span>&#8221;;
  24. sb = new StringBuffer();
  25. sb.append(&#8220;<span class="quote">&lt;</span>&#8221;).append(tag).append(&#8220;<span class="quote">&gt;</span>&#8221;);
  26. sb.append(text);
  27. sb.append(&#8220;<span class="quote">&lt;/</span>&#8221;).append(tag).append(&#8220;<span class="quote">&gt;</span>&#8221;);
  28. textArea.setSelectedText(sb.toString());
  29. if(text.length() == 0)
  30. textArea.setCaretPosition(caret + tag.length() + 2);
  31. }
  32. insertTag();
  33. // end Insert_Tag.bsh</pre></td></tr></table></div><p>
  34. Here the call to <tt class="function">Macros.input()</tt> seeks the name
  35. of the markup tag. This method sets the message box title to a fixed string,
  36. &#8220;<span class="quote">Macro input</span>&#8221;, but the specific message <span><b class="guilabel">Enter name
  37. of tag</b></span> provides all the information necessary. The return value
  38. <tt class="varname">tag</tt> must be tested to see if it is null. This would
  39. occur if the user presses the <span><b class="guilabel">Cancel</b></span> button or
  40. closes the dialog window displayed by <tt class="function">Macros.input()</tt>.
  41. </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="macro-tips-input-multiple-data"></a>Getting Multiple Data Items</h3></div></div><div></div></div><p>
  42. If more than one item of input is needed, a succession of calls to
  43. <tt class="function">Macros.input()</tt> is a possible, but awkward approach,
  44. because it would not be possible to correct early input after the
  45. corresponding message box is dismissed. Where more is required,
  46. but a full dialog layout is either unnecessary or too much work,
  47. the Java method <tt class="function">JOptionPane.showConfirmDialog()</tt>
  48. is available. The version to use has the following prototype:
  49. </p><div class="itemizedlist"><ul type="disc"><li><div class="funcsynopsis"><table border="0" summary="Function synopsis" cellspacing="0" cellpadding="0"><tr><td><code class="funcdef">public static int <b class="fsfunc">showConfirmDialog</b>(</code></td><td>Component  </td><td><var class="pdparam">parentComponent</var>, </td></tr><tr><td> </td><td>Object  </td><td><var class="pdparam">message</var>, </td></tr><tr><td> </td><td>String  </td><td><var class="pdparam">title</var>, </td></tr><tr><td> </td><td>int  </td><td><var class="pdparam">optionType</var>, </td></tr><tr><td> </td><td>int  </td><td><var class="pdparam">messageType</var><code>)</code>;</td></tr></table></div></li></ul></div><p>
  50. The usefulness of this method arises from the fact that the
  51. <tt class="varname">message</tt> parameter can be an object of any
  52. Java class (since all classes are derived from
  53. <tt class="classname">Object</tt>), or any array of objects. The
  54. following example shows how this feature can be used.
  55. </p><div class="informalexample"><table border="0" bgcolor="#E0E0E0"><tr><td><pre class="programlisting">// excerpt from Write_File_Header.bsh
  56. title = &#8220;<span class="quote">Write file header</span>&#8221;;
  57. currentName = buffer.getName();
  58. nameField = new JTextField(currentName);
  59. authorField = new JTextField(&#8220;<span class="quote">Your name here</span>&#8221;);
  60. descField = new JTextField(&#8220;<span class="quote"></span>&#8221;, 25);
  61. namePanel = new JPanel(new GridLayout(1, 2));
  62. nameLabel = new JLabel(&#8220;<span class="quote">Name of file:</span>&#8221;, SwingConstants.LEFT);
  63. saveField = new JCheckBox(&#8220;<span class="quote">Save file when done</span>&#8221;,
  64. !buffer.isNewFile());
  65. namePanel.add(nameLabel);
  66. namePanel.add(saveField);
  67. message = new Object[9];
  68. message[0] = namePanel;
  69. message[1] = nameField;
  70. message[2] = Box.createVerticalStrut(10);
  71. message[3] = &#8220;<span class="quote">Author's name:</span>&#8221;;
  72. message[4] = authorField;
  73. message[5] = Box.createVerticalStrut(10);
  74. message[6] = &#8220;<span class="quote">Enter description:</span>&#8221;;
  75. message[7] = descField;
  76. message[8] = Box.createVerticalStrut(5);
  77. if( JOptionPane.OK_OPTION !=
  78. JOptionPane.showConfirmDialog(view, message, title,
  79. JOptionPane.OK_CANCEL_OPTION,
  80. JOptionPane.QUESTION_MESSAGE))
  81. return null;
  82. // *****remainder of macro script omitted*****
  83. // end excerpt from Write_File_Header.bsh</pre></td></tr></table></div><p>
  84. This macro takes several items of user input and produces a formatted
  85. file header at the beginning of the buffer. The full macro is included in
  86. the set of macros installed by jEdit. There are a number of input
  87. features of this excerpt worth noting.
  88. </p><div class="itemizedlist"><ul type="disc"><li><p>
  89. The macro uses a total of seven visible components. Two of them are
  90. created behind the scenes by <tt class="function">showConfirmDialog()</tt>,
  91. the rest are made by the macro. To arrange them, the script creates an
  92. array of <tt class="classname">Object</tt> objects and assigns components to
  93. each location in the array. This translates to a fixed, top-to-bottom
  94. arrangement in the message box created by
  95. <tt class="function">showConfirmDialog()</tt>.
  96. </p></li><li><p>
  97. The macro uses <tt class="classname">JTextField</tt> objects to
  98. obtain most of the input data. The fields <tt class="varname">nameField</tt>
  99. and <tt class="varname">authorField</tt> are created with constructors
  100. that take the initial, default text to be displayed in the field as a
  101. parameter. When the message box is displayed, the default text
  102. will appear and can be altered or deleted by the user.
  103. </p></li><li><p>
  104. The text field <tt class="varname">descField</tt> uses an empty string for its
  105. initial value. The second parameter in its constructor sets the width of
  106. the text field component, expressed as the number of characters of
  107. &#8220;<span class="quote">average</span>&#8221; width. When
  108. <tt class="function">showConfirmDialog()</tt> prepares the layout of the
  109. message box, it sets the width wide enough to accommodate the
  110. designated with of <tt class="varname">descField</tt>. This technique produces
  111. a message box and input text fields that are wide enough for your data
  112. with one line of code.
  113. </p></li><li><p>
  114. The displayed message box includes a <tt class="classname">JCheckBox</tt>
  115. component that determines whether the buffer will be saved to disk
  116. immediately after the file header is written. To conserve space
  117. in the message box, we want to display the check box to the
  118. right of the label <span><b class="guilabel">Name of file:</b></span>. To do that,
  119. we create a <tt class="classname">JPanel</tt> object and populate it with
  120. the label and the checkbox in a left-to-right
  121. <tt class="classname">GridLayout</tt>. The <tt class="classname">JPanel</tt>
  122. containing the two components is then added to the beginning of
  123. <tt class="varname">message</tt> array.
  124. </p></li><li><p>
  125. The two visible components created by
  126. <tt class="function">showConfirmDialog()</tt> appear at positions 3 and 6 of
  127. the <tt class="varname">message</tt> array. Only the text is required; they
  128. are rendered as text labels.
  129. </p></li><li><p>
  130. There are three invisible components created by
  131. <tt class="function">showConfirmDialog()</tt>. Each of them involves
  132. a call to <tt class="function">Box.createVerticalStrut()</tt>. The
  133. <tt class="classname">Box</tt> class is a sophisticated layout class
  134. that gives the user great flexibility in sizing and positioning
  135. components. Here we use a <tt class="function">static</tt> method of
  136. the <tt class="classname">Box</tt> class that produces a vertical
  137. <i class="glossterm">strut</i>. This is a transparent component
  138. whose width expands to fill its parent component (in this case,
  139. the message box). The single parameter indicates the height
  140. of the strut in pixels. The last call to
  141. <tt class="function">createVerticalStrut()</tt> separates the
  142. description text field from the <span><b class="guilabel">OK</b></span> and
  143. <span><b class="guilabel">Cancel</b></span> buttons that are automatically added
  144. by <tt class="function">showConfirmDialog()</tt>.
  145. </p></li><li><p>
  146. Finally, the call to <tt class="function">showConfirmDialog()</tt> uses
  147. defined constants for the option type and the message type. The
  148. constants are the same as those used with the
  149. <tt class="function">Macros.confirm()</tt> method; see
  150. <a href="helpful-methods.html" title="Helpful Methods in the
  151. Macros Class">the section called &#8220;Helpful Methods in the
  152. Macros Class&#8221;</a>. The
  153. option type signifies the use of <span><b class="guilabel">OK</b></span>
  154. and <span><b class="guilabel">Cancel</b></span> buttons. The
  155. <tt class="constant">QUERY_MESSAGE</tt> message type causes the message box
  156. to display a question mark icon.
  157. </p><p>
  158. The return value of the method
  159. is tested against the value <tt class="constant">OK_OPTION</tt>. If
  160. the return value is something else (because the
  161. <span><b class="guilabel">Cancel</b></span> button was pressed or because the
  162. message box window was closed without a button press), a
  163. <tt class="constant">null</tt> value is returned to a calling function,
  164. signaling that the user canceled macro execution. If the return
  165. value is <tt class="constant">OK_OPTION</tt>, each of the input components
  166. can yield their contents for further processing by calls to
  167. <tt class="function">JTextField.getText()</tt> (or, in the case of
  168. the check box, <tt class="function">JCheckBox.isSelected()</tt>).
  169. </p></li></ul></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="tips-macro-input-combo"></a>Selecting Input From a List</h3></div></div><div></div></div><p>
  170. Another useful way to get user input for a macro is to use a combo box
  171. containing a number of pre-set options. If this is the only input
  172. required, one of the versions of <tt class="function">showInputDialog()</tt>
  173. in the <tt class="classname">JOptionPane</tt> class provides a shortcut.
  174. Here is its prototype:
  175. </p><div class="itemizedlist"><ul type="disc"><li><div class="funcsynopsis"><table border="0" summary="Function synopsis" cellspacing="0" cellpadding="0"><tr><td><code class="funcdef">public static Object <b class="fsfunc">showInputDialog</b>(</code></td><td>Component  </td><td><var class="pdparam">parentComponent</var>, </td></tr><tr><td> </td><td>Object  </td><td><var class="pdparam">message</var>, </td></tr><tr><td> </td><td>String  </td><td><var class="pdparam">title</var>, </td></tr><tr><td> </td><td>int  </td><td><var class="pdparam">messageType</var>, </td></tr><tr><td> </td><td>Icon  </td><td><var class="pdparam">icon</var>, </td></tr><tr><td> </td><td>Object[]  </td><td><var class="pdparam">selectionValues</var>, </td></tr><tr><td> </td><td>Object  </td><td><var class="pdparam">initialSelectionValue</var><code>)</code>;</td></tr></table></div></li></ul></div><p>
  176. This method creates a message box containing a drop-down list of the
  177. options specified in the method's parameters, along with
  178. <span><b class="guilabel">OK</b></span> and <span><b class="guilabel">Cancel</b></span> buttons.
  179. Compared to <tt class="function">showConfirmDialog()</tt>, this method lacks
  180. an <tt class="varname">optionType</tt> parameter and has three additional
  181. parameters: an <tt class="varname">icon</tt> to display in the dialog
  182. (which can be set to <tt class="constant">null</tt>), an array of
  183. <tt class="varname">selectionValues</tt> objects, and a reference to one
  184. of the options as the <tt class="varname">initialSelectionValue</tt> to be
  185. displayed. In addition, instead of returning an <tt class="classname">int</tt>
  186. representing the user's action, <tt class="function">showInputDialog()</tt>
  187. returns the <tt class="classname">Object</tt> corresponding to the user's
  188. selection, or <tt class="constant">null</tt> if the selection is canceled.
  189. </p><p>
  190. The following macro fragment illustrates the use of this method.
  191. </p><div class="informalexample"><table border="0" bgcolor="#E0E0E0"><tr><td><pre class="programlisting">// fragment illustrating use of showInputDialog()
  192. options = new Object[5];
  193. options[0] = "JLabel";
  194. options[1] = "JTextField";
  195. options[2] = "JCheckBox";
  196. options[3] = "HistoryTextField";
  197. options[4} = "-- other --";
  198. result = JOptionPane.showInputDialog(view,
  199. "Choose component class",
  200. "Select class for input component",
  201. JOptionPane.QUESTION_MESSAGE,
  202. null, options, options[0]);</pre></td></tr></table></div><p>
  203. The return value <tt class="varname">result</tt> will contain either the
  204. <tt class="classname">String</tt> object representing the selected text
  205. item or <tt class="constant">null</tt> representing no selection. Any
  206. further use of this fragment would have to test the value of
  207. <tt class="varname">result</tt> and likely exit from the macro if the value
  208. equaled <tt class="constant">null</tt>.
  209. </p><p>
  210. A set of options can be similarly placed in a
  211. <tt class="classname">JComboBox</tt> component created as part of a larger
  212. dialog or <tt class="function">showMessageDialog()</tt> layout. Here are some
  213. code fragments showing this approach:
  214. </p><div class="informalexample"><table border="0" bgcolor="#E0E0E0"><tr><td><pre class="programlisting">// fragments from Display_Abbreviations.bsh
  215. // import statements and other code omitted
  216. // from main routine, this method call returns an array
  217. // of Strings representing the names of abbreviation sets
  218. abbrevSets = getActiveSets();
  219. ...
  220. // from showAbbrevs() method
  221. combo = new JComboBox(abbrevSets);
  222. // set width to uniform size regardless of combobox contents
  223. Dimension dim = combo.getPreferredSize();
  224. dim.width = Math.max(dim.width, 120);
  225. combo.setPreferredSize(dim);
  226. combo.setSelectedItem(STARTING_SET); // defined as "global"
  227. // end fragments</pre></td></tr></table></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="macro-tips-single-char"></a>Using a Single Keypress as Input</h3></div></div><div></div></div><p>
  228. Some macros may choose to emulate the style of character-based text
  229. editors such as <span class="application">emacs</span> or
  230. <span class="application">vi</span>. They will require only a single keypress
  231. as input that would be handled by the macro but not displayed on the
  232. screen. If the keypress corresponds to a character value, jEdit can pass
  233. that value as a parameter to a BeanShell script.
  234. </p><p>
  235. The jEdit class <a href="../api/org/gjt/sp/jedit/gui/InputHandler.html" target="_top">InputHandler</a> is an abstract class
  236. that that manages associations between keyboard input and editing
  237. actions, along with the recording of macros. Keyboard input
  238. in jEdit is normally managed by the derived class
  239. <a href="../api/org/gjt/sp/jedit/gui/DefaultInputHandler.html" target="_top">DefaultInputHandler</a>. One of the methods in
  240. the <a href="../api/org/gjt/sp/jedit/gui/InputHandler.html" target="_top">InputHandler</a> class handles input from a
  241. single keypress:
  242. </p><div class="itemizedlist"><ul type="disc"><li><div class="funcsynopsis"><table border="0" summary="Function synopsis" cellspacing="0" cellpadding="0"><tr><td><code class="funcdef">public void <b class="fsfunc">readNextChar</b>(</code></td><td>String  </td><td><var class="pdparam">prompt</var>, </td></tr><tr><td> </td><td>String  </td><td><var class="pdparam">code</var><code>)</code>;</td></tr></table></div></li></ul></div><p>
  243. When this method is called, the contents of the <tt class="varname">prompt</tt>
  244. parameter is shown in the view's status
  245. bar. The method then waits for a key press, after which
  246. the contents of the <tt class="varname">code</tt> parameter will be run as
  247. a BeanShell script, with one important modification. Each time the
  248. string <tt class="varname">__char__</tt> appears in the parameter script, it
  249. will be substituted by the character pressed. The key press
  250. is &#8220;<span class="quote">consumed</span>&#8221; by <tt class="function">readNextChar()</tt>.
  251. It will not be displayed on the screen or otherwise processed by jEdit.
  252. </p><p>
  253. Using <tt class="function">readNextChar()</tt> requires a macro within the
  254. macro, formatted as a single, potentially lengthy string literal. The
  255. following macro illustrates this technique. It selects a line of text
  256. from the current caret position to the first occurrence of the character
  257. next typed by the user. If the character does not appear on the line, no
  258. new selection occurs and the display remains unchanged.
  259. </p><div class="informalexample"><table border="0" bgcolor="#E0E0E0"><tr><td><pre class="programlisting">// Next_Char.bsh
  260. script = new StringBuffer(512);
  261. script.append( "start = textArea.getCaretPosition();" );
  262. script.append( "line = textArea.getCaretLine();" );
  263. script.append( "end = textArea.getLineEndOffset(line) + 1;" );
  264. script.append( "text = buffer.getText(start, end - start);" );
  265. script.append( "match = text.indexOf(__char__, 1);" );
  266. script.append( "if(match != -1) {" );
  267. script.append( "if(__char__ != '\\n') ++match;" );
  268. script.append( "textArea.select(start, start + match - 1);" );
  269. script.append( "}" );
  270. view.getInputHandler().readNextChar("Enter a character",
  271. script.toString());
  272. // end Next_Char.bsh</pre></td></tr></table></div><p>
  273. Once again, here are a few comments on the macro's design.
  274. </p><div class="itemizedlist"><ul type="disc"><li><p>
  275. A <tt class="classname">StringBuffer</tt> object is used for efficiency; it
  276. obviates multiple creation of fixed-length <tt class="classname">String</tt>
  277. objects. The parameter to the constructor of <tt class="varname">script</tt>
  278. specifies the initial size of the buffer that will receive the contents
  279. of the child script.
  280. </p></li><li><p>
  281. Besides the quoting of the script code, the formatting of the macro is
  282. entirely optional but (hopefully) makes it easier to read.
  283. </p></li><li><p>
  284. It is important that the child script be self-contained. It does
  285. not run in the same namespace as the &#8220;<span class="quote">parent</span>&#8221; macro
  286. <tt class="filename">Next_Char.bsh</tt> and therefore does not share
  287. variables, methods, or scripted objects defined in the parent
  288. macro.
  289. </p></li><li><p>
  290. Finally, access to the <a href="../api/org/gjt/sp/jedit/gui/InputHandler.html" target="_top">InputHandler</a> object used
  291. by jEdit is available by calling
  292. <tt class="function">getInputHandler()</tt> on the current view.
  293. </p></li></ul></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="macro-tips.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="macro-tips.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="startup-scripts.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 15. Macro Tips and Techniques </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Startup Scripts</td></tr></table></div></body></html>