📄 tij0145.html
字号:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Button
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Canvas</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in this example, and remember to call the base-class constructor
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>super(label)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
You’ll see that the button doesn’t get painted and the events
don’t get handled.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>myButton</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class is specific: it works only with an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>AutoEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
“parent window” (not a base class, but the window in which this
button is created and lives). With this knowledge,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>myButton</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can reach into the parent window and manipulate its text fields, which is
what’s necessary to be able to write the status information into the
fields of the parent. Of course this is a much more limited solution, since
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>myButton</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can be used only in conjunction with
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>AutoEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This kind of code is sometimes called “highly coupled.” However, to
make
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>myButton</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
more generic requires a lot more effort that isn’t warranted for this
example (and possibly for many of the applets that you will write). Again, keep
in mind that the following code uses APIs that are deprecated in Java 1.1<A NAME="Index1748"></A>.</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: AutoEvent.java</font>
<font color="#009900">// Alternatives to action()</font>
<font color="#0000ff">import</font> java.awt.*;
<font color="#0000ff">import</font> java.applet.*;
<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">class</font> MyButton <font color="#0000ff">extends</font> Canvas {
AutoEvent parent;
Color color;
String label;
MyButton(AutoEvent parent,
Color color, String label) {
<font color="#0000ff">this</font>.label = label;
<font color="#0000ff">this</font>.parent = parent;
<font color="#0000ff">this</font>.color = color;
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> paint(Graphics g) {
g.setColor(color);
<font color="#0000ff">int</font> rnd = 30;
g.fillRoundRect(0, 0, size().width,
size().height, rnd, rnd);
g.setColor(Color.black);
g.drawRoundRect(0, 0, size().width,
size().height, rnd, rnd);
FontMetrics fm = g.getFontMetrics();
<font color="#0000ff">int</font> width = fm.stringWidth(label);
<font color="#0000ff">int</font> height = fm.getHeight();
<font color="#0000ff">int</font> ascent = fm.getAscent();
<font color="#0000ff">int</font> leading = fm.getLeading();
<font color="#0000ff">int</font> horizMargin = (size().width - width)/2;
<font color="#0000ff">int</font> verMargin = (size().height - height)/2;
g.setColor(Color.white);
g.drawString(label, horizMargin,
verMargin + ascent + leading);
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font> keyDown(Event evt, <font color="#0000ff">int</font> key) {
TextField t =
(TextField)parent.h.get("keyDown");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font> keyUp(Event evt, <font color="#0000ff">int</font> key) {
TextField t =
(TextField)parent.h.get("keyUp");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font> lostFocus(Event evt, Object w) {
TextField t =
(TextField)parent.h.get("lostFocus");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font> gotFocus(Event evt, Object w) {
TextField t =
(TextField)parent.h.get("gotFocus");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font>
mouseDown(Event evt,<font color="#0000ff">int</font> x,<font color="#0000ff">int</font> y) {
TextField t =
(TextField)parent.h.get("mouseDown");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font>
mouseDrag(Event evt,<font color="#0000ff">int</font> x,<font color="#0000ff">int</font> y) {
TextField t =
(TextField)parent.h.get("mouseDrag");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font>
mouseEnter(Event evt,<font color="#0000ff">int</font> x,<font color="#0000ff">int</font> y) {
TextField t =
(TextField)parent.h.get("mouseEnter");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font>
mouseExit(Event evt,<font color="#0000ff">int</font> x,<font color="#0000ff">int</font> y) {
TextField t =
(TextField)parent.h.get("mouseExit");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font>
mouseMove(Event evt,<font color="#0000ff">int</font> x,<font color="#0000ff">int</font> y) {
TextField t =
(TextField)parent.h.get("mouseMove");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
<font color="#0000ff">public</font> <font color="#0000ff">boolean</font> mouseUp(Event evt,<font color="#0000ff">int</font> x,<font color="#0000ff">int</font> y) {
TextField t =
(TextField)parent.h.get("mouseUp");
t.setText(evt.toString());
<font color="#0000ff">return</font> <font color="#0000ff">true</font>;
}
}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> AutoEvent <font color="#0000ff">extends</font> Applet {
Hashtable h = <font color="#0000ff">new</font> Hashtable();
String[] event = {
"keyDown", "keyUp", "lostFocus",
"gotFocus", "mouseDown", "mouseUp",
"mouseMove", "mouseDrag", "mouseEnter",
"mouseExit"
};
MyButton
b1 = <font color="#0000ff">new</font> MyButton(<font color="#0000ff">this</font>, Color.blue, "test1"),
b2 = <font color="#0000ff">new</font> MyButton(<font color="#0000ff">this</font>, Color.red, "test2");
<font color="#0000ff">public</font> <font color="#0000ff">void</font> init() {
setLayout(<font color="#0000ff">new</font> GridLayout(event.length+1,2));
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i < event.length; i++) {
TextField t = <font color="#0000ff">new</font> TextField();
t.setEditable(<font color="#0000ff">false</font>);
add(<font color="#0000ff">new</font> Label(event[i], Label.CENTER));
add(t);
h.put(event[i], t);
}
add(b1);
add(b2);
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see the constructor uses the technique of using the same name for the
argument as what it’s assigned to, and differentiating between the two
using
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV><DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">this.label
= label;
</FONT></TT><P></DIV><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method starts out simple: it fills a “round rectangle” with the
button’s color, and then draws a black line around it. Notice the use of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>size( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to determine the width and height of the component (in pixels, of course).
After this,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>paint( )
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">seems
quite complicated because there’s a lot of calculation going on to figure
out how to center the button’s label inside the button using the
“font metrics.” You can get a pretty good idea of what’s
going on by looking at the method call, and it turns out that this is pretty
stock code, so you can just cut and paste it when you want to center a label
inside any component.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can’t understand exactly how the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>keyDown( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>keyUp( ),</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
etc. methods work until you look down at the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>AutoEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class. This contains a <A NAME="Index1749"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to hold the strings representing the type of event and the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TextField</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
where information about that event is held. Of course, these could have been
created statically rather than putting them in a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
but I think you’ll agree that it’s a lot easier to use and change.
In particular, if you need to add or remove a new type of event in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>AutoEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
you simply add or remove a string in the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>event</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
array – everything else happens automatically.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
place where you look up the strings is in the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>keyDown( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>keyUp( ),</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
etc. methods back in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>MyButton</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Each of these methods uses the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>parent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle to reach back to the parent window. Since that parent is an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>AutoEvent</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
it contains the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable
h
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>get( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, when provided with the appropriate
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
will produce a handle to an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that we happen to know is a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TextField</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
– so it is cast to that. Then the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Event</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object is converted to its
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
representation, which is displayed in the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TextField</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It
turns out this example is rather fun to play with since you can really see
what’s going on with the events in your program.
</FONT><a name="_Toc375545464"></a><a name="_Toc408018700"></a><P></DIV>
<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0144.html">Prev</a> | <a href="tij0146.html">Next</a>
</div>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -