Full Code of l0y/learnjava5e for AI

master 8dd1bb833643 cached
92 files
231.9 KB
55.5k tokens
587 symbols
1 requests
Download .txt
Showing preview only (253K chars total). Download the full file or copy to clipboard to get everything.
Repository: l0y/learnjava5e
Branch: master
Commit: 8dd1bb833643
Files: 92
Total size: 231.9 KB

Directory structure:
gitextract_wyoxb4rf/

├── .gitignore
├── LICENSE
├── README.md
├── ch02/
│   ├── HelloJava.java
│   └── HelloJava2.java
├── ch04/
│   └── EuclidGCD.java
├── ch05/
│   ├── Apple.java
│   ├── AppleToss.java
│   ├── Field.java
│   ├── GamePiece.java
│   ├── HelloJava3.java
│   ├── Physicist.java
│   ├── PrintAppleDetails.java
│   ├── PrintAppleDetails2.java
│   ├── PrintAppleDetails3.java
│   ├── PrintAppleDetails4.java
│   └── Tree.java
├── ch06/
│   ├── Euclid2.java
│   └── LogTest.java
├── ch07/
│   ├── Apple.java
│   ├── AppleToss.java
│   ├── Field.java
│   ├── GamePiece.java
│   ├── GameUtilities.java
│   ├── Physicist.java
│   └── Tree.java
├── ch08/
│   ├── Apple.java
│   ├── AppleToss.java
│   ├── Field.java
│   ├── GamePiece.java
│   ├── GameUtilities.java
│   ├── Physicist.java
│   └── Tree.java
├── ch09/
│   ├── URLConsumer.java
│   ├── URLDemo.java
│   ├── URLProducer.java
│   ├── URLQueue.java
│   └── game/
│       ├── Apple.java
│       ├── AppleToss.java
│       ├── Field.java
│       ├── GamePiece.java
│       ├── GameUtilities.java
│       ├── Physicist.java
│       └── Tree.java
├── ch10/
│   ├── ActionDemo1.java
│   ├── ActionDemo2.java
│   ├── BorderLayoutDemo.java
│   ├── Buttons.java
│   ├── HelloJavaAgain.java
│   ├── HelloMouse.java
│   ├── HelloMouseHelper.java
│   ├── Labels.java
│   ├── MenuDemo.java
│   ├── ModalDemo.java
│   ├── NestedPanelDemo.java
│   ├── PhoneGridDemo.java
│   ├── ProgressDemo.java
│   ├── TextInputs.java
│   ├── Widget.java
│   └── game/
│       ├── Apple.java
│       ├── AppleToss.java
│       ├── Field.java
│       ├── GamePiece.java
│       ├── GameUtilities.java
│       ├── Physicist.java
│       └── Tree.java
├── ch11/
│   ├── CopyChannels.java
│   ├── CopyChannels2.java
│   ├── CopyChannels3.java
│   ├── CopyFile.java
│   ├── CopyStreams.java
│   ├── DateAtHost.java
│   ├── ListIt.java
│   └── game/
│       ├── Apple.java
│       ├── AppleToss.java
│       ├── Field.java
│       ├── GamePiece.java
│       ├── GameUtilities.java
│       ├── Physicist.java
│       └── Tree.java
├── ch12/
│   ├── Post.java
│   └── Read.java
├── ch13/
│   ├── ActionDemoLambda.java
│   └── ListItLambda.java
└── game/
    ├── Apple.java
    ├── AppleToss.java
    ├── Field.java
    ├── GamePiece.java
    ├── GameUtilities.java
    ├── Multiplayer.java
    ├── Physicist.java
    └── Tree.java

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 l0y

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# learnjava5e
Code examples for Learning Java, 5e by Marc Loy, Patrick Niemeyer, and Daniel Leuck


================================================
FILE: ch02/HelloJava.java
================================================
package ch02;

import javax.swing.*;

/**
 * A bare bones graphical version of Hello World.
 */
public class HelloJava {
    public static void main( String[] args ) {
        JFrame frame = new JFrame( "Hello, Java!" );
        JLabel label = new JLabel("Hello, Java!", JLabel.CENTER );
        frame.add(label);
        frame.setSize( 300, 300 );
        frame.setVisible( true );
    }
}


================================================
FILE: ch02/HelloJava2.java
================================================
package ch02;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * An upgraded graphical application with interactivity!
 */
public class HelloJava2 {
	public static void main( String[] args ) {
    	JFrame frame = new JFrame( "HelloJava2" );
		frame.add( new HelloComponent2("Hello, Java!") );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setSize( 300, 300 );
		frame.setVisible( true );
	}
}

/*
 * Inheritence (the "extends" keyword below) and interfaces
 * (the "implements MouseMotionListener" portion) are covered in
 * Chapter 5.
 */
class HelloComponent2 extends JComponent implements MouseMotionListener {
	String theMessage;
	int messageX = 125, messageY = 95; // Coordinates of the message

	/**
	 * Create a new component that can draw its message at an arbitrary position.
	 * That position can be changed by dragging the mouse; we attach a listener
	 * to pick up those drag events.
	 */
	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) { 
		// Ignore simple movements
	}
}


================================================
FILE: ch04/EuclidGCD.java
================================================
package ch04;

/**
 * A basic implementation of Euclid's greatest common denominator
 * algorithm.
 *
 * https://en.wikipedia.org/wiki/Algorithm
 */
public class EuclidGCD {
    public static void main(String args[]) {
		// For now, just "hard code" the two numbers to compare
        int a = 2701;
        int b = 222;
        while (b != 0) {
            if (a > b) {
                a = a - b;
            } else {
                b = b - a;
            }
        }
        System.out.println("GCD is " + a);
    }
}


================================================
FILE: ch05/Apple.java
================================================
package ch05;

import java.awt.*;

/**
 * Apple
 *
 * This class sums up everything we know about the apples our physicists will be lobbing.
 * We keep the size and weight details. We'll expand this class as we cover more topics.
 */
public class Apple implements GamePiece {
    float mass;
    float diameter = 1.0f;
    int x, y;
    int size;

    // Setup some size constants
    public static final int SMALL = 0;
    public static final int MEDIUM = 1;
    public static final int LARGE = 2;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int centerX, centerY;
    int scaledLength;

    // Boundary helper for optimizing collision detection with physicists and trees
    Rectangle boundingBox;

    // If we bumped into something, keep a reference to that thing around for cleanup and removal
    GamePiece collided;

    /**
     * Create a default, Medium apple
     */
    public Apple() {
        this(MEDIUM);
    }

    /**
     * Create an Apple of the given size
     */
    public Apple(int size) {
        setSize(size);
    }

    /**
     * Sets the size (and dependent properties) of the apple based on the
     * supplied value which must be one of the size constants.
     *
     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE
     */
    public void setSize(int size) {
        if (size < SMALL) {
            size = SMALL;
        }
        if (size > LARGE) {
            size = LARGE;
        }
        this.size = size;
        switch (size) {
            case SMALL:
                diameter = 0.9f;
                mass = 0.5f;
                break;
            case MEDIUM:
                diameter = 1.0f;
                mass = 1.0f;
                break;
            case LARGE:
                diameter = 1.1f;
                mass = 1.8f;
                break;
        }
        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.
        // Since we want a circle, we simply make our box a square so we only need one length.
        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    public double getDiameter() {
        return diameter;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of the apple, but it will be drawn from the
        // upper left corner, so figure out the distance of that gap
        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our apple will be red, then paint it!
        g.setColor(Color.RED);
        g.fillOval(x, y, scaledLength, scaledLength);
    }

    /**
     * Determine whether or not this apple is touching another piece.
     */
    public boolean isTouching(GamePiece other) {
        double xdiff = x - other.getPositionX();
        double ydiff = y - other.getPositionY();
        double distance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
        // For now, we can only really collide with other apples.
        // Just cheat a little and assume the other piece is in fact
        // an apple, and an apple with the same diameter. We'll fix
        // this as we fill out the other game pieces in later chapters.
        if (distance < diameter) {
            return true;
        } else {
            return false;
        }
    }

    public void printDetails() {
        System.out.println("  mass: " + mass);
        // Print the exact diameter:
        //System.out.println("  diameter: " + diameter);
        // Or a nice, human-friendly approximate:
        String niceNames[] = getAppleSizes();
        if (diameter < 5.0f) {
            System.out.println(niceNames[SMALL]);
        } else if (diameter < 10.0f) {
            System.out.println(niceNames[MEDIUM]);
        } else {
            System.out.println(niceNames[LARGE]);
        }
        System.out.println("  position: (" + x + ", " + y +")");
    }

    public static String[] getAppleSizes() {
        // Return names for our constants
        // The index of the name should match the value of the constant
        return new String[] { "SMALL", "MEDIUM", "LARGE" };
    }
}


================================================
FILE: ch05/AppleToss.java
================================================
package ch05;

import javax.swing.*;

/**
 * Our apple tossing game. This class extends JFrame to create our
 * main application window. We'll be filling this out along the way, 
 * but for now we can setup a field with some trees and our player.
 */
public class AppleToss extends JFrame {

    Field field = new Field();
    Physicist player1 = new Physicist();

    public AppleToss() {
        // Create our frame
        super("Apple Toss Game");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(800,600);
        setResizable(false);

        // Build the field with our player and some trees
        setupFieldForOnePlayer();
    }

    /**
     * A helper method to populate a one player field with target trees.
     */
    private void setupFieldForOnePlayer() {
        // Place our (new) physicist in the lower left corner and connect them to the field
        player1.setPosition(100,500);
        field.setPlayer(player1);
        player1.setField(field);
		field.setupApples();
		field.setupTree();
		add(field);
    }

    public static void main(String args[]) {
        AppleToss game = new AppleToss();
        game.setVisible(true);
    }
}


================================================
FILE: ch05/Field.java
================================================
package ch05;

import javax.swing.*;
import java.awt.*;

/**
 * The playing field for our game. This class will be undergoing quite a few
 * changes as we learn about more of Java's features in coming chapters.
 * For now, we can demonstrate how to work with member variables like a1 and a2
 * as well as how to create new methods like setupApples() and detectCollisions().
 */
public class Field extends JComponent {
    public static final float GRAVITY = 9.8f;  // feet per second per second
    public static final int STEP = 40;   // duration of an animation frame in milliseconds
    public static final int APPLE_SIZE_IN_PIXELS = 30;
    public static final int TREE_WIDTH_IN_PIXELS = 60;
    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;
    public static final int MAX_TREES = 12;

    Color fieldColor = Color.GRAY;

    Apple a1 = new Apple();
    Apple a2 = new Apple();
	Tree tree = new Tree();
	Physicist physicist;

    public void setupApples() {
		// For now, just play with our apple attributes directly
        a1.diameter = 3.0f;
        a1.mass = 5.0f;
        a1.x = 20;
        a1.y = 40;
        a2.diameter = 8.0f;
        a2.mass = 10.0f;
        a2.x = 70;
        a2.y = 200;
    }
	
	public void setupTree() {
		// Unlike apples, we'll use the setPosition() method from our
		// GamePiece interface to setup our lonely tree
		tree.setPosition(500,200);
	}

    public void setPlayer(Physicist p) {
        physicist = p;
    }
	
    protected void paintComponent(Graphics g) {
        g.setColor(fieldColor);
        g.fillRect(0,0, getWidth(), getHeight());
        tree.draw(g);
        physicist.draw(g);
		a1.draw(g);
		a2.draw(g);
    }

    public void detectCollisions() {
        if (a1.isTouching(a2)) {
            System.out.println("Collision detected!");
        } else {
            System.out.println("Apples are not touching.");
        }
    }
}


================================================
FILE: ch05/GamePiece.java
================================================
package ch05;

import java.awt.*;

/**
 * Interface to hold common elements for our apples, trees, and physicists
 *   - methods for positioning on a Field
 *   - methods for Drawing
 *   - methods for detecting a collision with other GamePieces
 */

public interface GamePiece {
    /**
     * Sets the position of the piece on the playing field.
     * (0,0) is the upper left per standard Java drawing methods.
     *
     * @param x
     * @param y
     */
    void setPosition(int x, int y);

    /**
     * Gets the current horizontal position of the piece on the field.
     *
     * @return current X position of the piece
     */
    int getPositionX();

    /**
     * Gets the current vertical position of the piece on the field.
     *
     * @return current Y position of the piece
     */
    int getPositionY();

    /**
     * Gets the bounding box of this piece.
     *
     * @return a Rectangle encompassing the visual elements of the piece
     */
    Rectangle getBoundingBox();

    /**
     * Draws the piece inside the given graphics context.
     * Do not assume anything about the state of the context.
     *
     * @param g
     */
    void draw(Graphics g);

    /**
     * Detect a collision with another piece on the field.
     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
     *
     * @param otherPiece
     * @return
     */
    boolean isTouching(GamePiece otherPiece);
}


================================================
FILE: ch05/HelloJava3.java
================================================
package ch05;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Another (minor) upgrade to our graphical Hello, World example.
 * This variation introduces an inner class for the message component
 * and an anonymous inner class for the listener handling the mouse
 * drag events. (More on events and listeners in Chapter 10.)
 */
public class HelloJava3 extends JFrame {
    public static void main( String[] args ) {
        HelloJava3 demo = new HelloJava3();
        demo.setVisible( true );
    }

    public HelloJava3() {
        super( "HelloJava3" );
        add( new HelloComponent3("Hello, Inner Java!") );
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        setSize( 300, 300 );
    }

    class HelloComponent3 extends JComponent {
        String theMessage;
        int messageX = 125, messageY = 95; // Coordinates of the message

        public HelloComponent3( String message ) {
            theMessage = message;
            addMouseMotionListener(new MouseMotionListener() {
                public void mouseDragged(MouseEvent e) {
                    messageX = e.getX();
                    messageY = e.getY();
                    repaint();
                }

                public void mouseMoved(MouseEvent e) { }
            });
        }

        public void paintComponent( Graphics g ) {
            g.drawString( theMessage, messageX, messageY );
        }
    }
}


================================================
FILE: ch05/Physicist.java
================================================
package ch05;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static java.awt.Color.*;

/**
 * Our player class. A physicist can aim where to toss an apple in addition
 * to implementing the basic methods for GamePiece. We can also set a custom
 * color in case you build on the game and allow multiple physicists to be
 * on the screen at the same time.
 */
public class Physicist implements GamePiece {
    Color color;
    int centerX, centerY;
    float aimingAngle;
    float aimingForce;
    Field field;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;

    // Boundary helpers
    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);
    private Rectangle boundingBox;


    /**
     * Create a default, blue physicist
     */
    public Physicist() {
        this(BLUE);
    }

    /**
     * Create a Physicist of the given color
     */
    public Physicist(Color color) {
        setColor(color);
        aimingAngle = 90.0f;
        aimingForce = 50.0f;
    }

    public void setAimingAngle(Float angle) {
        aimingAngle = angle;
    }

    public void setAimingForce(Float force) {
        if (force < 0) {
            force = 0.0f;
        }
        aimingForce = force;
    }

    /**
     * Sets the color for the physicist.
     *
     * @param color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of our dome,
        // but it will be drawn from the upper left corner.
        // Figure out the distance of that gap
        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    /**
     * Sets the active field once our physicist is being displayed.
     *
     * @param field Active game field
     */
    public void setField(Field field) {
        this.field = field;
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our physicist is the right color, then draw the semi-circle and box
        g.setColor(color);
        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);
        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
		// We don't really have any collisions to detect yet, so just return "no".
		// As we fill out all of the game pieces, we'll come back to this method
		// and provide a more useful response.
		return false;
    }
}


================================================
FILE: ch05/PrintAppleDetails.java
================================================
package ch05;

/**
 * A simple demonstration of accessing the contents of an object. We create
 * a new apple and print out some of its details.
 */
public class PrintAppleDetails {
    public static void main(String args[]) {
        String niceNames[] = Apple.getAppleSizes();
        Apple a1 = new Apple();
        System.out.println("Apple a1:");
        System.out.println("  mass: " + a1.mass);
        System.out.println("  diameter: " + a1.diameter);
        System.out.println("  position: (" + a1.x + ", " + a1.y +")");
        if (a1.diameter < 5.0f) {
            System.out.println("This is a " + niceNames[Apple.SMALL] + " apple.");
        } else if (a1.diameter < 10.0f) {
            System.out.println("This is a " + niceNames[Apple.MEDIUM] + " apple.");
        } else {
            System.out.println("This is a " + niceNames[Apple.LARGE] + " apple.");
        }
    }
}


================================================
FILE: ch05/PrintAppleDetails2.java
================================================
package ch05;

/**
 * Another quick example of working with an object. This time we print
 * the initial details of an apple, change some of those details, and
 * then do the same printing to provide a comparison of the results.
 */
public class PrintAppleDetails2 {
    public static void main(String args[]) {
        Apple a1 = new Apple();
        System.out.println("Apple a1:");
        System.out.println("  mass: " + a1.mass);
        System.out.println("  diameter: " + a1.diameter);
        System.out.println("  position: (" + a1.x + ", " + a1.y +")");
        // fill in some information on a1
        a1.mass = 10.0f;
        a1.x = 20;
        a1.y = 42;
        System.out.println("Updated a1:");
        System.out.println("  mass: " + a1.mass);
        System.out.println("  diameter: " + a1.diameter);
        System.out.println("  position: (" + a1.x + ", " + a1.y +")");
    }
}


================================================
FILE: ch05/PrintAppleDetails3.java
================================================
package ch05;

/**
 * A variation on PrintAppleDetails2 where we have moved the printing code
 * to the Apple class. Notice that this file is smaller than PrintAppleDetails2
 * meaning fewer lines to make mistakes!
 */
public class PrintAppleDetails3 {
    public static void main(String args[]) {
        Apple a1 = new Apple();
        System.out.println("Apple a1:");
        a1.printDetails();
        // fill in some information on a1
        a1.mass = 10.0f;
        a1.x = 20;
        a1.y = 42;
        System.out.println("Updated a1:");
        a1.printDetails();
    }
}


================================================
FILE: ch05/PrintAppleDetails4.java
================================================
package ch05;

/**
 * One final iteration of manipulating and printing apple details.
 * Now the Field class understands apples so we access those apples
 * through the field object. Notice the double dot-notation.
 */
public class PrintAppleDetails4 {
    public static void main(String args[]) {
        Field f = new Field();
        f.setupApples();
        System.out.println("Apple a1:");
        f.a1.printDetails();
        System.out.println("Apple a2:");
        f.a2.printDetails();
        f.detectCollisions();
    }
}


================================================
FILE: ch05/Tree.java
================================================
package ch05;

import java.awt.*;

/**
 * An obstacle for our game. Trees includ a simple circle and rectangle shape.
 * They are built using sizes determined by the constants in the Field class.
 */
public class Tree implements GamePiece {
    int x, y;

    // Drawing helpers
    private Color leafColor = Color.GREEN.darker();
    private Color trunkColor = new Color(101, 67, 33);
    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
    private int trunkX, trunkY;

    // Boundary helpers
    private Rectangle boundingBox;

    @Override
    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
    }

    @Override
    public int getPositionX() {
        return x;
    }

    @Override
    public int getPositionY() {
        return y;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        g.setColor(trunkColor);
        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
        g.setColor(leafColor);
        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
		// We don't really have any collisions to detect yet, so just return "no".
		// As we fill out all of the game pieces, we'll come back to this method
		// and provide a more useful response.
		return false;
    }
}


================================================
FILE: ch06/Euclid2.java
================================================
package ch06;

/**
 * A basic implementation of Euclid's greatest common denominator
 * algorithm. This version build on ch04 allowing you to pass the
 * numbers to use as command line arguments.
 */
public class Euclid2 {
    public static void main(String args[]) {
        int a = 2701;
        int b = 222;
		// Only try to parse arguments if we have exactly 2
		if (args.length == 2) {
			try {
				a = Integer.parseInt(args[0]);
				b = Integer.parseInt(args[1]);
			} catch (NumberFormatException nfe) {
				System.err.println("Arguments were not both numbers. Using defaults.");
			}
		} else {
			System.err.println("Wrong number of arguments (expected 2). Using defaults.");
		}
		System.out.print("The GCD of " + a + " and " + b + " is ");
        while (b != 0) {
            if (a > b) {
                a = a - b;
            } else {
                b = b - a;
            }
        }
        System.out.println(a);
    }
}


================================================
FILE: ch06/LogTest.java
================================================
package ch06;

import java.util.logging.*;

/**
 * A simple example of creating a logger and then using some of its methods.
 * For homework, try adjusting the log level where the comment is and see
 * which lines of output you still get on the console.
 */ 
public class LogTest {
    public static void main(String argv[]) {
        Logger logger = Logger.getLogger("com.oreilly.LogTest");

		// try setting the log level here
        logger.severe("Power lost - running on backup!");
        logger.warning("Database connection lost, retrying...");
        logger.info("Startup complete.");
        logger.config("Server configuration: standalone, JVM version 1.5");
        logger.fine("Loading graphing package.");
        logger.finer("Doing pie chart");
        logger.finest("Starting bubble sort: value =" + 42);
    }
}


================================================
FILE: ch07/Apple.java
================================================
/**
 * Apple
 *
 * This class sums up everything we know about the apples our physicists will be lobbing.
 * We keep the size and weight details and provide a few simple methods for lobbing.
 */
package ch07;

import java.awt.*;

public class Apple implements GamePiece {
    public static final int SMALL  = 0;
    public static final int MEDIUM = 1;
    public static final int LARGE  = 2;

    int size;
    double diameter;
    double mass;
    int centerX, centerY;
    Physicist myPhysicist;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;
    int scaledLength;

    // Boundary helper for optimizing collision detection with physicists and trees
    Rectangle boundingBox;

    // If we bumped into something, keep a reference to that thing around for cleanup and removal
    GamePiece collided;

    /**
     * Create a default, Medium apple
     */
    public Apple(Physicist owner) {
        this(owner, MEDIUM);
    }

    /**
     * Create an Apple of the given size
     */
    public Apple(Physicist owner, int size) {
        myPhysicist = owner;
        setSize(size);
    }

    /**
     * Sets the size (and dependent properties) of the apple based on the
     * supplied value which must be one of the size constants.
     *
     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE
     */
    public void setSize(int size) {
        if (size < SMALL) {
            size = SMALL;
        }
        if (size > LARGE) {
            size = LARGE;
        }
        this.size = size;
        switch (size) {
            case SMALL:
                diameter = 0.9;
                mass = 0.5;
                break;
            case MEDIUM:
                diameter = 1.0;
                mass = 1.0;
                break;
            case LARGE:
                diameter = 1.1;
                mass = 1.8;
                break;
        }
        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.
        // Since we want a circle, we simply make our box a square so we only need one length.
        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    public double getDiameter() {
        return diameter;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of the apple, but it will be drawn from the
        // upper left corner, so figure out the distance of that gap
        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our apple will be red, then paint it!
        g.setColor(Color.RED);
        g.fillOval(x, y, scaledLength, scaledLength);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {
            // By definition we don't collide with ourselves, our physicist, or with more than one other piece
            return false;
        }
        if (otherPiece instanceof Apple) {
            // The other piece is an apple, so we can do a simple distance calculation using
            // the diameters of both apples.
            Apple otherApple = (Apple) otherPiece;
            int v = this.y - otherPiece.getPositionY(); // vertical difference
            int h = this.x - otherPiece.getPositionX(); // horizontal difference
            double distance = Math.sqrt(v * v + h * h);

            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;
            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;
            if (distance < (myRadius + otherRadius)) {
                // Since apples track collisions, we'll update the other apple to keep everyone in sync
                setCollided(otherPiece);
                otherApple.setCollided(this);
                return true;
            }
            return false;
        }
        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {
            setCollided(otherPiece);
            return true;
        }
        return false;
    }

    public GamePiece getCollidedPiece() {
        return collided;
    }

    public void setCollided(GamePiece otherPiece) {
        this.collided = otherPiece;
    }
}


================================================
FILE: ch07/AppleToss.java
================================================
package ch07;

import javax.swing.*;

/**
 * Our apple tossing game. This class extends JFrame to create our
 * main application window. We'll be filling this out along the way, 
 * but for now we can setup a field with some trees and our player.
 */
public class AppleToss extends JFrame {

    Field field = new Field();
    Physicist player1 = new Physicist();

    public AppleToss() {
        // Create our frame
        super("Apple Toss Game");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(800,600);
        setResizable(false);

        // Build the field with our player and some trees
        setupFieldForOnePlayer();
    }

    /**
     * A helper method to populate a one player field with target trees.
     */
    private void setupFieldForOnePlayer() {
        // Place our (new) physicist in the lower left corner and connect them to the field
        player1.setPosition(100,500);
        field.setPlayer(player1);
        player1.setField(field);
		
		// And now make a few trees for target practice
	    for (int row = 1; row <= 2; row++) {
	        for (int col = 1; col <=3; col++) {
	            field.addTree(col * 100, row * 100);
	        }
	    }
		add(field);
    }

