PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/doc/users-guide/plugin-api.xml

#
XML | 909 lines | 752 code | 106 blank | 51 comment | 0 complexity | dd4d520aeca86e841725ecadaad60c9b 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. <!-- jEdit 4.0 Plugin Guide, (C) 2001 John Gellene -->
  2. <!-- jEdit buffer-local properties: -->
  3. <!-- :indentSize=1:tabSize=2:noTabs=true:maxLineLen=72: -->
  4. <!-- This chapter of the jEdit 3.2 Plugin Guide -->
  5. <!-- describes the principal elements of the jEdit Plugin API -->
  6. <!-- $Id: plugin-api.xml 3898 2001-11-13 15:22:32Z jgellene $
  7. -->
  8. <chapter id="plugin-api"><title>The jEdit Plugin API</title>
  9. <sect1 id="plugin-classes"><title>Plugin Core Classes</title>
  10. <para>
  11. As mentioned earlier, a plugin must provide a
  12. <quote>plugin core class</quote>, otherwise it will not do anything
  13. useful (but recall that a class library intended for use by other
  14. plugins need not provide a plugin core class).
  15. That class must extend
  16. either <classname>EditPlugin</classname> or its convinience subclass,
  17. <classname>EBPlugin</classname>. We begin our review of the jEdit
  18. plugin API with these two classes.
  19. </para>
  20. <sect2 id="class-EditPlugin"><title>Class EditPlugin</title>
  21. <para>
  22. This abstract class is the base for every plugin core class. Its methods
  23. provide for basic interaction between the plugin and jEdit. The class
  24. has four methods which are called by jEdit at various times. None of
  25. these methods are required to be implemented, but most plugins will
  26. override at least one.
  27. </para>
  28. <itemizedlist>
  29. <listitem>
  30. <funcsynopsis>
  31. <funcprototype>
  32. <funcdef>public void <function>start</function></funcdef>
  33. <paramdef></paramdef>
  34. </funcprototype>
  35. </funcsynopsis>
  36. <para>
  37. The jEdit startup routine calls this method for each loaded
  38. plugin. Plugins typically use this method to register information
  39. with the EditBus and perform other initialization.
  40. </para>
  41. </listitem>
  42. <listitem>
  43. <funcsynopsis>
  44. <funcprototype>
  45. <funcdef>public void <function>stop</function></funcdef>
  46. <paramdef></paramdef>
  47. </funcprototype>
  48. </funcsynopsis>
  49. <para>
  50. When jEdit is exiting, it calls this method on each plugin. If a
  51. plugin uses
  52. or creates state information or other persistent data that should
  53. be stored in a special format, this would be a good place to write
  54. the data to storage. Note that most plugins will use jEdit's
  55. properties API to save settings, and the persistance of properties
  56. is handled automatically by jEdit and requires no special
  57. processing in the <function>stop()</function> method.
  58. </para>
  59. </listitem>
  60. <listitem>
  61. <funcsynopsis>
  62. <funcprototype>
  63. <funcdef>public void <function>createMenuItems</function></funcdef>
  64. <paramdef>Vector <parameter>menuItems</parameter></paramdef>
  65. </funcprototype>
  66. </funcsynopsis>
  67. <para>
  68. When a <classname>View</classname> object is created, it calls this
  69. method on each plugin to obtain entries to be displayed in the view's
  70. <guimenu>Plugins</guimenu> menu. The
  71. <parameter>menuItems</parameter> parameter is a
  72. <classname>Vector</classname> that accumilates menu items and
  73. menus as it is passed from plugin to plugin.
  74. </para>
  75. <para>
  76. jEdit does not require a plugin to supply menu items. If menu
  77. items are desired, the easiest way to provide for them is to
  78. package the desired menu items as entries in the plugin's property
  79. file and implement <function>createMenuItems()</function> with a
  80. call to jEdit's <function>GUIUtilities.loadMenu()</function>
  81. method; for example:
  82. </para>
  83. <informalexample><programlisting>public void createMenuItems(Vector menuItems)
  84. {
  85. menuItems.addElement(GUIUtilities.loadMenu(
  86. "myplugin.menu"));
  87. }</programlisting></informalexample>
  88. <para>
  89. The parameter passed to <function>loadMenu()</function> is
  90. the name of a property containing menu data. We will explain the format
  91. of the menu data in <xref linkend="plugin-implement-menu"/>
  92. </para>
  93. <para>
  94. The <function>GUIUtilities.loadMenuItem()</function> method is also
  95. available for plugins that only wish to add a single menu item to
  96. the <guimenu>Plugins</guimenu> menu.
  97. </para>
  98. </listitem>
  99. <listitem>
  100. <funcsynopsis>
  101. <funcprototype>
  102. <funcdef>public void <function>createOptionPanes</function></funcdef>
  103. <paramdef>OptionsDialog <parameter>dialog</parameter></paramdef>
  104. </funcprototype>
  105. </funcsynopsis>
  106. <para>
  107. This method is called for each plugin during the creation of
  108. the <guilabel>Global Options</guilabel> dialog box.
  109. To show an option pane, the plugin should define an
  110. option pane class and implement <function>createOptionPane()</function>
  111. as follows:
  112. </para>
  113. <informalexample><programlisting>dialog.addOptionPane(new MyPluginOptionPane());</programlisting></informalexample>
  114. <para>
  115. Plugins can also define more than one option pane, grouped in an
  116. <quote>option group</quote>.
  117. We will discuss the design and elements of the option pane API
  118. in <xref linkend="api-option-classes"/>.
  119. </para>
  120. </listitem>
  121. </itemizedlist>
  122. <para>
  123. This class defines two other methods which may be useful to some
  124. plugins, but are mainly of use to the jEdit core:
  125. </para>
  126. <itemizedlist>
  127. <listitem>
  128. <funcsynopsis>
  129. <funcprototype>
  130. <funcdef>public String <function>getClassName</function></funcdef>
  131. <void/>
  132. </funcprototype>
  133. </funcsynopsis>
  134. <para>
  135. This shortcut method returns <function>getClass().getName()</function>.
  136. </para>
  137. </listitem>
  138. <listitem>
  139. <funcsynopsis>
  140. <funcprototype>
  141. <funcdef>public EditPlugin.JAR <function>getJAR</function></funcdef>
  142. <void/>
  143. </funcprototype>
  144. </funcsynopsis>
  145. <para>
  146. This method returns the <classname>EditPlugin.JAR</classname> data
  147. object associated with the plugin.
  148. </para>
  149. </listitem>
  150. </itemizedlist>
  151. </sect2>
  152. <sect2 id="class-EBPlugin"><title>Class EBPlugin</title>
  153. <para>
  154. Every plugin core class class that uses the EditBus for receiving
  155. messages
  156. must extend this class. This class implements the
  157. <classname>EBComponent</classname> interface, required for any
  158. object that wishes to receive EditBus messages.
  159. </para>
  160. <para>
  161. The <classname>EBComponent</classname> interface contains a single
  162. method that an implementing class (including any class derived from
  163. <classname>EBPlugin</classname>) must provide:
  164. </para>
  165. <itemizedlist>
  166. <listitem>
  167. <funcsynopsis>
  168. <funcprototype>
  169. <funcdef>public void <function>handleMessage</function></funcdef>
  170. <paramdef>EBMessage <parameter>message</parameter></paramdef>
  171. </funcprototype>
  172. </funcsynopsis>
  173. </listitem>
  174. </itemizedlist>
  175. <para>
  176. The parameter's type, <classname>EBMessage</classname>, is another
  177. abstract class which establishes the core elements of any message that
  178. is published to the EditBus. It has two attributes: an
  179. <classname>EBComponent</classname> that is the source of the message
  180. (the source will be <type>null</type> in some cases),
  181. and a <type>boolean</type> data member, <varname>vetoed</varname>. This
  182. flag indicates whether a prior recipient of the message has determined
  183. that the message has been handled and need not be passed on to other
  184. subscribers. The flag is set by a call
  185. to the <function>veto()</function> method of the
  186. <classname>EBMessage</classname>. Some message classes, however,
  187. are configured so that they cannot be vetoed, to ensure they are
  188. received by all subscribers.
  189. </para>
  190. <para>
  191. Message classes extending <classname>EBMessage</classname> typically add
  192. other data members and methods to provide subscribers with whatever is
  193. needed to handle the message appropriately. Descriptions of specific
  194. message classes can be found in <xref linkend="api-message"/>.
  195. </para>
  196. <para>
  197. The <function>handleMessage()</function> method
  198. must specify the type of responses
  199. the plugin will have for various subclasses of the
  200. <classname>EBMessage</classname> class. Typically this is done with
  201. one or more <function>if</function> blocks that test whether the message
  202. is an instance of a derived message class in which the plugin has an
  203. interest, for example like so:
  204. </para>
  205. <informalexample><programlisting>if(msg instanceof CreateDockableWindow)
  206. // create dockable window, if necessary
  207. else if(msg instanceof BufferUpdate)
  208. // a buffer's state has changed!
  209. else if(msg instanceof ViewUpdate)
  210. // a view's state has changed!
  211. // ... and so on</programlisting></informalexample>
  212. <para>
  213. If a plugin defines dockable windows, it should respond to a
  214. <classname>CreateDockableWindow</classname> message by creating the
  215. appropriate user interface objects and setting the relevant data
  216. field in the message, for example like so:
  217. </para>
  218. <informalexample><programlisting>if(msg instanceof CreateDockableWindow)
  219. {
  220. CreateDockableWindow cmsg = (CreateDockableWindow)msg;
  221. if(cmsg.getDockableWindowName().equals("myplugin"))
  222. cmsg.setDockableWindow(new MyPluginWindow());
  223. }</programlisting></informalexample>
  224. <para>
  225. Note that any object, whether or not derived from
  226. <classname>EBComponent</classname>, can send a message to the EditBus
  227. by calling the static method <function>EditBus.send()</function>.
  228. This method takes a single parameter, an <classname>EBMessage</classname>
  229. object that is the message being sent. Most plugins, however, will
  230. only concern themselves with receiving, not sending, messages.
  231. </para>
  232. </sect2>
  233. </sect1>
  234. <sect1 id="class-dockablewindow"><title>Interface DockableWindow</title>
  235. <para>
  236. The dockable plugin API consists of a single interface,
  237. <classname>DockableWindow</classname>. It links the visible
  238. components of a plugin with the dockable window management facility. The
  239. interface gives developers flexibility and minimizes code refactoring,
  240. for it can be implemented as part of the plugin's top-level display
  241. window or in a separate lightweight class. The dockable window API
  242. handles the display of windows as either docked or floating
  243. without specific direction from the plugin.
  244. </para>
  245. <!-- <para>
  246. The <classname>DockableWindowContainer</classname> class is also used
  247. by the API behind the scenes. Most plugins will not need to know about this
  248. class.
  249. </para>
  250. <sect2 id="class-DockableWindow"><title>Interface DockableWindow</title> -->
  251. <para>
  252. This interface provides the connection between the plugin's visible
  253. components and a top-level <classname>View</classname> object of the
  254. host application. As mentioned earlier, the plugin window class
  255. implementing this interface must be created by the plugin core class in
  256. response to a <classname>CreateDockableWindow</classname> message.
  257. After its creation, the plugin window object is attached to the
  258. message for routing back to jEdit.
  259. </para>
  260. <para>
  261. The <classname>DockableWindow</classname> interface contains two
  262. methods that must be implemented by a derived plugin window class:
  263. </para>
  264. <itemizedlist>
  265. <listitem>
  266. <funcsynopsis>
  267. <funcprototype>
  268. <funcdef>String <function>getName</function></funcdef>
  269. <paramdef></paramdef>
  270. </funcprototype>
  271. </funcsynopsis>
  272. <para>
  273. This method should return the internal working name of the
  274. plugin window, used to key various properties.
  275. </para>
  276. </listitem>
  277. <listitem>
  278. <funcsynopsis>
  279. <funcprototype>
  280. <funcdef>Component <function>getComponent</function></funcdef>
  281. <paramdef></paramdef>
  282. </funcprototype>
  283. </funcsynopsis>
  284. <para>
  285. This method should return the top-level visible component of the
  286. plugin.
  287. Typically this component is a <classname>JPanel</classname> containing
  288. other components, but any object derived from the Java
  289. <classname>Component</classname> class will suffice. If the
  290. top-level component implements the <classname>DockableWindow</classname>
  291. interface, so that the plugin window and the top-level visible window
  292. are implemented in the same class, the implementation of
  293. <function>getComponent()</function> would simply return
  294. <varname>this</varname>.
  295. </para>
  296. </listitem>
  297. </itemizedlist>
  298. <!-- <sect2 id="class-DockableDindowContainer">
  299. <title>Interface DockableWindowContainer</title>
  300. <para>
  301. Depending upon the settings chosen by the user, the jEdit Plugin API
  302. will place the <classname>Component</classname> returned by the
  303. <function>DockableWindow.getComponent()</function> method in a floating frame
  304. window or in a tabbed window at the designated docking location. Both
  305. types of containing windows implement the interface
  306. <classname>DockableWindowContainer</classname> and are managed entirely
  307. by the host application.
  308. </para>
  309. <itemizedlist>
  310. <listitem>
  311. <para>
  312. The <classname>DockableWindowContainer.Floating</classname> class is
  313. derived from <classname>JFrame</classname> and uses a
  314. <classname>BorderLayout</classname>. The plugin window's component is
  315. placed in the center position of the frame's content pane.
  316. </para>
  317. </listitem>
  318. <listitem>
  319. <para>
  320. The <classname>DockableWindowContainer.TabbedPane</classname> class is
  321. derived from <classname>JTabbedPane</classname>. Here the plugin
  322. window's component is added to the container's collection of tabbed
  323. components.
  324. </para>
  325. </listitem>
  326. </itemizedlist>
  327. </sect2> -->
  328. </sect1>
  329. <sect1 id="api-option-classes"><title>Plugin Option Pane Classes</title>
  330. <para>
  331. The plugin API provides a mechanism for displaying a plugin's
  332. configuration options in the <guilabel>Global
  333. Options</guilabel> dialog. A plugin that allows user configuration
  334. should provide one or more implementations of
  335. jEdit's <classname>OptionPane</classname> interface to have
  336. configuration options displayed in a manner consistent wth the rest of
  337. the application.
  338. </para>
  339. <sect2 id="class-AbstractOptionPane"><title>Class AbstractOptionPane</title>
  340. <para>
  341. Most plugin option panes extend this implementation of
  342. <classname>OptionPane</classname>, instead of implementing
  343. <classname>OptionPane</classname> directly. It provides
  344. a convenient default framework for laying out configuration options in
  345. a manner similar to the option panes created by jEdit itself.
  346. It is derived from Java's <classname>JPanel</classname> class and
  347. contains a <classname>GridBagLayout</classname> object for component
  348. management. It also contains shortcut methods to simplify layout.
  349. </para>
  350. <para>
  351. The constructor for a class derived from
  352. <classname>AbstractOptionPane</classname> should
  353. call the parent constructor and pass the option pane's <quote>internal
  354. name</quote> as a
  355. parameter. The internal name is used to key a property where the
  356. option pane's label is stored; see
  357. <xref linkend="api-resource-properties" />.
  358. It should also implement two methods:
  359. </para>
  360. <itemizedlist>
  361. <listitem>
  362. <funcsynopsis>
  363. <funcprototype>
  364. <funcdef>protected void <function>_init</function></funcdef>
  365. <paramdef></paramdef>
  366. </funcprototype>
  367. </funcsynopsis>
  368. <para>
  369. This method should create and arrange the components of the option pane
  370. and initialize the option data displayed to the user. This method
  371. is called when the option pane is first displayed, and is not
  372. called again for the lifetime of the object.
  373. </para>
  374. </listitem>
  375. <listitem>
  376. <funcsynopsis>
  377. <funcprototype>
  378. <funcdef>protected void <function>_save</function></funcdef>
  379. <paramdef></paramdef>
  380. </funcprototype>
  381. </funcsynopsis>
  382. <para>
  383. This method should save any settings, to the jEdit properties or
  384. other data store.
  385. </para>
  386. </listitem>
  387. </itemizedlist>
  388. <para>
  389. <classname>AbstractOptionPane</classname> also contains three shortcut
  390. methods, typically called from <function>_init()</function>,
  391. for adding components to the option pane:
  392. </para>
  393. <itemizedlist>
  394. <listitem>
  395. <funcsynopsis>
  396. <funcprototype>
  397. <funcdef>protected void <function>addComponent</function></funcdef>
  398. <paramdef>String <parameter>label</parameter></paramdef>
  399. <paramdef>Component <parameter>comp</parameter></paramdef>
  400. </funcprototype>
  401. </funcsynopsis>
  402. </listitem>
  403. <listitem>
  404. <funcsynopsis>
  405. <funcprototype>
  406. <funcdef>protected void <function>addComponent</function></funcdef>
  407. <paramdef>Component <parameter>comp</parameter></paramdef>
  408. </funcprototype>
  409. </funcsynopsis>
  410. <para>
  411. These shortcut methods add components to the option pane in a
  412. single vertical column, running top to bottom. The first
  413. displays the text of the <parameter>label</parameter> parameter
  414. to the left of the <classname>Component</classname> represented
  415. by <parameter>comp</parameter>.
  416. </para>
  417. </listitem>
  418. <listitem>
  419. <funcsynopsis>
  420. <funcprototype>
  421. <funcdef>protected void <function>addSeparator</function></funcdef>
  422. <paramdef>String <parameter>label</parameter></paramdef>
  423. </funcprototype>
  424. </funcsynopsis>
  425. <para>
  426. This is another shortcut method that adds a text label between
  427. two horizontal separators to the option pane.
  428. The <parameter>label</parameter> parameter represents the name
  429. of a property (typically a property defined in the plugin's
  430. property file) whose value will be used as the separator text.
  431. </para>
  432. </listitem>
  433. </itemizedlist>
  434. </sect2>
  435. <sect2 id="class-OptionGroup"><title>Class OptionGroup</title>
  436. <para>
  437. In those cases where a single option pane is inadequate to present all
  438. of a plugin's configuration options, this class can be used to create a
  439. group of options panes. The group will appear as a single node in the
  440. options dialog tree-based index. The member option panes will appear as
  441. leaf nodes under the group's node. Threee simple methods create and
  442. populate an option pane:
  443. </para>
  444. <itemizedlist>
  445. <listitem>
  446. <funcsynopsis>
  447. <funcprototype>
  448. <funcdef>public <function>OptionGroup</function></funcdef>
  449. <paramdef>String <parameter>name</parameter></paramdef>
  450. </funcprototype>
  451. </funcsynopsis>
  452. <para>
  453. The constructor's single parameter represents the internal
  454. name of the option group. The internal name is used to key a
  455. property where the option group's label is stored; see
  456. <xref linkend="api-resource-properties" />.
  457. </para>
  458. </listitem>
  459. <listitem>
  460. <funcsynopsis>
  461. <funcprototype>
  462. <funcdef>public void <function>addOptionPane</function></funcdef>
  463. <paramdef>OptionPane <parameter>pane</parameter></paramdef>
  464. </funcprototype>
  465. </funcsynopsis>
  466. </listitem>
  467. <listitem>
  468. <funcsynopsis>
  469. <funcprototype>
  470. <funcdef>public void <function>addOptionGroup</function></funcdef>
  471. <paramdef>OptionGroup <parameter>group</parameter></paramdef>
  472. </funcprototype>
  473. </funcsynopsis>
  474. <para>
  475. This pair of methods adds members to the option group. The second
  476. method enables option groups to be nested, for plugins with a
  477. particularly large set of configurable options.
  478. </para>
  479. </listitem>
  480. </itemizedlist>
  481. </sect2>
  482. </sect1>
  483. <sect1 id="api-other-resources"><title>Other Plugin Resources</title>
  484. <para>
  485. There are four other types of files containing resources used by a
  486. plugin:
  487. </para>
  488. <itemizedlist>
  489. <listitem>
  490. <para>
  491. a file named <filename>dockables.xml</filename> contained the
  492. name of the plugin and the code for costructing an instance of the
  493. plugin's docking window component, set forth in a specified XML
  494. format;
  495. </para>
  496. </listitem>
  497. <listitem>
  498. <para>
  499. a catalog of the plugin's user actions in a specified XML format,
  500. contained in a file named <filename>actions.xml</filename>;
  501. </para>
  502. </listitem>
  503. <listitem>
  504. <para>
  505. one or more properties files named with a <filename>.props</filename>
  506. extension, each containing key-value pairs in conventional Java
  507. format; and
  508. </para>
  509. </listitem>
  510. <listitem>
  511. <para>
  512. a help file written in HTML format. The name of this file must be
  513. specified in a property; see <xref
  514. linkend="api-resource-properties" />.
  515. </para>
  516. </listitem>
  517. </itemizedlist>
  518. <!-- open sect2 -->
  519. <sect2 id="api-resources-activation"><title>The Activation Data File</title>
  520. <para>
  521. [To be supplied]
  522. </para>
  523. </sect2>
  524. <sect2 id="api-resources-action"><title>The Action Catalog</title>
  525. <para>
  526. Actions define procedures that can be bound to a menu
  527. item, a toolbar button or a keyboard shortcut. They can perform any
  528. task encompassed in a public method of any class currently loaded in
  529. jEdit, including plugin classes and classes of the host application.
  530. Among other things, they can cause the appearance and disappearance of
  531. plugin windows.
  532. </para>
  533. <para>
  534. To manage user actions, jEdit maintains a lookup table of actions
  535. using descriptive strings as keys. The values in the table are
  536. sets of statements written in BeanShell, jEdit's macro scripting
  537. language. These scripts either direct the action themselves,
  538. delegate to a method in one of the plugin's classes that
  539. encapsulates the action, or do a little of both. The scripts are
  540. usually short; elaborate action protocols are usually contained in
  541. compiled code, rather than an interpreted macro script, to speed
  542. execution.
  543. </para>
  544. <para>
  545. Actions are defined by creating an XML file entitled
  546. <filename>actions.xml</filename> at the top level of the plugin JAR
  547. file. A sample action catalog looks like so:
  548. </para>
  549. <informalexample><programlisting>&lt;!DOCTYPE ACTIONS SYSTEM "actions.dtd"&gt;
  550. &lt;ACTIONS&gt;
  551. &lt;ACTION NAME="quicknotepad.toggle"&gt;
  552. &lt;CODE&gt;
  553. view.getDockableWindowManager()
  554. .toggleDockableWindow(QuickNotepadPlugin.NAME);
  555. &lt;/CODE&gt;
  556. &lt;IS_SELECTED&gt;
  557. return view.getDockableWindowManager()
  558. .isDockableWindowVisible(QuickNotepadPlugin.NAME);
  559. &lt;/IS_SELECTED&gt;
  560. &lt;/ACTION&gt;
  561. &lt;ACTION NAME="quicknotepad-to-front"&gt;
  562. &lt;CODE&gt;
  563. view.getDockableWindowManager()
  564. .addDockableWindow(QuickNotepadPlugin.NAME);
  565. &lt;/CODE&gt;
  566. &lt;/ACTION&gt;
  567. &lt;/ACTIONS&gt;</programlisting></informalexample>
  568. <para>
  569. The defined elements have the following functions:
  570. </para>
  571. <itemizedlist>
  572. <listitem>
  573. <para>
  574. <varname>ACTIONS</varname> is the top-level element and refers
  575. to the set of actions used by the plugin.
  576. </para>
  577. </listitem>
  578. <listitem>
  579. <para>
  580. An <varname>ACTION</varname> contains the data for a particular action.
  581. It has three attributes: a required <varname>NAME</varname>;
  582. an optional <varname>NO_REPEAT</varname>, which is a flag
  583. indicating whether the action should not be repeated with the
  584. <keycombo><keycap>Control</keycap><keycap>Enter</keycap></keycombo>
  585. command (see <xref linkend="repeat" />); and an optional
  586. <varname>NO_RECORD</varname> which is a a flag indicating whether the
  587. action should be recorded if it is invoked while a user is recording a
  588. macro. The two flag attributes
  589. can have two possible values, <quote>TRUE</quote> or
  590. <quote>FALSE</quote>. In both cases, <quote>FALSE</quote> is the
  591. default if the attribute is not specified.
  592. </para>
  593. </listitem>
  594. <listitem>
  595. <para>
  596. An <varname>ACTION</varname> can have two child elements
  597. within it: a required <varname>CODE</varname> element which
  598. specifies the
  599. BeanShell code that will be executed when the action is invoked,
  600. and an optional <varname>IS_SELECTED</varname> element, used for
  601. checkbox
  602. menu items. The <varname>IS_SELECTED</varname> element contains
  603. BeanShell code that returns a boolean flag that will
  604. determine the state of the checkbox.
  605. </para>
  606. </listitem>
  607. </itemizedlist>
  608. <para>
  609. More discussion of the action catalog can be found in <xref
  610. linkend="plugin-implement-actions" />.
  611. </para>
  612. </sect2>
  613. <sect2 id="api-resource-properties"><title>Plugin Properties</title>
  614. <para>
  615. jEdit maintains a list of <quote>properties</quote>, which are
  616. name/value pairs used to store human-readable strings, user settings,
  617. and various other forms of meta-data. During startup, jEdit loads the
  618. default set of properties, followed by plugin properties stored in
  619. plugin JAR files, finally followed by user properties. Plugins can
  620. access properties from all three sources.
  621. </para>
  622. <para>
  623. Property files contained in plugin JARs must end with the filename
  624. extension <filename>.props</filename>, and have a very simple syntax,
  625. which the following example suffices to describe:
  626. </para>
  627. <informalexample><programlisting># Lines starting with '#' are ignored.
  628. name=value
  629. another.name=another value
  630. long.property=Long property value, split over \
  631. several lines
  632. escape.property=Newlines and tabs can be inserted \
  633. using the \t and \n escapes
  634. backslash.property=A backslash can be inserted by writing \\.</programlisting>
  635. </informalexample>
  636. <para>
  637. The following types of plugin information
  638. are supplied using properties:
  639. </para>
  640. <itemizedlist>
  641. <listitem>
  642. <para>
  643. Information regarding the name, author, and version of the plugin.
  644. This information is required. Here is an example:
  645. </para>
  646. <informalexample><programlisting>plugin.MyPlugin.name=My Plugin
  647. plugin.MyPlugin.author=Joe Random Hacker
  648. plugin.MyPlugin.version=1.0.3</programlisting></informalexample>
  649. <para>
  650. Note that each property is prefixed with
  651. <literal>plugin.</literal>, followed by the fully qualified name
  652. of the plugin core class (including a package name, if there is
  653. one).
  654. </para>
  655. </listitem>
  656. <listitem>
  657. <para>
  658. Identification of any dependencies the plugin may have on a
  659. particular version of a Java runtime environment, the jEdit
  660. application, or other plugins.
  661. </para>
  662. <para>
  663. Each dependency is defined in a property prefixed with
  664. <literal>plugin.<replaceable>class name</replaceable>.depend.</literal>,
  665. followed by a number. Dependencies must be numbered in order,
  666. starting from zero.
  667. </para>
  668. <para>
  669. The value of a dependency property is one of the words
  670. <literal>jdk</literal>, <literal>jedit</literal>,
  671. <literal>class</literal> or <literal>plugin</literal>,
  672. followed by a Java version number, a jEdit build number, a class
  673. name, or plugin class name and plugin version number,
  674. respectively.
  675. </para>
  676. <para>
  677. Here are some examples:
  678. </para>
  679. <informalexample><programlisting>plugin.MyPlugin.depend.0=jdk 1.2
  680. plugin.MyPlugin.depend.1=jedit 03.02.97.00
  681. plugin.MyPlugin.depend.2=class com.ice.tar.tar
  682. plugin.MyPlugin.depend.3=plugin console.ConsolePlugin 3.0</programlisting>
  683. </informalexample>
  684. </listitem>
  685. <listitem>
  686. <para>
  687. A list of external class library JARs shipped with the plugin.
  688. If your plugin bundles extra JARs, this property is required
  689. for the plugin manager to be able to remove the plugin completely.
  690. </para>
  691. <para>
  692. The property is a space-separated list of filenames. Here is an
  693. example:
  694. </para>
  695. <informalexample><programlisting>plugin.AntFarmPlugin.jars=crimson.jar jaxp.jar</programlisting></informalexample>
  696. </listitem>
  697. <listitem>
  698. <para>
  699. The titles of dockable windows, as displayed in a tabbed or
  700. floating container.
  701. </para>
  702. <para>
  703. These labels are specified in properties named by the return value
  704. of the dockable window's <function>getName()</function> method,
  705. suffixed with <literal>.title</literal>. For example:
  706. </para>
  707. <informalexample><programlisting>quick-notepad.title=QuickNotepad</programlisting>
  708. </informalexample>
  709. </listitem>
  710. <listitem>
  711. <para>
  712. Labels for user actions for inclusion in menus and option panes
  713. relating to toolbars and keyboard shortcuts.
  714. </para>
  715. <para>
  716. Action labels are defined in properties named by the
  717. action's internal name as specified in the action catalog,
  718. followed by <literal>.label</literal>:
  719. </para>
  720. <informalexample><programlisting>myplugin.label=My Plugin
  721. myplugin-grok.label=Grok Current Buffer</programlisting>
  722. </informalexample>
  723. </listitem>
  724. <listitem>
  725. <para>
  726. The list of menu items contained in plugin menus, if any.
  727. </para>
  728. <para>
  729. This is discussed in detail in <xref
  730. linkend="plugin-implement-menu" />.
  731. </para>
  732. </listitem>
  733. <listitem>
  734. <para>
  735. Labels and other information regarding the controls contained in
  736. the plugin's windows. These properties can be named any way you
  737. like, however take care not to choose names which may conflict
  738. with those in other plugins.
  739. </para>
  740. </listitem>
  741. </itemizedlist>
  742. </sect2>
  743. <sect2 id="api-resources-help"><title>Plugin Documentation</title>
  744. <para>
  745. While not required by the plugin API, a help file is an essential
  746. element of any plugin written for public release. A single web page is
  747. often all that is required. There are no specific requirements on
  748. layout, but because of the design of jEdit's help viewer, the use of
  749. frames should be avoided. Topics that would be useful include
  750. the following:
  751. </para>
  752. <itemizedlist>
  753. <listitem>
  754. <para>
  755. a description of the purpose of the plugin;
  756. </para>
  757. </listitem>
  758. <listitem>
  759. <para>
  760. an explanation of the type of input the user can supply through its
  761. visible interface (such as mouse action or text entry in controls);
  762. </para>
  763. </listitem>
  764. <listitem>
  765. <para>
  766. a listing of available user actions that can be taken when the
  767. plugin does not have input focus;
  768. </para>
  769. </listitem>
  770. <listitem>
  771. <para>
  772. a summary of configuration options;
  773. </para>
  774. </listitem>
  775. <listitem>
  776. <para>
  777. information on development of the plugin (such as a change log,
  778. a list of <quote>to do</quote> items, and contact information for
  779. the plugin's author); and
  780. </para>
  781. </listitem>
  782. <listitem>
  783. <para>
  784. licensing information, including acknowledgements for any library
  785. software used by the plugin.
  786. </para>
  787. </listitem>
  788. </itemizedlist>
  789. <para>
  790. The location of the plugin's help file should be stored in the
  791. <literal>plugin.<replaceable>class name</replaceable>.docs</literal>
  792. property.
  793. </para>
  794. </sect2>
  795. </sect1>
  796. </chapter>