[
  {
    "path": ".gitignore",
    "content": "# 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# Package Files #\n*.jar\n*.war\n*.nar\n*.ear\n*.zip\n*.tar.gz\n*.rar\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 l0y\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# learnjava5e\nCode examples for Learning Java, 5e by Marc Loy, Patrick Niemeyer, and Daniel Leuck\n"
  },
  {
    "path": "ch02/HelloJava.java",
    "content": "package ch02;\n\nimport javax.swing.*;\n\n/**\n * A bare bones graphical version of Hello World.\n */\npublic class HelloJava {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"Hello, Java!\" );\n        JLabel label = new JLabel(\"Hello, Java!\", JLabel.CENTER );\n        frame.add(label);\n        frame.setSize( 300, 300 );\n        frame.setVisible( true );\n    }\n}\n"
  },
  {
    "path": "ch02/HelloJava2.java",
    "content": "package ch02;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport javax.swing.*;\n\n/**\n * An upgraded graphical application with interactivity!\n */\npublic class HelloJava2 {\n\tpublic static void main( String[] args ) {\n    \tJFrame frame = new JFrame( \"HelloJava2\" );\n\t\tframe.add( new HelloComponent2(\"Hello, Java!\") );\n\t\tframe.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );\n\t\tframe.setSize( 300, 300 );\n\t\tframe.setVisible( true );\n\t}\n}\n\n/*\n * Inheritence (the \"extends\" keyword below) and interfaces\n * (the \"implements MouseMotionListener\" portion) are covered in\n * Chapter 5.\n */\nclass HelloComponent2 extends JComponent implements MouseMotionListener {\n\tString theMessage;\n\tint messageX = 125, messageY = 95; // Coordinates of the message\n\n\t/**\n\t * Create a new component that can draw its message at an arbitrary position.\n\t * That position can be changed by dragging the mouse; we attach a listener\n\t * to pick up those drag events.\n\t */\n\tpublic HelloComponent2( String message ) {\n    \ttheMessage = message;\n    \taddMouseMotionListener(this);\n\t}\n\n\tpublic void paintComponent( Graphics g ) {\n    \tg.drawString( theMessage, messageX, messageY );\n\t}\n\n\tpublic void mouseDragged(MouseEvent e) {\n    \t// Save the mouse coordinates and paint the message.\n    \tmessageX = e.getX();\n    \tmessageY = e.getY();\n    \trepaint();\n\t}\n\n  \tpublic void mouseMoved(MouseEvent e) { \n\t\t// Ignore simple movements\n\t}\n}\n"
  },
  {
    "path": "ch04/EuclidGCD.java",
    "content": "package ch04;\n\n/**\n * A basic implementation of Euclid's greatest common denominator\n * algorithm.\n *\n * https://en.wikipedia.org/wiki/Algorithm\n */\npublic class EuclidGCD {\n    public static void main(String args[]) {\n\t\t// For now, just \"hard code\" the two numbers to compare\n        int a = 2701;\n        int b = 222;\n        while (b != 0) {\n            if (a > b) {\n                a = a - b;\n            } else {\n                b = b - a;\n            }\n        }\n        System.out.println(\"GCD is \" + a);\n    }\n}\n"
  },
  {
    "path": "ch05/Apple.java",
    "content": "package ch05;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the size and weight details. We'll expand this class as we cover more topics.\n */\npublic class Apple implements GamePiece {\n    float mass;\n    float diameter = 1.0f;\n    int x, y;\n    int size;\n\n    // Setup some size constants\n    public static final int SMALL = 0;\n    public static final int MEDIUM = 1;\n    public static final int LARGE = 2;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int centerX, centerY;\n    int scaledLength;\n\n    // Boundary helper for optimizing collision detection with physicists and trees\n    Rectangle boundingBox;\n\n    // If we bumped into something, keep a reference to that thing around for cleanup and removal\n    GamePiece collided;\n\n    /**\n     * Create a default, Medium apple\n     */\n    public Apple() {\n        this(MEDIUM);\n    }\n\n    /**\n     * Create an Apple of the given size\n     */\n    public Apple(int size) {\n        setSize(size);\n    }\n\n    /**\n     * Sets the size (and dependent properties) of the apple based on the\n     * supplied value which must be one of the size constants.\n     *\n     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE\n     */\n    public void setSize(int size) {\n        if (size < SMALL) {\n            size = SMALL;\n        }\n        if (size > LARGE) {\n            size = LARGE;\n        }\n        this.size = size;\n        switch (size) {\n            case SMALL:\n                diameter = 0.9f;\n                mass = 0.5f;\n                break;\n            case MEDIUM:\n                diameter = 1.0f;\n                mass = 1.0f;\n                break;\n            case LARGE:\n                diameter = 1.1f;\n                mass = 1.8f;\n                break;\n        }\n        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.\n        // Since we want a circle, we simply make our box a square so we only need one length.\n        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    public double getDiameter() {\n        return diameter;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of the apple, but it will be drawn from the\n        // upper left corner, so figure out the distance of that gap\n        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our apple will be red, then paint it!\n        g.setColor(Color.RED);\n        g.fillOval(x, y, scaledLength, scaledLength);\n    }\n\n    /**\n     * Determine whether or not this apple is touching another piece.\n     */\n    public boolean isTouching(GamePiece other) {\n        double xdiff = x - other.getPositionX();\n        double ydiff = y - other.getPositionY();\n        double distance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);\n        // For now, we can only really collide with other apples.\n        // Just cheat a little and assume the other piece is in fact\n        // an apple, and an apple with the same diameter. We'll fix\n        // this as we fill out the other game pieces in later chapters.\n        if (distance < diameter) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    public void printDetails() {\n        System.out.println(\"  mass: \" + mass);\n        // Print the exact diameter:\n        //System.out.println(\"  diameter: \" + diameter);\n        // Or a nice, human-friendly approximate:\n        String niceNames[] = getAppleSizes();\n        if (diameter < 5.0f) {\n            System.out.println(niceNames[SMALL]);\n        } else if (diameter < 10.0f) {\n            System.out.println(niceNames[MEDIUM]);\n        } else {\n            System.out.println(niceNames[LARGE]);\n        }\n        System.out.println(\"  position: (\" + x + \", \" + y +\")\");\n    }\n\n    public static String[] getAppleSizes() {\n        // Return names for our constants\n        // The index of the name should match the value of the constant\n        return new String[] { \"SMALL\", \"MEDIUM\", \"LARGE\" };\n    }\n}\n"
  },
  {
    "path": "ch05/AppleToss.java",
    "content": "package ch05;\n\nimport javax.swing.*;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main application window. We'll be filling this out along the way, \n * but for now we can setup a field with some trees and our player.\n */\npublic class AppleToss extends JFrame {\n\n    Field field = new Field();\n    Physicist player1 = new Physicist();\n\n    public AppleToss() {\n        // Create our frame\n        super(\"Apple Toss Game\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n\t\tsetSize(800,600);\n        setResizable(false);\n\n        // Build the field with our player and some trees\n        setupFieldForOnePlayer();\n    }\n\n    /**\n     * A helper method to populate a one player field with target trees.\n     */\n    private void setupFieldForOnePlayer() {\n        // Place our (new) physicist in the lower left corner and connect them to the field\n        player1.setPosition(100,500);\n        field.setPlayer(player1);\n        player1.setField(field);\n\t\tfield.setupApples();\n\t\tfield.setupTree();\n\t\tadd(field);\n    }\n\n    public static void main(String args[]) {\n        AppleToss game = new AppleToss();\n        game.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch05/Field.java",
    "content": "package ch05;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * The playing field for our game. This class will be undergoing quite a few\n * changes as we learn about more of Java's features in coming chapters.\n * For now, we can demonstrate how to work with member variables like a1 and a2\n * as well as how to create new methods like setupApples() and detectCollisions().\n */\npublic class Field extends JComponent {\n    public static final float GRAVITY = 9.8f;  // feet per second per second\n    public static final int STEP = 40;   // duration of an animation frame in milliseconds\n    public static final int APPLE_SIZE_IN_PIXELS = 30;\n    public static final int TREE_WIDTH_IN_PIXELS = 60;\n    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;\n    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;\n    public static final int MAX_TREES = 12;\n\n    Color fieldColor = Color.GRAY;\n\n    Apple a1 = new Apple();\n    Apple a2 = new Apple();\n\tTree tree = new Tree();\n\tPhysicist physicist;\n\n    public void setupApples() {\n\t\t// For now, just play with our apple attributes directly\n        a1.diameter = 3.0f;\n        a1.mass = 5.0f;\n        a1.x = 20;\n        a1.y = 40;\n        a2.diameter = 8.0f;\n        a2.mass = 10.0f;\n        a2.x = 70;\n        a2.y = 200;\n    }\n\t\n\tpublic void setupTree() {\n\t\t// Unlike apples, we'll use the setPosition() method from our\n\t\t// GamePiece interface to setup our lonely tree\n\t\ttree.setPosition(500,200);\n\t}\n\n    public void setPlayer(Physicist p) {\n        physicist = p;\n    }\n\t\n    protected void paintComponent(Graphics g) {\n        g.setColor(fieldColor);\n        g.fillRect(0,0, getWidth(), getHeight());\n        tree.draw(g);\n        physicist.draw(g);\n\t\ta1.draw(g);\n\t\ta2.draw(g);\n    }\n\n    public void detectCollisions() {\n        if (a1.isTouching(a2)) {\n            System.out.println(\"Collision detected!\");\n        } else {\n            System.out.println(\"Apples are not touching.\");\n        }\n    }\n}\n"
  },
  {
    "path": "ch05/GamePiece.java",
    "content": "package ch05;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n *   - methods for positioning on a Field\n *   - methods for Drawing\n *   - methods for detecting a collision with other GamePieces\n */\n\npublic interface GamePiece {\n    /**\n     * Sets the position of the piece on the playing field.\n     * (0,0) is the upper left per standard Java drawing methods.\n     *\n     * @param x\n     * @param y\n     */\n    void setPosition(int x, int y);\n\n    /**\n     * Gets the current horizontal position of the piece on the field.\n     *\n     * @return current X position of the piece\n     */\n    int getPositionX();\n\n    /**\n     * Gets the current vertical position of the piece on the field.\n     *\n     * @return current Y position of the piece\n     */\n    int getPositionY();\n\n    /**\n     * Gets the bounding box of this piece.\n     *\n     * @return a Rectangle encompassing the visual elements of the piece\n     */\n    Rectangle getBoundingBox();\n\n    /**\n     * Draws the piece inside the given graphics context.\n     * Do not assume anything about the state of the context.\n     *\n     * @param g\n     */\n    void draw(Graphics g);\n\n    /**\n     * Detect a collision with another piece on the field.\n     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).\n     *\n     * @param otherPiece\n     * @return\n     */\n    boolean isTouching(GamePiece otherPiece);\n}\n"
  },
  {
    "path": "ch05/HelloJava3.java",
    "content": "package ch05;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport javax.swing.*;\n\n/**\n * Another (minor) upgrade to our graphical Hello, World example.\n * This variation introduces an inner class for the message component\n * and an anonymous inner class for the listener handling the mouse\n * drag events. (More on events and listeners in Chapter 10.)\n */\npublic class HelloJava3 extends JFrame {\n    public static void main( String[] args ) {\n        HelloJava3 demo = new HelloJava3();\n        demo.setVisible( true );\n    }\n\n    public HelloJava3() {\n        super( \"HelloJava3\" );\n        add( new HelloComponent3(\"Hello, Inner Java!\") );\n        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );\n        setSize( 300, 300 );\n    }\n\n    class HelloComponent3 extends JComponent {\n        String theMessage;\n        int messageX = 125, messageY = 95; // Coordinates of the message\n\n        public HelloComponent3( String message ) {\n            theMessage = message;\n            addMouseMotionListener(new MouseMotionListener() {\n                public void mouseDragged(MouseEvent e) {\n                    messageX = e.getX();\n                    messageY = e.getY();\n                    repaint();\n                }\n\n                public void mouseMoved(MouseEvent e) { }\n            });\n        }\n\n        public void paintComponent( Graphics g ) {\n            g.drawString( theMessage, messageX, messageY );\n        }\n    }\n}\n"
  },
  {
    "path": "ch05/Physicist.java",
    "content": "package ch05;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport static java.awt.Color.*;\n\n/**\n * Our player class. A physicist can aim where to toss an apple in addition\n * to implementing the basic methods for GamePiece. We can also set a custom\n * color in case you build on the game and allow multiple physicists to be\n * on the screen at the same time.\n */\npublic class Physicist implements GamePiece {\n    Color color;\n    int centerX, centerY;\n    float aimingAngle;\n    float aimingForce;\n    Field field;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n\n    // Boundary helpers\n    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);\n    private Rectangle boundingBox;\n\n\n    /**\n     * Create a default, blue physicist\n     */\n    public Physicist() {\n        this(BLUE);\n    }\n\n    /**\n     * Create a Physicist of the given color\n     */\n    public Physicist(Color color) {\n        setColor(color);\n        aimingAngle = 90.0f;\n        aimingForce = 50.0f;\n    }\n\n    public void setAimingAngle(Float angle) {\n        aimingAngle = angle;\n    }\n\n    public void setAimingForce(Float force) {\n        if (force < 0) {\n            force = 0.0f;\n        }\n        aimingForce = force;\n    }\n\n    /**\n     * Sets the color for the physicist.\n     *\n     * @param color\n     */\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of our dome,\n        // but it will be drawn from the upper left corner.\n        // Figure out the distance of that gap\n        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    /**\n     * Sets the active field once our physicist is being displayed.\n     *\n     * @param field Active game field\n     */\n    public void setField(Field field) {\n        this.field = field;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our physicist is the right color, then draw the semi-circle and box\n        g.setColor(color);\n        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);\n        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n\t\t// We don't really have any collisions to detect yet, so just return \"no\".\n\t\t// As we fill out all of the game pieces, we'll come back to this method\n\t\t// and provide a more useful response.\n\t\treturn false;\n    }\n}\n"
  },
  {
    "path": "ch05/PrintAppleDetails.java",
    "content": "package ch05;\n\n/**\n * A simple demonstration of accessing the contents of an object. We create\n * a new apple and print out some of its details.\n */\npublic class PrintAppleDetails {\n    public static void main(String args[]) {\n        String niceNames[] = Apple.getAppleSizes();\n        Apple a1 = new Apple();\n        System.out.println(\"Apple a1:\");\n        System.out.println(\"  mass: \" + a1.mass);\n        System.out.println(\"  diameter: \" + a1.diameter);\n        System.out.println(\"  position: (\" + a1.x + \", \" + a1.y +\")\");\n        if (a1.diameter < 5.0f) {\n            System.out.println(\"This is a \" + niceNames[Apple.SMALL] + \" apple.\");\n        } else if (a1.diameter < 10.0f) {\n            System.out.println(\"This is a \" + niceNames[Apple.MEDIUM] + \" apple.\");\n        } else {\n            System.out.println(\"This is a \" + niceNames[Apple.LARGE] + \" apple.\");\n        }\n    }\n}\n"
  },
  {
    "path": "ch05/PrintAppleDetails2.java",
    "content": "package ch05;\n\n/**\n * Another quick example of working with an object. This time we print\n * the initial details of an apple, change some of those details, and\n * then do the same printing to provide a comparison of the results.\n */\npublic class PrintAppleDetails2 {\n    public static void main(String args[]) {\n        Apple a1 = new Apple();\n        System.out.println(\"Apple a1:\");\n        System.out.println(\"  mass: \" + a1.mass);\n        System.out.println(\"  diameter: \" + a1.diameter);\n        System.out.println(\"  position: (\" + a1.x + \", \" + a1.y +\")\");\n        // fill in some information on a1\n        a1.mass = 10.0f;\n        a1.x = 20;\n        a1.y = 42;\n        System.out.println(\"Updated a1:\");\n        System.out.println(\"  mass: \" + a1.mass);\n        System.out.println(\"  diameter: \" + a1.diameter);\n        System.out.println(\"  position: (\" + a1.x + \", \" + a1.y +\")\");\n    }\n}\n"
  },
  {
    "path": "ch05/PrintAppleDetails3.java",
    "content": "package ch05;\n\n/**\n * A variation on PrintAppleDetails2 where we have moved the printing code\n * to the Apple class. Notice that this file is smaller than PrintAppleDetails2\n * meaning fewer lines to make mistakes!\n */\npublic class PrintAppleDetails3 {\n    public static void main(String args[]) {\n        Apple a1 = new Apple();\n        System.out.println(\"Apple a1:\");\n        a1.printDetails();\n        // fill in some information on a1\n        a1.mass = 10.0f;\n        a1.x = 20;\n        a1.y = 42;\n        System.out.println(\"Updated a1:\");\n        a1.printDetails();\n    }\n}\n"
  },
  {
    "path": "ch05/PrintAppleDetails4.java",
    "content": "package ch05;\n\n/**\n * One final iteration of manipulating and printing apple details.\n * Now the Field class understands apples so we access those apples\n * through the field object. Notice the double dot-notation.\n */\npublic class PrintAppleDetails4 {\n    public static void main(String args[]) {\n        Field f = new Field();\n        f.setupApples();\n        System.out.println(\"Apple a1:\");\n        f.a1.printDetails();\n        System.out.println(\"Apple a2:\");\n        f.a2.printDetails();\n        f.detectCollisions();\n    }\n}\n"
  },
  {
    "path": "ch05/Tree.java",
    "content": "package ch05;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n * They are built using sizes determined by the constants in the Field class.\n */\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    private Color leafColor = Color.GREEN.darker();\n    private Color trunkColor = new Color(101, 67, 33);\n    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);\n    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);\n    private int trunkX, trunkY;\n\n    // Boundary helpers\n    private Rectangle boundingBox;\n\n    @Override\n    public void setPosition(int x, int y) {\n        this.x = x;\n        this.y = y;\n        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;\n        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;\n        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);\n    }\n\n    @Override\n    public int getPositionX() {\n        return x;\n    }\n\n    @Override\n    public int getPositionY() {\n        return y;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        g.setColor(trunkColor);\n        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);\n        g.setColor(leafColor);\n        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n\t\t// We don't really have any collisions to detect yet, so just return \"no\".\n\t\t// As we fill out all of the game pieces, we'll come back to this method\n\t\t// and provide a more useful response.\n\t\treturn false;\n    }\n}\n"
  },
  {
    "path": "ch06/Euclid2.java",
    "content": "package ch06;\n\n/**\n * A basic implementation of Euclid's greatest common denominator\n * algorithm. This version build on ch04 allowing you to pass the\n * numbers to use as command line arguments.\n */\npublic class Euclid2 {\n    public static void main(String args[]) {\n        int a = 2701;\n        int b = 222;\n\t\t// Only try to parse arguments if we have exactly 2\n\t\tif (args.length == 2) {\n\t\t\ttry {\n\t\t\t\ta = Integer.parseInt(args[0]);\n\t\t\t\tb = Integer.parseInt(args[1]);\n\t\t\t} catch (NumberFormatException nfe) {\n\t\t\t\tSystem.err.println(\"Arguments were not both numbers. Using defaults.\");\n\t\t\t}\n\t\t} else {\n\t\t\tSystem.err.println(\"Wrong number of arguments (expected 2). Using defaults.\");\n\t\t}\n\t\tSystem.out.print(\"The GCD of \" + a + \" and \" + b + \" is \");\n        while (b != 0) {\n            if (a > b) {\n                a = a - b;\n            } else {\n                b = b - a;\n            }\n        }\n        System.out.println(a);\n    }\n}\n"
  },
  {
    "path": "ch06/LogTest.java",
    "content": "package ch06;\n\nimport java.util.logging.*;\n\n/**\n * A simple example of creating a logger and then using some of its methods.\n * For homework, try adjusting the log level where the comment is and see\n * which lines of output you still get on the console.\n */ \npublic class LogTest {\n    public static void main(String argv[]) {\n        Logger logger = Logger.getLogger(\"com.oreilly.LogTest\");\n\n\t\t// try setting the log level here\n        logger.severe(\"Power lost - running on backup!\");\n        logger.warning(\"Database connection lost, retrying...\");\n        logger.info(\"Startup complete.\");\n        logger.config(\"Server configuration: standalone, JVM version 1.5\");\n        logger.fine(\"Loading graphing package.\");\n        logger.finer(\"Doing pie chart\");\n        logger.finest(\"Starting bubble sort: value =\" + 42);\n    }\n}\n"
  },
  {
    "path": "ch07/Apple.java",
    "content": "/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the size and weight details and provide a few simple methods for lobbing.\n */\npackage ch07;\n\nimport java.awt.*;\n\npublic class Apple implements GamePiece {\n    public static final int SMALL  = 0;\n    public static final int MEDIUM = 1;\n    public static final int LARGE  = 2;\n\n    int size;\n    double diameter;\n    double mass;\n    int centerX, centerY;\n    Physicist myPhysicist;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n    int scaledLength;\n\n    // Boundary helper for optimizing collision detection with physicists and trees\n    Rectangle boundingBox;\n\n    // If we bumped into something, keep a reference to that thing around for cleanup and removal\n    GamePiece collided;\n\n    /**\n     * Create a default, Medium apple\n     */\n    public Apple(Physicist owner) {\n        this(owner, MEDIUM);\n    }\n\n    /**\n     * Create an Apple of the given size\n     */\n    public Apple(Physicist owner, int size) {\n        myPhysicist = owner;\n        setSize(size);\n    }\n\n    /**\n     * Sets the size (and dependent properties) of the apple based on the\n     * supplied value which must be one of the size constants.\n     *\n     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE\n     */\n    public void setSize(int size) {\n        if (size < SMALL) {\n            size = SMALL;\n        }\n        if (size > LARGE) {\n            size = LARGE;\n        }\n        this.size = size;\n        switch (size) {\n            case SMALL:\n                diameter = 0.9;\n                mass = 0.5;\n                break;\n            case MEDIUM:\n                diameter = 1.0;\n                mass = 1.0;\n                break;\n            case LARGE:\n                diameter = 1.1;\n                mass = 1.8;\n                break;\n        }\n        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.\n        // Since we want a circle, we simply make our box a square so we only need one length.\n        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    public double getDiameter() {\n        return diameter;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of the apple, but it will be drawn from the\n        // upper left corner, so figure out the distance of that gap\n        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our apple will be red, then paint it!\n        g.setColor(Color.RED);\n        g.fillOval(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {\n            // By definition we don't collide with ourselves, our physicist, or with more than one other piece\n            return false;\n        }\n        if (otherPiece instanceof Apple) {\n            // The other piece is an apple, so we can do a simple distance calculation using\n            // the diameters of both apples.\n            Apple otherApple = (Apple) otherPiece;\n            int v = this.y - otherPiece.getPositionY(); // vertical difference\n            int h = this.x - otherPiece.getPositionX(); // horizontal difference\n            double distance = Math.sqrt(v * v + h * h);\n\n            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;\n            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;\n            if (distance < (myRadius + otherRadius)) {\n                // Since apples track collisions, we'll update the other apple to keep everyone in sync\n                setCollided(otherPiece);\n                otherApple.setCollided(this);\n                return true;\n            }\n            return false;\n        }\n        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {\n            setCollided(otherPiece);\n            return true;\n        }\n        return false;\n    }\n\n    public GamePiece getCollidedPiece() {\n        return collided;\n    }\n\n    public void setCollided(GamePiece otherPiece) {\n        this.collided = otherPiece;\n    }\n}\n"
  },
  {
    "path": "ch07/AppleToss.java",
    "content": "package ch07;\n\nimport javax.swing.*;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main application window. We'll be filling this out along the way, \n * but for now we can setup a field with some trees and our player.\n */\npublic class AppleToss extends JFrame {\n\n    Field field = new Field();\n    Physicist player1 = new Physicist();\n\n    public AppleToss() {\n        // Create our frame\n        super(\"Apple Toss Game\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n\t\tsetSize(800,600);\n        setResizable(false);\n\n        // Build the field with our player and some trees\n        setupFieldForOnePlayer();\n    }\n\n    /**\n     * A helper method to populate a one player field with target trees.\n     */\n    private void setupFieldForOnePlayer() {\n        // Place our (new) physicist in the lower left corner and connect them to the field\n        player1.setPosition(100,500);\n        field.setPlayer(player1);\n        player1.setField(field);\n\t\t\n\t\t// And now make a few trees for target practice\n\t    for (int row = 1; row <= 2; row++) {\n\t        for (int col = 1; col <=3; col++) {\n\t            field.addTree(col * 100, row * 100);\n\t        }\n\t    }\n\t\tadd(field);\n    }\n\n    public static void main(String args[]) {\n        AppleToss game = new AppleToss();\n        game.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch07/Field.java",
    "content": "package ch07;\n\nimport javax.swing.*;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.util.*;\n\n/**\n * The playing field for our game. Now we can setup some constants for\n * other game classes to use and create member variables for our player and some trees.\n */\npublic class Field extends JComponent {\n    public static final float GRAVITY = 9.8f;  // feet per second per second\n    public static final int STEP = 40;   // duration of an animation frame in milliseconds\n    public static final int APPLE_SIZE_IN_PIXELS = 30;\n    public static final int TREE_WIDTH_IN_PIXELS = 60;\n    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;\n    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;\n    public static final int MAX_TREES = 12;\n\n    Color fieldColor = Color.GRAY;\n    Random random = new Random();\n\n    // List and ArrayList are covered in chapter 8 on Generics\n    // synchronizedArrayList is covered in chapter 9 on Threads\n    Physicist physicist;\n    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(fieldColor);\n        g.fillRect(0,0, getWidth(), getHeight());\n        for (Tree t : trees) {\n            t.draw(g);\n        }\n        physicist.draw(g);\n    }\n\n    public void setPlayer(Physicist p) {\n        physicist = p;\n    }\n\t\n    public void addTree(int x, int y) {\n        Tree tree = new Tree();\n        tree.setPosition(x,y);\n        trees.add(tree);\n    }\n}\n"
  },
  {
    "path": "ch07/GamePiece.java",
    "content": "package ch07;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * From the README:\n * GamePiece\n *   - methods for positioning on a PlayingField\n *   - methods for Drawing\n *   - methods for detecting a collision with other GamePieces\n */\n\npublic interface GamePiece {\n    /**\n     * Sets the position of the piece on the playing field.\n     * (0,0) is the upper left per standard Java drawing methods.\n     *\n     * @param x\n     * @param y\n     */\n    void setPosition(int x, int y);\n\n    /**\n     * Gets the current horizontal position of the piece on the field.\n     *\n     * @return current X position of the piece\n     */\n    int getPositionX();\n\n    /**\n     * Gets the current vertical position of the piece on the field.\n     *\n     * @return current Y position of the piece\n     */\n    int getPositionY();\n\n    /**\n     * Gets the bounding box of this piece.\n     *\n     * @return a Rectangle encompassing the visual elements of the piece\n     */\n    Rectangle getBoundingBox();\n\n    /**\n     * Draws the piece inside the given graphics context.\n     * Do not assume anything about the state of the context.\n     *\n     * @param g\n     */\n    void draw(Graphics g);\n\n    /**\n     * Detect a collision with another piece on the field.\n     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).\n     *\n     * @param otherPiece\n     * @return\n     */\n    boolean isTouching(GamePiece otherPiece);\n}\n"
  },
  {
    "path": "ch07/GameUtilities.java",
    "content": "package ch07;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection\n\nimport java.awt.*;\n\n/**\n * Utility class with a few helper methods for calculating various collisions and\n * intersections.\n */\npublic class GameUtilities {\n    static boolean isPointInsideBox(int x, int y, Rectangle box) {\n        // Our own custom test. We could of course use box.contains(),\n        // but we can practice some interesting conditional checking here.\n        // Let's test left and right first\n        if (x >= box.x && x <= (box.x + box.width)) {\n            // Our x coordinate is ok, so check our y\n            if (y >= box.y && y <= (box.y + box.height)) {\n                return true;\n            }\n        }\n        // x or y was outside the box, so return false\n        return false;\n    }\n\n    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {\n        // If any of the four corners of box are inside other, we intersect, so\n        // let's check each one. Happily, that answer doesn't change if more\n        // than one corner is contained in other, so we can return as soon as\n        // we find the first contained corner.\n\n        // Let's get some local copies of the corner coordinates\n        // to make the call arguments easier to read.\n        int x1 = box.x;\n        int y1 = box.y;\n        int x2 = x1 + box.width;\n        int y2 = y1 + box.height;\n        if (isPointInsideBox(x1, y1, other)) {\n            // upper left\n            return true;\n        } else if (isPointInsideBox(x1, y2, other)) {\n            // lower left\n            return true;\n        } else if (isPointInsideBox(x2, y1, other)) {\n            // upper right\n            return true;\n        } else if (isPointInsideBox(x2, y2, other)) {\n            // lower right\n            return true;\n        }\n        // No box points in other so no intersection\n        return false;\n    }\n\n    /**\n     * Given two rectangles, do the overlap at all? This includes one box being\n     * completely contained by the other box.\n     *\n     * @param box1 a box to test, order does not matter\n     * @param box2 the other box\n     * @return true if the boxes overlap, false otherwise\n     */\n    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {\n        // Another custom test. We could of course use box1.intersects(box2)\n        // but we can practice method calls and some boolean logic here.\n        if (doesBoxIntersect(box1, box2)) {\n            // At least one of box1's points must be inside box2\n            return true;\n        } else if (doesBoxIntersect(box2, box1)) {\n            // None of box1's points were in box2, but at least one of box2's points are inside box1\n            return true;\n        }\n        // No intersections in either direction\n        return false;\n    }\n}\n"
  },
  {
    "path": "ch07/Physicist.java",
    "content": "package ch07;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport static java.awt.Color.*;\n\n/**\n * Our player class. A physicist has an apple that they can throw in addition\n * to implementing the basic methods for GamePiece. We can also set a custom\n * color in case you build on the game and allow multiple physicists to be\n * on the screen at the same time.\n */\npublic class Physicist implements GamePiece {\n    Color color;\n    int centerX, centerY;\n    Apple aimingApple;\n    float aimingAngle;\n    float aimingForce;\n    Field field;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n\n    // Boundary helpers\n    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);\n    private Rectangle boundingBox;\n\n\n    /**\n     * Create a default, blue physicist\n     */\n    public Physicist() {\n        this(BLUE);\n    }\n\n    /**\n     * Create a Physicist of the given color\n     */\n    public Physicist(Color color) {\n        setColor(color);\n        aimingAngle = 90.0f;\n        aimingForce = 50.0f;\n        getNewApple();\n    }\n\n    public void setAimingAngle(Float angle) {\n        aimingAngle = angle;\n    }\n\n    public void setAimingForce(Float force) {\n        if (force < 0) {\n            force = 0.0f;\n        }\n        aimingForce = force;\n    }\n\n    /**\n     * Sets the color for the physicist.\n     *\n     * @param color\n     */\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of our dome,\n        // but it will be drawn from the upper left corner.\n        // Figure out the distance of that gap\n        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    /**\n     * Sets the active field once our physicist is being displayed.\n     *\n     * @param field Active game field\n     */\n    public void setField(Field field) {\n        this.field = field;\n    }\n\n    /**\n     * Take the current apple away from the physicist. Returns the apple for\n     * use in animating on the field. Note that if there is no current apple being\n     * aimed, null is returned.\n     *\n     * @return the current apple (if any) being aimed\n     */\n    public Apple takeApple() {\n        Apple myApple = aimingApple;\n        aimingApple = null;\n        return myApple;\n    }\n\n    /**\n     * Get a new apple ready if we need one. Do not discard an existing apple.\n     */\n    public void getNewApple() {\n        // Don't drop the current apple if we already have one!\n        if (aimingApple == null) {\n            aimingApple = new Apple(this);\n        }\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our physicist is the right color, then draw the semi-circle and box\n        g.setColor(color);\n        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);\n        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);\n\n        // Do we have an apple to draw as well?\n        if (aimingApple != null) {\n            // Yes. Position the center of the apple on the edge of our semi-circle.\n            // Use the current aimingAngle to determine where on the edge.\n            double angleInRadians = Math.toRadians(aimingAngle);\n            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;\n            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);\n            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);\n            aimingApple.setPosition(aimingX, aimingY);\n            aimingApple.draw(g);\n        }\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  },
  {
    "path": "ch07/Tree.java",
    "content": "package ch07;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n * They are built using sizes determined by the constants in the Field class.\n */\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    private Color leafColor = Color.GREEN.darker();\n    private Color trunkColor = new Color(101, 67, 33);\n    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);\n    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);\n    private int trunkX, trunkY;\n\n    // Boundary helpers\n    private Rectangle boundingBox;\n\n    @Override\n    public void setPosition(int x, int y) {\n        this.x = x;\n        this.y = y;\n        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;\n        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;\n        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);\n    }\n\n    @Override\n    public int getPositionX() {\n        return x;\n    }\n\n    @Override\n    public int getPositionY() {\n        return y;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        g.setColor(trunkColor);\n        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);\n        g.setColor(leafColor);\n        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  },
  {
    "path": "ch08/Apple.java",
    "content": "/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the size and weight details and provide a few simple methods for lobbing. We\n * can now detect collisions as well.\n */\npackage ch08;\n\nimport java.awt.*;\n\npublic class Apple implements GamePiece {\n    public static final int SMALL  = 0;\n    public static final int MEDIUM = 1;\n    public static final int LARGE  = 2;\n\n    int size;\n    double diameter;\n    double mass;\n    int centerX, centerY;\n    Physicist myPhysicist;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n    int scaledLength;\n\n    // Boundary helper for optimizing collision detection with physicists and trees\n    Rectangle boundingBox;\n\n    // If we bumped into something, keep a reference to that thing around for cleanup and removal\n    GamePiece collided;\n\n    /**\n     * Create a default, Medium apple\n     */\n    public Apple(Physicist owner) {\n        this(owner, MEDIUM);\n    }\n\n    /**\n     * Create an Apple of the given size\n     */\n    public Apple(Physicist owner, int size) {\n        myPhysicist = owner;\n        setSize(size);\n    }\n\n    /**\n     * Sets the size (and dependent properties) of the apple based on the\n     * supplied value which must be one of the size constants.\n     *\n     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE\n     */\n    public void setSize(int size) {\n        if (size < SMALL) {\n            size = SMALL;\n        }\n        if (size > LARGE) {\n            size = LARGE;\n        }\n        this.size = size;\n        switch (size) {\n            case SMALL:\n                diameter = 0.9;\n                mass = 0.5;\n                break;\n            case MEDIUM:\n                diameter = 1.0;\n                mass = 1.0;\n                break;\n            case LARGE:\n                diameter = 1.1;\n                mass = 1.8;\n                break;\n        }\n        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.\n        // Since we want a circle, we simply make our box a square so we only need one length.\n        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    public double getDiameter() {\n        return diameter;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of the apple, but it will be drawn from the\n        // upper left corner, so figure out the distance of that gap\n        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our apple will be red, then paint it!\n        g.setColor(Color.RED);\n        g.fillOval(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {\n            // By definition we don't collide with ourselves, our physicist, or with more than one other piece\n            return false;\n        }\n        if (otherPiece instanceof Apple) {\n            // The other piece is an apple, so we can do a simple distance calculation using\n            // the diameters of both apples.\n            Apple otherApple = (Apple) otherPiece;\n            int v = this.y - otherPiece.getPositionY(); // vertical difference\n            int h = this.x - otherPiece.getPositionX(); // horizontal difference\n            double distance = Math.sqrt(v * v + h * h);\n\n            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;\n            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;\n            if (distance < (myRadius + otherRadius)) {\n                // Since apples track collisions, we'll update the other apple to keep everyone in sync\n                setCollided(otherPiece);\n                otherApple.setCollided(this);\n                return true;\n            }\n            return false;\n        }\n        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {\n            setCollided(otherPiece);\n            return true;\n        }\n        return false;\n    }\n\n    public GamePiece getCollidedPiece() {\n        return collided;\n    }\n\n    public void setCollided(GamePiece otherPiece) {\n        this.collided = otherPiece;\n    }\n}\n"
  },
  {
    "path": "ch08/AppleToss.java",
    "content": "package ch08;\n\nimport javax.swing.*;\nimport java.util.Random;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main application window. We can now setup several trees for\n * target practice. (The ability for the player to aim and throw\n * will be covered in Chapter 10.)\n */\npublic class AppleToss extends JFrame {\n\n    public static final int FIELD_WIDTH = 800;\n    public static final int FIELD_HEIGHT = 600;\n\n    Field field = new Field();\n    Physicist player1 = new Physicist();\n\t\n\t// Helper class\n\tRandom random = new Random();\n\n    public AppleToss() {\n        // Create our frame\n        super(\"Apple Toss Game\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n\t\tsetSize(FIELD_WIDTH,FIELD_HEIGHT);\n        setResizable(false);\n\n        // Build the field with our player and some trees\n        setupFieldForOnePlayer();\n    }\n\n    /**\n     * Helper method to return a good x value for a tree so it's not off the left or right edge.\n     *\n     * @return x value within the bounds of the playing field width\n     */\n    private int goodX() {\n        // at least half the width of the tree plus a few pixels\n        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // now find a random number between a left and right margin\n        int rightMargin = FIELD_WIDTH - leftMargin;\n\n        // And return a random number starting at the left margin\n        return leftMargin + random.nextInt(rightMargin - leftMargin);\n    }\n\n    /**\n     * Helper method to return a good y value for a tree so it's\n\t * not off the top or bottom of the screen.\n     *\n     * @return y value within the bounds of the playing field height\n     */\n    private int goodY() {\n        // at least half the height of the \"leaves\" plus a few pixels\n        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // a little higher off the bottom\n        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;\n\n        // And return a random number starting at the top margin but not past the bottom\n        return topMargin + random.nextInt(bottomMargin - topMargin);\n    }\n\n    /**\n     * A helper method to populate a one player field with target trees.\n     */\n    private void setupFieldForOnePlayer() {\n        // Place our (new) physicist in the lower left corner and connect them to the field\n        player1.setPosition(100,500);\n        field.setPlayer(player1);\n        player1.setField(field);\n\t\t\n\t\t// And now make a few trees for target practice\n        for (int i = field.trees.size(); i < Field.MAX_TREES; i++) {\n            Tree t = new Tree();\n            t.setPosition(goodX(), goodY());\n            // Trees can be close to each other and overlap,\n\t\t\t// but they shouldn't intersect our physicist\n            while(player1.isTouching(t)) {\n                // We do intersect this tree, so let's try again\n                t.setPosition(goodX(), goodY());\n                System.err.println(\"Repositioning an intersecting tree...\");\n            }\n\t\t\tfield.addTree(t);\n        }\n\t\tadd(field);\n    }\n\n    public static void main(String args[]) {\n        AppleToss game = new AppleToss();\n        game.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch08/Field.java",
    "content": "package ch08;\n\nimport javax.swing.*;\nimport javax.swing.Timer;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.util.*;\nimport java.util.List;\n\n/**\n * The playing field for our game. Now we can setup some constants for\n * other game classes to use and create member variables for our player and some trees.\n */\npublic class Field extends JComponent {\n    public static final float GRAVITY = 9.8f;  // feet per second per second\n    public static final int STEP = 40;   // duration of an animation frame in milliseconds\n    public static final int APPLE_SIZE_IN_PIXELS = 30;\n    public static final int TREE_WIDTH_IN_PIXELS = 60;\n    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;\n    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;\n    public static final int MAX_TREES = 12;\n\n    Color fieldColor = Color.GRAY;\n    Random random = new Random();\n\n    // ArrayList covered in Generics chapter\n    // synchronizedArrayList covered in Threads chapter\n    Physicist physicist;\n    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(fieldColor);\n        g.fillRect(0,0, getWidth(), getHeight());\n        for (Tree t : trees) {\n            t.draw(g);\n        }\n        physicist.draw(g);\n    }\n\n    public void setPlayer(Physicist p) {\n        physicist = p;\n    }\n\t\n\t/**\n\t * Create and add a new tree to the field.\n\t *\n\t * @param x The X-coordinate for the tree\n\t * @param y The Y-coordinate for the tree\n\t */\n    public void addTree(int x, int y) {\n        Tree tree = new Tree();\n        tree.setPosition(x,y);\n        trees.add(tree);\n    }\n\t\n\t/**\n\t * Add an existing tree to our field. Useful if the position\n\t * of the tree has already been set.\n\t *\n\t * @param t The existing tree to add\n\t */\n\tpublic void addTree(Tree t) {\n\t\ttrees.add(t);\n\t}\n}\n"
  },
  {
    "path": "ch08/GamePiece.java",
    "content": "package ch08;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * From the README:\n * GamePiece\n *   - methods for positioning on a PlayingField\n *   - methods for Drawing\n *   - methods for detecting a collision with other GamePieces\n */\n\npublic interface GamePiece {\n    /**\n     * Sets the position of the piece on the playing field.\n     * (0,0) is the upper left per standard Java drawing methods.\n     *\n     * @param x\n     * @param y\n     */\n    void setPosition(int x, int y);\n\n    /**\n     * Gets the current horizontal position of the piece on the field.\n     *\n     * @return current X position of the piece\n     */\n    int getPositionX();\n\n    /**\n     * Gets the current vertical position of the piece on the field.\n     *\n     * @return current Y position of the piece\n     */\n    int getPositionY();\n\n    /**\n     * Gets the bounding box of this piece.\n     *\n     * @return a Rectangle encompassing the visual elements of the piece\n     */\n    Rectangle getBoundingBox();\n\n    /**\n     * Draws the piece inside the given graphics context.\n     * Do not assume anything about the state of the context.\n     *\n     * @param g\n     */\n    void draw(Graphics g);\n\n    /**\n     * Detect a collision with another piece on the field.\n     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).\n     *\n     * @param otherPiece\n     * @return\n     */\n    boolean isTouching(GamePiece otherPiece);\n}\n"
  },
  {
    "path": "ch08/GameUtilities.java",
    "content": "package ch08;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection\n\nimport java.awt.*;\n\n/**\n * Utility class with a few helper methods for calculating various collisions and\n * intersections.\n */\npublic class GameUtilities {\n    static boolean isPointInsideBox(int x, int y, Rectangle box) {\n        // Our own custom test. We could of course use box.contains(),\n        // but we can practice some interesting conditional checking here.\n        // Let's test left and right first\n        if (x >= box.x && x <= (box.x + box.width)) {\n            // Our x coordinate is ok, so check our y\n            if (y >= box.y && y <= (box.y + box.height)) {\n                return true;\n            }\n        }\n        // x or y was outside the box, so return false\n        return false;\n    }\n\n    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {\n        // If any of the four corners of box are inside other, we intersect, so\n        // let's check each one. Happily, that answer doesn't change if more\n        // than one corner is contained in other, so we can return as soon as\n        // we find the first contained corner.\n\n        // Let's get some local copies of the corner coordinates\n        // to make the call arguments easier to read.\n        int x1 = box.x;\n        int y1 = box.y;\n        int x2 = x1 + box.width;\n        int y2 = y1 + box.height;\n        if (isPointInsideBox(x1, y1, other)) {\n            // upper left\n            return true;\n        } else if (isPointInsideBox(x1, y2, other)) {\n            // lower left\n            return true;\n        } else if (isPointInsideBox(x2, y1, other)) {\n            // upper right\n            return true;\n        } else if (isPointInsideBox(x2, y2, other)) {\n            // lower right\n            return true;\n        }\n        // No box points in other so no intersection\n        return false;\n    }\n\n    /**\n     * Given two rectangles, do the overlap at all? This includes one box being\n     * completely contained by the other box.\n     *\n     * @param box1 a box to test, order does not matter\n     * @param box2 the other box\n     * @return true if the boxes overlap, false otherwise\n     */\n    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {\n        // Another custom test. We could of course use box1.intersects(box2)\n        // but we can practice method calls and some boolean logic here.\n        if (doesBoxIntersect(box1, box2)) {\n            // At least one of box1's points must be inside box2\n            return true;\n        } else if (doesBoxIntersect(box2, box1)) {\n            // None of box1's points were in box2, but at least one of box2's points are inside box1\n            return true;\n        }\n        // No intersections in either direction\n        return false;\n    }\n}\n"
  },
  {
    "path": "ch08/Physicist.java",
    "content": "package ch08;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport static java.awt.Color.*;\n\n/**\n * Our player class. A physicist has an apple that they can throw in addition\n * to implementing the basic methods for GamePiece. We can also set a custom\n * color in case you build on the game and allow multiple physicists to be\n * on the screen at the same time.\n */\npublic class Physicist implements GamePiece {\n    Color color;\n    int centerX, centerY;\n    Apple aimingApple;\n    float aimingAngle;\n    float aimingForce;\n    Field field;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n\n    // Boundary helpers\n    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);\n    private Rectangle boundingBox;\n\n\n    /**\n     * Create a default, blue physicist\n     */\n    public Physicist() {\n        this(BLUE);\n    }\n\n    /**\n     * Create a Physicist of the given color\n     */\n    public Physicist(Color color) {\n        setColor(color);\n        aimingAngle = 90.0f;\n        aimingForce = 50.0f;\n        getNewApple();\n    }\n\n    public void setAimingAngle(Float angle) {\n        aimingAngle = angle;\n    }\n\n    public void setAimingForce(Float force) {\n        if (force < 0) {\n            force = 0.0f;\n        }\n        aimingForce = force;\n    }\n\n    /**\n     * Sets the color for the physicist.\n     *\n     * @param color\n     */\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of our dome,\n        // but it will be drawn from the upper left corner.\n        // Figure out the distance of that gap\n        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    /**\n     * Sets the active field once our physicist is being displayed.\n     *\n     * @param field Active game field\n     */\n    public void setField(Field field) {\n        this.field = field;\n    }\n\n    /**\n     * Take the current apple away from the physicist. Returns the apple for\n     * use in animating on the field. Note that if there is no current apple being\n     * aimed, null is returned.\n     *\n     * @return the current apple (if any) being aimed\n     */\n    public Apple takeApple() {\n        Apple myApple = aimingApple;\n        aimingApple = null;\n        return myApple;\n    }\n\n    /**\n     * Get a new apple ready if we need one. Do not discard an existing apple.\n     */\n    public void getNewApple() {\n        // Don't drop the current apple if we already have one!\n        if (aimingApple == null) {\n            aimingApple = new Apple(this);\n        }\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our physicist is the right color, then draw the semi-circle and box\n        g.setColor(color);\n        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);\n        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);\n\n        // Do we have an apple to draw as well?\n        if (aimingApple != null) {\n            // Yes. Position the center of the apple on the edge of our semi-circle.\n            // Use the current aimingAngle to determine where on the edge.\n            double angleInRadians = Math.toRadians(aimingAngle);\n            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;\n            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);\n            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);\n            aimingApple.setPosition(aimingX, aimingY);\n            aimingApple.draw(g);\n        }\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  },
  {
    "path": "ch08/Tree.java",
    "content": "package ch08;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n * They are built using sizes determined by the constants in the Field class.\n */\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    private Color leafColor = Color.GREEN.darker();\n    private Color trunkColor = new Color(101, 67, 33);\n    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);\n    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);\n    private int trunkX, trunkY;\n\n    // Boundary helpers\n    private Rectangle boundingBox;\n\n    @Override\n    public void setPosition(int x, int y) {\n        this.x = x;\n        this.y = y;\n        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;\n        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;\n        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);\n    }\n\n    @Override\n    public int getPositionX() {\n        return x;\n    }\n\n    @Override\n    public int getPositionY() {\n        return y;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        g.setColor(trunkColor);\n        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);\n        g.setColor(leafColor);\n        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  },
  {
    "path": "ch09/URLConsumer.java",
    "content": "package ch09;\n\nimport java.util.Random;\n\n/**\n * A threaded client for our URL producer. Uses a synchronized queue\n * to safely read a URL for processing. (Our simple demo \"processes\"\n * by printing out the ID of this consumer and the url it consumed.)\n */\npublic class URLConsumer extends Thread {\n    String consumerID;\n    URLQueue queue;\n    boolean keepWorking;\n\n    Random delay;\n\n\t/**\n\t * Creates a new consumer with the given ID and reference to the shared queue.\n\t *\n\t * @param id A unique (unenforced) name for this consumer\n\t * @param queue The shared queue for storing and distributing URLs\n\t */\n    public URLConsumer(String id, URLQueue queue) {\n        if (queue == null) {\n            throw new IllegalArgumentException(\"Shared queue cannot be null\");\n        }\n        consumerID = id;\n        this.queue = queue;\n        keepWorking = true;\n        delay = new Random();\n    }\n\n\t/**\n\t * Our working method for the thread. Watches the boolean flag\n\t * keepWorking as well as the state of the queue to determine\n\t * whether or not to complete the loop. While working, grab a\n\t * URL and print it out then repeat.\n\t */\n    public void run() {\n        while (keepWorking || !queue.isEmpty()) {\n            String url = queue.getURL();\n            if (url != null) {\n                System.out.println(consumerID + \" consumed \" + url);\n            } else {\n                System.out.println(consumerID + \" skipped empty queue\");\n            }\n            try {\n                Thread.sleep(delay.nextInt(1000));\n            } catch (InterruptedException ie) {\n                System.err.println(\"Consumer \" + consumerID + \" interrupted. Quitting.\");\n                break;\n            }\n        }\n    }\n\n\t/**\n\t * Allow for politely halting this consumer.\n\t * Watched in the run() method.\n\t * \n\t * @see #run()\n\t */\n    public void setKeepWorking(boolean keepWorking) {\n        this.keepWorking = keepWorking;\n    }\n}\n"
  },
  {
    "path": "ch09/URLDemo.java",
    "content": "package ch09;\n\n/**\n * Manage multiple producers and consumers to demonstrate how\n * threads work in tandem. Creates a pair of producers and a\n * pair of consumers all with access to a shared queue.\n *\n * @see URLQueue\n * @see URLProducer\n * @see URLConsumer\n */\npublic class URLDemo {\n    public static void main(String args[]) {\n\t\t// Create our shared queue object\n        URLQueue queue = new URLQueue();\n\t\t\n\t\t// Now create some producers with unique names and a reference to our queue\n        URLProducer p1 = new URLProducer(\"P1\", 3, queue);\n        URLProducer p2 = new URLProducer(\"P2\", 3, queue);\n\t\t\n\t\t// And some consumers with their own names and a reference to our queue\n        URLConsumer c1 = new URLConsumer(\"C1\", queue);\n        URLConsumer c2 = new URLConsumer(\"C2\", queue);\n\t\t\n\t\t// Get everyone going!\n        System.out.println(\"Starting...\");\n        p1.start();\n        p2.start();\n        c1.start();\n        c2.start();\n\t\t\n\t\t// First wait around for the producers to finish\n        try {\n            p1.join();\n            p2.join();\n        } catch (InterruptedException ie) {\n            System.err.println(\"Interrupted waiting for producers to finish\");\n        }\n\t\t\n\t\t// OK, we know there won't be any more URLs made, so let the consumers\n\t\t// finish once the queue is empty\n        c1.setKeepWorking(false);\n        c2.setKeepWorking(false);\n        try {\n            c1.join();\n            c2.join();\n        } catch (InterruptedException ie) {\n            System.err.println(\"Interrupted waiting for consumers to finish\");\n        }\n\t\t\n        System.out.println(\"Done\");\n    }\n}\n"
  },
  {
    "path": "ch09/URLProducer.java",
    "content": "package ch09;\n\nimport java.util.Random;\n\n/**\n * Simple producer for use in our multithreaded example. Uses a synchronized queue\n * to safely store URLs for processing.\n */\npublic class URLProducer extends Thread {\n    String producerID;\n    int urlCount;\n    URLQueue queue;\n\n    Random delay;\n\n\t/**\n\t * Create a new producer with the given name. It will produce the\n\t * specified number of URLs and store them in the provided queue.\n\t *\n\t * @param id A unique (unenforced) name for this producer\n\t * @param count How many URLs this producer will create before quitting\n\t * @param queue The shared, synchronized queue for URLs\n\t */\n    public URLProducer(String id, int count, URLQueue queue) {\n        // Don't even create this producer if a negative count was supplied or there's no queue\n        if (count <= 0) {\n            throw new IllegalArgumentException(\"Count must be positive\");\n        }\n        if (queue == null) {\n            throw new IllegalArgumentException(\"Shared queue cannot be null\");\n        }\n        producerID = id;\n        urlCount = count;\n        this.queue = queue;\n        delay = new Random();\n    }\n\n\t/**\n\t * Our working method for the thread. Uses the count supplied to\n\t * the constructor to produce a batch of URLs and store them to\n\t * the shared queue. To make it a little more interesting, a random\n\t * delay is added at the end of each iteration. \n\t */\n    public void run() {\n        for (int i = 1; i <= urlCount; i++) {\n            String url = \"https://some.url/at/path/\" + i;\n            queue.addURL(producerID + \" \" + url);\n            System.out.println(producerID + \" produced \" + url);\n            try {\n                Thread.sleep(delay.nextInt(500));\n            } catch (InterruptedException ie) {\n                System.err.println(\"Producer \" + producerID + \" interrupted. Quitting.\");\n                break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ch09/URLQueue.java",
    "content": "package ch09;\n\nimport java.util.LinkedList;\n\n/**\n * A manually synchronized wrapper for a LinkedList.\n * Allows for safely adding and removing URLs in order.\n */\npublic class URLQueue {\n    LinkedList<String> urlQueue = new LinkedList<>();\n\n    public synchronized void addURL(String url) {\n        urlQueue.add(url);\n    }\n\n    public synchronized String getURL() {\n        if (!urlQueue.isEmpty()) {\n            return urlQueue.removeFirst();\n        }\n        return null;\n    }\n\n    public boolean isEmpty() {\n        return urlQueue.isEmpty();\n    }\n}\n"
  },
  {
    "path": "ch09/game/Apple.java",
    "content": "package ch09.game;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the size and weight details and provide a few simple methods for lobbing. We\n * also provide animation helpers for use with the PlayingField class.\n */\npublic class Apple implements GamePiece {\n    public static final int SMALL  = 0;\n    public static final int MEDIUM = 1;\n    public static final int LARGE  = 2;\n\n    int size;\n    double diameter;\n    double mass;\n    int centerX, centerY;\n    Physicist myPhysicist;\n\n    // In game play, apples can be thrown so track their velocities\n    long lastStep;\n    float velocityX, velocityY;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n    int scaledLength;\n\n    // Boundary helper for optimizing collision detection with physicists and trees\n    Rectangle boundingBox;\n\n    // If we bumped into something, keep a reference to that thing around for cleanup and removal\n    GamePiece collided;\n\n    /**\n     * Create a default, Medium apple\n     */\n    public Apple(Physicist owner) {\n        this(owner, MEDIUM);\n    }\n\n    /**\n     * Create an Apple of the given size\n     */\n    public Apple(Physicist owner, int size) {\n        myPhysicist = owner;\n        setSize(size);\n    }\n\n    /**\n     * Sets the size (and dependent properties) of the apple based on the\n     * supplied value which must be one of the size constants.\n     *\n     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE\n     */\n    public void setSize(int size) {\n        if (size < SMALL) {\n            size = SMALL;\n        }\n        if (size > LARGE) {\n            size = LARGE;\n        }\n        this.size = size;\n        switch (size) {\n            case SMALL:\n                diameter = 0.9;\n                mass = 0.5;\n                break;\n            case MEDIUM:\n                diameter = 1.0;\n                mass = 1.0;\n                break;\n            case LARGE:\n                diameter = 1.1;\n                mass = 1.8;\n                break;\n        }\n        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.\n        // Since we want a circle, we simply make our box a square so we only need one length.\n        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    public double getDiameter() {\n        return diameter;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of the apple, but it will be drawn from the\n        // upper left corner, so figure out the distance of that gap\n        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our apple will be red, then paint it!\n        g.setColor(Color.RED);\n        g.fillOval(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {\n            // By definition we don't collide with ourselves, our physicist, or with more than one other piece\n            return false;\n        }\n        if (otherPiece instanceof Apple) {\n            // The other piece is an apple, so we can do a simple distance calculation using\n            // the diameters of both apples.\n            Apple otherApple = (Apple) otherPiece;\n            int v = this.y - otherPiece.getPositionY(); // vertical difference\n            int h = this.x - otherPiece.getPositionX(); // horizontal difference\n            double distance = Math.sqrt(v * v + h * h);\n\n            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;\n            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;\n            if (distance < (myRadius + otherRadius)) {\n                // Since apples track collisions, we'll update the other apple to keep everyone in sync\n                setCollided(otherPiece);\n                otherApple.setCollided(this);\n                return true;\n            }\n            return false;\n        }\n        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {\n            setCollided(otherPiece);\n            return true;\n        }\n        return false;\n    }\n\n    public GamePiece getCollidedPiece() {\n        return collided;\n    }\n\n    public void setCollided(GamePiece otherPiece) {\n        this.collided = otherPiece;\n    }\n\n    public void toss(float angle, float velocity) {\n        lastStep = System.currentTimeMillis();\n        double radians = angle / 180 * Math.PI;\n        velocityX = (float)(velocity * Math.cos(radians) / mass);\n        // Start with negative velocity since \"up\" means smaller values of y\n        velocityY = (float)(-velocity * Math.sin(radians) / mass);\n    }\n\n    public void step() {\n        // Make sure we're moving at all using our lastStep tracker as a sentinel\n        if (lastStep > 0) {\n            // let's apply our gravity\n            long now = System.currentTimeMillis();\n            float slice = (now - lastStep) / 1000.0f;\n            velocityY = velocityY + (slice * Field.GRAVITY);\n            int newX = (int)(centerX + velocityX);\n            int newY = (int)(centerY + velocityY);\n            setPosition(newX, newY);\n        }\n    }\n}\n"
  },
  {
    "path": "ch09/game/AppleToss.java",
    "content": "package ch09.game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ArrayList;\nimport java.util.Random;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main application window. We can now demonstrate one apple being\n * tossed. (The ability for the player to aim and throw on demand\n * will be covered in Chapter 10.)\n */\npublic class AppleToss extends JFrame {\n\n    public static final int FIELD_WIDTH = 800;\n    public static final int FIELD_HEIGHT = 500;\n\n    Field field = new Field();\n    Physicist player1 = new Physicist();\n    ArrayList<Physicist> otherPlayers = new ArrayList<>();\n\n    Random random = new Random();\n\n    public AppleToss() {\n        // Create our frame\n        super(\"Apple Toss Game\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setResizable(false);\n        setSize(FIELD_WIDTH,FIELD_HEIGHT + 20);\n\n        // Build the field with our player and some trees\n        setupFieldForOnePlayer();\n        add(field);\n    }\n\n    /**\n     * Helper method to return a good x value for a tree so it's not off the left or right edge.\n     *\n     * @return x value within the bounds of the playing field width\n     */\n    private int goodX() {\n        // at least half the width of the tree plus a few pixels\n        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // now find a random number between a left and right margin\n        int rightMargin = FIELD_WIDTH - leftMargin;\n\n        // And return a random number starting at the left margin\n        return leftMargin + random.nextInt(rightMargin - leftMargin);\n    }\n\n    /**\n     * Helper method to return a good y value for a tree so it's not off the top or bottom of the screen.\n     *\n     * @return y value within the bounds of the playing field height\n     */\n    private int goodY() {\n        // at least half the height of the \"leaves\" plus a few pixels\n        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // a little higher off the bottom\n        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;\n\n        // And return a random number starting at the top margin but not past the bottom\n        return topMargin + random.nextInt(bottomMargin - topMargin);\n    }\n\n    /**\n     * A helper method to populate a one player field with target trees.\n     */\n    private void setupFieldForOnePlayer() {\n        // place our (new) physicist in the lower left corner\n        if (field.physicists.size() == 0) {\n            player1.setPosition(Field.PHYSICIST_SIZE_IN_PIXELS, FIELD_HEIGHT - (int) (Field.PHYSICIST_SIZE_IN_PIXELS * 1.5));\n            field.physicists.add(player1);\n            player1.setField(field);\n        }\n\n        // Create some trees for target practice\n        for (int i = field.trees.size(); i < 10; i++) {\n            Tree t = new Tree();\n            t.setPosition(goodX(), goodY());\n            // Trees can be close to each other and overlap, but they shouldn't intersect our physicist\n            while(player1.isTouching(t)) {\n                // We do intersect this tree, so let's try again\n                t.setPosition(goodX(), goodY());\n                System.err.println(\"Repositioning an intersecting tree...\");\n            }\n            field.trees.add(t);\n        }\n    }\n\n    public static void main(String args[]) {\n        AppleToss game = new AppleToss();\n        game.setVisible(true);\n        try {\n            game.player1.setAimingAngle(45.0f);\n            game.field.repaint();\n            Thread.sleep(1000);\n            game.field.startTossFromPlayer(game.player1);\n        } catch (InterruptedException ie) {\n            System.err.println(\"Interrupted during initial pause before tossing an apple.\");\n        }\n    }\n}\n"
  },
  {
    "path": "ch09/game/Field.java",
    "content": "package ch09.game;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * The playing field for our game. Now we can setup some constants for\n * other game classes to use and create member variables for our player and some trees.\n */\npublic class Field extends JComponent implements ActionListener {\n    public static final float GRAVITY = 9.8f;  // feet per second per second\n    public static final int STEP = 40;   // duration of an animation frame in milliseconds\n    public static final int APPLE_SIZE_IN_PIXELS = 30;\n    public static final int TREE_WIDTH_IN_PIXELS = 60;\n    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;\n    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;\n\n    public static final int MAX_PHYSICISTS = 5;\n    public static final int MAX_APPLES_PER_PHYSICIST = 3;\n    public static final int MAX_TREES = 12;\n\n    Color fieldColor = Color.GRAY;\n\n    // ArrayList was covered in Generics chapter\n    List<Physicist> physicists = Collections.synchronizedList(new ArrayList<>());\n    List<Apple> apples = Collections.synchronizedList(new ArrayList<>());\n    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());\n\n    boolean animating = false;\n    Thread animationThread;\n    Timer animationTimer;\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(fieldColor);\n        g.fillRect(0,0, getWidth(), getHeight());\n        for (Physicist p : physicists) {\n            p.draw(g);\n        }\n        for (Tree t : trees) {\n            t.draw(g);\n        }\n        for (Apple a : apples) {\n            a.draw(g);\n        }\n    }\n\n    public void actionPerformed(ActionEvent event) {\n        if (animating && event.getActionCommand().equals(\"repaint\")) {\n            System.out.println(\"Timer stepping \" + apples.size() + \" apples\");\n            for (Apple a : apples) {\n                a.step();\n                detectCollisions(a);\n            }\n            repaint();\n            cullFallenApples();\n        }\n    }\n\n    /**\n     * Toss an apple from the given physicist using that physicist's aim and force.\n     * Make sure the field is in the animating state.\n     *\n     * @param physicist the player whose apple should be tossed\n     */\n    public void startTossFromPlayer(Physicist physicist) {\n        if (!animating) {\n            System.out.println(\"Starting animation!\");\n            animating = true;\n            startAnimation();\n        }\n        if (animating) {\n            // Check to make sure we have an apple to toss\n            if (physicist.aimingApple != null) {\n                Apple apple = physicist.takeApple();\n                apple.toss(physicist.aimingAngle, physicist.aimingForce);\n                apples.add(apple);\n            }\n        }\n    }\n\n    void cullFallenApples() {\n        Iterator<Apple> iterator = apples.iterator();\n        while (iterator.hasNext()) {\n            Apple a = iterator.next();\n            if (a.getPositionY() > 600) {\n                System.out.println(\"Culling apple\");\n                iterator.remove();\n            }\n        }\n        if (apples.size() <= 0) {\n            animating = false;\n            if (animationTimer != null && animationTimer.isRunning()) {\n                animationTimer.stop();\n            }\n        }\n    }\n\n    void detectCollisions(Apple apple) {\n        // Check for other apples\n        for (Apple a : apples) {\n            if (apple.isTouching(a)) {\n                System.out.println(\"Touching another apple!\");\n                return;\n            }\n        }\n        // Check for physicists\n        for (Physicist p : physicists) {\n            if (apple.isTouching(p)) {\n                System.out.println(\"Touching a physicist!\");\n                return;\n            }\n        }\n        // Check for trees\n        for (Tree t : trees) {\n            if (apple.isTouching(t)) {\n                System.out.println(\"Touching a tree!\");\n                return;\n            }\n        }\n    }\n\n    void hitPhysicist(Physicist physicist) {\n        // do any scoring or notifications here\n        physicists.remove(physicist);\n    }\n\n    void hitTree(Tree tree) {\n        // do any scoring or notifications here\n        trees.remove(tree);\n    }\n\n    void startAnimation() {\n        // Animator myAnimator = new Animator();\n        // animationThread = new Thread(myAnimator);\n        // animationThread.start();\n        if (animationTimer == null) {\n            animationTimer = new Timer(STEP, this);\n            animationTimer.setActionCommand(\"repaint\");\n            animationTimer.setRepeats(true);\n            animationTimer.start();\n        } else if (!animationTimer.isRunning()) {\n            animationTimer.restart();\n        }\n    }\n\n    class Animator implements Runnable {\n        public void run() {\n            while (animating) {\n                System.out.println(\"Stepping \" + apples.size() + \" apples\");\n                for (Apple a : apples) {\n                    a.step();\n                    detectCollisions(a);\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Field.this.repaint();\n                    }\n                });\n                cullFallenApples();\n                try {\n                    Thread.sleep((int)(STEP * 1000));\n                } catch (InterruptedException ie) {\n                    System.err.println(\"Animation interrupted\");\n                    animating = false;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ch09/game/GamePiece.java",
    "content": "package ch09.game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * From the README:\n * GamePiece\n *   - methods for positioning on a PlayingField\n *   - methods for Drawing\n *   - methods for detecting a collision with other GamePieces\n */\n\npublic interface GamePiece {\n    /**\n     * Sets the position of the piece on the playing field.\n     * (0,0) is the upper left per standard Java drawing methods.\n     *\n     * @param x\n     * @param y\n     */\n    void setPosition(int x, int y);\n\n    /**\n     * Gets the current horizontal position of the piece on the field.\n     *\n     * @return current X position of the piece\n     */\n    int getPositionX();\n\n    /**\n     * Gets the current vertical position of the piece on the field.\n     *\n     * @return current Y position of the piece\n     */\n    int getPositionY();\n\n    /**\n     * Gets the bounding box of this piece.\n     *\n     * @return a Rectangle encompassing the visual elements of the piece\n     */\n    Rectangle getBoundingBox();\n\n    /**\n     * Draws the piece inside the given graphics context.\n     * Do not assume anything about the state of the context.\n     *\n     * @param g\n     */\n    void draw(Graphics g);\n\n    /**\n     * Detect a collision with another piece on the field.\n     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).\n     *\n     * @param otherPiece\n     * @return\n     */\n    boolean isTouching(GamePiece otherPiece);\n}\n"
  },
  {
    "path": "ch09/game/GameUtilities.java",
    "content": "package ch09.game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection\n\nimport java.awt.*;\n\n/**\n * Utility class with a few helper methods for calculating various collisions and\n * intersections.\n */\npublic class GameUtilities {\n    static boolean isPointInsideBox(int x, int y, Rectangle box) {\n        // Our own custom test. We could of course use box.contains(),\n        // but we can practice some interesting conditional checking here.\n        // Let's test left and right first\n        if (x >= box.x && x <= (box.x + box.width)) {\n            // Our x coordinate is ok, so check our y\n            if (y >= box.y && y <= (box.y + box.height)) {\n                return true;\n            }\n        }\n        // x or y was outside the box, so return false\n        return false;\n    }\n\n    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {\n        // If any of the four corners of box are inside other, we intersect, so\n        // let's check each one. Happily, that answer doesn't change if more\n        // than one corner is contained in other, so we can return as soon as\n        // we find the first contained corner.\n\n        // Let's get some local copies of the corner coordinates\n        // to make the call arguments easier to read.\n        int x1 = box.x;\n        int y1 = box.y;\n        int x2 = x1 + box.width;\n        int y2 = y1 + box.height;\n        if (isPointInsideBox(x1, y1, other)) {\n            // upper left\n            return true;\n        } else if (isPointInsideBox(x1, y2, other)) {\n            // lower left\n            return true;\n        } else if (isPointInsideBox(x2, y1, other)) {\n            // upper right\n            return true;\n        } else if (isPointInsideBox(x2, y2, other)) {\n            // lower right\n            return true;\n        }\n        // No box points in other so no intersection\n        return false;\n    }\n\n    /**\n     * Given two rectangles, do the overlap at all? This includes one box being\n     * completely contained by the other box.\n     *\n     * @param box1 a box to test, order does not matter\n     * @param box2 the other box\n     * @return true if the boxes overlap, false otherwise\n     */\n    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {\n        // Another custom test. We could of course use box1.intersects(box2)\n        // but we can practice method calls and some boolean logic here.\n        if (doesBoxIntersect(box1, box2)) {\n            // At least one of box1's points must be inside box2\n            return true;\n        } else if (doesBoxIntersect(box2, box1)) {\n            // None of box1's points were in box2, but at least one of box2's points are inside box1\n            return true;\n        }\n        // No intersections in either direction\n        return false;\n    }\n}\n"
  },
  {
    "path": "ch09/game/Physicist.java",
    "content": "package ch09.game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport static java.awt.Color.*;\n\n/**\n * Our player class. A physicist has an apple that they can throw in addition\n * to implementing the basic methods for GamePiece. We can also set a custom\n * color in case you build on the game and allow multiple physicists to be\n * on the screen at the same time.\n */\npublic class Physicist implements GamePiece, ActionListener {\n    Color color;\n    int centerX, centerY;\n    Apple aimingApple;\n    float aimingAngle;\n    float aimingForce;\n    Field field;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n\n    // Boundary helpers\n    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);\n    private Rectangle boundingBox;\n\n\n    /**\n     * Create a default, blue physicist\n     */\n    public Physicist() {\n        this(BLUE);\n    }\n\n    /**\n     * Create a Physicist of the given color\n     */\n    public Physicist(Color color) {\n        setColor(color);\n        aimingAngle = 90.0f;\n        aimingForce = 50.0f;\n        getNewApple();\n    }\n\n    public void setAimingAngle(Float angle) {\n        aimingAngle = angle;\n    }\n\n    public void setAimingForce(Float force) {\n        if (force < 0) {\n            force = 0.0f;\n        }\n        aimingForce = force;\n    }\n\n    /**\n     * Sets the color for the physicist.\n     *\n     * @param color\n     */\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of our dome,\n        // but it will be drawn from the upper left corner.\n        // Figure out the distance of that gap\n        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    /**\n     * Sets the active field once our physicist is being displayed.\n     *\n     * @param field Active game field\n     */\n    public void setField(Field field) {\n        this.field = field;\n    }\n\n    /**\n     * Take the current apple away from the physicist. Returns the apple for\n     * use in animating on the field. Note that if there is no current apple being\n     * aimed, null is returned.\n     *\n     * @return the current apple (if any) being aimed\n     */\n    public Apple takeApple() {\n        Apple myApple = aimingApple;\n        aimingApple = null;\n        return myApple;\n    }\n\n    /**\n     * Get a new apple ready if we need one. Do not discard an existing apple.\n     */\n    public void getNewApple() {\n        // Don't drop the current apple if we already have one!\n        if (aimingApple == null) {\n            aimingApple = new Apple(this);\n        }\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our physicist is the right color, then draw the semi-circle and box\n        g.setColor(color);\n        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);\n        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);\n\n        // Do we have an apple to draw as well?\n        if (aimingApple != null) {\n            // Yes. Position the center of the apple on the edge of our semi-circle.\n            // Use the current aimingAngle to determine where on the edge.\n            double angleInRadians = Math.toRadians(aimingAngle);\n            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;\n            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);\n            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);\n            aimingApple.setPosition(aimingX, aimingY);\n            aimingApple.draw(g);\n        }\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        if (e.getActionCommand().equals(\"New Apple\")) {\n            getNewApple();\n            if (field != null) {\n                field.repaint();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ch09/game/Tree.java",
    "content": "package ch09.game;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n * They are built using sizes determined by the constants in the Field class.\n */\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    private Color leafColor = Color.GREEN.darker();\n    private Color trunkColor = new Color(101, 67, 33);\n    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);\n    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);\n    private int trunkX, trunkY;\n\n    // Boundary helpers\n    private Rectangle boundingBox;\n\n    @Override\n    public void setPosition(int x, int y) {\n        this.x = x;\n        this.y = y;\n        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;\n        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;\n        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);\n    }\n\n    @Override\n    public int getPositionX() {\n        return x;\n    }\n\n    @Override\n    public int getPositionY() {\n        return y;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        g.setColor(trunkColor);\n        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);\n        g.setColor(leafColor);\n        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  },
  {
    "path": "ch10/ActionDemo1.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\n/**\n * A simple, classic demonstration of event handling. Create a frame\n * with a button and a label. As the button is pressed, a counter\n * shown in the label is incremented.\n */\npublic class ActionDemo1 extends JFrame implements ActionListener {\n    int counterValue = 0;\n    JLabel counterLabel;\n\n    public ActionDemo1() {\n        super( \"ActionEvent Counter Demo\" );\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setLayout(new FlowLayout());\n        setSize( 300, 180 );\n\n        counterLabel = new JLabel(\"Count: 0\", JLabel.CENTER );\n        add(counterLabel);\n\n        JButton incrementer = new JButton(\"Increment\");\n        incrementer.addActionListener(this);\n        add(incrementer);\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        counterValue++;\n        counterLabel.setText(\"Count: \" + counterValue);\n    }\n\n    public static void main( String[] args ) {\n        ActionDemo1 demo = new ActionDemo1();\n        demo.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch10/ActionDemo2.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\n/**\n * A simple, classic demonstration of event handling. Create a frame\n * with a button and a label. As the button is pressed, a counter\n * shown in the label is incremented.\n *\n * This second variation uses a separate class to handle the action\n * events rather than implementing the ActionListener interface\n * directly as in ActionDemo1.\n */\npublic class ActionDemo2 {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"ActionListener Demo\" );\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setLayout(new FlowLayout());\n        frame.setSize( 300, 180 );\n\n        JLabel label = new JLabel(\"Results go here\", JLabel.CENTER );\n        ActionCommandHelper helper = new ActionCommandHelper(label);\n\n        JButton simpleButton = new JButton(\"Button\");\n        simpleButton.addActionListener(helper);\n\n        JTextField simpleField = new JTextField(10);\n        simpleField.addActionListener(helper);\n\n        frame.add(simpleButton);\n        frame.add(simpleField);\n        frame.add(label);\n\n        frame.setVisible( true );\n    }\n}\n\n/**\n * Helper class to show the command property of any ActionEvent in a given label.\n */\nclass ActionCommandHelper implements ActionListener {\n    JLabel resultLabel;\n\n    public ActionCommandHelper(JLabel label) {\n        resultLabel = label;\n    }\n\n    public void actionPerformed(ActionEvent ae) {\n        resultLabel.setText(ae.getActionCommand());\n    }\n}"
  },
  {
    "path": "ch10/BorderLayoutDemo.java",
    "content": "package ch10;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n/**\n * A basic demonstration of the BorderLayout with higlighted\n * areas in different colors.\n */\npublic class BorderLayoutDemo {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame(\"BorderLayout Demo\");\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setSize(400, 200);\n\n        JLabel northLabel = new JLabel(\"Top - North\", JLabel.CENTER);\n        JLabel southLabel = new JLabel(\"Bottom - South\", JLabel.CENTER);\n        JLabel eastLabel = new JLabel(\"Right - East\", JLabel.CENTER);\n        JLabel westLabel = new JLabel(\"Left - West\", JLabel.CENTER);\n        JLabel centerLabel = new JLabel(\"Center (everything else)\", JLabel.CENTER);\n\n        // Color the labels so we can see their boundaries better\n        northLabel.setOpaque(true);\n        northLabel.setBackground(Color.GREEN);\n        southLabel.setOpaque(true);\n        southLabel.setBackground(Color.GREEN);\n        eastLabel.setOpaque(true);\n        eastLabel.setBackground(Color.RED);\n        westLabel.setOpaque(true);\n        westLabel.setBackground(Color.RED);\n        centerLabel.setOpaque(true);\n        centerLabel.setBackground(Color.YELLOW);\n\n        frame.add(northLabel, BorderLayout.NORTH);\n        frame.add(southLabel, BorderLayout.SOUTH);\n        frame.add(eastLabel, BorderLayout.EAST);\n        frame.add(westLabel, BorderLayout.WEST);\n        frame.add(centerLabel, BorderLayout.CENTER);\n\n        frame.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch10/Buttons.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * A very simple button placed on a frame. This button is\n * not connected to any listener so it will \"press\" when\n * clicked but action is taken in response.\n */\npublic class Buttons {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"JButton Examples\" );\n        frame.setLayout(new FlowLayout());\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setSize( 300, 200 );\n\n        JButton basic = new JButton(\"Try me!\");\n        frame.add(basic);\n\n        frame.setVisible( true );\n    }\n}\n"
  },
  {
    "path": "ch10/HelloJavaAgain.java",
    "content": "package ch10;\n\nimport javax.swing.*;\n\n/**\n * A simple label placed on a frame.\n */\npublic class HelloJavaAgain {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"Hello, Java!\" );\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setSize( 300, 300 );\n\n        JLabel label = new JLabel(\"Hello, Java!\", JLabel.CENTER );\n        frame.add(label);\n\n        frame.setVisible( true );\n    }\n}\n"
  },
  {
    "path": "ch10/HelloMouse.java",
    "content": "package ch10;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\n\n/**\n * A quick demo of how mouse events work. Clicking around the\n * frame will move the label.\n *\n * Note that \"mouse\" events are the up, down, and click actions\n * of mouse buttons. If you want to catch the mouse moving or dragging,\n * those are handled by the MouseMotionListener interface.\n */\npublic class HelloMouse extends JFrame implements MouseListener {\n    JLabel label;\n\n    public HelloMouse() {\n        super(\"MouseEvent Demo\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setLayout(null);\n        setSize( 300, 100 );\n\n        label = new JLabel(\"Hello, Mouse!\", JLabel.CENTER );\n        label.setOpaque(true);\n        label.setBackground(Color.YELLOW);\n        label.setSize(100,20);\n        label.setLocation(100,100);\n        add(label);\n\n        getContentPane().addMouseListener(this);\n    }\n\n    public void mouseClicked(MouseEvent e) {\n        label.setLocation(e.getX(), e.getY());\n    }\n\n    public void mousePressed(MouseEvent e) { }\n    public void mouseReleased(MouseEvent e) { }\n    public void mouseEntered(MouseEvent e) { }\n    public void mouseExited(MouseEvent e) { }\n\n    public static void main( String[] args ) {\n        HelloMouse frame = new HelloMouse();\n        frame.setVisible( true );\n    }\n}\n"
  },
  {
    "path": "ch10/HelloMouseHelper.java",
    "content": "package ch10;\n\nimport java.awt.*;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.*;\n\n/**\n * A variation on HelloMouse with a separate class implementing\n * the mouse event handler. Note that we have to pass a reference\n * to the label we wish to affect when creating the event\n * helper.\n */\npublic class HelloMouseHelper {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"MouseAdapter Demo\" );\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setLayout(null);\n        frame.setSize( 300, 300 );\n\n        JLabel label = new JLabel(\"Hello, Mouse!\", JLabel.CENTER );\n        label.setOpaque(true);\n        label.setBackground(Color.YELLOW);\n        label.setSize(100,20);\n        label.setLocation(100,100);\n        frame.add(label);\n\n        LabelMover mover = new LabelMover(label);\n        frame.getContentPane().addMouseListener(mover);\n        frame.setVisible( true );\n    }\n}\n\n/**\n * Helper class to move a label to the position of a mouse click.\n */\nclass LabelMover extends MouseAdapter {\n    JLabel labelToMove;\n\n    public LabelMover(JLabel label) {\n        labelToMove = label;\n    }\n\n    public void mouseClicked(MouseEvent e) {\n        labelToMove.setLocation(e.getX(), e.getY());\n    }\n}\n"
  },
  {
    "path": "ch10/Labels.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * A simple demo of several label options with variations\n * on color, alignment, and icons.\n */\npublic class Labels {\n\n    // To make this simple example run from inside an IDE like IntelliJ IDEA,\n    // set this path to match where you unzipped the book's projects.\n    static final String PROJECT_PATH = \"/Users/work/LearningJava5e\";\n\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"JLabel Examples\" );\n        frame.setLayout(new FlowLayout());\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setSize( 300, 300 );\n\n        JLabel basic = new JLabel(\"Default Label\");\n        basic.setOpaque(true);\n        basic.setBackground(Color.YELLOW);\n        JLabel another = new JLabel(\"Another Label\");\n        another.setOpaque(true);\n        another.setBackground(Color.GREEN);\n        JLabel simple = new JLabel(\"A Simple Label\");\n        simple.setOpaque(true);\n        simple.setBackground(Color.WHITE);\n        JLabel standard = new JLabel(\"A Standard Label\");\n        standard.setOpaque(true);\n        standard.setBackground(Color.ORANGE);\n        JLabel centered = new JLabel(\"Centered Text\", JLabel.CENTER);\n        centered.setPreferredSize(new Dimension(150, 24));\n        centered.setOpaque(true);\n        centered.setBackground(Color.WHITE);\n        JLabel times = new JLabel(\"Times Roman\");\n        times.setOpaque(true);\n        times.setBackground(Color.WHITE);\n        times.setFont(new Font(\"TimesRoman\", Font.BOLD, 18));\n        JLabel styled = new JLabel(\"<html>Some <b><i>styling</i></b> is also allowed</html>\");\n        styled.setOpaque(true);\n        styled.setBackground(Color.WHITE);\n        JLabel icon = new JLabel(\"Verified\", new ImageIcon(PROJECT_PATH + \"/ch10/check.png\"), JLabel.LEFT);\n        icon.setOpaque(true);\n        icon.setBackground(Color.WHITE);\n\n        frame.add(basic);\n        frame.add(another);\n        frame.add(simple);\n        frame.add(standard);\n        frame.add(centered);\n        frame.add(times);\n        frame.add(styled);\n        frame.add(icon);\n\n        frame.setVisible( true );\n    }\n}\n"
  },
  {
    "path": "ch10/MenuDemo.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\n/**\n * Basic demonstration of creating menus and catching events\n * from selected menu items.\n */\npublic class MenuDemo extends JFrame implements ActionListener {\n    JLabel resultsLabel;\n\n    public MenuDemo() {\n        super( \"JMenu Demo\" );\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setLayout(new FlowLayout());\n        setSize( 300, 180 );\n\n        resultsLabel = new JLabel(\"Click a menu item!\" );\n        add(resultsLabel);\n\n        // Now let's create a couple menus and populate them\n        JMenu fileMenu = new JMenu(\"File\");\n        JMenuItem saveItem = new JMenuItem(\"Save\");\n        saveItem.addActionListener(this);\n        fileMenu.add(saveItem);\n        JMenuItem quitItem = new JMenuItem(\"Quit\");\n        quitItem.addActionListener(this);\n        fileMenu.add(quitItem);\n\n        JMenu editMenu = new JMenu(\"Edit\");\n        JMenuItem cutItem = new JMenuItem(\"Cut\");\n        cutItem.addActionListener(this);\n        editMenu.add(cutItem);\n        JMenuItem copyItem = new JMenuItem(\"Copy\");\n        copyItem.addActionListener(this);\n        editMenu.add(copyItem);\n        JMenuItem pasteItem = new JMenuItem(\"Paste\");\n        pasteItem.addActionListener(this);\n        editMenu.add(pasteItem);\n\n        // And finally build a JMenuBar for the application\n        JMenuBar mainBar = new JMenuBar();\n        mainBar.add(fileMenu);\n        mainBar.add(editMenu);\n        setJMenuBar(mainBar);\n    }\n\n    public void actionPerformed(ActionEvent event) {\n        resultsLabel.setText(\"Menu selected: \" + event.getActionCommand());\n    }\n\n    public static void main(String args[]) {\n        MenuDemo demo = new MenuDemo();\n        demo.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch10/ModalDemo.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\n/**\n * A demonstration of showing modal dialogs. Pressing\n * the Go button will popup a new window which must be\n * dismissed before interacting with the main application again.\n */\npublic class ModalDemo extends JFrame implements ActionListener {\n\n    JLabel modalLabel;\n\n    public ModalDemo() {\n        super( \"Modal Dialog Demo\" );\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setLayout(new FlowLayout());\n        setSize( 300, 180 );\n\n        modalLabel = new JLabel(\"Press 'Go' to show the popup!\", JLabel.CENTER );\n        add(modalLabel);\n\n        JButton goButton = new JButton(\"Go\");\n        goButton.addActionListener(this);\n        add(goButton);\n    }\n\n    public void actionPerformed(ActionEvent ae) {\n        JOptionPane.showMessageDialog(this, \"We're going!\", \"Alert\", JOptionPane.INFORMATION_MESSAGE);\n        modalLabel.setText(\"Go pressed! Press again if you like.\");\n    }\n\n    public static void main(String args[]) {\n        ModalDemo demo = new ModalDemo();\n        demo.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch10/NestedPanelDemo.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * An alternate way to arrange complex UIs. Rather than\n * use more flexible (but complicated) layout managers,\n * you can nest containers each with simpler managers.\n */\npublic class NestedPanelDemo {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame(\"Nested Panel Demo\");\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setSize(400, 200);\n\n        // Create the text area and go ahead and add it to the center\n        JTextArea messageArea = new JTextArea();\n        frame.add(messageArea, BorderLayout.CENTER);\n\n        // Create the button container\n        //JPanel buttonPanel = new JPanel(new FlowLayout());\n        JPanel buttonPanel = new JPanel(new GridLayout(1,0));\n\n        // Create the buttons\n        JButton sendButton = new JButton(\"Send\");\n        JButton saveButton = new JButton(\"Save\");\n        JButton resetButton = new JButton(\"Reset\");\n        JButton cancelButton = new JButton(\"Cancel\");\n\n        // Add the buttons to their container\n        buttonPanel.add(sendButton);\n        buttonPanel.add(saveButton);\n        buttonPanel.add(resetButton);\n        buttonPanel.add(cancelButton);\n\n        // And finally, add the button container to the bottom of the app\n        frame.add(buttonPanel, BorderLayout.SOUTH);\n\n        frame.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch10/PhoneGridDemo.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * Demo of the GridLayout manager used to create a\n * dial pad like you might find on a phone.\n */\npublic class PhoneGridDemo {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame(\"Nested Panel Demo\");\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setSize(200, 300);\n\n        // Create the phone pad container\n        JPanel phonePad = new JPanel(new GridLayout(4,3));\n\n        // Create and add the 12 buttons, top-left to bottom-right\n        phonePad.add(new JButton(\"1\"));\n        phonePad.add(new JButton(\"2\"));\n        phonePad.add(new JButton(\"3\"));\n\n        phonePad.add(new JButton(\"4\"));\n        phonePad.add(new JButton(\"5\"));\n        phonePad.add(new JButton(\"6\"));\n\n        phonePad.add(new JButton(\"7\"));\n        phonePad.add(new JButton(\"8\"));\n        phonePad.add(new JButton(\"9\"));\n\n        phonePad.add(new JButton(\"*\"));\n        phonePad.add(new JButton(\"0\"));\n        phonePad.add(new JButton(\"#\"));\n\n        // And finally, add the pad to the center of the app\n        frame.add(phonePad, BorderLayout.CENTER);\n\n        frame.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch10/ProgressDemo.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\n/**\n * A multithreaded example showing how to safely update Swing components\n * from a background thread. The ProgressPretender class below slowly\n * counts up to 100 and keeps a JLabel updated with the current value.\n */\npublic class ProgressDemo {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"SwingUtilities 'invoke' Demo\" );\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setLayout(new FlowLayout());\n        frame.setSize( 300, 180 );\n\n        JLabel label = new JLabel(\"Download Progress Goes Here!\", JLabel.CENTER );\n        Thread pretender = new Thread(new ProgressPretender(label));\n\n        JButton simpleButton = new JButton(\"Start\");\n        simpleButton.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                simpleButton.setEnabled(false);\n                pretender.start();\n            }\n        });\n\n        JLabel checkLabel = new JLabel(\"Can you still type?\");\n        JTextField checkField = new JTextField(10);\n\n        frame.add(label);\n        frame.add(simpleButton);\n        frame.add(checkLabel);\n        frame.add(checkField);\n        frame.setVisible( true );\n    }\n}\n\n/**\n * Simulated worker that updates a provided JLabel\n * with the work \"progress\". In this simulation, we just\n * count from 0 to 100 with a one-second delay between\n * each step.\n */\nclass ProgressPretender implements Runnable {\n    JLabel label;\n    int progress;\n\n    public ProgressPretender(JLabel label) {\n        this.label = label;\n        progress = 0;\n    }\n\n    public void run() {\n        while (progress <= 100) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    label.setText(progress + \"%\");\n                }\n            });\n            try {\n                Thread.sleep(1000);\n            } catch (InterruptedException ie) {\n                System.err.println(\"Someone interrupted us. Skipping download.\");\n                break;\n            }\n            progress++;\n        }\n    }\n}\n"
  },
  {
    "path": "ch10/TextInputs.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * Some example text inputs including a text area embedded in a\n * JScrollPane.\n */\npublic class TextInputs {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"JTextField Examples\" );\n        frame.setLayout(new FlowLayout());\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setSize( 400, 300 );\n\n        JLabel nameLabel = new JLabel(\"Name:\");\n        JTextField nameField = new JTextField(10);\n        JLabel emailLabel = new JLabel(\"Email:\");\n        JTextField emailField = new JTextField(24);\n\n        JLabel bodyLabel = new JLabel(\"Body:\");\n        JTextArea bodyArea = new JTextArea(10,30);\n        bodyArea.setLineWrap(true);\n        bodyArea.setWrapStyleWord(true);\n        JScrollPane bodyScroller = new JScrollPane(bodyArea);\n        bodyScroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        bodyScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);\n\n        frame.add(nameLabel);\n        frame.add(nameField);\n        frame.add(emailLabel);\n        frame.add(emailField);\n        frame.add(bodyLabel);\n        frame.add(bodyScroller);\n\n        frame.setVisible( true );\n    }\n}\n"
  },
  {
    "path": "ch10/Widget.java",
    "content": "package ch10;\n\nimport javax.swing.*;\nimport java.awt.*;\n\n/**\n * A helper class aimed at making it easier to try out\n * the many Swing components in jshell. A small frame will\n * show up once the Widget class is imported into jshell\n * and a new instance is created. Be sure to keep a variable\n * for the new object!\n *\n * <pre>\n * jshell> import javax.swing.*\n *\n * jshell> import ch10.Widget\n * \n * jshell> Widget w = new Widget(\"My demo widget\")\n * w ==> ch10.Widget[frame0,0,23,300x300,layout=java.awt.B ... tPaneCheckingEnabled=true]\n * \n * jshell> w.add(new JLabel(\"Hi\"))\n * $5 ==> javax.swing.JLabel[,0,0,0x0,invalid,alignmentX=0 ... rticalTextPosition=CENTER]\n * </pre>\n */\npublic class Widget extends JFrame {\n\n    public Widget() {\n        this(\"jshell GUI Widget\");\n    }\n\n    public Widget(String title) {\n        super(title);\n        setLayout(new FlowLayout());\n        setSize(300,300);\n        setVisible(true);\n    }\n\n    @Override\n    public Component add(Component comp) {\n        SwingUtilities.invokeLater(new Runnable() {\n            @Override\n            public void run() {\n                getContentPane().add(comp);\n                getContentPane().doLayout();\n            }\n        });\n        return comp;\n    }\n\n    @Override\n    public void remove(Component comp) {\n        SwingUtilities.invokeLater(new Runnable() {\n            @Override\n            public void run() {\n                getContentPane().remove(comp);\n                getContentPane().doLayout();\n                getContentPane().repaint();\n            }\n        });\n    }\n\n    public void reset() {\n        SwingUtilities.invokeLater(new Runnable() {\n            @Override\n            public void run() {\n                getContentPane().removeAll();\n                getContentPane().doLayout();\n                getContentPane().repaint();\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "ch10/game/Apple.java",
    "content": "package ch10.game;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the size and weight details and provide a few simple methods for lobbing. We\n * also provide animation helpers for use with the PlayingField class.\n */\npublic class Apple implements GamePiece {\n    public static final int SMALL  = 0;\n    public static final int MEDIUM = 1;\n    public static final int LARGE  = 2;\n\n    int size;\n    double diameter;\n    double mass;\n    int centerX, centerY;\n    Physicist myPhysicist;\n\n    // In game play, apples can be thrown so track their velocities\n    long lastStep;\n    float velocityX, velocityY;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n    int scaledLength;\n\n    // Boundary helper for optimizing collision detection with physicists and trees\n    Rectangle boundingBox;\n\n    // If we bumped into something, keep a reference to that thing around for cleanup and removal\n    GamePiece collided;\n\n    /**\n     * Create a default, Medium apple\n     */\n    public Apple(Physicist owner) {\n        this(owner, MEDIUM);\n    }\n\n    /**\n     * Create an Apple of the given size\n     */\n    public Apple(Physicist owner, int size) {\n        myPhysicist = owner;\n        setSize(size);\n    }\n\n    /**\n     * Sets the size (and dependent properties) of the apple based on the\n     * supplied value which must be one of the size constants.\n     *\n     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE\n     */\n    public void setSize(int size) {\n        if (size < SMALL) {\n            size = SMALL;\n        }\n        if (size > LARGE) {\n            size = LARGE;\n        }\n        this.size = size;\n        switch (size) {\n            case SMALL:\n                diameter = 0.9;\n                mass = 0.5;\n                break;\n            case MEDIUM:\n                diameter = 1.0;\n                mass = 1.0;\n                break;\n            case LARGE:\n                diameter = 1.1;\n                mass = 1.8;\n                break;\n        }\n        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.\n        // Since we want a circle, we simply make our box a square so we only need one length.\n        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    public double getDiameter() {\n        return diameter;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of the apple, but it will be drawn from the\n        // upper left corner, so figure out the distance of that gap\n        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our apple will be red, then paint it!\n        g.setColor(Color.RED);\n        g.fillOval(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {\n            // By definition we don't collide with ourselves, our physicist, or with more than one other piece\n            return false;\n        }\n        if (otherPiece instanceof Apple) {\n            // The other piece is an apple, so we can do a simple distance calculation using\n            // the diameters of both apples.\n            Apple otherApple = (Apple) otherPiece;\n            int v = this.y - otherPiece.getPositionY(); // vertical difference\n            int h = this.x - otherPiece.getPositionX(); // horizontal difference\n            double distance = Math.sqrt(v * v + h * h);\n\n            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;\n            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;\n            if (distance < (myRadius + otherRadius)) {\n                // Since apples track collisions, we'll update the other apple to keep everyone in sync\n                setCollided(otherPiece);\n                otherApple.setCollided(this);\n                return true;\n            }\n            return false;\n        }\n        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {\n            setCollided(otherPiece);\n            return true;\n        }\n        return false;\n    }\n\n    public GamePiece getCollidedPiece() {\n        return collided;\n    }\n\n    public void setCollided(GamePiece otherPiece) {\n        this.collided = otherPiece;\n    }\n\n    public void toss(float angle, float velocity) {\n        lastStep = System.currentTimeMillis();\n        double radians = angle / 180 * Math.PI;\n        velocityX = (float)(velocity * Math.cos(radians) / mass);\n        // Start with negative velocity since \"up\" means smaller values of y\n        velocityY = (float)(-velocity * Math.sin(radians) / mass);\n    }\n\n    public void step() {\n        // Make sure we're moving at all using our lastStep tracker as a sentinel\n        if (lastStep > 0) {\n            // let's apply our gravity\n            long now = System.currentTimeMillis();\n            float slice = (now - lastStep) / 1000.0f;\n            velocityY = velocityY + (slice * Field.GRAVITY);\n            int newX = (int)(centerX + velocityX);\n            int newY = (int)(centerY + velocityY);\n            setPosition(newX, newY);\n        }\n    }\n}\n"
  },
  {
    "path": "ch10/game/AppleToss.java",
    "content": "package ch10.game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ArrayList;\nimport java.util.Random;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main application window. With the new Swing components discussed\n * in this chapter, we can now make a fully functioning physicist\n * who can aim and toss apples.\n */\npublic class AppleToss extends JFrame {\n    public static final int SCORE_HEIGHT = 30;\n    public static final int CONTROL_WIDTH = 300;\n    public static final int CONTROL_HEIGHT = 40;\n    public static final int FIELD_WIDTH = 3 * CONTROL_WIDTH;\n    public static final int FIELD_HEIGHT = 2 * CONTROL_WIDTH;\n    public static final float FORCE_SCALE = 0.7f;\n\n    GridBagLayout gameLayout = new GridBagLayout();\n    GridBagConstraints gameConstraints = new GridBagConstraints();\n    JPanel gamePane = new JPanel(gameLayout);\n\n    Field field = new Field();\n    Physicist player1 = new Physicist();\n    ArrayList<Physicist> otherPlayers = new ArrayList<>();\n\n    Random random = new Random();\n\n    public AppleToss() {\n        // Create our frame\n        super(\"Apple Toss Game\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setResizable(false);\n\n        // Build the field with our player and some trees\n        setupFieldForOnePlayer();\n\n        // Setup the grid we'll use to layout our various components\n        gameLayout.columnWidths = new int[] { CONTROL_WIDTH, CONTROL_WIDTH, CONTROL_WIDTH };\n        gameLayout.rowHeights = new int[] { SCORE_HEIGHT, FIELD_HEIGHT, CONTROL_HEIGHT, CONTROL_HEIGHT };\n\n        // Now build and add those components at the desired position\n        JLabel player1score = new JLabel(\" Player 1: 0\");\n        field.scoreLabels[1] = player1score;\n        gamePane.add(player1score, buildConstraints(0, 0, 1, 1));\n        gamePane.add(buildRestartButton(), buildConstraints(0, 2, 1, 1));\n        gamePane.add(field, buildConstraints(1, 0, 1, 3));\n        gamePane.add(buildAngleControl(), buildConstraints(2, 0, 1, 1));\n        gamePane.add(buildForceControl(), buildConstraints(2, 1, 1, 1));\n        gamePane.add(buildTossButton(), buildConstraints(2, 2, 2, 1));\n        gamePane.add(new JLabel(\"Angle\", JLabel.CENTER), buildConstraints(3, 0, 1, 1));\n        gamePane.add(new JLabel(\"Force\", JLabel.CENTER), buildConstraints(3, 1, 1, 1));\n\n        // replace the frame's content with our game\n        setContentPane(gamePane);\n\n        // And set the correct size + a buffer for any OS frame title\n        setSize(FIELD_WIDTH,SCORE_HEIGHT + FIELD_HEIGHT + (2 * CONTROL_HEIGHT) + 20);\n    }\n\n    private GridBagConstraints buildConstraints(int row, int col, int rowspan, int colspan) {\n        gameConstraints.fill = GridBagConstraints.BOTH;\n        gameConstraints.gridy = row;\n        gameConstraints.gridx = col;\n        gameConstraints.gridheight = rowspan;\n        gameConstraints.gridwidth = colspan;\n        return gameConstraints;\n    }\n\n    private JButton buildRestartButton() {\n        JButton button = new JButton(\"Play Again\");\n        button.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                setupFieldForOnePlayer();\n                field.repaint();\n            }\n        });\n        return button;\n    }\n\n    private JSlider buildAngleControl() {\n        JSlider slider = new JSlider(0,180);\n        slider.setInverted(true);\n        slider.addChangeListener(new ChangeListener() {\n            @Override\n            public void stateChanged(ChangeEvent e) {\n                player1.setAimingAngle((float)slider.getValue());\n                field.repaint();\n            }\n        });\n        return slider;\n    }\n\n    private JSlider buildForceControl() {\n        JSlider slider = new JSlider();\n        slider.addChangeListener(new ChangeListener() {\n            @Override\n            public void stateChanged(ChangeEvent e) {\n                player1.setAimingForce(slider.getValue() * FORCE_SCALE);\n            }\n        });\n        return slider;\n    }\n\n    private JButton buildTossButton() {\n        JButton button = new JButton(\"Toss\");\n        button.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                field.startTossFromPlayer(player1);\n            }\n        });\n        return button;\n    }\n\n    /**\n     * Helper method to return a good x value for a tree so it's not off the left or right edge.\n     *\n     * @return x value within the bounds of the playing field width\n     */\n    private int goodX() {\n        // at least half the width of the tree plus a few pixels\n        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // now find a random number between a left and right margin\n        int rightMargin = FIELD_WIDTH - leftMargin;\n\n        // And return a random number starting at the left margin\n        return leftMargin + random.nextInt(rightMargin - leftMargin);\n    }\n\n    /**\n     * Helper method to return a good y value for a tree so it's not off the top or bottom of the screen.\n     *\n     * @return y value within the bounds of the playing field height\n     */\n    private int goodY() {\n        // at least half the height of the \"leaves\" plus a few pixels\n        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // a little higher off the bottom\n        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;\n\n        // And return a random number starting at the top margin but not past the bottom\n        return topMargin + random.nextInt(bottomMargin - topMargin);\n    }\n\n    /**\n     * A helper method to populate a one player field with target trees.\n     */\n    private void setupFieldForOnePlayer() {\n        // place our (new) physicist in the lower left corner\n        if (field.physicists.size() == 0) {\n            player1.setPosition(Field.PHYSICIST_SIZE_IN_PIXELS, FIELD_HEIGHT - (int) (Field.PHYSICIST_SIZE_IN_PIXELS * 1.5));\n            field.physicists.add(player1);\n            player1.setField(field);\n        }\n\t\t// Reset the score for our sole player\n\t\tfield.resetScore(1);\n\n        // Create some trees for target practice\n        for (int i = field.trees.size(); i < 10; i++) {\n            Tree t = new Tree();\n            t.setPosition(goodX(), goodY());\n            // Trees can be close to each other and overlap, but they shouldn't intersect our physicist\n            while(player1.isTouching(t)) {\n                // We do intersect this tree, so let's try again\n                t.setPosition(goodX(), goodY());\n                System.err.println(\"Repositioning an intersecting tree...\");\n            }\n            field.trees.add(t);\n        }\n    }\n\n    public static void main(String args[]) {\n        AppleToss game = new AppleToss();\n        game.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch10/game/Field.java",
    "content": "package ch10.game;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * The playing field for our game. Now we can setup some constants for\n * other game classes to use and create member variables for our player and some trees.\n */\npublic class Field extends JComponent implements ActionListener {\n    public static final float GRAVITY = 9.8f;  // feet per second per second\n    public static final int STEP = 40;   // duration of an animation frame in milliseconds\n    public static final int APPLE_SIZE_IN_PIXELS = 30;\n    public static final int TREE_WIDTH_IN_PIXELS = 60;\n    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;\n    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;\n\n    public static final int MAX_PHYSICISTS = 5;\n    public static final int MAX_APPLES_PER_PHYSICIST = 3;\n    public static final int MAX_TREES = 12;\n\n    Color fieldColor = Color.GRAY;\n\n\t// Keep track of our own score and also make room for multiple players\n    int myScore = 0;\n    String[] scores = new String[3];\n    JLabel[] scoreLabels = new JLabel[3];\n\t\n    List<Physicist> physicists = Collections.synchronizedList(new ArrayList<>());\n    List<Apple> apples = Collections.synchronizedList(new ArrayList<>());\n    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());\n\n    boolean animating = false;\n    Thread animationThread;\n    Timer animationTimer;\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(fieldColor);\n        g.fillRect(0,0, getWidth(), getHeight());\n        for (Physicist p : physicists) {\n            p.draw(g);\n        }\n        for (Tree t : trees) {\n            t.draw(g);\n        }\n        for (Apple a : apples) {\n            a.draw(g);\n        }\n    }\n\n    public void actionPerformed(ActionEvent event) {\n        if (animating && event.getActionCommand().equals(\"repaint\")) {\n            System.out.println(\"Timer stepping \" + apples.size() + \" apples\");\n            for (Apple a : apples) {\n                a.step();\n                detectCollisions(a);\n            }\n            repaint();\n            cullFallenApples();\n        }\n    }\n\n    /**\n     * Toss an apple from the given physicist using that physicist's aim and force.\n     * Make sure the field is in the animating state.\n     *\n     * @param physicist the player whose apple should be tossed\n     */\n    public void startTossFromPlayer(Physicist physicist) {\n        if (!animating) {\n            System.out.println(\"Starting animation!\");\n            animating = true;\n            startAnimation();\n        }\n        if (animating) {\n            // Check to make sure we have an apple to toss\n            if (physicist.aimingApple != null) {\n                Apple apple = physicist.takeApple();\n                apple.toss(physicist.aimingAngle, physicist.aimingForce);\n                apples.add(apple);\n                Timer appleLoader = new Timer(800, physicist);\n                appleLoader.setActionCommand(\"New Apple\");\n                appleLoader.setRepeats(false);\n                appleLoader.start();\n            }\n        }\n    }\n\n    void cullFallenApples() {\n        Iterator<Apple> iterator = apples.iterator();\n        while (iterator.hasNext()) {\n            Apple a = iterator.next();\n            if (a.getCollidedPiece() != null) {\n                GamePiece otherPiece = a.getCollidedPiece();\n                if (otherPiece instanceof Physicist) {\n                    hitPhysicist((Physicist) otherPiece);\n                } else if (otherPiece instanceof Tree) {\n                    hitTree((Tree) otherPiece);\n                }\n                // Remove ourselves. If the other piece we hit was an apple, leave it alone.\n                // It will be removed when the iterator comes to it.\n                iterator.remove();\n            } else if (a.getPositionY() > 600) {\n                System.out.println(\"Culling apple\");\n                iterator.remove();\n            }\n        }\n        if (apples.size() <= 0) {\n            animating = false;\n            if (animationTimer != null && animationTimer.isRunning()) {\n                animationTimer.stop();\n            }\n        }\n    }\n\n    void detectCollisions(Apple apple) {\n        // Check for other apples\n        for (Apple a : apples) {\n            if (apple.isTouching(a)) {\n                System.out.println(\"Touching another apple!\");\n                return;\n            }\n        }\n        // Check for physicists\n        for (Physicist p : physicists) {\n            if (apple.isTouching(p)) {\n                System.out.println(\"Touching a physicist!\");\n                return;\n            }\n        }\n        // Check for trees\n        for (Tree t : trees) {\n            if (apple.isTouching(t)) {\n                System.out.println(\"Touching a tree!\");\n                return;\n            }\n        }\n    }\n\n    void hitPhysicist(Physicist physicist) {\n        // do any scoring or notifications here\n        physicists.remove(physicist);\n    }\n\n    void hitTree(Tree tree) {\n        // do any scoring or notifications here\n        myScore += 10;\n        trees.remove(tree);\n        setScore(1, String.valueOf(myScore));\n    }\n\n    public void resetScore(int playerNumber) {\n\t\tmyScore = 0;\n\t\tsetScore(playerNumber, \"0\");\n    }\n\n    public String getScore(int playerNumber) {\n        return scores[playerNumber];\n    }\n\n    public void setScore(int playerNumber, String score) {\n        scores[playerNumber] = score;\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                String newScore = \" Player \" + playerNumber + \": \" + score;\n                scoreLabels[playerNumber].setText(newScore);\n            }\n        });\n    }\n\n    void startAnimation() {\n        // Animator myAnimator = new Animator();\n        // animationThread = new Thread(myAnimator);\n        // animationThread.start();\n        if (animationTimer == null) {\n            animationTimer = new Timer(STEP, this);\n            animationTimer.setActionCommand(\"repaint\");\n            animationTimer.setRepeats(true);\n            animationTimer.start();\n        } else if (!animationTimer.isRunning()) {\n            animationTimer.restart();\n        }\n    }\n\n    class Animator implements Runnable {\n        public void run() {\n            while (animating) {\n                System.out.println(\"Stepping \" + apples.size() + \" apples\");\n                for (Apple a : apples) {\n                    a.step();\n                    detectCollisions(a);\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Field.this.repaint();\n                    }\n                });\n                cullFallenApples();\n                try {\n                    Thread.sleep((int)(STEP * 1000));\n                } catch (InterruptedException ie) {\n                    System.err.println(\"Animation interrupted\");\n                    animating = false;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ch10/game/GamePiece.java",
    "content": "package ch10.game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * From the README:\n * GamePiece\n *   - methods for positioning on a PlayingField\n *   - methods for Drawing\n *   - methods for detecting a collision with other GamePieces\n */\npublic interface GamePiece {\n    /**\n     * Sets the position of the piece on the playing field.\n     * (0,0) is the upper left per standard Java drawing methods.\n     *\n     * @param x\n     * @param y\n     */\n    void setPosition(int x, int y);\n\n    /**\n     * Gets the current horizontal position of the piece on the field.\n     *\n     * @return current X position of the piece\n     */\n    int getPositionX();\n\n    /**\n     * Gets the current vertical position of the piece on the field.\n     *\n     * @return current Y position of the piece\n     */\n    int getPositionY();\n\n    /**\n     * Gets the bounding box of this piece.\n     *\n     * @return a Rectangle encompassing the visual elements of the piece\n     */\n    Rectangle getBoundingBox();\n\n    /**\n     * Draws the piece inside the given graphics context.\n     * Do not assume anything about the state of the context.\n     *\n     * @param g\n     */\n    void draw(Graphics g);\n\n    /**\n     * Detect a collision with another piece on the field.\n     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).\n     *\n     * @param otherPiece\n     * @return\n     */\n    boolean isTouching(GamePiece otherPiece);\n}\n"
  },
  {
    "path": "ch10/game/GameUtilities.java",
    "content": "package ch10.game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection\n\nimport java.awt.*;\n\n/**\n * Utility class with a few helper methods for calculating various collisions and\n * intersections.\n */\npublic class GameUtilities {\n    static boolean isPointInsideBox(int x, int y, Rectangle box) {\n        // Our own custom test. We could of course use box.contains(),\n        // but we can practice some interesting conditional checking here.\n        // Let's test left and right first\n        if (x >= box.x && x <= (box.x + box.width)) {\n            // Our x coordinate is ok, so check our y\n            if (y >= box.y && y <= (box.y + box.height)) {\n                return true;\n            }\n        }\n        // x or y was outside the box, so return false\n        return false;\n    }\n\n    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {\n        // If any of the four corners of box are inside other, we intersect, so\n        // let's check each one. Happily, that answer doesn't change if more\n        // than one corner is contained in other, so we can return as soon as\n        // we find the first contained corner.\n\n        // Let's get some local copies of the corner coordinates\n        // to make the call arguments easier to read.\n        int x1 = box.x;\n        int y1 = box.y;\n        int x2 = x1 + box.width;\n        int y2 = y1 + box.height;\n        if (isPointInsideBox(x1, y1, other)) {\n            // upper left\n            return true;\n        } else if (isPointInsideBox(x1, y2, other)) {\n            // lower left\n            return true;\n        } else if (isPointInsideBox(x2, y1, other)) {\n            // upper right\n            return true;\n        } else if (isPointInsideBox(x2, y2, other)) {\n            // lower right\n            return true;\n        }\n        // No box points in other so no intersection\n        return false;\n    }\n\n    /**\n     * Given two rectangles, do the overlap at all? This includes one box being\n     * completely contained by the other box.\n     *\n     * @param box1 a box to test, order does not matter\n     * @param box2 the other box\n     * @return true if the boxes overlap, false otherwise\n     */\n    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {\n        // Another custom test. We could of course use box1.intersects(box2)\n        // but we can practice method calls and some boolean logic here.\n        if (doesBoxIntersect(box1, box2)) {\n            // At least one of box1's points must be inside box2\n            return true;\n        } else if (doesBoxIntersect(box2, box1)) {\n            // None of box1's points were in box2, but at least one of box2's points are inside box1\n            return true;\n        }\n        // No intersections in either direction\n        return false;\n    }\n}\n"
  },
  {
    "path": "ch10/game/Physicist.java",
    "content": "package ch10.game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport static java.awt.Color.*;\n\n/**\n * Our player class. A physicist has an apple that they can throw in addition\n * to implementing the basic methods for GamePiece. We can also set a custom\n * color in case you build on the game and allow multiple physicists to be\n * on the screen at the same time.\n */\npublic class Physicist implements GamePiece, ActionListener {\n    Color color;\n    int centerX, centerY;\n    Apple aimingApple;\n    float aimingAngle;\n    float aimingForce;\n    Field field;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n\n    // Boundary helpers\n    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);\n    private Rectangle boundingBox;\n\n\n    /**\n     * Create a default, blue physicist\n     */\n    public Physicist() {\n        this(BLUE);\n    }\n\n    /**\n     * Create a Physicist of the given color\n     */\n    public Physicist(Color color) {\n        setColor(color);\n        aimingAngle = 90.0f;\n        aimingForce = 50.0f;\n        getNewApple();\n    }\n\n    public void setAimingAngle(Float angle) {\n        aimingAngle = angle;\n    }\n\n    public void setAimingForce(Float force) {\n        if (force < 0) {\n            force = 0.0f;\n        }\n        aimingForce = force;\n    }\n\n    /**\n     * Sets the color for the physicist.\n     *\n     * @param color\n     */\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of our dome,\n        // but it will be drawn from the upper left corner.\n        // Figure out the distance of that gap\n        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    /**\n     * Sets the active field once our physicist is being displayed.\n     *\n     * @param field Active game field\n     */\n    public void setField(Field field) {\n        this.field = field;\n    }\n\n    /**\n     * Take the current apple away from the physicist. Returns the apple for\n     * use in animating on the field. Note that if there is no current apple being\n     * aimed, null is returned.\n     *\n     * @return the current apple (if any) being aimed\n     */\n    public Apple takeApple() {\n        Apple myApple = aimingApple;\n        aimingApple = null;\n        return myApple;\n    }\n\n    /**\n     * Get a new apple ready if we need one. Do not discard an existing apple.\n     */\n    public void getNewApple() {\n        // Don't drop the current apple if we already have one!\n        if (aimingApple == null) {\n            aimingApple = new Apple(this);\n        }\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our physicist is the right color, then draw the semi-circle and box\n        g.setColor(color);\n        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);\n        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);\n\n        // Do we have an apple to draw as well?\n        if (aimingApple != null) {\n            // Yes. Position the center of the apple on the edge of our semi-circle.\n            // Use the current aimingAngle to determine where on the edge.\n            double angleInRadians = Math.toRadians(aimingAngle);\n            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;\n            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);\n            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);\n            aimingApple.setPosition(aimingX, aimingY);\n            aimingApple.draw(g);\n        }\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        if (e.getActionCommand().equals(\"New Apple\")) {\n            getNewApple();\n            if (field != null) {\n                field.repaint();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ch10/game/Tree.java",
    "content": "package ch10.game;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n * They are built using sizes determined by the constants in the Field class.\n */\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    private Color leafColor = Color.GREEN.darker();\n    private Color trunkColor = new Color(101, 67, 33);\n    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);\n    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);\n    private int trunkX, trunkY;\n\n    // Boundary helpers\n    private Rectangle boundingBox;\n\n    @Override\n    public void setPosition(int x, int y) {\n        this.x = x;\n        this.y = y;\n        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;\n        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;\n        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);\n    }\n\n    @Override\n    public int getPositionX() {\n        return x;\n    }\n\n    @Override\n    public int getPositionY() {\n        return y;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        g.setColor(trunkColor);\n        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);\n        g.setColor(leafColor);\n        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  },
  {
    "path": "ch11/CopyChannels.java",
    "content": "package ch11;\n\nimport java.io.*;\nimport java.nio.*;\nimport java.nio.channels.*;\n\n/**\n * A quick demo of copying files using FileChannels.\n * The names of the source and destination are passed as\n * command line arguments.\n */\npublic class CopyChannels {\n\tpublic static void main( String [] args ) throws Exception {\n\t\tString fromFileName = args[0];\n\t\tString toFileName = args[1];\n\t\tFileChannel in = new FileInputStream( fromFileName ).getChannel();\n\t\tFileChannel out = new FileOutputStream( toFileName ).getChannel();\n\t\t\n\t\tByteBuffer buff = ByteBuffer.allocate( 32*1024 );\n\n\t\twhile ( in.read( buff ) > 0 ) {\n\t\t\tbuff.flip();\n\t\t\tout.write( buff );\n\t\t\tbuff.clear();\n\t\t}\n\n\t\tin.close();\n\t\tout.close();\n\t}\n}\n"
  },
  {
    "path": "ch11/CopyChannels2.java",
    "content": "package ch11;\n\nimport java.io.*;\nimport java.nio.*;\nimport java.nio.channels.*;\n\n/**\n * A quick demo of copying files using FileChannels.\n * The names of the source and destination are passed as\n * command line arguments.\n */\npublic class CopyChannels2 {\n\tpublic static void main( String [] args ) throws Exception {\n\t\tString fromFileName = args[0];\n\t\tString toFileName = args[1];\n\t\tFileChannel in = new FileInputStream( fromFileName ).getChannel();\n\t\tFileChannel out = new FileOutputStream( toFileName ).getChannel();\n\t\t\n\t\tByteBuffer buff = ByteBuffer.allocateDirect( 32*1024 );\n\n\t\twhile ( in.read( buff ) > 0 ) {\n\t\t\tbuff.flip();\n\t\t\tout.write( buff );\n\t\t\tbuff.clear();\n\t\t}\n\n\t\tin.close();\n\t\tout.close();\n\t}\n}\n"
  },
  {
    "path": "ch11/CopyChannels3.java",
    "content": "package ch11;\n\nimport java.io.*;\nimport java.nio.*;\nimport java.nio.channels.*;\n\n/**\n * A quick demo of copying files using FileChannels.\n * The names of the source and destination are passed as\n * command line arguments.\n */\npublic class CopyChannels3 {\n\tpublic static void main( String [] args ) throws Exception {\n\t\tString fromFileName = args[0];\n\t\tString toFileName = args[1];\n\t\tFileChannel in = new FileInputStream( fromFileName ).getChannel();\n\t\tFileChannel out = new FileOutputStream( toFileName ).getChannel();\n\t\tin.transferTo( 0, (int)in.size(), out );\n\t\tin.close();\n\t\tout.close();\n\t}\n}\n"
  },
  {
    "path": "ch11/CopyFile.java",
    "content": "package ch11;\n\nimport java.nio.channels.*;\nimport java.nio.file.*;\nimport static java.nio.file.StandardOpenOption.*;\n\n/**\n * A quick demo of copying files using the FileChannel class.\n * The names of the source and destination are passed as\n * command line arguments.\n */\npublic class CopyFile {\n    public static void main( String [] args ) throws Exception {\n        FileSystem fs = FileSystems.getDefault();\n        Path fromFile = fs.getPath( args[0] );\n        Path toFile = fs.getPath( args[1] );\n\n\t\t// By using the try-with-resources pattern, our channels\n\t\t// will automagically be cleaned up when we're done.\n        try (\n            FileChannel in = FileChannel.open( fromFile );\n            FileChannel out = FileChannel.open( toFile, CREATE, WRITE ); )\n        {\n            in.transferTo( 0, (int)in.size(), out );\n        }\n    }\n}"
  },
  {
    "path": "ch11/CopyStreams.java",
    "content": "package ch11;\n\nimport java.io.*;\n\n/**\n * A quick demo of copying files using basic streams.\n * The names of the source and destination are passed as\n * command line arguments.\n */\npublic class CopyStreams {\n\tpublic static void main( String [] args ) throws Exception {\n\t\tString fromFileName = args[0];\n\t\tString toFileName = args[1];\n\t\tBufferedInputStream in = new BufferedInputStream(\n\t\t\tnew FileInputStream( fromFileName ) );\n\t\tBufferedOutputStream out = new BufferedOutputStream(\n\t\t\tnew FileOutputStream( toFileName ) );\n\t\tbyte [] buff = new byte [ 32*1024 ];\n\t\tint len;\n\t\twhile ( (len = in.read( buff )) > 0 )\n\t\t\tout.write( buff, 0, len );\n\t\tin.close();\n\t\tout.close();\n\t}\n}\n"
  },
  {
    "path": "ch11/DateAtHost.java",
    "content": "//file: DateAtHost.java\nimport java.net.Socket;\nimport java.io.*;\n\npublic class DateAtHost extends java.util.Date {\n    static int timePort = 37;\n    // seconds from start of 20th century to Jan 1, 1970 00:00 GMT\n    static final long offset = 2208988800L;\n\n    public DateAtHost( String host ) throws IOException {\n        this( host, timePort );\n    }\n\n    public DateAtHost( String host, int port ) throws IOException {\n        Socket server = new Socket( host, port );\n        DataInputStream din =\n          new DataInputStream( server.getInputStream(  ) );\n        int time = din.readInt(  );\n        server.close(  );\n\n        setTime( (((1L << 32) + time) - offset) * 1000 );\n    }\n}\n"
  },
  {
    "path": "ch11/ListIt.java",
    "content": "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 directory, the directory gets listed. If it\n * is a readable file, the content is dumped to the console.\n */\npublic class ListIt {\n    public static void main ( String args[] ) throws Exception {\n        File file =  new File( args[0] );\n\n        if ( !file.exists() || !file.canRead(  ) ) {\n            System.out.println( \"Can't read \" + file );\n            return;\n        }\n\n        if ( file.isDirectory(  ) ) {\n            String [] files = file.list(  );\n            for (int i=0; i< files.length; i++)\n                System.out.println( files[i] );\n        }\n        else\n            try {\n                Reader ir = new InputStreamReader( new FileInputStream( file ) );\n                BufferedReader in = new BufferedReader( ir );\n                String line;\n                while ((line = in.readLine(  )) != null)\n                System.out.println(line);\n            }\n            catch ( FileNotFoundException e ) {\n                System.out.println( \"File Disappeared\" );\n            }\n    }\n}\n"
  },
  {
    "path": "ch11/game/Apple.java",
    "content": "package ch11.game;\n\nimport java.awt.*;\n\n/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the size and weight details and provide a few simple methods for lobbing. We\n * also provide animation helpers for use with the PlayingField class.\n */\npublic class Apple implements GamePiece {\n    public static final int SMALL  = 0;\n    public static final int MEDIUM = 1;\n    public static final int LARGE  = 2;\n\n    int size;\n    double diameter;\n    double mass;\n    int centerX, centerY;\n    Physicist myPhysicist;\n\n    // In game play, apples can be thrown so track their velocities\n    long lastStep;\n    float velocityX, velocityY;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n    int scaledLength;\n\n    // Boundary helper for optimizing collision detection with physicists and trees\n    Rectangle boundingBox;\n\n    // If we bumped into something, keep a reference to that thing around for cleanup and removal\n    GamePiece collided;\n\n    /**\n     * Create a default, Medium apple\n     */\n    public Apple(Physicist owner) {\n        this(owner, MEDIUM);\n    }\n\n    /**\n     * Create an Apple of the given size\n     */\n    public Apple(Physicist owner, int size) {\n        myPhysicist = owner;\n        setSize(size);\n    }\n\n    /**\n     * Sets the size (and dependent properties) of the apple based on the\n     * supplied value which must be one of the size constants.\n     *\n     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE\n     */\n    public void setSize(int size) {\n        if (size < SMALL) {\n            size = SMALL;\n        }\n        if (size > LARGE) {\n            size = LARGE;\n        }\n        this.size = size;\n        switch (size) {\n            case SMALL:\n                diameter = 0.9;\n                mass = 0.5;\n                break;\n            case MEDIUM:\n                diameter = 1.0;\n                mass = 1.0;\n                break;\n            case LARGE:\n                diameter = 1.1;\n                mass = 1.8;\n                break;\n        }\n        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.\n        // Since we want a circle, we simply make our box a square so we only need one length.\n        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    public double getDiameter() {\n        return diameter;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of the apple, but it will be drawn from the\n        // upper left corner, so figure out the distance of that gap\n        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our apple will be red, then paint it!\n        g.setColor(Color.RED);\n        g.fillOval(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {\n            // By definition we don't collide with ourselves, our physicist, or with more than one other piece\n            return false;\n        }\n        if (otherPiece instanceof Apple) {\n            // The other piece is an apple, so we can do a simple distance calculation using\n            // the diameters of both apples.\n            Apple otherApple = (Apple) otherPiece;\n            int v = this.y - otherPiece.getPositionY(); // vertical difference\n            int h = this.x - otherPiece.getPositionX(); // horizontal difference\n            double distance = Math.sqrt(v * v + h * h);\n\n            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;\n            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;\n            if (distance < (myRadius + otherRadius)) {\n                // Since apples track collisions, we'll update the other apple to keep everyone in sync\n                setCollided(otherPiece);\n                otherApple.setCollided(this);\n                return true;\n            }\n            return false;\n        }\n        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {\n            setCollided(otherPiece);\n            return true;\n        }\n        return false;\n    }\n\n    public GamePiece getCollidedPiece() {\n        return collided;\n    }\n\n    public void setCollided(GamePiece otherPiece) {\n        this.collided = otherPiece;\n    }\n\n    public void toss(float angle, float velocity) {\n        lastStep = System.currentTimeMillis();\n        double radians = angle / 180 * Math.PI;\n        velocityX = (float)(velocity * Math.cos(radians) / mass);\n        // Start with negative velocity since \"up\" means smaller values of y\n        velocityY = (float)(-velocity * Math.sin(radians) / mass);\n    }\n\n    public void step() {\n        // Make sure we're moving at all using our lastStep tracker as a sentinel\n        if (lastStep > 0) {\n            // let's apply our gravity\n            long now = System.currentTimeMillis();\n            float slice = (now - lastStep) / 1000.0f;\n            velocityY = velocityY + (slice * Field.GRAVITY);\n            int newX = (int)(centerX + velocityX);\n            int newY = (int)(centerY + velocityY);\n            setPosition(newX, newY);\n        }\n    }\n}\n"
  },
  {
    "path": "ch11/game/AppleToss.java",
    "content": "package ch11.game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ArrayList;\nimport java.util.Random;\n\n/**\n * Our apple tossing game. This class extends JFrame to create our\n * main application window. We're getting closer to our final\n * version of the game which allows two players to compete in a timed\n * trial to see who can clear the trees fastest.\n */\npublic class AppleToss extends JFrame {\n    public static final int SCORE_HEIGHT = 30;\n    public static final int CONTROL_WIDTH = 300;\n    public static final int CONTROL_HEIGHT = 40;\n    public static final int FIELD_WIDTH = 3 * CONTROL_WIDTH;\n    public static final int FIELD_HEIGHT = 2 * CONTROL_WIDTH;\n    public static final float FORCE_SCALE = 0.7f;\n\n    GridBagLayout gameLayout = new GridBagLayout();\n    GridBagConstraints gameConstraints = new GridBagConstraints();\n    JPanel gamePane = new JPanel(gameLayout);\n\n    Field field = new Field();\n    Physicist player1 = new Physicist();\n    ArrayList<Physicist> otherPlayers = new ArrayList<>();\n\n    Random random = new Random();\n\n    public AppleToss() {\n        // Create our frame\n        super(\"Apple Toss Game\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setResizable(false);\n\n        // Build the field with our player and some trees\n        setupFieldForOnePlayer();\n\n        // Setup the grid we'll use to layout our various components\n        gameLayout.columnWidths = new int[] { CONTROL_WIDTH, CONTROL_WIDTH, CONTROL_WIDTH };\n        gameLayout.rowHeights = new int[] { SCORE_HEIGHT, FIELD_HEIGHT, CONTROL_HEIGHT, CONTROL_HEIGHT };\n\n        // Now build and add those components at the desired position\n        gamePane.add(new JLabel(\" Player 1: 0\"), buildConstraints(0, 0, 1, 1));\n        // gamePane.add(new JLabel(\" Player 2: 0\"), buildConstraints(0, 1, 1, 1));\n        gamePane.add(buildRestartButton(), buildConstraints(0, 2, 1, 1));\n        gamePane.add(field, buildConstraints(1, 0, 1, 3));\n        gamePane.add(buildAngleControl(), buildConstraints(2, 0, 1, 1));\n        gamePane.add(buildForceControl(), buildConstraints(2, 1, 1, 1));\n        gamePane.add(buildTossButton(), buildConstraints(2, 2, 2, 1));\n        gamePane.add(new JLabel(\"Angle\", JLabel.CENTER), buildConstraints(3, 0, 1, 1));\n        gamePane.add(new JLabel(\"Force\", JLabel.CENTER), buildConstraints(3, 1, 1, 1));\n\n\t\t// Setup the networking menu (actions are left to the read to implement)\n\t\tsetupNetworkMenu();\n\t\t\n        // replace the frame's content with our game\n        setContentPane(gamePane);\n\n        // And set the correct size + a buffer for any OS frame title\n        setSize(FIELD_WIDTH,SCORE_HEIGHT + FIELD_HEIGHT + (2 * CONTROL_HEIGHT) + 20);\n    }\n\n    private GridBagConstraints buildConstraints(int row, int col, int rowspan, int colspan) {\n        gameConstraints.fill = GridBagConstraints.BOTH;\n        gameConstraints.gridy = row;\n        gameConstraints.gridx = col;\n        gameConstraints.gridheight = rowspan;\n        gameConstraints.gridwidth = colspan;\n        return gameConstraints;\n    }\n\n    private JButton buildRestartButton() {\n        JButton button = new JButton(\"Play Again\");\n        button.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                setupFieldForOnePlayer();\n                field.repaint();\n            }\n        });\n        return button;\n    }\n\n    private JSlider buildAngleControl() {\n        JSlider slider = new JSlider(0,180);\n        slider.setInverted(true);\n        slider.addChangeListener(new ChangeListener() {\n            @Override\n            public void stateChanged(ChangeEvent e) {\n                player1.setAimingAngle((float)slider.getValue());\n                field.repaint();\n            }\n        });\n        return slider;\n    }\n\n    private JSlider buildForceControl() {\n        JSlider slider = new JSlider();\n        slider.addChangeListener(new ChangeListener() {\n            @Override\n            public void stateChanged(ChangeEvent e) {\n                player1.setAimingForce(slider.getValue() * FORCE_SCALE);\n            }\n        });\n        return slider;\n    }\n\n    private JButton buildTossButton() {\n        JButton button = new JButton(\"Toss\");\n        button.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                field.startTossFromPlayer(player1);\n            }\n        });\n        return button;\n    }\n\n    private void setupNetworkMenu() {\n        JMenu netMenu = new JMenu(\"Multiplayer\");\n\n        JMenuItem startItem = new JMenuItem(\"Start Server\");\n        startItem.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n\t\t\t\tJOptionPane.showMessageDialog(AppleToss.this, \"Start Server selected\",\n\t\t\t\t\t\"Network Alert\", JOptionPane.INFORMATION_MESSAGE);\n            }\n        });\n        netMenu.add(startItem);\n\n        JMenuItem joinItem = new JMenuItem(\"Join Game...\");\n        joinItem.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n\t\t\t\tJOptionPane.showMessageDialog(AppleToss.this, \"Join Game selected\",\n\t\t\t\t\t\"Network Alert\", JOptionPane.INFORMATION_MESSAGE);\n            }\n        });\n        netMenu.add(joinItem);\n\n        JMenuItem quitItem = new JMenuItem(\"Disconnect\");\n        quitItem.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n\t\t\t\tJOptionPane.showMessageDialog(AppleToss.this, \"Disconnect selected\",\n\t\t\t\t\t\"Network Alert\", JOptionPane.INFORMATION_MESSAGE);\n            }\n        });\n        netMenu.add(quitItem);\n\n        // build a JMenuBar for the application\n        JMenuBar mainBar = new JMenuBar();\n        mainBar.add(netMenu);\n        setJMenuBar(mainBar);\n    }\n\n    /**\n     * Helper method to return a good x value for a tree so it's not off the left or right edge.\n     *\n     * @return x value within the bounds of the playing field width\n     */\n    private int goodX() {\n        // at least half the width of the tree plus a few pixels\n        int leftMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // now find a random number between a left and right margin\n        int rightMargin = FIELD_WIDTH - leftMargin;\n\n        // And return a random number starting at the left margin\n        return leftMargin + random.nextInt(rightMargin - leftMargin);\n    }\n\n    /**\n     * Helper method to return a good y value for a tree so it's not off the top or bottom of the screen.\n     *\n     * @return y value within the bounds of the playing field height\n     */\n    private int goodY() {\n        // at least half the height of the \"leaves\" plus a few pixels\n        int topMargin = Field.TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // a little higher off the bottom\n        int bottomMargin = FIELD_HEIGHT - Field.TREE_HEIGHT_IN_PIXELS;\n\n        // And return a random number starting at the top margin but not past the bottom\n        return topMargin + random.nextInt(bottomMargin - topMargin);\n    }\n\n    /**\n     * A helper method to populate a one player field with target trees.\n     */\n    private void setupFieldForOnePlayer() {\n        // place our (new) physicist in the lower left corner\n        if (field.physicists.size() == 0) {\n            player1.setPosition(Field.PHYSICIST_SIZE_IN_PIXELS, FIELD_HEIGHT - (int) (Field.PHYSICIST_SIZE_IN_PIXELS * 1.5));\n            field.physicists.add(player1);\n            player1.setField(field);\n        }\n\n        // Create some trees for target practice\n        for (int i = field.trees.size(); i < 10; i++) {\n            Tree t = new Tree();\n            t.setPosition(goodX(), goodY());\n            // Trees can be close to each other and overlap, but they shouldn't intersect our physicist\n            while(player1.isTouching(t)) {\n                // We do intersect this tree, so let's try again\n                t.setPosition(goodX(), goodY());\n                System.err.println(\"Repositioning an intersecting tree...\");\n            }\n            field.trees.add(t);\n        }\n    }\n\n    public static void main(String args[]) {\n        AppleToss game = new AppleToss();\n        game.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "ch11/game/Field.java",
    "content": "package ch11.game;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * The playing field for our game. Now we can setup some constants for\n * other game classes to use and create member variables for our player and some trees.\n */\npublic class Field extends JComponent implements ActionListener {\n    public static final float GRAVITY = 9.8f;  // feet per second per second\n    public static final int STEP = 40;   // duration of an animation frame in milliseconds\n    public static final int APPLE_SIZE_IN_PIXELS = 30;\n    public static final int TREE_WIDTH_IN_PIXELS = 60;\n    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;\n    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;\n\n    public static final int MAX_PHYSICISTS = 5;\n    public static final int MAX_APPLES_PER_PHYSICIST = 3;\n    public static final int MAX_TREES = 12;\n\n    Color fieldColor = Color.GRAY;\n\n    // ArrayList will be covered in Generics chapter\n    // synchronizedArrayList will be covered in Threads chapter\n    List<Physicist> physicists = Collections.synchronizedList(new ArrayList<>());\n    List<Apple> apples = Collections.synchronizedList(new ArrayList<>());\n    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());\n\n    boolean animating = false;\n    Thread animationThread;\n    Timer animationTimer;\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(fieldColor);\n        g.fillRect(0,0, getWidth(), getHeight());\n        for (Physicist p : physicists) {\n            p.draw(g);\n        }\n        for (Tree t : trees) {\n            t.draw(g);\n        }\n        for (Apple a : apples) {\n            a.draw(g);\n        }\n    }\n\n    public void actionPerformed(ActionEvent event) {\n        if (animating && event.getActionCommand().equals(\"repaint\")) {\n            System.out.println(\"Timer stepping \" + apples.size() + \" apples\");\n            for (Apple a : apples) {\n                a.step();\n                detectCollisions(a);\n            }\n            repaint();\n            cullFallenApples();\n        }\n    }\n\n    /**\n     * Toss an apple from the given physicist using that physicist's aim and force.\n     * Make sure the field is in the animating state.\n     *\n     * @param physicist the player whose apple should be tossed\n     */\n    public void startTossFromPlayer(Physicist physicist) {\n        if (!animating) {\n            System.out.println(\"Starting animation!\");\n            animating = true;\n            startAnimation();\n        }\n        if (animating) {\n            // Check to make sure we have an apple to toss\n            if (physicist.aimingApple != null) {\n                Apple apple = physicist.takeApple();\n                apple.toss(physicist.aimingAngle, physicist.aimingForce);\n                apples.add(apple);\n                Timer appleLoader = new Timer(800, physicist);\n                appleLoader.setActionCommand(\"New Apple\");\n                appleLoader.setRepeats(false);\n                appleLoader.start();\n            }\n        }\n    }\n\n    void cullFallenApples() {\n        Iterator<Apple> iterator = apples.iterator();\n        while (iterator.hasNext()) {\n            Apple a = iterator.next();\n            if (a.getCollidedPiece() != null) {\n                GamePiece otherPiece = a.getCollidedPiece();\n                if (otherPiece instanceof Physicist) {\n                    hitPhysicist((Physicist) otherPiece);\n                } else if (otherPiece instanceof Tree) {\n                    hitTree((Tree) otherPiece);\n                }\n                // Remove ourselves. If the other piece we hit was an apple, leave it alone.\n                // It will be removed when the iterator comes to it.\n                iterator.remove();\n            } else if (a.getPositionY() > 600) {\n                System.out.println(\"Culling apple\");\n                iterator.remove();\n            }\n        }\n        if (apples.size() <= 0) {\n            animating = false;\n            if (animationTimer != null && animationTimer.isRunning()) {\n                animationTimer.stop();\n            }\n        }\n    }\n\n    void detectCollisions(Apple apple) {\n        // Check for other apples\n        for (Apple a : apples) {\n            if (apple.isTouching(a)) {\n                System.out.println(\"Touching another apple!\");\n                return;\n            }\n        }\n        // Check for physicists\n        for (Physicist p : physicists) {\n            if (apple.isTouching(p)) {\n                System.out.println(\"Touching a physicist!\");\n                return;\n            }\n        }\n        // Check for trees\n        for (Tree t : trees) {\n            if (apple.isTouching(t)) {\n                System.out.println(\"Touching a tree!\");\n                return;\n            }\n        }\n    }\n\n    void hitPhysicist(Physicist physicist) {\n        // do any scoring or notifications here\n        physicists.remove(physicist);\n    }\n\n    void hitTree(Tree tree) {\n        // do any scoring or notifications here\n        trees.remove(tree);\n    }\n\n    void startAnimation() {\n        // Animator myAnimator = new Animator();\n        // animationThread = new Thread(myAnimator);\n        // animationThread.start();\n        if (animationTimer == null) {\n            animationTimer = new Timer(STEP, this);\n            animationTimer.setActionCommand(\"repaint\");\n            animationTimer.setRepeats(true);\n            animationTimer.start();\n        } else if (!animationTimer.isRunning()) {\n            animationTimer.restart();\n        }\n    }\n\n    class Animator implements Runnable {\n        public void run() {\n            while (animating) {\n                System.out.println(\"Stepping \" + apples.size() + \" apples\");\n                for (Apple a : apples) {\n                    a.step();\n                    detectCollisions(a);\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Field.this.repaint();\n                    }\n                });\n                cullFallenApples();\n                try {\n                    Thread.sleep((int)(STEP * 1000));\n                } catch (InterruptedException ie) {\n                    System.err.println(\"Animation interrupted\");\n                    animating = false;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ch11/game/GamePiece.java",
    "content": "package ch11.game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * From the README:\n * GamePiece\n *   - methods for positioning on a PlayingField\n *   - methods for Drawing\n *   - methods for detecting a collision with other GamePieces\n */\npublic interface GamePiece {\n    /**\n     * Sets the position of the piece on the playing field.\n     * (0,0) is the upper left per standard Java drawing methods.\n     *\n     * @param x\n     * @param y\n     */\n    void setPosition(int x, int y);\n\n    /**\n     * Gets the current horizontal position of the piece on the field.\n     *\n     * @return current X position of the piece\n     */\n    int getPositionX();\n\n    /**\n     * Gets the current vertical position of the piece on the field.\n     *\n     * @return current Y position of the piece\n     */\n    int getPositionY();\n\n    /**\n     * Gets the bounding box of this piece.\n     *\n     * @return a Rectangle encompassing the visual elements of the piece\n     */\n    Rectangle getBoundingBox();\n\n    /**\n     * Draws the piece inside the given graphics context.\n     * Do not assume anything about the state of the context.\n     *\n     * @param g\n     */\n    void draw(Graphics g);\n\n    /**\n     * Detect a collision with another piece on the field.\n     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).\n     *\n     * @param otherPiece\n     * @return\n     */\n    boolean isTouching(GamePiece otherPiece);\n}\n"
  },
  {
    "path": "ch11/game/GameUtilities.java",
    "content": "package ch11.game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection\n\nimport java.awt.*;\n\n/**\n * Utility class with a few helper methods for calculating various collisions and\n * intersections.\n */\npublic class GameUtilities {\n    static boolean isPointInsideBox(int x, int y, Rectangle box) {\n        // Our own custom test. We could of course use box.contains(),\n        // but we can practice some interesting conditional checking here.\n        // Let's test left and right first\n        if (x >= box.x && x <= (box.x + box.width)) {\n            // Our x coordinate is ok, so check our y\n            if (y >= box.y && y <= (box.y + box.height)) {\n                return true;\n            }\n        }\n        // x or y was outside the box, so return false\n        return false;\n    }\n\n    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {\n        // If any of the four corners of box are inside other, we intersect, so\n        // let's check each one. Happily, that answer doesn't change if more\n        // than one corner is contained in other, so we can return as soon as\n        // we find the first contained corner.\n\n        // Let's get some local copies of the corner coordinates\n        // to make the call arguments easier to read.\n        int x1 = box.x;\n        int y1 = box.y;\n        int x2 = x1 + box.width;\n        int y2 = y1 + box.height;\n        if (isPointInsideBox(x1, y1, other)) {\n            // upper left\n            return true;\n        } else if (isPointInsideBox(x1, y2, other)) {\n            // lower left\n            return true;\n        } else if (isPointInsideBox(x2, y1, other)) {\n            // upper right\n            return true;\n        } else if (isPointInsideBox(x2, y2, other)) {\n            // lower right\n            return true;\n        }\n        // No box points in other so no intersection\n        return false;\n    }\n\n    /**\n     * Given two rectangles, do the overlap at all? This includes one box being\n     * completely contained by the other box.\n     *\n     * @param box1 a box to test, order does not matter\n     * @param box2 the other box\n     * @return true if the boxes overlap, false otherwise\n     */\n    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {\n        // Another custom test. We could of course use box1.intersects(box2)\n        // but we can practice method calls and some boolean logic here.\n        if (doesBoxIntersect(box1, box2)) {\n            // At least one of box1's points must be inside box2\n            return true;\n        } else if (doesBoxIntersect(box2, box1)) {\n            // None of box1's points were in box2, but at least one of box2's points are inside box1\n            return true;\n        }\n        // No intersections in either direction\n        return false;\n    }\n}\n"
  },
  {
    "path": "ch11/game/Physicist.java",
    "content": "package ch11.game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport static java.awt.Color.*;\n\n/**\n * Our player class. A physicist has an apple that they can throw in addition\n * to implementing the basic methods for GamePiece. We can also set a custom\n * color in case you build on the game and allow multiple physicists to be\n * on the screen at the same time.\n */\npublic class Physicist implements GamePiece, ActionListener {\n    Color color;\n    int centerX, centerY;\n    Apple aimingApple;\n    float aimingAngle;\n    float aimingForce;\n    Field field;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n\n    // Boundary helpers\n    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);\n    private Rectangle boundingBox;\n\n\n    /**\n     * Create a default, blue physicist\n     */\n    public Physicist() {\n        this(BLUE);\n    }\n\n    /**\n     * Create a Physicist of the given color\n     */\n    public Physicist(Color color) {\n        setColor(color);\n        aimingAngle = 90.0f;\n        aimingForce = 50.0f;\n        getNewApple();\n    }\n\n    public void setAimingAngle(Float angle) {\n        aimingAngle = angle;\n    }\n\n    public void setAimingForce(Float force) {\n        if (force < 0) {\n            force = 0.0f;\n        }\n        aimingForce = force;\n    }\n\n    /**\n     * Sets the color for the physicist.\n     *\n     * @param color\n     */\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of our dome,\n        // but it will be drawn from the upper left corner.\n        // Figure out the distance of that gap\n        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    /**\n     * Sets the active field once our physicist is being displayed.\n     *\n     * @param field Active game field\n     */\n    public void setField(Field field) {\n        this.field = field;\n    }\n\n    /**\n     * Take the current apple away from the physicist. Returns the apple for\n     * use in animating on the field. Note that if there is no current apple being\n     * aimed, null is returned.\n     *\n     * @return the current apple (if any) being aimed\n     */\n    public Apple takeApple() {\n        Apple myApple = aimingApple;\n        aimingApple = null;\n        return myApple;\n    }\n\n    /**\n     * Get a new apple ready if we need one. Do not discard an existing apple.\n     */\n    public void getNewApple() {\n        // Don't drop the current apple if we already have one!\n        if (aimingApple == null) {\n            aimingApple = new Apple(this);\n        }\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our physicist is the right color, then draw the semi-circle and box\n        g.setColor(color);\n        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);\n        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);\n\n        // Do we have an apple to draw as well?\n        if (aimingApple != null) {\n            // Yes. Position the center of the apple on the edge of our semi-circle.\n            // Use the current aimingAngle to determine where on the edge.\n            double angleInRadians = Math.toRadians(aimingAngle);\n            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;\n            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);\n            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);\n            aimingApple.setPosition(aimingX, aimingY);\n            aimingApple.draw(g);\n        }\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        if (e.getActionCommand().equals(\"New Apple\")) {\n            getNewApple();\n            if (field != null) {\n                field.repaint();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ch11/game/Tree.java",
    "content": "package ch11.game;\n\nimport java.awt.*;\n\n/**\n * An obstacle for our game. Trees includ a simple circle and rectangle shape.\n * They are built using sizes determined by the constants in the Field class.\n */\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    private Color leafColor = Color.GREEN.darker();\n    private Color trunkColor = new Color(101, 67, 33);\n    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);\n    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);\n    private int trunkX, trunkY;\n\n    // Boundary helpers\n    private Rectangle boundingBox;\n\n    @Override\n    public void setPosition(int x, int y) {\n        this.x = x;\n        this.y = y;\n        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;\n        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;\n        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);\n    }\n\n    @Override\n    public int getPositionX() {\n        return x;\n    }\n\n    @Override\n    public int getPositionY() {\n        return y;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        g.setColor(trunkColor);\n        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);\n        g.setColor(leafColor);\n        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  },
  {
    "path": "ch12/Post.java",
    "content": "package ch12;\n\nimport java.net.*;\nimport java.io.*;\nimport java.awt.*;\nimport java.awt.event.*;\nimport javax.swing.*;\n\n/**\n * A small graphical application that demonstrates use of the\n * HTTP POST mechanism. Provide a POST-able URL to the command line\n * and use the \"Post\" button to send sample name and password\n * data to the URL.\n * \n * See the servlet section of this chapter for the ShowParameters\n * example that can serve (ha!) as the receiving (server) side.\n */\npublic class Post extends JPanel implements ActionListener {\n  JTextField nameField;\n  JPasswordField passwordField;\n  String postURL;\n\n  GridBagConstraints constraints = new GridBagConstraints(  );\n  \n  void addGB( Component component, int x, int y ) {\n    constraints.gridx = x;  constraints.gridy = y;\n    add ( component, constraints );\n  }\n\n  public Post( String postURL ) {\n\t  \n    this.postURL = postURL;  \n\t  \n    setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 5));\n    JButton postButton = new JButton(\"Post\");\n    postButton.addActionListener( this );\n    setLayout( new GridBagLayout(  ) );\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    addGB( new JLabel(\"Name \", JLabel.TRAILING), 0, 0 );\n    addGB( nameField = new JTextField(20), 1, 0 );\n    addGB( new JLabel(\"Password \", JLabel.TRAILING), 0, 1 );\n    addGB( passwordField = new JPasswordField(20), 1, 1 );\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.gridwidth = 2;\n    constraints.anchor = GridBagConstraints.EAST;\n    addGB( postButton, 1, 2 );\n  }\n\n  public void actionPerformed(ActionEvent e) {\n    postData(  );\n  }\n\n  protected void postData(  ) {\n    StringBuilder sb = new StringBuilder();\n    String pw = new String(passwordField.getPassword());\n    try {\n      sb.append( URLEncoder.encode(\"Name\", \"UTF-8\") + \"=\" );\n      sb.append( URLEncoder.encode(nameField.getText(), \"UTF-8\") );\n      sb.append( \"&\" + URLEncoder.encode(\"Password\", \"UTF-8\") + \"=\" );\n      sb.append( URLEncoder.encode(pw, \"UTF-8\") );\n    } catch (UnsupportedEncodingException uee) {\n      System.out.println(uee);\n    }\n    String formData = sb.toString(  );\n\n    try {\n      URL url = new URL( postURL );\n      HttpURLConnection urlcon =\n          (HttpURLConnection) url.openConnection(  );\n      urlcon.setRequestMethod(\"POST\");\n      urlcon.setRequestProperty(\"Content-type\",\n          \"application/x-www-form-urlencoded\");\n      urlcon.setDoOutput(true);\n      urlcon.setDoInput(true);\n      PrintWriter pout = new PrintWriter( new OutputStreamWriter(\n          urlcon.getOutputStream(  ), \"8859_1\"), true );\n      pout.print( formData );\n      pout.flush(  );\n\n      // Did the post succeed?\n      if ( urlcon.getResponseCode() == HttpURLConnection.HTTP_OK )\n        System.out.println(\"Posted ok!\");\n      else {\n        System.out.println(\"Bad post...\");\n        return;\n      }\n      // Hooray! Go ahead and read the results...\n      //InputStream in = urlcon.getInputStream(  );\n      // ...\n\n    } catch (MalformedURLException e) {\n      System.out.println(e);     // bad postURL\n    } catch (IOException e2) {\n      System.out.println(e2);    // I/O error\n    }\n  }\n\n  public static void main( String [] args ) {\n    if (args.length != 1) {\n      System.err.println(\"Must specify URL on command line. Exiting.\");\n      System.exit(1);\n    }\n    JFrame frame = new JFrame(\"SimplePost\");\n    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n    frame.add( new Post(args[0]), \"Center\" );\n    frame.pack();\n    frame.setVisible(true);\n  }\n}\n"
  },
  {
    "path": "ch12/Read.java",
    "content": "package ch12;\n\nimport java.io.*;\nimport java.net.*;\n\n/**\n * A simple command line demonstration of reading from a URL.\n * The URL to read must be passed as the only argument on the command line.\n */\npublic class Read {\n  public static void main(String args[]) {\n    // Did we get an argument to use as the URL?\n    if (args.length != 1) {\n      System.err.println(\"Must specify URL on command line. Exiting.\");\n      System.exit(1);\n    }\n    // Great! Let's try to read it and dump the contents to the terminal.\n    try {\n      URL url = new URL(args[0]);\n\n      BufferedReader bin = new BufferedReader (\n          new InputStreamReader( url.openStream() ));\n      String line;\n      while ( (line = bin.readLine()) != null ) {\n        System.out.println( line );\n      }\n      bin.close();\n    } catch (Exception e) { \n      System.err.println(\"Error occurred while reading:\" + e);\n    }\n  }\n}\n"
  },
  {
    "path": "ch13/ActionDemoLambda.java",
    "content": "package ch13;\n\nimport javax.swing.*;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\n/**\n * An update to the ch10.ActionDemo2 class with a lambda expression\n * to help handle action events.\n */\npublic class ActionDemoLambda {\n    public static void main( String[] args ) {\n        JFrame frame = new JFrame( \"ActionListener & Lambdas Demo\" );\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setLayout(new FlowLayout());\n        frame.setSize( 300, 180 );\n\n        JLabel label = new JLabel(\"Results go here\", JLabel.CENTER );\n\n        // We can replace our separate helper class with a simple lambda expression\n        ActionListener helper = ae -> label.setText(ae.getActionCommand());\n\n        JButton simpleButton = new JButton(\"Button\");\n        simpleButton.addActionListener(helper);\n\n        JTextField simpleField = new JTextField(10);\n        simpleField.addActionListener(helper);\n\n        frame.add(simpleButton);\n        frame.add(simpleField);\n        frame.add(label);\n\n        frame.setVisible( true );\n    }\n}\n"
  },
  {
    "path": "ch13/ListItLambda.java",
    "content": "package ch13;\n\nimport java.io.*;\nimport java.util.Arrays;\n\n/**\n * An update to ListIt from ch11 with a lambda expression example\n * when listing the contents of a directory.\n */\npublic class ListItLambda {\n    public static void main ( String args[] ) throws Exception {\n        File file =  new File( args[0] );\n\n        if ( !file.exists() || !file.canRead(  ) ) {\n            System.out.println( \"Can't read \" + file );\n            return;\n        }\n\n        if ( file.isDirectory(  ) ) {\n            // We can condense the previous explicit loop to a forEach + lambda\n            Arrays.asList(file.list()).forEach(f -> System.out.println(f));\n        }\n        else\n            try {\n                Reader ir = new InputStreamReader( new FileInputStream( file ) );\n                BufferedReader in = new BufferedReader( ir );\n                String line;\n                while ((line = in.readLine(  )) != null)\n                    System.out.println(line);\n            }\n            catch ( FileNotFoundException e ) {\n                System.out.println( \"File Disappeared\" );\n            }\n    }\n}"
  },
  {
    "path": "game/Apple.java",
    "content": "/**\n * Apple\n *\n * This class sums up everything we know about the apples our physicists will be lobbing.\n * We keep the size and weight details and provide a few simple methods for lobbing. We\n * also provide animation helpers for use with the PlayingField class.\n */\npackage game;\n\nimport java.awt.*;\n\npublic class Apple implements GamePiece {\n    public static final int SMALL  = 0;\n    public static final int MEDIUM = 1;\n    public static final int LARGE  = 2;\n\n    int size;\n    double diameter;\n    double mass;\n    int centerX, centerY;\n    Physicist myPhysicist;\n\n    // In game play, apples can be thrown so track their velocities\n    long lastStep;\n    float velocityX, velocityY;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n    int scaledLength;\n\n    // Boundary helper for optimizing collision detection with physicists and trees\n    Rectangle boundingBox;\n\n    // If we bumped into something, keep a reference to that thing around for cleanup and removal\n    GamePiece collided;\n\n    /**\n     * Create a default, Medium apple\n     */\n    public Apple(Physicist owner) {\n        this(owner, MEDIUM);\n    }\n\n    /**\n     * Create an Apple of the given size\n     */\n    public Apple(Physicist owner, int size) {\n        myPhysicist = owner;\n        setSize(size);\n    }\n\n    /**\n     * Sets the size (and dependent properties) of the apple based on the\n     * supplied value which must be one of the size constants.\n     *\n     * @param size one of SMALL, MEDIUM, or LARGE, other values are bounded to SMALL or LARGE\n     */\n    public void setSize(int size) {\n        if (size < SMALL) {\n            size = SMALL;\n        }\n        if (size > LARGE) {\n            size = LARGE;\n        }\n        this.size = size;\n        switch (size) {\n            case SMALL:\n                diameter = 0.9;\n                mass = 0.5;\n                break;\n            case MEDIUM:\n                diameter = 1.0;\n                mass = 1.0;\n                break;\n            case LARGE:\n                diameter = 1.1;\n                mass = 1.8;\n                break;\n        }\n        // fillOval() used below draws an oval bounded by a box, so figure out the length of the sides.\n        // Since we want a circle, we simply make our box a square so we only need one length.\n        scaledLength = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS + 0.5);\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    public double getDiameter() {\n        return diameter;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of the apple, but it will be drawn from the\n        // upper left corner, so figure out the distance of that gap\n        int offset = (int)(diameter * Field.APPLE_SIZE_IN_PIXELS / 2);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our apple will be red, then paint it!\n        g.setColor(Color.RED);\n        g.fillOval(x, y, scaledLength, scaledLength);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece || myPhysicist == otherPiece || collided != null) {\n            // By definition we don't collide with ourselves, our physicist, or with more than one other piece\n            return false;\n        }\n        if (otherPiece instanceof Apple) {\n            // The other piece is an apple, so we can do a simple distance calculation using\n            // the diameters of both apples.\n            Apple otherApple = (Apple) otherPiece;\n            int v = this.y - otherPiece.getPositionY(); // vertical difference\n            int h = this.x - otherPiece.getPositionX(); // horizontal difference\n            double distance = Math.sqrt(v * v + h * h);\n\n            double myRadius = diameter * Field.APPLE_SIZE_IN_PIXELS / 2;\n            double otherRadius = otherApple.getDiameter() * Field.APPLE_SIZE_IN_PIXELS / 2;\n            if (distance < (myRadius + otherRadius)) {\n                // Since apples track collisions, we'll update the other apple to keep everyone in sync\n                setCollided(otherPiece);\n                otherApple.setCollided(this);\n                return true;\n            }\n            return false;\n        }\n        if (GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox())) {\n            setCollided(otherPiece);\n            return true;\n        }\n        return false;\n    }\n\n    public GamePiece getCollidedPiece() {\n        return collided;\n    }\n\n    public void setCollided(GamePiece otherPiece) {\n        this.collided = otherPiece;\n    }\n\n    public void toss(float angle, float velocity) {\n        lastStep = System.currentTimeMillis();\n        double radians = angle / 180 * Math.PI;\n        velocityX = (float)(velocity * Math.cos(radians) / mass);\n        // Start with negative velocity since \"up\" means smaller values of y\n        velocityY = (float)(-velocity * Math.sin(radians) / mass);\n    }\n\n    public void step() {\n        // Make sure we're moving at all using our lastStep tracker as a sentinel\n        if (lastStep > 0) {\n            // let's apply our gravity\n            long now = System.currentTimeMillis();\n            float slice = (now - lastStep) / 1000.0f;\n            velocityY = velocityY + (slice * Field.GRAVITY);\n            int newX = (int)(centerX + velocityX);\n            int newY = (int)(centerY + velocityY);\n            setPosition(newX, newY);\n        }\n    }\n}\n"
  },
  {
    "path": "game/AppleToss.java",
    "content": "package game;\n\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ArrayList;\nimport java.util.Random;\n\npublic class AppleToss extends JFrame {\n    public static final int SCORE_HEIGHT = 30;\n    public static final int CONTROL_WIDTH = 300;\n    public static final int CONTROL_HEIGHT = 40;\n    public static final int FIELD_WIDTH = 3 * CONTROL_WIDTH;\n    public static final int FIELD_HEIGHT = 2 * CONTROL_WIDTH;\n    public static final float FORCE_SCALE = 0.7f;\n\n    GridBagLayout gameLayout = new GridBagLayout();\n    GridBagConstraints gameConstraints = new GridBagConstraints();\n    JPanel gamePane = new JPanel(gameLayout);\n\n    Field field = new Field();\n    Physicist player1 = new Physicist();\n    Multiplayer multiplayerHelper;\n\n    public AppleToss() {\n        // Create our frame\n        super(\"Apple Toss Game\");\n        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        setResizable(false);\n\n        // Build the field with our player and some trees\n        setupFieldForOnePlayer();\n\n        // Setup the grid we'll use to layout our various components\n        gameLayout.columnWidths = new int[] { CONTROL_WIDTH, CONTROL_WIDTH, CONTROL_WIDTH };\n        gameLayout.rowHeights = new int[] { SCORE_HEIGHT, FIELD_HEIGHT, CONTROL_HEIGHT, CONTROL_HEIGHT };\n\n        // Now build and add those components at the desired position\n        JLabel player1score = new JLabel(\" Player 1: 0\");\n        field.scoreLabels[1] = player1score;\n        JLabel player2score = new JLabel(\" Player 2\");\n        field.scoreLabels[2] = player2score;\n        gamePane.add(player1score, buildConstraints(0, 0, 1, 1));\n        gamePane.add(player2score, buildConstraints(0, 1, 1, 1));\n        gamePane.add(buildRestartButton(), buildConstraints(0, 2, 1, 1));\n        gamePane.add(field, buildConstraints(1, 0, 1, 3));\n        gamePane.add(buildAngleControl(), buildConstraints(2, 0, 1, 1));\n        gamePane.add(buildForceControl(), buildConstraints(2, 1, 1, 1));\n        gamePane.add(buildTossButton(), buildConstraints(2, 2, 2, 1));\n        gamePane.add(new JLabel(\"Angle\", JLabel.CENTER), buildConstraints(3, 0, 1, 1));\n        gamePane.add(new JLabel(\"Force\", JLabel.CENTER), buildConstraints(3, 1, 1, 1));\n\n        // replace the frame's content with our game and set the pane's size\n        gamePane.setPreferredSize(new Dimension(FIELD_WIDTH,SCORE_HEIGHT + FIELD_HEIGHT + (2 * CONTROL_HEIGHT)));\n        setContentPane(gamePane);\n\n        // Setup our networking menu\n        setupNetworkMenu();\n\n        // And set the correct size of the frame itself\n        pack();\n    }\n\n    private GridBagConstraints buildConstraints(int row, int col, int rowspan, int colspan) {\n        gameConstraints.fill = GridBagConstraints.BOTH;\n        gameConstraints.gridy = row;\n        gameConstraints.gridx = col;\n        gameConstraints.gridheight = rowspan;\n        gameConstraints.gridwidth = colspan;\n        return gameConstraints;\n    }\n\n    private JButton buildRestartButton() {\n        JButton button = new JButton(\"Play Again\");\n        button.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                setupFieldForOnePlayer();\n                field.repaint();\n            }\n        });\n        return button;\n    }\n\n    private JSlider buildAngleControl() {\n        JSlider slider = new JSlider(0,180);\n        slider.setInverted(true);\n        slider.addChangeListener(new ChangeListener() {\n            @Override\n            public void stateChanged(ChangeEvent e) {\n                player1.setAimingAngle((float)slider.getValue());\n                field.repaint();\n            }\n        });\n        return slider;\n    }\n\n    private JSlider buildForceControl() {\n        JSlider slider = new JSlider();\n        slider.addChangeListener(new ChangeListener() {\n            @Override\n            public void stateChanged(ChangeEvent e) {\n                player1.setAimingForce(slider.getValue() * FORCE_SCALE);\n            }\n        });\n        return slider;\n    }\n\n    private JButton buildTossButton() {\n        JButton button = new JButton(\"Toss\");\n        button.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                field.startTossFromPlayer(player1);\n            }\n        });\n        return button;\n    }\n\n    /**\n     * A helper method to populate a one player field with target trees.\n     */\n    private void setupFieldForOnePlayer() {\n        // place our (new) physicist in the lower left corner and connect them to the field\n        player1.setPosition(Field.PHYSICIST_SIZE_IN_PIXELS, FIELD_HEIGHT - (int) (Field.PHYSICIST_SIZE_IN_PIXELS * 1.5));\n        field.setPlayer(player1);\n        player1.setField(field);\n        field.setupNewGame();\n    }\n\n    private void setupNetworkMenu() {\n        JMenu netMenu = new JMenu(\"Multiplayer\");\n        multiplayerHelper = new Multiplayer(field);\n\n        JMenuItem startItem = new JMenuItem(\"Start Server\");\n        startItem.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                multiplayerHelper.startServer();\n            }\n        });\n        netMenu.add(startItem);\n\n        JMenuItem joinItem = new JMenuItem(\"Join Game...\");\n        joinItem.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                String otherServer = JOptionPane.showInputDialog(AppleToss.this, \"Enter server name or address:\");\n                multiplayerHelper.joinGame(otherServer);\n            }\n        });\n        netMenu.add(joinItem);\n\n        JMenuItem quitItem = new JMenuItem(\"Disconnect\");\n        quitItem.addActionListener(new ActionListener() {\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                multiplayerHelper.disconnect();\n            }\n        });\n        netMenu.add(quitItem);\n\n        // build a JMenuBar for the application\n        JMenuBar mainBar = new JMenuBar();\n        mainBar.add(netMenu);\n        setJMenuBar(mainBar);\n    }\n\n    public static void main(String args[]) {\n        AppleToss game = new AppleToss();\n        game.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "game/Field.java",
    "content": "package game;\n\nimport javax.swing.*;\nimport javax.swing.Timer;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.util.*;\nimport java.util.List;\n\npublic class Field extends JComponent implements ActionListener {\n    public static final float GRAVITY = 9.8f;  // feet per second per second\n    public static final int STEP = 40;   // duration of an animation frame in milliseconds\n    public static final int APPLE_SIZE_IN_PIXELS = 30;\n    public static final int TREE_WIDTH_IN_PIXELS = 60;\n    public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;\n    public static final int PHYSICIST_SIZE_IN_PIXELS = 75;\n    public static final int MAX_TREES = 12;\n\n    Color fieldColor = Color.GRAY;\n    Random random = new Random();\n\n    // ArrayList covered in Generics chapter\n    // synchronizedArrayList covered in Threads chapter\n    Physicist physicist;\n    int myScore = 0;\n    String[] scores = new String[3];\n    JLabel[] scoreLabels = new JLabel[3];\n    List<Apple> apples = Collections.synchronizedList(new ArrayList<>());\n    List<Tree> trees = Collections.synchronizedList(new ArrayList<>());\n\n    boolean animating = false;\n    Thread animationThread;\n    Timer animationTimer;\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(fieldColor);\n        g.fillRect(0,0, getWidth(), getHeight());\n        physicist.draw(g);\n        for (Tree t : trees) {\n            t.draw(g);\n        }\n        for (Apple a : apples) {\n            a.draw(g);\n        }\n    }\n\n    public void setPlayer(Physicist p) {\n        physicist = p;\n    }\n\n    public void actionPerformed(ActionEvent event) {\n        if (animating && event.getActionCommand().equals(\"repaint\")) {\n            for (Apple a : apples) {\n                a.step();\n                detectCollisions(a);\n            }\n            repaint();\n            cullFallenApples();\n        }\n    }\n\n    /**\n     * Toss an apple from the given physicist using that physicist's aim and force.\n     * Make sure the field is in the animating state.\n     *\n     * @param physicist the player whose apple should be tossed\n     */\n    public void startTossFromPlayer(Physicist physicist) {\n        if (!animating) {\n            System.out.println(\"Starting animation!\");\n            animating = true;\n            startAnimation();\n        }\n        if (animating) {\n            // Check to make sure we have an apple to toss\n            if (physicist.aimingApple != null) {\n                Apple apple = physicist.takeApple();\n                apple.toss(physicist.aimingAngle, physicist.aimingForce);\n                apples.add(apple);\n                Timer appleLoader = new Timer(800, physicist);\n                appleLoader.setActionCommand(\"New Apple\");\n                appleLoader.setRepeats(false);\n                appleLoader.start();\n            }\n        }\n    }\n\n    void cullFallenApples() {\n        Iterator<Apple> iterator = apples.iterator();\n        while (iterator.hasNext()) {\n            Apple a = iterator.next();\n            if (a.getCollidedPiece() != null) {\n                GamePiece otherPiece = a.getCollidedPiece();\n                if (otherPiece instanceof Physicist) {\n                    hitPhysicist((Physicist) otherPiece);\n                } else if (otherPiece instanceof Tree) {\n                    hitTree((Tree) otherPiece);\n                }\n                // Remove ourselves. If the other piece we hit was an apple, leave it alone.\n                // It will be removed when the iterator comes to it.\n                iterator.remove();\n            } else if (a.getPositionY() > 600) {\n                System.out.println(\"Culling apple\");\n                iterator.remove();\n            }\n        }\n        if (apples.size() <= 0) {\n            animating = false;\n            if (animationTimer != null && animationTimer.isRunning()) {\n                animationTimer.stop();\n            }\n        }\n    }\n\n    void detectCollisions(Apple apple) {\n        // Check for other apples\n        for (Apple a : apples) {\n            if (apple.isTouching(a)) {\n                System.out.println(\"Touching another apple!\");\n                return;\n            }\n        }\n        // Check our physicist\n        if (apple.isTouching(physicist)) {\n            System.out.println(\"Touching a physicist!\");\n            return;\n        }\n\n        // Check for trees\n        for (Tree t : trees) {\n            if (apple.isTouching(t)) {\n                System.out.println(\"Touching a tree!\");\n                return;\n            }\n        }\n    }\n\n    void hitPhysicist(Physicist physicist) {\n        // do any scoring or notifications here\n    }\n\n    void hitTree(Tree tree) {\n        // do any scoring or notifications here\n        myScore += 10;\n        trees.remove(tree);\n        setScore(1, String.valueOf(myScore));\n    }\n\n    void startAnimation() {\n        // Animator myAnimator = new Animator();\n        // animationThread = new Thread(myAnimator);\n        // animationThread.start();\n        if (animationTimer == null) {\n            animationTimer = new Timer(STEP, this);\n            animationTimer.setActionCommand(\"repaint\");\n            animationTimer.setRepeats(true);\n            animationTimer.start();\n        } else if (!animationTimer.isRunning()) {\n            animationTimer.restart();\n        }\n    }\n\n    public String getScore(int playerNumber) {\n        return scores[playerNumber];\n    }\n\n    public void setScore(int playerNumber, String score) {\n        scores[playerNumber] = score;\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                String newScore = \" Player \" + playerNumber + \": \" + score;\n                scoreLabels[playerNumber].setText(newScore);\n            }\n        });\n    }\n\n    public String getWinner() {\n        int score2 = -1;\n        try {\n            score2 = Integer.parseInt(scores[2]);\n        } catch (NumberFormatException nfe) {\n            System.err.println(\"Couldn't parse the other player's score: \" + scores[2]);\n        }\n        if (myScore == score2) {\n            return \"It's a tie!\";\n        } else if (myScore > score2) {\n            return \"You won!\";\n        } else {\n            return \"They won.\";\n        }\n    }\n\n    /**\n     * Helper method to return a good x value for a tree so it's not off the left or right edge.\n     *\n     * @return x value within the bounds of the playing field width\n     */\n    private int goodX() {\n        // at least half the width of the tree plus a few pixels\n        int leftMargin = TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // now find a random number between a left and right margin\n        int rightMargin = AppleToss.FIELD_WIDTH - leftMargin;\n\n        // And return a random number starting at the left margin\n        return leftMargin + random.nextInt(rightMargin - leftMargin);\n    }\n\n    /**\n     * Helper method to return a good y value for a tree so it's not off the top or bottom of the screen.\n     *\n     * @return y value within the bounds of the playing field height\n     */\n    private int goodY() {\n        // at least half the height of the \"leaves\" plus a few pixels\n        int topMargin = TREE_WIDTH_IN_PIXELS / 2 + 5;\n        // a little higher off the bottom\n        int bottomMargin = AppleToss.FIELD_HEIGHT - TREE_HEIGHT_IN_PIXELS;\n\n        // And return a random number starting at the top margin but not past the bottom\n        return topMargin + random.nextInt(bottomMargin - topMargin);\n    }\n\n    public void setupNewGame() {\n        // Clear out any old trees\n        trees.clear();\n\n        // Now create some trees for target practice\n        for (int i = trees.size(); i < Field.MAX_TREES; i++) {\n            Tree t = new Tree();\n            t.setPosition(goodX(), goodY());\n            // Trees can be close to each other and overlap, but they shouldn't intersect our physicist\n            while(physicist.isTouching(t)) {\n                // We do intersect this tree, so let's try again\n                t.setPosition(goodX(), goodY());\n                System.err.println(\"Repositioning an intersecting tree...\");\n            }\n            trees.add(t);\n        }\n        repaint();\n    }\n\n    class Animator implements Runnable {\n        public void run() {\n            while (animating) {\n                System.out.println(\"Stepping \" + apples.size() + \" apples\");\n                for (Apple a : apples) {\n                    a.step();\n                    detectCollisions(a);\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Field.this.repaint();\n                    }\n                });\n                cullFallenApples();\n                try {\n                    Thread.sleep((int)(STEP * 1000));\n                } catch (InterruptedException ie) {\n                    System.err.println(\"Animation interrupted\");\n                    animating = false;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "game/GamePiece.java",
    "content": "package game;\n\nimport java.awt.*;\n\n/**\n * Interface to hold common elements for our apples, trees, and physicists\n * From the README:\n * GamePiece\n *   - methods for positioning on a PlayingField\n *   - methods for Drawing\n *   - methods for detecting a collision with other GamePieces\n */\n\npublic interface GamePiece {\n    /**\n     * Sets the position of the piece on the playing field.\n     * (0,0) is the upper left per standard Java drawing methods.\n     *\n     * @param x\n     * @param y\n     */\n    void setPosition(int x, int y);\n\n    /**\n     * Gets the current horizontal position of the piece on the field.\n     *\n     * @return current X position of the piece\n     */\n    int getPositionX();\n\n    /**\n     * Gets the current vertical position of the piece on the field.\n     *\n     * @return current Y position of the piece\n     */\n    int getPositionY();\n\n    /**\n     * Gets the bounding box of this piece.\n     *\n     * @return a Rectangle encompassing the visual elements of the piece\n     */\n    Rectangle getBoundingBox();\n\n    /**\n     * Draws the piece inside the given graphics context.\n     * Do not assume anything about the state of the context.\n     *\n     * @param g\n     */\n    void draw(Graphics g);\n\n    /**\n     * Detect a collision with another piece on the field.\n     * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).\n     *\n     * @param otherPiece\n     * @return\n     */\n    boolean isTouching(GamePiece otherPiece);\n}\n"
  },
  {
    "path": "game/GameUtilities.java",
    "content": "package game;\n\n// collision detection between a circle and a rectangle\n// https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection\n\nimport java.awt.*;\n\n/**\n * Utility class with a few helper methods for calculating various collisions and\n * intersections.\n */\npublic class GameUtilities {\n    static boolean isPointInsideBox(int x, int y, Rectangle box) {\n        // Our own custom test. We could of course use box.contains(),\n        // but we can practice some interesting conditional checking here.\n        // Let's test left and right first\n        if (x >= box.x && x <= (box.x + box.width)) {\n            // Our x coordinate is ok, so check our y\n            if (y >= box.y && y <= (box.y + box.height)) {\n                return true;\n            }\n        }\n        // x or y was outside the box, so return false\n        return false;\n    }\n\n    static boolean doesBoxIntersect(Rectangle box, Rectangle other) {\n        // If any of the four corners of box are inside other, we intersect, so\n        // let's check each one. Happily, that answer doesn't change if more\n        // than one corner is contained in other, so we can return as soon as\n        // we find the first contained corner.\n\n        // Let's get some local copies of the corner coordinates\n        // to make the call arguments easier to read.\n        int x1 = box.x;\n        int y1 = box.y;\n        int x2 = x1 + box.width;\n        int y2 = y1 + box.height;\n        if (isPointInsideBox(x1, y1, other)) {\n            // upper left\n            return true;\n        } else if (isPointInsideBox(x1, y2, other)) {\n            // lower left\n            return true;\n        } else if (isPointInsideBox(x2, y1, other)) {\n            // upper right\n            return true;\n        } else if (isPointInsideBox(x2, y2, other)) {\n            // lower right\n            return true;\n        }\n        // No box points in other so no intersection\n        return false;\n    }\n\n    /**\n     * Given two rectangles, do the overlap at all? This includes one box being\n     * completely contained by the other box.\n     *\n     * @param box1 a box to test, order does not matter\n     * @param box2 the other box\n     * @return true if the boxes overlap, false otherwise\n     */\n    public static boolean doBoxesIntersect(Rectangle box1, Rectangle box2) {\n        // Another custom test. We could of course use box1.intersects(box2)\n        // but we can practice method calls and some boolean logic here.\n        if (doesBoxIntersect(box1, box2)) {\n            // At least one of box1's points must be inside box2\n            return true;\n        } else if (doesBoxIntersect(box2, box1)) {\n            // None of box1's points were in box2, but at least one of box2's points are inside box1\n            return true;\n        }\n        // No intersections in either direction\n        return false;\n    }\n}\n"
  },
  {
    "path": "game/Multiplayer.java",
    "content": "package game;\n\nimport javax.swing.*;\nimport java.io.*;\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java.net.SocketException;\n\npublic class Multiplayer {\n    private Field gameField;\n    private int gamePort;\n    private volatile boolean keepListening;\n    private volatile boolean keepPlaying;\n    private volatile boolean startNewGame;\n    private volatile boolean disconnecting;\n    private Server server;\n    private Thread serverThread;\n    private Thread clientThread;\n\n    public Multiplayer(Field field) {\n        this(field,8677);\n    }\n\n    public Multiplayer(Field field, int port) {\n        gameField = field;\n        gamePort = port;\n    }\n\n    public void startServer() {\n        keepListening = true;\n        keepPlaying = false;\n        startNewGame = true;\n        disconnecting = false;\n        server = new Server();\n        serverThread = new Thread(server);\n        serverThread.start();\n        gameField.setScore(2, \"waiting...\");\n    }\n\n    public void joinGame(String otherServer) {\n        clientThread = new Thread(new Client(otherServer));\n        clientThread.start();\n    }\n\n    public void startGame() {\n        startNewGame = true;\n    }\n\n    public void disconnect() {\n        disconnecting = true;\n        keepListening = false;\n        // Are we in the middle of a game and regularly checking these flags?\n        // If not, just close the server socket to interrupt the blocking accept() method.\n        if (server != null && keepPlaying == false) {\n            server.stopListening();\n        }\n        keepPlaying = false;\n    }\n\n    class Server implements Runnable {\n        ServerSocket listener;\n\n        public void run() {\n            Socket socket = null;\n            try {\n                listener = new ServerSocket(gamePort);\n                while (keepListening) {\n                    socket = listener.accept();  // wait for connection\n\n                    InputStream in = socket.getInputStream();\n                    BufferedReader reader = new BufferedReader( new InputStreamReader(in) );\n                    OutputStream out = socket.getOutputStream();\n                    PrintWriter writer = new PrintWriter(out, true);\n\n                    while (startNewGame) {\n                        // Create a new game, but assume this will be the last\n                        writer.println(\"NEW_GAME\");\n                        startNewGame = false;\n\n                        // If the client agrees, Send over the location of the trees\n                        String response = reader.readLine();\n                        if (response != null && response.equals(\"OK\")) {\n                            gameField.setupNewGame();\n                            for (Tree tree : gameField.trees) {\n                                writer.println(\"TREE \" + tree.getPositionX() + \" \" + tree.getPositionY());\n                            }\n                        } else {\n                            System.err.println(\"Unexpected start response: \" + response);\n                            System.err.println(\"Skipping game and waiting again.\");\n                            keepPlaying = false;\n                            break;\n                        }\n\n                        // Start the action!\n                        writer.println(\"START\");\n                        response = reader.readLine();\n                        keepPlaying = response.equals(\"OK\");\n\n                        while (keepPlaying) {\n                            try {\n                                if (gameField.trees.size() > 0) {\n                                    writer.print(\"SCORE \");\n                                } else {\n                                    writer.print(\"END \");\n                                    keepPlaying = false;\n                                }\n                                writer.println(gameField.getScore(1));\n                                response = reader.readLine();\n                                if (response == null) {\n                                    keepPlaying = false;\n                                    disconnecting = true;\n                                } else {\n                                    String parts[] = response.split(\" \");\n                                    switch (parts[0]) {\n                                        case \"END\":\n                                            keepPlaying = false;\n                                        case \"SCORE\":\n                                            gameField.setScore(2, parts[1]);\n                                            break;\n                                        case \"DISCONNECT\":\n                                            disconnecting = true;\n                                            keepPlaying = false;\n                                            break;\n                                        default:\n                                            System.err.println(\"Warning. Unexpected command: \" + parts[0] + \". Ignoring.\");\n                                    }\n                                }\n                                Thread.sleep(500);\n                            } catch(InterruptedException e) {\n                                System.err.println(\"Interrupted while polling. Ignoring.\");\n                            }\n                        }\n\n                        // If we're not disconnecting, ask about playing again with the same player\n                        if (!disconnecting) {\n                            String message = gameField.getWinner() + \" Would you like to ask them to play again?\";\n                            int myPlayAgain = JOptionPane.showConfirmDialog(gameField, message, \"Play Again?\", JOptionPane.YES_NO_OPTION);\n\n                            if (myPlayAgain == JOptionPane.YES_OPTION) {\n                                // If they haven't disconnected, ask if they want to play again\n                                writer.println(\"PLAY_AGAIN\");\n                                String playAgain = reader.readLine();\n                                if (playAgain != null) {\n                                    switch (playAgain) {\n                                        case \"YES\":\n                                            startNewGame = true;\n                                            break;\n                                        case \"DISCONNECT\":\n                                            keepPlaying = false;\n                                            startNewGame = false;\n                                            disconnecting = true;\n                                            break;\n                                        default:\n                                            System.err.println(\"Warning. Unexpected response: \" + playAgain + \". Not playing again.\");\n                                    }\n                                }\n                            }\n                        }\n                    }\n\n                    if (socket.isConnected()) {\n                        // say goodbye\n                        writer.println(\"DISCONNECT\");\n                        socket.close();\n                    }\n                }\n            } catch (SocketException se) {\n                System.err.println(\"Disconnecting. Closing down server.\");\n                keepListening = false;\n            } catch (IOException ioe) {\n                System.err.println(\"Networking error. Closing down server.\");\n                ioe.printStackTrace();\n                keepListening = false;\n            } catch (Exception e) {\n                System.err.println(\"Other exception occurred. Closing down server.\");\n                e.printStackTrace();\n                keepListening = false;\n            } finally {\n                try {\n                    if (socket != null && !socket.isClosed()) {\n                        socket.close();\n                    }\n                } catch (IOException closingException) {\n                    System.err.println(\"Error closing client socket: \" + closingException.getMessage());\n                }\n            }\n        }\n\n        public void stopListening() {\n            if (listener != null && !listener.isClosed()) {\n                try {\n                    listener.close();\n                } catch (IOException ioe) {\n                    System.err.println(\"Error disconnecting listener: \" + ioe.getMessage());\n                }\n            }\n        }\n    }\n\n    class Client implements Runnable {\n        String gameHost;\n        boolean startNewGame;\n\n        public Client(String host) {\n            gameHost = host;\n            keepPlaying = false;\n            startNewGame = false;\n        }\n\n        public void run() {\n            try (Socket socket = new Socket(gameHost, gamePort)) {\n\n                InputStream in = socket.getInputStream();\n                BufferedReader reader = new BufferedReader( new InputStreamReader( in ) );\n                OutputStream out = socket.getOutputStream();\n                PrintWriter writer = new PrintWriter( out, true );\n\n                // Assume the first game will start...\n                startNewGame = true;\n                while (startNewGame) {\n                    // ... but only the first\n                    startNewGame = false;\n\n                    // We expect to see the NEW_GAME command first\n                    String response = reader.readLine();\n\n                    // If we don't see that command, bail\n                    if (response == null || !response.equals(\"NEW_GAME\")) {\n                        System.err.println(\"Unexpected initial command: \" + response);\n                        System.err.println(\"Disconnecting\");\n                        writer.println(\"DISCONNECT\");\n                        return;\n                    }\n                    // Yay! We're going to play a game. Acknowledge this command\n                    writer.println(\"OK\");\n                    // And now gather the trees and setup our field\n                    gameField.trees.clear();\n                    response = reader.readLine();\n                    while (response.startsWith(\"TREE\")) {\n                        String[] parts = response.split(\" \");\n                        int x = Integer.parseInt(parts[1]);\n                        int y = Integer.parseInt(parts[2]);\n                        Tree tree = new Tree();\n                        tree.setPosition(x, y);\n                        gameField.trees.add(tree);\n                        response = reader.readLine();\n                    }\n                    if (!response.equals(\"START\")) {\n                        // Hmm, we should have ended the list of trees with a START, but didn't. Bail out.\n                        System.err.println(\"Unexpected start to the game: \" + response);\n                        System.err.println(\"Disconnecting\");\n                        writer.println(\"DISCONNECT\");\n                        return;\n                    } else {\n                        // Yay again! We're starting a game. Acknowledge this command\n                        writer.println(\"OK\");\n                        keepPlaying = true;\n                        gameField.repaint();\n                    }\n                    while (keepPlaying) {\n                        response = reader.readLine();\n                        System.out.println(\"DEBUG: --\" + response + \"--\");\n                        String[] parts = response.split(\" \");\n                        switch (parts[0]) {\n                            case \"END\":\n                                keepPlaying = false;\n                            case \"SCORE\":\n                                gameField.setScore(2, parts[1]);\n                                break;\n                            case \"DISCONNECT\":\n                                disconnecting = true;\n                                keepPlaying = false;\n                                break;\n                            default:\n                                System.err.println(\"Unexpected game command: \" + response + \". Ignoring.\");\n                        }\n                        if (disconnecting) {\n                            // We're disconnecting or they are. Acknowledge and quit.\n                            writer.println(\"DISCONNECT\");\n                            return;\n                        } else {\n                            // If we're not disconnecting, reply with our current score\n                            if (gameField.trees.size() > 0) {\n                                writer.print(\"SCORE \");\n                            } else {\n                                keepPlaying = false;\n                                writer.print(\"END \");\n                            }\n                            writer.println(gameField.getScore(1));\n                        }\n                    }\n                    if (!disconnecting) {\n                        // Check to see if they want to play again\n                        response = reader.readLine();\n                        if (response != null && response.equals(\"PLAY_AGAIN\")) {\n                            // Do we want to play again?\n                            String message = gameField.getWinner() + \" Would you like to play again?\";\n                            int myPlayAgain = JOptionPane.showConfirmDialog(gameField, message, \"Play Again?\", JOptionPane.YES_NO_OPTION);\n                            if (myPlayAgain == JOptionPane.YES_OPTION) {\n                                writer.println(\"YES\");\n                                startNewGame = true;\n                            } else {\n                                // Not playing again so disconnect.\n                                disconnecting = true;\n                                writer.println(\"DISCONNECT\");\n                            }\n                        }\n                    }\n                }\n            }\n            catch (IOException e ) {\n                System.err.println(\"Networking error. Closing down client.\");\n                e.printStackTrace();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "game/Physicist.java",
    "content": "package game;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport static java.awt.Color.*;\n\npublic class Physicist implements GamePiece, ActionListener {\n    Color color;\n    int centerX, centerY;\n    Apple aimingApple;\n    float aimingAngle;\n    float aimingForce;\n    Field field;\n\n    // Some helpers for optimizing the draw() method that can be called many, many times\n    int x, y;\n\n    // Boundary helpers\n    private final int physicistHeight = (int)(1.5 * Field.PHYSICIST_SIZE_IN_PIXELS);\n    private Rectangle boundingBox;\n\n\n    /**\n     * Create a default, blue physicist\n     */\n    public Physicist() {\n        this(BLUE);\n    }\n\n    /**\n     * Create a Physicist of the given color\n     */\n    public Physicist(Color color) {\n        setColor(color);\n        aimingAngle = 90.0f;\n        aimingForce = 50.0f;\n        getNewApple();\n    }\n\n    public void setAimingAngle(Float angle) {\n        aimingAngle = angle;\n    }\n\n    public void setAimingForce(Float force) {\n        if (force < 0) {\n            force = 0.0f;\n        }\n        aimingForce = force;\n    }\n\n    /**\n     * Sets the color for the physicist.\n     *\n     * @param color\n     */\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    @Override\n    public void setPosition(int x, int y) {\n        // Our position is based on the center of our dome,\n        // but it will be drawn from the upper left corner.\n        // Figure out the distance of that gap\n        int offset = (int)(Field.PHYSICIST_SIZE_IN_PIXELS / 2.0f);\n\n        this.centerX = x;\n        this.centerY = y;\n        this.x = x - offset;\n        this.y = y - offset;\n        boundingBox = new Rectangle(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, physicistHeight);\n    }\n\n    @Override\n    public int getPositionX() {\n        return centerX;\n    }\n\n    @Override\n    public int getPositionY() {\n        return centerY;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    /**\n     * Sets the active field once our physicist is being displayed.\n     *\n     * @param field Active game field\n     */\n    public void setField(Field field) {\n        this.field = field;\n    }\n\n    /**\n     * Take the current apple away from the physicist. Returns the apple for\n     * use in animating on the field. Note that if there is no current apple being\n     * aimed, null is returned.\n     *\n     * @return the current apple (if any) being aimed\n     */\n    public Apple takeApple() {\n        Apple myApple = aimingApple;\n        aimingApple = null;\n        return myApple;\n    }\n\n    /**\n     * Get a new apple ready if we need one. Do not discard an existing apple.\n     */\n    public void getNewApple() {\n        // Don't drop the current apple if we already have one!\n        if (aimingApple == null) {\n            aimingApple = new Apple(this);\n        }\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        // Make sure our physicist is the right color, then draw the semi-circle and box\n        g.setColor(color);\n        g.fillArc(x, y, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS, 0, 180);\n        g.fillRect(x, centerY, Field.PHYSICIST_SIZE_IN_PIXELS, Field.PHYSICIST_SIZE_IN_PIXELS);\n\n        // Do we have an apple to draw as well?\n        if (aimingApple != null) {\n            // Yes. Position the center of the apple on the edge of our semi-circle.\n            // Use the current aimingAngle to determine where on the edge.\n            double angleInRadians = Math.toRadians(aimingAngle);\n            double radius = Field.PHYSICIST_SIZE_IN_PIXELS / 2.0;\n            int aimingX = centerX + (int)(Math.cos(angleInRadians) * radius);\n            int aimingY = centerY - (int)(Math.sin(angleInRadians) * radius);\n            aimingApple.setPosition(aimingX, aimingY);\n            aimingApple.draw(g);\n        }\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        if (e.getActionCommand().equals(\"New Apple\")) {\n            getNewApple();\n            if (field != null) {\n                field.repaint();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "game/Tree.java",
    "content": "package game;\n\nimport java.awt.*;\n\npublic class Tree implements GamePiece {\n    int x, y;\n\n    // Drawing helpers\n    private Color leafColor = Color.GREEN.darker();\n    private Color trunkColor = new Color(101, 67, 33);\n    private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);\n    private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);\n    private int trunkX, trunkY;\n\n    // Boundary helpers\n    private Rectangle boundingBox;\n\n    @Override\n    public void setPosition(int x, int y) {\n        this.x = x;\n        this.y = y;\n        trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;\n        trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;\n        boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);\n    }\n\n    @Override\n    public int getPositionX() {\n        return x;\n    }\n\n    @Override\n    public int getPositionY() {\n        return y;\n    }\n\n    @Override\n    public Rectangle getBoundingBox() {\n        return boundingBox;\n    }\n\n    @Override\n    public void draw(Graphics g) {\n        g.setColor(trunkColor);\n        g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);\n        g.setColor(leafColor);\n        g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);\n    }\n\n    @Override\n    public boolean isTouching(GamePiece otherPiece) {\n        if (this == otherPiece) {\n            // By definition we don't collide with ourselves\n            return false;\n        }\n        return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());\n    }\n}\n"
  }
]