UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

63 lines (61 loc) 9.8 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <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>