    public static void main(String args[]) {
        AppleToss game = new AppleToss();
        game.setVisible(true);
    }
}


================================================
FILE: ch07/Field.java
================================================
package ch07;

import javax.swing.*;
import java.awt.Color;
import java.awt.Graphics;
import java.util.*;

/**
 * The playing field for our game. Now we can setup some constants for
 * other game classes to use and create member variables for our player and some trees.
 */
public class Field extends JComponent {
    public static final float GRAVITY = 9.8f;  // feet per second per second
    public static final int STEP = 40;   // duration of an animation frame in milliseconds
    public static final int APPLE_SIZE_IN_PIXELS = 30;
    public static final int TREE_WIDTH_IN_PIXELS = 60;
    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;
    public static final int MAX_TREES = 12;

    Color fieldColor = Color.GRAY;
    Random random = new Random();

    // List and ArrayList are covered in chapter 8 on Generics
    // synchronizedArrayList is covered in chapter 9 on Threads
    Physicist physicist;
    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());

    protected void paintComponent(Graphics g) {
        g.setColor(fieldColor);
        g.fillRect(0,0, getWidth(), getHeight());
        for (Tree t : trees) {
            t.draw(g);
        }
        physicist.draw(g);
    }

    public void setPlayer(Physicist p) {
        physicist = p;
    }
	
    public void addTree(int x, int y) {
        Tree tree = new Tree();
        tree.setPosition(x,y);
        trees.add(tree);
    }
}


================================================
FILE: ch07/GamePiece.java
================================================
package ch07;

import java.awt.*;

/**
 * Interface to hold common elements for our apples, trees, and physicists
 * From the README:
 * GamePiece
 *   - methods for positioning on a PlayingField
 *   - methods for Drawing
 *   - methods for detecting a collision with other GamePieces
 */

public interface GamePiece {
    /**
     * Sets the position of the piece on the playing field.
     * (0,0) is the upper left per standard Java drawing methods.
     *
     * @param x
     * @param y
     */
    void setPosition(int x, int y);

    /**
     * Gets the current horizontal position of the piece on the field.
     *
     * @return current X position of the piece
     */
    int getPositionX();

    /**
     * Gets the current vertical position of the piece on the field.
     *
     * @return current Y position of the piece
     */
    int getPositionY();

    /**
     * Gets the bounding box of this piece.
     *
     * @return a Rectangle encompassing the visual elements of the piece
     */
    Rectangle getBoundingBox();

    /**
     * Draws the piece inside the given graphics context.
     * Do not assume anything about the state of the context.
     *
     * @param g
     */
    void draw(Graphics g);

    /**
     * Detect a collision with another piece on the field.
     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
     *
     * @param otherPiece
     * @return
     */
    boolean isTouching(GamePiece otherPiece);
}


================================================
FILE: ch07/GameUtilities.java
================================================
package ch07;

// collision detection between a circle and a rectangle
// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection

import java.awt.*;

/**
 * Utility class with a few helper methods for calculating various collisions and
 * intersections.
 */
public class GameUtilities {
    static boolean isPointInsideBox(int x, int y, Rectangle box) {
        // Our own custom test. We could of course use box.contains(),
        // but we can practice some interesting conditional checking here.
        // Let's test left and right first
        if (x >= box.x && x <= (box.x + box.width)) {
            // Our x coordinate is ok, so check our y
            if (y >= box.y && y <= (box.y + box.height)) {
                return true;
            }
        }
        // x or y was outside the box, so return false
        return false;
    }

    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
        // If any of the four corners of box are inside other, we intersect, so
        // let's check each one. Happily, that answer doesn't change if more
        // than one corner is contained in other, so we can return as soon as
        // we find the first contained corner.

        // Let's get some local copies of the corner coordinates
        // to make the call arguments easier to read.
        int x1 = box.x;
        int y1 = box.y;
        int x2 = x1 + box.width;
        int y2 = y1 + box.height;
        if (isPointInsideBox(x1, y1, other)) {
            // upper left
            return true;
        } else if (isPointInsideBox(x1, y2, other)) {
            // lower left
            return true;
        } else if (isPointInsideBox(x2, y1, other)) {
            // upper right
            return true;
        } else if (isPointInsideBox(x2, y2, other)) {
            // lower right
            return true;
        }
        // No box points in other so no intersection
        return false;
    }

    /**
     * Given two rectangles, do the overlap at all? This includes one box being
     * completely contained by the other box.
     *
     * @param box1 a box to test, order does not matter
     * @param box2 the other box
     * @return true if the boxes overlap, false otherwise
     */
    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {
        // Another custom test. We could of course use box1.intersects(box2)
        // but we can practice method calls and some boolean logic here.
        if (doesBoxIntersect(box1, box2)) {
            // At least one of box1's points must be inside box2
            return true;
        } else if (doesBoxIntersect(box2, box1)) {
            // None of box1's points were in box2, but at least one of box2's points are inside box1
            return true;
        }
        // No intersections in either direction
        return false;
    }
}


================================================
FILE: ch07/Physicist.java
================================================
package ch07;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static java.awt.Color.*;

/**
 * Our player class. A physicist has an apple that they can throw in addition
 * to implementing the basic methods for GamePiece. We can also set a custom
 * color in case you build on the game and allow multiple physicists to be
 * on the screen at the same time.
 */
public class Physicist implements GamePiece {
    Color color;
    int centerX, centerY;
    Apple aimingApple;
    float aimingAngle;
    float aimingForce;
    Field field;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;

    // Boundary helpers
    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);
    private Rectangle boundingBox;


    /**
     * Create a default, blue physicist
     */
    public Physicist() {
        this(BLUE);
    }

    /**
     * Create a Physicist of the given color
     */
    public Physicist(Color color) {
        setColor(color);
        aimingAngle = 90.0f;
        aimingForce = 50.0f;
        getNewApple();
    }

    public void setAimingAngle(Float angle) {
        aimingAngle = angle;
    }

    public void setAimingForce(Float force) {
        if (force < 0) {
            force = 0.0f;
        }
        aimingForce = force;
    }

    /**
     * Sets the color for the physicist.
     *
     * @param color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of our dome,
        // but it will be drawn from the upper left corner.
        // Figure out the distance of that gap
        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    /**
     * Sets the active field once our physicist is being displayed.
     *
     * @param field Active game field
     */
    public void setField(Field field) {
        this.field = field;
    }

    /**
     * Take the current apple away from the physicist. Returns the apple for
     * use in animating on the field. Note that if there is no current apple being
     * aimed, null is returned.
     *
     * @return the current apple (if any) being aimed
     */
    public Apple takeApple() {
        Apple myApple = aimingApple;
        aimingApple = null;
        return myApple;
    }

    /**
     * Get a new apple ready if we need one. Do not discard an existing apple.
     */
    public void getNewApple() {
        // Don't drop the current apple if we already have one!
        if (aimingApple == null) {
            aimingApple = new Apple(this);
        }
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our physicist is the right color, then draw the semi-circle and box
        g.setColor(color);
        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);
        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);

        // Do we have an apple to draw as well?
        if (aimingApple != null) {
            // Yes. Position the center of the apple on the edge of our semi-circle.
            // Use the current aimingAngle to determine where on the edge.
            double angleInRadians = Math.toRadians(aimingAngle);
            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;
            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);
            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);
            aimingApple.setPosition(aimingX, aimingY);
            aimingApple.draw(g);
        }
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }
}


================================================
FILE: ch07/Tree.java
================================================
package ch07;

import java.awt.*;

/**
 * An obstacle for our game. Trees includ a simple circle and rectangle shape.
 * They are built using sizes determined by the constants in the Field class.
 */
public class Tree implements GamePiece {
    int x, y;

    // Drawing helpers
    private Color leafColor = Color.GREEN.darker();
    private Color trunkColor = new Color(101, 67, 33);
    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
    private int trunkX, trunkY;

    // Boundary helpers
    private Rectangle boundingBox;

    @Override
    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
    }

    @Override
    public int getPositionX() {
        return x;
    }

    @Override
    public int getPositionY() {
        return y;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        g.setColor(trunkColor);
        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
        g.setColor(leafColor);
        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }
}


================================================
FILE: ch08/Apple.java
================================================
/**
 * Apple
 *
 * This class sums up everything we know about the apples our physicists will be lobbing.
 * We keep the size and weight details and provide a few simple methods for lobbing. We
 * can now detect collisions as well.
 */
package ch08;

import java.awt.*;

public class Apple implements GamePiece {
    public static final int SMALL  = 0;
    public static final int MEDIUM = 1;
    public static final int LARGE  = 2;

    int size;
    double diameter;
    double mass;
    int centerX, centerY;
    Physicist myPhysicist;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;
    int scaledLength;

    // Boundary helper for optimizing collision detection with physicists and trees
    Rectangle boundingBox;

    // If we bumped into something, keep a reference to that thing around for cleanup and removal
    GamePiece collided;

    /**
     * Create a default, Medium apple
     */
    public Apple(Physicist owner) {
        this(owner, MEDIUM);
    }

    /**
     * Create an Apple of the given size
     */
    public Apple(Physicist owner, int size) {
        myPhysicist = owner;
        setSize(size);
    }

    /**
     * Sets the size (and dependent properties) of the apple based on the
     * supplied value which must be one of the size constants.
     *
     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE
     */
    public void setSize(int size) {
        if (size < SMALL) {
            size = SMALL;
        }
        if (size > LARGE) {
            size = LARGE;
        }
        this.size = size;
        switch (size) {
            case SMALL:
                diameter = 0.9;
                mass = 0.5;
                break;
            case MEDIUM:
                diameter = 1.0;
                mass = 1.0;
                break;
            case LARGE:
                diameter = 1.1;
                mass = 1.8;
                break;
        }
        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.
        // Since we want a circle, we simply make our box a square so we only need one length.
        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    public double getDiameter() {
        return diameter;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of the apple, but it will be drawn from the
        // upper left corner, so figure out the distance of that gap
        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our apple will be red, then paint it!
        g.setColor(Color.RED);
        g.fillOval(x, y, scaledLength, scaledLength);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {
            // By definition we don't collide with ourselves, our physicist, or with more than one other piece
            return false;
        }
        if (otherPiece instanceof Apple) {
            // The other piece is an apple, so we can do a simple distance calculation using
            // the diameters of both apples.
            Apple otherApple = (Apple) otherPiece;
            int v = this.y - otherPiece.getPositionY(); // vertical difference
            int h = this.x - otherPiece.getPositionX(); // horizontal difference
            double distance = Math.sqrt(v * v + h * h);

            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;
            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;
            if (distance < (myRadius + otherRadius)) {
                // Since apples track collisions, we'll update the other apple to keep everyone in sync
                setCollided(otherPiece);
                otherApple.setCollided(this);
                return true;
            }
            return false;
        }
        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {
            setCollided(otherPiece);
            return true;
        }
        return false;
    }

    public GamePiece getCollidedPiece() {
        return collided;
    }

    public void setCollided(GamePiece otherPiece) {
        this.collided = otherPiece;
    }
}


================================================
FILE: ch08/AppleToss.java
================================================
package ch08;

import javax.swing.*;
import java.util.Random;

/**
 * Our apple tossing game. This class extends JFrame to create our
 * main application window. We can now setup several trees for
 * target practice. (The ability for the player to aim and throw
 * will be covered in Chapter 10.)
 */
public class AppleToss extends JFrame {

    public static final int FIELD_WIDTH = 800;
    public static final int FIELD_HEIGHT = 600;

    Field field = new Field();
    Physicist player1 = new Physicist();
	
	// Helper class
	Random random = new Random();

    public AppleToss() {
        // Create our frame
        super("Apple Toss Game");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(FIELD_WIDTH,FIELD_HEIGHT);
        setResizable(false);

        // Build the field with our player and some trees
        setupFieldForOnePlayer();
    }

    /**
     * Helper method to return a good x value for a tree so it's not off the left or right edge.
     *
     * @return x value within the bounds of the playing field width
     */
    private int goodX() {
        // at least half the width of the tree plus a few pixels
        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // now find a random number between a left and right margin
        int rightMargin = FIELD_WIDTH - leftMargin;

        // And return a random number starting at the left margin
        return leftMargin + random.nextInt(rightMargin - leftMargin);
    }

    /**
     * Helper method to return a good y value for a tree so it's
	 * not off the top or bottom of the screen.
     *
     * @return y value within the bounds of the playing field height
     */
    private int goodY() {
        // at least half the height of the "leaves" plus a few pixels
        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // a little higher off the bottom
        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;

        // And return a random number starting at the top margin but not past the bottom
        return topMargin + random.nextInt(bottomMargin - topMargin);
    }

    /**
     * A helper method to populate a one player field with target trees.
     */
    private void setupFieldForOnePlayer() {
        // Place our (new) physicist in the lower left corner and connect them to the field
        player1.setPosition(100,500);
        field.setPlayer(player1);
        player1.setField(field);
		
		// And now make a few trees for target practice
        for (int i = field.trees.size(); i < Field.MAX_TREES; i++) {
            Tree t = new Tree();
            t.setPosition(goodX(), goodY());
            // Trees can be close to each other and overlap,
			// but they shouldn't intersect our physicist
            while(player1.isTouching(t)) {
                // We do intersect this tree, so let's try again
                t.setPosition(goodX(), goodY());
                System.err.println("Repositioning an intersecting tree...");
            }
			field.addTree(t);
        }
		add(field);
    }

    public static void main(String args[]) {
        AppleToss game = new AppleToss();
        game.setVisible(true);
    }
}


================================================
FILE: ch08/Field.java
================================================
package ch08;

import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;

/**
 * The playing field for our game. Now we can setup some constants for
 * other game classes to use and create member variables for our player and some trees.
 */
public class Field extends JComponent {
    public static final float GRAVITY = 9.8f;  // feet per second per second
    public static final int STEP = 40;   // duration of an animation frame in milliseconds
    public static final int APPLE_SIZE_IN_PIXELS = 30;
    public static final int TREE_WIDTH_IN_PIXELS = 60;
    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;
    public static final int MAX_TREES = 12;

    Color fieldColor = Color.GRAY;
    Random random = new Random();

    // ArrayList covered in Generics chapter
    // synchronizedArrayList covered in Threads chapter
    Physicist physicist;
    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());

    protected void paintComponent(Graphics g) {
        g.setColor(fieldColor);
        g.fillRect(0,0, getWidth(), getHeight());
        for (Tree t : trees) {
            t.draw(g);
        }
        physicist.draw(g);
    }

    public void setPlayer(Physicist p) {
        physicist = p;
    }
	
	/**
	 * Create and add a new tree to the field.
	 *
	 * @param x The X-coordinate for the tree
	 * @param y The Y-coordinate for the tree
	 */
    public void addTree(int x, int y) {
        Tree tree = new Tree();
        tree.setPosition(x,y);
        trees.add(tree);
    }
	
	/**
	 * Add an existing tree to our field. Useful if the position
	 * of the tree has already been set.
	 *
	 * @param t The existing tree to add
	 */
	public void addTree(Tree t) {
		trees.add(t);
	}
}


================================================
FILE: ch08/GamePiece.java
================================================
package ch08;

import java.awt.*;

/**
 * Interface to hold common elements for our apples, trees, and physicists
 * From the README:
 * GamePiece
 *   - methods for positioning on a PlayingField
 *   - methods for Drawing
 *   - methods for detecting a collision with other GamePieces
 */

public interface GamePiece {
    /**
     * Sets the position of the piece on the playing field.
     * (0,0) is the upper left per standard Java drawing methods.
     *
     * @param x
     * @param y
     */
    void setPosition(int x, int y);

    /**
     * Gets the current horizontal position of the piece on the field.
     *
     * @return current X position of the piece
     */
    int getPositionX();

    /**
     * Gets the current vertical position of the piece on the field.
     *
     * @return current Y position of the piece
     */
    int getPositionY();

    /**
     * Gets the bounding box of this piece.
     *
     * @return a Rectangle encompassing the visual elements of the piece
     */
    Rectangle getBoundingBox();

    /**
     * Draws the piece inside the given graphics context.
     * Do not assume anything about the state of the context.
     *
     * @param g
     */
    void draw(Graphics g);

    /**
     * Detect a collision with another piece on the field.
     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
     *
     * @param otherPiece
     * @return
     */
    boolean isTouching(GamePiece otherPiece);
}


================================================
FILE: ch08/GameUtilities.java
================================================
package ch08;

// collision detection between a circle and a rectangle
// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection

import java.awt.*;

/**
 * Utility class with a few helper methods for calculating various collisions and
 * intersections.
 */
public class GameUtilities {
    static boolean isPointInsideBox(int x, int y, Rectangle box) {
        // Our own custom test. We could of course use box.contains(),
        // but we can practice some interesting conditional checking here.
        // Let's test left and right first
        if (x >= box.x && x <= (box.x + box.width)) {
            // Our x coordinate is ok, so check our y
            if (y >= box.y && y <= (box.y + box.height)) {
                return true;
            }
        }
        // x or y was outside the box, so return false
        return false;
    }

    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
        // If any of the four corners of box are inside other, we intersect, so
        // let's check each one. Happily, that answer doesn't change if more
        // than one corner is contained in other, so we can return as soon as
        // we find the first contained corner.

        // Let's get some local copies of the corner coordinates
        // to make the call arguments easier to read.
        int x1 = box.x;
        int y1 = box.y;
        int x2 = x1 + box.width;
        int y2 = y1 + box.height;
        if (isPointInsideBox(x1, y1, other)) {
            // upper left
            return true;
        } else if (isPointInsideBox(x1, y2, other)) {
            // lower left
            return true;
        } else if (isPointInsideBox(x2, y1, other)) {
            // upper right
            return true;
        } else if (isPointInsideBox(x2, y2, other)) {
            // lower right
            return true;
        }
        // No box points in other so no intersection
        return false;
    }

    /**
     * Given two rectangles, do the overlap at all? This includes one box being
     * completely contained by the other box.
     *
     * @param box1 a box to test, order does not matter
     * @param box2 the other box
     * @return true if the boxes overlap, false otherwise
     */
    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {
        // Another custom test. We could of course use box1.intersects(box2)
        // but we can practice method calls and some boolean logic here.
        if (doesBoxIntersect(box1, box2)) {
            // At least one of box1's points must be inside box2
            return true;
        } else if (doesBoxIntersect(box2, box1)) {
            // None of box1's points were in box2, but at least one of box2's points are inside box1
            return true;
        }
        // No intersections in either direction
        return false;
    }
}


================================================
FILE: ch08/Physicist.java
================================================
package ch08;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static java.awt.Color.*;

/**
 * Our player class. A physicist has an apple that they can throw in addition
 * to implementing the basic methods for GamePiece. We can also set a custom
 * color in case you build on the game and allow multiple physicists to be
 * on the screen at the same time.
 */
public class Physicist implements GamePiece {
    Color color;
    int centerX, centerY;
    Apple aimingApple;
    float aimingAngle;
    float aimingForce;
    Field field;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;

    // Boundary helpers
    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);
    private Rectangle boundingBox;


    /**
     * Create a default, blue physicist
     */
    public Physicist() {
        this(BLUE);
    }

    /**
     * Create a Physicist of the given color
     */
    public Physicist(Color color) {
        setColor(color);
        aimingAngle = 90.0f;
        aimingForce = 50.0f;
        getNewApple();
    }

    public void setAimingAngle(Float angle) {
        aimingAngle = angle;
    }

    public void setAimingForce(Float force) {
        if (force < 0) {
            force = 0.0f;
        }
        aimingForce = force;
    }

    /**
     * Sets the color for the physicist.
     *
     * @param color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of our dome,
        // but it will be drawn from the upper left corner.
        // Figure out the distance of that gap
        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    /**
     * Sets the active field once our physicist is being displayed.
     *
     * @param field Active game field
     */
    public void setField(Field field) {
        this.field = field;
    }

    /**
     * Take the current apple away from the physicist. Returns the apple for
     * use in animating on the field. Note that if there is no current apple being
     * aimed, null is returned.
     *
     * @return the current apple (if any) being aimed
     */
    public Apple takeApple() {
        Apple myApple = aimingApple;
        aimingApple = null;
        return myApple;
    }

    /**
     * Get a new apple ready if we need one. Do not discard an existing apple.
     */
    public void getNewApple() {
        // Don't drop the current apple if we already have one!
        if (aimingApple == null) {
            aimingApple = new Apple(this);
        }
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our physicist is the right color, then draw the semi-circle and box
        g.setColor(color);
        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);
        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);

        // Do we have an apple to draw as well?
        if (aimingApple != null) {
            // Yes. Position the center of the apple on the edge of our semi-circle.
            // Use the current aimingAngle to determine where on the edge.
            double angleInRadians = Math.toRadians(aimingAngle);
            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;
            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);
            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);
            aimingApple.setPosition(aimingX, aimingY);
            aimingApple.draw(g);
        }
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }
}


================================================
FILE: ch08/Tree.java
================================================
package ch08;

import java.awt.*;

/**
 * An obstacle for our game. Trees includ a simple circle and rectangle shape.
 * They are built using sizes determined by the constants in the Field class.
 */
public class Tree implements GamePiece {
    int x, y;

    // Drawing helpers
    private Color leafColor = Color.GREEN.darker();
    private Color trunkColor = new Color(101, 67, 33);
    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
    private int trunkX, trunkY;

    // Boundary helpers
    private Rectangle boundingBox;

    @Override
    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
    }

    @Override
    public int getPositionX() {
        return x;
    }

    @Override
    public int getPositionY() {
        return y;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        g.setColor(trunkColor);
        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
        g.setColor(leafColor);
        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }
}


================================================
FILE: ch09/URLConsumer.java
================================================
package ch09;

import java.util.Random;

/**
 * A threaded client for our URL producer. Uses a synchronized queue
 * to safely read a URL for processing. (Our simple demo "processes"
 * by printing out the ID of this consumer and the url it consumed.)
 */
public class URLConsumer extends Thread {
    String consumerID;
    URLQueue queue;
    boolean keepWorking;

    Random delay;

	/**
	 * Creates a new consumer with the given ID and reference to the shared queue.
	 *
	 * @param id A unique (unenforced) name for this consumer
	 * @param queue The shared queue for storing and distributing URLs
	 */
    public URLConsumer(String id, URLQueue queue) {
        if (queue == null) {
            throw new IllegalArgumentException("Shared queue cannot be null");
        }
        consumerID = id;
        this.queue = queue;
        keepWorking = true;
        delay = new Random();
    }

	/**
	 * Our working method for the thread. Watches the boolean flag
	 * keepWorking as well as the state of the queue to determine
	 * whether or not to complete the loop. While working, grab a
	 * URL and print it out then repeat.
	 */
    public void run() {
        while (keepWorking || !queue.isEmpty()) {
            String url = queue.getURL();
            if (url != null) {
                System.out.println(consumerID + " consumed " + url);
            } else {
                System.out.println(consumerID + " skipped empty queue");
            }
            try {
                Thread.sleep(delay.nextInt(1000));
            } catch (InterruptedException ie) {
                System.err.println("Consumer " + consumerID + " interrupted. Quitting.");
                break;
            }
        }
    }

	/**
	 * Allow for politely halting this consumer.
	 * Watched in the run() method.
	 * 
	 * @see #run()
	 */
    public void setKeepWorking(boolean keepWorking) {
        this.keepWorking = keepWorking;
    }
}


================================================
FILE: ch09/URLDemo.java
================================================
package ch09;

/**
 * Manage multiple producers and consumers to demonstrate how
 * threads work in tandem. Creates a pair of producers and a
 * pair of consumers all with access to a shared queue.
 *
 * @see URLQueue
 * @see URLProducer
 * @see URLConsumer
 */
public class URLDemo {
    public static void main(String args[]) {
		// Create our shared queue object
        URLQueue queue = new URLQueue();
		
		// Now create some producers with unique names and a reference to our queue
        URLProducer p1 = new URLProducer("P1", 3, queue);
        URLProducer p2 = new URLProducer("P2", 3, queue);
		
		// And some consumers with their own names and a reference to our queue
        URLConsumer c1 = new URLConsumer("C1", queue);
        URLConsumer c2 = new URLConsumer("C2", queue);
		
		// Get everyone going!
        System.out.println("Starting...");
        p1.start();
        p2.start();
        c1.start();
        c2.start();
		
		// First wait around for the producers to finish
        try {
            p1.join();
            p2.join();
        } catch (InterruptedException ie) {
            System.err.println("Interrupted waiting for producers to finish");
        }
		
		// OK, we know there won't be any more URLs made, so let the consumers
		// finish once the queue is empty
        c1.setKeepWorking(false);
        c2.setKeepWorking(false);
        try {
            c1.join();
            c2.join();
        } catch (InterruptedException ie) {
            System.err.println("Interrupted waiting for consumers to finish");
        }
		
        System.out.println("Done");
    }
}


================================================
FILE: ch09/URLProducer.java
================================================
package ch09;

import java.util.Random;

/**
 * Simple producer for use in our multithreaded example. Uses a synchronized queue
 * to safely store URLs for processing.
 */
public class URLProducer extends Thread {
    String producerID;
    int urlCount;
    URLQueue queue;

    Random delay;

	/**
	 * Create a new producer with the given name. It will produce the
	 * specified number of URLs and store them in the provided queue.
	 *
	 * @param id A unique (unenforced) name for this producer
	 * @param count How many URLs this producer will create before quitting
	 * @param queue The shared, synchronized queue for URLs
	 */
    public URLProducer(String id, int count, URLQueue queue) {
        // Don't even create this producer if a negative count was supplied or there's no queue
        if (count <= 0) {
            throw new IllegalArgumentException("Count must be positive");
        }
        if (queue == null) {
            throw new IllegalArgumentException("Shared queue cannot be null");
        }
        producerID = id;
        urlCount = count;
        this.queue = queue;
        delay = new Random();
    }

	/**
	 * Our working method for the thread. Uses the count supplied to
	 * the constructor to produce a batch of URLs and store them to
	 * the shared queue. To make it a little more interesting, a random
	 * delay is added at the end of each iteration. 
	 */
    public void run() {
        for (int i = 1; i <= urlCount; i++) {
            String url = "https://some.url/at/path/" + i;
            queue.addURL(producerID + " " + url);
            System.out.println(producerID + " produced " + url);
            try {
                Thread.sleep(delay.nextInt(500));
            } catch (InterruptedException ie) {
                System.err.println("Producer " + producerID + " interrupted. Quitting.");
                break;
            }
        }
    }
}


================================================
FILE: ch09/URLQueue.java
================================================
package ch09;

import java.util.LinkedList;

/**
 * A manually synchronized wrapper for a LinkedList.
 * Allows for safely adding and removing URLs in order.
 */
public class URLQueue {
    LinkedList<String> urlQueue = new LinkedList<>();

    public synchronized void addURL(String url) {
        urlQueue.add(url);
    }

    public synchronized String getURL() {
        if (!urlQueue.isEmpty()) {
            return urlQueue.removeFirst();
        }
        return null;
    }

    public boolean isEmpty() {
        return urlQueue.isEmpty();
    }
}


================================================
FILE: ch09/game/Apple.java
================================================
package ch09.game;

import java.awt.*;

/**
 * Apple
 *
 * This class sums up everything we know about the apples our physicists will be lobbing.
 * We keep the size and weight details and provide a few simple methods for lobbing. We
 * also provide animation helpers for use with the PlayingField class.
 */
public class Apple implements GamePiece {
    public static final int SMALL  = 0;
    public static final int MEDIUM = 1;
    public static final int LARGE  = 2;

    int size;
    double diameter;
    double mass;
    int centerX, centerY;
    Physicist myPhysicist;

    // In game play, apples can be thrown so track their velocities
    long lastStep;
    float velocityX, velocityY;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;
    int scaledLength;

    // Boundary helper for optimizing collision detection with physicists and trees
    Rectangle boundingBox;

    // If we bumped into something, keep a reference to that thing around for cleanup and removal
    GamePiece collided;

    /**
     * Create a default, Medium apple
     */
    public Apple(Physicist owner) {
        this(owner, MEDIUM);
    }

    /**
     * Create an Apple of the given size
     */
    public Apple(Physicist owner, int size) {
        myPhysicist = owner;
        setSize(size);
    }

    /**
     * Sets the size (and dependent properties) of the apple based on the
     * supplied value which must be one of the size constants.
     *
     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE
     */
    public void setSize(int size) {
        if (size < SMALL) {
            size = SMALL;
        }
        if (size > LARGE) {
            size = LARGE;
        }
        this.size = size;
        switch (size) {
            case SMALL:
                diameter = 0.9;
                mass = 0.5;
                break;
            case MEDIUM:
                diameter = 1.0;
                mass = 1.0;
                break;
            case LARGE:
                diameter = 1.1;
                mass = 1.8;
                break;
        }
        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.
        // Since we want a circle, we simply make our box a square so we only need one length.
        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    public double getDiameter() {
        return diameter;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of the apple, but it will be drawn from the
        // upper left corner, so figure out the distance of that gap
        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our apple will be red, then paint it!
        g.setColor(Color.RED);
        g.fillOval(x, y, scaledLength, scaledLength);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {
            // By definition we don't collide with ourselves, our physicist, or with more than one other piece
            return false;
        }
        if (otherPiece instanceof Apple) {
            // The other piece is an apple, so we can do a simple distance calculation using
            // the diameters of both apples.
            Apple otherApple = (Apple) otherPiece;
            int v = this.y - otherPiece.getPositionY(); // vertical difference
            int h = this.x - otherPiece.getPositionX(); // horizontal difference
            double distance = Math.sqrt(v * v + h * h);

            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;
            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;
            if (distance < (myRadius + otherRadius)) {
                // Since apples track collisions, we'll update the other apple to keep everyone in sync
                setCollided(otherPiece);
                otherApple.setCollided(this);
                return true;
            }
            return false;
        }
        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {
            setCollided(otherPiece);
            return true;
        }
        return false;
    }

    public GamePiece getCollidedPiece() {
        return collided;
    }

    public void setCollided(GamePiece otherPiece) {
        this.collided = otherPiece;
    }

    public void toss(float angle, float velocity) {
        lastStep = System.currentTimeMillis();
        double radians = angle / 180 * Math.PI;
        velocityX = (float)(velocity * Math.cos(radians) / mass);
        // Start with negative velocity since "up" means smaller values of y
        velocityY = (float)(-velocity * Math.sin(radians) / mass);
    }

    public void step() {
        // Make sure we're moving at all using our lastStep tracker as a sentinel
        if (lastStep > 0) {
            // let's apply our gravity
            long now = System.currentTimeMillis();
            float slice = (now - lastStep) / 1000.0f;
            velocityY = velocityY + (slice * Field.GRAVITY);
            int newX = (int)(centerX + velocityX);
            int newY = (int)(centerY + velocityY);
            setPosition(newX, newY);
        }
    }
}


================================================
FILE: ch09/game/AppleToss.java
================================================
package ch09.game;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;

/**
 * Our apple tossing game. This class extends JFrame to create our
 * main application window. We can now demonstrate one apple being
 * tossed. (The ability for the player to aim and throw on demand
 * will be covered in Chapter 10.)
 */
public class AppleToss extends JFrame {

    public static final int FIELD_WIDTH = 800;
    public static final int FIELD_HEIGHT = 500;

    Field field = new Field();
    Physicist player1 = new Physicist();
    ArrayList<Physicist> otherPlayers = new ArrayList<>();

    Random random = new Random();

    public AppleToss() {
        // Create our frame
        super("Apple Toss Game");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setSize(FIELD_WIDTH,FIELD_HEIGHT + 20);

        // Build the field with our player and some trees
        setupFieldForOnePlayer();
        add(field);
    }

    /**
     * Helper method to return a good x value for a tree so it's not off the left or right edge.
     *
     * @return x value within the bounds of the playing field width
     */
    private int goodX() {
        // at least half the width of the tree plus a few pixels
        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // now find a random number between a left and right margin
        int rightMargin = FIELD_WIDTH - leftMargin;

        // And return a random number starting at the left margin
        return leftMargin + random.nextInt(rightMargin - leftMargin);
    }

    /**
     * Helper method to return a good y value for a tree so it's not off the top or bottom of the screen.
     *
     * @return y value within the bounds of the playing field height
     */
    private int goodY() {
        // at least half the height of the "leaves" plus a few pixels
        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // a little higher off the bottom
        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;

        // And return a random number starting at the top margin but not past the bottom
        return topMargin + random.nextInt(bottomMargin - topMargin);
    }

    /**
     * A helper method to populate a one player field with target trees.
     */
    private void setupFieldForOnePlayer() {
        // place our (new) physicist in the lower left corner
        if (field.physicists.size() == 0) {
            player1.setPosition(Field.PHYSICIST_SIZE_IN_PIXELS, FIELD_HEIGHT - (int) (Field.PHYSICIST_SIZE_IN_PIXELS * 1.5));
            field.physicists.add(player1);
            player1.setField(field);
        }

        // Create some trees for target practice
        for (int i = field.trees.size(); i < 10; i++) {
            Tree t = new Tree();
            t.setPosition(goodX(), goodY());
            // Trees can be close to each other and overlap, but they shouldn't intersect our physicist
            while(player1.isTouching(t)) {
                // We do intersect this tree, so let's try again
                t.setPosition(goodX(), goodY());
                System.err.println("Repositioning an intersecting tree...");
            }
            field.trees.add(t);
        }
    }

    public static void main(String args[]) {
        AppleToss game = new AppleToss();
        game.setVisible(true);
        try {
            game.player1.setAimingAngle(45.0f);
            game.field.repaint();
            Thread.sleep(1000);
            game.field.startTossFromPlayer(game.player1);
        } catch (InterruptedException ie) {
            System.err.println("Interrupted during initial pause before tossing an apple.");
        }
    }
}


================================================
FILE: ch09/game/Field.java
================================================
package ch09.game;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * The playing field for our game. Now we can setup some constants for
 * other game classes to use and create member variables for our player and some trees.
 */
public class Field extends JComponent implements ActionListener {
    public static final float GRAVITY = 9.8f;  // feet per second per second
    public static final int STEP = 40;   // duration of an animation frame in milliseconds
    public static final int APPLE_SIZE_IN_PIXELS = 30;
    public static final int TREE_WIDTH_IN_PIXELS = 60;
    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;

    public static final int MAX_PHYSICISTS = 5;
    public static final int MAX_APPLES_PER_PHYSICIST = 3;
    public static final int MAX_TREES = 12;

    Color fieldColor = Color.GRAY;

    // ArrayList was covered in Generics chapter
    List<Physicist> physicists = Collections.synchronizedList(new ArrayList<>());
    List<Apple> apples = Collections.synchronizedList(new ArrayList<>());
    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());

    boolean animating = false;
    Thread animationThread;
    Timer animationTimer;

    protected void paintComponent(Graphics g) {
        g.setColor(fieldColor);
        g.fillRect(0,0, getWidth(), getHeight());
        for (Physicist p : physicists) {
            p.draw(g);
        }
        for (Tree t : trees) {
            t.draw(g);
        }
        for (Apple a : apples) {
            a.draw(g);
        }
    }

    public void actionPerformed(ActionEvent event) {
        if (animating && event.getActionCommand().equals("repaint")) {
            System.out.println("Timer stepping " + apples.size() + " apples");
            for (Apple a : apples) {
                a.step();
                detectCollisions(a);
            }
            repaint();
            cullFallenApples();
        }
    }

    /**
     * Toss an apple from the given physicist using that physicist's aim and force.
     * Make sure the field is in the animating state.
     *
     * @param physicist the player whose apple should be tossed
     */
    public void startTossFromPlayer(Physicist physicist) {
        if (!animating) {
            System.out.println("Starting animation!");
            animating = true;
            startAnimation();
        }
        if (animating) {
            // Check to make sure we have an apple to toss
            if (physicist.aimingApple != null) {
                Apple apple = physicist.takeApple();
                apple.toss(physicist.aimingAngle, physicist.aimingForce);
                apples.add(apple);
            }
        }
    }

    void cullFallenApples() {
        Iterator<Apple> iterator = apples.iterator();
        while (iterator.hasNext()) {
            Apple a = iterator.next();
            if (a.getPositionY() > 600) {
                System.out.println("Culling apple");
                iterator.remove();
            }
        }
        if (apples.size() <= 0) {
            animating = false;
            if (animationTimer != null && animationTimer.isRunning()) {
                animationTimer.stop();
            }
        }
    }

    void detectCollisions(Apple apple) {
        // Check for other apples
        for (Apple a : apples) {
            if (apple.isTouching(a)) {
                System.out.println("Touching another apple!");
                return;
            }
        }
        // Check for physicists
        for (Physicist p : physicists) {
            if (apple.isTouching(p)) {
                System.out.println("Touching a physicist!");
                return;
            }
        }
        // Check for trees
        for (Tree t : trees) {
            if (apple.isTouching(t)) {
                System.out.println("Touching a tree!");
                return;
            }
        }
    }

    void hitPhysicist(Physicist physicist) {
        // do any scoring or notifications here
        physicists.remove(physicist);
    }

    void hitTree(Tree tree) {
        // do any scoring or notifications here
        trees.remove(tree);
    }

    void startAnimation() {
        // Animator myAnimator = new Animator();
        // animationThread = new Thread(myAnimator);
        // animationThread.start();
        if (animationTimer == null) {
            animationTimer = new Timer(STEP, this);
            animationTimer.setActionCommand("repaint");
            animationTimer.setRepeats(true);
            animationTimer.start();
        } else if (!animationTimer.isRunning()) {
            animationTimer.restart();
        }
    }

    class Animator implements Runnable {
        public void run() {
            while (animating) {
                System.out.println("Stepping " + apples.size() + " apples");
                for (Apple a : apples) {
                    a.step();
                    detectCollisions(a);
                }
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        Field.this.repaint();
                    }
                });
                cullFallenApples();
                try {
                    Thread.sleep((int)(STEP * 1000));
                } catch (InterruptedException ie) {
                    System.err.println("Animation interrupted");
                    animating = false;
                }
            }
        }
    }
}


================================================
FILE: ch09/game/GamePiece.java
================================================
package ch09.game;

import java.awt.*;

/**
 * Interface to hold common elements for our apples, trees, and physicists
 * From the README:
 * GamePiece
 *   - methods for positioning on a PlayingField
 *   - methods for Drawing
 *   - methods for detecting a collision with other GamePieces
 */

public interface GamePiece {
    /**
     * Sets the position of the piece on the playing field.
     * (0,0) is the upper left per standard Java drawing methods.
     *
     * @param x
     * @param y
     */
    void setPosition(int x, int y);

    /**
     * Gets the current horizontal position of the piece on the field.
     *
     * @return current X position of the piece
     */
    int getPositionX();

    /**
     * Gets the current vertical position of the piece on the field.
     *
     * @return current Y position of the piece
     */
    int getPositionY();

    /**
     * Gets the bounding box of this piece.
     *
     * @return a Rectangle encompassing the visual elements of the piece
     */
    Rectangle getBoundingBox();

    /**
     * Draws the piece inside the given graphics context.
     * Do not assume anything about the state of the context.
     *
     * @param g
     */
    void draw(Graphics g);

    /**
     * Detect a collision with another piece on the field.
     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
     *
     * @param otherPiece
     * @return
     */
    boolean isTouching(GamePiece otherPiece);
}


================================================
FILE: ch09/game/GameUtilities.java
================================================
package ch09.game;

// collision detection between a circle and a rectangle
// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection

import java.awt.*;

/**
 * Utility class with a few helper methods for calculating various collisions and
 * intersections.
 */
public class GameUtilities {
    static boolean isPointInsideBox(int x, int y, Rectangle box) {
        // Our own custom test. We could of course use box.contains(),
        // but we can practice some interesting conditional checking here.
        // Let's test left and right first
        if (x >= box.x && x <= (box.x + box.width)) {
            // Our x coordinate is ok, so check our y
            if (y >= box.y && y <= (box.y + box.height)) {
                return true;
            }
        }
        // x or y was outside the box, so return false
        return false;
    }

    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
        // If any of the four corners of box are inside other, we intersect, so
        // let's check each one. Happily, that answer doesn't change if more
        // than one corner is contained in other, so we can return as soon as
        // we find the first contained corner.

        // Let's get some local copies of the corner coordinates
        // to make the call arguments easier to read.
        int x1 = box.x;
        int y1 = box.y;
        int x2 = x1 + box.width;
        int y2 = y1 + box.height;
        if (isPointInsideBox(x1, y1, other)) {
            // upper left
            return true;
        } else if (isPointInsideBox(x1, y2, other)) {
            // lower left
            return true;
        } else if (isPointInsideBox(x2, y1, other)) {
            // upper right
            return true;
        } else if (isPointInsideBox(x2, y2, other)) {
            // lower right
            return true;
        }
        // No box points in other so no intersection
        return false;
    }

    /**
     * Given two rectangles, do the overlap at all? This includes one box being
     * completely contained by the other box.
     *
     * @param box1 a box to test, order does not matter
     * @param box2 the other box
     * @return true if the boxes overlap, false otherwise
     */
    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {
        // Another custom test. We could of course use box1.intersects(box2)
        // but we can practice method calls and some boolean logic here.
        if (doesBoxIntersect(box1, box2)) {
            // At least one of box1's points must be inside box2
            return true;
        } else if (doesBoxIntersect(box2, box1)) {
            // None of box1's points were in box2, but at least one of box2's points are inside box1
            return true;
        }
        // No intersections in either direction
        return false;
    }
}


================================================
FILE: ch09/game/Physicist.java
================================================
package ch09.game;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static java.awt.Color.*;

/**
 * Our player class. A physicist has an apple that they can throw in addition
 * to implementing the basic methods for GamePiece. We can also set a custom
 * color in case you build on the game and allow multiple physicists to be
 * on the screen at the same time.
 */
public class Physicist implements GamePiece, ActionListener {
    Color color;
    int centerX, centerY;
    Apple aimingApple;
    float aimingAngle;
    float aimingForce;
    Field field;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;

    // Boundary helpers
    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);
    private Rectangle boundingBox;


    /**
     * Create a default, blue physicist
     */
    public Physicist() {
        this(BLUE);
    }

    /**
     * Create a Physicist of the given color
     */
    public Physicist(Color color) {
        setColor(color);
        aimingAngle = 90.0f;
        aimingForce = 50.0f;
        getNewApple();
    }

    public void setAimingAngle(Float angle) {
        aimingAngle = angle;
    }

    public void setAimingForce(Float force) {
        if (force < 0) {
            force = 0.0f;
        }
        aimingForce = force;
    }

    /**
     * Sets the color for the physicist.
     *
     * @param color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of our dome,
        // but it will be drawn from the upper left corner.
        // Figure out the distance of that gap
        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    /**
     * Sets the active field once our physicist is being displayed.
     *
     * @param field Active game field
     */
    public void setField(Field field) {
        this.field = field;
    }

    /**
     * Take the current apple away from the physicist. Returns the apple for
     * use in animating on the field. Note that if there is no current apple being
     * aimed, null is returned.
     *
     * @return the current apple (if any) being aimed
     */
    public Apple takeApple() {
        Apple myApple = aimingApple;
        aimingApple = null;
        return myApple;
    }

    /**
     * Get a new apple ready if we need one. Do not discard an existing apple.
     */
    public void getNewApple() {
        // Don't drop the current apple if we already have one!
        if (aimingApple == null) {
            aimingApple = new Apple(this);
        }
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our physicist is the right color, then draw the semi-circle and box
        g.setColor(color);
        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);
        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);

        // Do we have an apple to draw as well?
        if (aimingApple != null) {
            // Yes. Position the center of the apple on the edge of our semi-circle.
            // Use the current aimingAngle to determine where on the edge.
            double angleInRadians = Math.toRadians(aimingAngle);
            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;
            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);
            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);
            aimingApple.setPosition(aimingX, aimingY);
            aimingApple.draw(g);
        }
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("New Apple")) {
            getNewApple();
            if (field != null) {
                field.repaint();
            }
        }
    }
}


================================================
FILE: ch09/game/Tree.java
================================================
package ch09.game;

import java.awt.*;

/**
 * An obstacle for our game. Trees includ a simple circle and rectangle shape.
 * They are built using sizes determined by the constants in the Field class.
 */
public class Tree implements GamePiece {
    int x, y;

    // Drawing helpers
    private Color leafColor = Color.GREEN.darker();
    private Color trunkColor = new Color(101, 67, 33);
    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
    private int trunkX, trunkY;

    // Boundary helpers
    private Rectangle boundingBox;

    @Override
    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
    }

    @Override
    public int getPositionX() {
        return x;
    }

    @Override
    public int getPositionY() {
        return y;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        g.setColor(trunkColor);
        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
        g.setColor(leafColor);
        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }
}


================================================
FILE: ch10/ActionDemo1.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * A simple, classic demonstration of event handling. Create a frame
 * with a button and a label. As the button is pressed, a counter
 * shown in the label is incremented.
 */
public class ActionDemo1 extends JFrame implements ActionListener {
    int counterValue = 0;
    JLabel counterLabel;

    public ActionDemo1() {
        super( "ActionEvent Counter Demo" );
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());
        setSize( 300, 180 );

        counterLabel = new JLabel("Count: 0", JLabel.CENTER );
        add(counterLabel);

        JButton incrementer = new JButton("Increment");
        incrementer.addActionListener(this);
        add(incrementer);
    }

    public void actionPerformed(ActionEvent e) {
        counterValue++;
        counterLabel.setText("Count: " + counterValue);
    }

    public static void main( String[] args ) {
        ActionDemo1 demo = new ActionDemo1();
        demo.setVisible(true);
    }
}


================================================
FILE: ch10/ActionDemo2.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * A simple, classic demonstration of event handling. Create a frame
 * with a button and a label. As the button is pressed, a counter
 * shown in the label is incremented.
 *
 * This second variation uses a separate class to handle the action
 * events rather than implementing the ActionListener interface
 * directly as in ActionDemo1.
 */
public class ActionDemo2 {
    public static void main( String[] args ) {
        JFrame frame = new JFrame( "ActionListener Demo" );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.setSize( 300, 180 );

        JLabel label = new JLabel("Results go here", JLabel.CENTER );
        ActionCommandHelper helper = new ActionCommandHelper(label);

        JButton simpleButton = new JButton("Button");
        simpleButton.addActionListener(helper);

        JTextField simpleField = new JTextField(10);
        simpleField.addActionListener(helper);

        frame.add(simpleButton);
        frame.add(simpleField);
        frame.add(label);

        frame.setVisible( true );
    }
}

/**
 * Helper class to show the command property of any ActionEvent in a given label.
 */
class ActionCommandHelper implements ActionListener {
    JLabel resultLabel;

    public ActionCommandHelper(JLabel label) {
        resultLabel = label;
    }

    public void actionPerformed(ActionEvent ae) {
        resultLabel.setText(ae.getActionCommand());
    }
}

================================================
FILE: ch10/BorderLayoutDemo.java
================================================
package ch10;

import java.awt.*;
import javax.swing.*;

/**
 * A basic demonstration of the BorderLayout with higlighted
 * areas in different colors.
 */
public class BorderLayoutDemo {
    public static void main( String[] args ) {
        JFrame frame = new JFrame("BorderLayout Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 200);

        JLabel northLabel = new JLabel("Top - North", JLabel.CENTER);
        JLabel southLabel = new JLabel("Bottom - South", JLabel.CENTER);
        JLabel eastLabel = new JLabel("Right - East", JLabel.CENTER);
        JLabel westLabel = new JLabel("Left - West", JLabel.CENTER);
        JLabel centerLabel = new JLabel("Center (everything else)", JLabel.CENTER);

        // Color the labels so we can see their boundaries better
        northLabel.setOpaque(true);
        northLabel.setBackground(Color.GREEN);
        southLabel.setOpaque(true);
        southLabel.setBackground(Color.GREEN);
        eastLabel.setOpaque(true);
        eastLabel.setBackground(Color.RED);
        westLabel.setOpaque(true);
        westLabel.setBackground(Color.RED);
        centerLabel.setOpaque(true);
        centerLabel.setBackground(Color.YELLOW);

        frame.add(northLabel, BorderLayout.NORTH);
        frame.add(southLabel, BorderLayout.SOUTH);
        frame.add(eastLabel, BorderLayout.EAST);
        frame.add(westLabel, BorderLayout.WEST);
        frame.add(centerLabel, BorderLayout.CENTER);

        frame.setVisible(true);
    }
}


================================================
FILE: ch10/Buttons.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;

/**
 * A very simple button placed on a frame. This button is
 * not connected to any listener so it will "press" when
 * clicked but action is taken in response.
 */
public class Buttons {
    public static void main( String[] args ) {
        JFrame frame = new JFrame( "JButton Examples" );
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize( 300, 200 );

        JButton basic = new JButton("Try me!");
        frame.add(basic);

        frame.setVisible( true );
    }
}


================================================
FILE: ch10/HelloJavaAgain.java
================================================
package ch10;

import javax.swing.*;

/**
 * A simple label placed on a frame.
 */
public class HelloJavaAgain {
    public static void main( String[] args ) {
        JFrame frame = new JFrame( "Hello, Java!" );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize( 300, 300 );

        JLabel label = new JLabel("Hello, Java!", JLabel.CENTER );
        frame.add(label);

        frame.setVisible( true );
    }
}


================================================
FILE: ch10/HelloMouse.java
================================================
package ch10;

import java.awt.*;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**
 * A quick demo of how mouse events work. Clicking around the
 * frame will move the label.
 *
 * Note that "mouse" events are the up, down, and click actions
 * of mouse buttons. If you want to catch the mouse moving or dragging,
 * those are handled by the MouseMotionListener interface.
 */
public class HelloMouse extends JFrame implements MouseListener {
    JLabel label;

