📄 tij0150.html
字号:
<html><body>
<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0149.html">Prev</a> | <a href="tij0151.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
Visual
programming
<P>and
Beans
</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">So
far in this book you’ve seen how valuable <A NAME="Index2180"></A>Java
is for creating <A NAME="Index2181"></A>reusable
pieces of code. The “most reusable” unit of code has been the
class, since it comprises a cohesive unit of characteristics (fields) and
behaviors (methods) that can be reused either directly via composition or
through inheritance.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Inheritance
and polymorphism are essential parts of object-oriented programming, but in the
majority of cases when you’re putting together an application, what you
really want is components that do exactly what you need. You’d like to
drop these parts into your design like the electronic engineer puts together
chips on a circuit board (or even, in the case of Java, onto a Web page). It
seems, too, that there should be some way to accelerate this “modular
assembly” style of programming.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">“<A NAME="Index2182"></A><A NAME="Index2183"></A>Visual
programming” first became successful –
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>very</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
successful – with <A NAME="Index2184"></A><A NAME="Index2185"></A><A NAME="Index2186"></A><A NAME="Index2187"></A>Microsoft’s
Visual Basic (VB), followed by a second-generation design in <A NAME="Index2188"></A><A NAME="Index2189"></A><A NAME="Index2190"></A>Borland’s
Delphi (the primary inspiration for the Java Beans design). With these
programming tools the components are represented visually, which makes sense
since they usually display some kind of visual component such as a button or a
text field. The visual representation, in fact, is often exactly the way the
component will look in the running program. So part of the process of visual
programming involves dragging a component from a pallet and dropping it onto
your form. The <A NAME="Index2191"></A><A NAME="Index2192"></A>application
builder tool writes code as you do this, and that code will cause the component
to be created in the running program.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Simply
dropping the component onto a form is usually not enough to complete the
program. Often, you must change the characteristics of a component, such as
what color it is, what text is on it, what database it’s connected to,
etc. Characteristics that can be modified at design time are referred to as <A NAME="Index2193"></A><A NAME="Index2194"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>properties</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
You can manipulate the properties of your component inside the application
builder tool, and when you create the program this configuration data is saved
so that it can be rejuvenated when the program is started.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">By
now you’re probably used to the idea that an object is more than
characteristics; it’s also a set of behaviors. At design-time, the
behaviors of a visual component are partially represented by <A NAME="Index2195"></A><A NAME="Index2196"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>events</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
meaning “Here’s something that can happen to the component.”
Ordinarily, you decide what you want to happen when an event occurs by tying
code to that event.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Here’s
the critical part: the application builder tool is able to dynamically
interrogate (using <A NAME="Index2197"></A><A NAME="Index2198"></A>reflection)
the component to find out which properties and events the component supports.
Once it knows what they are, it can display the properties and allow you to
change those (saving the state when you build the program), and also display
the events. In general, you do something like double clicking on an event and
the application builder tool creates a code body and ties it to that particular
event. All you have to do at that point is write the code that executes when
the event occurs.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">All
this adds up to a lot of work that’s done for you by the application
builder tool. As a result you can focus on what the program looks like and what
it is supposed to do, and rely on the application builder tool to manage the
connection details for you. The reason that visual programming tools have been
so successful is that they dramatically speed up the process of building an
application – certainly the user interface, but often other portions of
the application as well.
</FONT><a name="_Toc408018718"></a><P></DIV>
<A NAME="Heading455"></A><H3 ALIGN=LEFT>
What
is a Bean?
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">After
the dust settles, then, a <A NAME="Index2199"></A><A NAME="Index2200"></A>component
is really just a block of code, typically embodied in a class. The key issue is
the ability for the application builder tool to discover the properties and
events for that component. To create a VB component, the programmer had to
write a fairly complicated piece of code following certain conventions to
expose the properties and events. Delphi was a second-generation visual
programming tool and the language was actively designed around visual
programming so it is much easier to create a visual component. However, Java
has brought the creation of visual components to its most advanced state with
Java Beans, because a Bean is just a class. You don’t have to write any
extra code or use special language extensions in order to make something a
Bean. The only thing you need to do, in fact, is slightly modify the way that
you name your methods. It is the method name that tells the application builder
tool whether this is a property, an event, or just an ordinary method.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
the Java documentation, this naming convention is mistakenly termed a
“design pattern.” This is unfortunate since design patterns (see
Chapter 16) are challenging enough without this sort of confusion. It’s
not a design pattern, it’s just a <A NAME="Index2201"></A>naming
convention and it’s fairly simple:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> For
a property named
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>xxx</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
you typically create two methods:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getXxx( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>setXxx( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Note that the first letter after get or set is automatically lowercased to
produce the property name. The type produced by the “get” method is
the same as the type of the argument to the “set” method. The name
of the property and the type for the “get” and “set”
are not related.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> For
a boolean property, you can use the “get” and “set”
approach above, but you can also use “is” instead of
“get.”
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Ordinary
methods of the Bean don’t conform to the above naming convention, but
they’re
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> For
events, you use the “listener” approach. It’s exactly the
same as you’ve been seeing:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addFooBarListener(FooBarListener)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>removeFooBarListener(FooBarListener)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to handle a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>FooBarEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Most of the time the built-in events and listeners will satisfy your needs, but
you can also create your own events and listener interfaces.
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Point
1 above answers a question about something you might have noticed in the change
from Java 1.0<A NAME="Index2202"></A>
to Java 1.1<A NAME="Index2203"></A>:
a number of method names have had small, apparently meaningless name changes.
Now you can see that most of those changes had to do with adapting to the
“get” and “set” naming conventions in order to make
that particular component into a Bean.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">We
can use these guidelines to create a simple Bean:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Frog.java</font>
<font color="#009900">// A trivial Java Bean</font>
<font color="#0000ff">package</font> frogbean;
<font color="#0000ff">import</font> java.awt.*;
<font color="#0000ff">import</font> java.awt.event.*;
<font color="#0000ff">class</font> Spots {}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> Frog {
<font color="#0000ff">private</font> <font color="#0000ff">int</font> jumps;
<font color="#0000ff">private</font> Color color;
<font color="#0000ff">private</font> Spots spots;
<font color="#0000ff">private</font> <font color="#0000ff">boolean</font> jmpr;
<font color="#0000ff">public</font> <font color="#0000ff">int</font> getJumps() { <font color="#0000ff">return</font> jumps; }
<font color="#0000ff">public</font> <font color="#0000ff">void</font> setJumps(<font color="#0000ff">int</font> newJumps) {
jumps = newJumps;
}
<font color="#0000ff">public</font> Color getColor() { <font color="#0000ff">return</font> color; }
<font color="#0000ff">public</font> <font color="#0000ff">void</font> setColor(Color newColor) {
color = newColor;
}
<font color="#0000ff">public</font> Spots getSpots() { <font color="#0000ff">return</font> spots; }
<font color="#0000ff">public</font> <font color="#0000ff">void</font> setSpots(Spots newSpots) {
spots = newSpots;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font> isJumper() { <font color="#0000ff">return</font> jmpr; }
<font color="#0000ff">public</font> <font color="#0000ff">void</font> setJumper(<font color="#0000ff">boolean</font> j) { jmpr = j; }
<font color="#0000ff">public</font> <font color="#0000ff">void</font> addActionListener(
ActionListener l) {
<font color="#009900">//...</font>
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> removeActionListener(
ActionListener l) {
<font color="#009900">// ...</font>
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> addKeyListener(KeyListener l) {
<font color="#009900">// ...</font>
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> removeKeyListener(KeyListener l) {
<font color="#009900">// ...</font>
}
<font color="#009900">// An "ordinary" public method:</font>
<font color="#0000ff">public</font> <font color="#0000ff">void</font> croak() {
System.out.println("Ribbet!");
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">First,
you can see that it’s just a class. Usually, all your fields will be
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and accessible only through methods. Following the naming convention, the
properties are
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>jumps</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>color</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>spots</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>jumper</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(notice the change in case of the first letter in the property name). Although
the name of the internal identifier is the same as the name of the property in
the first three cases, in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>jumper</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you can see that the property name does not force you to use any particular
name for internal variables (or, indeed, to even
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>have</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
any internal variable for that property).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
events this Bean handles are
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ActionEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>KeyEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
based on the naming of the “add” and “remove” methods
for the associated listener. Finally, you can see that the ordinary method
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>croak( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is still part of the Bean simply because it’s a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, not because it conforms to any naming scheme.
</FONT><a name="_Toc408018719"></a><P></DIV>
<A NAME="Heading456"></A><H3 ALIGN=LEFT>
Extracting
BeanInfo
<P>with
the Introspector
</H3>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -