<?xml version="1.0" encoding="UTF-8"?>
<chapter id="macro-basics">
    <title>Macro Basics</title>
    <!-- jEdit 4.0 Macro Guide, (C) 2001, 2002 John Gellene          -->
    <!-- jEdit buffer-local properties:                              -->
    <!-- :indentSize=1:noTabs=yes:maxLineLen=72:tabSize=2:           -->
    <!-- :xml.root=users-guide.xml:                                  -->
    <!-- This file cover the introductory section of the macro guide -->
    <!-- $Id: macro-basics.xml 11181 2007-12-02 17:51:37Z ezust $  -->

    <sect1 id="beanshell-intro">
        <title>Introducing BeanShell</title>

        <para>Here is how BeanShell's author, Pat Niemeyer, describes his
        creation:</para>

        <blockquote>
            <para><quote>BeanShell is a small, free, embeddable, Java source
            interpreter with object scripting language features, written in
            Java. BeanShell executes standard Java statements and expressions,
            in addition to obvious scripting commands and syntax. BeanShell
            supports scripted objects as simple method closures like those in
            Perl and JavaScript.</quote></para>
        </blockquote>

        <para>You do not have to know anything about Java to begin writing your
        own jEdit macros. But if you know how to program in Java, you already
        know how to write BeanShell scripts. The major strength of using
        BeanShell with a program written in Java is that it allows the user to
        customize the program's behavior using the same interfaces designed and
        used by the program itself. BeanShell can turn a well-designed
        application into a powerful, extensible toolkit.</para>

        <para>This guide focuses on using BeanShell in macros. If you are
        interested in learning more about BeanShell generally, consult the
        <ulink url="http://www.beanshell.org">BeanShell web site</ulink>.
        Information on how to run and organize macros, whether included with the
        jEdit installation or written by you, can be found in <xref
        linkend="using-macros" />.</para>
    </sect1>

    <sect1 id="single-macros">
        <title>Single Execution Macros</title>

        <para>As noted in <xref linkend="organizing-macros" />, you can save a
        BeanShell script of any length as a text file with the
        <filename>.bsh</filename> extension and run it from the
        <guimenu>Macros</guimenu> menu. There are three other ways jEdit lets
        you use BeanShell quickly, without saving a script to storage, on a
        <quote>one time only</quote> basis. You will find them in the
        <guimenu>Utilities</guimenu> menu.</para>

        <para><guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate
        BeanShell Expression</guimenuitem> displays a text input dialog that
        asks you to type a single line of BeanShell commands. You can type more
        than one BeanShell statement so long as each of them ends with a
        semicolon. If BeanShell successfully interprets your input, a message
        box will appear with the return value of the last statement.</para>

        <para><guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate
        For Selected Lines</guimenuitem> displays a text input dialog that asks
        you to type a single line of BeanShell commands. The commands are
        evaluated for each line of the selection. In addition to the standard
        set of variables described in <xref linkend="predefined-variables" />,
        this command defines the following:</para>

        <itemizedlist>
            <listitem>
                <para><varname>line</varname> - the line number, from the start
                of the buffer. The first line is numbered 0.</para>
            </listitem>

            <listitem>
                <para><varname>index</varname> - the line number, from the start
                of the selection. The first line is numbered 0.</para>
            </listitem>

            <listitem>
                <para><varname>text</varname> - the text of the line.</para>
            </listitem>
        </itemizedlist>

        <informalexample>
            <para>Try typing an expression like <userinput>(line + 1) + ": " +
            text</userinput> in the <guimenuitem>Evaluate For Selected
            Lines</guimenuitem> dialog box. This will add a line number to each
            selected line beginning with the number
            <userinput>1</userinput>.</para>
        </informalexample>

        <para>The BeanShell expression you enter will be evaluated and
        substituted in place of the entire text of a selected line. If you want
        to leave the line's current text as an element of the modified line, you
        must include the defined variable <userinput>text</userinput> as part of
        the BeanShell expression that you enter.</para>

        <para><guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate
        Selection</guimenuitem> evaluates the selected text as a BeanShell
        script and replaces it with the return value of the statement.</para>

        <para>Using <guimenuitem>Evaluate Selection</guimenuitem> is an easy way
        to do arithmetic calculations inline while editing. BeanShell uses
        numbers and arithmetic operations in an ordinary, intuitive way.</para>

        <informalexample>
            <para>Try typing an expression like
            <userinput>(3745*856)+74</userinput> in the buffer, select it, and
            choose
            <guimenu>Utilities</guimenu>&gt;<guisubmenu>BeanShell</guisubmenu>&gt;<guimenuitem>Evaluate
            Selection</guimenuitem>. The selected text will be replaced by the
            answer, <userinput>3205794</userinput>. <!-- Irrelevant? --> <!-- Since this is a text file
    and not a spreadsheet, the original values that BeanShell evaluated are
    not retained or saved as part of the buffer's contents. --></para>
        </informalexample>

        <sidebar>
            <title>Console plugin</title>

            <para>You can also do the same thing using the BeanShell interpreter
            option of the <application>Console</application> plugin.</para>
        </sidebar>
    </sect1>

    <sect1 id="first-example">
        <title>The Mandatory First Example</title>

        <informalexample>
            <!-- <title>A first one-line macro</title> -->

            <programlisting>Macros.message(view, "Hello world!");</programlisting>
        </informalexample>

        <para>Running this one line script causes jEdit to display a message box
        (more precisely, a <classname>JOptionPane</classname> object) with the
        traditional beginner's message and an <guilabel>OK</guilabel> button.
        Let's see what is happening here.</para>

        <para>This statement calls a static method (or function) named
        <function>message</function> in jEdit's <ulink
        url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class. If you
        don't know anything about classes or static methods or Java (or C++,
        which employs the same concept), you will need to gain some
        understanding of a few terms. Obviously this is not the place for
        academic precision, but if you are entirely new to object-oriented
        programming, here are a few skeleton ideas to help you with
        BeanShell.</para>

        <itemizedlist>
            <listitem>
                <para>An <glossterm>object</glossterm> is a collection of data
                that can be initialized, accessed and manipulated in certain
                defined ways.</para>
            </listitem>

            <listitem>
                <para>A <glossterm>class</glossterm> is a specification of what
                data an object contains and what methods can be used to work
                with the data. A Java application consists of one or more
                classes (in the case of jEdit ,over 600 classes) written by the
                programmer that defines the application's behavior. A BeanShell
                macro uses these classes, along with built-in classes that are
                supplied with the Java platform, to define its own
                behavior.</para>
            </listitem>

            <listitem>
                <para>A <glossterm>subclass</glossterm> (or child class) is a
                class which uses (or <quote>inherits</quote>) the data and
                methods of its parent class along with additions or
                modifications that alter the subclass's behavior. Classes are
                typically organized in hierarchies of parent and child classes
                to organize program code, to define common behavior in shared
                parent class code, and to specify the types of similar behavior
                that child classes will perform in their own specific
                ways.</para>
            </listitem>

            <listitem>
                <para>A <glossterm>method</glossterm> (or function) is a
                procedure that works with data in a particular object, other
                data (including other objects) supplied as
                <glossterm>parameters</glossterm>, or both. Methods typically
                are applied to a particular object which is an
                <glossterm>instance</glossterm> of the class to which the method
                belongs.</para>
            </listitem>

            <listitem>
                <para>A <glossterm>static method</glossterm> differs from other
                methods in that it does not deal with the data in a particular
                object but is included within a class for the sake of
                convenience.</para>
            </listitem>
        </itemizedlist>

        <para>Java has a rich set of classes defined as part of the Java
        platform. Like all Java applications, jEdit is organized as a set of
        classes that are themselves derived from the Java platform's classes. We
        will refer to <firstterm>Java classes</firstterm> and <firstterm>jEdit
        classes</firstterm> to make this distinction. Some of jEdit's classes
        (such as those dealing with regular expressions and XML) are derived
        from or make use of classes in other open-source Java packages. Except
        for BeanShell itself, we won't be discussing them in this guide.</para>

        <para>In our one line script, the static method
        <function>Macros.message()</function> has two parameters because that is
        the way the method is defined in the <ulink
        url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class. You must
        specify both parameters when you call the function. The first parameter,
        <parameter>view</parameter>, is a variable naming the current, active
        <ulink url="../api/org/gjt/sp/jedit/View.html">View</ulink> object.
        Information about pre-defined variables can be found in <xref
        linkend="predefined-variables" />.</para>

        <para>The second parameter, which appears to be quoted text, is a
        <glossterm>string literal</glossterm> - a sequence of characters of
        fixed length and content. Behind the scenes, BeanShell and Java take
        this string literal and use it to create a <classname>String</classname>
        object. Normally, if you want to create an object in Java or BeanShell,
        you must construct the object using the <function>new</function> keyword
        and a <firstterm>constructor</firstterm> method that is part of the
        object's class. We'll show an example of that later. However, both Java
        and BeanShell let you use a string literal anytime a method's parameter
        calls for a <classname>String</classname>.</para>

        <para>If you are a Java programmer, you might wonder about a few things
        missing from this one line program. There is no class definition, for
        example. You can think of a BeanShell script as an implicit definition
        of a <function>main()</function> method in an anonymous class. That is
        in fact how BeanShell is implemented; the class is derived from a
        BeanShell class called <ulink url="../api/bsh/XThis.html">XThis</ulink>.
        If you don't find that helpful, just think of a script as one or more
        blocks of procedural statements conforming to Java syntax rules. You
        will also get along fine (for the most part) with C or C++ syntax if you
        leave out anything to do with pointers or memory management - Java and
        BeanShell do not have pointers and deal with memory management
        automatically.</para>

        <para>Another missing item from a Java perspective is a
        <function>package</function> statement. In Java, such a statement is
        used to bundle together a number of files so that their classes become
        visible to one another. Packages are not part of BeanShell, and you
        don't need to know anything about them to write BeanShell macros.</para>

        <para>Finally, there are no <function>import</function> statements in
        this script. In Java, an <function>import</function> statement makes
        public classes from other packages visible within the file in which the
        statement occurs without having to specify a fully qualified class name.
        Without an import statement or a fully qualified name, Java cannot
        identify most classes using a single name as an identifier.</para>

        <para>jEdit automatically imports a number of commonly-used packages
        into the namespace of every BeanShell script. Because of this, the
        script output of a recorded macro does not contain
        <function>import</function> statements. For the same reason, most
        BeanShell scripts you write will not require <function>import</function>
        statements.</para>

        <para>Java requires <literal>import</literal> statement to be located at
        the beginning of a source file. BeanShell allows you to place
        <literal>import</literal> statements anywhere in a script, including
        inside a block of statements. The <literal>import</literal> statement
        will cover all names used following the statement in the enclosing
        block.</para>

        <para>If you try to use a class that is not imported without its
        fully-qualified name, the BeanShell interpreter will complain with an
        error message relating to the offending line of code.</para>

        <sidebar>
            <para>Here is the full list of packages automatically imported by
            jEdit:</para>

            <programlisting>java.awt