    public HelloMouse() {
        super("MouseEvent Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);
        setSize( 300, 100 );

        label = new JLabel("Hello, Mouse!", JLabel.CENTER );
        label.setOpaque(true);
        label.setBackground(Color.YELLOW);
        label.setSize(100,20);
        label.setLocation(100,100);
        add(label);

        getContentPane().addMouseListener(this);
    }

    public void mouseClicked(MouseEvent e) {
        label.setLocation(e.getX(), e.getY());
    }

    public void mousePressed(MouseEvent e) { }
    public void mouseReleased(MouseEvent e) { }
    public void mouseEntered(MouseEvent e) { }
    public void mouseExited(MouseEvent e) { }

    public static void main( String[] args ) {
        HelloMouse frame = new HelloMouse();
        frame.setVisible( true );
    }
}


================================================
FILE: ch10/HelloMouseHelper.java
================================================
package ch10;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

/**
 * A variation on HelloMouse with a separate class implementing
 * the mouse event handler. Note that we have to pass a reference
 * to the label we wish to affect when creating the event
 * helper.
 */
public class HelloMouseHelper {
    public static void main( String[] args ) {
        JFrame frame = new JFrame( "MouseAdapter Demo" );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);
        frame.setSize( 300, 300 );

        JLabel label = new JLabel("Hello, Mouse!", JLabel.CENTER );
        label.setOpaque(true);
        label.setBackground(Color.YELLOW);
        label.setSize(100,20);
        label.setLocation(100,100);
        frame.add(label);

        LabelMover mover = new LabelMover(label);
        frame.getContentPane().addMouseListener(mover);
        frame.setVisible( true );
    }
}

/**
 * Helper class to move a label to the position of a mouse click.
 */
class LabelMover extends MouseAdapter {
    JLabel labelToMove;

    public LabelMover(JLabel label) {
        labelToMove = label;
    }

    public void mouseClicked(MouseEvent e) {
        labelToMove.setLocation(e.getX(), e.getY());
    }
}


================================================
FILE: ch10/Labels.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;

/**
 * A simple demo of several label options with variations
 * on color, alignment, and icons.
 */
public class Labels {

    // To make this simple example run from inside an IDE like IntelliJ IDEA,
    // set this path to match where you unzipped the book's projects.
    static final String PROJECT_PATH = "/Users/work/LearningJava5e";

    public static void main( String[] args ) {
        JFrame frame = new JFrame( "JLabel Examples" );
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize( 300, 300 );

        JLabel basic = new JLabel("Default Label");
        basic.setOpaque(true);
        basic.setBackground(Color.YELLOW);
        JLabel another = new JLabel("Another Label");
        another.setOpaque(true);
        another.setBackground(Color.GREEN);
        JLabel simple = new JLabel("A Simple Label");
        simple.setOpaque(true);
        simple.setBackground(Color.WHITE);
        JLabel standard = new JLabel("A Standard Label");
        standard.setOpaque(true);
        standard.setBackground(Color.ORANGE);
        JLabel centered = new JLabel("Centered Text", JLabel.CENTER);
        centered.setPreferredSize(new Dimension(150, 24));
        centered.setOpaque(true);
        centered.setBackground(Color.WHITE);
        JLabel times = new JLabel("Times Roman");
        times.setOpaque(true);
        times.setBackground(Color.WHITE);
        times.setFont(new Font("TimesRoman", Font.BOLD, 18));
        JLabel styled = new JLabel("<html>Some <b><i>styling</i></b> is also allowed</html>");
        styled.setOpaque(true);
        styled.setBackground(Color.WHITE);
        JLabel icon = new JLabel("Verified", new ImageIcon(PROJECT_PATH + "/ch10/check.png"), JLabel.LEFT);
        icon.setOpaque(true);
        icon.setBackground(Color.WHITE);

        frame.add(basic);
        frame.add(another);
        frame.add(simple);
        frame.add(standard);
        frame.add(centered);
        frame.add(times);
        frame.add(styled);
        frame.add(icon);

        frame.setVisible( true );
    }
}


================================================
FILE: ch10/MenuDemo.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * Basic demonstration of creating menus and catching events
 * from selected menu items.
 */
public class MenuDemo extends JFrame implements ActionListener {
    JLabel resultsLabel;

    public MenuDemo() {
        super( "JMenu Demo" );
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());
        setSize( 300, 180 );

        resultsLabel = new JLabel("Click a menu item!" );
        add(resultsLabel);

        // Now let's create a couple menus and populate them
        JMenu fileMenu = new JMenu("File");
        JMenuItem saveItem = new JMenuItem("Save");
        saveItem.addActionListener(this);
        fileMenu.add(saveItem);
        JMenuItem quitItem = new JMenuItem("Quit");
        quitItem.addActionListener(this);
        fileMenu.add(quitItem);

        JMenu editMenu = new JMenu("Edit");
        JMenuItem cutItem = new JMenuItem("Cut");
        cutItem.addActionListener(this);
        editMenu.add(cutItem);
        JMenuItem copyItem = new JMenuItem("Copy");
        copyItem.addActionListener(this);
        editMenu.add(copyItem);
        JMenuItem pasteItem = new JMenuItem("Paste");
        pasteItem.addActionListener(this);
        editMenu.add(pasteItem);

        // And finally build a JMenuBar for the application
        JMenuBar mainBar = new JMenuBar();
        mainBar.add(fileMenu);
        mainBar.add(editMenu);
        setJMenuBar(mainBar);
    }

    public void actionPerformed(ActionEvent event) {
        resultsLabel.setText("Menu selected: " + event.getActionCommand());
    }

    public static void main(String args[]) {
        MenuDemo demo = new MenuDemo();
        demo.setVisible(true);
    }
}


================================================
FILE: ch10/ModalDemo.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * A demonstration of showing modal dialogs. Pressing
 * the Go button will popup a new window which must be
 * dismissed before interacting with the main application again.
 */
public class ModalDemo extends JFrame implements ActionListener {

    JLabel modalLabel;

    public ModalDemo() {
        super( "Modal Dialog Demo" );
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());
        setSize( 300, 180 );

        modalLabel = new JLabel("Press 'Go' to show the popup!", JLabel.CENTER );
        add(modalLabel);

        JButton goButton = new JButton("Go");
        goButton.addActionListener(this);
        add(goButton);
    }

    public void actionPerformed(ActionEvent ae) {
        JOptionPane.showMessageDialog(this, "We're going!", "Alert", JOptionPane.INFORMATION_MESSAGE);
        modalLabel.setText("Go pressed! Press again if you like.");
    }

    public static void main(String args[]) {
        ModalDemo demo = new ModalDemo();
        demo.setVisible(true);
    }
}


================================================
FILE: ch10/NestedPanelDemo.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;

/**
 * An alternate way to arrange complex UIs. Rather than
 * use more flexible (but complicated) layout managers,
 * you can nest containers each with simpler managers.
 */
public class NestedPanelDemo {
    public static void main( String[] args ) {
        JFrame frame = new JFrame("Nested Panel Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 200);

        // Create the text area and go ahead and add it to the center
        JTextArea messageArea = new JTextArea();
        frame.add(messageArea, BorderLayout.CENTER);

        // Create the button container
        //JPanel buttonPanel = new JPanel(new FlowLayout());
        JPanel buttonPanel = new JPanel(new GridLayout(1,0));

        // Create the buttons
        JButton sendButton = new JButton("Send");
        JButton saveButton = new JButton("Save");
        JButton resetButton = new JButton("Reset");
        JButton cancelButton = new JButton("Cancel");

        // Add the buttons to their container
        buttonPanel.add(sendButton);
        buttonPanel.add(saveButton);
        buttonPanel.add(resetButton);
        buttonPanel.add(cancelButton);

        // And finally, add the button container to the bottom of the app
        frame.add(buttonPanel, BorderLayout.SOUTH);

        frame.setVisible(true);
    }
}


================================================
FILE: ch10/PhoneGridDemo.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;

/**
 * Demo of the GridLayout manager used to create a
 * dial pad like you might find on a phone.
 */
public class PhoneGridDemo {
    public static void main( String[] args ) {
        JFrame frame = new JFrame("Nested Panel Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(200, 300);

        // Create the phone pad container
        JPanel phonePad = new JPanel(new GridLayout(4,3));

        // Create and add the 12 buttons, top-left to bottom-right
        phonePad.add(new JButton("1"));
        phonePad.add(new JButton("2"));
        phonePad.add(new JButton("3"));

        phonePad.add(new JButton("4"));
        phonePad.add(new JButton("5"));
        phonePad.add(new JButton("6"));

        phonePad.add(new JButton("7"));
        phonePad.add(new JButton("8"));
        phonePad.add(new JButton("9"));

        phonePad.add(new JButton("*"));
        phonePad.add(new JButton("0"));
        phonePad.add(new JButton("#"));

        // And finally, add the pad to the center of the app
        frame.add(phonePad, BorderLayout.CENTER);

        frame.setVisible(true);
    }
}


================================================
FILE: ch10/ProgressDemo.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * A multithreaded example showing how to safely update Swing components
 * from a background thread. The ProgressPretender class below slowly
 * counts up to 100 and keeps a JLabel updated with the current value.
 */
public class ProgressDemo {
    public static void main( String[] args ) {
        JFrame frame = new JFrame( "SwingUtilities 'invoke' Demo" );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.setSize( 300, 180 );

        JLabel label = new JLabel("Download Progress Goes Here!", JLabel.CENTER );
        Thread pretender = new Thread(new ProgressPretender(label));

        JButton simpleButton = new JButton("Start");
        simpleButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                simpleButton.setEnabled(false);
                pretender.start();
            }
        });

        JLabel checkLabel = new JLabel("Can you still type?");
        JTextField checkField = new JTextField(10);

        frame.add(label);
        frame.add(simpleButton);
        frame.add(checkLabel);
        frame.add(checkField);
        frame.setVisible( true );
    }
}

/**
 * Simulated worker that updates a provided JLabel
 * with the work "progress". In this simulation, we just
 * count from 0 to 100 with a one-second delay between
 * each step.
 */
class ProgressPretender implements Runnable {
    JLabel label;
    int progress;

    public ProgressPretender(JLabel label) {
        this.label = label;
        progress = 0;
    }

    public void run() {
        while (progress <= 100) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    label.setText(progress + "%");
                }
            });
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {
                System.err.println("Someone interrupted us. Skipping download.");
                break;
            }
            progress++;
        }
    }
}


================================================
FILE: ch10/TextInputs.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;

/**
 * Some example text inputs including a text area embedded in a
 * JScrollPane.
 */
public class TextInputs {
    public static void main( String[] args ) {
        JFrame frame = new JFrame( "JTextField Examples" );
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize( 400, 300 );

        JLabel nameLabel = new JLabel("Name:");
        JTextField nameField = new JTextField(10);
        JLabel emailLabel = new JLabel("Email:");
        JTextField emailField = new JTextField(24);

        JLabel bodyLabel = new JLabel("Body:");
        JTextArea bodyArea = new JTextArea(10,30);
        bodyArea.setLineWrap(true);
        bodyArea.setWrapStyleWord(true);
        JScrollPane bodyScroller = new JScrollPane(bodyArea);
        bodyScroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        bodyScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        frame.add(nameLabel);
        frame.add(nameField);
        frame.add(emailLabel);
        frame.add(emailField);
        frame.add(bodyLabel);
        frame.add(bodyScroller);

        frame.setVisible( true );
    }
}


================================================
FILE: ch10/Widget.java
================================================
package ch10;

import javax.swing.*;
import java.awt.*;

/**
 * A helper class aimed at making it easier to try out
 * the many Swing components in jshell. A small frame will
 * show up once the Widget class is imported into jshell
 * and a new instance is created. Be sure to keep a variable
 * for the new object!
 *
 * <pre>
 * jshell> import javax.swing.*
 *
 * jshell> import ch10.Widget
 * 
 * jshell> Widget w = new Widget("My demo widget")
 * w ==> ch10.Widget[frame0,0,23,300x300,layout=java.awt.B ... tPaneCheckingEnabled=true]
 * 
 * jshell> w.add(new JLabel("Hi"))
 * $5 ==> javax.swing.JLabel[,0,0,0x0,invalid,alignmentX=0 ... rticalTextPosition=CENTER]
 * </pre>
 */
public class Widget extends JFrame {

    public Widget() {
        this("jshell GUI Widget");
    }

    public Widget(String title) {
        super(title);
        setLayout(new FlowLayout());
        setSize(300,300);
        setVisible(true);
    }

    @Override
    public Component add(Component comp) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                getContentPane().add(comp);
                getContentPane().doLayout();
            }
        });
        return comp;
    }

    @Override
    public void remove(Component comp) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                getContentPane().remove(comp);
                getContentPane().doLayout();
                getContentPane().repaint();
            }
        });
    }

    public void reset() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                getContentPane().removeAll();
                getContentPane().doLayout();
                getContentPane().repaint();
            }
        });
    }
}


================================================
FILE: ch10/game/Apple.java
================================================
package ch10.game;

import java.awt.*;

/**
 * Apple
 *
 * This class sums up everything we know about the apples our physicists will be lobbing.
 * We keep the size and weight details and provide a few simple methods for lobbing. We
 * also provide animation helpers for use with the PlayingField class.
 */
public class Apple implements GamePiece {
    public static final int SMALL  = 0;
    public static final int MEDIUM = 1;
    public static final int LARGE  = 2;

    int size;
    double diameter;
    double mass;
    int centerX, centerY;
    Physicist myPhysicist;

    // In game play, apples can be thrown so track their velocities
    long lastStep;
    float velocityX, velocityY;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;
    int scaledLength;

    // Boundary helper for optimizing collision detection with physicists and trees
    Rectangle boundingBox;

    // If we bumped into something, keep a reference to that thing around for cleanup and removal
    GamePiece collided;

    /**
     * Create a default, Medium apple
     */
    public Apple(Physicist owner) {
        this(owner, MEDIUM);
    }

    /**
     * Create an Apple of the given size
     */
    public Apple(Physicist owner, int size) {
        myPhysicist = owner;
        setSize(size);
    }

    /**
     * Sets the size (and dependent properties) of the apple based on the
     * supplied value which must be one of the size constants.
     *
     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE
     */
    public void setSize(int size) {
        if (size < SMALL) {
            size = SMALL;
        }
        if (size > LARGE) {
            size = LARGE;
        }
        this.size = size;
        switch (size) {
            case SMALL:
                diameter = 0.9;
                mass = 0.5;
                break;
            case MEDIUM:
                diameter = 1.0;
                mass = 1.0;
                break;
            case LARGE:
                diameter = 1.1;
                mass = 1.8;
                break;
        }
        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.
        // Since we want a circle, we simply make our box a square so we only need one length.
        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    public double getDiameter() {
        return diameter;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of the apple, but it will be drawn from the
        // upper left corner, so figure out the distance of that gap
        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our apple will be red, then paint it!
        g.setColor(Color.RED);
        g.fillOval(x, y, scaledLength, scaledLength);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {
            // By definition we don't collide with ourselves, our physicist, or with more than one other piece
            return false;
        }
        if (otherPiece instanceof Apple) {
            // The other piece is an apple, so we can do a simple distance calculation using
            // the diameters of both apples.
            Apple otherApple = (Apple) otherPiece;
            int v = this.y - otherPiece.getPositionY(); // vertical difference
            int h = this.x - otherPiece.getPositionX(); // horizontal difference
            double distance = Math.sqrt(v * v + h * h);

            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;
            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;
            if (distance < (myRadius + otherRadius)) {
                // Since apples track collisions, we'll update the other apple to keep everyone in sync
                setCollided(otherPiece);
                otherApple.setCollided(this);
                return true;
            }
            return false;
        }
        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {
            setCollided(otherPiece);
            return true;
        }
        return false;
    }

    public GamePiece getCollidedPiece() {
        return collided;
    }

    public void setCollided(GamePiece otherPiece) {
        this.collided = otherPiece;
    }

    public void toss(float angle, float velocity) {
        lastStep = System.currentTimeMillis();
        double radians = angle / 180 * Math.PI;
        velocityX = (float)(velocity * Math.cos(radians) / mass);
        // Start with negative velocity since "up" means smaller values of y
        velocityY = (float)(-velocity * Math.sin(radians) / mass);
    }

    public void step() {
        // Make sure we're moving at all using our lastStep tracker as a sentinel
        if (lastStep > 0) {
            // let's apply our gravity
            long now = System.currentTimeMillis();
            float slice = (now - lastStep) / 1000.0f;
            velocityY = velocityY + (slice * Field.GRAVITY);
            int newX = (int)(centerX + velocityX);
            int newY = (int)(centerY + velocityY);
            setPosition(newX, newY);
        }
    }
}


================================================
FILE: ch10/game/AppleToss.java
================================================
package ch10.game;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;

/**
 * Our apple tossing game. This class extends JFrame to create our
 * main application window. With the new Swing components discussed
 * in this chapter, we can now make a fully functioning physicist
 * who can aim and toss apples.
 */
public class AppleToss extends JFrame {
    public static final int SCORE_HEIGHT = 30;
    public static final int CONTROL_WIDTH = 300;
    public static final int CONTROL_HEIGHT = 40;
    public static final int FIELD_WIDTH = 3 * CONTROL_WIDTH;
    public static final int FIELD_HEIGHT = 2 * CONTROL_WIDTH;
    public static final float FORCE_SCALE = 0.7f;

    GridBagLayout gameLayout = new GridBagLayout();
    GridBagConstraints gameConstraints = new GridBagConstraints();
    JPanel gamePane = new JPanel(gameLayout);

    Field field = new Field();
    Physicist player1 = new Physicist();
    ArrayList<Physicist> otherPlayers = new ArrayList<>();

    Random random = new Random();

    public AppleToss() {
        // Create our frame
        super("Apple Toss Game");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        // Build the field with our player and some trees
        setupFieldForOnePlayer();

        // Setup the grid we'll use to layout our various components
        gameLayout.columnWidths = new int[] { CONTROL_WIDTH, CONTROL_WIDTH, CONTROL_WIDTH };
        gameLayout.rowHeights = new int[] { SCORE_HEIGHT, FIELD_HEIGHT, CONTROL_HEIGHT, CONTROL_HEIGHT };

        // Now build and add those components at the desired position
        JLabel player1score = new JLabel(" Player 1: 0");
        field.scoreLabels[1] = player1score;
        gamePane.add(player1score, buildConstraints(0, 0, 1, 1));
        gamePane.add(buildRestartButton(), buildConstraints(0, 2, 1, 1));
        gamePane.add(field, buildConstraints(1, 0, 1, 3));
        gamePane.add(buildAngleControl(), buildConstraints(2, 0, 1, 1));
        gamePane.add(buildForceControl(), buildConstraints(2, 1, 1, 1));
        gamePane.add(buildTossButton(), buildConstraints(2, 2, 2, 1));
        gamePane.add(new JLabel("Angle", JLabel.CENTER), buildConstraints(3, 0, 1, 1));
        gamePane.add(new JLabel("Force", JLabel.CENTER), buildConstraints(3, 1, 1, 1));

        // replace the frame's content with our game
        setContentPane(gamePane);

        // And set the correct size + a buffer for any OS frame title
        setSize(FIELD_WIDTH,SCORE_HEIGHT + FIELD_HEIGHT + (2 * CONTROL_HEIGHT) + 20);
    }

    private GridBagConstraints buildConstraints(int row, int col, int rowspan, int colspan) {
        gameConstraints.fill = GridBagConstraints.BOTH;
        gameConstraints.gridy = row;
        gameConstraints.gridx = col;
        gameConstraints.gridheight = rowspan;
        gameConstraints.gridwidth = colspan;
        return gameConstraints;
    }

    private JButton buildRestartButton() {
        JButton button = new JButton("Play Again");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setupFieldForOnePlayer();
                field.repaint();
            }
        });
        return button;
    }

    private JSlider buildAngleControl() {
        JSlider slider = new JSlider(0,180);
        slider.setInverted(true);
        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                player1.setAimingAngle((float)slider.getValue());
                field.repaint();
            }
        });
        return slider;
    }

    private JSlider buildForceControl() {
        JSlider slider = new JSlider();
        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                player1.setAimingForce(slider.getValue() * FORCE_SCALE);
            }
        });
        return slider;
    }

    private JButton buildTossButton() {
        JButton button = new JButton("Toss");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                field.startTossFromPlayer(player1);
            }
        });
        return button;
    }

    /**
     * Helper method to return a good x value for a tree so it's not off the left or right edge.
     *
     * @return x value within the bounds of the playing field width
     */
    private int goodX() {
        // at least half the width of the tree plus a few pixels
        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // now find a random number between a left and right margin
        int rightMargin = FIELD_WIDTH - leftMargin;

        // And return a random number starting at the left margin
        return leftMargin + random.nextInt(rightMargin - leftMargin);
    }

    /**
     * Helper method to return a good y value for a tree so it's not off the top or bottom of the screen.
     *
     * @return y value within the bounds of the playing field height
     */
    private int goodY() {
        // at least half the height of the "leaves" plus a few pixels
        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // a little higher off the bottom
        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;

        // And return a random number starting at the top margin but not past the bottom
        return topMargin + random.nextInt(bottomMargin - topMargin);
    }

    /**
     * A helper method to populate a one player field with target trees.
     */
    private void setupFieldForOnePlayer() {
        // place our (new) physicist in the lower left corner
        if (field.physicists.size() == 0) {
            player1.setPosition(Field.PHYSICIST_SIZE_IN_PIXELS, FIELD_HEIGHT - (int) (Field.PHYSICIST_SIZE_IN_PIXELS * 1.5));
            field.physicists.add(player1);
            player1.setField(field);
        }
		// Reset the score for our sole player
		field.resetScore(1);

        // Create some trees for target practice
        for (int i = field.trees.size(); i < 10; i++) {
            Tree t = new Tree();
            t.setPosition(goodX(), goodY());
            // Trees can be close to each other and overlap, but they shouldn't intersect our physicist
            while(player1.isTouching(t)) {
                // We do intersect this tree, so let's try again
                t.setPosition(goodX(), goodY());
                System.err.println("Repositioning an intersecting tree...");
            }
            field.trees.add(t);
        }
    }

    public static void main(String args[]) {
        AppleToss game = new AppleToss();
        game.setVisible(true);
    }
}


================================================
FILE: ch10/game/Field.java
================================================
package ch10.game;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * The playing field for our game. Now we can setup some constants for
 * other game classes to use and create member variables for our player and some trees.
 */
public class Field extends JComponent implements ActionListener {
    public static final float GRAVITY = 9.8f;  // feet per second per second
    public static final int STEP = 40;   // duration of an animation frame in milliseconds
    public static final int APPLE_SIZE_IN_PIXELS = 30;
    public static final int TREE_WIDTH_IN_PIXELS = 60;
    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;

    public static final int MAX_PHYSICISTS = 5;
    public static final int MAX_APPLES_PER_PHYSICIST = 3;
    public static final int MAX_TREES = 12;

    Color fieldColor = Color.GRAY;

	// Keep track of our own score and also make room for multiple players
    int myScore = 0;
    String[] scores = new String[3];
    JLabel[] scoreLabels = new JLabel[3];
	
