By Patrick Niemeyer, Jonathan Knudsen
Price: $44.95 USD
£31.95 GBP
Cover | Table of Contents
#define statements, or conditional source compilation. These constructs exist in other languages primarily to support platform dependencies, so in that sense, they should not be needed in Java. Conditional compilation is also commonly used for debugging, but Java's sophisticated runtime optimizations and features such as private
to designate hidden members of classes in C++, he was probably thinking about shielding you from the messy details of a class developer's code, not the issues of shielding that developer's classes and objects from attack by someone else's viruses and Trojan horses. Arbitrary casting and pointer arithmetic in C or C++ make it trivial to violate access permissions on classes without breaking the rules of the language. Consider the following code:
// C++ code
class Finances {
private:
char creditCardNumber[16];
...
};
main() {
Finances finances;
// Forge a pointer to peek inside the class
char *cardno = (char *)&finances;
printf("Card Number = %s\n", cardno);
}Finances class and pulls out some secret information. This sort of shenanigan—abusing an untyped pointer—is not possible in Java. If this example seems unrealistic, consider how important it is to protect the foundation (system) classes of the runtime environment from similar kinds of attacks. If untrusted code can corrupt the components that provide access to real resources, such as the filesystem, the network, or the windowing system, it certainly has a chance at stealing your credit card numbers.http://www.oreilly.com/catalog/learnjava3. Compile the programs and try them. Then, turn our examples into your examples: play with them, change their behavior, break them, fix them, and hopefully have some fun along the way.java runtime and the javac compiler for Java 5.0. But we have also packaged all of the example code in this book to be run with the open-source Eclipse integrated development environment (IDE). If you would like to follow along with the examples using Eclipse, see Appendix A for an introduction to Eclipse and full instructions on loading the example project. You can then return here to follow along as we build the examples.java runtime and the javac compiler for Java 5.0. But we have also packaged all of the example code in this book to be run with the open-source Eclipse integrated development environment (IDE). If you would like to follow along with the examples using Eclipse, see Appendix A for an introduction to Eclipse and full instructions on loading the example project. You can then return here to follow along as we build the examples.
C:\> javac HelloJava
.java
% javac HelloJava.java
HelloJava.HelloJava, HelloJava2, etc.), adding features, and introducing new concepts along the way. But let's start with the minimalist version:
public class HelloJava {
public static void main( String[] args ) {
System.out.println("Hello, Java!");
}
}HelloJava and a method called main()
. It uses a predefined method called println() to write some text as output. This is a command-line program, which means that it runs in a shell or DOS window and prints its output there. That's a bit old school for our taste, so before we go any further, we're going to give HelloJava a graphical user interface (GUI). Don't worry about the code yet; just follow along with the progression here, and we'll come back for explanations in a moment.println() method, we're going to use something called a JFrame
object to put a window on the screen. We can start by replacing the println line with the following three lines:
JFrame frame = new JFrame( "Hello, Java!" );
frame.setSize( 300, 300 );
frame.setVisible( true );JFrame object with the title "Hello, Java!" The JFrame is a graphical window. To display it, we simply configure its size on the screen using the setSize() method and make it visible by calling the setVisible() method.JLabel
object to display the text centered in our window. The additional HelloJava2
, allows us to drag the message text around with the mouse.HelloJava2 rather than cause confusion by continuing to expand the old one, but the primary changes here and further on lie in adding capabilities to the HelloComponent class and simply making the corresponding changes to the names to keep them straight, e.g., HelloComponent2, HelloComponent3, etc. Having just seen inheritance at work, you might wonder why we aren't creating a subclass of HelloComponent and exploiting inheritance to build upon our previous example and extend its functionality. Well, in this case, that would not provide much advantage, and for clarity we simply start over.HelloJava2:
//file: HelloJava2.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloJava2
{
public static void main( String[] args ) {
JFrame frame = new JFrame( "HelloJava2" );
frame.getContentPane().add( new HelloComponent2("Hello, Java!") );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 300, 300 );
frame.setVisible( true );
}
}
class HelloComponent2 extends JComponent
implements MouseMotionListener
{
String theMessage;
int messageX = 125, messageY = 95; // Coordinates of the message
public HelloComponent2( String message ) {
theMessage = message;
addMouseMotionListener(this);
}
public void paintComponent( Graphics g ) {
g.drawString( theMessage, messageX, messageY );
}
public void mouseDragged(MouseEvent e) {
// Save the mouse coordinates and paint the message.
messageX = e.getX();
messageY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e) { }
}HelloJava2HelloJava3 brings us a new graphical interface component: JButton
. In this example, we add a JButton component to our application that changes the color of our text each time the button is pressed. The draggable-message capability is still there, too. Our new code looks like this:
//file: HelloJava3.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloJava3
{
public static void main( String[] args ) {
JFrame frame = new JFrame( "HelloJava3" );
frame.add( new HelloComponent3("Hello, Java!") );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 300, 300 );
frame.setVisible( true );
}
}
class HelloComponent3 extends JComponent
implements MouseMotionListener, ActionListener
{
String theMessage;
int messageX = 125, messageY = 95; // Coordinates of the message
JButton theButton;
int colorIndex; // Current index into someColors
static Color[] someColors = {
Color.black, Color.red, Color.green, Color.blue, Color.magenta };
public HelloComponent3( String message ) {
theMessage = message;
theButton = new JButton("Change Color");
setLayout( new FlowLayout() );
add( theButton );
theButton.addActionListener( this );
addMouseMotionListener( this );
}
public void paintComponent( Graphics g ) {
g.drawString( theMessage, messageX, messageY );
}
public void mouseDragged( MouseEvent e ) {
messageX = e.getX();
messageY = e.getY();
repaint();
}
public void mouseMoved( MouseEvent e ) {}
public void actionPerformed( ActionEvent e ) {
// Did somebody push our button?
if (e.getSource() == theButton)
changeColor();
}
synchronized private void changeColor() {
// Change the index to the next color, awkwardly.
if (++colorIndex == someColors.length)
colorIndex = 0;
setForeground( currentColor() ); // Use the new color.
repaint();
}
synchronized private Color currentColor() {
return someColors[colorIndex];
}
}HelloJava application. But until now, our application has been rather passive; it has been completely event-driven, waiting patiently for events to come its way and responding to the whims of the user. Now our application is going to take some initiative—HelloJava4 will blink! Here is the code for our latest version:
//file: HelloJava4.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloJava4
{
public static void main( String[] args ) {
JFrame frame = new JFrame( "HelloJava4" );
frame.add( new HelloComponent4("Hello, Java!") );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 300, 300 );
frame.setVisible( true );
}
}
class HelloComponent4 extends JComponent
implements MouseMotionListener, ActionListener, Runnable
{
String theMessage;
int messageX = 125, messageY = 95; // Coordinates of the message
JButton theButton;
int colorIndex; // Current index into someColors.
static Color[] someColors = {
Color.black, Color.red, Color.green, Color.blue, Color.magenta };
boolean blinkState;
public HelloComponent4( String message ) {
theMessage = message;
theButton = new JButton("Change Color");
setLayout( new FlowLayout() );
add( theButton );
theButton.addActionListener( this );
addMouseMotionListener( this );
Thread t = new Thread( this );
t.start();
}
public void paintComponent( Graphics g ) {
g.setColor(blinkState ? getBackground() : currentColor());
g.drawString(theMessage, messageX, messageY);
}
public void mouseDragged(MouseEvent e) {
messageX = e.getX();
messageY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e) { }
public void actionPerformed( ActionEvent e ) {
if ( e.getSource() == theButton )
changeColor();
}
synchronized private void changeColor() {
if (++colorIndex == someColors.length)
colorIndex = 0;
setForeground( currentColor() );
repaint();
}
synchronized private Color currentColor() {
return someColors[colorIndex];
}
public void run() {
try {
while(true) {
blinkState = !blinkState; // Toggle blinkState.
repaint(); // Show the change.
Thread.sleep(300);
}
} catch (InterruptedException ie) { }
}
}HelloJava examples, it is likely that your source code has a mistake or that the source file has become corrupted. The best way to eliminate this possibility is to copy the source directly from the ZIP file on the CD or download them from the examples link at the web site for this book, http://www.oreilly.com/catalog/learnjava3/.NoClassDefFound or ClassNotFound errors when attempting to run the examples using the java command, you may have a classpath issue. By default there should be no value set in the environment variable CLASSPATH, but some untidy applications may set this value for you when you install them.
C:\> set classpath
% echo $CLASSPATH
C:\> set classpath=
% unset CLASSPATH; export CLASSPATH
C:\> java -version
main(), which contains the first code to be executed upon start up. To run the application, start the VM, specifying that class as an argument. You can also specify options to the interpreter as well as arguments to be passed to the application. Sun's Java VM is called java:
% java [interpreter options] class_name [program arguments]
% java animals.birds.BigBird
% java MyTest
% java -jar spaceblaster.jar
main() method and the classpath becomes the JAR file itself.main() method. From there, the application can reference other classes, start additional threads, and create its user interface or other structures, as shown in Figure 3-1.
main() method must have the right method signature
. A method signature is the set of information that defines the method. It includes the method's name, arguments, and return type, as well as type and visibility modifiers. The main() method must be a public, static method that takes an array of String objects as its argument and does not return any value (PATH environment variable is a colon-separated list of directories that are searched, in order, when the user types the name of a command. The Java CLASSPATH environment variable, similarly, is a list of locations that are searched for Java class files. Both the Java interpreter and the Java compiler use the CLASSPATH when searching for packages and Java classes.CLASSPATH environment variable with a colon-separated list of directories and class archive files:
% CLASSPATH=/home/vicky/Java/classes:/home/josh/lib/foo.jar:.
% export CLASSPATH
.). The last component of the classpath, the current directory, is useful when tinkering with classes.CLASSPATH environment variable is set with a semicolon-separated list of directories and class archive files:package and import statements.
package animals.birds;
public class BigBird extends Bird {
}
% javac BigBird.java
CLASSPATH, as described earlier. You can do the equivalent for applets by listing the JAR file in the ARCHIVE
attribute of the HTML
<applet> tag. Nonclass files (data, images, etc.) contained in your JAR file can also be retrieved from the classpath using the getResource()
method (described in Chapter 12). Using this facility, your code doesn't have to know whether any resource is in a plain file or a member of a JAR archive. Whether a given class or datafile is an item in a JAR file, an individual file on the classpath, or an applet on a remote server, you can always refer to it in a standard way and let Java's class loader resolve the location.