java.awt.event
java.net
java.util
java.io
java.lang
javax.swing
javax.swing.event
org.gjt.sp.jedit
org.gjt.sp.jedit.browser
org.gjt.sp.jedit.buffer
org.gjt.sp.jedit.gui
org.gjt.sp.jedit.help
org.gjt.sp.jedit.io
org.gjt.sp.jedit.msg
org.gjt.sp.jedit.options
org.gjt.sp.jedit.pluginmgr
org.gjt.sp.jedit.print
org.gjt.sp.jedit.search
org.gjt.sp.jedit.syntax
org.gjt.sp.jedit.textarea
org.gjt.sp.util</programlisting>
        </sidebar>
    </sect1>

    <sect1 id="predefined-variables">
        <title>Predefined Variables in BeanShell</title>

        <para>The following variables are always available for use in BeanShell
        scripts:</para>

        <itemizedlist>
            <listitem>
                <para><varname>buffer</varname> - a <ulink
                url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink> object
                represents the contents of the currently visible open text
                file.</para>
            </listitem>

            <listitem>
                <para><varname>view</varname> - A <ulink
                url="../api/org/gjt/sp/jedit/View.html">View</ulink> represents
                the current top-level editor window, extending Java's
                <classname>JFrame</classname> class, that contains the various
                visible components of the program, including the text area, menu
                bar, toolbar, and any docked windows.</para>

                <para>This variable has the same value as the return value
                of:</para>

                <programlisting>jEdit.getActiveView()</programlisting>
            </listitem>

            <listitem>
                <para><varname>editPane</varname> - an <ulink
                url="../api/org/gjt/sp/jedit/EditPane.html">EditPane</ulink>
                object contains a text area and buffer switcher. A view can be
                split to display edit panes. Among other things, the <ulink
                url="../api/org/gjt/sp/jedit/EditPane.html">EditPane</ulink>
                class contains methods for selecting the buffer to edit.</para>

                <para>Most of the time your macros will manipulate the
                <varname>buffer</varname> or the <varname>textArea</varname>.
                Sometimes you will need to use <varname>view</varname> as a
                parameter in a method call. You will probably only need to use
                <varname>editPane</varname> if your macros work with split
                views.</para>

                <para>This variable has the same value as the return value
                of:</para>

                <programlisting>view.getEditPane()</programlisting>
            </listitem>

            <listitem>
                <para><varname>textArea</varname> - a <ulink
                url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink>
                is the visible component that displays the current
                buffer.</para>

                <para>This variable has the same value as the return value
                of:</para>

                <programlisting>editPane.getTextArea()</programlisting>
            </listitem>

            <listitem>
                <para><varname>wm</varname> - a <ulink
                url="../api/org/gjt/sp/jedit/gui/DockableWindowManager.html">DockableWindowManager</ulink>
                is the visible component that manages dockable windows in the
                current view. This class is discussed in detail in <xref
                linkend="writing-plugins-part" />. This object is useful for
                writing macros that interface with, open, or close plugin
                windows.</para>

                <para>This variable has the same value the return value
                of:</para>

                <programlisting>view.getDockableWindowManager()</programlisting>
            </listitem>

            <listitem>
                <para><varname>scriptPath</varname> - set to the full path of
                the script currently being executed.</para>
            </listitem>

            <listitem>
                <para><varname>scriptPath</varname> - set to the full path of
                the script currently being executed.</para>
            </listitem>
        </itemizedlist>

        <para>Note that these variables are set at the beginning of macro
        execution. If the macro switches views, buffers or edit panes, the
        variable values will be out of date. In that case, you can use the
        equivalent method calls.</para>
    </sect1>

    <sect1 id="helpful-methods">
        <title>Helpful Methods in the Macros Class</title>

        <para>Including <function>message()</function>, there are five static
        methods in the <ulink
        url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class that
        allow you to converse easily with your macros. They all encapsulate
        calls to methods of the Java platform's
        <classname>JOptionPane</classname> class.</para>

        <itemizedlist>
            <listitem>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>public static void
                        <function>message</function></funcdef>

                        <paramdef>Component
                        <parameter>comp</parameter></paramdef>

                        <paramdef>String
                        <parameter>message</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </listitem>

            <listitem>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>public static void
                        <function>error</function></funcdef>

                        <paramdef>Component
                        <parameter>comp</parameter></paramdef>

                        <paramdef>String
                        <parameter>message</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </listitem>

            <listitem>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>public static String
                        <function>input</function></funcdef>

                        <paramdef>Component
                        <parameter>comp</parameter></paramdef>

                        <paramdef>String
                        <parameter>prompt</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </listitem>

            <listitem>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>public static String
                        <function>input</function></funcdef>

                        <paramdef>Component
                        <parameter>comp</parameter></paramdef>

                        <paramdef>String
                        <parameter>prompt</parameter></paramdef>

                        <paramdef>String
                        <parameter>defaultValue</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </listitem>

            <listitem>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>public static int
                        <function>confirm</function></funcdef>

                        <paramdef>Component
                        <parameter>comp</parameter></paramdef>

                        <paramdef>String
                        <parameter>prompt</parameter></paramdef>

                        <paramdef>int <parameter>buttons</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </listitem>
        </itemizedlist>

        <para>The format of these four <glossterm>declarations</glossterm>
        provides a concise reference to the way in which the methods may be
        used. The keyword <function>public</function> means that the method can
        be used outside the <ulink
        url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class. The
        alternatives are <function>private</function> and
        <function>protected</function>. For purposes of BeanShell, you just have
        to know that BeanShell can only use public methods of other Java
        classes. The keyword <function>static</function> we have already
        discussed. It means that the method does not operate on a particular
        object. You call a static function using the name of the class (like
        <ulink url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink>) rather
        than the name of a particular object (like <varname>view</varname>). The
        third word is the type of the value returned by the method. The keyword
        <function>void</function> is Java's way of saying the the method does
        not have a return value.</para>

        <para>The <function>error()</function> method works just like
        <function>message()</function> but displays an error icon in the message
        box. The <function>input()</function> method furnishes a text field for
        input, an <guilabel>OK</guilabel> button and a
        <guilabel>Cancel</guilabel> button. If <guilabel>Cancel</guilabel> is
        pressed, the method returns <constant>null</constant>. If
        <guilabel>OK</guilabel> is pressed, a <classname>String</classname>
        containing the contents of the text field is returned. Note that there
        are two forms of the <function>input()</function> method; the first form
        with two parameters displays an empty input field, the other forms lets
        you specify an initial, default input value.</para>

        <para>For those without Java experience, it is important to know that
        <constant>null</constant> is <emphasis>not</emphasis> the same as an
        empty, <quote>zero-length</quote> <classname>String</classname>. It is
        Java's way of saying that there is no object associated with this
        variable. Whenever you seek to use a return value from
        <function>input()</function> in your macro, you should test it to see if
        it is <constant>null</constant>. In most cases, you will want to exit
        gracefully from the script with a <function>return</function> statement,
        because the presence of a null value for an input variable usually means
        that the user intended to cancel macro execution. BeanShell will
        complain if you call any methods on a <constant>null</constant>
        object.</para>

        <para>The <function>confirm()</function> method in the <ulink
        url="../api/org/gjt/sp/jedit/Macros.html">Macros</ulink> class is a
        little more complex. The <varname>buttons</varname> parameter has an
        <classname>int</classname> type, and the usual way to supply a value is
        to use one of the predefined values taken from Java's
        <classname>JOptionPane</classname> class. You can choose among
        <constant>JOptionPane.YES_NO_OPTION</constant>,
        <constant>JOptionPane.YES_NO_CANCEL_OPTION</constant>, or
        <constant>JOptionPane.OK_CANCEL_OPTION</constant>. The return value of
        the method is also an <classname>int</classname>, and should be tested
        against the value of other predefined constants:
        <constant>JOptionPane.YES_OPTION</constant>,
        <constant>JOptionPane.NO_OPTION</constant>,
        <constant>JOptionPane.OK_OPTION</constant> or
        <constant>JOptionPane.CANCEL_OPTION</constant>.</para>

        <para>We've looked at using <function>Macros.message()</function>. To
        use the other methods, you would write something like the
        following:</para>

        <informalexample>
            <!-- <title>Using <function>Macros.error()</function> and
  <function>Macros.input()</function></title> -->

            <programlisting>Macros.error(view, "Goodbye, cruel world!");

String result = Macros.input(view, "Type something here.");

String result = Macros.input(view, "When were you born?",
    "I don't remember, I was very young at the time");

int result = Macros.confirm(view, "Do you really want to learn"
    + " about BeanShell?",JOptionPane.YES_NO_OPTION);
    </programlisting>
        </informalexample>

        <para>In the last three examples, placing the word
        <classname>String</classname> or <classname>int</classname> before the
        variable name <varname>result</varname> tells BeanShell that the
        variable refers to an integer or a <classname>String</classname> object,
        even before a particular value is assigned to the variable. In
        BeanShell, this <glossterm>declaration</glossterm> of the
        <glossterm>type</glossterm> of <varname>result</varname> is not
        necessary; BeanShell can figure it out when the macro runs. This can be
        helpful if you are not comfortable with specifying types and classes;
        just use your variables and let BeanShell worry about it.</para>

        <para>Note that macros are not limited to using these methods for
        presenting a user interface. In fact, full-blown user interfaces using
        the Java Swing APIs are also possible, and will be covered later on in
        <xref linkend="dialog-macro" />.</para>
    </sect1>

    <sect1 id="dynamic-typing">
        <title>BeanShell Dynamic Typing</title>

        <para>Without an explicit <glossterm>type declaration</glossterm> like
        <classname>String</classname> <varname>result</varname>, BeanShell
        variables can change their type at runtime depending on the object or
        data assigned to it. This dynamic typing allows you to write code like
        this (if you really wanted to):</para>

        <informalexample>
            <!-- <title>Dynamic typing of variables</title> -->

            <programlisting>// note: no type declaration