    List<Physicist> physicists = Collections.synchronizedList(new ArrayList<>());
    List<Apple> apples = Collections.synchronizedList(new ArrayList<>());
    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());

    boolean animating = false;
    Thread animationThread;
    Timer animationTimer;

    protected void paintComponent(Graphics g) {
        g.setColor(fieldColor);
        g.fillRect(0,0, getWidth(), getHeight());
        for (Physicist p : physicists) {
            p.draw(g);
        }
        for (Tree t : trees) {
            t.draw(g);
        }
        for (Apple a : apples) {
            a.draw(g);
        }
    }

    public void actionPerformed(ActionEvent event) {
        if (animating && event.getActionCommand().equals("repaint")) {
            System.out.println("Timer stepping " + apples.size() + " apples");
            for (Apple a : apples) {
                a.step();
                detectCollisions(a);
            }
            repaint();
            cullFallenApples();
        }
    }

    /**
     * Toss an apple from the given physicist using that physicist's aim and force.
     * Make sure the field is in the animating state.
     *
     * @param physicist the player whose apple should be tossed
     */
    public void startTossFromPlayer(Physicist physicist) {
        if (!animating) {
            System.out.println("Starting animation!");
            animating = true;
            startAnimation();
        }
        if (animating) {
            // Check to make sure we have an apple to toss
            if (physicist.aimingApple != null) {
                Apple apple = physicist.takeApple();
                apple.toss(physicist.aimingAngle, physicist.aimingForce);
                apples.add(apple);
                Timer appleLoader = new Timer(800, physicist);
                appleLoader.setActionCommand("New Apple");
                appleLoader.setRepeats(false);
                appleLoader.start();
            }
        }
    }

    void cullFallenApples() {
        Iterator<Apple> iterator = apples.iterator();
        while (iterator.hasNext()) {
            Apple a = iterator.next();
            if (a.getCollidedPiece() != null) {
                GamePiece otherPiece = a.getCollidedPiece();
                if (otherPiece instanceof Physicist) {
                    hitPhysicist((Physicist) otherPiece);
                } else if (otherPiece instanceof Tree) {
                    hitTree((Tree) otherPiece);
                }
                // Remove ourselves. If the other piece we hit was an apple, leave it alone.
                // It will be removed when the iterator comes to it.
                iterator.remove();
            } else if (a.getPositionY() > 600) {
                System.out.println("Culling apple");
                iterator.remove();
            }
        }
        if (apples.size() <= 0) {
            animating = false;
            if (animationTimer != null && animationTimer.isRunning()) {
                animationTimer.stop();
            }
        }
    }

    void detectCollisions(Apple apple) {
        // Check for other apples
        for (Apple a : apples) {
            if (apple.isTouching(a)) {
                System.out.println("Touching another apple!");
                return;
            }
        }
        // Check for physicists
        for (Physicist p : physicists) {
            if (apple.isTouching(p)) {
                System.out.println("Touching a physicist!");
                return;
            }
        }
        // Check for trees
        for (Tree t : trees) {
            if (apple.isTouching(t)) {
                System.out.println("Touching a tree!");
                return;
            }
        }
    }

    void hitPhysicist(Physicist physicist) {
        // do any scoring or notifications here
        physicists.remove(physicist);
    }

    void hitTree(Tree tree) {
        // do any scoring or notifications here
        myScore += 10;
        trees.remove(tree);
        setScore(1, String.valueOf(myScore));
    }

    public void resetScore(int playerNumber) {
		myScore = 0;
		setScore(playerNumber, "0");
    }

    public String getScore(int playerNumber) {
        return scores[playerNumber];
    }

    public void setScore(int playerNumber, String score) {
        scores[playerNumber] = score;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                String newScore = " Player " + playerNumber + ": " + score;
                scoreLabels[playerNumber].setText(newScore);
            }
        });
    }

    void startAnimation() {
        // Animator myAnimator = new Animator();
        // animationThread = new Thread(myAnimator);
        // animationThread.start();
        if (animationTimer == null) {
            animationTimer = new Timer(STEP, this);
            animationTimer.setActionCommand("repaint");
            animationTimer.setRepeats(true);
            animationTimer.start();
        } else if (!animationTimer.isRunning()) {
            animationTimer.restart();
        }
    }

    class Animator implements Runnable {
        public void run() {
            while (animating) {
                System.out.println("Stepping " + apples.size() + " apples");
                for (Apple a : apples) {
                    a.step();
                    detectCollisions(a);
                }
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        Field.this.repaint();
                    }
                });
                cullFallenApples();
                try {
                    Thread.sleep((int)(STEP * 1000));
                } catch (InterruptedException ie) {
                    System.err.println("Animation interrupted");
                    animating = false;
                }
            }
        }
    }
}


================================================
FILE: ch10/game/GamePiece.java
================================================
package ch10.game;

import java.awt.*;

/**
 * Interface to hold common elements for our apples, trees, and physicists
 * From the README:
 * GamePiece
 *   - methods for positioning on a PlayingField
 *   - methods for Drawing
 *   - methods for detecting a collision with other GamePieces
 */
public interface GamePiece {
    /**
     * Sets the position of the piece on the playing field.
     * (0,0) is the upper left per standard Java drawing methods.
     *
     * @param x
     * @param y
     */
    void setPosition(int x, int y);

    /**
     * Gets the current horizontal position of the piece on the field.
     *
     * @return current X position of the piece
     */
    int getPositionX();

    /**
     * Gets the current vertical position of the piece on the field.
     *
     * @return current Y position of the piece
     */
    int getPositionY();

    /**
     * Gets the bounding box of this piece.
     *
     * @return a Rectangle encompassing the visual elements of the piece
     */
    Rectangle getBoundingBox();

    /**
     * Draws the piece inside the given graphics context.
     * Do not assume anything about the state of the context.
     *
     * @param g
     */
    void draw(Graphics g);

    /**
     * Detect a collision with another piece on the field.
     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
     *
     * @param otherPiece
     * @return
     */
    boolean isTouching(GamePiece otherPiece);
}


================================================
FILE: ch10/game/GameUtilities.java
================================================
package ch10.game;

// collision detection between a circle and a rectangle
// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection

import java.awt.*;

/**
 * Utility class with a few helper methods for calculating various collisions and
 * intersections.
 */
public class GameUtilities {
    static boolean isPointInsideBox(int x, int y, Rectangle box) {
        // Our own custom test. We could of course use box.contains(),
        // but we can practice some interesting conditional checking here.
        // Let's test left and right first
        if (x >= box.x && x <= (box.x + box.width)) {
            // Our x coordinate is ok, so check our y
            if (y >= box.y && y <= (box.y + box.height)) {
                return true;
            }
        }
        // x or y was outside the box, so return false
        return false;
    }

    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
        // If any of the four corners of box are inside other, we intersect, so
        // let's check each one. Happily, that answer doesn't change if more
        // than one corner is contained in other, so we can return as soon as
        // we find the first contained corner.

        // Let's get some local copies of the corner coordinates
        // to make the call arguments easier to read.
        int x1 = box.x;
        int y1 = box.y;
        int x2 = x1 + box.width;
        int y2 = y1 + box.height;
        if (isPointInsideBox(x1, y1, other)) {
            // upper left
            return true;
        } else if (isPointInsideBox(x1, y2, other)) {
            // lower left
            return true;
        } else if (isPointInsideBox(x2, y1, other)) {
            // upper right
            return true;
        } else if (isPointInsideBox(x2, y2, other)) {
            // lower right
            return true;
        }
        // No box points in other so no intersection
        return false;
    }

    /**
     * Given two rectangles, do the overlap at all? This includes one box being
     * completely contained by the other box.
     *
     * @param box1 a box to test, order does not matter
     * @param box2 the other box
     * @return true if the boxes overlap, false otherwise
     */
    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {
        // Another custom test. We could of course use box1.intersects(box2)
        // but we can practice method calls and some boolean logic here.
        if (doesBoxIntersect(box1, box2)) {
            // At least one of box1's points must be inside box2
            return true;
        } else if (doesBoxIntersect(box2, box1)) {
            // None of box1's points were in box2, but at least one of box2's points are inside box1
            return true;
        }
        // No intersections in either direction
        return false;
    }
}


================================================
FILE: ch10/game/Physicist.java
================================================
package ch10.game;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static java.awt.Color.*;

/**
 * Our player class. A physicist has an apple that they can throw in addition
 * to implementing the basic methods for GamePiece. We can also set a custom
 * color in case you build on the game and allow multiple physicists to be
 * on the screen at the same time.
 */
public class Physicist implements GamePiece, ActionListener {
    Color color;
    int centerX, centerY;
    Apple aimingApple;
    float aimingAngle;
    float aimingForce;
    Field field;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;

    // Boundary helpers
    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);
    private Rectangle boundingBox;


    /**
     * Create a default, blue physicist
     */
    public Physicist() {
        this(BLUE);
    }

    /**
     * Create a Physicist of the given color
     */
    public Physicist(Color color) {
        setColor(color);
        aimingAngle = 90.0f;
        aimingForce = 50.0f;
        getNewApple();
    }

    public void setAimingAngle(Float angle) {
        aimingAngle = angle;
    }

    public void setAimingForce(Float force) {
        if (force < 0) {
            force = 0.0f;
        }
        aimingForce = force;
    }

    /**
     * Sets the color for the physicist.
     *
     * @param color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of our dome,
        // but it will be drawn from the upper left corner.
        // Figure out the distance of that gap
        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    /**
     * Sets the active field once our physicist is being displayed.
     *
     * @param field Active game field
     */
    public void setField(Field field) {
        this.field = field;
    }

    /**
     * Take the current apple away from the physicist. Returns the apple for
     * use in animating on the field. Note that if there is no current apple being
     * aimed, null is returned.
     *
     * @return the current apple (if any) being aimed
     */
    public Apple takeApple() {
        Apple myApple = aimingApple;
        aimingApple = null;
        return myApple;
    }

    /**
     * Get a new apple ready if we need one. Do not discard an existing apple.
     */
    public void getNewApple() {
        // Don't drop the current apple if we already have one!
        if (aimingApple == null) {
            aimingApple = new Apple(this);
        }
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our physicist is the right color, then draw the semi-circle and box
        g.setColor(color);
        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);
        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);

        // Do we have an apple to draw as well?
        if (aimingApple != null) {
            // Yes. Position the center of the apple on the edge of our semi-circle.
            // Use the current aimingAngle to determine where on the edge.
            double angleInRadians = Math.toRadians(aimingAngle);
            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;
            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);
            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);
            aimingApple.setPosition(aimingX, aimingY);
            aimingApple.draw(g);
        }
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("New Apple")) {
            getNewApple();
            if (field != null) {
                field.repaint();
            }
        }
    }
}


================================================
FILE: ch10/game/Tree.java
================================================
package ch10.game;

import java.awt.*;

/**
 * An obstacle for our game. Trees includ a simple circle and rectangle shape.
 * They are built using sizes determined by the constants in the Field class.
 */
public class Tree implements GamePiece {
    int x, y;

    // Drawing helpers
    private Color leafColor = Color.GREEN.darker();
    private Color trunkColor = new Color(101, 67, 33);
    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
    private int trunkX, trunkY;

    // Boundary helpers
    private Rectangle boundingBox;

    @Override
    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
    }

    @Override
    public int getPositionX() {
        return x;
    }

    @Override
    public int getPositionY() {
        return y;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        g.setColor(trunkColor);
        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
        g.setColor(leafColor);
        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }
}


================================================
FILE: ch11/CopyChannels.java
================================================
package ch11;

import java.io.*;
import java.nio.*;
import java.nio.channels.*;

/**
 * A quick demo of copying files using FileChannels.
 * The names of the source and destination are passed as
 * command line arguments.
 */
public class CopyChannels {
	public static void main( String [] args ) throws Exception {
		String fromFileName = args[0];
		String toFileName = args[1];
		FileChannel in = new FileInputStream( fromFileName ).getChannel();
		FileChannel out = new FileOutputStream( toFileName ).getChannel();
		
		ByteBuffer buff = ByteBuffer.allocate( 32*1024 );

		while ( in.read( buff ) > 0 ) {
			buff.flip();
			out.write( buff );
			buff.clear();
		}

		in.close();
		out.close();
	}
}


================================================
FILE: ch11/CopyChannels2.java
================================================
package ch11;

import java.io.*;
import java.nio.*;
import java.nio.channels.*;

/**
 * A quick demo of copying files using FileChannels.
 * The names of the source and destination are passed as
 * command line arguments.
 */
public class CopyChannels2 {
	public static void main( String [] args ) throws Exception {
		String fromFileName = args[0];
		String toFileName = args[1];
		FileChannel in = new FileInputStream( fromFileName ).getChannel();
		FileChannel out = new FileOutputStream( toFileName ).getChannel();
		
		ByteBuffer buff = ByteBuffer.allocateDirect( 32*1024 );

		while ( in.read( buff ) > 0 ) {
			buff.flip();
			out.write( buff );
			buff.clear();
		}

		in.close();
		out.close();
	}
}


================================================
FILE: ch11/CopyChannels3.java
================================================
package ch11;

import java.io.*;
import java.nio.*;
import java.nio.channels.*;

/**
 * A quick demo of copying files using FileChannels.
 * The names of the source and destination are passed as
 * command line arguments.
 */
public class CopyChannels3 {
	public static void main( String [] args ) throws Exception {
		String fromFileName = args[0];
		String toFileName = args[1];
		FileChannel in = new FileInputStream( fromFileName ).getChannel();
		FileChannel out = new FileOutputStream( toFileName ).getChannel();
		in.transferTo( 0, (int)in.size(), out );
		in.close();
		out.close();
	}
}


================================================
FILE: ch11/CopyFile.java
================================================
package ch11;

import java.nio.channels.*;
import java.nio.file.*;
import static java.nio.file.StandardOpenOption.*;

/**
 * A quick demo of copying files using the FileChannel class.
 * The names of the source and destination are passed as
 * command line arguments.
 */
public class CopyFile {
    public static void main( String [] args ) throws Exception {
        FileSystem fs = FileSystems.getDefault();
        Path fromFile = fs.getPath( args[0] );
        Path toFile = fs.getPath( args[1] );

		// By using the try-with-resources pattern, our channels
		// will automagically be cleaned up when we're done.
        try (
            FileChannel in = FileChannel.open( fromFile );
            FileChannel out = FileChannel.open( toFile, CREATE, WRITE ); )
        {
            in.transferTo( 0, (int)in.size(), out );
        }
    }
}

================================================
FILE: ch11/CopyStreams.java
================================================
package ch11;

import java.io.*;

/**
 * A quick demo of copying files using basic streams.
 * The names of the source and destination are passed as
 * command line arguments.
 */
public class CopyStreams {
	public static void main( String [] args ) throws Exception {
		String fromFileName = args[0];
		String toFileName = args[1];
		BufferedInputStream in = new BufferedInputStream(
			new FileInputStream( fromFileName ) );
		BufferedOutputStream out = new BufferedOutputStream(
			new FileOutputStream( toFileName ) );
		byte [] buff = new byte [ 32*1024 ];
		int len;
		while ( (len = in.read( buff )) > 0 )
			out.write( buff, 0, len );
		in.close();
		out.close();
	}
}


================================================
FILE: ch11/DateAtHost.java
================================================
//file: DateAtHost.java
import java.net.Socket;
import java.io.*;

public class DateAtHost extends java.util.Date {
    static int timePort = 37;
    // seconds from start of 20th century to Jan 1, 1970 00:00 GMT
    static final long offset = 2208988800L;

    public DateAtHost( String host ) throws IOException {
        this( host, timePort );
    }

    public DateAtHost( String host, int port ) throws IOException {
        Socket server = new Socket( host, port );
        DataInputStream din =
          new DataInputStream( server.getInputStream(  ) );
        int time = din.readInt(  );
        server.close(  );

        setTime( (((1L << 32) + time) - offset) * 1000 );
    }
}


================================================
FILE: ch11/ListIt.java
================================================
package ch11;

import java.io.*;

/**
 * A quick demo of file and directory operations. If the file
 * exists and is a directory, the directory gets listed. If it
 * is a readable file, the content is dumped to the console.
 */
public class ListIt {
    public static void main ( String args[] ) throws Exception {
        File file =  new File( args[0] );

        if ( !file.exists() || !file.canRead(  ) ) {
            System.out.println( "Can't read " + file );
            return;
        }

        if ( file.isDirectory(  ) ) {
            String [] files = file.list(  );
            for (int i=0; i< files.length; i++)
                System.out.println( files[i] );
        }
        else
            try {
                Reader ir = new InputStreamReader( new FileInputStream( file ) );
                BufferedReader in = new BufferedReader( ir );
                String line;
                while ((line = in.readLine(  )) != null)
                System.out.println(line);
            }
            catch ( FileNotFoundException e ) {
                System.out.println( "File Disappeared" );
            }
    }
}


================================================
FILE: ch11/game/Apple.java
================================================
package ch11.game;

import java.awt.*;

/**
 * Apple
 *
 * This class sums up everything we know about the apples our physicists will be lobbing.
 * We keep the size and weight details and provide a few simple methods for lobbing. We
 * also provide animation helpers for use with the PlayingField class.
 */
public class Apple implements GamePiece {
    public static final int SMALL  = 0;
    public static final int MEDIUM = 1;
    public static final int LARGE  = 2;

    int size;
    double diameter;
    double mass;
    int centerX, centerY;
    Physicist myPhysicist;

    // In game play, apples can be thrown so track their velocities
    long lastStep;
    float velocityX, velocityY;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;
    int scaledLength;

    // Boundary helper for optimizing collision detection with physicists and trees
    Rectangle boundingBox;

    // If we bumped into something, keep a reference to that thing around for cleanup and removal
    GamePiece collided;

    /**
     * Create a default, Medium apple
     */
    public Apple(Physicist owner) {
        this(owner, MEDIUM);
    }

    /**
     * Create an Apple of the given size
     */
    public Apple(Physicist owner, int size) {
        myPhysicist = owner;
        setSize(size);
    }

    /**
     * Sets the size (and dependent properties) of the apple based on the
     * supplied value which must be one of the size constants.
     *
     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE
     */
    public void setSize(int size) {
        if (size < SMALL) {
            size = SMALL;
        }
        if (size > LARGE) {
            size = LARGE;
        }
        this.size = size;
        switch (size) {
            case SMALL:
                diameter = 0.9;
                mass = 0.5;
                break;
            case MEDIUM:
                diameter = 1.0;
                mass = 1.0;
                break;
            case LARGE:
                diameter = 1.1;
                mass = 1.8;
                break;
        }
        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.
        // Since we want a circle, we simply make our box a square so we only need one length.
        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    public double getDiameter() {
        return diameter;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of the apple, but it will be drawn from the
        // upper left corner, so figure out the distance of that gap
        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our apple will be red, then paint it!
        g.setColor(Color.RED);
        g.fillOval(x, y, scaledLength, scaledLength);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {
            // By definition we don't collide with ourselves, our physicist, or with more than one other piece
            return false;
        }
        if (otherPiece instanceof Apple) {
            // The other piece is an apple, so we can do a simple distance calculation using
            // the diameters of both apples.
            Apple otherApple = (Apple) otherPiece;
            int v = this.y - otherPiece.getPositionY(); // vertical difference
            int h = this.x - otherPiece.getPositionX(); // horizontal difference
            double distance = Math.sqrt(v * v + h * h);

            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;
            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;
            if (distance < (myRadius + otherRadius)) {
                // Since apples track collisions, we'll update the other apple to keep everyone in sync
                setCollided(otherPiece);
                otherApple.setCollided(this);
                return true;
            }
            return false;
        }
        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {
            setCollided(otherPiece);
            return true;
        }
        return false;
    }

    public GamePiece getCollidedPiece() {
        return collided;
    }

    public void setCollided(GamePiece otherPiece) {
        this.collided = otherPiece;
    }

    public void toss(float angle, float velocity) {
        lastStep = System.currentTimeMillis();
        double radians = angle / 180 * Math.PI;
        velocityX = (float)(velocity * Math.cos(radians) / mass);
        // Start with negative velocity since "up" means smaller values of y
        velocityY = (float)(-velocity * Math.sin(radians) / mass);
    }

    public void step() {
        // Make sure we're moving at all using our lastStep tracker as a sentinel
        if (lastStep > 0) {
            // let's apply our gravity
            long now = System.currentTimeMillis();
            float slice = (now - lastStep) / 1000.0f;
            velocityY = velocityY + (slice * Field.GRAVITY);
            int newX = (int)(centerX + velocityX);
            int newY = (int)(centerY + velocityY);
            setPosition(newX, newY);
        }
    }
}


================================================
FILE: ch11/game/AppleToss.java
================================================
package ch11.game;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;

/**
 * Our apple tossing game. This class extends JFrame to create our
 * main application window. We're getting closer to our final
 * version of the game which allows two players to compete in a timed
 * trial to see who can clear the trees fastest.
 */
public class AppleToss extends JFrame {
    public static final int SCORE_HEIGHT = 30;
    public static final int CONTROL_WIDTH = 300;
    public static final int CONTROL_HEIGHT = 40;
    public static final int FIELD_WIDTH = 3 * CONTROL_WIDTH;
    public static final int FIELD_HEIGHT = 2 * CONTROL_WIDTH;
    public static final float FORCE_SCALE = 0.7f;

    GridBagLayout gameLayout = new GridBagLayout();
    GridBagConstraints gameConstraints = new GridBagConstraints();
    JPanel gamePane = new JPanel(gameLayout);

    Field field = new Field();
    Physicist player1 = new Physicist();
    ArrayList<Physicist> otherPlayers = new ArrayList<>();

    Random random = new Random();

    public AppleToss() {
        // Create our frame
        super("Apple Toss Game");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        // Build the field with our player and some trees
        setupFieldForOnePlayer();

        // Setup the grid we'll use to layout our various components
        gameLayout.columnWidths = new int[] { CONTROL_WIDTH, CONTROL_WIDTH, CONTROL_WIDTH };
        gameLayout.rowHeights = new int[] { SCORE_HEIGHT, FIELD_HEIGHT, CONTROL_HEIGHT, CONTROL_HEIGHT };

        // Now build and add those components at the desired position
        gamePane.add(new JLabel(" Player 1: 0"), buildConstraints(0, 0, 1, 1));
        // gamePane.add(new JLabel(" Player 2: 0"), buildConstraints(0, 1, 1, 1));
        gamePane.add(buildRestartButton(), buildConstraints(0, 2, 1, 1));
        gamePane.add(field, buildConstraints(1, 0, 1, 3));
        gamePane.add(buildAngleControl(), buildConstraints(2, 0, 1, 1));
        gamePane.add(buildForceControl(), buildConstraints(2, 1, 1, 1));
        gamePane.add(buildTossButton(), buildConstraints(2, 2, 2, 1));
        gamePane.add(new JLabel("Angle", JLabel.CENTER), buildConstraints(3, 0, 1, 1));
        gamePane.add(new JLabel("Force", JLabel.CENTER), buildConstraints(3, 1, 1, 1));

		// Setup the networking menu (actions are left to the read to implement)
		setupNetworkMenu();
		
        // replace the frame's content with our game
        setContentPane(gamePane);

        // And set the correct size + a buffer for any OS frame title
        setSize(FIELD_WIDTH,SCORE_HEIGHT + FIELD_HEIGHT + (2 * CONTROL_HEIGHT) + 20);
    }

    private GridBagConstraints buildConstraints(int row, int col, int rowspan, int colspan) {
        gameConstraints.fill = GridBagConstraints.BOTH;
        gameConstraints.gridy = row;
        gameConstraints.gridx = col;
        gameConstraints.gridheight = rowspan;
        gameConstraints.gridwidth = colspan;
        return gameConstraints;
    }

