HTTP/2 302
server: nginx
date: Fri, 18 Jul 2025 05:17:07 GMT
content-type: text/plain; charset=utf-8
content-length: 0
x-archive-redirect-reason: found capture at 20060626183028
location: https://web.archive.org/web/20060626183028/https://examples.oreilly.com/javanut2/examples.tar.gz
server-timing: captures_list;dur=0.615049, exclusion.robots;dur=0.026649, exclusion.robots.policy;dur=0.012511, esindex;dur=0.013191, cdx.remote;dur=24.878439, LoadShardBlock;dur=216.438193, PetaboxLoader3.datanode;dur=95.532738, PetaboxLoader3.resolve;dur=118.806381
x-app-server: wwwb-app210
x-ts: 302
x-tr: 272
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
set-cookie: SERVER=wwwb-app210; path=/
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
HTTP/2 200
server: nginx
date: Fri, 18 Jul 2025 05:17:08 GMT
content-type: application/x-tar
content-length: 27536
x-archive-orig-date: Mon, 26 Jun 2006 18:30:24 GMT
x-archive-orig-server: Apache
x-archive-orig-last-modified: Sat, 02 Jun 2001 01:19:40 GMT
x-archive-orig-etag: "22f61f-6b90-3b183f2c"
x-archive-orig-accept-ranges: bytes
x-archive-orig-content-length: 27536
x-archive-orig-connection: close
content-encoding: x-gzip
cache-control: max-age=1800
x-archive-guessed-content-type: application/x-tar
x-archive-guessed-charset: utf-8
memento-datetime: Mon, 26 Jun 2006 18:30:28 GMT
link:
; rel="original", ; rel="timemap"; type="application/link-format", ; rel="timegate", ; rel="first memento"; datetime="Tue, 28 Mar 2006 06:31:46 GMT", ; rel="prev memento"; datetime="Tue, 28 Mar 2006 06:31:46 GMT", ; rel="memento"; datetime="Mon, 26 Jun 2006 18:30:28 GMT", ; rel="last memento"; datetime="Mon, 26 Jun 2006 18:30:28 GMT"
content-security-policy: default-src 'self' 'unsafe-eval' 'unsafe-inline' data: blob: archive.org web.archive.org web-static.archive.org wayback-api.archive.org athena.archive.org analytics.archive.org pragma.archivelab.org wwwb-events.archive.org
x-archive-src: 26_0_20060626182707_crawl27-c/26_0_20060626182807_crawl22.arc.gz
server-timing: captures_list;dur=0.785781, exclusion.robots;dur=0.033950, exclusion.robots.policy;dur=0.015147, esindex;dur=0.014603, cdx.remote;dur=53.940788, LoadShardBlock;dur=128.692785, PetaboxLoader3.datanode;dur=114.615656, PetaboxLoader3.resolve;dur=95.856523, load_resource;dur=132.917464
x-app-server: wwwb-app210
x-ts: 200
x-tr: 349
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
accept-ranges: bytes
examples/ 40775 765 765 0 6340337115 10226 5 ustar david examples/ch01/ 40775 765 765 0 6340142375 10763 5 ustar david examples/ch01/Scribble.java 100664 765 765 5704 6340142301 13443 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
public class Scribble extends Applet {
private int last_x, last_y; // Store the last mouse position.
private Color current_color = Color.black; // Store the current color.
private Button clear_button; // The clear button.
private Choice color_choices; // The color dropdown list.
// This method is called to initialize the applet.
// Applets don't have a main() method.
public void init() {
// Set the background color
this.setBackground(Color.white);
// Create a button and add it to the applet. Set the button's colors
clear_button = new Button("Clear");
clear_button.setForeground(Color.black);
clear_button.setBackground(Color.lightGray);
this.add(clear_button);
// Create a menu of colors and add it to the applet.
// Also set the menus's colors and add a label.
color_choices = new Choice();
color_choices.addItem("black");
color_choices.addItem("red");
color_choices.addItem("yellow");
color_choices.addItem("green");
color_choices.setForeground(Color.black);
color_choices.setBackground(Color.lightGray);
this.add(new Label("Color: "));
this.add(color_choices);
}
// This method is called when the user clicks the mouse to start a scribble.
public boolean mouseDown(Event e, int x, int y)
{
last_x = x; last_y = y;
return true;
}
// This method is called when the user drags the mouse.
public boolean mouseDrag(Event e, int x, int y)
{
Graphics g = this.getGraphics();
g.setColor(current_color);
g.drawLine(last_x, last_y, x, y);
last_x = x;
last_y = y;
return true;
}
// This method is called when the user clicks the button or chooses a color
public boolean action(Event event, Object arg) {
// If the Clear button was clicked on, handle it.
if (event.target == clear_button) {
Graphics g = this.getGraphics();
Rectangle r = this.bounds();
g.setColor(this.getBackground());
g.fillRect(r.x, r.y, r.width, r.height);
return true;
}
// Otherwise if a color was chosen, handle that
else if (event.target == color_choices) {
if (arg.equals("black")) current_color = Color.black;
else if (arg.equals("red")) current_color = Color.red;
else if (arg.equals("yellow")) current_color = Color.yellow;
else if (arg.equals("green")) current_color = Color.green;
return true;
}
// Otherwise, let the superclass handle it.
else return super.action(event, arg);
}
}
examples/ch02/ 40775 765 765 0 6340337127 10765 5 ustar david examples/ch02/throwtest.java 100664 765 765 10730 6340336635 14014 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
// Here we define some exception types of our own.
// Exception classes generally have constructors but no data or
// other methods. All these do is to call their superclass constructors.
class MyException extends Exception {
public MyException() { super(); }
public MyException(String s) { super(s); }
}
class MyOtherException extends Exception {
public MyOtherException() { super(); }
public MyOtherException(String s) { super(s); }
}
class MySubException extends MyException {
public MySubException() { super(); }
public MySubException(String s) { super(s); }
}
// This class demonstrates defining, throwing and handling exceptions.
// Try invoking it in the following ways and try to understand the
// output:
// java throwtest
// java throwtest one
// java throwtest 0
// java throwtest 1
// java throwtest 99
// java throwtest 2
// java throwtest 3
public class throwtest {
// This is the main() method. Note that it uses two
// catch clauses to handle two standard Java exceptions.
public static void main(String argv[]) {
int i;
// First, convert our argument to an integer
// Make sure we have an argument and that it is convertible.
try {
i = Integer.parseInt(argv[0]);
}
catch (ArrayIndexOutOfBoundsException e) { // argv is empty
System.out.println("Must specify an argument");
return;
}
catch (NumberFormatException e) { // argv[0] isn't an integer
System.out.println("Must specify an integer argument.");
return;
}
// Now, pass that integer to method a().
a(i);
}
// This method invokes b(), which is declared to throw
// one type of exception. We handle that one exception.
public static void a(int i) {
try {
b(i);
}
catch (MyException e) { // Point 1.
// Here we handle MyException and
// its subclass MyOtherException
if (e instanceof MySubException)
System.out.print("MySubException: ");
else
System.out.print("MyException: ");
System.out.println(e.getMessage());
System.out.println("Handled at point 1");
}
}
// This method invokes c(), and handles one of the
// two exception types that that method can throw. The other
// exception type is not handled, and is propagated up
// and declared in this method's throws clause.
// This method also has a finally clause to finish up
// the work of its try clause. Note that the finally clause
// is executed after a local catch clause, but before a
// a containing catch clause or one in an invoking procedure.
public static void b(int i) throws MyException {
int result;
try {
System.out.print("i = " + i);
result = c(i);
System.out.print(" c(i) = " + result);
}
catch (MyOtherException e) { // Point 2
// Handle MyOtherException exceptions:
System.out.println("MyOtherException: " + e.getMessage());
System.out.println("Handled at point 2");
}
finally {
// Terminate the output we printed above with a newline.
System.out.print("\n");
}
}
// This method computes a value or throws an exception.
// The throws clause only lists two exceptions, because
// one of the exceptions thrown is a subclass of another.
public static int c(int i) throws MyException, MyOtherException {
switch (i) {
case 0: // processing resumes at point 1 above
throw new MyException("input too low");
case 1: // processing resumes at point 1 above
throw new MySubException("input still too low");
case 99:// processing resumes at point 2 above
throw new MyOtherException("input too high");
default:
return i*i;
}
}
}
examples/ch06/ 40775 765 765 0 6340142375 10770 5 ustar david examples/ch06/Soundmap.java 100664 765 765 13074 6340142301 13530 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
/**
* A Java applet that simulates a client-side imagemap.
* Plays a sound whenever the user clicks on one of the hyperlinks.
*/
public class Soundmap extends Applet {
protected Image image; // The image to display.
protected Vector rects; // A list of rectangles in it.
protected AudioClip sound; // A sound to play on user clicks in a rectangle.
/** Initialize the applet */
public void init() {
// Look up the name of the image, relative to a base URL, and load it.
// Note the use of three Applet methods in this one line.
image = this.getImage(this.getDocumentBase(), this.getParameter("image"));
// Lookup and parse a list of rectangular areas and the URLs they map to.
// The convenience routine getRectangleParameter() is defined below.
rects = new Vector();
ImagemapRectangle r;
for(int i = 0; (r = getRectangleParameter("rect" + i)) != null; i++)
rects.addElement(r);
// Look up a sound to play when the user clicks one of those areas.
sound = this.getAudioClip(this.getDocumentBase(),
this.getParameter("sound"));
// Specify an "event listener" object to respond to mouse button
// presses and releases. Note that this is the Java 1.1 event model.
// Note that it also uses a Java 1.1 inner class, defined below.
this.addMouseListener(new Listener());
}
/** Called when the applet is being unloaded from the system.
* We use it here to "flush" the image we no longer need. This may
* result in memory and other resources being freed more quickly. */
public void destroy() { image.flush(); }
/** To display the applet, we simply draw the image. */
public void paint(Graphics g) { g.drawImage(image, 0, 0, this); }
/** We override this method so that it doesn't clear the background
* before calling paint(). No clear is necessary, since paint() overwrites
* everything with an image. Causes less flickering this way. */
public void update(Graphics g) { paint(g); }
/** Parse a comma-separated list of rectangle coordinates and a URL.
* Used to read the imagemap rectangle definitions from applet parameters */
protected ImagemapRectangle getRectangleParameter(String name) {
int x, y, w, h;
URL url;
String value = this.getParameter(name);
if (value == null) return null;
try {
StringTokenizer st = new StringTokenizer(value, ",");
x = Integer.parseInt(st.nextToken());
y = Integer.parseInt(st.nextToken());
w = Integer.parseInt(st.nextToken());
h = Integer.parseInt(st.nextToken());
url = new URL(this.getDocumentBase(), st.nextToken());
}
catch (NoSuchElementException e) { return null; }
catch (NumberFormatException e) { return null; }
catch (MalformedURLException e) { return null; }
return new ImagemapRectangle(x, y, w, h, url);
}
/**
* An instance of this inner class is used to respond to mouse events
*/
class Listener extends MouseAdapter {
/** The rectangle that the mouse was pressed in. */
private ImagemapRectangle lastrect;
/** Called when a mouse button is pressed. */
public void mousePressed(MouseEvent e) {
// On button down, check if we're inside one of the specified rectangles.
// If so, highlight the rectangle, display a message, and play a sound.
// The utility routine findrect() is defined below.
ImagemapRectangle r = findrect(e);
if (r == null) return;
Graphics g = Applet.this.getGraphics();
g.setXORMode(Color.red);
g.drawRect(r.x, r.y, r.width, r.height); // highlight rectangle
Applet.this.showStatus("To: " + r.url); // display URL
sound.play(); // play the sound
lastrect = r; // Remember the rectangle so it can be un-highlighted.
}
/** Called when a mouse button is released. */
public void mouseReleased(MouseEvent e) {
// When the button is released, unhighlight the rectangle. If the
// mouse is still inside it, ask the browser to go to the URL.
if (lastrect != null) {
Graphics g = Applet.this.getGraphics();
g.setXORMode(Color.red);
g.drawRect(lastrect.x, lastrect.y, lastrect.width, lastrect.height);
Applet.this.showStatus(""); // Clear the message.
ImagemapRectangle r = findrect(e);
if ((r != null) && (r == lastrect)) // If still in the same rectangle
Applet.this.getAppletContext().showDocument(r.url); // Go to the URL
lastrect = null;
}
}
/** Find the rectangle we're inside. */
protected ImagemapRectangle findrect(MouseEvent e) {
int i, x = e.getX(), y = e.getY();
for(i = 0; i < rects.size(); i++) {
ImagemapRectangle r = (ImagemapRectangle) rects.elementAt(i);
if (r.contains(x, y)) return r;
}
return null;
}
}
/**
* A helper class. Just like java.awt.Rectangle, but with a URL field.
* Note the use of a nested toplevel class for neatness.
*/
static class ImagemapRectangle extends Rectangle {
URL url;
public ImagemapRectangle(int x, int y, int w, int h, URL url) {
super(x, y, w, h);
this.url = url;
}
}
}
examples/ch06/ColorScribble.java 100664 765 765 3632 6340142301 14445 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
public class ColorScribble extends Scribble {
// Read in two color parameters and set the colors.
public void init() {
super.init();
Color foreground = getColorParameter("foreground");
Color background = getColorParameter("background");
if (foreground != null) this.setForeground(foreground);
if (background != null) this.setBackground(background);
}
// Read the specified parameter. Interpret it as a hexadecimal
// number of the form RRGGBB and convert it to a color.
protected Color getColorParameter(String name) {
String value = this.getParameter(name);
try { return new Color(Integer.parseInt(value, 16)); }
catch (Exception e) { return null; }
}
// Return information suitable for display in an About dialog box.
public String getAppletInfo() {
return "ColorScribble v. 0.02. Written by David Flanagan.";
}
// Return info about the supported parameters. Web browsers and applet
// viewers should display this information, and may also allow users to
// set the parameter values.
public String[][] getParameterInfo() { return info; }
// Here's the information that getParameterInfo() returns.
// It is an array of arrays of strings describing each parameter.
// Format: parameter name, parameter type, parameter description
private String[][] info = {
{"foreground", "hexadecimal color value", "foreground color"},
{"background", "hexadecimal color value", "background color"}
};
}
examples/ch06/Scribble.java 100664 765 765 2136 6340142301 13444 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
public class Scribble extends Applet {
private int last_x = 0, last_y = 0; // Fields to store a point in.
// Called when the user clicks.
public boolean mouseDown(Event e, int x, int y) {
last_x = x; last_y = y; // Remember the location of the click.
return true;
}
// Called when the mouse moves with the button down
public boolean mouseDrag(Event e, int x, int y) {
Graphics g = getGraphics(); // Get a Graphics to draw with.
g.drawLine(last_x, last_y, x, y); // Draw a line from last point to this.
last_x = x; last_y = y; // And update the saved location.
return true;
}
}
examples/ch06/SecondApplet.java 100664 765 765 2442 6340142301 14300 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
public class SecondApplet extends Applet {
static final String message = "Hello World";
private Font font;
// One-time initialization for the applet
// Note: no constructor defined.
public void init() {
font = new Font("Helvetica", Font.BOLD, 48);
}
// Draw the applet whenever necessary. Do some fancy graphics.
public void paint(Graphics g) {
// The pink oval
g.setColor(Color.pink);
g.fillOval(10, 10, 330, 100);
// The red outline. Java doesn't support wide lines, so we
// try to simulate a 4-pixel wide line by drawing four ovals.
g.setColor(Color.red);
g.drawOval(10,10, 330, 100);
g.drawOval(9, 9, 332, 102);
g.drawOval(8, 8, 334, 104);
g.drawOval(7, 7, 336, 106);
// The text
g.setColor(Color.black);
g.setFont(font);
g.drawString(message, 40, 75);
}
}
examples/ch06/FirstApplet.java 100664 765 765 1404 6340142301 14151 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*; // Don't forget this import statement!
import java.awt.*; // Or this one for the graphics!
public class FirstApplet extends Applet {
// This method displays the applet.
// The Graphics class is how you do all drawing in Java.
public void paint(Graphics g) {
g.drawString("Hello World", 25, 50);
}
}
examples/ch07/ 40775 765 765 0 6340142375 10771 5 ustar david examples/ch07/Scribble4.java 100664 765 765 4022 6340142301 13525 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble4 extends Applet {
private int lastx, lasty;
/** Tell the system we're interested in mouse events, mouse motion events,
* and keyboard events. This is required or events won't be sent.
*/
public void init() {
this.enableEvents(AWTEvent.MOUSE_EVENT_MASK |
AWTEvent.MOUSE_MOTION_EVENT_MASK |
AWTEvent.KEY_EVENT_MASK);
this.requestFocus(); // Ask for keyboard focus so we get key events
}
/** Invoked when a mouse event of some type occurs */
public void processMouseEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_PRESSED) { // check the event type
lastx = e.getX(); lasty = e.getY();
}
else super.processMouseEvent(e); // pass unhandled events to superclass
}
/** Invoked when a mouse motion event occurs */
public void processMouseMotionEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_DRAGGED) { // check type
int x = e.getX(), y = e.getY();
Graphics g = this.getGraphics();
g.drawLine(lastx, lasty, x, y);
lastx = x; lasty = y;
}
else super.processMouseMotionEvent(e);
}
/** Called on key events: clear the screen when 'c' is typed */
public void processKeyEvent(KeyEvent e) {
if ((e.getID() == KeyEvent.KEY_TYPED) && (e.getKeyChar() == 'c')) {
Graphics g = this.getGraphics();
g.setColor(this.getBackground());
g.fillRect(0, 0, this.getSize().width, this.getSize().height);
}
else super.processKeyEvent(e); // pass unhandled events to our superclass
}
}
examples/ch07/Scribble3.java 100664 765 765 3175 6340142301 13534 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble3 extends Applet {
int last_x, last_y;
public void init() {
// Define, instantiate and register a MouseListener object.
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
last_x = e.getX();
last_y = e.getY();
}
});
// Define, instantiate and register a MouseMotionListener object.
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
Graphics g = getGraphics();
int x = e.getX(), y = e.getY();
g.setColor(Color.black);
g.drawLine(last_x, last_y, x, y);
last_x = x; last_y = y;
}
});
// Create a clear button
Button b = new Button("Clear");
// Define, instantiate, and register a listener to handle button presses
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { // clear the scribble
Graphics g = getGraphics();
g.setColor(getBackground());
g.fillRect(0, 0, getSize().width, getSize().height);
}
});
// And add the button to the applet
this.add(b);
}
}
examples/ch07/Scribble2.java 100664 765 765 3405 6340142301 13527 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble2 extends Applet
implements MouseListener, MouseMotionListener {
private int last_x, last_y;
public void init() {
// Tell this applet what MouseListener and MouseMotionListener
// objects to notify when mouse and mouse motion events occur.
// Since we implement the interfaces ourself, our own methods are called.
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
// A method from the MouseListener interface. Invoked when the
// user presses a mouse button.
public void mousePressed(MouseEvent e) {
last_x = e.getX();
last_y = e.getY();
}
// A method from the MouseMotionListener interface. Invoked when the
// user drags the mouse with a button pressed.
public void mouseDragged(MouseEvent e) {
Graphics g = this.getGraphics();
int x = e.getX(), y = e.getY();
g.drawLine(last_x, last_y, x, y);
last_x = x; last_y = y;
}
// The other, unused methods of the MouseListener interface.
public void mouseReleased(MouseEvent e) {;}
public void mouseClicked(MouseEvent e) {;}
public void mouseEntered(MouseEvent e) {;}
public void mouseExited(MouseEvent e) {;}
// The other method of the MouseMotionListener interface.
public void mouseMoved(MouseEvent e) {;}
}
examples/ch07/Scribble1.java 100664 765 765 3431 6340142301 13525 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.applet.*;
import java.awt.*;
/** A simple applet using the Java 1.0 event handling model */
public class Scribble1 extends Applet {
private int lastx, lasty; // Remember last mouse coordinates.
Button clear_button; // The Clear button.
Graphics g; // A Graphics object for drawing.
/** Initialize the button and the Graphics object */
public void init() {
clear_button = new Button("Clear");
this.add(clear_button);
g = this.getGraphics();
}
/** Respond to mouse clicks */
public boolean mouseDown(Event e, int x, int y) {
lastx = x; lasty = y;
return true;
}
/** Respond to mouse drags */
public boolean mouseDrag(Event e, int x, int y) {
g.setColor(Color.black);
g.drawLine(lastx, lasty, x, y);
lastx = x; lasty = y;
return true;
}
/** Respond to key presses */
public boolean keyDown(Event e, int key) {
if ((e.id == Event.KEY_PRESS) && (key == 'c')) {
clear();
return true;
}
else return false;
}
/** Respond to Button clicks */
public boolean action(Event e, Object arg) {
if (e.target == clear_button) {
clear();
return true;
}
else return false;
}
/** convenience method to erase the scribble */
public void clear() {
g.setColor(this.getBackground());
g.fillRect(0, 0, bounds().width, bounds().height);
}
}
examples/ch08/ 40775 765 765 0 6340142375 10772 5 ustar david examples/ch08/ScribbleFrame.java 100664 765 765 43132 6340142301 14442 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.awt.*; // ScrollPane, PopupMenu, MenuShortcut, etc.
import java.awt.datatransfer.*; // Clipboard, Transferable, DataFlavor, etc.
import java.awt.event.*; // New event model.
import java.io.*; // Object serialization streams.
import java.util.zip.*; // Data compression/decompression streams.
import java.util.Vector; // To store the scribble in.
import java.util.Properties; // To store printing preferences in.
/**
* This class places a Scribble component in a ScrollPane container,
* puts the ScrollPane in a window, and adds a simple pulldown menu system.
* The menu uses menu shortcuts. Events are handled with anonymous classes.
*/
public class ScribbleFrame extends Frame {
/** A very simple main() method for our program. */
public static void main(String[] args) { new ScribbleFrame(); }
/** Remember # of open windows so we can quit when last one is closed */
protected static int num_windows = 0;
/** Create a Frame, Menu, and ScrollPane for the scribble component */
public ScribbleFrame() {
super("ScribbleFrame"); // Create the window.
num_windows++; // Count it.
ScrollPane pane = new ScrollPane(); // Create a ScrollPane.
pane.setSize(300, 300); // Specify its size.
this.add(pane, "Center"); // Add it to the frame.
Scribble scribble;
scribble = new Scribble(this, 500, 500); // Create a bigger scribble area.
pane.add(scribble); // Add it to the ScrollPane.
MenuBar menubar = new MenuBar(); // Create a menubar.
this.setMenuBar(menubar); // Add it to the frame.
Menu file = new Menu("File"); // Create a File menu.
menubar.add(file); // Add to menubar.
// Create three menu items, with menu shortcuts, and add to the menu.
MenuItem n, c, q;
file.add(n = new MenuItem("New Window", new MenuShortcut(KeyEvent.VK_N)));
file.add(c = new MenuItem("Close Window",new MenuShortcut(KeyEvent.VK_W)));
file.addSeparator(); // Put a separator in the menu
file.add(q = new MenuItem("Quit", new MenuShortcut(KeyEvent.VK_Q)));
// Create and register action listener objects for the three menu items.
n.addActionListener(new ActionListener() { // Open a new window
public void actionPerformed(ActionEvent e) { new ScribbleFrame(); }
});
c.addActionListener(new ActionListener() { // Close this window.
public void actionPerformed(ActionEvent e) { close(); }
});
q.addActionListener(new ActionListener() { // Quit the program.
public void actionPerformed(ActionEvent e) { System.exit(0); }
});
// Another event listener, this one to handle window close requests.
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) { close(); }
});
// Set the window size and pop it up.
this.pack();
this.show();
}
/** Close a window. If this is the last open window, just quit. */
void close() {
if (--num_windows == 0) System.exit(0);
else this.dispose();
}
}
/**
* This class is a custom component that supports scribbling. It also has
* a popup menu that allows the scribble color to be set and provides access
* to printing, cut-and-paste, and file loading and saving facilities.
* Note that it extends Component rather than Canvas, making it "lightweight."
*/
class Scribble extends Component implements ActionListener {
protected short last_x, last_y; // Coordinates of last click.
protected Vector lines = new Vector(256,256); // Store the scribbles.
protected Color current_color = Color.black; // Current drawing color.
protected int width, height; // The preferred size.
protected PopupMenu popup; // The popup menu.
protected Frame frame; // The frame we are within.
/** This constructor requires a Frame and a desired size */
public Scribble(Frame frame, int width, int height) {
this.frame = frame;
this.width = width;
this.height = height;
// We handle scribbling with low-level events, so we must specify
// which events we are interested in.
this.enableEvents(AWTEvent.MOUSE_EVENT_MASK);
this.enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
// Create the popup menu using a loop. Note the separation of menu
// "action command" string from menu label. Good for internationalization.
String[] labels = new String[] {
"Clear", "Print", "Save", "Load", "Cut", "Copy", "Paste" };
String[] commands = new String[] {
"clear", "print", "save", "load", "cut", "copy", "paste" };
popup = new PopupMenu(); // Create the menu
for(int i = 0; i < labels.length; i++) {
MenuItem mi = new MenuItem(labels[i]); // Create a menu item.
mi.setActionCommand(commands[i]); // Set its action command.
mi.addActionListener(this); // And its action listener.
popup.add(mi); // Add item to the popup menu.
}
Menu colors = new Menu("Color"); // Create a submenu.
popup.add(colors); // And add it to the popup.
String[] colornames = new String[] { "Black", "Red", "Green", "Blue"};
for(int i = 0; i < colornames.length; i++) {
MenuItem mi = new MenuItem(colornames[i]); // Create the submenu items
mi.setActionCommand(colornames[i]); // in the same way.
mi.addActionListener(this);
colors.add(mi);
}
// Finally, register the popup menu with the component it appears over
this.add(popup);
}
/** Specifies big the component would like to be. It always returns the
* preferred size passed to the Scribble() constructor */
public Dimension getPreferredSize() { return new Dimension(width, height); }
/** This is the ActionListener method invoked by the popup menu items */
public void actionPerformed(ActionEvent event) {
// Get the "action command" of the event, and dispatch based on that.
// This method calls a lot of the interesting methods in this class.
String command = event.getActionCommand();
if (command.equals("clear")) clear();
else if (command.equals("print")) print();
else if (command.equals("save")) save();
else if (command.equals("load")) load();
else if (command.equals("cut")) cut();
else if (command.equals("copy")) copy();
else if (command.equals("paste")) paste();
else if (command.equals("Black")) current_color = Color.black;
else if (command.equals("Red")) current_color = Color.red;
else if (command.equals("Green")) current_color = Color.green;
else if (command.equals("Blue")) current_color = Color.blue;
}
/** Draw all the saved lines of the scribble, in the appropriate colors */
public void paint(Graphics g) {
for(int i = 0; i < lines.size(); i++) {
Line l = (Line)lines.elementAt(i);
g.setColor(l.color);
g.drawLine(l.x1, l.y1, l.x2, l.y2);
}
}
/**
* This is the low-level event-handling method called on mouse events
* that do not involve mouse motion. Note the use of isPopupTrigger()
* to check for the platform-dependent popup menu posting event, and of
* the show() method to make the popup visible. If the menu is not posted,
* then this method saves the coordinates of a mouse click or invokes
* the superclass method.
*/
public void processMouseEvent(MouseEvent e) {
if (e.isPopupTrigger()) // If popup trigger,
popup.show(this, e.getX(), e.getY()); // pop up the menu.
else if (e.getID() == MouseEvent.MOUSE_PRESSED) {
last_x = (short)e.getX(); last_y = (short)e.getY(); // Save position.
}
else super.processMouseEvent(e); // Pass other event types on.
}
/**
* This method is called for mouse motion events. It adds a line to the
* scribble, on screen, and in the saved representation
*/
public void processMouseMotionEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
Graphics g = getGraphics(); // Object to draw with.
g.setColor(current_color); // Set the current color.
g.drawLine(last_x, last_y, e.getX(), e.getY()); // Draw this line
lines.addElement(new Line(last_x, last_y, // and save it, too.
(short) e.getX(), (short)e.getY(),
current_color));
last_x = (short) e.getX(); // Remember current mouse coordinates.
last_y = (short) e.getY();
}
else super.processMouseMotionEvent(e); // Important!
}
/** Clear the scribble. Invoked by popup menu */
void clear() {
lines.removeAllElements(); // Throw out the saved scribble
repaint(); // and redraw everything.
}
/** Print out the scribble. Invoked by popup menu. */
void print() {
// Obtain a PrintJob object. This posts a Print dialog.
// printprefs (created below) stores user printing preferences.
Toolkit toolkit = this.getToolkit();
PrintJob job = toolkit.getPrintJob(frame, "Scribble", printprefs);
// If the user clicked Cancel in the print dialog, then do nothing.
if (job == null) return;
// Get a Graphics object for the first page of output.
Graphics page = job.getGraphics();
// Check the size of the scribble component and of the page.
Dimension size = this.getSize();
Dimension pagesize = job.getPageDimension();
// Center the output on the page. Otherwise it would be
// be scrunched up in the upper-left corner of the page.
page.translate((pagesize.width - size.width)/2,
(pagesize.height - size.height)/2);
// Draw a border around the output area, so it looks neat.
page.drawRect(-1, -1, size.width+1, size.height+1);
// Set a clipping region so our scribbles don't go outside the border.
// On-screen this clipping happens automatically, but not on paper.
page.setClip(0, 0, size.width, size.height);
// Print this Scribble component. By default this will just call paint().
// This method is named print(), too, but that is just coincidence.
this.print(page);
// Finish up printing.
page.dispose(); // End the page--send it to the printer.
job.end(); // End the print job.
}
/** This Properties object stores the user print dialog settings. */
private static Properties printprefs = new Properties();
/**
* The DataFlavor used for our particular type of cut-and-paste data.
* This one will transfer data in the form of a serialized Vector object.
* Note that in Java 1.1.1, this works intra-application, but not between
* applications. Java 1.1.1 inter-application data transfer is limited to
* the pre-defined string and text data flavors.
*/
public static final DataFlavor dataFlavor =
new DataFlavor(Vector.class, "ScribbleVectorOfLines");
/**
* Copy the current scribble and store it in a SimpleSelection object
* (defined below). Then put that object on the clipboard for pasting.
*/
public void copy() {
// Get system clipboard
Clipboard c = this.getToolkit().getSystemClipboard();
// Copy and save the scribble in a Transferable object
SimpleSelection s = new SimpleSelection(lines.clone(), dataFlavor);
// Put that object on the clipboard
c.setContents(s, s);
}
/** Cut is just like a copy, except we erase the scribble afterwards */
public void cut() { copy(); clear(); }
/**
* Ask for the Transferable contents of the system clipboard, then ask that
* object for the scribble data it represents. If either step fails, beep!
*/
public void paste() {
Clipboard c = this.getToolkit().getSystemClipboard(); // Get clipboard.
Transferable t = c.getContents(this); // Get its contents.
if (t == null) { // If there is nothing to paste, beep.
this.getToolkit().beep();
return;
}
try {
// Ask for clipboard contents to be converted to our data flavor.
// This will throw an exception if our flavor is not supported.
Vector newlines = (Vector) t.getTransferData(dataFlavor);
// Add all those pasted lines to our scribble.
for(int i = 0; i < newlines.size(); i++)
lines.addElement(newlines.elementAt(i));
// And redraw the whole thing
repaint();
}
catch (UnsupportedFlavorException e) {
this.getToolkit().beep(); // If clipboard has some other type of data
}
catch (Exception e) {
this.getToolkit().beep(); // Or if anything else goes wrong...
}
}
/**
* This nested class implements the Transferable and ClipboardOwner
* interfaces used in data transfer. It is a simple class that remembers a
* selected object and makes it available in only one specified flavor.
*/
static class SimpleSelection implements Transferable, ClipboardOwner {
protected Object selection; // The data to be transferred.
protected DataFlavor flavor; // The one data flavor supported.
public SimpleSelection(Object selection, DataFlavor flavor) {
this.selection = selection; // Specify data.
this.flavor = flavor; // Specify flavor.
}
/** Return the list of supported flavors. Just one in this case */
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { flavor };
}
/** Check whether we support a specified flavor */
public boolean isDataFlavorSupported(DataFlavor f) {
return f.equals(flavor);
}
/** If the flavor is right, transfer the data (i.e. return it) */
public Object getTransferData(DataFlavor f)
throws UnsupportedFlavorException {
if (f.equals(flavor)) return selection;
else throw new UnsupportedFlavorException(f);
}
/** This is the ClipboardOwner method. Called when the data is no
* longer on the clipboard. In this case, we don't need to do much. */
public void lostOwnership(Clipboard c, Transferable t) {
selection = null;
}
}
/**
* Prompt the user for a filename, and save the scribble in that file.
* Serialize the vector of lines with an ObjectOutputStream.
* Compress the serialized objects with a GZIPOutputStream.
* Write the compressed, serialized data to a file with a FileOutputStream.
* Don't forget to flush and close the stream.
*/
public void save() {
// Create a file dialog to query the user for a filename.
FileDialog f = new FileDialog(frame, "Save Scribble", FileDialog.SAVE);
f.show(); // Display the dialog and block.
String filename = f.getFile(); // Get the user's response
if (filename != null) { // If user didn't click "Cancel".
try {
// Create the necessary output streams to save the scribble.
FileOutputStream fos = new FileOutputStream(filename); // Save to file
GZIPOutputStream gzos = new GZIPOutputStream(fos); // Compressed
ObjectOutputStream out = new ObjectOutputStream(gzos); // Save objects
out.writeObject(lines); // Write the entire Vector of scribbles
out.flush(); // Always flush the output.
out.close(); // And close the stream.
}
// Print out exceptions. We should really display them in a dialog...
catch (IOException e) { System.out.println(e); }
}
}
/**
* Prompt for a filename, and load a scribble from that file.
* Read compressed, serialized data with a FileInputStream.
* Uncompress that data with a GZIPInputStream.
* Deserialize the vector of lines with a ObjectInputStream.
* Replace current data with new data, and redraw everything.
*/
public void load() {
// Create a file dialog to query the user for a filename.
FileDialog f = new FileDialog(frame, "Load Scribble", FileDialog.LOAD);
f.show(); // Display the dialog and block.
String filename = f.getFile(); // Get the user's response
if (filename != null) { // If user didn't click "Cancel".
try {
// Create necessary input streams
FileInputStream fis = new FileInputStream(filename); // Read from file
GZIPInputStream gzis = new GZIPInputStream(fis); // Uncompress
ObjectInputStream in = new ObjectInputStream(gzis); // Read objects
// Read in an object. It should be a vector of scribbles
Vector newlines = (Vector)in.readObject();
in.close(); // Close the stream.
lines = newlines; // Set the Vector of lines.
repaint(); // And redisplay the scribble.
}
// Print out exceptions. We should really display them in a dialog...
catch (Exception e) { System.out.println(e); }
}
}
/** A class to store the coordinates and color of one scribbled line.
* The complete scribble is stored as a Vector of these objects */
static class Line implements Serializable {
public short x1, y1, x2, y2;
public Color color;
public Line(short x1, short y1, short x2, short y2, Color c) {
this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.color = c;
}
}
}
examples/ch09/ 40775 765 765 0 6340142375 10773 5 ustar david examples/ch09/IntList.java 100664 765 765 4151 6340142301 13307 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.io.*;
/** A simple class that implements a growable array or ints, and knows
* how to serialize itself as efficiently as a non-growable array. */
public class IntList implements Serializable
{
private int[] nums = new int[8]; // An array to store the numbers.
private transient int size = 0; // Index of next unused element of nums[].
/** Return an element of the array */
public int elementAt(int index) throws ArrayIndexOutOfBoundsException {
if (index >= size) throw new ArrayIndexOutOfBoundsException(index);
else return nums[index];
}
/** Add an int to the array, growing the array if necessary */
public void add(int x) {
if (nums.length == size) resize(nums.length*2); // Grow array, if needed.
nums[size++] = x; // Store the int in it.
}
/** An internal method to change the allocated size of the array */
protected void resize(int newsize) {
int[] oldnums = nums;
nums = new int[newsize]; // Create a new array.
System.arraycopy(oldnums, 0, nums, 0, size); // Copy array elements.
}
/** Get rid of unused array elements before serializing the array */
private void writeObject(ObjectOutputStream out) throws IOException {
if (nums.length > size) resize(size); // Compact the array.
out.defaultWriteObject(); // Then write it out normally.
}
/** Compute the transient size field after deserializing the array */
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject(); // Read the array normally.
size = nums.length; // Restore the transient field.
}
}
examples/ch10/ 40775 765 765 0 6340142375 10763 5 ustar david examples/ch10/YesNoDialogCustomizer.java 100664 765 765 11143 6340142301 16172 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
/**
* This class is a customizer for the YesNoDialog bean. It displays a
* TextArea and three TextFields where the user can enter the dialog message
* and the labels for each of the three buttons. It does not allow the
* dialog title or other resources to be set.
*/
public class YesNoDialogCustomizer extends Panel
implements Customizer, TextListener
{
protected YesNoDialog bean; // The bean being customized
protected TextComponent message, fields[]; // Components used by customizer
// Default constructor: YesNoDialogCustomizer() { super(); }
// The bean box calls this method to tell us what object to customize.
// This method will always be called before the customizer is displayed,
// so it is safe to create the customizer GUI here.
public void setObject(Object o) {
bean = (YesNoDialog)o; // save the object we're customizing
// Put a label at the top of the panel.
this.setLayout(new BorderLayout());
this.add(new Label("Enter the message to appear in the dialog:"), "North");
// And a big text area below it for entering the dialog message.
message = new TextArea(bean.getMessage());
message.addTextListener(this);
// TextAreas don't know how big they want to be. You must tell them.
message.setSize(400, 200);
this.add(message, "Center");
// Then add a row of textfields for entering the button labels.
Panel buttonbox = new Panel(); // The row container
buttonbox.setLayout(new GridLayout(1, 0, 25, 10)); // Equally spaced items
this.add(buttonbox, "South"); // Put row on bottom
// Now go create three TextFields to put in this row. But actually
// position a Label above each, so create an container for each
// TextField+Label combination.
fields = new TextComponent[3]; // Array of TextFields.
String[] labels = new String[] { // Labels for each.
"Yes Button Label", "No Button Label", "Cancel Button Label"};
String[] values = new String[] { // Initial values of each.
bean.getYesLabel(), bean.getNoLabel(), bean.getCancelLabel()};
for(int i = 0; i < 3; i++) {
Panel p = new Panel(); // Create a container.
p.setLayout(new BorderLayout()); // Give it a BorderLayout.
p.add(new Label(labels[i]), "North"); // Put a label on the top.
fields[i] = new TextField(values[i]); // Create the text field.
p.add(fields[i], "Center"); // Put it below the label.
fields[i].addTextListener(this); // Set the event listener.
buttonbox.add(p); // Add container to row.
}
}
// Add some space around the outside of the panel.
public Insets getInsets() { return new Insets(10, 10, 10, 10); }
// This is the method defined by the TextListener interface. Whenever the
// user types a character in the TextArea or TextFields, this will get
// called. It updates the appropriate property of the bean and fires a
// property changed event, as all customizers are required to do.
// Note that we are not required to fire an event for every keystroke.
// Instead we could include an "Apply" button that would make all the
// changes at once, with a single property changed event.
public void textValueChanged(TextEvent e) {
TextComponent t = (TextComponent)e.getSource();
String s = t.getText();
if (t == message) bean.setMessage(s);
else if (t == fields[0]) bean.setYesLabel(s);
else if (t == fields[1]) bean.setNoLabel(s);
else if (t == fields[2]) bean.setCancelLabel(s);
listeners.firePropertyChange(null, null, null);
}
// This code uses the PropertyChangeSupport class to maintain a list of
// listeners interested in the edits we make to the bean.
protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener l) {
listeners.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
listeners.removePropertyChangeListener(l);
}
}
examples/ch10/YesNoDialogMessageEditor.java 100664 765 765 5516 6340142301 16550 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
/**
* This class is a custom editor for the message property of the
* YesNoDialog bean. It is necessary because the default editor for
* properties of type String does not allow multi-line strings to be entered.
*/
public class YesNoDialogMessageEditor implements PropertyEditor {
protected String value; // The value we will be editing.
public void setValue(Object o) { value = (String) o; }
public Object getValue() { return value; }
public void setAsText(String s) { value = s; }
public String getAsText() { return value; }
public String[] getTags() { return null; } // not enumerated; no tags
// Say that we allow custom editing.
public boolean supportsCustomEditor() { return true; }
// Return the custom editor. This just creates and returns a TextArea
// to edit the multi-line text. But it also registers a listener on the
// text area to update the value as the user types and to fire the
// property change events that property editors are required to fire.
public Component getCustomEditor() {
final TextArea t = new TextArea(value);
t.setSize(300, 150); // TextArea doesn't have a preferred size, so set one
t.addTextListener(new TextListener() {
public void textValueChanged(TextEvent e) {
value = t.getText();
listeners.firePropertyChange(null, null, null);
}
});
return t;
}
// Visual display of the value, for use with the custom editor.
// Just print some instructions and hope they fit in the in the box.
// This could be more sophisticated.
public boolean isPaintable() { return true; }
public void paintValue(Graphics g, Rectangle r) {
g.setClip(r);
g.drawString("Click to edit...", r.x+5, r.y+15);
}
// Important method for code generators. Note that it
// ought to add any necessary escape sequences.
public String getJavaInitializationString() { return "\"" + value + "\""; }
// This code uses the PropertyChangeSupport class to maintain a list of
// listeners interested in the edits we make to the value.
protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener l) {
listeners.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
listeners.removePropertyChangeListener(l);
}
}
examples/ch10/YesNoDialogAlignmentEditor.java 100664 765 765 3037 6340142301 17076 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno;
import java.beans.*;
import java.awt.*;
public class YesNoDialogAlignmentEditor extends PropertyEditorSupport {
// These two methods allow the property to be edited in a dropdown list.
// Return the list of value names for the enumerated type.
public String[] getTags() {
return new String[] { "left", "center", "right" };
}
// Convert each of those value names into the actual value.
public void setAsText(String s) {
if (s.equals("left")) setValue(new Integer(YesNoDialog.LEFT));
else if (s.equals("center")) setValue(new Integer(YesNoDialog.CENTER));
else if (s.equals("right")) setValue(new Integer(YesNoDialog.RIGHT));
else throw new IllegalArgumentException(s);
}
// This is an important method for code generation.
public String getJavaInitializationString() {
switch(((Number)getValue()).intValue()) {
default:
case YesNoDialog.LEFT: return "oreilly.beans.yesno.YesNoDialog.LEFT";
case YesNoDialog.CENTER: return "oreilly.beans.yesno.YesNoDialog.CENTER";
case YesNoDialog.RIGHT: return "oreilly.beans.yesno.YesNoDialog.RIGHT";
}
}
}
examples/ch10/YesNoDialogBeanInfo.java 100664 765 765 10201 6340142301 15501 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno;
import java.beans.*;
import java.lang.reflect.*;
import java.awt.*;
/** The BeanInfo class for the YesNoDialog bean */
public class YesNoDialogBeanInfo extends SimpleBeanInfo {
/** Return an icon for the bean. We should really check the kind argument
* to see what size icon the beanbox wants, but since we only have one
* icon to offer, we just return it and let the beanbox deal with it */
public Image getIcon(int kind) {
return loadImage("YesNoDialogIcon.gif");
}
/** Return a descriptor for the bean itself. It specifies a customizer
* for the bean class. We could also add a description string here */
public BeanDescriptor getBeanDescriptor() {
return new BeanDescriptor(YesNoDialog.class, YesNoDialogCustomizer.class);
}
/** This is a convenience routine for creating PropertyDescriptor objects */
public static PropertyDescriptor property(String name, String description)
throws IntrospectionException
{
PropertyDescriptor p = new PropertyDescriptor(name, YesNoDialog.class);
p.setShortDescription(description);
return p;
}
/** This method returns an array of PropertyDescriptor objects that specify
* additional information about the properties supported by the bean.
* By explicitly specifying property descriptors, we are able to provide
* simple help strings for each property; these would not be available to
* the beanbox through simple introspection. We are also able to register
* special property editors for two of the properties
*/
public PropertyDescriptor[] getPropertyDescriptors() {
try {
PropertyDescriptor[] props = {
property("title", "The string that appears in the dialog title bar"),
property("message", "The string that appears in the dialog body"),
property("yesLabel", "The label for the 'Yes' button, if any"),
property("noLabel", "The label for the 'No' button, if any"),
property("cancelLabel", "The label for the 'Cancel' button, if any"),
property("alignment", "The alignment of the message text"),
property("font", "The font to use for message and buttons"),
property("background", "The background color for the dialog"),
property("foreground", "The text color for message and buttons")
};
props[1].setPropertyEditorClass(YesNoDialogMessageEditor.class);
props[5].setPropertyEditorClass(YesNoDialogAlignmentEditor.class);
return props;
}
catch (IntrospectionException e) {return super.getPropertyDescriptors(); }
}
/** The message property is most often customized; make it the default */
public int getDefaultPropertyIndex() { return 1; }
/** This is a convenience method for creating MethodDescriptors. Note that
* it assumes we are talking about methods with no arguments */
public static MethodDescriptor method(String name, String description)
throws NoSuchMethodException, SecurityException {
Method m = YesNoDialog.class.getMethod(name, new Class[] {});
MethodDescriptor md = new MethodDescriptor(m);
md.setShortDescription(description);
return md;
}
/** This method returns an array of method descriptors for the supported
* methods of a bean. This allows us to provide useful description strings,
* but it also allows us to filter out non-useful methods like wait()
* and notify() that the bean inherits and which might otherwise be
* displayed by the beanbox.
*/
public MethodDescriptor[] getMethodDescriptors() {
try {
MethodDescriptor[] methods = {
method("display", "Pop up the dialog; make it visible")
};
return methods;
}
catch (Exception e) {
return super.getMethodDescriptors();
}
}
}
examples/ch10/AnswerListener.java 100664 765 765 1165 6340142301 14660 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno;
public interface AnswerListener extends java.util.EventListener {
public void yes(AnswerEvent e);
public void no(AnswerEvent e);
public void cancel(AnswerEvent e);
}
examples/ch10/AnswerEvent.java 100664 765 765 1312 6340142301 14146 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno;
public class AnswerEvent extends java.util.EventObject {
protected int id;
public static final int YES = 0, NO = 1, CANCEL = 2;
public AnswerEvent(Object source, int id) {
super(source);
this.id = id;
}
public int getID() { return id; }
}
examples/ch10/YesNoDialog.java 100664 765 765 17471 6340142301 14117 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno; // Put this bean in its own private package.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class YesNoDialog {
// Properties of the bean.
protected String message, title;
protected String yesLabel, noLabel, cancelLabel;
protected int alignment;
protected Font font = new Font("Serif", Font.PLAIN, 12);
protected Color background = SystemColor.control;
protected Color foreground = SystemColor.controlText;
// Constants for the alignment property.
public static final int LEFT = MultiLineLabel.LEFT;
public static final int RIGHT = MultiLineLabel.RIGHT;
public static final int CENTER = MultiLineLabel.CENTER;
// Methods to query all of the bean properties.
public String getMessage() { return message; }
public String getTitle() { return title; }
public String getYesLabel() { return yesLabel; }
public String getNoLabel() { return noLabel; }
public String getCancelLabel() { return cancelLabel; }
public int getAlignment() { return alignment; }
public Font getFont() { return font; }
public Color getBackground() { return background; }
public Color getForeground() { return foreground; }
// Methods to set all of the bean properties.
public void setMessage(String m) { message = m; }
public void setTitle(String t) { title=t; }
public void setYesLabel(String l) { yesLabel = l; }
public void setNoLabel(String l) { noLabel = l; }
public void setCancelLabel(String l) { cancelLabel = l; }
public void setAlignment(int a) { alignment = a; }
public void setFont(Font f) { font = f; }
public void setBackground(Color bg) { background = bg; }
public void setForeground(Color fg) { foreground = fg; }
/** This field holds a list of registered ActionListeners.
* Vector is internally synchronized to prevent race conditions */
protected Vector listeners = new Vector();
/** Register an action listener to be notified when a button is pressed */
public void addAnswerListener(AnswerListener l) {
listeners.addElement(l);
}
/** Remove an Answer listener from our list of interested listeners */
public void removeAnswerListener(AnswerListener l) {
listeners.removeElement(l);
}
/** Send an event to all registered listeners */
public void fireEvent(AnswerEvent e) {
// Make a copy of the list and fire the events using that copy.
// This means that listeners can be added or removed from the original
// list in response to this event. We ought to be able to just use an
// enumeration for the vector, but that doesn't copy the list internally.
Vector list = (Vector) listeners.clone();
for(int i = 0; i < list.size(); i++) {
AnswerListener listener = (AnswerListener)list.elementAt(i);
switch(e.getID()) {
case AnswerEvent.YES: listener.yes(e); break;
case AnswerEvent.NO: listener.no(e); break;
case AnswerEvent.CANCEL: listener.cancel(e); break;
}
}
}
/** The no-argument bean constructor, with default property values */
public YesNoDialog() {
this("Question", "Your\nMessage\nHere", "Yes", "No", "Cancel", LEFT);
}
/** A constructor for programmers using this class "by hand" */
public YesNoDialog(String title, String message,
String yesLabel, String noLabel, String cancelLabel,
int alignment) {
this.title = title;
this.message = message;
this.yesLabel = yesLabel;
this.noLabel = noLabel;
this.cancelLabel = cancelLabel;
this.alignment = alignment;
}
/** This method makes the bean display the dialog box */
public void display() {
// Create a frame with the specified title. It would be nice to
// use a Dialog, but that needs to be passed a Frame argument, and
// the BDK beanbox tool only seems to work with no-argument methods.
final Frame frame = new Frame(title);
// Specify a LayoutManager for it.
frame.setLayout(new BorderLayout(15, 15));
// Specify font and colors, if any are specified.
if (font != null) frame.setFont(font);
if (background != null) frame.setBackground(background);
if (foreground != null) frame.setForeground(foreground);
// Put the message label in the middle of the window.
frame.add("Center", new MultiLineLabel(message, 20, 20, alignment));
// Create an action listener for use by the buttons of the dialog.
// When a button is pressed, this listener first closes the dialog box.
// Then, it creates an AnswerEvent object that corresponds to the
// button that was pressed, and send that new event to all registered
// listeners, using the fireEvent() method defined above.
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.dispose(); // pop down window
if (listeners != null) { // notify any registered listeners
String cmd = e.getActionCommand();
int type;
if (cmd.equals("yes")) type = AnswerEvent.YES;
else if (cmd.equals("no")) type = AnswerEvent.NO;
else type = AnswerEvent.CANCEL;
fireEvent(new AnswerEvent(YesNoDialog.this, type));
}
}
};
// Create a panel for the dialog buttons and put it at the bottom
// of the dialog. Specify a FlowLayout layout manager for it.
Panel buttonbox = new Panel();
buttonbox.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 15));
frame.add("South", buttonbox);
// Create each specified button, specifying the action listener
// and action command for each, and adding them to the buttonbox
if ((yesLabel != null) && (yesLabel.length() > 0)) {
Button yes = new Button(yesLabel); // Create button.
yes.setActionCommand("yes"); // Set action command.
yes.addActionListener(listener); // Set listener.
buttonbox.add(yes); // Add button to the panel.
}
if ((noLabel != null) && (noLabel.length() > 0)) {
Button no = new Button(noLabel);
no.setActionCommand("no");
no.addActionListener(listener);
buttonbox.add(no);
}
if ((cancelLabel != null) && (cancelLabel.length() > 0)) {
Button cancel = new Button(cancelLabel);
cancel.setActionCommand("cancel");
cancel.addActionListener(listener);
buttonbox.add(cancel);
}
// Finally, set the dialog to its preferred size and display it.
frame.pack();
frame.show();
}
/**
* A main method that demonstrates how to use this class, and allows testing
*/
public static void main(String[] args) {
// Create an instance of InfoDialog, with title and message specified:
YesNoDialog d =
new YesNoDialog("YesNoDialog Test",
"There are unsaved files.\n" +
"Do you want to save them before quitting?",
"Yes, save and quit",
"No, quit without saving",
"Cancel; don't quit",
YesNoDialog.CENTER);
// Register an action listener for the dialog. This one just prints
// the results out to the console.
d.addAnswerListener(new AnswerListener() {
public void yes(AnswerEvent e) { System.out.println("Yes"); }
public void no(AnswerEvent e) { System.out.println("No"); }
public void cancel(AnswerEvent e) { System.out.println("Cancel"); }
});
// Now pop the dialog up. It will pop itself down automatically.
d.display();
}
}
examples/ch10/MultiLineLabel.java 100664 765 765 13742 6340142301 14601 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
package oreilly.beans.yesno;
import java.awt.*;
import java.util.*;
/**
* A custom component that displays multiple lines of text with specified
* margins and alignment. In Java 1.1, we could extend Component instead
* of Canvas, making this a more efficient "Lightweight component"
*/
public class MultiLineLabel extends Canvas {
// User-specified attributes
protected String label; // The label, not broken into lines
protected int margin_width; // Left and right margins
protected int margin_height; // Top and bottom margins
protected int alignment; // The alignment of the text.
public static final int LEFT = 0, CENTER = 1, RIGHT = 2; // alignment values
// Computed state values
protected int num_lines; // The number of lines
protected String[] lines; // The label, broken into lines
protected int[] line_widths; // How wide each line is
protected int max_width; // The width of the widest line
protected int line_height; // Total height of the font
protected int line_ascent; // Font height above baseline
protected boolean measured = false; // Have the lines been measured?
// Here are five versions of the constructor.
public MultiLineLabel(String label, int margin_width,
int margin_height, int alignment) {
this.label = label; // Remember all the properties.
this.margin_width = margin_width;
this.margin_height = margin_height;
this.alignment = alignment;
newLabel(); // Break the label up into lines.
}
public MultiLineLabel(String label, int margin_width, int margin_height) {
this(label, margin_width, margin_height, LEFT);
}
public MultiLineLabel(String label, int alignment) {
this(label, 10, 10, alignment);
}
public MultiLineLabel(String label) { this(label, 10, 10, LEFT); }
public MultiLineLabel() { this(""); }
// Methods to set and query the various attributes of the component.
// Note that some query methods are inherited from the superclass.
public void setLabel(String label) {
this.label = label;
newLabel(); // Break the label into lines.
measured = false; // Note that we need to measure lines.
repaint(); // Request a redraw.
}
public void setFont(Font f) {
super.setFont(f); // Tell our superclass about the new font.
measured = false; // Note that we need to remeasure lines.
repaint(); // Request a redraw.
}
public void setForeground(Color c) {
super.setForeground(c); // Tell our superclass about the new color.
repaint(); // Request a redraw (size is unchanged).
}
public void setAlignment(int a) { alignment = a; repaint(); }
public void setMarginWidth(int mw) { margin_width = mw; repaint(); }
public void setMarginHeight(int mh) { margin_height = mh; repaint(); }
public String getLabel() { return label; }
public int getAlignment() { return alignment; }
public int getMarginWidth() { return margin_width; }
public int getMarginHeight() { return margin_height; }
/**
* This method is called by a layout manager when it wants to
* know how big we'd like to be. In Java 1.1, getPreferredSize() is
* the preferred version of this method. We use this deprecated version
* so that this component can interoperate with 1.0 components.
*/
public Dimension preferredSize() {
if (!measured) measure();
return new Dimension(max_width + 2*margin_width,
num_lines * line_height + 2*margin_height);
}
/**
* This method is called when the layout manager wants to know
* the bare minimum amount of space we need to get by.
* For Java 1.1, we'd use getMinimumSize().
*/
public Dimension minimumSize() { return preferredSize(); }
/**
* This method draws the label (same method that applets use).
* Note that it handles the margins and the alignment, but that
* it doesn't have to worry about the color or font--the superclass
* takes care of setting those in the Graphics object we're passed.
*/
public void paint(Graphics g) {
int x, y;
Dimension size = this.size(); // use getSize() in Java 1.1
if (!measured) measure();
y = line_ascent + (size.height - num_lines * line_height)/2;
for(int i = 0; i < num_lines; i++, y += line_height) {
switch(alignment) {
default:
case LEFT: x = margin_width; break;
case CENTER: x = (size.width - line_widths[i])/2; break;
case RIGHT: x = size.width - margin_width - line_widths[i]; break;
}
g.drawString(lines[i], x, y);
}
}
/** This internal method breaks a specified label up into an array of lines.
* It uses the StringTokenizer utility class. */
protected synchronized void newLabel() {
StringTokenizer t = new StringTokenizer(label, "\n");
num_lines = t.countTokens();
lines = new String[num_lines];
line_widths = new int[num_lines];
for(int i = 0; i < num_lines; i++) lines[i] = t.nextToken();
}
/** This internal method figures out how the font is, and how wide each
* line of the label is, and how wide the widest line is. */
protected synchronized void measure() {
FontMetrics fm = this.getToolkit().getFontMetrics(this.getFont());
line_height = fm.getHeight();
line_ascent = fm.getAscent();
max_width = 0;
for(int i = 0; i < num_lines; i++) {
line_widths[i] = fm.stringWidth(lines[i]);
if (line_widths[i] > max_width) max_width = line_widths[i];
}
measured = true;
}
}
examples/ch11/ 40775 765 765 0 6340142375 10764 5 ustar david examples/ch11/Errors.properties 100664 765 765 1533 6340131120 14437 0 ustar david #
# This is the file Errors.properties
# One property for each class of exceptions that our program might
# report. Note the use of backslashes to continue long lines onto the
# next. Also note the use of \n and \t for newlines and tabs
#
java.io.FileNotFoundException: \
Error: File "{0}" not found\n\t\
Error occurred at line {3} of file "{2}"\n\tat {4}
java.io.UnsupportedEncodingException: \
Error: Specified encoding not supported\n\t\
Error occurred at line {3} of file "{2}"\n\tat {4,time} on {4,date}
java.io.CharConversionException:\
Error: Character conversion failure. Input data is not in specified format.
# A generic resource. Display a message for any error or exception that
# is not handled by a more specific resource.
java.lang.Throwable:\
Error: {1}: {0}\n\t\
Error occurred at line {3} of file "{2}"\n\t{4,time,long} {4,date,long}
examples/ch11/LocalizedError.java 100664 765 765 7453 6340142301 14642 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.text.*;
import java.io.*;
import java.util.*;
/**
* A convenience class that can display a localized exception message
* depending on the class of the exception. It uses a MessageFormat,
* and passes five arguments that the localized message may include:
* {0}: the message included in the exception or error.
* {1}: the full class name of the exception or error.
* {2}: a guess at what file the exception was caused by.
* {3}: a line number in that file.
* {4}: the current date and time.
* Messages are looked up in a ResourceBundle with the basename
* "Errors", using a the full class name of the exception object as
* the resource name. If no resource is found for a given exception
* class, the superclasses are checked.
*/
public class LocalizedError {
public static void display(Throwable error) {
ResourceBundle bundle;
// Try to get the resource bundle.
// If none, print the error in a non-localized way.
try { bundle = ResourceBundle.getBundle("Errors"); }
catch (MissingResourceException e) {
error.printStackTrace(System.err);
return;
}
// Look up a localized message resource in that bundle, using the
// classname of the error (or its superclasses) as the resource name.
// If no resource was found, display the error without localization.
String message = null;
Class c = error.getClass();
while((message == null) && (c != Object.class)) {
try { message = bundle.getString(c.getName()); }
catch (MissingResourceException e) { c = c.getSuperclass(); }
}
if (message == null) { error.printStackTrace(System.err); return; }
// Try to figure out the filename and line number of the
// exception. Output the error's stack trace into a string, and
// use the heuristic that the first line number that appears in
// the stack trace is after the first or second colon. We assume that
// this stack frame is the first one the programmer has any control
// over, and so report it as the location of the exception.
String filename = "";
int linenum = 0;
try {
StringWriter sw = new StringWriter(); // Output stream into a string.
PrintWriter out = new PrintWriter(sw); // PrintWriter wrapper.
error.printStackTrace(out); // Print stacktrace.
String trace = sw.toString(); // Get it as a string.
int pos = trace.indexOf(':'); // Look for first colon.
if (error.getMessage() != null) // If the error has a message
pos = trace.indexOf(':', pos+1); // look for second colon.
int pos2 = trace.indexOf(')', pos); // Look for end of line number.
linenum = Integer.parseInt(trace.substring(pos+1,pos2)); // Get linenum.
pos2 = trace.lastIndexOf('(', pos); // Back to start of filename.
filename = trace.substring(pos2+1, pos); // Get filename.
}
catch (Exception e) { ; } // Ignore exceptions.
// Set up an array of arguments to use with the message
String errmsg = error.getMessage();
Object[] args = {
((errmsg!= null)?errmsg:""), error.getClass().getName(),
filename, new Integer(linenum), new Date()
};
// Finally, display the localized error message, using
// MessageFormat.format() to substitute the arguments into the message.
System.out.println(MessageFormat.format(message, args));
}
}
examples/ch11/Menus_fr.properties 100664 765 765 445 6340131121 14723 0 ustar david # This is the file Menus_fr.properties. It is the resource bundle for all
# French-speaking locales. It overrides most, but not all, of the resources
# in the default bundle.
colors.label=Couleurs
colors.red.label=Rouge
colors.green.label=Vert
colors.green.shortcut=V
colors.blue.label=Bleu
examples/ch11/Menus_en_GB.properties 100664 765 765 357 6340131121 15270 0 ustar david # This is the file Menus_en_GB.properties. It is the resource bundle for
# British English. Note that it overrides only a single resource definition
# and simply inherits the rest from the default (American) bundle.
colors.label=Colours
examples/ch11/Menus.properties 100664 765 765 441 6340131121 14230 0 ustar david # The file Menus.properties is the default "Menus" resource bundle.
# As an American programmer, I made my own locale the default.
colors.label=Colors
colors.red.label=Red
colors.red.shortcut=R
colors.green.label=Green
colors.green.shortcut=G
colors.blue.label=Blue
colors.blue.shortcut=B
examples/ch11/SimpleMenu.java 100664 765 765 6524 6340142301 13776 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.awt.*;
import java.awt.event.*;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
/** A convenience class to automatically create localized menu panes */
public class SimpleMenu {
/** The convenience method that creates menu panes */
public static Menu create(String bundlename,
String menuname, String[] itemnames,
ActionListener listener, boolean popup) {
// Get the resource bundle used for this menu.
ResourceBundle b = ResourceBundle.getBundle(bundlename);
// Get the menu title from the bundle. Use name as default label.
String menulabel;
try { menulabel = b.getString(menuname + ".label"); }
catch(MissingResourceException e) { menulabel = menuname; }
// Create the menu pane.
Menu m;
if (popup) m = new PopupMenu(menulabel);
else m = new Menu(menulabel);
// For each named item in the menu.
for(int i = 0; i < itemnames.length; i++) {
// Look up the label for the item, using name as default.
String itemlabel;
try { itemlabel=b.getString(menuname + "." + itemnames[i] + ".label"); }
catch (MissingResourceException e) { itemlabel = itemnames[i]; }
// Look up a shortcut for the item, and create the menu shortcut, if any.
String shortcut;
try{shortcut = b.getString(menuname + "." + itemnames[i]+".shortcut"); }
catch (MissingResourceException e) { shortcut = null; }
MenuShortcut ms = null;
if (shortcut != null) ms = new MenuShortcut(shortcut.charAt(0));
// Create the menu item.
MenuItem mi;
if (ms != null) mi = new MenuItem(itemlabel, ms);
else mi = new MenuItem(itemlabel);
// Register an action listener and command for the item.
if (listener != null) {
mi.addActionListener(listener);
mi.setActionCommand(itemnames[i]);
}
// Add the item to the menu.
m.add(mi);
}
// Return the automatically created localized menu.
return m;
}
/** A simple test program for the above code */
public static void main(String[] args) {
// Set the default locale based on the command-line args.
if (args.length == 2) Locale.setDefault(new Locale(args[0], args[1]));
Frame f = new Frame("SimpleMenu Test"); // Create a window.
MenuBar menubar = new MenuBar(); // Create a menubar.
f.setMenuBar(menubar); // Add menubar to window.
// Create a menu using our convenience routine (and the default locale).
Menu colors = SimpleMenu.create("Menus", "colors",
new String[] { "red", "green", "blue" },
null, false);
menubar.add(colors); // Add the menu to the menubar.
f.setSize(300, 150); // Set the window size.
f.show(); // Pop the window up.
}
}
examples/ch11/Portfolio.java 100664 765 765 4664 6340142301 13700 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.text.*;
import java.util.Date;
/**
* A partial implementation of a hypothetical stock portfolio class.
* We use it only to demonstrate number and date internationalization.
*/
public class Portfolio {
EquityPosition[] positions;
Date lastQuoteTime = new Date();
public void print() {
// Obtain NumberFormat and DateFormat objects to format our data.
NumberFormat number = NumberFormat.getInstance();
NumberFormat price = NumberFormat.getCurrencyInstance();
NumberFormat percent = NumberFormat.getPercentInstance();
DateFormat shortdate = DateFormat.getDateInstance(DateFormat.SHORT);
DateFormat fulldate = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG);
// Print some introductory data.
System.out.println("Portfolio value at " +
fulldate.format(lastQuoteTime) + ":");
System.out.println("Symbol\tShares\tBought On\tAt\t" +
"Quote\tChange");
// Then display the table using the format() methods of the Format objects.
for(int i = 0; i < positions.length; i++) {
System.out.print(positions[i].name + "\t");
System.out.print(number.format(positions[i].shares) + "\t");
System.out.print(shortdate.format(positions[i].purchased) + "\t");
System.out.print(price.format(positions[i].bought) + "\t");
System.out.print(price.format(positions[i].current) + "\t");
double change =
(positions[i].current - positions[i].bought)/positions[i].bought;
System.out.println(percent.format(change));
}
}
static class EquityPosition {
String name; // Name of the stock.
int shares; // Number of shares held.
Date purchased; // When purchased.
double bought, current; // Purchase price and current price (per share).
EquityPosition(String n, int s, Date when, double then, double now) {
name = n; shares = s; purchased = when; bought = then; current = now;
}
}
}
examples/ch11/ConvertEncoding.java 100664 765 765 5633 6340142301 15007 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.io.*;
/** A program to convert from one character encoding to another */
public class ConvertEncoding {
public static void main(String[] args) {
String from = null, to = null;
String infile = null, outfile = null;
for(int i = 0; i < args.length; i++) { // Parse command-line arguments.
if (i == args.length-1) usage(); // All legal args require another.
if (args[i].equals("-from")) from = args[++i];
else if (args[i].equals("-to")) to = args[++i];
else if (args[i].equals("-in")) infile = args[++i];
else if (args[i].equals("-out")) outfile = args[++i];
else usage();
}
try { convert(infile, outfile, from, to); } // Attempt conversion.
catch (Exception e) { // Handle possible exceptions.
LocalizedError.display(e); // Defined at the end of this chapter.
System.exit(1);
}
}
public static void usage() {
System.err.println("Usage: java ConvertEncoding \n" +
"Options:\n\t-from \n\t-to \n\t" +
"-in \n\t-out ");
System.exit(1);
}
public static void convert(String infile, String outfile,
String from, String to)
throws IOException, UnsupportedEncodingException
{
// Set up byte streams.
InputStream in;
if (infile != null) in = new FileInputStream(infile);
else in = System.in;
OutputStream out;
if (outfile != null) out = new FileOutputStream(outfile);
else out = System.out;
// Use default encoding if no encoding is specified.
if (from == null) from = System.getProperty("file.encoding");
if (to == null) to = System.getProperty("file.encoding");
// Set up character streams.
Reader r = new BufferedReader(new InputStreamReader(in, from));
Writer w = new BufferedWriter(new OutputStreamWriter(out, to));
// Copy characters from input to output. The InputStreamReader converts
// from the input encoding to Unicode, and the OutputStreamWriter converts
// from Unicode to the output encoding. Characters that cannot be
// represented in the output encoding are output as '?'
char[] buffer = new char[4096];
int len;
while((len = r.read(buffer)) != -1) // Read a block of input.
w.write(buffer, 0, len); // And write it out.
r.close(); // Close the input.
w.flush(); // Flush and close output.
w.close();
}
}
examples/ch12/ 40775 765 765 0 6340142375 10765 5 ustar david examples/ch12/UniversalActionListener.java 100664 765 765 6247 6340142301 16537 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.awt.event.*;
import java.lang.reflect.*;
import java.awt.*; // Only used for the test program below.
public class UniversalActionListener implements ActionListener {
protected Object target;
protected Object arg;
protected Method m;
public UniversalActionListener(Object target, String methodname, Object arg)
throws NoSuchMethodException, SecurityException
{
this.target = target; // Save the target object.
this.arg = arg; // And method argument.
// Now look up and save the Method to invoke on that target object
Class c, parameters[];
c = target.getClass(); // The Class object.
if (arg == null) parameters = new Class[0]; // Method parameter.
else parameters = new Class[] { arg.getClass() };
m = c.getMethod(methodname, parameters); // Find matching method.
}
public void actionPerformed(ActionEvent event) {
Object[] arguments;
if (arg == null) arguments = new Object[0]; // Set up arguments.
else arguments = new Object[] { arg };
try { m.invoke(target, arguments); } // And invoke the method.
catch (IllegalAccessException e) { // Should never happen.
System.err.println("UniversalActionListener: " + e);
} catch (InvocationTargetException e) { // Should never happen.
System.err.println("UniversalActionListener: " + e);
}
}
// A simple test program for the UniversalActionListener
public static void main(String[] args) throws NoSuchMethodException {
Frame f = new Frame("UniversalActionListener Test");// Create window.
f.setLayout(new FlowLayout()); // Set layout manager.
Button b1 = new Button("tick"); // Create buttons.
Button b2 = new Button("tock");
Button b3 = new Button("Close Window");
f.add(b1); f.add(b2); f.add(b3); // Add them to window.
// Specify what the buttons do. Invoke a named method with
// the UniversalActionListener object.
b1.addActionListener(new UniversalActionListener(b1, "setLabel", "tock"));
b1.addActionListener(new UniversalActionListener(b2, "setLabel", "tick"));
b1.addActionListener(new UniversalActionListener(b3, "hide", null));
b2.addActionListener(new UniversalActionListener(b1, "setLabel", "tick"));
b2.addActionListener(new UniversalActionListener(b2, "setLabel", "tock"));
b2.addActionListener(new UniversalActionListener(b3, "show", null));
b3.addActionListener(new UniversalActionListener(f, "dispose", null));
f.pack(); // Set window size.
f.show(); // And pop it up.
}
}
examples/ch12/ShowClass.java 100664 765 765 11156 6340142301 13644 0 ustar david // This example is from the book "Java in a Nutshell, Second Edition".
// Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates.
// You may distribute this source code for non-commercial purposes only.
// You may study, modify, and use this example for any purpose, as long as
// this notice is retained. Note that this example is provided "as is",
// WITHOUT WARRANTY of any kind either expressed or implied.
import java.lang.reflect.*;
/** A program that displays a class synopsis for the named class */
public class ShowClass {
/** The main method. Print info about the named class */
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName(args[0]);
print_class(c);
}
/** Display the modifiers, name, superclass and interfaces of a class
* or interface. Then go and list all constructors, fields, and methods. */
public static void print_class(Class c)
{
// Print modifiers, type (class or interface), name and superclass.
if (c.isInterface()) {
// The modifiers will include the "interface" keyword here...
System.out.print(Modifier.toString(c.getModifiers()) + c.getName());
}
else
System.out.print(Modifier.toString(c.getModifiers()) + " class " +
c.getName() +
" extends " + c.getSuperclass().getName());
// Print interfaces or super-interfaces of the class or interface.
Class[] interfaces = c.getInterfaces();
if ((interfaces != null) && (interfaces.length > 0)) {
if (c.isInterface()) System.out.println(" extends ");
else System.out.print(" implements ");
for(int i = 0; i < interfaces.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(interfaces[i].getName());
}
}
System.out.println(" {"); // Begin class member listing.
// Now look up and display the members of the class.
System.out.println(" // Constructors");
Constructor[] constructors = c.getDeclaredConstructors();
for(int i = 0; i < constructors.length; i++) // Display constructors.
print_method_or_constructor(constructors[i]);
System.out.println(" // Fields");
Field[] fields = c.getDeclaredFields(); // Look up fields.
for(int i = 0; i < fields.length; i++) // Display them.
print_field(fields[i]);
System.out.println(" // Methods");
Method[] methods = c.getDeclaredMethods(); // Look up methods.
for(int i = 0; i < methods.length; i++) // Display them.
print_method_or_constructor(methods[i]);
System.out.println("}"); // End class member listing.
}
/** Return the name of an interface or primitive type, handling arrays. */
public static String typename(Class t) {
String brackets = "";
while(t.isArray()) {
brackets += "[]";
t = t.getComponentType();
}
return t.getName() + brackets;
}
/** Return a string version of modifiers, handling spaces nicely. */
public static String modifiers(int m) {
if (m == 0) return "";
else return Modifier.toString(m) + " ";
}
/** Print the modifiers, type, and name of a field */
public static void print_field(Field f) {
System.out.println(" " +
modifiers(f.getModifiers()) +
typename(f.getType()) + " " + f.getName() + ";");
}
/** Print the modifiers, return type, name, parameter types and exception
* type of a method or constructor. Note the use of the Member interface
* to allow this method to work with both Method and Constructor objects */
public static void print_method_or_constructor(Member member) {
Class returntype=null, parameters[], exceptions[];
if (member instanceof Method) {
Method m = (Method) member;
returntype = m.getReturnType();
parameters = m.getParameterTypes();
exceptions = m.getExceptionTypes();
} else {
Constructor c = (Constructor) member;
parameters = c.getParameterTypes();
exceptions = c.getExceptionTypes();
}
System.out.print(" " + modifiers(member.getModifiers()) +
((returntype!=null)? typename(returntype)+" " : "") +
member.getName() + "(");
for(int i = 0; i < parameters.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(typename(parameters[i]));
}
System.out.print(")");
if (exceptions.length > 0) System.out.print(" throws ");
for(int i = 0; i < exceptions.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(typename(exceptions[i]));
}
System.out.println(";");
}
}
examples/index.html 100664 765 765 14737 6340336653 12362 0 ustar david
Examples From Java in a Nutshell, Second Edition
Examples From Java in a Nutshell, Second Edition
The Java programming examples linked below are from the book
Java in a Nutshell, Second Edition, by David Flanagan,
published by O'Reilly & Associates.
Although you can view the example source code online, by following the
links below, I recommend that you download the complete set of examples
so that you can work with them on your computer locally. They are
available as a
zip file
or as a
gzipped tar file.
Reporting Bugs
If you find any bugs in these examples, please send e-mail describing
the bug to bookquestions@ora.com.
If you have found a workaround to the problem, please include it.
Copyright
The examples were written by David Flanagan, and are Copyright (c) 1997
by O'Reilly and Associates.
You may study, use, and modify these examples for any purpose. This
means that you can use the examples, or modified versions of the
examples in your programs, and you can even sell those programs. You
can distribute the source code to these examples, but only for
non-commercial purposes, and only as long as the copyright notice is
retained. This means that you can make them available on a public Web
site, for example, but that you cannot include them on a commercial
CD-ROM without the prior permission of O'Reilly and Associates.
Note that these examples are provided AS-IS, with absolutely NO WARRANTY
of any kind, either expressed or implied.
Example 1-2
Scribble.java:
an applet of intermediate complexity, used as an example in the
introductory chapter.
Example 2-3
throwtest.java:
an application that demonstrates how to define, throw, and handle
exceptions. This application doesn't do anything other than print out
some text, but you might want to study it and play around with it to
learn more about how exceptions work in Java. See the usage instructions
in the source code.
Example 6-1
FirstApplet.java:
the simplest possible applet. Displays "Hello World"
Example 6-2
SecondApplet.java:
a fancier version of "Hello World"
Example 6-3
Scribble.java:
a simple applet with user interaction. It allows the user to click and
scribble in the window.
Example 6-4
ColorScribble.java:
the scribble applet, with colors specified through applet parameters in
an HTML file.
Example 6-5
Soundmap.java:
An applet that displays an image, plays a sound, and demonstrates
several other applet capabilities.
Example 7-1
Scribble1.java:
a simple applet, using the Java 1.0 event model.
Example 7-2
Scribble2.java:
the same applet, using the Java 1.1 event model.
Example 7-3
Scribble3.java:
the applet using the Java 1.1 event model and inner classes.
Example 7-4
Scribble4.java:
the applet using a low-level interface to the Java 1.1 event model.
Example 8-1
ScribbleFrame.java:
a relatively long application that demonstrates many of the new AWT
features of Java 1.1, and also demonstrates object serialization and
data compression.
Example 9-2
IntList.java:
a simple datatype that defines custom serialziation and de-serialization
behavior for itself.
Example 10-1
MultiLineLabel.java:
a custom AWT component and Java Bean that displays a specified string of
text, using multiple lines, if the string contains newline characters.
Example 10-2
YesNoDialog.java:
a bean that displays a dialog box.
Example 10-3
AnswerEvent.java:
an event type used by the bean.
Example 10-4
AnswerListener.java:
the event listener interface used by the bean
Example 10-5
YesNoDialogBeanInfo.java:
a BeanInfo class for the bean.
Example 10-6
YesNoDialogAlignmentEditor.java:
a property editor class for one of the bean's properties.
Example 10-7
YesNoDialogMessageEditor.java:
a property editor class for another of the bean's properties.
Example 10-8
YesNoDialogCustomizer.java:
a customizer class for the bean.
Example 11-1
ConvertEncoding.java:
an application that converts a file from one character encoding to another.
Example 11-3
Portfolio.java:
a dummy stock portfolio program that demonstrates internationalization
of dates, times and numbers.
Example 11-4
SimpleMenu.java:
a convenience class for simple creation of localized menus using
ResourceBundles.
Example 11-5
Menus.properties
Menus_en_GB.properties
Menus_fr.properties:
property files that specify default, British, and French resource
bundles for simple menu creation.
Example 11-6
LocalizedError.java:
a class that displays a localized error message fora given exception
object, using the MessageFormat class.
Example 11-7
Errors.properties:
a sample property file used by the previous example
Example 12-1
ShowClass.java:
a program that uses the Reflection API to show the fields and methods of
a class.
Example 12-2
UniversalActionListener.java:
an ActionListener implementation that uses reflection to invoke a named
method of an object.