epubjs
Version:
Render ePub documents in the browser, across many devices
63 lines (61 loc) • 9.8 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Scripted Methods and Objects</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Scripted Methods and Objects"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-APP-B-SECT-4"/>Scripted Methods and Objects</h1></div></div></div><p><a id="idx11252" class="indexterm"/>You can declare and use methods in BeanShell, just as you
would inside a Java class:</p><a id="I__tt1372"/><pre class="programlisting"> <code class="kt">int</code> <code class="nf">addTwoNumbers</code><code class="o">(</code> <code class="kt">int</code> <code class="n">a</code><code class="o">,</code> <code class="kt">int</code> <code class="n">b</code> <code class="o">)</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">a</code> <code class="o">+</code> <code class="n">b</code><code class="o">;</code>
<code class="o">}</code>
<code class="n">sum</code> <code class="o">=</code> <code class="n">addTwoNumbers</code><code class="o">(</code> <code class="mi">5</code><code class="o">,</code> <code class="mi">7</code> <code class="o">);</code> <code class="c1">// 12</code></pre><p>BeanShell methods may also have dynamic (loose) argument and return
types.</p><a id="I__tt1373"/><pre class="programlisting"> <code class="n">add</code><code class="o">(</code> <code class="n">a</code><code class="o">,</code> <code class="n">b</code> <code class="o">)</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">a</code> <code class="o">+</code> <code class="n">b</code><code class="o">;</code>
<code class="o">}</code>
<code class="n">foo</code> <code class="o">=</code> <code class="n">add</code><code class="o">(</code><code class="mi">1</code><code class="o">,</code> <code class="mi">2</code><code class="o">);</code> <code class="c1">// 3</code>
<code class="n">foo</code> <code class="o">=</code> <code class="n">add</code><code class="o">(</code><code class="s">"Hello "</code><code class="o">,</code> <code class="s">"Kitty"</code><code class="o">);</code> <code class="c1">// "Hello Kitty"</code></pre><p>In BeanShell, as in JavaScript and Perl, method <a id="I_indexterm_id839320" class="indexterm"/><span class="emphasis"><em>closures</em></span> can take the place of classes
for scripting objects (but in BeanShell you can also use the regular class
syntax). You can turn the context of a method call into an object
reference by having the method return the special value <a id="I_indexterm_id839330" class="indexterm"/><code class="literal">this</code>. You can then use
the <code class="literal">this</code> reference to refer to any
variables that were set during the method call. To be useful, an object
may also need methods; so in BeanShell, methods may also contain methods
at any level. Here is a simple example:</p><a id="I__tt1374"/><pre class="programlisting"> <code class="n">user</code><code class="o">(</code> <code class="n">n</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">name</code> <code class="o">=</code> <code class="n">n</code><code class="o">;</code>
<code class="n">reset</code><code class="o">()</code> <code class="o">{</code>
<code class="n">print</code><code class="o">(</code> <code class="s">"Reset user:"</code><code class="o">+</code><code class="n">name</code> <code class="o">);</code>
<code class="o">}</code>
<code class="k">return</code> <code class="k">this</code><code class="o">;</code> <code class="c1">// return user as object</code>
<code class="o">}</code>
<code class="n">bob</code> <code class="o">=</code> <code class="n">user</code><code class="o">(</code><code class="s">"Bob"</code> <code class="o">);</code>
<code class="n">print</code><code class="o">(</code> <code class="n">bob</code><code class="o">.</code><code class="na">name</code> <code class="o">);</code> <code class="c1">// "Bob"</code>
<code class="n">bob</code><code class="o">.</code><code class="na">reset</code><code class="o">();</code> <code class="c1">// prints "Reset user: Bob"</code></pre><p>This example assigns the context of the <code class="literal">user()</code> method to the variable <code class="literal">bob</code> and refers to the field <code class="literal">bob.name</code> and the method <code class="literal">bob.reset().</code></p><p>If you find this strange, don’t worry. The most common reason you’d
want to script an object is to implement a Java interface, and you can do
that using the standard Java anonymous inner class syntax, as we’ll
discuss next, or just use a regular class. BeanShell gives you a lot of
options.</p><div class="sect2" title="Scripting Interfaces and Adapters"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-APP-B-SECT-4.1"/>Scripting Interfaces and Adapters</h2></div></div></div><p><a id="idx11253" class="indexterm"/>One of the most powerful features of BeanShell is that you
can “script” any interface type. BeanShell-scripted objects can
automatically implement any required interface type. The only thing you
need to do is implement the necessary method (or at least the ones that
are going to be invoked). You can use this feature either by explicitly
referring to a BeanShell script using a <a id="I_indexterm_id839420" class="indexterm"/><code class="literal">this</code>-style reference as
described earlier, or by using the standard Java anonymous inner class
syntax. Here is an example:</p><a id="I__tt1375"/><pre class="programlisting"> <code class="n">actionPerformed</code><code class="o">(</code> <code class="n">event</code> <code class="o">)</code> <code class="o">{</code> <code class="n">print</code><code class="o">(</code> <code class="n">event</code> <code class="o">);</code> <code class="o">}</code>
<code class="n">button</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Press Me!"</code><code class="o">);</code>
<code class="n">button</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">(</code> <code class="n">button</code> <code class="o">);</code></pre><p>You can type this code right on the command line and press the
button to see the events it generates. In this case, the <code class="literal">this</code> reference refers to the current context,
just as in a method. BeanShell automatically implements the <code class="literal">ActionListener</code> interface and delegates calls
to its <code class="literal">actionPerformed()</code> method to
our scripted method.</p><p>Alternately, we could use the anonymous inner class syntax to
create an <code class="literal">ActionListener</code> for our
button:</p><a id="I__tt1376"/><pre class="programlisting"> <code class="n">button</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Press Me!"</code><code class="o">);</code>
<code class="n">button</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code> <code class="k">new</code> <code class="n">ActionListener</code><code class="o">()</code> <code class="o">{</code>
<code class="n">actionPerformed</code><code class="o">(</code> <code class="n">event</code> <code class="o">)</code> <code class="o">{</code> <code class="n">print</code><code class="o">(</code> <code class="n">event</code> <code class="o">);</code> <code class="o">}</code>
<code class="o">}</code> <code class="o">);</code>
<code class="n">frame</code><code class="o">(</code> <code class="n">button</code> <code class="o">);</code></pre><p>In this case the “anonymous inner class” is actually a BeanShell
script that implements the <code class="literal">ActionListener</code> interface for us in the same
way as the previous example.</p><p>One more thing: we hinted earlier that you only have to implement
those methods of the interface that you want to use. If you don’t script
a method, it’s OK as long as it’s not invoked (in which case, you’d get
an exception). For convenience in implementing a large interface, you
can define the special <a id="I_indexterm_id839502" class="indexterm"/><code class="literal">invoke()</code> method, which
handles calls to scripted methods that don’t exist:</p><a id="I__tt1377"/><pre class="programlisting"> <code class="n">invoke</code><code class="o">(</code> <code class="n">name</code><code class="o">,</code> <code class="n">args</code> <code class="o">)</code> <code class="o">{</code> <code class="n">print</code><code class="o">(</code><code class="s">"Method: "</code><code class="o">+</code><code class="n">name</code><code class="o">+</code><code class="s">" invoked!"</code><code class="o">);</code> <code class="o">}</code></pre><p>This <code class="literal">invoke()</code> method will
handle method calls for methods that are not defined and simply print
their names. See the user manual for more details.<a id="I_indexterm_id839532" class="indexterm"/><a id="I_indexterm_id839539" class="indexterm"/></p></div></div></body></html>