    private JButton buildRestartButton() {
        JButton button = new JButton("Play Again");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setupFieldForOnePlayer();
                field.repaint();
            }
        });
        return button;
    }

    private JSlider buildAngleControl() {
        JSlider slider = new JSlider(0,180);
        slider.setInverted(true);
        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                player1.setAimingAngle((float)slider.getValue());
                field.repaint();
            }
        });
        return slider;
    }

    private JSlider buildForceControl() {
        JSlider slider = new JSlider();
        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                player1.setAimingForce(slider.getValue() * FORCE_SCALE);
            }
        });
        return slider;
    }

    private JButton buildTossButton() {
        JButton button = new JButton("Toss");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                field.startTossFromPlayer(player1);
            }
        });
        return button;
    }

    private void setupNetworkMenu() {
        JMenu netMenu = new JMenu("Multiplayer");

        JMenuItem startItem = new JMenuItem("Start Server");
        startItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(AppleToss.this, "Start Server selected",
					"Network Alert", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        netMenu.add(startItem);

        JMenuItem joinItem = new JMenuItem("Join Game...");
        joinItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(AppleToss.this, "Join Game selected",
					"Network Alert", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        netMenu.add(joinItem);

        JMenuItem quitItem = new JMenuItem("Disconnect");
        quitItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(AppleToss.this, "Disconnect selected",
					"Network Alert", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        netMenu.add(quitItem);

        // build a JMenuBar for the application
        JMenuBar mainBar = new JMenuBar();
        mainBar.add(netMenu);
        setJMenuBar(mainBar);
    }

    /**
     * Helper method to return a good x value for a tree so it's not off the left or right edge.
     *
     * @return x value within the bounds of the playing field width
     */
    private int goodX() {
        // at least half the width of the tree plus a few pixels
        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // now find a random number between a left and right margin
        int rightMargin = FIELD_WIDTH - leftMargin;

        // And return a random number starting at the left margin
        return leftMargin + random.nextInt(rightMargin - leftMargin);
    }

    /**
     * Helper method to return a good y value for a tree so it's not off the top or bottom of the screen.
     *
     * @return y value within the bounds of the playing field height
     */
    private int goodY() {
        // at least half the height of the "leaves" plus a few pixels
        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;
        // a little higher off the bottom
        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;

        // And return a random number starting at the top margin but not past the bottom
        return topMargin + random.nextInt(bottomMargin - topMargin);
    }

    /**
     * A helper method to populate a one player field with target trees.
     */
    private void setupFieldForOnePlayer() {
        // place our (new) physicist in the lower left corner
        if (field.physicists.size() == 0) {
            player1.setPosition(Field.PHYSICIST_SIZE_IN_PIXELS, FIELD_HEIGHT - (int) (Field.PHYSICIST_SIZE_IN_PIXELS * 1.5));
            field.physicists.add(player1);
            player1.setField(field);
        }

        // Create some trees for target practice
        for (int i = field.trees.size(); i < 10; i++) {
            Tree t = new Tree();
            t.setPosition(goodX(), goodY());
            // Trees can be close to each other and overlap, but they shouldn't intersect our physicist
            while(player1.isTouching(t)) {
                // We do intersect this tree, so let's try again
                t.setPosition(goodX(), goodY());
                System.err.println("Repositioning an intersecting tree...");
            }
            field.trees.add(t);
        }
    }

    public static void main(String args[]) {
        AppleToss game = new AppleToss();
        game.setVisible(true);
    }
}


================================================
FILE: ch11/game/Field.java
================================================
package ch11.game;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * The playing field for our game. Now we can setup some constants for
 * other game classes to use and create member variables for our player and some trees.
 */
public class Field extends JComponent implements ActionListener {
    public static final float GRAVITY = 9.8f;  // feet per second per second
    public static final int STEP = 40;   // duration of an animation frame in milliseconds
    public static final int APPLE_SIZE_IN_PIXELS = 30;
    public static final int TREE_WIDTH_IN_PIXELS = 60;
    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;

    public static final int MAX_PHYSICISTS = 5;
    public static final int MAX_APPLES_PER_PHYSICIST = 3;
    public static final int MAX_TREES = 12;

    Color fieldColor = Color.GRAY;

    // ArrayList will be covered in Generics chapter
    // synchronizedArrayList will be covered in Threads chapter
    List<Physicist> physicists = Collections.synchronizedList(new ArrayList<>());
    List<Apple> apples = Collections.synchronizedList(new ArrayList<>());
    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());

    boolean animating = false;
    Thread animationThread;
    Timer animationTimer;

    protected void paintComponent(Graphics g) {
        g.setColor(fieldColor);
        g.fillRect(0,0, getWidth(), getHeight());
        for (Physicist p : physicists) {
            p.draw(g);
        }
        for (Tree t : trees) {
            t.draw(g);
        }
        for (Apple a : apples) {
            a.draw(g);
        }
    }

    public void actionPerformed(ActionEvent event) {
        if (animating && event.getActionCommand().equals("repaint")) {
            System.out.println("Timer stepping " + apples.size() + " apples");
            for (Apple a : apples) {
                a.step();
                detectCollisions(a);
            }
            repaint();
            cullFallenApples();
        }
    }

    /**
     * Toss an apple from the given physicist using that physicist's aim and force.
     * Make sure the field is in the animating state.
     *
     * @param physicist the player whose apple should be tossed
     */
    public void startTossFromPlayer(Physicist physicist) {
        if (!animating) {
            System.out.println("Starting animation!");
            animating = true;
            startAnimation();
        }
        if (animating) {
            // Check to make sure we have an apple to toss
            if (physicist.aimingApple != null) {
                Apple apple = physicist.takeApple();
                apple.toss(physicist.aimingAngle, physicist.aimingForce);
                apples.add(apple);
                Timer appleLoader = new Timer(800, physicist);
                appleLoader.setActionCommand("New Apple");
                appleLoader.setRepeats(false);
                appleLoader.start();
            }
        }
    }

    void cullFallenApples() {
        Iterator<Apple> iterator = apples.iterator();
        while (iterator.hasNext()) {
            Apple a = iterator.next();
            if (a.getCollidedPiece() != null) {
                GamePiece otherPiece = a.getCollidedPiece();
                if (otherPiece instanceof Physicist) {
                    hitPhysicist((Physicist) otherPiece);
                } else if (otherPiece instanceof Tree) {
                    hitTree((Tree) otherPiece);
                }
                // Remove ourselves. If the other piece we hit was an apple, leave it alone.
                // It will be removed when the iterator comes to it.
                iterator.remove();
            } else if (a.getPositionY() > 600) {
                System.out.println("Culling apple");
                iterator.remove();
            }
        }
        if (apples.size() <= 0) {
            animating = false;
            if (animationTimer != null && animationTimer.isRunning()) {
                animationTimer.stop();
            }
        }
    }

    void detectCollisions(Apple apple) {
        // Check for other apples
        for (Apple a : apples) {
            if (apple.isTouching(a)) {
                System.out.println("Touching another apple!");
                return;
            }
        }
        // Check for physicists
        for (Physicist p : physicists) {
            if (apple.isTouching(p)) {
                System.out.println("Touching a physicist!");
                return;
            }
        }
        // Check for trees
        for (Tree t : trees) {
            if (apple.isTouching(t)) {
                System.out.println("Touching a tree!");
                return;
            }
        }
    }

    void hitPhysicist(Physicist physicist) {
        // do any scoring or notifications here
        physicists.remove(physicist);
    }

    void hitTree(Tree tree) {
        // do any scoring or notifications here
        trees.remove(tree);
    }

    void startAnimation() {
        // Animator myAnimator = new Animator();
        // animationThread = new Thread(myAnimator);
        // animationThread.start();
        if (animationTimer == null) {
            animationTimer = new Timer(STEP, this);
            animationTimer.setActionCommand("repaint");
            animationTimer.setRepeats(true);
            animationTimer.start();
        } else if (!animationTimer.isRunning()) {
            animationTimer.restart();
        }
    }

    class Animator implements Runnable {
        public void run() {
            while (animating) {
                System.out.println("Stepping " + apples.size() + " apples");
                for (Apple a : apples) {
                    a.step();
                    detectCollisions(a);
                }
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        Field.this.repaint();
                    }
                });
                cullFallenApples();
                try {
                    Thread.sleep((int)(STEP * 1000));
                } catch (InterruptedException ie) {
                    System.err.println("Animation interrupted");
                    animating = false;
                }
            }
        }
    }
}


================================================
FILE: ch11/game/GamePiece.java
================================================
package ch11.game;

import java.awt.*;

/**
 * Interface to hold common elements for our apples, trees, and physicists
 * From the README:
 * GamePiece
 *   - methods for positioning on a PlayingField
 *   - methods for Drawing
 *   - methods for detecting a collision with other GamePieces
 */
public interface GamePiece {
    /**
     * Sets the position of the piece on the playing field.
     * (0,0) is the upper left per standard Java drawing methods.
     *
     * @param x
     * @param y
     */
    void setPosition(int x, int y);

    /**
     * Gets the current horizontal position of the piece on the field.
     *
     * @return current X position of the piece
     */
    int getPositionX();

    /**
     * Gets the current vertical position of the piece on the field.
     *
     * @return current Y position of the piece
     */
    int getPositionY();

    /**
     * Gets the bounding box of this piece.
     *
     * @return a Rectangle encompassing the visual elements of the piece
     */
    Rectangle getBoundingBox();

    /**
     * Draws the piece inside the given graphics context.
     * Do not assume anything about the state of the context.
     *
     * @param g
     */
    void draw(Graphics g);

    /**
     * Detect a collision with another piece on the field.
     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
     *
     * @param otherPiece
     * @return
     */
    boolean isTouching(GamePiece otherPiece);
}


================================================
FILE: ch11/game/GameUtilities.java
================================================
package ch11.game;

// collision detection between a circle and a rectangle
// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection

import java.awt.*;

/**
 * Utility class with a few helper methods for calculating various collisions and
 * intersections.
 */
public class GameUtilities {
    static boolean isPointInsideBox(int x, int y, Rectangle box) {
        // Our own custom test. We could of course use box.contains(),
        // but we can practice some interesting conditional checking here.
        // Let's test left and right first
        if (x >= box.x && x <= (box.x + box.width)) {
            // Our x coordinate is ok, so check our y
            if (y >= box.y && y <= (box.y + box.height)) {
                return true;
            }
        }
        // x or y was outside the box, so return false
        return false;
    }

    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
        // If any of the four corners of box are inside other, we intersect, so
        // let's check each one. Happily, that answer doesn't change if more
        // than one corner is contained in other, so we can return as soon as
        // we find the first contained corner.

        // Let's get some local copies of the corner coordinates
        // to make the call arguments easier to read.
        int x1 = box.x;
        int y1 = box.y;
        int x2 = x1 + box.width;
        int y2 = y1 + box.height;
        if (isPointInsideBox(x1, y1, other)) {
            // upper left
            return true;
        } else if (isPointInsideBox(x1, y2, other)) {
            // lower left
            return true;
        } else if (isPointInsideBox(x2, y1, other)) {
            // upper right
            return true;
        } else if (isPointInsideBox(x2, y2, other)) {
            // lower right
            return true;
        }
        // No box points in other so no intersection
        return false;
    }

    /**
     * Given two rectangles, do the overlap at all? This includes one box being
     * completely contained by the other box.
     *
     * @param box1 a box to test, order does not matter
     * @param box2 the other box
     * @return true if the boxes overlap, false otherwise
     */
    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {
        // Another custom test. We could of course use box1.intersects(box2)
        // but we can practice method calls and some boolean logic here.
        if (doesBoxIntersect(box1, box2)) {
            // At least one of box1's points must be inside box2
            return true;
        } else if (doesBoxIntersect(box2, box1)) {
            // None of box1's points were in box2, but at least one of box2's points are inside box1
            return true;
        }
        // No intersections in either direction
        return false;
    }
}


================================================
FILE: ch11/game/Physicist.java
================================================
package ch11.game;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static java.awt.Color.*;

/**
 * Our player class. A physicist has an apple that they can throw in addition
 * to implementing the basic methods for GamePiece. We can also set a custom
 * color in case you build on the game and allow multiple physicists to be
 * on the screen at the same time.
 */
public class Physicist implements GamePiece, ActionListener {
    Color color;
    int centerX, centerY;
    Apple aimingApple;
    float aimingAngle;
    float aimingForce;
    Field field;

    // Some helpers for optimizing the draw() method that can be called many, many times
    int x, y;

    // Boundary helpers
    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);
    private Rectangle boundingBox;


    /**
     * Create a default, blue physicist
     */
    public Physicist() {
        this(BLUE);
    }

    /**
     * Create a Physicist of the given color
     */
    public Physicist(Color color) {
        setColor(color);
        aimingAngle = 90.0f;
        aimingForce = 50.0f;
        getNewApple();
    }

    public void setAimingAngle(Float angle) {
        aimingAngle = angle;
    }

    public void setAimingForce(Float force) {
        if (force < 0) {
            force = 0.0f;
        }
        aimingForce = force;
    }

    /**
     * Sets the color for the physicist.
     *
     * @param color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void setPosition(int x, int y) {
        // Our position is based on the center of our dome,
        // but it will be drawn from the upper left corner.
        // Figure out the distance of that gap
        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);

        this.centerX = x;
        this.centerY = y;
        this.x = x - offset;
        this.y = y - offset;
        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);
    }

    @Override
    public int getPositionX() {
        return centerX;
    }

    @Override
    public int getPositionY() {
        return centerY;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    /**
     * Sets the active field once our physicist is being displayed.
     *
     * @param field Active game field
     */
    public void setField(Field field) {
        this.field = field;
    }

    /**
     * Take the current apple away from the physicist. Returns the apple for
     * use in animating on the field. Note that if there is no current apple being
     * aimed, null is returned.
     *
     * @return the current apple (if any) being aimed
     */
    public Apple takeApple() {
        Apple myApple = aimingApple;
        aimingApple = null;
        return myApple;
    }

    /**
     * Get a new apple ready if we need one. Do not discard an existing apple.
     */
    public void getNewApple() {
        // Don't drop the current apple if we already have one!
        if (aimingApple == null) {
            aimingApple = new Apple(this);
        }
    }

    @Override
    public void draw(Graphics g) {
        // Make sure our physicist is the right color, then draw the semi-circle and box
        g.setColor(color);
        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);
        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);

        // Do we have an apple to draw as well?
        if (aimingApple != null) {
            // Yes. Position the center of the apple on the edge of our semi-circle.
            // Use the current aimingAngle to determine where on the edge.
            double angleInRadians = Math.toRadians(aimingAngle);
            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;
            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);
            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);
            aimingApple.setPosition(aimingX, aimingY);
            aimingApple.draw(g);
        }
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("New Apple")) {
            getNewApple();
            if (field != null) {
                field.repaint();
            }
        }
    }
}


================================================
FILE: ch11/game/Tree.java
================================================
package ch11.game;

import java.awt.*;

/**
 * An obstacle for our game. Trees includ a simple circle and rectangle shape.
 * They are built using sizes determined by the constants in the Field class.
 */
public class Tree implements GamePiece {
    int x, y;

    // Drawing helpers
    private Color leafColor = Color.GREEN.darker();
    private Color trunkColor = new Color(101, 67, 33);
    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
    private int trunkX, trunkY;

    // Boundary helpers
    private Rectangle boundingBox;

    @Override
    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
    }

    @Override
    public int getPositionX() {
        return x;
    }

    @Override
    public int getPositionY() {
        return y;
    }

    @Override
    public Rectangle getBoundingBox() {
        return boundingBox;
    }

    @Override
    public void draw(Graphics g) {
        g.setColor(trunkColor);
        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
        g.setColor(leafColor);
        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
    }

    @Override
    public boolean isTouching(GamePiece otherPiece) {
        if (this == otherPiece) {
            // By definition we don't collide with ourselves
            return false;
        }
        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
    }
}


================================================
FILE: ch12/Post.java
================================================
package ch12;

import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * A small graphical application that demonstrates use of the
 * HTTP POST mechanism. Provide a POST-able URL to the command line
 * and use the "Post" button to send sample name and password
 * data to the URL.
 * 
 * See the servlet section of this chapter for the ShowParameters
 * example that can serve (ha!) as the receiving (server) side.
 */
public class Post extends JPanel implements ActionListener {
  JTextField nameField;
  JPasswordField passwordField;
  String postURL;

  GridBagConstraints constraints = new GridBagConstraints(  );
  
  void addGB( Component component, int x, int y ) {
    constraints.gridx = x;  constraints.gridy = y;
    add ( component, constraints );
  }

  public Post( String postURL ) {
	  
    this.postURL = postURL;  
	  
    setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 5));
    JButton postButton = new JButton("Post");
    postButton.addActionListener( this );
    setLayout( new GridBagLayout(  ) );
    constraints.fill = GridBagConstraints.HORIZONTAL;
    addGB( new JLabel("Name ", JLabel.TRAILING), 0, 0 );
    addGB( nameField = new JTextField(20), 1, 0 );
    addGB( new JLabel("Password ", JLabel.TRAILING), 0, 1 );
    addGB( passwordField = new JPasswordField(20), 1, 1 );
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridwidth = 2;
    constraints.anchor = GridBagConstraints.EAST;
    addGB( postButton, 1, 2 );
  }

  public void actionPerformed(ActionEvent e) {
    postData(  );
  }

  protected void postData(  ) {
    StringBuilder sb = new StringBuilder();
    String pw = new String(passwordField.getPassword());
    try {
      sb.append( URLEncoder.encode("Name", "UTF-8") + "=" );
      sb.append( URLEncoder.encode(nameField.getText(), "UTF-8") );
      sb.append( "&" + URLEncoder.encode("Password", "UTF-8") + "=" );
      sb.append( URLEncoder.encode(pw, "UTF-8") );
    } catch (UnsupportedEncodingException uee) {
      System.out.println(uee);
    }
    String formData = sb.toString(  );

    try {
      URL url = new URL( postURL );
      HttpURLConnection urlcon =
          (HttpURLConnection) url.openConnection(  );
      urlcon.setRequestMethod("POST");
      urlcon.setRequestProperty("Content-type",
          "application/x-www-form-urlencoded");
      urlcon.setDoOutput(true);
      urlcon.setDoInput(true);
      PrintWriter pout = new PrintWriter( new OutputStreamWriter(
          urlcon.getOutputStream(  ), "8859_1"), true );
      pout.print( formData );
      pout.flush(  );

      // Did the post succeed?
      if ( urlcon.getResponseCode() == HttpURLConnection.HTTP_OK )
        System.out.println("Posted ok!");
      else {
        System.out.println("Bad post...");
        return;
      }
      // Hooray! Go ahead and read the results...
      //InputStream in = urlcon.getInputStream(  );
      // ...

    } catch (MalformedURLException e) {
      System.out.println(e);     // bad postURL
    } catch (IOException e2) {
      System.out.println(e2);    // I/O error
    }
  }

  public static void main( String [] args ) {
    if (args.length != 1) {
      System.err.println("Must specify URL on command line. Exiting.");
      System.exit(1);
    }
    JFrame frame = new JFrame("SimplePost");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add( new Post(args[0]), "Center" );
    frame.pack();
    frame.setVisible(true);
  }
}


================================================
FILE: ch12/Read.java
================================================
package ch12;

import java.io.*;
import java.net.*;

/**
 * A simple command line demonstration of reading from a URL.
 * The URL to read must be passed as the only argument on the command line.
 */
public class Read {
  public static void main(String args[]) {
    // Did we get an argument to use as the URL?
    if (args.length != 1) {
      System.err.println("Must specify URL on command line. Exiting.");
      System.exit(1);
    }
    // Great! Let's try to read it and dump the contents to the terminal.
    try {
      URL url = new URL(args[0]);

      BufferedReader bin = new BufferedReader (
          new InputStreamReader( url.openStream() ));
      String line;
      while ( (line = bin.readLine()) != null ) {
        System.out.println( line );
      }
      bin.close();
    } catch (Exception e) { 
      System.err.println("Error occurred while reading:" + e);
    }
  }
}


================================================
FILE: ch13/ActionDemoLambda.java
================================================
package ch13;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * An update to the ch10.ActionDemo2 class with a lambda expressi
Download .txt
gitextract_wyoxb4rf/

├── .gitignore
├── LICENSE
├── README.md
├── ch02/
│   ├── HelloJava.java
│   └── HelloJava2.java
├── ch04/
│   └── EuclidGCD.java
├── ch05/
│   ├── Apple.java
│   ├── AppleToss.java
│   ├── Field.java
│   ├── GamePiece.java
│   ├── HelloJava3.java
│   ├── Physicist.java
│   ├── PrintAppleDetails.java
│   ├── PrintAppleDetails2.java
│   ├── PrintAppleDetails3.java
│   ├── PrintAppleDetails4.java
│   └── Tree.java
├── ch06/
│   ├── Euclid2.java
│   └── LogTest.java
├── ch07/
│   ├── Apple.java
│   ├── AppleToss.java
│   ├── Field.java
│   ├── GamePiece.java
│   ├── GameUtilities.java
│   ├── Physicist.java
│   └── Tree.java
├── ch08/
│   ├── Apple.java
│   ├── AppleToss.java
│   ├── Field.java
│   ├── GamePiece.java
│   ├── GameUtilities.java
│   ├── Physicist.java
│   └── Tree.java
├── ch09/
│   ├── URLConsumer.java
│   ├── URLDemo.java
│   ├── URLProducer.java
│   ├── URLQueue.java
│   └── game/
│       ├── Apple.java
│       ├── AppleToss.java
│       ├── Field.java
│       ├── GamePiece.java
│       ├── GameUtilities.java
│       ├── Physicist.java
│       └── Tree.java
├── ch10/
│   ├── ActionDemo1.java
│   ├── ActionDemo2.java
│   ├── BorderLayoutDemo.java
│   ├── Buttons.java
│   ├── HelloJavaAgain.java
│   ├── HelloMouse.java
│   ├── HelloMouseHelper.java
│   ├── Labels.java
│   ├── MenuDemo.java
│   ├── ModalDemo.java
│   ├── NestedPanelDemo.java
│   ├── PhoneGridDemo.java
│   ├── ProgressDemo.java
│   ├── TextInputs.java
│   ├── Widget.java
│   └── game/
│       ├── Apple.java
│       ├── AppleToss.java
│       ├── Field.java
│       ├── GamePiece.java
│       ├── GameUtilities.java
│       ├── Physicist.java
│       └── Tree.java
├── ch11/
│   ├── CopyChannels.java
│   ├── CopyChannels2.java
│   ├── CopyChannels3.java
│   ├── CopyFile.java
│   ├── CopyStreams.java
│   ├── DateAtHost.java
│   ├── ListIt.java
│   └── game/
│       ├── Apple.java
│       ├── AppleToss.java
│       ├── Field.java
│       ├── GamePiece.java
│       ├── GameUtilities.java
│       ├── Physicist.java
│       └── Tree.java
├── ch12/
│   ├── Post.java
│   └── Read.java
├── ch13/
│   ├── ActionDemoLambda.java
│   └── ListItLambda.java
└── game/
    ├── Apple.java
    ├── AppleToss.java
    ├── Field.java
    ├── GamePiece.java
    ├── GameUtilities.java
    ├── Multiplayer.java
    ├── Physicist.java
    └── Tree.java
Download .txt
SYMBOL INDEX (587 symbols across 89 files)