result = Macros.input(view, <quote>Type something here.</quote>);

// this is our predefined, current View
result = view;

// this is an <quote>int</quote> (for integer);
// in Java and BeanShell, int is one of a small number
// of <quote>primitive</quote> data types which are not classes
result = 14;</programlisting>
        </informalexample>

        <para>However, if you first declared <varname>result</varname> to be
        type <classname>String</classname> and and then tried these
        reassignments, BeanShell would complain. While avoiding explicit type
        declaration makes writing macro code simpler, using them can act as a
        check to make sure you are not using the wrong variable type of object
        at a later point in your script. It also makes it easier (if you are so
        inclined) to take a BeanShell <quote>prototype</quote> and incorporate
        it in a Java program.</para>

        <para>One last thing before we bury our first macro. The double slashes
        in the examples just above signify that everything following them on
        that line should be ignored by BeanShell as a comment. As in Java and
        C/C++, you can also embed comments in your BeanShell code by setting
        them off with pairs of <userinput>/* */</userinput>, as in the following
        example:</para>

        <informalexample>
            <programlisting>/* This is a long comment that covers several lines
and will be totally ignored by BeanShell regardless of how
many lines it covers */</programlisting>
        </informalexample>
    </sect1>

    <sect1 id="something-useful">
        <title>Now For Something Useful</title>

        <para>Here is a macro that inserts the path of the current buffer in the
        text:</para>

        <informalexample>
            <!-- <title>Insert buffer path in text</title> -->

            <programlisting>String newText = buffer.getPath();
