You can declare and use methods in BeanShell, just as you would inside a Java class:
int
addTwoNumbers
(
int
a
,
int
b
)
{
return
a
+
b
;
}
sum
=
addTwoNumbers
(
5
,
7
);
// 12
BeanShell methods may also have dynamic (loose) argument and return types.
add
(
a
,
b
)
{
return
a
+
b
;
}
foo
=
add
(
1
,
2
);
// 3
foo
=
add
(
"Hello "
,
"Kitty"
);
// "Hello Kitty"
In BeanShell, as in JavaScript and Perl, method closures 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 this
. You can then use
the this
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:
user
(
n
)
{
name
=
n
;
reset
()
{
(
"Reset user:"
+
name
);
}
return
this
;
// return user as object
}
bob
=
user
(
"Bob"
);
(
bob
.
name
);
// "Bob"
bob
.
reset
();
// prints "Reset user: Bob"
This example assigns the context of the user()
method to the variable bob
and refers to the field bob.name
and the method bob.reset().
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.
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 this
-style reference as
described earlier, or by using the standard Java anonymous inner class
syntax. Here is an example:
actionPerformed
(
event
)
{
(
event
);
}
button
=
new
JButton
(
"Press Me!"
);
button
.
addActionListener
(
this
);
frame
(
button
);
You can type this code right on the command line and press the
button to see the events it generates. In this case, the this
reference refers to the current context,
just as in a method. BeanShell automatically implements the ActionListener
interface and delegates calls
to its actionPerformed()
method to
our scripted method.
Alternately, we could use the anonymous inner class syntax to
create an ActionListener
for our
button:
button
=
new
JButton
(
"Press Me!"
);
button
.
addActionListener
(
new
ActionListener
()
{
actionPerformed
(
event
)
{
(
event
);
}
}
);
frame
(
button
);
In this case the “anonymous inner class” is actually a BeanShell
script that implements the ActionListener
interface for us in the same
way as the previous example.
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 invoke()
method, which
handles calls to scripted methods that don’t exist:
invoke
(
name
,
args
)
{
(
"Method: "
+
name
+
" invoked!"
);
}
This invoke()
method will
handle method calls for methods that are not defined and simply print
their names. See the user manual for more details.
Get Learning Java, 4th Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.