FILE: ch02/HelloJava.java
  class HelloJava (line 8) | public class HelloJava {
    method main (line 9) | public static void main( String[] args ) {

FILE: ch02/HelloJava2.java
  class HelloJava2 (line 10) | public class HelloJava2 {
    method main (line 11) | public static void main( String[] args ) {
  class HelloComponent2 (line 25) | class HelloComponent2 extends JComponent implements MouseMotionListener {
    method HelloComponent2 (line 34) | public HelloComponent2( String message ) {
    method paintComponent (line 39) | public void paintComponent( Graphics g ) {
    method mouseDragged (line 43) | public void mouseDragged(MouseEvent e) {
    method mouseMoved (line 50) | public void mouseMoved(MouseEvent e) {

FILE: ch04/EuclidGCD.java
  class EuclidGCD (line 9) | public class EuclidGCD {
    method main (line 10) | public static void main(String args[]) {

FILE: ch05/Apple.java
  class Apple (line 11) | public class Apple implements GamePiece {
    method Apple (line 35) | public Apple() {
    method Apple (line 42) | public Apple(int size) {
    method setSize (line 52) | public void setSize(int size) {
    method getDiameter (line 80) | public double getDiameter() {
    method setPosition (line 84) | @Override
    method getPositionX (line 97) | @Override
    method getPositionY (line 102) | @Override
    method getBoundingBox (line 107) | @Override
    method draw (line 112) | @Override
    method isTouching (line 122) | public boolean isTouching(GamePiece other) {
    method printDetails (line 137) | public void printDetails() {
    method getAppleSizes (line 153) | public static String[] getAppleSizes() {

FILE: ch05/AppleToss.java
  class AppleToss (line 10) | public class AppleToss extends JFrame {
    method AppleToss (line 15) | public AppleToss() {
    method setupFieldForOnePlayer (line 29) | private void setupFieldForOnePlayer() {
    method main (line 39) | public static void main(String args[]) {

FILE: ch05/Field.java
  class Field (line 12) | public class Field extends JComponent {
    method setupApples (line 28) | public void setupApples() {
    method setupTree (line 40) | public void setupTree() {
    method setPlayer (line 46) | public void setPlayer(Physicist p) {
    method paintComponent (line 50) | protected void paintComponent(Graphics g) {
    method detectCollisions (line 59) | public void detectCollisions() {

FILE: ch05/GamePiece.java
  type GamePiece (line 12) | public interface GamePiece {
    method setPosition (line 20) | void setPosition(int x, int y);
    method getPositionX (line 27) | int getPositionX();
    method getPositionY (line 34) | int getPositionY();
    method getBoundingBox (line 41) | Rectangle getBoundingBox();
    method draw (line 49) | void draw(Graphics g);
    method isTouching (line 58) | boolean isTouching(GamePiece otherPiece);

FILE: ch05/HelloJava3.java
  class HelloJava3 (line 13) | public class HelloJava3 extends JFrame {
    method main (line 14) | public static void main( String[] args ) {
    method HelloJava3 (line 19) | public HelloJava3() {
    class HelloComponent3 (line 26) | class HelloComponent3 extends JComponent {
      method HelloComponent3 (line 30) | public HelloComponent3( String message ) {
      method paintComponent (line 43) | public void paintComponent( Graphics g ) {

FILE: ch05/Physicist.java
  class Physicist (line 15) | public class Physicist implements GamePiece {
    method Physicist (line 33) | public Physicist() {
    method Physicist (line 40) | public Physicist(Color color) {
    method setAimingAngle (line 46) | public void setAimingAngle(Float angle) {
    method setAimingForce (line 50) | public void setAimingForce(Float force) {
    method setColor (line 62) | public void setColor(Color color) {
    method setPosition (line 66) | @Override
    method getPositionX (line 80) | @Override
    method getPositionY (line 85) | @Override
    method getBoundingBox (line 90) | @Override
    method setField (line 100) | public void setField(Field field) {
    method draw (line 104) | @Override
    method isTouching (line 112) | @Override

FILE: ch05/PrintAppleDetails.java
  class PrintAppleDetails (line 7) | public class PrintAppleDetails {
    method main (line 8) | public static void main(String args[]) {

FILE: ch05/PrintAppleDetails2.java
  class PrintAppleDetails2 (line 8) | public class PrintAppleDetails2 {
    method main (line 9) | public static void main(String args[]) {

FILE: ch05/PrintAppleDetails3.java
  class PrintAppleDetails3 (line 8) | public class PrintAppleDetails3 {
    method main (line 9) | public static void main(String args[]) {

FILE: ch05/PrintAppleDetails4.java
  class PrintAppleDetails4 (line 8) | public class PrintAppleDetails4 {
    method main (line 9) | public static void main(String args[]) {

FILE: ch05/Tree.java
  class Tree (line 9) | public class Tree implements GamePiece {
    method setPosition (line 22) | @Override
    method getPositionX (line 31) | @Override
    method getPositionY (line 36) | @Override
    method getBoundingBox (line 41) | @Override
    method draw (line 46) | @Override
    method isTouching (line 54) | @Override

FILE: ch06/Euclid2.java
  class Euclid2 (line 8) | public class Euclid2 {
    method main (line 9) | public static void main(String args[]) {

FILE: ch06/LogTest.java
  class LogTest (line 10) | public class LogTest {
    method main (line 11) | public static void main(String argv[]) {

FILE: ch07/Apple.java
  class Apple (line 11) | public class Apple implements GamePiece {
    method Apple (line 35) | public Apple(Physicist owner) {
    method Apple (line 42) | public Apple(Physicist owner, int size) {
    method setSize (line 53) | public void setSize(int size) {
    method getDiameter (line 81) | public double getDiameter() {
    method setPosition (line 85) | @Override
    method getPositionX (line 98) | @Override
    method getPositionY (line 103) | @Override
    method getBoundingBox (line 108) | @Override
    method draw (line 113) | @Override
    method isTouching (line 120) | @Override
    method getCollidedPiece (line 151) | public GamePiece getCollidedPiece() {
    method setCollided (line 155) | public void setCollided(GamePiece otherPiece) {

FILE: ch07/AppleToss.java
  class AppleToss (line 10) | public class AppleToss extends JFrame {
    method AppleToss (line 15) | public AppleToss() {
    method setupFieldForOnePlayer (line 29) | private void setupFieldForOnePlayer() {
    method main (line 44) | public static void main(String args[]) {

FILE: ch07/Field.java
  class Field (line 12) | public class Field extends JComponent {
    method paintComponent (line 29) | protected void paintComponent(Graphics g) {
    method setPlayer (line 38) | public void setPlayer(Physicist p) {
    method addTree (line 42) | public void addTree(int x, int y) {

FILE: ch07/GamePiece.java
  type GamePiece (line 14) | public interface GamePiece {
    method setPosition (line 22) | void setPosition(int x, int y);
    method getPositionX (line 29) | int getPositionX();
    method getPositionY (line 36) | int getPositionY();
    method getBoundingBox (line 43) | Rectangle getBoundingBox();
    method draw (line 51) | void draw(Graphics g);
    method isTouching (line 60) | boolean isTouching(GamePiece otherPiece);

FILE: ch07/GameUtilities.java
  class GameUtilities (line 12) | public class GameUtilities {
    method isPointInsideBox (line 13) | static boolean isPointInsideBox(int x, int y, Rectangle box) {
    method doesBoxIntersect (line 27) | static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
    method doBoxesIntersect (line 64) | public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {

FILE: ch07/Physicist.java
  class Physicist (line 15) | public class Physicist implements GamePiece {
    method Physicist (line 34) | public Physicist() {
    method Physicist (line 41) | public Physicist(Color color) {
    method setAimingAngle (line 48) | public void setAimingAngle(Float angle) {
    method setAimingForce (line 52) | public void setAimingForce(Float force) {
    method setColor (line 64) | public void setColor(Color color) {
    method setPosition (line 68) | @Override
    method getPositionX (line 82) | @Override
    method getPositionY (line 87) | @Override
    method getBoundingBox (line 92) | @Override
    method setField (line 102) | public void setField(Field field) {
    method takeApple (line 113) | public Apple takeApple() {
    method getNewApple (line 122) | public void getNewApple() {
    method draw (line 129) | @Override
    method isTouching (line 149) | @Override

FILE: ch07/Tree.java
  class Tree (line 9) | public class Tree implements GamePiece {
    method setPosition (line 22) | @Override
    method getPositionX (line 31) | @Override
    method getPositionY (line 36) | @Override
    method getBoundingBox (line 41) | @Override
    method draw (line 46) | @Override
    method isTouching (line 54) | @Override

FILE: ch08/Apple.java
  class Apple (line 12) | public class Apple implements GamePiece {
    method Apple (line 36) | public Apple(Physicist owner) {
    method Apple (line 43) | public Apple(Physicist owner, int size) {
    method setSize (line 54) | public void setSize(int size) {
    method getDiameter (line 82) | public double getDiameter() {
    method setPosition (line 86) | @Override
    method getPositionX (line 99) | @Override
    method getPositionY (line 104) | @Override
    method getBoundingBox (line 109) | @Override
    method draw (line 114) | @Override
    method isTouching (line 121) | @Override
    method getCollidedPiece (line 152) | public GamePiece getCollidedPiece() {
    method setCollided (line 156) | public void setCollided(GamePiece otherPiece) {

FILE: ch08/AppleToss.java
  class AppleToss (line 12) | public class AppleToss extends JFrame {
    method AppleToss (line 23) | public AppleToss() {
    method goodX (line 39) | private int goodX() {
    method goodY (line 55) | private int goodY() {
    method setupFieldForOnePlayer (line 68) | private void setupFieldForOnePlayer() {
    method main (line 90) | public static void main(String args[]) {

FILE: ch08/Field.java
  class Field (line 16) | public class Field extends JComponent {
    method paintComponent (line 33) | protected void paintComponent(Graphics g) {
    method setPlayer (line 42) | public void setPlayer(Physicist p) {
    method addTree (line 52) | public void addTree(int x, int y) {
    method addTree (line 64) | public void addTree(Tree t) {

FILE: ch08/GamePiece.java
  type GamePiece (line 14) | public interface GamePiece {
    method setPosition (line 22) | void setPosition(int x, int y);
    method getPositionX (line 29) | int getPositionX();
    method getPositionY (line 36) | int getPositionY();
    method getBoundingBox (line 43) | Rectangle getBoundingBox();
    method draw (line 51) | void draw(Graphics g);
    method isTouching (line 60) | boolean isTouching(GamePiece otherPiece);

FILE: ch08/GameUtilities.java
  class GameUtilities (line 12) | public class GameUtilities {
    method isPointInsideBox (line 13) | static boolean isPointInsideBox(int x, int y, Rectangle box) {
    method doesBoxIntersect (line 27) | static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
    method doBoxesIntersect (line 64) | public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {

FILE: ch08/Physicist.java
  class Physicist (line 15) | public class Physicist implements GamePiece {
    method Physicist (line 34) | public Physicist() {
    method Physicist (line 41) | public Physicist(Color color) {
    method setAimingAngle (line 48) | public void setAimingAngle(Float angle) {
    method setAimingForce (line 52) | public void setAimingForce(Float force) {
    method setColor (line 64) | public void setColor(Color color) {
    method setPosition (line 68) | @Override
    method getPositionX (line 82) | @Override
    method getPositionY (line 87) | @Override
    method getBoundingBox (line 92) | @Override
    method setField (line 102) | public void setField(Field field) {
    method takeApple (line 113) | public Apple takeApple() {
    method getNewApple (line 122) | public void getNewApple() {
    method draw (line 129) | @Override
    method isTouching (line 149) | @Override

FILE: ch08/Tree.java
  class Tree (line 9) | public class Tree implements GamePiece {
    method setPosition (line 22) | @Override
    method getPositionX (line 31) | @Override
    method getPositionY (line 36) | @Override
    method getBoundingBox (line 41) | @Override
    method draw (line 46) | @Override
    method isTouching (line 54) | @Override

FILE: ch09/URLConsumer.java
  class URLConsumer (line 10) | public class URLConsumer extends Thread {
    method URLConsumer (line 23) | public URLConsumer(String id, URLQueue queue) {
    method run (line 39) | public void run() {
    method setKeepWorking (line 62) | public void setKeepWorking(boolean keepWorking) {

FILE: ch09/URLDemo.java
  class URLDemo (line 12) | public class URLDemo {
    method main (line 13) | public static void main(String args[]) {

FILE: ch09/URLProducer.java
  class URLProducer (line 9) | public class URLProducer extends Thread {
    method URLProducer (line 24) | public URLProducer(String id, int count, URLQueue queue) {
    method run (line 44) | public void run() {

FILE: ch09/URLQueue.java
  class URLQueue (line 9) | public class URLQueue {
    method addURL (line 12) | public synchronized void addURL(String url) {
    method getURL (line 16) | public synchronized String getURL() {
    method isEmpty (line 23) | public boolean isEmpty() {

FILE: ch09/game/Apple.java
  class Apple (line 12) | public class Apple implements GamePiece {
    method Apple (line 40) | public Apple(Physicist owner) {
    method Apple (line 47) | public Apple(Physicist owner, int size) {
    method setSize (line 58) | public void setSize(int size) {
    method getDiameter (line 86) | public double getDiameter() {
    method setPosition (line 90) | @Override
    method getPositionX (line 103) | @Override
    method getPositionY (line 108) | @Override
    method getBoundingBox (line 113) | @Override
    method draw (line 118) | @Override
    method isTouching (line 125) | @Override
    method getCollidedPiece (line 156) | public GamePiece getCollidedPiece() {
    method setCollided (line 160) | public void setCollided(GamePiece otherPiece) {
    method toss (line 164) | public void toss(float angle, float velocity) {
    method step (line 172) | public void step() {

FILE: ch09/game/AppleToss.java
  class AppleToss (line 18) | public class AppleToss extends JFrame {
    method AppleToss (line 29) | public AppleToss() {
    method goodX (line 46) | private int goodX() {
    method goodY (line 61) | private int goodY() {
    method setupFieldForOnePlayer (line 74) | private void setupFieldForOnePlayer() {
    method main (line 96) | public static void main(String args[]) {

FILE: ch09/game/Field.java
  class Field (line 17) | public class Field extends JComponent implements ActionListener {
    method paintComponent (line 40) | protected void paintComponent(Graphics g) {
    method actionPerformed (line 54) | public void actionPerformed(ActionEvent event) {
    method startTossFromPlayer (line 72) | public void startTossFromPlayer(Physicist physicist) {
    method cullFallenApples (line 88) | void cullFallenApples() {
    method detectCollisions (line 105) | void detectCollisions(Apple apple) {
    method hitPhysicist (line 129) | void hitPhysicist(Physicist physicist) {
    method hitTree (line 134) | void hitTree(Tree tree) {
    method startAnimation (line 139) | void startAnimation() {
    class Animator (line 153) | class Animator implements Runnable {
      method run (line 154) | public void run() {

FILE: ch09/game/GamePiece.java
  type GamePiece (line 14) | public interface GamePiece {
    method setPosition (line 22) | void setPosition(int x, int y);
    method getPositionX (line 29) | int getPositionX();
    method getPositionY (line 36) | int getPositionY();
    method getBoundingBox (line 43) | Rectangle getBoundingBox();
    method draw (line 51) | void draw(Graphics g);
    method isTouching (line 60) | boolean isTouching(GamePiece otherPiece);

FILE: ch09/game/GameUtilities.java
  class GameUtilities (line 12) | public class GameUtilities {
    method isPointInsideBox (line 13) | static boolean isPointInsideBox(int x, int y, Rectangle box) {
    method doesBoxIntersect (line 27) | static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
    method doBoxesIntersect (line 64) | public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {

FILE: ch09/game/Physicist.java
  class Physicist (line 15) | public class Physicist implements GamePiece, ActionListener {
    method Physicist (line 34) | public Physicist() {
    method Physicist (line 41) | public Physicist(Color color) {
    method setAimingAngle (line 48) | public void setAimingAngle(Float angle) {
    method setAimingForce (line 52) | public void setAimingForce(Float force) {
    method setColor (line 64) | public void setColor(Color color) {
    method setPosition (line 68) | @Override
    method getPositionX (line 82) | @Override
    method getPositionY (line 87) | @Override
    method getBoundingBox (line 92) | @Override
    method setField (line 102) | public void setField(Field field) {
    method takeApple (line 113) | public Apple takeApple() {
    method getNewApple (line 122) | public void getNewApple() {
    method draw (line 129) | @Override
    method isTouching (line 149) | @Override
    method actionPerformed (line 158) | @Override

FILE: ch09/game/Tree.java
  class Tree (line 9) | public class Tree implements GamePiece {
    method setPosition (line 22) | @Override
    method getPositionX (line 31) | @Override
    method getPositionY (line 36) | @Override
    method getBoundingBox (line 41) | @Override
    method draw (line 46) | @Override
    method isTouching (line 54) | @Override

FILE: ch10/ActionDemo1.java
  class ActionDemo1 (line 13) | public class ActionDemo1 extends JFrame implements ActionListener {
    method ActionDemo1 (line 17) | public ActionDemo1() {
    method actionPerformed (line 31) | public void actionPerformed(ActionEvent e) {
    method main (line 36) | public static void main( String[] args ) {

FILE: ch10/ActionDemo2.java
  class ActionDemo2 (line 17) | public class ActionDemo2 {
    method main (line 18) | public static void main( String[] args ) {
  class ActionCommandHelper (line 44) | class ActionCommandHelper implements ActionListener {
    method ActionCommandHelper (line 47) | public ActionCommandHelper(JLabel label) {
    method actionPerformed (line 51) | public void actionPerformed(ActionEvent ae) {

FILE: ch10/BorderLayoutDemo.java
  class BorderLayoutDemo (line 10) | public class BorderLayoutDemo {
    method main (line 11) | public static void main( String[] args ) {

FILE: ch10/Buttons.java
  class Buttons (line 11) | public class Buttons {
    method main (line 12) | public static void main( String[] args ) {

FILE: ch10/HelloJavaAgain.java
  class HelloJavaAgain (line 8) | public class HelloJavaAgain {
    method main (line 9) | public static void main( String[] args ) {

FILE: ch10/HelloMouse.java
  class HelloMouse (line 16) | public class HelloMouse extends JFrame implements MouseListener {
    method HelloMouse (line 19) | public HelloMouse() {
    method mouseClicked (line 35) | public void mouseClicked(MouseEvent e) {
    method mousePressed (line 39) | public void mousePressed(MouseEvent e) { }
    method mouseReleased (line 40) | public void mouseReleased(MouseEvent e) { }
    method mouseEntered (line 41) | public void mouseEntered(MouseEvent e) { }
    method mouseExited (line 42) | public void mouseExited(MouseEvent e) { }
    method main (line 44) | public static void main( String[] args ) {

FILE: ch10/HelloMouseHelper.java
  class HelloMouseHelper (line 14) | public class HelloMouseHelper {
    method main (line 15) | public static void main( String[] args ) {
  class LabelMover (line 37) | class LabelMover extends MouseAdapter {
    method LabelMover (line 40) | public LabelMover(JLabel label) {
    method mouseClicked (line 44) | public void mouseClicked(MouseEvent e) {

FILE: ch10/Labels.java
  class Labels (line 10) | public class Labels {
    method main (line 16) | public static void main( String[] args ) {

FILE: ch10/MenuDemo.java
  class MenuDemo (line 12) | public class MenuDemo extends JFrame implements ActionListener {
    method MenuDemo (line 15) | public MenuDemo() {
    method actionPerformed (line 51) | public void actionPerformed(ActionEvent event) {
    method main (line 55) | public static void main(String args[]) {

FILE: ch10/ModalDemo.java
  class ModalDemo (line 13) | public class ModalDemo extends JFrame implements ActionListener {
    method ModalDemo (line 17) | public ModalDemo() {
    method actionPerformed (line 31) | public void actionPerformed(ActionEvent ae) {
    method main (line 36) | public static void main(String args[]) {

FILE: ch10/NestedPanelDemo.java
  class NestedPanelDemo (line 11) | public class NestedPanelDemo {
    method main (line 12) | public static void main( String[] args ) {

FILE: ch10/PhoneGridDemo.java
  class PhoneGridDemo (line 10) | public class PhoneGridDemo {
    method main (line 11) | public static void main( String[] args ) {

FILE: ch10/ProgressDemo.java
  class ProgressDemo (line 13) | public class ProgressDemo {
    method main (line 14) | public static void main( String[] args ) {
  class ProgressPretender (line 49) | class ProgressPretender implements Runnable {
    method ProgressPretender (line 53) | public ProgressPretender(JLabel label) {
    method run (line 58) | public void run() {

FILE: ch10/TextInputs.java
  class TextInputs (line 10) | public class TextInputs {
    method main (line 11) | public static void main( String[] args ) {

FILE: ch10/Widget.java
  class Widget (line 25) | public class Widget extends JFrame {
    method Widget (line 27) | public Widget() {
    method Widget (line 31) | public Widget(String title) {
    method add (line 38) | @Override
    method remove (line 50) | @Override
    method reset (line 62) | public void reset() {

FILE: ch10/game/Apple.java
  class Apple (line 12) | public class Apple implements GamePiece {
    method Apple (line 40) | public Apple(Physicist owner) {
    method Apple (line 47) | public Apple(Physicist owner, int size) {
    method setSize (line 58) | public void setSize(int size) {
    method getDiameter (line 86) | public double getDiameter() {
    method setPosition (line 90) | @Override
    method getPositionX (line 103) | @Override
    method getPositionY (line 108) | @Override
    method getBoundingBox (line 113) | @Override
    method draw (line 118) | @Override
    method isTouching (line 125) | @Override
    method getCollidedPiece (line 156) | public GamePiece getCollidedPiece() {
    method setCollided (line 160) | public void setCollided(GamePiece otherPiece) {
    method toss (line 164) | public void toss(float angle, float velocity) {
    method step (line 172) | public void step() {

FILE: ch10/game/AppleToss.java
  class AppleToss (line 18) | public class AppleToss extends JFrame {
    method AppleToss (line 36) | public AppleToss() {
    method buildConstraints (line 68) | private GridBagConstraints buildConstraints(int row, int col, int rows...
    method buildRestartButton (line 77) | private JButton buildRestartButton() {
    method buildAngleControl (line 89) | private JSlider buildAngleControl() {
    method buildForceControl (line 102) | private JSlider buildForceControl() {
    method buildTossButton (line 113) | private JButton buildTossButton() {
    method goodX (line 129) | private int goodX() {
    method goodY (line 144) | private int goodY() {
    method setupFieldForOnePlayer (line 157) | private void setupFieldForOnePlayer() {
    method main (line 181) | public static void main(String args[]) {

FILE: ch10/game/Field.java
  class Field (line 17) | public class Field extends JComponent implements ActionListener {
    method paintComponent (line 44) | protected void paintComponent(Graphics g) {
    method actionPerformed (line 58) | public void actionPerformed(ActionEvent event) {
    method startTossFromPlayer (line 76) | public void startTossFromPlayer(Physicist physicist) {
    method cullFallenApples (line 96) | void cullFallenApples() {
    method detectCollisions (line 123) | void detectCollisions(Apple apple) {
    method hitPhysicist (line 147) | void hitPhysicist(Physicist physicist) {
    method hitTree (line 152) | void hitTree(Tree tree) {
    method resetScore (line 159) | public void resetScore(int playerNumber) {
    method getScore (line 164) | public String getScore(int playerNumber) {
    method setScore (line 168) | public void setScore(int playerNumber, String score) {
    method startAnimation (line 178) | void startAnimation() {
    class Animator (line 192) | class Animator implements Runnable {
      method run (line 193) | public void run() {

FILE: ch10/game/GamePiece.java
  type GamePiece (line 13) | public interface GamePiece {
    method setPosition (line 21) | void setPosition(int x, int y);
    method getPositionX (line 28) | int getPositionX();
    method getPositionY (line 35) | int getPositionY();
    method getBoundingBox (line 42) | Rectangle getBoundingBox();
    method draw (line 50) | void draw(Graphics g);
    method isTouching (line 59) | boolean isTouching(GamePiece otherPiece);

FILE: ch10/game/GameUtilities.java
  class GameUtilities (line 12) | public class GameUtilities {
    method isPointInsideBox (line 13) | static boolean isPointInsideBox(int x, int y, Rectangle box) {
    method doesBoxIntersect (line 27) | static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
    method doBoxesIntersect (line 64) | public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {

FILE: ch10/game/Physicist.java
  class Physicist (line 15) | public class Physicist implements GamePiece, ActionListener {
    method Physicist (line 34) | public Physicist() {
    method Physicist (line 41) | public Physicist(Color color) {
    method setAimingAngle (line 48) | public void setAimingAngle(Float angle) {
    method setAimingForce (line 52) | public void setAimingForce(Float force) {
    method setColor (line 64) | public void setColor(Color color) {
    method setPosition (line 68) | @Override
    method getPositionX (line 82) | @Override
    method getPositionY (line 87) | @Override
    method getBoundingBox (line 92) | @Override
    method setField (line 102) | public void setField(Field field) {
    method takeApple (line 113) | public Apple takeApple() {
    method getNewApple (line 122) | public void getNewApple() {
    method draw (line 129) | @Override
    method isTouching (line 149) | @Override
    method actionPerformed (line 158) | @Override

FILE: ch10/game/Tree.java
  class Tree (line 9) | public class Tree implements GamePiece {
    method setPosition (line 22) | @Override
    method getPositionX (line 31) | @Override
    method getPositionY (line 36) | @Override
    method getBoundingBox (line 41) | @Override
    method draw (line 46) | @Override
    method isTouching (line 54) | @Override

FILE: ch11/CopyChannels.java
  class CopyChannels (line 12) | public class CopyChannels {
    method main (line 13) | public static void main( String [] args ) throws Exception {

FILE: ch11/CopyChannels2.java
  class CopyChannels2 (line 12) | public class CopyChannels2 {
    method main (line 13) | public static void main( String [] args ) throws Exception {

FILE: ch11/CopyChannels3.java
  class CopyChannels3 (line 12) | public class CopyChannels3 {
    method main (line 13) | public static void main( String [] args ) throws Exception {

FILE: ch11/CopyFile.java
  class CopyFile (line 12) | public class CopyFile {
    method main (line 13) | public static void main( String [] args ) throws Exception {

FILE: ch11/CopyStreams.java
  class CopyStreams (line 10) | public class CopyStreams {
    method main (line 11) | public static void main( String [] args ) throws Exception {

FILE: ch11/DateAtHost.java
  class DateAtHost (line 5) | public class DateAtHost extends java.util.Date {
    method DateAtHost (line 10) | public DateAtHost( String host ) throws IOException {
    method DateAtHost (line 14) | public DateAtHost( String host, int port ) throws IOException {

FILE: ch11/ListIt.java
  class ListIt (line 10) | public class ListIt {
    method main (line 11) | public static void main ( String args[] ) throws Exception {

FILE: ch11/game/Apple.java
  class Apple (line 12) | public class Apple implements GamePiece {
    method Apple (line 40) | public Apple(Physicist owner) {
    method Apple (line 47) | public Apple(Physicist owner, int size) {
    method setSize (line 58) | public void setSize(int size) {
    method getDiameter (line 86) | public double getDiameter() {
    method setPosition (line 90) | @Override
    method getPositionX (line 103) | @Override
    method getPositionY (line 108) | @Override
    method getBoundingBox (line 113) | @Override
    method draw (line 118) | @Override
    method isTouching (line 125) | @Override
    method getCollidedPiece (line 156) | public GamePiece getCollidedPiece() {
    method setCollided (line 160) | public void setCollided(GamePiece otherPiece) {
    method toss (line 164) | public void toss(float angle, float velocity) {
    method step (line 172) | public void step() {

FILE: ch11/game/AppleToss.java
  class AppleToss (line 18) | public class AppleToss extends JFrame {
    method AppleToss (line 36) | public AppleToss() {
    method buildConstraints (line 70) | private GridBagConstraints buildConstraints(int row, int col, int rows...
    method buildRestartButton (line 79) | private JButton buildRestartButton() {
    method buildAngleControl (line 91) | private JSlider buildAngleControl() {
    method buildForceControl (line 104) | private JSlider buildForceControl() {
    method buildTossButton (line 115) | private JButton buildTossButton() {
    method setupNetworkMenu (line 126) | private void setupNetworkMenu() {
    method goodX (line 170) | private int goodX() {
    method goodY (line 185) | private int goodY() {
    method setupFieldForOnePlayer (line 198) | private void setupFieldForOnePlayer() {
    method main (line 220) | public static void main(String args[]) {

FILE: ch11/game/Field.java
  class Field (line 17) | public class Field extends JComponent implements ActionListener {
    method paintComponent (line 41) | protected void paintComponent(Graphics g) {
    method actionPerformed (line 55) | public void actionPerformed(ActionEvent event) {
    method startTossFromPlayer (line 73) | public void startTossFromPlayer(Physicist physicist) {
    method cullFallenApples (line 93) | void cullFallenApples() {
    method detectCollisions (line 120) | void detectCollisions(Apple apple) {
    method hitPhysicist (line 144) | void hitPhysicist(Physicist physicist) {
    method hitTree (line 149) | void hitTree(Tree tree) {
    method startAnimation (line 154) | void startAnimation() {
    class Animator (line 168) | class Animator implements Runnable {
      method run (line 169) | public void run() {

FILE: ch11/game/GamePiece.java
  type GamePiece (line 13) | public interface GamePiece {
    method setPosition (line 21) | void setPosition(int x, int y);
    method getPositionX (line 28) | int getPositionX();
    method getPositionY (line 35) | int getPositionY();
    method getBoundingBox (line 42) | Rectangle getBoundingBox();
    method draw (line 50) | void draw(Graphics g);
    method isTouching (line 59) | boolean isTouching(GamePiece otherPiece);

FILE: ch11/game/GameUtilities.java
  class GameUtilities (line 12) | public class GameUtilities {
    method isPointInsideBox (line 13) | static boolean isPointInsideBox(int x, int y, Rectangle box) {
    method doesBoxIntersect (line 27) | static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
    method doBoxesIntersect (line 64) | public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {

FILE: ch11/game/Physicist.java
  class Physicist (line 15) | public class Physicist implements GamePiece, ActionListener {
    method Physicist (line 34) | public Physicist() {
    method Physicist (line 41) | public Physicist(Color color) {
    method setAimingAngle (line 48) | public void setAimingAngle(Float angle) {
    method setAimingForce (line 52) | public void setAimingForce(Float force) {
    method setColor (line 64) | public void setColor(Color color) {
    method setPosition (line 68) | @Override
    method getPositionX (line 82) | @Override
    method getPositionY (line 87) | @Override
    method getBoundingBox (line 92) | @Override
    method setField (line 102) | public void setField(Field field) {
    method takeApple (line 113) | public Apple takeApple() {
    method getNewApple (line 122) | public void getNewApple() {
    method draw (line 129) | @Override
    method isTouching (line 149) | @Override
    method actionPerformed (line 158) | @Override

FILE: ch11/game/Tree.java
  class Tree (line 9) | public class Tree implements GamePiece {
    method setPosition (line 22) | @Override
    method getPositionX (line 31) | @Override
    method getPositionY (line 36) | @Override
    method getBoundingBox (line 41) | @Override
    method draw (line 46) | @Override
    method isTouching (line 54) | @Override

FILE: ch12/Post.java
  class Post (line 18) | public class Post extends JPanel implements ActionListener {
    method addGB (line 25) | void addGB( Component component, int x, int y ) {
    method Post (line 30) | public Post( String postURL ) {
    method actionPerformed (line 49) | public void actionPerformed(ActionEvent e) {
    method postData (line 53) | protected void postData(  ) {
    method main (line 98) | public static void main( String [] args ) {

FILE: ch12/Read.java
  class Read (line 10) | public class Read {
    method main (line 11) | public static void main(String args[]) {

FILE: ch13/ActionDemoLambda.java
  class ActionDemoLambda (line 12) | public class ActionDemoLambda {
    method main (line 13) | public static void main( String[] args ) {

FILE: ch13/ListItLambda.java
  class ListItLambda (line 10) | public class ListItLambda {
    method main (line 11) | public static void main ( String args[] ) throws Exception {

FILE: game/Apple.java
  class Apple (line 12) | public class Apple implements GamePiece {
    method Apple (line 40) | public Apple(Physicist owner) {
    method Apple (line 47) | public Apple(Physicist owner, int size) {
    method setSize (line 58) | public void setSize(int size) {
    method getDiameter (line 86) | public double getDiameter() {
    method setPosition (line 90) | @Override
    method getPositionX (line 103) | @Override
    method getPositionY (line 108) | @Override
    method getBoundingBox (line 113) | @Override
    method draw (line 118) | @Override
    method isTouching (line 125) | @Override
    method getCollidedPiece (line 156) | public GamePiece getCollidedPiece() {
    method setCollided (line 160) | public void setCollided(GamePiece otherPiece) {
    method toss (line 164) | public void toss(float angle, float velocity) {
    method step (line 172) | public void step() {

FILE: game/AppleToss.java
  class AppleToss (line 12) | public class AppleToss extends JFrame {
    method AppleToss (line 28) | public AppleToss() {
    method buildConstraints (line 67) | private GridBagConstraints buildConstraints(int row, int col, int rows...
    method buildRestartButton (line 76) | private JButton buildRestartButton() {
    method buildAngleControl (line 88) | private JSlider buildAngleControl() {
    method buildForceControl (line 101) | private JSlider buildForceControl() {
    method buildTossButton (line 112) | private JButton buildTossButton() {
    method setupFieldForOnePlayer (line 126) | private void setupFieldForOnePlayer() {
    method setupNetworkMenu (line 134) | private void setupNetworkMenu() {
    method main (line 172) | public static void main(String args[]) {

FILE: game/Field.java
  class Field (line 12) | public class Field extends JComponent implements ActionListener {
    method paintComponent (line 37) | protected void paintComponent(Graphics g) {
    method setPlayer (line 49) | public void setPlayer(Physicist p) {
    method actionPerformed (line 53) | public void actionPerformed(ActionEvent event) {
    method startTossFromPlayer (line 70) | public void startTossFromPlayer(Physicist physicist) {
    method cullFallenApples (line 90) | void cullFallenApples() {
    method detectCollisions (line 117) | void detectCollisions(Apple apple) {
    method hitPhysicist (line 140) | void hitPhysicist(Physicist physicist) {
    method hitTree (line 144) | void hitTree(Tree tree) {
    method startAnimation (line 151) | void startAnimation() {
    method getScore (line 165) | public String getScore(int playerNumber) {
    method setScore (line 169) | public void setScore(int playerNumber, String score) {
    method getWinner (line 179) | public String getWinner() {
    method goodX (line 200) | private int goodX() {
    method goodY (line 215) | private int goodY() {
    method setupNewGame (line 225) | public void setupNewGame() {
    class Animator (line 244) | class Animator implements Runnable {
      method run (line 245) | public void run() {

FILE: game/GamePiece.java
  type GamePiece (line 14) | public interface GamePiece {
    method setPosition (line 22) | void setPosition(int x, int y);
    method getPositionX (line 29) | int getPositionX();
    method getPositionY (line 36) | int getPositionY();
    method getBoundingBox (line 43) | Rectangle getBoundingBox();
    method draw (line 51) | void draw(Graphics g);
    method isTouching (line 60) | boolean isTouching(GamePiece otherPiece);

FILE: game/GameUtilities.java
  class GameUtilities (line 12) | public class GameUtilities {
    method isPointInsideBox (line 13) | static boolean isPointInsideBox(int x, int y, Rectangle box) {
    method doesBoxIntersect (line 27) | static boolean doesBoxIntersect(Rectangle box, Rectangle other) {
    method doBoxesIntersect (line 64) | public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {

FILE: game/Multiplayer.java
  class Multiplayer (line 9) | public class Multiplayer {
    method Multiplayer (line 20) | public Multiplayer(Field field) {
    method Multiplayer (line 24) | public Multiplayer(Field field, int port) {
    method startServer (line 29) | public void startServer() {
    method joinGame (line 40) | public void joinGame(String otherServer) {
    method startGame (line 45) | public void startGame() {
    method disconnect (line 49) | public void disconnect() {
    class Server (line 60) | class Server implements Runnable {
      method run (line 63) | public void run() {
      method stopListening (line 189) | public void stopListening() {
    class Client (line 200) | class Client implements Runnable {
      method Client (line 204) | public Client(String host) {
      method run (line 210) | public void run() {

FILE: game/Physicist.java
  class Physicist (line 9) | public class Physicist implements GamePiece, ActionListener {
    method Physicist (line 28) | public Physicist() {
    method Physicist (line 35) | public Physicist(Color color) {
    method setAimingAngle (line 42) | public void setAimingAngle(Float angle) {
    method setAimingForce (line 46) | public void setAimingForce(Float force) {
    method setColor (line 58) | public void setColor(Color color) {
    method setPosition (line 62) | @Override
    method getPositionX (line 76) | @Override
    method getPositionY (line 81) | @Override
    method getBoundingBox (line 86) | @Override
    method setField (line 96) | public void setField(Field field) {
    method takeApple (line 107) | public Apple takeApple() {
    method getNewApple (line 116) | public void getNewApple() {
    method draw (line 123) | @Override
    method isTouching (line 143) | @Override
    method actionPerformed (line 152) | @Override

FILE: game/Tree.java
  class Tree (line 5) | public class Tree implements GamePiece {
    method setPosition (line 18) | @Override
    method getPositionX (line 27) | @Override
    method getPositionY (line 32) | @Override
    method getBoundingBox (line 37) | @Override
    method draw (line 42) | @Override
    method isTouching (line 50) | @Override
Condensed preview — 92 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (251K chars).
[
  {
    "path": ".gitignore",
    "chars": 278,
    "preview": "# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Packa"
  },
  {
    "path": "LICENSE",
    "chars": 1060,
    "preview": "MIT License\n\nCopyright (c) 2019 l0y\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof thi"
  },
  {
    "path": "README.md",
    "chars": 98,
    "preview": "# learnjava5e\nCode examples for Learning Java, 5e by Marc Loy, Patrick Niemeyer, and Daniel Leuck\n"
  },
  {
    "path": "ch02/HelloJava.java",
    "chars": 391,
    "preview": "package ch02;\n\nimport javax.swing.*;\n\n/**\n * A bare bones graphical version of Hello World.\n */\npublic class HelloJava {"
  },
  {
    "path": "ch02/HelloJava2.java",
    "chars": 1405,
    "preview": "package ch02;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport javax.swing.*;\n\n/**\n * An upgraded graphical applicati"
  },
  {
    "path": "ch04/EuclidGCD.java",
    "chars": 520,
    "preview": "package ch04;\n\n/**\n * A basic implementation of Euclid's greatest common denominator\n * algorithm.\n *\n * https://en.wiki"
  },
  {
    "path": "ch05/Apple.java",
    "chars": 4751,
    "preview": "package ch05;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our physici"
  },
  {
    "path": "ch05/AppleToss.java",
    "chars": 1178,
    "preview": "package ch05;\n\nimport javax.swing.*;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main app"
  },
  {
    "path": "ch05/Field.java",
    "chars": 1979,
    "preview": "package ch05;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * The playing field for our game. This class will be under"
  },
  {
    "path": "ch05/GamePiece.java",
    "chars": 1447,
    "preview": "package ch05;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n *   -"
  },
  {
    "path": "ch05/HelloJava3.java",
    "chars": 1435,
    "preview": "package ch05;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport javax.swing.*;\n\n/**\n * Another (minor) upgrade to our "
  },
  {
    "path": "ch05/Physicist.java",
    "chars": 3093,
    "preview": "package ch05;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport stati"
  },
  {
    "path": "ch05/PrintAppleDetails.java",
    "chars": 892,
    "preview": "package ch05;\n\n/**\n * A simple demonstration of accessing the contents of an object. We create\n * a new apple and print "
  },
  {
    "path": "ch05/PrintAppleDetails2.java",
    "chars": 899,
    "preview": "package ch05;\n\n/**\n * Another quick example of working with an object. This time we print\n * the initial details of an a"
  },
  {
    "path": "ch05/PrintAppleDetails3.java",
    "chars": 581,
    "preview": "package ch05;\n\n/**\n * A variation on PrintAppleDetails2 where we have moved the printing code\n * to the Apple class. Not"
  },
  {
    "path": "ch05/PrintAppleDetails4.java",
    "chars": 532,
    "preview": "package ch05;\n\n/**\n * One final iteration of manipulating and printing apple details.\n * Now the Field class understands"
  },
  {
    "path": "ch05/Tree.java",
    "chars": 1738,
    "preview": "package ch05;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n *"
  },
  {
    "path": "ch06/Euclid2.java",
    "chars": 939,
    "preview": "package ch06;\n\n/**\n * A basic implementation of Euclid's greatest common denominator\n * algorithm. This version build on"
  },
  {
    "path": "ch06/LogTest.java",
    "chars": 830,
    "preview": "package ch06;\n\nimport java.util.logging.*;\n\n/**\n * A simple example of creating a logger and then using some of its meth"
  },
  {
    "path": "ch07/Apple.java",
    "chars": 4883,
    "preview": "/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the"
  },
  {
    "path": "ch07/AppleToss.java",
    "chars": 1342,
    "preview": "package ch07;\n\nimport javax.swing.*;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main app"
  },
  {
    "path": "ch07/Field.java",
    "chars": 1505,
    "preview": "package ch07;\n\nimport javax.swing.*;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.util.*;\n\n/**\n * The pl"
  },
  {
    "path": "ch07/GamePiece.java",
    "chars": 1487,
    "preview": "package ch07;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * Fro"
  },
  {
    "path": "ch07/GameUtilities.java",
    "chars": 2901,
    "preview": "package ch07;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/cir"
  },
  {
    "path": "ch07/Physicist.java",
    "chars": 4463,
    "preview": "package ch07;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport stati"
  },
  {
    "path": "ch07/Tree.java",
    "chars": 1749,
    "preview": "package ch07;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n *"
  },
  {
    "path": "ch08/Apple.java",
    "chars": 4924,
    "preview": "/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the"
  },
  {
    "path": "ch08/AppleToss.java",
    "chars": 3177,
    "preview": "package ch08;\n\nimport javax.swing.*;\nimport java.util.Random;\n\n/**\n * Our apple tossing game. This class extends JFrame "
  },
  {
    "path": "ch08/Field.java",
    "chars": 1953,
    "preview": "package ch08;\n\nimport javax.swing.*;\nimport javax.swing.Timer;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimp"
  },
  {
    "path": "ch08/GamePiece.java",
    "chars": 1487,
    "preview": "package ch08;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * Fro"
  },
  {
    "path": "ch08/GameUtilities.java",
    "chars": 2901,
    "preview": "package ch08;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/cir"
  },
  {
    "path": "ch08/Physicist.java",
    "chars": 4463,
    "preview": "package ch08;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport stati"
  },
  {
    "path": "ch08/Tree.java",
    "chars": 1749,
    "preview": "package ch08;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n *"
  },
  {
    "path": "ch09/URLConsumer.java",
    "chars": 1929,
    "preview": "package ch09;\n\nimport java.util.Random;\n\n/**\n * A threaded client for our URL producer. Uses a synchronized queue\n * to "
  },
  {
    "path": "ch09/URLDemo.java",
    "chars": 1609,
    "preview": "package ch09;\n\n/**\n * Manage multiple producers and consumers to demonstrate how\n * threads work in tandem. Creates a pa"
  },
  {
    "path": "ch09/URLProducer.java",
    "chars": 1899,
    "preview": "package ch09;\n\nimport java.util.Random;\n\n/**\n * Simple producer for use in our multithreaded example. Uses a synchronize"
  },
  {
    "path": "ch09/URLQueue.java",
    "chars": 557,
    "preview": "package ch09;\n\nimport java.util.LinkedList;\n\n/**\n * A manually synchronized wrapper for a LinkedList.\n * Allows for safe"
  },
  {
    "path": "ch09/game/Apple.java",
    "chars": 5942,
    "preview": "package ch09.game;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our ph"
  },
  {
    "path": "ch09/game/AppleToss.java",
    "chars": 3890,
    "preview": "package ch09.game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;"
  },
  {
    "path": "ch09/game/Field.java",
    "chars": 5739,
    "preview": "package ch09.game;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.Ac"
  },
  {
    "path": "ch09/game/GamePiece.java",
    "chars": 1492,
    "preview": "package ch09.game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n "
  },
  {
    "path": "ch09/game/GameUtilities.java",
    "chars": 2906,
    "preview": "package ch09.game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/40184"
  },
  {
    "path": "ch09/game/Physicist.java",
    "chars": 4727,
    "preview": "package ch09.game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport "
  },
  {
    "path": "ch09/game/Tree.java",
    "chars": 1754,
    "preview": "package ch09.game;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shap"
  },
  {
    "path": "ch10/ActionDemo1.java",
    "chars": 1119,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionL"
  },
  {
    "path": "ch10/ActionDemo2.java",
    "chars": 1592,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionL"
  },
  {
    "path": "ch10/BorderLayoutDemo.java",
    "chars": 1525,
    "preview": "package ch10;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n/**\n * A basic demonstration of the BorderLayout with higlighte"
  },
  {
    "path": "ch10/Buttons.java",
    "chars": 609,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * A very simple button placed on a frame. This button is\n "
  },
  {
    "path": "ch10/HelloJavaAgain.java",
    "chars": 447,
    "preview": "package ch10;\n\nimport javax.swing.*;\n\n/**\n * A simple label placed on a frame.\n */\npublic class HelloJavaAgain {\n    pub"
  },
  {
    "path": "ch10/HelloMouse.java",
    "chars": 1383,
    "preview": "package ch10;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseLis"
  },
  {
    "path": "ch10/HelloMouseHelper.java",
    "chars": 1304,
    "preview": "package ch10;\n\nimport java.awt.*;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swi"
  },
  {
    "path": "ch10/Labels.java",
    "chars": 2170,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * A simple demo of several label options with variations\n "
  },
  {
    "path": "ch10/MenuDemo.java",
    "chars": 1826,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionL"
  },
  {
    "path": "ch10/ModalDemo.java",
    "chars": 1169,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionL"
  },
  {
    "path": "ch10/NestedPanelDemo.java",
    "chars": 1400,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * An alternate way to arrange complex UIs. Rather than\n * "
  },
  {
    "path": "ch10/PhoneGridDemo.java",
    "chars": 1193,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * Demo of the GridLayout manager used to create a\n * dial "
  },
  {
    "path": "ch10/ProgressDemo.java",
    "chars": 2242,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionL"
  },
  {
    "path": "ch10/TextInputs.java",
    "chars": 1267,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * Some example text inputs including a text area embedded "
  },
  {
    "path": "ch10/Widget.java",
    "chars": 1872,
    "preview": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * A helper class aimed at making it easier to try out\n * t"
  },
  {
    "path": "ch10/game/Apple.java",
    "chars": 5942,
    "preview": "package ch10.game;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our ph"
  },
  {
    "path": "ch10/game/AppleToss.java",
    "chars": 7014,
    "preview": "package ch10.game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;"
  },
  {
    "path": "ch10/game/Field.java",
    "chars": 7230,
    "preview": "package ch10.game;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.Ac"
  },
  {
    "path": "ch10/game/GamePiece.java",
    "chars": 1491,
    "preview": "package ch10.game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n "
  },
  {
    "path": "ch10/game/GameUtilities.java",
    "chars": 2906,
    "preview": "package ch10.game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/40184"
  },
  {
    "path": "ch10/game/Physicist.java",
    "chars": 4727,
    "preview": "package ch10.game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport "
  },
  {
    "path": "ch10/game/Tree.java",
    "chars": 1754,
    "preview": "package ch10.game;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shap"
  },
  {
    "path": "ch11/CopyChannels.java",
    "chars": 702,
    "preview": "package ch11;\n\nimport java.io.*;\nimport java.nio.*;\nimport java.nio.channels.*;\n\n/**\n * A quick demo of copying files us"
  },
  {
    "path": "ch11/CopyChannels2.java",
    "chars": 709,
    "preview": "package ch11;\n\nimport java.io.*;\nimport java.nio.*;\nimport java.nio.channels.*;\n\n/**\n * A quick demo of copying files us"
  },
  {
    "path": "ch11/CopyChannels3.java",
    "chars": 596,
    "preview": "package ch11;\n\nimport java.io.*;\nimport java.nio.*;\nimport java.nio.channels.*;\n\n/**\n * A quick demo of copying files us"
  },
  {
    "path": "ch11/CopyFile.java",
    "chars": 846,
    "preview": "package ch11;\n\nimport java.nio.channels.*;\nimport java.nio.file.*;\nimport static java.nio.file.StandardOpenOption.*;\n\n/*"
  },
  {
    "path": "ch11/CopyStreams.java",
    "chars": 677,
    "preview": "package ch11;\n\nimport java.io.*;\n\n/**\n * A quick demo of copying files using basic streams.\n * The names of the source a"
  },
  {
    "path": "ch11/DateAtHost.java",
    "chars": 692,
    "preview": "//file: DateAtHost.java\nimport java.net.Socket;\nimport java.io.*;\n\npublic class DateAtHost extends java.util.Date {\n    "
  },
  {
    "path": "ch11/ListIt.java",
    "chars": 1132,
    "preview": "package ch11;\n\nimport java.io.*;\n\n/**\n * A quick demo of file and directory operations. If the file\n * exists and is a d"
  },
  {
    "path": "ch11/game/Apple.java",
    "chars": 5942,
    "preview": "package ch11.game;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our ph"
  },
  {
    "path": "ch11/game/AppleToss.java",
    "chars": 8460,
    "preview": "package ch11.game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;"
  },
  {
    "path": "ch11/game/Field.java",
    "chars": 6562,
    "preview": "package ch11.game;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.Ac"
  },
  {
    "path": "ch11/game/GamePiece.java",
    "chars": 1491,
    "preview": "package ch11.game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n "
  },
  {
    "path": "ch11/game/GameUtilities.java",
    "chars": 2906,
    "preview": "package ch11.game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/40184"
  },
  {
    "path": "ch11/game/Physicist.java",
    "chars": 4727,
    "preview": "package ch11.game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport "
  },
  {
    "path": "ch11/game/Tree.java",
    "chars": 1754,
    "preview": "package ch11.game;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shap"
  },
  {
    "path": "ch12/Post.java",
    "chars": 3511,
    "preview": "package ch12;\n\nimport java.net.*;\nimport java.io.*;\nimport java.awt.*;\nimport java.awt.event.*;\nimport javax.swing.*;\n\n/"
  },
  {
    "path": "ch12/Read.java",
    "chars": 896,
    "preview": "package ch12;\n\nimport java.io.*;\nimport java.net.*;\n\n/**\n * A simple command line demonstration of reading from a URL.\n "
  },
  {
    "path": "ch13/ActionDemoLambda.java",
    "chars": 1099,
    "preview": "package ch13;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionL"
  },
  {
    "path": "ch13/ListItLambda.java",
    "chars": 1106,
    "preview": "package ch13;\n\nimport java.io.*;\nimport java.util.Arrays;\n\n/**\n * An update to ListIt from ch11 with a lambda expression"
  },
  {
    "path": "game/Apple.java",
    "chars": 5937,
    "preview": "/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the"
  },
  {
    "path": "game/AppleToss.java",
    "chars": 6439,
    "preview": "package game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimpo"
  },
  {
    "path": "game/Field.java",
    "chars": 9074,
    "preview": "package game;\n\nimport javax.swing.*;\nimport javax.swing.Timer;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimp"
  },
  {
    "path": "game/GamePiece.java",
    "chars": 1487,
    "preview": "package game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * Fro"
  },
  {
    "path": "game/GameUtilities.java",
    "chars": 2901,
    "preview": "package game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/cir"
  },
  {
    "path": "game/Multiplayer.java",
    "chars": 14090,
    "preview": "package game;\n\nimport javax.swing.*;\nimport java.io.*;\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java"
  },
  {
    "path": "game/Physicist.java",
    "chars": 4449,
    "preview": "package game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport stati"
  },
  {
    "path": "game/Tree.java",
    "chars": 1584,
    "preview": "package game;\n\nimport java.awt.*;\n\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    pr"
  }
]

About this extraction

This page contains the full source code of the l0y/learnjava5e GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 92 files (231.9 KB), approximately 55.5k tokens, and a symbol index with 587 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!