textArea.setSelectedText(newText);</programlisting>
        </informalexample>

        <para>Unlike in our first macro example, here we are calling class
        methods on particular objects. First, we call
        <function>getPath()</function> on the current <ulink
        url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink> object to get
        the full path of the text file currently being edited. Next, we call
        <function>setSelectedText()</function> on the current text display
        component, specifying the text to be inserted as a parameter.</para>

        <para>In precise terms, the <function>setSelectedText()</function>
        method substitutes the contents of the <classname>String</classname>
        parameter for a range of selected text that includes the current caret
        position. If no text is selected at the caret position, the effect of
        this operation is simply to insert the new text at that position.</para>

        <para>Here's a few alternatives to the full file path that you could use
        to insert various useful things:</para>

        <informalexample>
            <!-- <title>Items to use with
  <function>setSelectedText()</function></title> -->

            <programlisting>// the file name (without full path)
String newText = buffer.getName();

// today's date
import java.text.DateFormat;

String newText = DateFormat.getDateInstance()
    .format(new Date());

// a line count for the current buffer
String newText = "This file contains "
    + textArea.getLineCount() + " lines.";</programlisting>
        </informalexample>

        <para>Here are brief comments on each:</para>

        <itemizedlist>
            <listitem>
                <para>In the first, the call to <function>getName()</function>
                invokes another method of the <ulink
                url="../api/org/gjt/sp/jedit/Buffer.html">Buffer</ulink>
                class.</para>
            </listitem>

            <listitem>
                <para>The syntax of the second example chains the results of
                several methods. You could write it this way:</para>

                <programlisting>import java.text.DateFormat;
Date d = new Date();
DateFormat df = DateFormat.getDateInstance();
String result = df.format(d);
</programlisting>

                <para>Taking the pieces in order:</para>

                <itemizedlist>
                    <listitem>
                        <para>A Java <classname>Date</classname> object is
                        created using the <function>new</function> keyword. The
                        empty parenthesis after <classname>Date</classname>
                        signify a call on the <glossterm> constructor
                        method</glossterm> of <classname>Date</classname> having
                        no parameters; here, a <classname>Date</classname> is
                        created representing the current date and time.</para>
                    </listitem>

                    <listitem>
                        <para><function>DateFormat.getDateInstance()</function>
                        is a static method that creates and returns a
                        <classname>DateFormat</classname> object. As the name
                        implies, <classname>DateFormat</classname> is a Java
                        class that takes <classname>Date</classname> objects and
                        produces readable text. The method
                        <function>getDateInstance()</function> returns a
                        <classname>DateFormat</classname> object that parses and
                        formats dates. It will use the default
                        <glossterm>locale</glossterm> or text format specified
                        in the user's Java installation.</para>
                    </listitem>

                    <listitem>
                        <para>Finally,
                        <classname>DateFormat.format()</classname> is called on
                        the new <classname>DateFormat</classname> object using
                        the <classname>Date</classname> object as a parameter.
                        The result is a <classname>String</classname> containing
                        the date in the default locale.</para>
                    </listitem>

                    <listitem>
                        <para>Note that the <classname>Date</classname> class is
                        contained in the <literal>java.util</literal> package,
                        so an explicit import statement is not required.
                        However, <classname>DateFormat</classname> is part of
                        the <literal>java.text</literal> package, which is not
                        automatically imported, so an explicit
                        <function>import</function> statement must be
                        used.</para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>The third example shows three items of note: <itemizedlist>
                        <listitem>
                            <para><function>getLineCount()</function> is a method
                            in jEdit's <ulink
                            url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink>
                            class. It returns an <classname>int</classname>
                            representing the number of lines in the current text
                            buffer. We call it on <varname>textArea</varname>,
                            the pre-defined, current <ulink
                            url="../api/org/gjt/sp/jedit/textarea/JEditTextArea.html">JEditTextArea</ulink>
                            object.</para>
                        </listitem>

                        <listitem>
                            <para>The use of the <function>+</function> operator
                            (which can be chained, as here) appends objects and
                            string literals to return a single, concatenated
                            <classname>String</classname>.</para>
                        </listitem>
                    </itemizedlist></para>
            </listitem>
        </itemizedlist>
    </sect1>
</chapter>