├── .gitignore
├── LICENSE
├── README.md
├── ch02
├── examples
│ ├── HelloJava.java
│ ├── HelloJava2.java
│ └── HelloWorld.java
├── exercises
│ ├── HelloJava.java
│ └── HelloWorld.java
└── solutions
│ ├── GoodbyeJava.java
│ └── GoodbyeWorld.java
├── ch03
├── examples
│ ├── MyTest.java
│ ├── animals
│ │ └── birds
│ │ │ ├── BigBird.class
│ │ │ └── BigBird.java
│ ├── spaceblaster-src
│ │ ├── manifest.mf
│ │ └── spaceblaster
│ │ │ └── game
│ │ │ ├── Game.java
│ │ │ ├── Planetoid.java
│ │ │ └── SpaceShip.java
│ ├── spaceblaster.jar
│ └── spaceblaster
│ │ ├── docs
│ │ ├── help1.html
│ │ └── help2.html
│ │ ├── game
│ │ ├── Game.class
│ │ ├── Planetoid.class
│ │ └── SpaceShip.class
│ │ └── images
│ │ ├── planetoid.png
│ │ └── spaceship.png
├── exercises
│ ├── HelloJar.java
│ └── manifest.mf
└── solutions
│ ├── HelloComponent2.class
│ ├── HelloJar.class
│ ├── HelloJar.java
│ ├── hello.jar
│ └── manifest.mf
├── ch04
├── examples
│ ├── EnhancedForDemo.java
│ ├── EuclidGCD.java
│ ├── ForDemo.java
│ ├── HelloJava.java
│ ├── IfDemo.java
│ ├── SwitchDemo.java
│ └── WhileDemo.java
├── exercises
│ ├── Euclid.java
│ └── SimpleTriangle.java
└── solutions
│ ├── Euclid.java
│ ├── SimpleTriangle.java
│ └── VisualTriangle.java
├── ch05
├── examples
│ ├── Apple.java
│ ├── Field.java
│ ├── HelloJava3.java
│ ├── PrintAppleDetails.java
│ ├── PrintAppleDetails2.java
│ ├── PrintAppleDetails3.java
│ ├── PrintAppleDetails4.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── Physicist.java
│ │ └── Tree.java
├── exercises
│ ├── Zoo.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── Physicist.java
│ │ └── Tree.java
└── solutions
│ ├── Zoo.java
│ ├── Zoo2.java
│ ├── Zoo3.java
│ └── game
│ ├── Apple.java
│ ├── AppleToss.java
│ ├── Field.java
│ ├── GamePiece.java
│ ├── Hedge.java
│ ├── Physicist.java
│ └── Tree.java
├── ch06
├── examples
│ ├── Euclid2.java
│ └── LogTest.java
├── exercises
│ ├── Euclid2.java
│ ├── HelloZero.java
│ └── Pause.java.bad
└── solutions
│ ├── Euclid2.java
│ ├── Euclid3.java
│ ├── GCDException.java
│ ├── HelloZero.java
│ ├── Pause.java
│ └── severe.properties
├── ch07
├── examples
│ ├── RawType.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Hedge.java
│ │ ├── Physicist.java
│ │ └── Tree.java
├── exercises
│ ├── Employee.java
│ ├── EmployeeList.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Hedge.java
│ │ ├── Physicist.java
│ │ └── Tree.java
└── solutions
│ ├── Employee.java
│ ├── Employee2.java
│ ├── EmployeeList.java
│ ├── EmployeeList2.java
│ └── game
│ ├── Apple.java
│ ├── AppleToss.java
│ ├── Field.java
│ ├── GamePiece.java
│ ├── GameUtilities.java
│ ├── Hedge.java
│ ├── Physicist.java
│ └── Tree.java
├── ch08
├── examples
│ ├── ValidEmail.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Physicist.java
│ │ └── Tree.java
├── exercises
│ └── HelloChapter8.java
└── solutions
│ └── HelloChapter8.java
├── ch09
├── examples
│ ├── Interruption.java
│ ├── Thready.java
│ ├── Thready2.java
│ ├── URLConsumer.java
│ ├── URLConsumer3.java
│ ├── URLConsumer4.java
│ ├── URLDemo.java
│ ├── URLDemo2.java.preview
│ ├── URLDemo3.java.preview
│ ├── URLDemo4.java.preview
│ ├── URLProducer.java
│ ├── URLProducer4.java
│ ├── URLQueue.java
│ ├── VirtualDemo.java.preview
│ ├── VirtualDemo2.java.preview
│ └── VirtualThready.java.preview
├── exercises
│ ├── Clock.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Hedge.java
│ │ ├── Physicist.java
│ │ └── Tree.java
└── solutions
│ ├── Clock.java
│ └── game
│ ├── Apple.java
│ ├── AppleToss.java
│ ├── Field.java
│ ├── GamePiece.java
│ ├── GameUtilities.java
│ ├── Hedge.java
│ ├── Physicist.java
│ └── Tree.java
├── ch10
├── examples
│ ├── AccessNIO.java
│ ├── ListIt.java
│ ├── ParseKeyboard.java
│ └── access.txt
├── exercises
│ └── Count.java
└── solutions
│ ├── Count1.java
│ ├── Count2.java
│ ├── Count3.java
│ ├── Count4.java
│ └── countlog.txt
├── ch11
├── examples
│ ├── Adjuster.java
│ ├── PaidEmployee.java
│ ├── Report.java
│ ├── VirtualDemo2.java.preview
│ ├── VirtualDemo3.java.preview
│ └── WeekDayGenerator.java
├── exercises
│ ├── Adjuster.java
│ ├── PaidEmployee.java
│ └── Report.java
└── solutions
│ ├── Adjuster.java
│ ├── PaidEmployee.java
│ ├── PaidEmployee2.java
│ ├── Report.java
│ └── Report2.java
├── ch12
├── examples
│ ├── ActionDemo1.java
│ ├── ActionDemo2.java
│ ├── BorderLayoutDemo.java
│ ├── Buttons.java
│ ├── HelloJavaAgain.java
│ ├── HelloMouse.java
│ ├── HelloMouseHelper.java
│ ├── Labels.java
│ ├── MenuDemo.java
│ ├── ModalDemo.java
│ ├── NestedPanelDemo.java
│ ├── PhoneGridDemo.java
│ ├── ProgressDemo.java
│ ├── TextInputs.java
│ ├── Widget.java
│ ├── check.png
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Hedge.java
│ │ ├── Physicist.java
│ │ └── Tree.java
├── exercises
│ ├── Calculator.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Hedge.java
│ │ ├── Physicist.java
│ │ └── Tree.java
└── solutions
│ ├── Calculator.java
│ ├── Calculator2.java
│ └── game
│ ├── Apple.java
│ ├── AppleToss.java
│ ├── Field.java
│ ├── GamePiece.java
│ ├── GameUtilities.java
│ ├── Hedge.java
│ ├── Physicist.java
│ └── Tree.java
├── ch13
├── examples
│ ├── DateAtHost.java
│ ├── IconLabel.java
│ ├── Post.java
│ ├── ReadUrl.java
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Hedge.java
│ │ ├── Multiplayer.java
│ │ ├── Physicist.java
│ │ └── Tree.java
├── exercises
│ └── game
│ │ ├── Apple.java
│ │ ├── AppleToss.java
│ │ ├── Field.java
│ │ ├── GamePiece.java
│ │ ├── GameUtilities.java
│ │ ├── Hedge.java
│ │ ├── Multiplayer.java
│ │ ├── Physicist.java
│ │ └── Tree.java
└── solutions
│ ├── FDClient.java
│ ├── FDServer.java
│ ├── FDServer2.java.preview
│ ├── NetworkInt.java
│ └── game
│ ├── Apple.java
│ ├── AppleToss.java
│ ├── Field.java
│ ├── GamePiece.java
│ ├── GameUtilities.java
│ ├── Hedge.java
│ ├── Multiplayer.java
│ ├── Physicist.java
│ └── Tree.java
├── game
├── Apple.java
├── AppleToss.java
├── Field.java
├── GamePiece.java
├── GameUtilities.java
├── Hedge.java
├── Multiplayer.java
├── Physicist.java
└── Tree.java
└── quiz
├── .gitignore
├── build.sh
├── lj6review.jar
├── manifest.mf
├── quizgen.pl
└── src
├── com
└── loyinc
│ ├── quiz
│ ├── Answer.java
│ ├── Chapter.java
│ ├── Question.java
│ ├── QuestionPane.java
│ ├── QuizFrame.java
│ ├── QuizPane.java
│ ├── QuizTree.java
│ ├── Quizzes.java
│ └── Review.java
│ └── util
│ ├── CWButton.java
│ ├── CWLabel.java
│ ├── Config.java
│ ├── RollingButtonGroup.java
│ ├── StateProvider.java
│ └── StateProviderCellRenderer.java
└── res
├── ch_done_ok.png
├── ch_filled.png
├── ch_list.png
├── ch_list_inv.png
├── ch_not_ok.png
├── ch_open.png
├── correct01.png
├── cover-480.png
├── cover.png
├── notquite01.png
├── quiz-data.txt
└── unknown01.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | # Don't skip as we occasionally provide pre-compiled classes for readers
3 | #*.class
4 |
5 | # Log file
6 | *.log
7 |
8 | # BlueJ files
9 | *.ctxt
10 |
11 | # Mobile Tools for Java (J2ME)
12 | .mtj.tmp/
13 |
14 | # Package Files #
15 | #*.jar # we include a few jars as solutions and pre-built apps
16 | *.war
17 | *.nar
18 | *.ear
19 | *.zip
20 | *.tar.gz
21 | *.rar
22 |
23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
24 | hs_err_pid*
25 |
26 | # VS Code stuffs
27 | settings.json
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # learnjava6e
2 | Code examples for O'Reilly's Learning Java, 6e by Marc Loy, Patrick Niemeyer, and Daniel Leuck
3 |
--------------------------------------------------------------------------------
/ch02/examples/HelloJava.java:
--------------------------------------------------------------------------------
1 | package ch02.examples;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * A bare bones graphical version of Hello World.
7 | */
8 | public class HelloJava {
9 | public static void main( String[] args ) {
10 | JFrame frame = new JFrame( "Hello, Java!" );
11 | JLabel label = new JLabel("Hello, Java!", JLabel.CENTER );
12 | frame.add(label);
13 | frame.setSize( 300, 300 );
14 | frame.setVisible( true );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch02/examples/HelloJava2.java:
--------------------------------------------------------------------------------
1 | package ch02.examples;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 | import javax.swing.*;
6 |
7 | /**
8 | * An upgraded graphical application with interactivity!
9 | */
10 | public class HelloJava2 {
11 | public static void main( String[] args ) {
12 | JFrame frame = new JFrame( "HelloJava2" );
13 | frame.add( new HelloComponent2("Hello, Java!") );
14 | frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
15 | frame.setSize( 300, 300 );
16 | frame.setVisible( true );
17 | }
18 | }
19 |
20 | /*
21 | * Inheritence (the "extends" keyword below) and interfaces
22 | * (the "implements MouseMotionListener" portion) are covered in
23 | * more detail in Chapter 5.
24 | */
25 | class HelloComponent2 extends JComponent implements MouseMotionListener {
26 | String theMessage;
27 | int messageX = 125, messageY = 95; // Coordinates of the message
28 |
29 | /**
30 | * Create a new component that can draw its message at an arbitrary position.
31 | * That position can be changed by dragging the mouse; we attach a listener
32 | * to pick up those drag events.
33 | */
34 | public HelloComponent2( String message ) {
35 | theMessage = message;
36 | addMouseMotionListener(this);
37 | }
38 |
39 | public void paintComponent( Graphics g ) {
40 | g.drawString( theMessage, messageX, messageY );
41 | }
42 |
43 | public void mouseDragged(MouseEvent e) {
44 | // Save the mouse coordinates and paint the message.
45 | messageX = e.getX();
46 | messageY = e.getY();
47 | repaint();
48 | }
49 |
50 | public void mouseMoved(MouseEvent e) {
51 | // Ignore simple movements
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ch02/examples/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package ch02.examples;
2 |
3 | /**
4 | * The canonical first program: Hello, world!
5 | */
6 | public class HelloWorld {
7 | public static void main( String[] args ) {
8 | System.out.println("Hello, world!");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ch02/exercises/HelloJava.java:
--------------------------------------------------------------------------------
1 | package ch02.exercises;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * A simple variation on the HelloJava class.
7 | * Added the step to quit when the window is closed.
8 | * (See HelloWorld.java for the commandline version.)
9 | */
10 | public class HelloJava {
11 | public static void main( String[] args ) {
12 | JFrame frame = new JFrame( "Chapter 2, Exercise 1" );
13 | JLabel label = new JLabel("Hello, Java!", JLabel.CENTER );
14 | frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
15 | frame.add(label);
16 | frame.setSize( 300, 200 );
17 | frame.setVisible( true );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ch02/exercises/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package ch02.exercises;
2 |
3 | /**
4 | * A simple variation on the commandline version
5 | * of Hello, world. (See HelloJava.java for the
6 | * graphical version.)
7 | */
8 | public class HelloWorld {
9 | public static void main( String[] args ) {
10 | System.out.println("Hello, world!");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ch02/solutions/GoodbyeJava.java:
--------------------------------------------------------------------------------
1 | package ch02.solutions;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * A simple variation on the HelloJava class.
7 | * Added the step to quit when the window is closed.
8 | * (See GoodbyeWorld.java for the commandline version.)
9 | */
10 | public class GoodbyeJava {
11 | public static void main( String[] args ) {
12 | JFrame frame = new JFrame( "Exercise: Goodbye, Java" );
13 | JLabel label = new JLabel("Goodbye, Java!", JLabel.CENTER );
14 | frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
15 | frame.add(label);
16 | frame.setSize( 300, 200 );
17 | frame.setVisible( true );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ch02/solutions/GoodbyeWorld.java:
--------------------------------------------------------------------------------
1 | package ch02.solutions;
2 |
3 | /**
4 | * A simple variation on the commandline version
5 | * of Hello, world. (See GoodbyeJava.java for the
6 | * graphical version.)
7 | */
8 | public class GoodbyeWorld {
9 | public static void main( String[] args ) {
10 | System.out.println("Goodbye, world!");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ch03/examples/MyTest.java:
--------------------------------------------------------------------------------
1 | // No package declared here. This class will be part of the
2 | // "default" package.
3 |
4 | public class MyTest {
5 | public static void main(String args[]) {
6 | System.out.println("Congrats! You ran MyTest correctly!");
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/ch03/examples/animals/birds/BigBird.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/examples/animals/birds/BigBird.class
--------------------------------------------------------------------------------
/ch03/examples/animals/birds/BigBird.java:
--------------------------------------------------------------------------------
1 | package animals.birds;
2 |
3 | public class BigBird {
4 | public static void main(String args[]) {
5 | System.out.println("This is the animals.birds.BigBird class.");
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster-src/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Created-By: 11.0.16
3 | Main-Class: spaceblaster.game.Game
4 |
5 |
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster-src/spaceblaster/game/Game.java:
--------------------------------------------------------------------------------
1 | package spaceblaster.game;
2 |
3 | public class Game {
4 | public static void main(String args[]) {
5 | SpaceShip ship = new SpaceShip();
6 | Planetoid planet = new Planetoid();
7 |
8 | ship.fireOn(planet);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster-src/spaceblaster/game/Planetoid.java:
--------------------------------------------------------------------------------
1 | package spaceblaster.game;
2 |
3 | public class Planetoid {
4 | public void destroy() {
5 | System.out.println("We've been hit! It's as if millions of voices suddenly cried out");
6 | System.out.println("in terror and were suddenly silenced. I fear... oh wait...");
7 | System.out.println("Nevermind. I accidentally hit the mute button. We're fine.");
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster-src/spaceblaster/game/SpaceShip.java:
--------------------------------------------------------------------------------
1 | package spaceblaster.game;
2 |
3 | public class SpaceShip {
4 | private String laserSound = "pew";
5 |
6 | public void fireOn(Planetoid target) {
7 | System.out.print("Firing:");
8 | for (int i = 0; i < 3; i++) {
9 | System.out.print(" " + laserSound);
10 | }
11 | System.out.println("!\n");
12 | target.destroy();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/examples/spaceblaster.jar
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster/docs/help1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SpaceBlaster Help, Page 1
5 |
6 |
7 |
12 |
13 |
14 | Welcome to SpaceBlaster!
15 | This example doesn't really do much, but it will print a fun message when you run it.
16 | The help continues on page 2.
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster/docs/help2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SpaceBlaster Help, Page 2
5 |
6 |
7 |
12 |
13 |
14 | More SpaceBlaster!
15 |
16 | To run the game, you'll need Java 17 or higher and a terminal window.
17 | Type in java -jar spaceblaster.jar
and off you go!
18 |
19 | This help is continued from page 1.
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster/game/Game.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/examples/spaceblaster/game/Game.class
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster/game/Planetoid.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/examples/spaceblaster/game/Planetoid.class
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster/game/SpaceShip.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/examples/spaceblaster/game/SpaceShip.class
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster/images/planetoid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/examples/spaceblaster/images/planetoid.png
--------------------------------------------------------------------------------
/ch03/examples/spaceblaster/images/spaceship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/examples/spaceblaster/images/spaceship.png
--------------------------------------------------------------------------------
/ch03/exercises/HelloJar.java:
--------------------------------------------------------------------------------
1 | package ch03.exercises;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 | import javax.swing.*;
6 |
7 | /**
8 | * Reusing our graphical application with interactivity!
9 | */
10 | public class HelloJar {
11 | public static void main( String[] args ) {
12 | String msg = "You cheated! :)";
13 | if ( HelloJar.class.getProtectionDomain()
14 | .getCodeSource()
15 | .getLocation()
16 | .getFile()
17 | .endsWith(".jar") ) {
18 | // You didn't cheat, so let's fix the message
19 | msg = "Hello from a JAR file!";
20 | }
21 | JFrame frame = new JFrame( "Hello Jar" );
22 | frame.add( new HelloComponent2(msg) );
23 | frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
24 | frame.setSize( 300, 300 );
25 | frame.setVisible( true );
26 | }
27 | }
28 |
29 | /*
30 | * Inheritence (the "extends" keyword below) and interfaces
31 | * (the "implements MouseMotionListener" portion) are covered in
32 | * more detail in Chapter 5.
33 | */
34 | class HelloComponent2 extends JComponent implements MouseMotionListener {
35 | String theMessage;
36 | int messageX = 125, messageY = 95; // Coordinates of the message
37 |
38 | /**
39 | * Create a new component that can draw its message at an arbitrary position.
40 | * That position can be changed by dragging the mouse; we attach a listener
41 | * to pick up those drag events.
42 | */
43 | public HelloComponent2( String message ) {
44 | theMessage = message;
45 | addMouseMotionListener(this);
46 | }
47 |
48 | public void paintComponent( Graphics g ) {
49 | g.drawString( theMessage, messageX, messageY );
50 | }
51 |
52 | public void mouseDragged(MouseEvent e) {
53 | // Save the mouse coordinates and paint the message.
54 | messageX = e.getX();
55 | messageY = e.getY();
56 | repaint();
57 | }
58 |
59 | public void mouseMoved(MouseEvent e) {
60 | // Ignore simple movements
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch03/exercises/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Created-By: 11.0.16
3 |
4 |
--------------------------------------------------------------------------------
/ch03/solutions/HelloComponent2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/solutions/HelloComponent2.class
--------------------------------------------------------------------------------
/ch03/solutions/HelloJar.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/solutions/HelloJar.class
--------------------------------------------------------------------------------
/ch03/solutions/HelloJar.java:
--------------------------------------------------------------------------------
1 | package ch03.solutions;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 | import javax.swing.*;
6 |
7 | /**
8 | * Reusing our graphical application with interactivity!
9 | */
10 | public class HelloJar {
11 | public static void main( String[] args ) {
12 | String msg = "You cheated! :)";
13 | if ( HelloJar.class.getProtectionDomain()
14 | .getCodeSource()
15 | .getLocation()
16 | .getFile()
17 | .endsWith(".jar") ) {
18 | // You didn't cheat, so let's fix the message
19 | msg = "Hello from a JAR file!";
20 | }
21 | JFrame frame = new JFrame( "Hello Jar" );
22 | frame.add( new HelloComponent2(msg) );
23 | frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
24 | frame.setSize( 300, 300 );
25 | frame.setVisible( true );
26 | }
27 | }
28 |
29 | /*
30 | * Inheritence (the "extends" keyword below) and interfaces
31 | * (the "implements MouseMotionListener" portion) are covered in
32 | * more detail in Chapter 5.
33 | */
34 | class HelloComponent2 extends JComponent implements MouseMotionListener {
35 | String theMessage;
36 | int messageX = 125, messageY = 95; // Coordinates of the message
37 |
38 | /**
39 | * Create a new component that can draw its message at an arbitrary position.
40 | * That position can be changed by dragging the mouse; we attach a listener
41 | * to pick up those drag events.
42 | */
43 | public HelloComponent2( String message ) {
44 | theMessage = message;
45 | addMouseMotionListener(this);
46 | }
47 |
48 | public void paintComponent( Graphics g ) {
49 | g.drawString( theMessage, messageX, messageY );
50 | }
51 |
52 | public void mouseDragged(MouseEvent e) {
53 | // Save the mouse coordinates and paint the message.
54 | messageX = e.getX();
55 | messageY = e.getY();
56 | repaint();
57 | }
58 |
59 | public void mouseMoved(MouseEvent e) {
60 | // Ignore simple movements
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch03/solutions/hello.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch03/solutions/hello.jar
--------------------------------------------------------------------------------
/ch03/solutions/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Created-By: 11.0.16
3 | Main-Class: ch03.solutions.HelloJar
4 |
5 |
--------------------------------------------------------------------------------
/ch04/examples/EnhancedForDemo.java:
--------------------------------------------------------------------------------
1 | package ch04.examples;
2 |
3 | import java.util.ArrayList;
4 |
5 | public class EnhancedForDemo {
6 | public static void main(String args[]) {
7 | int [] arrayOfInts = new int [] { 1, 2, 3, 4 };
8 | int total = 0;
9 |
10 | for( int i : arrayOfInts ) {
11 | System.out.println( i );
12 | total = total + i;
13 | }
14 | System.out.println("Total: " + total);
15 |
16 | // ArrayList is a popular collection class
17 | // Chapter 7 discusses collections in more detail
18 | ArrayList list = new ArrayList();
19 | list.add("foo");
20 | list.add("bar");
21 |
22 | for( String s : list )
23 | System.out.println( s );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ch04/examples/EuclidGCD.java:
--------------------------------------------------------------------------------
1 | package ch04.examples;
2 |
3 | /**
4 | * A basic implementation of Euclid's greatest common denominator
5 | * algorithm.
6 | *
7 | * https://en.wikipedia.org/wiki/Algorithm
8 | */
9 | public class EuclidGCD {
10 | public static void main(String args[]) {
11 | // For now, just "hard code" the two numbers to compare
12 | int a = 2701;
13 | int b = 222;
14 | while (b != 0) {
15 | if (a > b) {
16 | a = a - b;
17 | } else {
18 | b = b - a;
19 | }
20 | }
21 | System.out.println("GCD is " + a);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch04/examples/ForDemo.java:
--------------------------------------------------------------------------------
1 | package ch04.examples;
2 |
3 | public class ForDemo {
4 | public static void main(String args[]) {
5 | System.out.println("Count up from 0 to 99:");
6 | for ( int i = 0; i < 100; i++ ) {
7 | System.out.println( i );
8 | int j = i;
9 | // do any other work needed
10 | }
11 |
12 | System.out.println("\nGenerate some coordinates:");
13 | for (int x = 0, y = 10; x < y; x++, y-- ) {
14 | System.out.println(x + ", " + y);
15 | // do other stuff with our new (x, y)...
16 | }
17 |
18 | System.out.println("\nCount from 0 to 9, but skip 5 using a continue statement:");
19 | for ( int i = 0; i < 10; i++ ) {
20 | if ( i == 5 )
21 | continue;
22 | System.out.println( i );
23 | }
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ch04/examples/HelloJava.java:
--------------------------------------------------------------------------------
1 | package ch04.examples;
2 |
3 | import javax.swing.*;
4 |
5 | public class HelloJava {
6 | public static void main( String[] args ) {
7 | JFrame frame = new JFrame( "Hello, Java!" );
8 | JLabel label = new JLabel("Hello, Java!", JLabel.CENTER );
9 | frame.add(label);
10 | frame.setSize( 300, 300 );
11 | frame.setVisible( true );
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/ch04/examples/IfDemo.java:
--------------------------------------------------------------------------------
1 | package ch04.examples;
2 |
3 | public class IfDemo {
4 | public static void main(String args[]) {
5 | int i = 0;
6 | // you can use i now to do other work and then
7 | // we can test it to see if anything has changed
8 | if (i == 0)
9 | System.out.println("i is still zero");
10 | else
11 | System.out.println("i is most definitely not zero");
12 |
13 | int j = 0;
14 | // you can use j now to do work like i before,
15 | // then make sure that work didn't drop
16 | // j's value below zero
17 | if (j < 0) {
18 | System.out.println("j is less than 0! Resetting.");
19 | j = 0;
20 | } else {
21 | System.out.println("j is positive or 0. Continuing.");
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ch04/examples/WhileDemo.java:
--------------------------------------------------------------------------------
1 | package ch04.examples;
2 |
3 | public class WhileDemo {
4 | public static void main(String args[]) {
5 | // A simple example of counting down
6 | int count = 10;
7 | while( count > 0 ) {
8 | System.out.println("Counting down: " + count);
9 | // maybe do other useful things
10 | // and decrement our count
11 | count = count - 1;
12 | }
13 | System.out.println("Done");
14 |
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch04/exercises/Euclid.java:
--------------------------------------------------------------------------------
1 | package ch04.exercises;
2 |
3 | /**
4 | * A basic implementation of Euclid's greatest common denominator
5 | * algorithm.
6 | *
7 | * https://en.wikipedia.org/wiki/Algorithm
8 | */
9 | public class Euclid {
10 | public static void main(String args[]) {
11 | // For now, just "hard code" the two numbers to compare
12 | int a = 2701;
13 | int b = 222;
14 | // Exercise 1, fill in the algorithm from Chapter 4
15 |
16 | // Can you include the original numbers in the output?
17 | System.out.println("The GCD is " + a);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ch04/exercises/SimpleTriangle.java:
--------------------------------------------------------------------------------
1 | package ch04.exercises;
2 |
3 | // Exercise 2. Print out the contents of our
4 | // "triangular" array.
5 |
6 | public class SimpleTriangle {
7 | public static void main(String args[]) {
8 | // Create our "triangular" two-dimensional array
9 | int[][] triangle = new int[5][];
10 |
11 | // Use nested loops to fill it
12 | for (int i = 0; i < triangle.length; i++) {
13 | triangle[i] = new int [i + 1];
14 | for (int j = 0; j < i + 1; j++)
15 | triangle[i][j] = i + j;
16 | }
17 |
18 | // Add your code to display the nested arrays here
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch04/solutions/Euclid.java:
--------------------------------------------------------------------------------
1 | package ch04.solutions;
2 |
3 | /**
4 | * A basic implementation of Euclid's greatest common denominator
5 | * algorithm.
6 | *
7 | * https://en.wikipedia.org/wiki/Algorithm
8 | */
9 | public class Euclid {
10 | public static void main(String args[]) {
11 | // For now, just "hard code" the two numbers to compare
12 | int a = 2701;
13 | int b = 222;
14 | int original_a = a;
15 | int original_b = b;
16 | while (b != 0) {
17 | if (a > b) {
18 | a = a - b;
19 | } else {
20 | b = b - a;
21 | }
22 | }
23 | System.out.println("The GCD of " + original_a + " and " + original_b + " is " + a);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ch04/solutions/SimpleTriangle.java:
--------------------------------------------------------------------------------
1 | package ch04.solutions;
2 |
3 | public class SimpleTriangle {
4 | public static void main(String args[]) {
5 | // Create our "triangular" two-dimensional array
6 | int[][] triangle = new int[5][];
7 |
8 | // Use nested loops to fill it
9 | for (int i = 0; i < triangle.length; i++) {
10 | triangle[i] = new int [i + 1];
11 | for (int j = 0; j < i + 1; j++)
12 | triangle[i][j] = i + j;
13 | }
14 |
15 | // And finally, use nested loops to display it
16 | for (int i = 0; i < triangle.length; i++) {
17 | for (int j = 0; j < triangle[i].length; j++) {
18 | System.out.println(triangle[i][j]);
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch04/solutions/VisualTriangle.java:
--------------------------------------------------------------------------------
1 | package ch04.solutions;
2 |
3 | public class VisualTriangle {
4 | public static void main(String args[]) {
5 | // Create our "triangular" two-dimensional array
6 | int[][] triangle = new int[5][];
7 |
8 | // Use nested loops to fill it
9 | for (int i = 0; i < triangle.length; i++) {
10 | triangle[i] = new int [i + 1];
11 | for (int j = 0; j < i + 1; j++)
12 | triangle[i][j] = i + j;
13 | }
14 |
15 | // And finally, use nested loops to display it
16 | for (int i = 0; i < triangle.length; i++) {
17 | for (int j = 0; j < triangle[i].length; j++) {
18 | System.out.print(triangle[i][j]);
19 | System.out.print(" ");
20 | }
21 | System.out.println();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ch05/examples/Field.java:
--------------------------------------------------------------------------------
1 | package ch05.examples;
2 |
3 | import java.awt.*;
4 | import javax.swing.*;
5 |
6 | /**
7 | * A reduced playing field for our game. This class sets up the apples
8 | * similar to our real game (in the ch05/examples/game folder) but leaves out
9 | * other details. It is meant for use with the various PrintDetails classes.
10 | */
11 | public class Field extends JComponent {
12 |
13 | public static final int APPLE_SIZE_IN_PIXELS = 30;
14 |
15 | Color fieldColor = Color.LIGHT_GRAY;
16 |
17 | Apple a1 = new Apple();
18 | Apple a2 = new Apple();
19 |
20 | public void setupApples() {
21 | // For now, just play with our apple attributes directly
22 | a1.diameter = 3.0f;
23 | a1.mass = 5.0f;
24 | a1.x = 20;
25 | a1.y = 40;
26 | a2.diameter = 8.0f;
27 | a2.mass = 10.0f;
28 | a2.x = 70;
29 | a2.y = 200;
30 | }
31 |
32 | protected void paintComponent(Graphics g) {
33 | g.setColor(fieldColor);
34 | g.fillRect(0, 0, getWidth(), getHeight());
35 | a1.draw(g);
36 | a2.draw(g);
37 | }
38 |
39 | public void detectCollisions() {
40 | if (a1.isTouching(a2)) {
41 | System.out.println("Collision detected!");
42 | } else {
43 | System.out.println("Apples are not touching.");
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/ch05/examples/HelloJava3.java:
--------------------------------------------------------------------------------
1 | package ch05.examples;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 | import javax.swing.*;
6 |
7 | /**
8 | * Another (minor) upgrade to our graphical Hello, World example.
9 | * This variation introduces an inner class for the message component
10 | * and an anonymous inner class for the listener handling the mouse
11 | * drag events. (More on events and listeners in Chapter 10.)
12 | */
13 | public class HelloJava3 extends JFrame {
14 | public static void main( String[] args ) {
15 | HelloJava3 demo = new HelloJava3();
16 | demo.setVisible( true );
17 | }
18 |
19 | public HelloJava3() {
20 | super( "HelloJava3" );
21 | add( new HelloComponent3("Hello, Inner Java!") );
22 | setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
23 | setSize( 300, 300 );
24 | }
25 |
26 | class HelloComponent3 extends JComponent {
27 | String theMessage;
28 | int messageX = 125, messageY = 95; // Coordinates of the message
29 |
30 | public HelloComponent3( String message ) {
31 | theMessage = message;
32 | addMouseMotionListener(new MouseMotionListener() {
33 | public void mouseDragged(MouseEvent e) {
34 | messageX = e.getX();
35 | messageY = e.getY();
36 | repaint();
37 | }
38 |
39 | public void mouseMoved(MouseEvent e) { }
40 | });
41 | }
42 |
43 | public void paintComponent( Graphics g ) {
44 | g.drawString( theMessage, messageX, messageY );
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ch05/examples/PrintAppleDetails.java:
--------------------------------------------------------------------------------
1 | package ch05.examples;
2 |
3 | /**
4 | * A simple demonstration of accessing the contents of an object. We create
5 | * a new apple and print out some of its details.
6 | */
7 | public class PrintAppleDetails {
8 | public static void main(String args[]) {
9 | String niceNames[] = Apple.getAppleSizes();
10 | Apple a1 = new Apple();
11 | System.out.println("Apple a1:");
12 | System.out.println(" mass: " + a1.mass);
13 | System.out.println(" diameter: " + a1.diameter);
14 | System.out.println(" position: (" + a1.x + ", " + a1.y +")");
15 | if (a1.diameter < 5.0f) {
16 | System.out.println("This is a " + niceNames[Apple.SMALL] + " apple.");
17 | } else if (a1.diameter < 10.0f) {
18 | System.out.println("This is a " + niceNames[Apple.MEDIUM] + " apple.");
19 | } else {
20 | System.out.println("This is a " + niceNames[Apple.LARGE] + " apple.");
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch05/examples/PrintAppleDetails2.java:
--------------------------------------------------------------------------------
1 | package ch05.examples;
2 |
3 | /**
4 | * Another quick example of working with an object. This time we print
5 | * the initial details of an apple, change some of those details, and
6 | * then do the same printing to provide a comparison of the results.
7 | */
8 | public class PrintAppleDetails2 {
9 | public static void main(String args[]) {
10 | Apple a1 = new Apple();
11 | System.out.println("Apple a1:");
12 | System.out.println(" mass: " + a1.mass);
13 | System.out.println(" diameter: " + a1.diameter);
14 | System.out.println(" position: (" + a1.x + ", " + a1.y +")");
15 | // fill in some information on a1
16 | a1.mass = 10.0f;
17 | a1.x = 20;
18 | a1.y = 42;
19 | System.out.println("Updated a1:");
20 | System.out.println(" mass: " + a1.mass);
21 | System.out.println(" diameter: " + a1.diameter);
22 | System.out.println(" position: (" + a1.x + ", " + a1.y +")");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ch05/examples/PrintAppleDetails3.java:
--------------------------------------------------------------------------------
1 | package ch05.examples;
2 |
3 | /**
4 | * A variation on PrintAppleDetails2 where we have moved the printing code
5 | * to the Apple class. Notice that this file is smaller than PrintAppleDetails2
6 | * meaning fewer lines to make mistakes!
7 | */
8 | public class PrintAppleDetails3 {
9 | public static void main(String args[]) {
10 | Apple a1 = new Apple();
11 | System.out.println("Apple a1:");
12 | a1.printDetails();
13 | // fill in some information on a1
14 | a1.mass = 10.0f;
15 | a1.x = 20;
16 | a1.y = 42;
17 | System.out.println("Updated a1:");
18 | a1.printDetails();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch05/examples/PrintAppleDetails4.java:
--------------------------------------------------------------------------------
1 | package ch05.examples;
2 |
3 | /**
4 | * One final iteration of manipulating and printing apple details.
5 | * Now the Field class understands apples so we access those apples
6 | * through the field object. Notice the double dot-notation.
7 | */
8 | public class PrintAppleDetails4 {
9 | public static void main(String args[]) {
10 | Field f = new Field();
11 | f.setupApples();
12 | System.out.println("Apple a1:");
13 | f.a1.printDetails();
14 | System.out.println("Apple a2:");
15 | f.a2.printDetails();
16 | f.detectCollisions();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch05/examples/game/AppleToss.java:
--------------------------------------------------------------------------------
1 | package ch05.examples.game;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * Our apple tossing game. This class extends JFrame to create our
7 | * main application window. We'll be filling this out along the way,
8 | * but for now we can setup a field with some trees and our player.
9 | */
10 | public class AppleToss extends JFrame {
11 |
12 | Field field = new Field();
13 | Physicist player1 = new Physicist();
14 |
15 | public AppleToss() {
16 | // Create our frame
17 | super("Apple Toss Game");
18 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
19 | setSize(800,600);
20 | setResizable(false);
21 |
22 | // Build the field with our player and some trees
23 | setupFieldForOnePlayer();
24 | }
25 |
26 | /**
27 | * A helper method to populate a one player field with target trees.
28 | */
29 | private void setupFieldForOnePlayer() {
30 | // Place our (new) physicist in the lower left corner and connect them to the field
31 | player1.setPosition(100,500);
32 | field.setPlayer(player1);
33 | player1.setField(field);
34 | field.setupApples();
35 | field.setupTree();
36 | add(field);
37 | }
38 |
39 | public static void main(String args[]) {
40 | AppleToss game = new AppleToss();
41 | game.setVisible(true);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ch05/examples/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch05.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * - methods for positioning on a Field
8 | * - methods for Drawing
9 | * - methods for detecting a collision with other GamePieces
10 | */
11 |
12 | public interface GamePiece {
13 | /**
14 | * Sets the position of the piece on the playing field.
15 | * (0,0) is the upper left per standard Java drawing methods.
16 | *
17 | * @param x
18 | * @param y
19 | */
20 | void setPosition(int x, int y);
21 |
22 | /**
23 | * Gets the current horizontal position of the piece on the field.
24 | *
25 | * @return current X position of the piece
26 | */
27 | int getPositionX();
28 |
29 | /**
30 | * Gets the current vertical position of the piece on the field.
31 | *
32 | * @return current Y position of the piece
33 | */
34 | int getPositionY();
35 |
36 | /**
37 | * Gets the bounding box of this piece.
38 | *
39 | * @return a Rectangle encompassing the visual elements of the piece
40 | */
41 | Rectangle getBoundingBox();
42 |
43 | /**
44 | * Draws the piece inside the given graphics context.
45 | * Do not assume anything about the state of the context.
46 | *
47 | * @param g
48 | */
49 | void draw(Graphics g);
50 |
51 | /**
52 | * Detect a collision with another piece on the field.
53 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
54 | *
55 | * @param otherPiece
56 | * @return
57 | */
58 | boolean isTouching(GamePiece otherPiece);
59 | }
60 |
--------------------------------------------------------------------------------
/ch05/examples/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch05.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | // We don't really have any collisions to detect yet, so just return "no".
57 | // As we fill out all of the game pieces, we'll come back to this method
58 | // and provide a more useful response.
59 | return false;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/ch05/exercises/Zoo.java:
--------------------------------------------------------------------------------
1 | package ch05.exercises;
2 |
3 | import java.util.*;
4 |
5 | public class Zoo {
6 |
7 | abstract class Animal {
8 | public abstract void speak();
9 | }
10 |
11 | class Lion extends Animal {
12 | public void speak() {
13 | System.out.print("roar");
14 | }
15 | }
16 |
17 | class Gibbon extends Animal {
18 | public void speak() {
19 | }
20 | }
21 |
22 | public void listen() {
23 | Lion lion = new Lion();
24 | Gibbon gibbon = new Gibbon();
25 | System.out.println("Let's listen to some animals!");
26 | System.out.print("The lion goes \"");
27 | lion.speak();
28 | System.out.println("\"");
29 | System.out.print("The gibbon goes \"");
30 | gibbon.speak();
31 | System.out.println("\"");
32 | }
33 |
34 | public static void main(String args[]) {
35 | Zoo myZoo = new Zoo();
36 | myZoo.listen();
37 | }
38 | }
39 |
40 |
41 |
--------------------------------------------------------------------------------
/ch05/exercises/game/AppleToss.java:
--------------------------------------------------------------------------------
1 | package ch05.exercises.game;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * Our apple tossing game. This class extends JFrame to create our
7 | * main application window. We'll be filling this out along the way,
8 | * but for now we can setup a field with some trees and our player.
9 | */
10 | public class AppleToss extends JFrame {
11 |
12 | Field field = new Field();
13 | Physicist player1 = new Physicist();
14 |
15 | public AppleToss() {
16 | // Create our frame
17 | super("Apple Toss Game");
18 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
19 | setSize(800,600);
20 | setResizable(false);
21 |
22 | // Build the field with our player and some trees
23 | setupFieldForOnePlayer();
24 | }
25 |
26 | /**
27 | * A helper method to populate a one player field with target trees.
28 | */
29 | private void setupFieldForOnePlayer() {
30 | // Place our (new) physicist in the lower left corner and connect them to the field
31 | player1.setPosition(100,500);
32 | field.setPlayer(player1);
33 | player1.setField(field);
34 | field.setupApples();
35 | field.setupTree();
36 | add(field);
37 | }
38 |
39 | public static void main(String args[]) {
40 | AppleToss game = new AppleToss();
41 | game.setVisible(true);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ch05/exercises/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch05.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * - methods for positioning on a Field
8 | * - methods for Drawing
9 | * - methods for detecting a collision with other GamePieces
10 | */
11 |
12 | public interface GamePiece {
13 | /**
14 | * Sets the position of the piece on the playing field.
15 | * (0,0) is the upper left per standard Java drawing methods.
16 | *
17 | * @param x
18 | * @param y
19 | */
20 | void setPosition(int x, int y);
21 |
22 | /**
23 | * Gets the current horizontal position of the piece on the field.
24 | *
25 | * @return current X position of the piece
26 | */
27 | int getPositionX();
28 |
29 | /**
30 | * Gets the current vertical position of the piece on the field.
31 | *
32 | * @return current Y position of the piece
33 | */
34 | int getPositionY();
35 |
36 | /**
37 | * Gets the bounding box of this piece.
38 | *
39 | * @return a Rectangle encompassing the visual elements of the piece
40 | */
41 | Rectangle getBoundingBox();
42 |
43 | /**
44 | * Draws the piece inside the given graphics context.
45 | * Do not assume anything about the state of the context.
46 | *
47 | * @param g
48 | */
49 | void draw(Graphics g);
50 |
51 | /**
52 | * Detect a collision with another piece on the field.
53 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
54 | *
55 | * @param otherPiece
56 | * @return
57 | */
58 | boolean isTouching(GamePiece otherPiece);
59 | }
60 |
--------------------------------------------------------------------------------
/ch05/exercises/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch05.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | // We don't really have any collisions to detect yet, so just return "no".
57 | // As we fill out all of the game pieces, we'll come back to this method
58 | // and provide a more useful response.
59 | return false;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/ch05/solutions/Zoo.java:
--------------------------------------------------------------------------------
1 | package ch05.solutions;
2 |
3 | import java.util.*;
4 |
5 | public class Zoo {
6 |
7 | abstract class Animal {
8 | public abstract void speak();
9 | }
10 |
11 | class Lion extends Animal {
12 | public void speak() {
13 | System.out.print("roar");
14 | }
15 | }
16 |
17 | class Gibbon extends Animal {
18 | public void speak() {
19 | System.out.print("hoot");
20 | }
21 | }
22 |
23 | public void listen() {
24 | Lion lion = new Lion();
25 | Gibbon gibbon = new Gibbon();
26 | System.out.println("Let's listen to some animals!");
27 | System.out.print("The lion goes \"");
28 | lion.speak();
29 | System.out.println("\"");
30 | System.out.print("The gibbon goes \"");
31 | gibbon.speak();
32 | System.out.println("\"");
33 | }
34 |
35 | public static void main(String args[]) {
36 | Zoo myZoo = new Zoo();
37 | myZoo.listen();
38 | }
39 | }
40 |
41 |
42 |
--------------------------------------------------------------------------------
/ch05/solutions/Zoo2.java:
--------------------------------------------------------------------------------
1 | package ch05.solutions;
2 |
3 | import java.util.*;
4 |
5 | public class Zoo2 {
6 |
7 | abstract class Animal {
8 | public abstract void speak();
9 | }
10 |
11 | class Lion extends Animal {
12 | public void speak() {
13 | System.out.print("roar");
14 | }
15 | }
16 |
17 | class Gibbon extends Animal {
18 | public void speak() {
19 | System.out.print("hoot");
20 | }
21 | }
22 |
23 | class Seal extends Animal {
24 | public void speak() {
25 | System.out.print("bark");
26 | }
27 | }
28 |
29 | public void listen() {
30 | Lion lion = new Lion();
31 | Gibbon gibbon = new Gibbon();
32 | Seal seal = new Seal();
33 | System.out.println("Let's listen to some animals!");
34 | System.out.print("The lion goes \"");
35 | lion.speak();
36 | System.out.println("\"");
37 | System.out.print("The gibbon goes \"");
38 | gibbon.speak();
39 | System.out.println("\"");
40 | System.out.print("The seal goes \"");
41 | seal.speak();
42 | System.out.println("\"");
43 | }
44 |
45 | public static void main(String args[]) {
46 | Zoo2 myZoo = new Zoo2();
47 | myZoo.listen();
48 | }
49 | }
50 |
51 |
52 |
--------------------------------------------------------------------------------
/ch05/solutions/Zoo3.java:
--------------------------------------------------------------------------------
1 | package ch05.solutions;
2 |
3 | import java.util.*;
4 |
5 | public class Zoo3 {
6 |
7 | abstract class Animal {
8 | public abstract void speak();
9 | public abstract String getSpecies();
10 | }
11 |
12 | class Lion extends Animal {
13 | public void speak() {
14 | System.out.print("roar");
15 | }
16 | public String getSpecies() {
17 | return "lion";
18 | }
19 | }
20 |
21 | class Gibbon extends Animal {
22 | public void speak() {
23 | System.out.print("hoot");
24 | }
25 | public String getSpecies() {
26 | return "gibbon";
27 | }
28 | }
29 |
30 | class Seal extends Animal {
31 | public void speak() {
32 | System.out.print("bark");
33 | }
34 | public String getSpecies() {
35 | return "seal";
36 | }
37 | }
38 |
39 | public void listen() {
40 | System.out.println("Let's listen to our menagerie!");
41 | Animal[] menagerie = { new Lion(), new Gibbon(), new Seal() };
42 | for (Animal animal : menagerie) {
43 | System.out.print("The ");
44 | System.out.print(animal.getSpecies());
45 | System.out.print(" goes \"");
46 | animal.speak();
47 | System.out.println("\"");
48 | }
49 | }
50 |
51 | public static void main(String args[]) {
52 | Zoo3 myZoo = new Zoo3();
53 | myZoo.listen();
54 | }
55 | }
56 |
57 |
58 |
--------------------------------------------------------------------------------
/ch05/solutions/game/AppleToss.java:
--------------------------------------------------------------------------------
1 | package ch05.solutions.game;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * Our apple tossing game. This class extends JFrame to create our
7 | * main application window. We'll be filling this out along the way,
8 | * but for now we can setup a field with some trees and our player.
9 | */
10 | public class AppleToss extends JFrame {
11 |
12 | Field field = new Field();
13 | Physicist player1 = new Physicist();
14 |
15 | public AppleToss() {
16 | // Create our frame
17 | super("Apple Toss Game");
18 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
19 | setSize(800,600);
20 | setResizable(false);
21 |
22 | // Build the field with our player and some trees
23 | setupFieldForOnePlayer();
24 | }
25 |
26 | /**
27 | * A helper method to populate a one player field with target trees.
28 | */
29 | private void setupFieldForOnePlayer() {
30 | // Place our (new) physicist in the lower left corner and connect them to the field
31 | player1.setPosition(100,500);
32 | field.setPlayer(player1);
33 | player1.setField(field);
34 | field.setupApples();
35 | field.setupTree();
36 | field.setupHedge();
37 | add(field);
38 | }
39 |
40 | public static void main(String args[]) {
41 | AppleToss game = new AppleToss();
42 | game.setVisible(true);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ch05/solutions/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch05.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * - methods for positioning on a Field
8 | * - methods for Drawing
9 | * - methods for detecting a collision with other GamePieces
10 | */
11 |
12 | public interface GamePiece {
13 | /**
14 | * Sets the position of the piece on the playing field.
15 | * (0,0) is the upper left per standard Java drawing methods.
16 | *
17 | * @param x
18 | * @param y
19 | */
20 | void setPosition(int x, int y);
21 |
22 | /**
23 | * Gets the current horizontal position of the piece on the field.
24 | *
25 | * @return current X position of the piece
26 | */
27 | int getPositionX();
28 |
29 | /**
30 | * Gets the current vertical position of the piece on the field.
31 | *
32 | * @return current Y position of the piece
33 | */
34 | int getPositionY();
35 |
36 | /**
37 | * Gets the bounding box of this piece.
38 | *
39 | * @return a Rectangle encompassing the visual elements of the piece
40 | */
41 | Rectangle getBoundingBox();
42 |
43 | /**
44 | * Draws the piece inside the given graphics context.
45 | * Do not assume anything about the state of the context.
46 | *
47 | * @param g
48 | */
49 | void draw(Graphics g);
50 |
51 | /**
52 | * Detect a collision with another piece on the field.
53 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
54 | *
55 | * @param otherPiece
56 | * @return
57 | */
58 | boolean isTouching(GamePiece otherPiece);
59 | }
60 |
--------------------------------------------------------------------------------
/ch05/solutions/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch05.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color hedgeColor = Color.GREEN.darker();
14 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
15 | private int hedgeHeight = (int)(hedgeWidth / 2);
16 |
17 | // Boundary helpers
18 | private Rectangle boundingBox;
19 |
20 | @Override
21 | public void setPosition(int x, int y) {
22 | this.x = x;
23 | this.y = y;
24 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(hedgeColor);
45 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
46 | }
47 |
48 | @Override
49 | public boolean isTouching(GamePiece otherPiece) {
50 | // We don't really have any collisions to detect yet, so just return "no".
51 | // As we fill out all of the game pieces, we'll come back to this method
52 | // and provide a more useful response.
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch05/solutions/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch05.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | // We don't really have any collisions to detect yet, so just return "no".
57 | // As we fill out all of the game pieces, we'll come back to this method
58 | // and provide a more useful response.
59 | return false;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/ch06/examples/Euclid2.java:
--------------------------------------------------------------------------------
1 | package ch06.examples;
2 |
3 | /**
4 | * A basic implementation of Euclid's greatest common denominator
5 | * algorithm. This version build on ch04 allowing you to pass the
6 | * numbers to use as command line arguments.
7 | */
8 | public class Euclid2 {
9 | public static void main(String args[]) {
10 | int a = 2701;
11 | int b = 222;
12 | // Only try to parse arguments if we have exactly 2
13 | if (args.length == 2) {
14 | try {
15 | a = Integer.parseInt(args[0]);
16 | b = Integer.parseInt(args[1]);
17 | } catch (NumberFormatException nfe) {
18 | System.err.println("Arguments were not both numbers. Using defaults.");
19 | }
20 | } else {
21 | System.err.println("Wrong number of arguments (expected 2). Using defaults.");
22 | }
23 | System.out.print("The GCD of " + a + " and " + b + " is ");
24 | while (b != 0) {
25 | if (a > b) {
26 | a = a - b;
27 | } else {
28 | b = b - a;
29 | }
30 | }
31 | System.out.println(a);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ch06/examples/LogTest.java:
--------------------------------------------------------------------------------
1 | package ch06.examples;
2 |
3 | import java.util.logging.*;
4 |
5 | public class LogTest {
6 | public static void main(String argv[]) {
7 | Logger logger = Logger.getLogger("ch06.LogTest");
8 |
9 | logger.severe("Power lost - running on backup!");
10 | logger.warning("Database connection lost, retrying...");
11 | logger.info("Startup complete.");
12 | logger.config("Server configuration: standalone, Java 20");
13 | logger.fine("Loading graphing package.");
14 | logger.finer("Doing pie chart");
15 | logger.finest("Starting bubble sort: value ="+42);
16 | }
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/ch06/exercises/Euclid2.java:
--------------------------------------------------------------------------------
1 | package ch06.exercises;
2 |
3 | public class Euclid2 {
4 | public static void main(String args[]) {
5 | int a = 2701;
6 | int b = 222;
7 | // Only try to parse arguments if we have exactly 2
8 | if (args.length == 2) {
9 | try {
10 | a = Integer.parseInt(args[0]);
11 | b = Integer.parseInt(args[1]);
12 | } catch (NumberFormatException nfe) {
13 | System.err.println("Arguments were not both numbers.");
14 | System.err.println("Using defaults.");
15 | }
16 | } else {
17 | System.err.print("Wrong number of arguments");
18 | System.err.println(" expected 2).");
19 | System.err.println("Using defaults.");
20 | }
21 | System.out.print("The GCD of " + a + " and " + b + " is ");
22 | while (b != 0) {
23 | if (a > b) {
24 | a = a - b;
25 | } else {
26 | b = b - a;
27 | }
28 | }
29 | System.out.println(a);
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/ch06/exercises/HelloZero.java:
--------------------------------------------------------------------------------
1 | package ch06.exercises;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 | import javax.swing.*;
6 |
7 | /**
8 | * An upgraded graphical application with interactivity!
9 | * Use this template to add assertions to guarantee our
10 | * message displays itself in a visible part of the window.
11 | */
12 | public class HelloZero {
13 | public static void main( String[] args ) {
14 | JFrame frame = new JFrame( "Chapter 6, Exercise 2" );
15 | frame.add( new HelloComponent0("Hello, Zero!") );
16 | frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
17 | frame.setSize( 300, 300 );
18 | frame.setVisible( true );
19 | }
20 | }
21 |
22 | /*
23 | * Our custom component to display a message and move
24 | * it around as the user drags their mouse. Hopefully
25 | * more of the extends/implements details make sense
26 | * now that you've worked with them more in Chapters
27 | * 5 and 6.
28 | */
29 | class HelloComponent0 extends JComponent implements MouseMotionListener {
30 | String theMessage;
31 | int messageX = 125, messageY = 95; // Coordinates of the message
32 |
33 | /**
34 | * Create a new component that can draw its message at an arbitrary position.
35 | * That position can be changed by dragging the mouse; we attach a listener
36 | * to pick up those drag events.
37 | */
38 | public HelloComponent0( String message ) {
39 | theMessage = message;
40 | addMouseMotionListener(this);
41 | }
42 |
43 | public void paintComponent( Graphics g ) {
44 | g.drawString( theMessage, messageX, messageY );
45 | }
46 |
47 | public void mouseDragged(MouseEvent e) {
48 | // Save the mouse coordinates and paint the message.
49 | messageX = e.getX();
50 | messageY = e.getY();
51 | repaint();
52 | }
53 |
54 | public void mouseMoved(MouseEvent e) {
55 | // Ignore simple movements
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ch06/exercises/Pause.java.bad:
--------------------------------------------------------------------------------
1 | package ch06.exercises;
2 |
3 | // NOTE: Be sure to rename this file to Pause.java when you want to
4 | // work on the exercise. We had to supply this "bad" file extension to
5 | // keep IDEs such as IntelliJ IDEA from failing. Many IDEs compile
6 | // every class in the project. If one fails, you can't run any of the
7 | // classes with main() methods. This is a quirk of our project that we
8 | // really have dozens and dozens of "projects" under one umbrella.
9 |
10 | public class Pause {
11 | public static void main(String args[]) {
12 | System.out.print("Starting... ");
13 | Thread.sleep(5000);
14 | System.out.println("done");
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch06/solutions/Euclid2.java:
--------------------------------------------------------------------------------
1 | package ch06.solutions;
2 |
3 | import java.util.logging.Logger;
4 |
5 | public class Euclid2 {
6 | static Logger log = Logger.getLogger("ch06.Euclid2");
7 | public static void main(String args[]) {
8 | int a = 2701;
9 | int b = 222;
10 | // Only try to parse arguments if we have exactly 2
11 | if (args.length == 2) {
12 | try {
13 | a = Integer.parseInt(args[0]);
14 | b = Integer.parseInt(args[1]);
15 | } catch (NumberFormatException nfe) {
16 | log.warning("Arguments were not both numbers.");
17 | log.warning("Using defaults.");
18 | }
19 | } else {
20 | System.err.print("Wrong number of arguments");
21 | System.err.println(" expected 2).");
22 | System.err.println("Using defaults.");
23 | }
24 | System.out.print("The GCD of " + a + " and " + b + " is ");
25 | while (b != 0) {
26 | if (a > b) {
27 | a = a - b;
28 | } else {
29 | b = b - a;
30 | }
31 | }
32 | System.out.println(a);
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/ch06/solutions/Euclid3.java:
--------------------------------------------------------------------------------
1 | package ch06.solutions;
2 |
3 | public class Euclid3 {
4 | public static void main(String args[]) {
5 | int a1, b1;
6 | int a = 2701;
7 | int b = 222;
8 | // Only try to parse arguments if we have exactly 2
9 | if (args.length == 2) {
10 | try {
11 | a = Integer.parseInt(args[0]);
12 | b = Integer.parseInt(args[1]);
13 | } catch (NumberFormatException nfe) {
14 | System.err.println("Arguments were not both numbers.");
15 | System.err.println("Using defaults.");
16 | }
17 | } else {
18 | System.err.print("Wrong number of arguments");
19 | System.err.println(" expected 2).");
20 | System.err.println("Using defaults.");
21 | }
22 | // Store our originals for messaging and such
23 | a1 = a;
24 | b1 = b;
25 | while (b != 0) {
26 | if (a > b) {
27 | a = a - b;
28 | } else {
29 | b = b - a;
30 | }
31 | }
32 | try {
33 | if (a == 1) {
34 | throw new GCDException(a1, b1);
35 | } else {
36 | System.out.print("The GCD of " + a1 + " and " + b1 + " is ");
37 | System.out.println(a);
38 | }
39 | } catch (GCDException gcde) {
40 | System.err.println(gcde.getA() + " and " + gcde.getB() + " have no common denominator.");
41 | }
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/ch06/solutions/GCDException.java:
--------------------------------------------------------------------------------
1 | package ch06.solutions;
2 |
3 | public class GCDException extends Exception {
4 | private int badA;
5 | private int badB;
6 |
7 | GCDException(int a, int b) {
8 | super("No common factors for " + a + ", " + b);
9 | badA = a;
10 | badB = b;
11 | }
12 |
13 | public int getA() { return badA; }
14 | public int getB() { return badB; }
15 | }
16 |
--------------------------------------------------------------------------------
/ch06/solutions/HelloZero.java:
--------------------------------------------------------------------------------
1 | package ch06.solutions;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 | import javax.swing.*;
6 |
7 | /**
8 | * An upgraded graphical application with interactivity!
9 | * Use this template to add assertions to guarantee our
10 | * message displays itself in a visible part of the window.
11 | */
12 | public class HelloZero {
13 | public static void main( String[] args ) {
14 | JFrame frame = new JFrame( "Chapter 6, Exercise 2" );
15 | frame.add( new HelloComponent0("Hello, Zero!") );
16 | frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
17 | frame.setSize( 300, 300 );
18 | frame.setVisible( true );
19 | }
20 | }
21 |
22 | /*
23 | * Our custom component to display a message and move
24 | * it around as the user drags their mouse. Hopefully
25 | * more of the extends/implements details make sense
26 | * now that you've worked with them more in Chapters
27 | * 5 and 6.
28 | */
29 | class HelloComponent0 extends JComponent implements MouseMotionListener {
30 | String theMessage;
31 | int messageX = -125, messageY = 95; // Coordinates of the message
32 |
33 | /**
34 | * Create a new component that can draw its message at an arbitrary position.
35 | * That position can be changed by dragging the mouse; we attach a listener
36 | * to pick up those drag events.
37 | */
38 | public HelloComponent0( String message ) {
39 | theMessage = message;
40 | addMouseMotionListener(this);
41 | assert messageX > 0 : "X coordinate is too small";
42 | assert messageY > 0 : "Y coordinate is too small";
43 | }
44 |
45 | public void paintComponent( Graphics g ) {
46 | g.drawString( theMessage, messageX, messageY );
47 | }
48 |
49 | public void mouseDragged(MouseEvent e) {
50 | // Save the mouse coordinates and paint the message.
51 | messageX = e.getX();
52 | messageY = e.getY();
53 | repaint();
54 | }
55 |
56 | public void mouseMoved(MouseEvent e) {
57 | // Ignore simple movements
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/ch06/solutions/Pause.java:
--------------------------------------------------------------------------------
1 | package ch06.solutions;
2 |
3 | public class Pause {
4 | public static void main(String args[]) {
5 | System.out.print("Starting... ");
6 | try {
7 | Thread.sleep(5000);
8 | } catch(InterruptedException ie) {
9 | System.out.println("Interrupted!");
10 | }
11 | System.out.println("done");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch06/solutions/severe.properties:
--------------------------------------------------------------------------------
1 | # Set the default logging level
2 | .level = SEVERE
3 | # Direct output to the console
4 | handlers = java.util.logging.ConsoleHandler
5 |
6 |
--------------------------------------------------------------------------------
/ch07/examples/RawType.java:
--------------------------------------------------------------------------------
1 | package ch07.examples;
2 |
3 | import java.util.*;
4 |
5 | public class RawType {
6 | public static void main(String args[]) {
7 | List list = new ArrayList();
8 | list.add("foo");
9 |
10 | String[] sa = {"hi", "there"};
11 | List ls = Arrays.asList(sa);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch07/examples/game/AppleToss.java:
--------------------------------------------------------------------------------
1 | package ch07.examples.game;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * Our apple tossing game. This class extends JFrame to create our
7 | * main application window. We'll be filling this out along the way,
8 | * but for now we can setup a field with some trees and our player.
9 | */
10 | public class AppleToss extends JFrame {
11 |
12 | Field field = new Field();
13 | Physicist player1 = new Physicist();
14 |
15 | public AppleToss() {
16 | // Create our frame
17 | super("Apple Toss Game");
18 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
19 | setSize(800,600);
20 | setResizable(false);
21 |
22 | // Build the field with our player and some trees
23 | setupFieldForOnePlayer();
24 | }
25 |
26 | /**
27 | * A helper method to populate a one player field with target trees.
28 | */
29 | private void setupFieldForOnePlayer() {
30 | // Place our (new) physicist in the lower left corner and connect them to the field
31 | player1.setPosition(100,500);
32 | field.setPlayer(player1);
33 | player1.setField(field);
34 |
35 | // Place our lone hedge
36 | field.setupHedge();
37 |
38 | // And now make a few trees for target practice
39 | for (int row = 1; row <= 2; row++) {
40 | for (int col = 1; col <=3; col++) {
41 | field.addTree(col * 100, row * 100);
42 | }
43 | }
44 | add(field);
45 | }
46 |
47 | public static void main(String args[]) {
48 | AppleToss game = new AppleToss();
49 | game.setVisible(true);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ch07/examples/game/Field.java:
--------------------------------------------------------------------------------
1 | package ch07.examples.game;
2 |
3 | import javax.swing.*;
4 | import java.awt.Color;
5 | import java.awt.Graphics;
6 | import java.util.*;
7 |
8 | /**
9 | * The playing field for our game. Now we can setup some constants for
10 | * other game classes to use and create member variables for our player and some trees.
11 | */
12 | public class Field extends JComponent {
13 | public static final float GRAVITY = 9.8f; // feet per second per second
14 | public static final int STEP = 40; // duration of an animation frame in milliseconds
15 | public static final int APPLE_SIZE_IN_PIXELS = 30;
16 | public static final int TREE_WIDTH_IN_PIXELS = 60;
17 | public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
18 | public static final int PHYSICIST_SIZE_IN_PIXELS = 75;
19 | public static final int MAX_TREES = 12;
20 |
21 | Color fieldColor = Color.LIGHT_GRAY;
22 | Random random = new Random();
23 |
24 | // List and ArrayList are covered in chapter 8 on Generics
25 | // synchronizedArrayList is covered in chapter 9 on Threads
26 | Physicist physicist;
27 | List trees = Collections.synchronizedList(new ArrayList<>());
28 | Hedge hedge = new Hedge();
29 |
30 | protected void paintComponent(Graphics g) {
31 | g.setColor(fieldColor);
32 | g.fillRect(0,0, getWidth(), getHeight());
33 | for (Tree t : trees) {
34 | t.draw(g);
35 | }
36 | hedge.draw(g);
37 | physicist.draw(g);
38 | }
39 |
40 | public void setPlayer(Physicist p) {
41 | physicist = p;
42 | }
43 |
44 | public void setupHedge() {
45 | // Setup our new obstacle similar to the tree
46 | hedge.setPosition(500,200);
47 | }
48 |
49 | public void addTree(int x, int y) {
50 | Tree tree = new Tree();
51 | tree.setPosition(x,y);
52 | trees.add(tree);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/ch07/examples/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch07.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch07/examples/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch07.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color hedgeColor = Color.GREEN.darker();
14 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
15 | private int hedgeHeight = (int)(hedgeWidth / 2);
16 |
17 | // Boundary helpers
18 | private Rectangle boundingBox;
19 |
20 | @Override
21 | public void setPosition(int x, int y) {
22 | this.x = x;
23 | this.y = y;
24 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(hedgeColor);
45 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
46 | }
47 |
48 | @Override
49 | public boolean isTouching(GamePiece otherPiece) {
50 | // We don't really have any collisions to detect yet, so just return "no".
51 | // As we fill out all of the game pieces, we'll come back to this method
52 | // and provide a more useful response.
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch07/examples/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch07.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | if (this == otherPiece) {
57 | // By definition we don't collide with ourselves
58 | return false;
59 | }
60 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch07/exercises/Employee.java:
--------------------------------------------------------------------------------
1 | package ch07.exercises;
2 |
3 | public class Employee {
4 | private Integer id;
5 | private String first;
6 | private String last;
7 |
8 | public Employee(String firstname, String lastname, Integer id) {
9 | this.first = firstname;
10 | this.last = lastname;
11 | this.id = id;
12 | }
13 |
14 | public String getFirstName() { return first; }
15 | public String getLastName() { return last; }
16 | public Integer getID() { return id; }
17 | }
18 |
--------------------------------------------------------------------------------
/ch07/exercises/EmployeeList.java:
--------------------------------------------------------------------------------
1 | package ch07.exercises;
2 |
3 | import java.util.*;
4 |
5 | public class EmployeeList {
6 | public static void main(String args[]) {
7 | Map employees = new HashMap<>();
8 | employees.put(2, new Employee("Plato", "Athens", 2));
9 | employees.put(4, new Employee("Alcibiades", "Athens", 4));
10 | employees.put(27, new Employee("Crito", "Alopece", 27));
11 | employees.put(64, new Employee("Phaedo", "Elis", 64));
12 | employees.put(125, new Employee("Apollodorus", "Phaleron", 125));
13 |
14 | for (Integer id : employees.keySet()) {
15 | Employee e = employees.get(id);
16 | System.out.print("Employee #" + id + " : ");
17 | System.out.println(e.getFirstName() + " " + e.getLastName());
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch07/exercises/game/AppleToss.java:
--------------------------------------------------------------------------------
1 | package ch07.exercises.game;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * Our apple tossing game. This class extends JFrame to create our
7 | * main application window. We'll be filling this out along the way,
8 | * but for now we can setup a field with some trees and our player.
9 | */
10 | public class AppleToss extends JFrame {
11 |
12 | Field field = new Field();
13 | Physicist player1 = new Physicist();
14 |
15 | public AppleToss() {
16 | // Create our frame
17 | super("Apple Toss Game");
18 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
19 | setSize(800,600);
20 | setResizable(false);
21 |
22 | // Build the field with our player and some trees
23 | setupFieldForOnePlayer();
24 | }
25 |
26 | /**
27 | * A helper method to populate a one player field with target trees.
28 | */
29 | private void setupFieldForOnePlayer() {
30 | // Place our (new) physicist in the lower left corner and connect them to the field
31 | player1.setPosition(100,500);
32 | field.setPlayer(player1);
33 | player1.setField(field);
34 |
35 | // Place our lone hedge
36 | field.setupHedge();
37 |
38 | // And now make a few trees for target practice
39 | for (int row = 1; row <= 2; row++) {
40 | for (int col = 1; col <=3; col++) {
41 | field.addTree(col * 100, row * 100);
42 | }
43 | }
44 | add(field);
45 | }
46 |
47 | public static void main(String args[]) {
48 | AppleToss game = new AppleToss();
49 | game.setVisible(true);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ch07/exercises/game/Field.java:
--------------------------------------------------------------------------------
1 | package ch07.exercises.game;
2 |
3 | import javax.swing.*;
4 | import java.awt.Color;
5 | import java.awt.Graphics;
6 | import java.util.*;
7 |
8 | /**
9 | * The playing field for our game. Now we can setup some constants for
10 | * other game classes to use and create member variables for our player and some trees.
11 | */
12 | public class Field extends JComponent {
13 | public static final float GRAVITY = 9.8f; // feet per second per second
14 | public static final int STEP = 40; // duration of an animation frame in milliseconds
15 | public static final int APPLE_SIZE_IN_PIXELS = 30;
16 | public static final int TREE_WIDTH_IN_PIXELS = 60;
17 | public static final int TREE_HEIGHT_IN_PIXELS = 2 * TREE_WIDTH_IN_PIXELS;
18 | public static final int PHYSICIST_SIZE_IN_PIXELS = 75;
19 | public static final int MAX_TREES = 12;
20 |
21 | Color fieldColor = Color.LIGHT_GRAY;
22 | Random random = new Random();
23 |
24 | // List and ArrayList are covered in chapter 8 on Generics
25 | // synchronizedArrayList is covered in chapter 9 on Threads
26 | Physicist physicist;
27 | List trees = Collections.synchronizedList(new ArrayList<>());
28 | Hedge hedge = new Hedge();
29 |
30 | protected void paintComponent(Graphics g) {
31 | g.setColor(fieldColor);
32 | g.fillRect(0,0, getWidth(), getHeight());
33 | for (Tree t : trees) {
34 | t.draw(g);
35 | }
36 | hedge.draw(g);
37 | physicist.draw(g);
38 | }
39 |
40 | public void setPlayer(Physicist p) {
41 | physicist = p;
42 | }
43 |
44 | public void setupHedge() {
45 | // Setup our new obstacle similar to the tree
46 | hedge.setPosition(500,200);
47 | }
48 |
49 | public void addTree(int x, int y) {
50 | Tree tree = new Tree();
51 | tree.setPosition(x,y);
52 | trees.add(tree);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/ch07/exercises/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch07.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch07/exercises/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch07.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color hedgeColor = Color.GREEN.darker();
14 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
15 | private int hedgeHeight = (int)(hedgeWidth / 2);
16 |
17 | // Boundary helpers
18 | private Rectangle boundingBox;
19 |
20 | @Override
21 | public void setPosition(int x, int y) {
22 | this.x = x;
23 | this.y = y;
24 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(hedgeColor);
45 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
46 | }
47 |
48 | @Override
49 | public boolean isTouching(GamePiece otherPiece) {
50 | // We don't really have any collisions to detect yet, so just return "no".
51 | // As we fill out all of the game pieces, we'll come back to this method
52 | // and provide a more useful response.
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch07/exercises/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch07.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | if (this == otherPiece) {
57 | // By definition we don't collide with ourselves
58 | return false;
59 | }
60 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch07/solutions/Employee.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions;
2 |
3 | public class Employee {
4 | private Integer id;
5 | private String first;
6 | private String last;
7 |
8 | public Employee(String firstname, String lastname, Integer id) {
9 | this.first = firstname;
10 | this.last = lastname;
11 | this.id = id;
12 | }
13 |
14 | public String getFirstName() { return first; }
15 | public String getLastName() { return last; }
16 | public Integer getID() { return id; }
17 | }
18 |
--------------------------------------------------------------------------------
/ch07/solutions/Employee2.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions;
2 |
3 | public class Employee2 implements Comparable {
4 | private Integer id;
5 | private String first;
6 | private String last;
7 |
8 | public Employee2(String firstname, String lastname, Integer id) {
9 | this.first = firstname;
10 | this.last = lastname;
11 | this.id = id;
12 | }
13 |
14 | public String getFirstName() { return first; }
15 | public String getLastName() { return last; }
16 | public Integer getID() { return id; }
17 |
18 | public int compareTo(Employee2 other) {
19 | // Let's be a little fancy and sort on a constructed name
20 | String myName = last + ", " + first;
21 | //String otherName = other.getLastName() + ", " + other.getFirstName();
22 | String otherName = other.last + ", " + other.first;
23 | return myName.compareToIgnoreCase(otherName);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ch07/solutions/EmployeeList.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions;
2 |
3 | import java.util.*;
4 |
5 | public class EmployeeList {
6 | public static void main(String args[]) {
7 | Map employees = new HashMap<>();
8 | employees.put(2, new Employee("Plato", "Athens", 2));
9 | employees.put(4, new Employee("Alcibiades", "Athens", 4));
10 | employees.put(27, new Employee("Crito", "Alopece", 27));
11 | employees.put(64, new Employee("Phaedo", "Elis", 64));
12 | employees.put(125, new Employee("Apollodorus", "Phaleron", 125));
13 |
14 | List ids = new ArrayList<>(employees.keySet());
15 | Collections.sort(ids);
16 |
17 | for (Integer id : ids) {
18 | Employee e = employees.get(id);
19 | System.out.print("Employee #" + id + " : ");
20 | System.out.println(e.getFirstName() + " " + e.getLastName());
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch07/solutions/EmployeeList2.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions;
2 |
3 | import java.util.*;
4 |
5 | public class EmployeeList2 {
6 | public static void main(String args[]) {
7 | Map employees = new HashMap<>();
8 | employees.put(2, new Employee2("Plato", "Athens", 2));
9 | employees.put(4, new Employee2("Alcibiades", "Athens", 4));
10 | employees.put(27, new Employee2("Crito", "Alopece", 27));
11 | employees.put(64, new Employee2("Phaedo", "Elis", 64));
12 | employees.put(125, new Employee2("Apollodorus", "Phaleron", 125));
13 |
14 | List es = new ArrayList<>(employees.values());
15 | Collections.sort(es);
16 |
17 | for (Employee2 e : es) {
18 | System.out.print("Employee #" + e.getID() + " : ");
19 | System.out.println(e.getFirstName() + " " + e.getLastName());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch07/solutions/game/AppleToss.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions.game;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * Our apple tossing game. This class extends JFrame to create our
7 | * main application window. We'll be filling this out along the way,
8 | * but for now we can setup a field with some trees and our player.
9 | */
10 | public class AppleToss extends JFrame {
11 |
12 | Field field = new Field();
13 | Physicist player1 = new Physicist();
14 |
15 | public AppleToss() {
16 | // Create our frame
17 | super("Apple Toss Game");
18 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
19 | setSize(800,600);
20 | setResizable(false);
21 |
22 | // Build the field with our player and some trees
23 | setupFieldForOnePlayer();
24 | }
25 |
26 | /**
27 | * A helper method to populate a one player field with target trees.
28 | * Expanded to include setting up hedges as part of Advanced Exercise 1.
29 | */
30 | private void setupFieldForOnePlayer() {
31 | // Place our (new) physicist in the lower left corner and connect them to the field
32 | player1.setPosition(100,500);
33 | field.setPlayer(player1);
34 | player1.setField(field);
35 |
36 | // Make a few trees for target practice
37 | for (int row = 1; row <= 2; row++) {
38 | for (int col = 1; col <=3; col++) {
39 | field.addTree(col * 100, row * 100);
40 | }
41 | }
42 |
43 | // And add one row of hedges similar to the trees
44 | for (int h = 1; h <= 4; h++) {
45 | field.addHedge(h * 80 + 380, 240);
46 | }
47 |
48 | add(field);
49 | }
50 |
51 | public static void main(String args[]) {
52 | AppleToss game = new AppleToss();
53 | game.setVisible(true);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch07/solutions/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch07/solutions/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color hedgeColor = Color.GREEN.darker();
14 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
15 | private int hedgeHeight = (int)(hedgeWidth / 2);
16 |
17 | // Boundary helpers
18 | private Rectangle boundingBox;
19 |
20 | @Override
21 | public void setPosition(int x, int y) {
22 | this.x = x;
23 | this.y = y;
24 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(hedgeColor);
45 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
46 | }
47 |
48 | @Override
49 | public boolean isTouching(GamePiece otherPiece) {
50 | // We don't really have any collisions to detect yet, so just return "no".
51 | // As we fill out all of the game pieces, we'll come back to this method
52 | // and provide a more useful response.
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch07/solutions/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch07.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | if (this == otherPiece) {
57 | // By definition we don't collide with ourselves
58 | return false;
59 | }
60 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch08/examples/ValidEmail.java:
--------------------------------------------------------------------------------
1 | package ch08.examples;
2 |
3 | import java.util.regex.Pattern;
4 |
5 | public class ValidEmail {
6 | static String[] validators = {
7 | ".*@.*",
8 | "[^@]+@[^@]+",
9 | "[^@]+@[^@]+\\.(com|org)",
10 | "[^@]+@[^@]+\\.[a-z]+",
11 | "(?i)[^@]+@[^@]+\\.[a-z]+"
12 | };
13 |
14 | public static void main(String args[]) {
15 | String sample = "my.name@some.domain";
16 | if (args.length == 1) {
17 | // Got one command-line arg, use it as the address to check
18 | sample = args[0];
19 | } else {
20 | System.out.println("Using default email address: " + sample);
21 | System.out.println("To use your own address, provide it as the sole command-line argument.");
22 | }
23 |
24 | // To make pretty output, let's find the longest pattern
25 | int max = 0;
26 | for (String v : validators) {
27 | if (v.length() > max) { max = v.length(); }
28 | }
29 |
30 | // Now let's try each validator and show our result
31 | for (String v : validators) {
32 | System.out.print(sample + " : ");
33 | System.out.print(v + " => ");
34 | for (int s = (max - v.length()); s > 0; s--) {
35 | System.out.print(" ");
36 | }
37 | System.out.println(Pattern.matches(v, sample));
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ch08/examples/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch08.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch08/examples/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch08.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | if (this == otherPiece) {
57 | // By definition we don't collide with ourselves
58 | return false;
59 | }
60 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch08/exercises/HelloChapter8.java:
--------------------------------------------------------------------------------
1 | package ch08.exercises;
2 |
3 | import java.awt.*;
4 | import java.awt.event.*;
5 | import javax.swing.*;
6 |
7 | /**
8 | * Starting with the HelloJava3 class as the basis for this
9 | * new variation. For this exercise, you need to process the
10 | * command-line arguments for the message and its initial
11 | * position on the screen.
12 | */
13 | public class HelloChapter8 extends JFrame {
14 |
15 | public static void main(String[] args) {
16 | String msg = "Hello, utilities!";
17 | int x = 150;
18 | int y = 150;
19 | HelloChapter8 demo = new HelloChapter8(msg, x, y);
20 | demo.setVisible(true);
21 | }
22 |
23 | public HelloChapter8(String msg, int x, int y) {
24 | super("Chapter 8, Exercise 1");
25 | add(new HelloComponent8(msg, x, y));
26 | setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
27 | setSize(300, 300);
28 | }
29 |
30 | class HelloComponent8 extends JComponent {
31 | String theMessage;
32 | int messageX = 125, messageY = 95; // Coordinates of the message
33 |
34 | public HelloComponent8(String message, int x, int y) {
35 | theMessage = message;
36 | messageX = x;
37 | messageY = y;
38 | addMouseMotionListener(new MouseMotionListener() {
39 | public void mouseDragged(MouseEvent e) {
40 | messageX = e.getX();
41 | messageY = e.getY();
42 | repaint();
43 | }
44 |
45 | public void mouseMoved(MouseEvent e) { }
46 | });
47 | }
48 |
49 | public void paintComponent( Graphics g ) {
50 | g.drawString( theMessage, messageX, messageY );
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ch09/examples/Thready.java:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | public class Thready {
4 | public static void main( String args [] ) {
5 | new Thread(new ShowThread("Foo")).start();
6 | new Thread(new ShowThread("Bar")).start();
7 | }
8 |
9 | static class ShowThread implements Runnable {
10 | String message;
11 |
12 | ShowThread( String message ) {
13 | this.message = message;
14 | }
15 | public void run() {
16 | while ( true )
17 | System.out.println( message );
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch09/examples/Thready2.java:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | public class Thready2 {
4 | public static void main( String args [] ) {
5 | Thread foo = new Thread(new ShowThread("Foo"));
6 | foo.setPriority( Thread.MIN_PRIORITY );
7 | Thread bar = new Thread(new ShowThread("Bar"));
8 | bar.setPriority( Thread.MAX_PRIORITY );
9 |
10 | foo.start();
11 | bar.start();
12 | }
13 |
14 | static class ShowThread implements Runnable {
15 | String message;
16 |
17 | ShowThread( String message ) {
18 | this.message = message;
19 | }
20 | public void run() {
21 | while ( true )
22 | System.out.println( message );
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ch09/examples/URLConsumer3.java:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * A threaded client for our URL producer. Uses a synchronized queue
7 | * to safely read a URL for processing. (Our simple demo "processes"
8 | * by printing out the ID of this consumer and the url it consumed.)
9 | *
10 | * This version handles one URL and ends. There is no "keep working"
11 | * flag nor delay.
12 | */
13 | public class URLConsumer3 implements Runnable {
14 | String consumerID;
15 | URLQueue queue;
16 |
17 | /**
18 | * Creates a new consumer with the given ID and reference to the shared queue.
19 | *
20 | * @param id A unique (unenforced) name for this consumer
21 | * @param queue The shared queue for storing and distributing URLs
22 | */
23 | public URLConsumer3(String id, URLQueue queue) {
24 | if (queue == null) {
25 | throw new IllegalArgumentException("Shared queue cannot be null");
26 | }
27 | consumerID = id;
28 | this.queue = queue;
29 | }
30 |
31 | /**
32 | * Our working method for the thread. Watches the boolean flag
33 | * keepWorking as well as the state of the queue to determine
34 | * whether or not to complete the loop. While working, grab a
35 | * URL and print it out then repeat.
36 | */
37 | public void run() {
38 | String url = queue.getURL();
39 | if (url != null) {
40 | if (url.endsWith("0000")) {
41 | System.out.println(consumerID + " consumed " + url);
42 | }
43 | } else {
44 | System.out.println(consumerID + " skipped empty queue");
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ch09/examples/URLDemo.java:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | /**
4 | * Manage multiple producers and consumers to demonstrate how
5 | * threads work in tandem. Creates a pair of producers and a
6 | * pair of consumers all with access to a shared queue.
7 | *
8 | * @see URLQueue
9 | * @see URLProducer
10 | * @see URLConsumer
11 | */
12 | public class URLDemo {
13 | public static void main(String args[]) {
14 | // Create our shared queue object
15 | URLQueue queue = new URLQueue();
16 |
17 | // Now create some producers with unique names and a reference to our queue
18 | URLProducer p1 = new URLProducer("P1", 3, queue);
19 | URLProducer p2 = new URLProducer("P2", 3, queue);
20 |
21 | // And some consumers with their own names and a reference to our queue
22 | URLConsumer c1 = new URLConsumer("C1", queue);
23 | URLConsumer c2 = new URLConsumer("C2", queue);
24 |
25 | // Get everyone going!
26 | System.out.println("Starting...");
27 | Thread tp1 = new Thread(p1);
28 | tp1.start();
29 | Thread tp2 = new Thread(p2);
30 | tp2.start();
31 | Thread tc1 = new Thread(c1);
32 | tc1.start();
33 | Thread tc2 = new Thread(c2);
34 | tc2.start();
35 |
36 | // First wait around for the producers to finish
37 | try {
38 | tp1.join();
39 | tp2.join();
40 | } catch (InterruptedException ie) {
41 | System.err.println("Interrupted waiting for producers to finish");
42 | }
43 |
44 | // OK, we know there won't be any more URLs made, so let the consumers
45 | // finish once the queue is empty
46 | c1.setKeepWorking(false);
47 | c2.setKeepWorking(false);
48 | try {
49 | tc1.join();
50 | tc2.join();
51 | } catch (InterruptedException ie) {
52 | System.err.println("Interrupted waiting for consumers to finish");
53 | }
54 |
55 | System.out.println("Done");
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ch09/examples/URLDemo2.java.preview:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | /**
4 | * Manage multiple producers and consumers to demonstrate how
5 | * threads work in tandem. Creates a pair of producers and a
6 | * pair of consumers all with access to a shared queue.
7 | *
8 | * This version uses virtual threads rather than the platform
9 | * threads in URLDemo.java
10 | *
11 | * @see URLQueue
12 | * @see URLProducer
13 | * @see URLConsumer
14 | */
15 | public class URLDemo2 {
16 | public static void main(String args[]) {
17 | // Create our shared queue object
18 | URLQueue queue = new URLQueue();
19 |
20 | // Now create some producers with unique names and a reference to our queue
21 | URLProducer p1 = new URLProducer("P1", 3, queue);
22 | URLProducer p2 = new URLProducer("P2", 3, queue);
23 |
24 | // And some consumers with their own names and a reference to our queue
25 | URLConsumer c1 = new URLConsumer("C1", queue);
26 | URLConsumer c2 = new URLConsumer("C2", queue);
27 |
28 | // Get everyone going!
29 | System.out.println("Starting virtual threads...");
30 | Thread vp1 = Thread.startVirtualThread(p1);
31 | Thread vp2 = Thread.startVirtualThread(p2);
32 | Thread vc1 = Thread.startVirtualThread(c1);
33 | Thread vc2 = Thread.startVirtualThread(c2);
34 |
35 | // First wait around for the producers to finish
36 | try {
37 | vp1.join();
38 | vp2.join();
39 | } catch (InterruptedException ie) {
40 | System.err.println("Interrupted waiting for producers to finish");
41 | }
42 |
43 | // OK, we know there won't be any more URLs made, so let the consumers
44 | // finish once the queue is empty
45 | c1.setKeepWorking(false);
46 | c2.setKeepWorking(false);
47 | try {
48 | vc1.join();
49 | vc2.join();
50 | } catch (InterruptedException ie) {
51 | System.err.println("Interrupted waiting for consumers to finish");
52 | }
53 |
54 | System.out.println("Done");
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ch09/examples/URLProducer.java:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * Simple producer for use in our multithreaded example.
7 | * Uses a synchronized queue to safely store URLs for processing.
8 | */
9 | public class URLProducer implements Runnable {
10 | String producerID;
11 | int urlCount;
12 | URLQueue queue;
13 |
14 | Random delay;
15 |
16 | /**
17 | * Create a new producer with the given name. It will produce the
18 | * specified number of URLs and store them in the provided queue.
19 | *
20 | * @param id A unique (unenforced) name for this producer
21 | * @param count How many URLs this producer will create before quitting
22 | * @param queue The shared, synchronized queue for URLs
23 | */
24 | public URLProducer(String id, int count, URLQueue queue) {
25 | // Don't even create this producer if a negative count was supplied or there's no queue
26 | if (count <= 0) {
27 | throw new IllegalArgumentException("Count must be positive");
28 | }
29 | if (queue == null) {
30 | throw new IllegalArgumentException("Shared queue cannot be null");
31 | }
32 | producerID = id;
33 | urlCount = count;
34 | this.queue = queue;
35 | delay = new Random();
36 | }
37 |
38 | /**
39 | * Our working method for the thread. Uses the count supplied to
40 | * the constructor to produce a batch of URLs and store them to
41 | * the shared queue. To make it a little more interesting, a random
42 | * delay is added at the end of each iteration.
43 | */
44 | public void run() {
45 | for (int i = 1; i <= urlCount; i++) {
46 | String url = "https://some.url/at/path/" + i;
47 | queue.addURL(producerID + " " + url);
48 | System.out.println(producerID + " produced " + url);
49 | try {
50 | Thread.sleep(delay.nextInt(500));
51 | } catch (InterruptedException ie) {
52 | System.err.println("Producer " + producerID + " interrupted. Quitting.");
53 | break;
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ch09/examples/URLProducer4.java:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | import java.util.Random;
4 | import java.util.Queue;
5 |
6 | /**
7 | * Simple producer for use in our multithreaded example.
8 | * Uses a synchronized queue to safely store URLs for processing.
9 | */
10 | public class URLProducer4 implements Runnable {
11 | String producerID;
12 | int urlCount;
13 | Queue queue;
14 |
15 | Random delay;
16 |
17 | /**
18 | * Create a new producer with the given name. It will produce the
19 | * specified number of URLs and store them in the provided queue.
20 | *
21 | * @param id A unique (unenforced) name for this producer
22 | * @param count How many URLs this producer will create before quitting
23 | * @param queue The shared, synchronized queue for URLs
24 | */
25 | public URLProducer4(String id, int count, Queue queue) {
26 | // Don't even create this producer if a negative count was supplied or there's no queue
27 | if (count <= 0) {
28 | throw new IllegalArgumentException("Count must be positive");
29 | }
30 | if (queue == null) {
31 | throw new IllegalArgumentException("Shared queue cannot be null");
32 | }
33 | producerID = id;
34 | urlCount = count;
35 | this.queue = queue;
36 | delay = new Random();
37 | }
38 |
39 | /**
40 | * Our working method for the thread. Uses the count supplied to
41 | * the constructor to produce a batch of URLs and store them to
42 | * the shared queue. To make it a little more interesting, a random
43 | * delay is added at the end of each iteration.
44 | */
45 | public void run() {
46 | for (int i = 1; i <= urlCount; i++) {
47 | String url = "https://some.url/at/path/" + i;
48 | queue.add(producerID + " " + url);
49 | System.out.println(producerID + " produced " + url);
50 | try {
51 | Thread.sleep(delay.nextInt(500));
52 | } catch (InterruptedException ie) {
53 | System.err.println("Producer " + producerID + " interrupted. Quitting.");
54 | break;
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ch09/examples/URLQueue.java:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | import java.util.LinkedList;
4 |
5 | /**
6 | * A manually synchronized wrapper for a LinkedList.
7 | * Allows for safely adding and removing URLs in order.
8 | */
9 | public class URLQueue {
10 | LinkedList urlQueue = new LinkedList<>();
11 |
12 | public synchronized void addURL(String url) {
13 | urlQueue.add(url);
14 | }
15 |
16 | public synchronized String getURL() {
17 | if (!urlQueue.isEmpty()) {
18 | return urlQueue.removeFirst();
19 | }
20 | return null;
21 | }
22 |
23 | public boolean isEmpty() {
24 | return urlQueue.isEmpty();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ch09/examples/VirtualDemo.java.preview:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | public class VirtualDemo {
4 | public static void main(String args[]) throws Exception {
5 | Runnable runnable = () -> System.out.println("Hello virtual thread! ID: " + Thread.currentThread().threadId());
6 | Thread thread = Thread.startVirtualThread(runnable);
7 | thread.join();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ch09/examples/VirtualDemo2.java.preview:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | public class VirtualDemo2 {
4 | public static void main(String args[]) throws Exception {
5 | Runnable runnable = new Runnable() {
6 | public void run() {
7 | Thread t = Thread.currentThread();
8 | System.out.println("Hello thread! " +
9 | (t.isVirtual() ? "virtual " : "platform ") +
10 | "ID: " + t.threadId());
11 | }
12 | };
13 | Thread thread1 = new Thread(runnable);
14 | thread1.start();
15 | Thread thread2 = Thread.startVirtualThread(runnable);
16 | thread1.join();
17 | thread2.join();
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/ch09/examples/VirtualThready.java.preview:
--------------------------------------------------------------------------------
1 | package ch09.examples;
2 |
3 | public class VirtualThready {
4 | public static void main( String args [] ) throws InterruptedException {
5 | Thread t1 = Thread.startVirtualThread(new ShowThread("VFoo"));
6 | Thread t2 = Thread.startVirtualThread(new ShowThread("VBar"));
7 | t1.join();
8 | t2.join();
9 | }
10 |
11 | static class ShowThread implements Runnable {
12 | String message;
13 |
14 | ShowThread( String message ) {
15 | this.message = message;
16 | }
17 | public void run() {
18 | while ( true )
19 | System.out.println( message );
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch09/exercises/Clock.java:
--------------------------------------------------------------------------------
1 | package ch09.exercises;
2 |
3 | import java.awt.*;
4 | import javax.swing.*;
5 |
6 | public class Clock extends JFrame {
7 | JLabel clockLabel;
8 |
9 | public Clock() {
10 | super("Java Clock");
11 | setSize(400,200);
12 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
13 | clockLabel = new JLabel("00:00:00", JLabel.CENTER);
14 | clockLabel.setFont(new Font("Arial", Font.BOLD, 24));
15 | getContentPane().add(clockLabel, BorderLayout.CENTER);
16 | }
17 |
18 | public void startClock() {
19 | // Set up your thread here. It should sleep for one second
20 | // and then update the text in clockLabel.
21 | }
22 |
23 | public static void main(String args[]) {
24 | Clock c = new Clock();
25 | c.setVisible(true);
26 | c.startClock();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ch09/exercises/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch09.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch09/exercises/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch09.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color hedgeColor = Color.GREEN.darker();
14 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
15 | private int hedgeHeight = (int)(hedgeWidth / 2);
16 |
17 | // Boundary helpers
18 | private Rectangle boundingBox;
19 |
20 | @Override
21 | public void setPosition(int x, int y) {
22 | this.x = x;
23 | this.y = y;
24 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(hedgeColor);
45 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
46 | }
47 |
48 | @Override
49 | public boolean isTouching(GamePiece otherPiece) {
50 | // We don't really have any collisions to detect yet, so just return "no".
51 | // As we fill out all of the game pieces, we'll come back to this method
52 | // and provide a more useful response.
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch09/exercises/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch09.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | if (this == otherPiece) {
57 | // By definition we don't collide with ourselves
58 | return false;
59 | }
60 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch09/solutions/Clock.java:
--------------------------------------------------------------------------------
1 | package ch09.solutions;
2 |
3 | import java.awt.*;
4 | import javax.swing.*;
5 | import java.time.LocalTime;
6 | import java.time.format.DateTimeFormatter;
7 |
8 | public class Clock extends JFrame {
9 | JLabel clockLabel;
10 | Thread runner;
11 | DateTimeFormatter hms = DateTimeFormatter.ofPattern("hh:mm:ss");
12 |
13 | public Clock() {
14 | super("Java Clock");
15 | setSize(400,200);
16 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
17 | clockLabel = new JLabel("00:00:00", JLabel.CENTER);
18 | clockLabel.setFont(new Font("Arial", Font.BOLD, 24));
19 | getContentPane().add(clockLabel, BorderLayout.CENTER);
20 | }
21 |
22 | public void startClock() {
23 | runner = new Thread(new Runnable() {
24 | public void run() {
25 | while (true) {
26 | String time = hms.format(LocalTime.now());
27 | clockLabel.setText(time);
28 | clockLabel.repaint();
29 | try {
30 | Thread.sleep(1000);
31 | } catch (InterruptedException ie) {
32 | clockLabel.setText("--:--:--");
33 | break;
34 | }
35 | }
36 | }
37 | });
38 | runner.start();
39 | }
40 |
41 | public static void main(String args[]) {
42 | Clock c = new Clock();
43 | c.setVisible(true);
44 | c.startClock();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/ch09/solutions/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch09.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch09/solutions/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch09.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color hedgeColor = Color.GREEN.darker();
14 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
15 | private int hedgeHeight = (int)(hedgeWidth / 2);
16 |
17 | // Boundary helpers
18 | private Rectangle boundingBox;
19 |
20 | @Override
21 | public void setPosition(int x, int y) {
22 | this.x = x;
23 | this.y = y;
24 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(hedgeColor);
45 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
46 | }
47 |
48 | @Override
49 | public boolean isTouching(GamePiece otherPiece) {
50 | // We don't really have any collisions to detect yet, so just return "no".
51 | // As we fill out all of the game pieces, we'll come back to this method
52 | // and provide a more useful response.
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch09/solutions/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch09.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 | int x, y;
11 |
12 | // Drawing helpers
13 | private Color leafColor = Color.GREEN.darker();
14 | private Color trunkColor = new Color(101, 67, 33);
15 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
16 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
17 | private int trunkX, trunkY;
18 |
19 | // Boundary helpers
20 | private Rectangle boundingBox;
21 |
22 | @Override
23 | public void setPosition(int x, int y) {
24 | this.x = x;
25 | this.y = y;
26 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
27 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
28 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
29 | }
30 |
31 | @Override
32 | public int getPositionX() {
33 | return x;
34 | }
35 |
36 | @Override
37 | public int getPositionY() {
38 | return y;
39 | }
40 |
41 | @Override
42 | public Rectangle getBoundingBox() {
43 | return boundingBox;
44 | }
45 |
46 | @Override
47 | public void draw(Graphics g) {
48 | g.setColor(trunkColor);
49 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
50 | g.setColor(leafColor);
51 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
52 | }
53 |
54 | @Override
55 | public boolean isTouching(GamePiece otherPiece) {
56 | if (this == otherPiece) {
57 | // By definition we don't collide with ourselves
58 | return false;
59 | }
60 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/ch10/examples/ListIt.java:
--------------------------------------------------------------------------------
1 | package ch10.examples;
2 |
3 | import java.io.*;
4 |
5 | /**
6 | * A quick demo of file and directory operations. If the file
7 | * exists and is a directory, the directory gets listed. If it
8 | * is a readable file, the content is dumped to the console.
9 | */
10 | public class ListIt {
11 | public static void main ( String args[] ) throws Exception {
12 | File file = new File( args[0] );
13 |
14 | if ( !file.exists() || !file.canRead( ) ) {
15 | System.out.println( "Can't read " + file );
16 | return;
17 | }
18 |
19 | if ( file.isDirectory( ) ) {
20 | String [] files = file.list( );
21 | for (int i=0; i< files.length; i++)
22 | System.out.println( files[i] );
23 | }
24 | else
25 | try {
26 | Reader ir = new InputStreamReader( new FileInputStream( file ) );
27 | BufferedReader in = new BufferedReader( ir );
28 | String line;
29 | while ((line = in.readLine( )) != null)
30 | System.out.println(line);
31 | }
32 | catch ( FileNotFoundException e ) {
33 | System.out.println( "File Disappeared" );
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ch10/examples/ParseKeyboard.java:
--------------------------------------------------------------------------------
1 | package ch10.examples;
2 |
3 | import java.io.*;
4 | import java.text.*;
5 |
6 | public class ParseKeyboard {
7 | public static void main(String args[]) {
8 | try {
9 | System.out.println("Enter a line starting with a number:");
10 |
11 | InputStream in = System.in;
12 | InputStreamReader charsIn = new InputStreamReader( in );
13 | BufferedReader bufferedCharsIn = new BufferedReader( charsIn );
14 |
15 | String line = bufferedCharsIn.readLine();
16 | int i = NumberFormat.getInstance().parse( line ).intValue();
17 |
18 | System.out.println("Read line: " + line);
19 | System.out.println("Parsed number: " + i);
20 | bufferedCharsIn.close();
21 | } catch ( IOException e ) {
22 | System.err.println("Error reading data: " + e);
23 | } catch ( ParseException pe ) {
24 | System.err.println("Error parsing data: " + pe);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch10/examples/access.txt:
--------------------------------------------------------------------------------
1 | This file has been accessed 5 times.
2 |
--------------------------------------------------------------------------------
/ch10/exercises/Count.java:
--------------------------------------------------------------------------------
1 | package ch10.exercises;
2 |
3 | import java.io.*;
4 |
5 | public class Count {
6 | String fileToCount;
7 |
8 | public Count(String fileToCount) {
9 | this.fileToCount = fileToCount;
10 | // ...
11 | }
12 |
13 | public void printStats() {
14 | System.out.println("Analyzing " + fileToCount);
15 | // ...
16 | }
17 |
18 | public static void main(String args[]) {
19 | // Check for a filename argument; if it's missing, print an error
20 | // ...
21 |
22 | // Create a new instance of Count with the given file and get its stats
23 | Count c = new Count(args[0]);
24 | c.printStats();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ch10/solutions/Count1.java:
--------------------------------------------------------------------------------
1 | package ch10.solutions;
2 |
3 | import java.io.*;
4 |
5 | public class Count1 {
6 | File toCount;
7 |
8 | public Count1(String fileToCount) {
9 | toCount = new File(fileToCount);
10 | }
11 |
12 | public void printStats() {
13 | System.out.println("Analyzing " + toCount.getName());
14 | if (toCount.exists()) {
15 | System.out.println(" Size: " + toCount.length() + " bytes");
16 | } else {
17 | System.out.println(" (Not found)");
18 | }
19 | }
20 |
21 | public static void main(String args[]) {
22 | // Check for a filename argument; if it's missing, print an error
23 | if (args.length != 1) {
24 | System.err.println("Must supply one filename to analyze.");
25 | System.exit(1);
26 | }
27 |
28 | // Create a new instance of Count with the given file and get its stats
29 | Count1 c = new Count1(args[0]);
30 | c.printStats();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ch10/solutions/Count2.java:
--------------------------------------------------------------------------------
1 | package ch10.solutions;
2 |
3 | import java.io.*;
4 |
5 | public class Count2 {
6 | File toCount;
7 | long lineCount;
8 | long wordCount;
9 |
10 | public Count2(String fileToCount) {
11 | toCount = new File(fileToCount);
12 | }
13 |
14 | public void printStats() {
15 | System.out.println("Analyzing " + toCount.getName());
16 | if (toCount.canRead()) {
17 | System.out.println(" Size: " + toCount.length() + " bytes");
18 | try (BufferedReader br = new BufferedReader(new FileReader(toCount))) {
19 | String line = null;
20 | while ((line = br.readLine()) != null) {
21 | lineCount++;
22 | String words[] = line.split("\\s+");
23 | wordCount += words.length;
24 | }
25 | System.out.println(" Lines: " + lineCount);
26 | System.out.println(" Words: " + wordCount);
27 | } catch (IOException ioe) {
28 | System.err.println("Failed to complete the analysis: " + ioe);
29 | ioe.printStackTrace(System.err);
30 | }
31 | } else {
32 | // Hmm, two possible reasons we can't read the file:
33 | // either it doesn't exist, or it exists but we don't have permission
34 | if (toCount.exists()) {
35 | System.out.println(" (No permission)");
36 | } else {
37 | System.out.println(" (Not found)");
38 | }
39 | }
40 | }
41 |
42 | public static void main(String args[]) {
43 | // Check for a filename argument; if it's missing, print an error
44 | if (args.length != 1) {
45 | System.err.println("Must supply one filename to analyze.");
46 | System.exit(1);
47 | }
48 |
49 | // Create a new instance of Count with the given file and get its stats
50 | Count2 c = new Count2(args[0]);
51 | c.printStats();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ch10/solutions/Count3.java:
--------------------------------------------------------------------------------
1 | package ch10.solutions;
2 |
3 | import java.util.List;
4 | import java.io.IOException;
5 | import java.nio.file.Path;
6 | import java.nio.file.Files;
7 |
8 | public class Count3 {
9 | Path toCount;
10 | long lineCount;
11 | long wordCount;
12 |
13 | public Count3(String fileToCount) {
14 | toCount = Path.of(fileToCount);
15 | }
16 |
17 | public void printStats() {
18 | System.out.println("Analyzing " + toCount.getFileName());
19 | try {
20 | if (Files.isReadable(toCount)) {
21 | System.out.println(" Size: " + Files.size(toCount) + " bytes");
22 | List lines = Files.readAllLines(toCount);
23 | for (String line : lines) {
24 | lineCount++;
25 | String words[] = line.split("\\s+");
26 | wordCount += words.length;
27 | }
28 | System.out.println(" Lines: " + lineCount);
29 | System.out.println(" Words: " + wordCount);
30 | } else {
31 | // Hmm, two possible reasons we can't read the file:
32 | // either it doesn't exist, or it exists but we don't have permission
33 | if (Files.exists(toCount)) {
34 | System.out.println(" (No permission)");
35 | } else {
36 | System.out.println(" (Not found)");
37 | }
38 | }
39 | } catch (IOException ioe) {
40 | System.err.println("Failed to complete the analysis: " + ioe);
41 | ioe.printStackTrace(System.err);
42 | }
43 | }
44 |
45 | public static void main(String args[]) {
46 | // Check for a filename argument; if it's missing, print an error
47 | if (args.length != 1) {
48 | System.err.println("Must supply one filename to analyze.");
49 | System.exit(1);
50 | }
51 |
52 | // Create a new instance of Count with the given file and get its stats
53 | Count3 c = new Count3(args[0]);
54 | c.printStats();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ch10/solutions/countlog.txt:
--------------------------------------------------------------------------------
1 | 2023-01-23 02:49:59 Count4.java 108 490 3526
2 | 2023-01-23 02:50:36 ListIt.java 36 178 1011
3 |
--------------------------------------------------------------------------------
/ch11/examples/Adjuster.java:
--------------------------------------------------------------------------------
1 | package ch11.examples;
2 |
3 | import java.util.function.DoubleUnaryOperator;
4 |
5 | public class Adjuster {
6 | public static double adjust(double val, DoubleUnaryOperator adjustment) {
7 | return adjustment.applyAsDouble(val);
8 | }
9 |
10 | public static void main(String args[]) {
11 | double sample = 70.2;
12 | System.out.println("Initial reading: " + sample);
13 | System.out.print("Adding 3: ");
14 | System.out.println(adjust(sample, s -> s + 3));
15 | System.out.print("Reducing by 10%: ");
16 | System.out.println(adjust(sample, s -> s * 0.9));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch11/examples/PaidEmployee.java:
--------------------------------------------------------------------------------
1 | package ch11.examples;
2 |
3 | public class PaidEmployee {
4 | private int id;
5 | private String name;
6 | private int salary; // annual, in whole dollars
7 |
8 | public PaidEmployee(String fullname, int id, int salary) {
9 | this.name = fullname;
10 | this.id = id;
11 | this.salary = salary;
12 | }
13 |
14 | public String getName() { return name; }
15 | public int getID() { return id; }
16 | public int getSalary() { return salary; }
17 | }
18 |
--------------------------------------------------------------------------------
/ch11/examples/Report.java:
--------------------------------------------------------------------------------
1 | package ch11.examples;
2 |
3 | import java.util.*;
4 |
5 | public class Report {
6 | List employees = new ArrayList<>();
7 |
8 | void buildEmployeeList() {
9 | employees.add(new PaidEmployee("Fozzi", 4, 30_000));
10 | employees.add(new PaidEmployee("Gonzo", 2, 50_000));
11 | employees.add(new PaidEmployee("Kermit", 1, 60_000));
12 | employees.add(new PaidEmployee("Piggy", 3, 80_000));
13 | }
14 |
15 | public void publishNames() {
16 | employees.stream().map(e -> e.getName()).forEach(System.out::println);
17 | }
18 |
19 | public void publishBudget() {
20 | int b = employees.stream().mapToInt(e -> e.getSalary()).sum();
21 | System.out.println("Annual bugdet is " + b);
22 | }
23 |
24 | public static void main(String args[]) {
25 | Report r = new Report();
26 | r.buildEmployeeList();
27 | r.publishNames();
28 | r.publishBudget();
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/ch11/examples/VirtualDemo2.java.preview:
--------------------------------------------------------------------------------
1 | package ch11.examples;
2 |
3 | public class VirtualDemo2 {
4 | public static void main(String args[]) throws Exception {
5 | Runnable runnable = new Runnable() {
6 | public void run() {
7 | System.out.println("Hello thread! " +
8 | "ID: " + Thread.currentThread().threadId());
9 | }
10 | };
11 | Thread t = Thread.startVirtualThread(runnable);
12 | t.join();
13 | }
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/ch11/examples/VirtualDemo3.java.preview:
--------------------------------------------------------------------------------
1 | package ch11.examples;
2 |
3 | public class VirtualDemo3 {
4 | public static void main(String args[]) throws Exception {
5 | Thread t = Thread.startVirtualThread( () ->
6 | System.out.println("Hello thread! " +
7 | "ID: " + Thread.currentThread().threadId())
8 | );
9 | t.join();
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/ch11/examples/WeekDayGenerator.java:
--------------------------------------------------------------------------------
1 | package ch11.examples;
2 |
3 | import java.util.Random;
4 | import java.util.stream.Stream;
5 | import java.util.function.Supplier;
6 |
7 | public class WeekDayGenerator implements Supplier {
8 | private static String[] days = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
9 | private Random randSrc = new Random();
10 |
11 | public String get() {
12 | return days[randSrc.nextInt(days.length)];
13 | }
14 |
15 | public static void main(String args[]) {
16 | Stream.generate(new WeekDayGenerator())
17 | .limit(5)
18 | .forEach(System.out::println);
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/ch11/exercises/Adjuster.java:
--------------------------------------------------------------------------------
1 | package ch11.exercises;
2 |
3 | import java.util.function.DoubleUnaryOperator;
4 |
5 | public class Adjuster {
6 | public static double adjust(double val, DoubleUnaryOperator adjustment) {
7 | return adjustment.applyAsDouble(val);
8 | }
9 |
10 | public static void main(String args[]) {
11 | double sample = 70.2;
12 | System.out.println("Initial reading: " + sample);
13 | System.out.print("Adding 3: ");
14 | System.out.println(adjust(sample, s -> s + 3));
15 | System.out.print("Reducing by 10%: ");
16 | System.out.println(adjust(sample, s -> s * 0.9));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch11/exercises/PaidEmployee.java:
--------------------------------------------------------------------------------
1 | package ch11.exercises;
2 |
3 | public class PaidEmployee {
4 | private int id;
5 | private String name;
6 | private int salary; // annual, in whole dollars
7 |
8 | public PaidEmployee(String fullname, int id, int salary) {
9 | this.name = fullname;
10 | this.id = id;
11 | this.salary = salary;
12 | }
13 |
14 | public String getName() { return name; }
15 | public int getID() { return id; }
16 | public int getSalary() { return salary; }
17 | }
18 |
--------------------------------------------------------------------------------
/ch11/exercises/Report.java:
--------------------------------------------------------------------------------
1 | package ch11.exercises;
2 |
3 | import java.util.*;
4 |
5 | public class Report {
6 | List employees = new ArrayList<>();
7 |
8 | void buildEmployeeList() {
9 | employees.add(new PaidEmployee("Fozzi", 4, 30_000));
10 | employees.add(new PaidEmployee("Gonzo", 2, 50_000));
11 | employees.add(new PaidEmployee("Kermit", 1, 60_000));
12 | employees.add(new PaidEmployee("Piggy", 3, 80_000));
13 | }
14 |
15 | public void publishNames() {
16 | employees.stream().map(e -> e.getName()).forEach(System.out::println);
17 | }
18 |
19 | public void publishBudget() {
20 | int b = employees.stream().mapToInt(e -> e.getSalary()).sum();
21 | System.out.println("Annual bugdet is " + b);
22 | }
23 |
24 | public static void main(String args[]) {
25 | Report r = new Report();
26 | r.buildEmployeeList();
27 | r.publishNames();
28 | r.publishBudget();
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/ch11/solutions/Adjuster.java:
--------------------------------------------------------------------------------
1 | package ch11.solutions;
2 |
3 | import java.util.function.DoubleUnaryOperator;
4 |
5 | public class Adjuster {
6 | public static double adjust(double val, DoubleUnaryOperator adjustment) {
7 | return adjustment.applyAsDouble(val);
8 | }
9 |
10 | public static void main(String args[]) {
11 | double sample = 70.2;
12 | System.out.println("Initial reading: " + sample);
13 | System.out.print("Adding 3: ");
14 | System.out.println(adjust(sample, s -> s + 3));
15 | System.out.print("Reducing by 10%: ");
16 | System.out.println(adjust(sample, s -> s * 0.9));
17 | System.out.print("Converting to Celsius: ");
18 | System.out.println(adjust(sample, s -> (s - 32) * 5 / 9));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch11/solutions/PaidEmployee.java:
--------------------------------------------------------------------------------
1 | package ch11.solutions;
2 |
3 | public class PaidEmployee {
4 | private int id;
5 | private String name;
6 | private int salary; // annual, in whole dollars
7 |
8 | public PaidEmployee(String fullname, int id, int salary) {
9 | this.name = fullname;
10 | this.id = id;
11 | this.salary = salary;
12 | }
13 |
14 | public String getName() { return name; }
15 | public int getID() { return id; }
16 | public int getSalary() { return salary; }
17 | }
18 |
--------------------------------------------------------------------------------
/ch11/solutions/PaidEmployee2.java:
--------------------------------------------------------------------------------
1 | package ch11.solutions;
2 |
3 | public class PaidEmployee2 {
4 | private int id;
5 | private String name;
6 | private int salary; // annual, in whole dollars
7 | private String role;
8 |
9 | public PaidEmployee2(String fullname, int id, int salary, String role) {
10 | this.name = fullname;
11 | this.id = id;
12 | this.salary = salary;
13 | this.role = role;
14 | }
15 |
16 | public String getName() { return name; }
17 | public int getID() { return id; }
18 | public int getSalary() { return salary; }
19 | public String getRole() { return role; }
20 | }
21 |
--------------------------------------------------------------------------------
/ch11/solutions/Report.java:
--------------------------------------------------------------------------------
1 | package ch11.solutions;
2 |
3 | import java.util.*;
4 |
5 | public class Report {
6 | List employees = new ArrayList<>();
7 |
8 | void buildEmployeeList() {
9 | employees.add(new PaidEmployee("Fozzi", 4, 30_000));
10 | employees.add(new PaidEmployee("Gonzo", 2, 50_000));
11 | employees.add(new PaidEmployee("Kermit", 1, 60_000));
12 | employees.add(new PaidEmployee("Piggy", 3, 80_000));
13 | }
14 |
15 | public void publishNames() {
16 | employees.stream().map(e -> e.getName()).forEach(System.out::println);
17 | }
18 |
19 | public void publishBudget() {
20 | int b = employees.stream().mapToInt(e -> e.getSalary()).sum();
21 | System.out.println("Annual bugdet is " + b);
22 | }
23 |
24 | public void publishAverage() {
25 | OptionalDouble avg = employees.stream().mapToInt(e -> e.getSalary()).average();
26 | if (avg.isPresent()) {
27 | System.out.println("Average salary is " + avg.getAsDouble());
28 | } else {
29 | System.out.println("No salaries were available.");
30 | }
31 | }
32 |
33 | public static void main(String args[]) {
34 | Report r = new Report();
35 | r.buildEmployeeList();
36 | r.publishNames();
37 | r.publishBudget();
38 | r.publishAverage();
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/ch12/examples/ActionDemo1.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 | import java.awt.event.ActionEvent;
6 | import java.awt.event.ActionListener;
7 |
8 | /**
9 | * A simple, classic demonstration of event handling. Create a frame
10 | * with a button and a label. As the button is pressed, a counter
11 | * shown in the label is incremented.
12 | */
13 | public class ActionDemo1 extends JFrame implements ActionListener {
14 | int counterValue = 0;
15 | JLabel counterLabel;
16 |
17 | public ActionDemo1() {
18 | super( "ActionEvent Counter Demo" );
19 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
20 | setLayout(new FlowLayout());
21 | setSize( 300, 180 );
22 |
23 | counterLabel = new JLabel("Count: 0", JLabel.CENTER );
24 | add(counterLabel);
25 |
26 | JButton incrementer = new JButton("Increment");
27 | incrementer.addActionListener(this);
28 | add(incrementer);
29 | }
30 |
31 | public void actionPerformed(ActionEvent e) {
32 | counterValue++;
33 | counterLabel.setText("Count: " + counterValue);
34 | }
35 |
36 | public static void main( String[] args ) {
37 | ActionDemo1 demo = new ActionDemo1();
38 | demo.setVisible(true);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ch12/examples/ActionDemo2.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 | import java.awt.event.ActionEvent;
6 | import java.awt.event.ActionListener;
7 |
8 | /**
9 | * A simple, classic demonstration of event handling. Create a frame
10 | * with a button and a label. As the button is pressed, a counter
11 | * shown in the label is incremented.
12 | *
13 | * This second variation uses a separate class to handle the action
14 | * events rather than implementing the ActionListener interface
15 | * directly as in ActionDemo1.
16 | */
17 | public class ActionDemo2 {
18 | public static void main( String[] args ) {
19 | JFrame frame = new JFrame( "ActionListener Demo" );
20 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21 | frame.setLayout(new FlowLayout());
22 | frame.setSize( 300, 180 );
23 |
24 | JLabel label = new JLabel("Results go here", JLabel.CENTER );
25 | ActionCommandHelper helper = new ActionCommandHelper(label);
26 |
27 | JButton simpleButton = new JButton("Button");
28 | simpleButton.addActionListener(helper);
29 |
30 | JTextField simpleField = new JTextField(10);
31 | simpleField.addActionListener(helper);
32 |
33 | frame.add(simpleButton);
34 | frame.add(simpleField);
35 | frame.add(label);
36 |
37 | frame.setVisible( true );
38 | }
39 | }
40 |
41 | /**
42 | * Helper class to show the command property of any ActionEvent in a given label.
43 | */
44 | class ActionCommandHelper implements ActionListener {
45 | JLabel resultLabel;
46 |
47 | public ActionCommandHelper(JLabel label) {
48 | resultLabel = label;
49 | }
50 |
51 | public void actionPerformed(ActionEvent ae) {
52 | resultLabel.setText(ae.getActionCommand());
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/ch12/examples/BorderLayoutDemo.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import java.awt.*;
4 | import javax.swing.*;
5 |
6 | /**
7 | * A basic demonstration of the BorderLayout with higlighted
8 | * areas in different colors.
9 | */
10 | public class BorderLayoutDemo {
11 | public static void main( String[] args ) {
12 | JFrame frame = new JFrame("BorderLayout Demo");
13 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
14 | frame.setSize(400, 200);
15 |
16 | JLabel northLabel = new JLabel("Top - North", JLabel.CENTER);
17 | JLabel southLabel = new JLabel("Bottom - South", JLabel.CENTER);
18 | JLabel eastLabel = new JLabel("Right - East", JLabel.CENTER);
19 | JLabel westLabel = new JLabel("Left - West", JLabel.CENTER);
20 | JLabel centerLabel = new JLabel("Center (everything else)", JLabel.CENTER);
21 |
22 | // Color the labels so we can see their boundaries better
23 | northLabel.setOpaque(true);
24 | northLabel.setBackground(Color.GREEN);
25 | southLabel.setOpaque(true);
26 | southLabel.setBackground(Color.GREEN);
27 | eastLabel.setOpaque(true);
28 | eastLabel.setBackground(Color.RED);
29 | westLabel.setOpaque(true);
30 | westLabel.setBackground(Color.RED);
31 | centerLabel.setOpaque(true);
32 | centerLabel.setBackground(Color.YELLOW);
33 |
34 | frame.add(northLabel, BorderLayout.NORTH);
35 | frame.add(southLabel, BorderLayout.SOUTH);
36 | frame.add(eastLabel, BorderLayout.EAST);
37 | frame.add(westLabel, BorderLayout.WEST);
38 | frame.add(centerLabel, BorderLayout.CENTER);
39 |
40 | frame.setVisible(true);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ch12/examples/Buttons.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | /**
7 | * A very simple button placed on a frame. This button is
8 | * not connected to any listener so it will "press" when
9 | * clicked but action is taken in response.
10 | */
11 | public class Buttons {
12 | public static void main( String[] args ) {
13 | JFrame frame = new JFrame( "JButton Examples" );
14 | frame.setLayout(new FlowLayout());
15 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
16 | frame.setSize( 300, 200 );
17 |
18 | JButton basic = new JButton("Try me!");
19 | frame.add(basic);
20 |
21 | frame.setVisible( true );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch12/examples/HelloJavaAgain.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import javax.swing.*;
4 |
5 | /**
6 | * A simple label placed on a frame.
7 | */
8 | public class HelloJavaAgain {
9 | public static void main( String[] args ) {
10 | JFrame frame = new JFrame( "Hello, Java!" );
11 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
12 | frame.setSize( 300, 150 );
13 |
14 | JLabel label = new JLabel("Hello, Java!", JLabel.CENTER );
15 | frame.add(label);
16 |
17 | frame.setVisible( true );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ch12/examples/HelloMouse.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import java.awt.*;
4 | import javax.swing.*;
5 | import java.awt.event.MouseEvent;
6 | import java.awt.event.MouseListener;
7 |
8 | /**
9 | * A quick demo of how mouse events work. Clicking around the
10 | * frame will move the label.
11 | *
12 | * Note that "mouse" events are the up, down, and click actions
13 | * of mouse buttons. If you want to catch the mouse moving or dragging,
14 | * those are handled by the MouseMotionListener interface.
15 | */
16 | public class HelloMouse extends JFrame implements MouseListener {
17 | JLabel label;
18 |
19 | public HelloMouse() {
20 | super("MouseEvent Demo");
21 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
22 | setLayout(null);
23 | setSize( 300, 100 );
24 |
25 | label = new JLabel("Hello, Mouse!", JLabel.CENTER );
26 | label.setOpaque(true);
27 | label.setBackground(Color.YELLOW);
28 | label.setSize(100,20);
29 | label.setLocation(100,100);
30 | add(label);
31 |
32 | getContentPane().addMouseListener(this);
33 | }
34 |
35 | public void mouseClicked(MouseEvent e) {
36 | label.setLocation(e.getX(), e.getY());
37 | }
38 |
39 | public void mousePressed(MouseEvent e) { }
40 | public void mouseReleased(MouseEvent e) { }
41 | public void mouseEntered(MouseEvent e) { }
42 | public void mouseExited(MouseEvent e) { }
43 |
44 | public static void main( String[] args ) {
45 | HelloMouse frame = new HelloMouse();
46 | frame.setVisible( true );
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ch12/examples/HelloMouseHelper.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import java.awt.*;
4 | import java.awt.event.MouseAdapter;
5 | import java.awt.event.MouseEvent;
6 | import javax.swing.*;
7 |
8 | /**
9 | * A variation on HelloMouse with a separate class implementing
10 | * the mouse event handler. Note that we have to pass a reference
11 | * to the label we wish to affect when creating the event
12 | * helper.
13 | */
14 | public class HelloMouseHelper {
15 | public static void main( String[] args ) {
16 | JFrame frame = new JFrame( "MouseAdapter Demo" );
17 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
18 | frame.setLayout(null);
19 | frame.setSize( 300, 200 );
20 |
21 | JLabel label = new JLabel("Hello, Mouse!", JLabel.CENTER );
22 | label.setOpaque(true);
23 | label.setBackground(Color.YELLOW);
24 | label.setSize(100,20);
25 | label.setLocation(100,100);
26 | frame.add(label);
27 |
28 | LabelMover mover = new LabelMover(label);
29 | frame.getContentPane().addMouseListener(mover);
30 | frame.setVisible( true );
31 | }
32 | }
33 |
34 | /**
35 | * Helper class to move a label to the position of a mouse click.
36 | */
37 | class LabelMover extends MouseAdapter {
38 | JLabel labelToMove;
39 |
40 | public LabelMover(JLabel label) {
41 | labelToMove = label;
42 | }
43 |
44 | public void mouseClicked(MouseEvent e) {
45 | labelToMove.setLocation(e.getX(), e.getY());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ch12/examples/NestedPanelDemo.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | /**
7 | * An alternate way to arrange complex UIs. Rather than
8 | * use more flexible (but complicated) layout managers,
9 | * you can nest containers each with simpler managers.
10 | */
11 | public class NestedPanelDemo {
12 | public static void main( String[] args ) {
13 | JFrame frame = new JFrame("Nested Panel Demo");
14 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
15 | frame.setSize(400, 200);
16 |
17 | // Create the text area and go ahead and add it to the center
18 | JTextArea messageArea = new JTextArea();
19 | frame.add(messageArea, BorderLayout.CENTER);
20 |
21 | // Create the button container
22 | //JPanel buttonPanel = new JPanel(new FlowLayout());
23 | JPanel buttonPanel = new JPanel(new GridLayout(1,0));
24 |
25 | // Create the buttons
26 | JButton sendButton = new JButton("Send");
27 | JButton saveButton = new JButton("Save");
28 | JButton resetButton = new JButton("Reset");
29 | JButton cancelButton = new JButton("Cancel");
30 |
31 | // Add the buttons to their container
32 | buttonPanel.add(sendButton);
33 | buttonPanel.add(saveButton);
34 | buttonPanel.add(resetButton);
35 | buttonPanel.add(cancelButton);
36 |
37 | // And finally, add the button container to the bottom of the app
38 | frame.add(buttonPanel, BorderLayout.SOUTH);
39 |
40 | frame.setVisible(true);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ch12/examples/PhoneGridDemo.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | /**
7 | * Demo of the GridLayout manager used to create a
8 | * dial pad like you might find on a phone.
9 | */
10 | public class PhoneGridDemo {
11 | public static void main( String[] args ) {
12 | JFrame frame = new JFrame("Nested Panel Demo");
13 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
14 | frame.setSize(200, 300);
15 |
16 | // Create the phone pad container
17 | JPanel phonePad = new JPanel(new GridLayout(4,3));
18 |
19 | // Create and add the 12 buttons, top-left to bottom-right
20 | phonePad.add(new JButton("1"));
21 | phonePad.add(new JButton("2"));
22 | phonePad.add(new JButton("3"));
23 |
24 | phonePad.add(new JButton("4"));
25 | phonePad.add(new JButton("5"));
26 | phonePad.add(new JButton("6"));
27 |
28 | phonePad.add(new JButton("7"));
29 | phonePad.add(new JButton("8"));
30 | phonePad.add(new JButton("9"));
31 |
32 | phonePad.add(new JButton("*"));
33 | phonePad.add(new JButton("0"));
34 | phonePad.add(new JButton("#"));
35 |
36 | // And finally, add the pad to the center of the app
37 | frame.add(phonePad, BorderLayout.CENTER);
38 |
39 | frame.setVisible(true);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ch12/examples/TextInputs.java:
--------------------------------------------------------------------------------
1 | package ch12.examples;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | /**
7 | * Some example text inputs including a text area embedded in a
8 | * JScrollPane.
9 | */
10 | public class TextInputs {
11 | public static void main( String[] args ) {
12 | JFrame frame = new JFrame( "JTextField Examples" );
13 | frame.setLayout(new FlowLayout());
14 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
15 | frame.setSize( 400, 300 );
16 |
17 | JLabel nameLabel = new JLabel("Name:");
18 | JTextField nameField = new JTextField(10);
19 | JLabel emailLabel = new JLabel("Email:");
20 | JTextField emailField = new JTextField(24);
21 |
22 | JLabel bodyLabel = new JLabel("Body:");
23 | JTextArea bodyArea = new JTextArea(10,30);
24 | bodyArea.setLineWrap(true);
25 | bodyArea.setWrapStyleWord(true);
26 | JScrollPane bodyScroller = new JScrollPane(bodyArea);
27 | bodyScroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
28 | bodyScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
29 |
30 | frame.add(nameLabel);
31 | frame.add(nameField);
32 | frame.add(emailLabel);
33 | frame.add(emailField);
34 | frame.add(bodyLabel);
35 | frame.add(bodyScroller);
36 |
37 | frame.setVisible( true );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ch12/examples/check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/ch12/examples/check.png
--------------------------------------------------------------------------------
/ch12/examples/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch12.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 | public interface GamePiece {
14 | /**
15 | * Sets the position of the piece on the playing field.
16 | * (0,0) is the upper left per standard Java drawing methods.
17 | *
18 | * @param x
19 | * @param y
20 | */
21 | void setPosition(int x, int y);
22 |
23 | /**
24 | * Gets the current horizontal position of the piece on the field.
25 | *
26 | * @return current X position of the piece
27 | */
28 | int getPositionX();
29 |
30 | /**
31 | * Gets the current vertical position of the piece on the field.
32 | *
33 | * @return current Y position of the piece
34 | */
35 | int getPositionY();
36 |
37 | /**
38 | * Gets the bounding box of this piece.
39 | *
40 | * @return a Rectangle encompassing the visual elements of the piece
41 | */
42 | Rectangle getBoundingBox();
43 |
44 | /**
45 | * Draws the piece inside the given graphics context.
46 | * Do not assume anything about the state of the context.
47 | *
48 | * @param g
49 | */
50 | void draw(Graphics g);
51 |
52 | /**
53 | * Detect a collision with another piece on the field.
54 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
55 | *
56 | * @param otherPiece
57 | * @return
58 | */
59 | boolean isTouching(GamePiece otherPiece);
60 | }
61 |
--------------------------------------------------------------------------------
/ch12/examples/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch12.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color hedgeColor = Color.GREEN.darker();
15 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
16 | private int hedgeHeight = (int) (hedgeWidth / 2);
17 |
18 | // Boundary helpers
19 | private Rectangle boundingBox;
20 |
21 | @Override
22 | public void setPosition(int x, int y) {
23 | this.x = x;
24 | this.y = y;
25 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
26 | }
27 |
28 | @Override
29 | public int getPositionX() {
30 | return x;
31 | }
32 |
33 | @Override
34 | public int getPositionY() {
35 | return y;
36 | }
37 |
38 | @Override
39 | public Rectangle getBoundingBox() {
40 | return boundingBox;
41 | }
42 |
43 | @Override
44 | public void draw(Graphics g) {
45 | g.setColor(hedgeColor);
46 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
47 | }
48 |
49 | @Override
50 | public boolean isTouching(GamePiece otherPiece) {
51 | // We don't really have any collisions to detect yet, so just return "no".
52 | // As we fill out all of the game pieces, we'll come back to this method
53 | // and provide a more useful response.
54 | return false;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ch12/examples/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch12.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color leafColor = Color.GREEN.darker();
15 | private Color trunkColor = new Color(101, 67, 33);
16 | private int trunkWidth = (int) (Field.TREE_WIDTH_IN_PIXELS * 0.2);
17 | private int trunkHeight = (int) (Field.TREE_WIDTH_IN_PIXELS * 1.1);
18 | private int trunkX, trunkY;
19 |
20 | // Boundary helpers
21 | private Rectangle boundingBox;
22 |
23 | @Override
24 | public void setPosition(int x, int y) {
25 | this.x = x;
26 | this.y = y;
27 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
28 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
29 | boundingBox =
30 | new Rectangle(
31 | x,
32 | y,
33 | Field.TREE_WIDTH_IN_PIXELS,
34 | Field.TREE_HEIGHT_IN_PIXELS
35 | );
36 | }
37 |
38 | @Override
39 | public int getPositionX() {
40 | return x;
41 | }
42 |
43 | @Override
44 | public int getPositionY() {
45 | return y;
46 | }
47 |
48 | @Override
49 | public Rectangle getBoundingBox() {
50 | return boundingBox;
51 | }
52 |
53 | @Override
54 | public void draw(Graphics g) {
55 | g.setColor(trunkColor);
56 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
57 | g.setColor(leafColor);
58 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
59 | }
60 |
61 | @Override
62 | public boolean isTouching(GamePiece otherPiece) {
63 | if (this == otherPiece) {
64 | // By definition we don't collide with ourselves
65 | return false;
66 | }
67 | return GameUtilities.doBoxesIntersect(
68 | boundingBox,
69 | otherPiece.getBoundingBox()
70 | );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/ch12/exercises/Calculator.java:
--------------------------------------------------------------------------------
1 | package ch12.exercises;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 | import java.awt.event.*;
6 |
7 | public class Calculator extends JFrame implements ActionListener {
8 |
9 | public Calculator() {
10 | super("Ex. 12.1");
11 | setSize(300,450);
12 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
13 | }
14 |
15 | public void actionPerformed(ActionEvent ae) {
16 | System.out.println(ae.getActionCommand());
17 | }
18 |
19 | public static void main(String args[]) {
20 | Calculator calc = new Calculator();
21 | SwingUtilities.invokeLater(() -> calc.setVisible(true));
22 | }
23 | }
--------------------------------------------------------------------------------
/ch12/exercises/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch12.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 | public interface GamePiece {
14 | /**
15 | * Sets the position of the piece on the playing field.
16 | * (0,0) is the upper left per standard Java drawing methods.
17 | *
18 | * @param x
19 | * @param y
20 | */
21 | void setPosition(int x, int y);
22 |
23 | /**
24 | * Gets the current horizontal position of the piece on the field.
25 | *
26 | * @return current X position of the piece
27 | */
28 | int getPositionX();
29 |
30 | /**
31 | * Gets the current vertical position of the piece on the field.
32 | *
33 | * @return current Y position of the piece
34 | */
35 | int getPositionY();
36 |
37 | /**
38 | * Gets the bounding box of this piece.
39 | *
40 | * @return a Rectangle encompassing the visual elements of the piece
41 | */
42 | Rectangle getBoundingBox();
43 |
44 | /**
45 | * Draws the piece inside the given graphics context.
46 | * Do not assume anything about the state of the context.
47 | *
48 | * @param g
49 | */
50 | void draw(Graphics g);
51 |
52 | /**
53 | * Detect a collision with another piece on the field.
54 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
55 | *
56 | * @param otherPiece
57 | * @return
58 | */
59 | boolean isTouching(GamePiece otherPiece);
60 | }
61 |
--------------------------------------------------------------------------------
/ch12/exercises/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch12.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color hedgeColor = Color.GREEN.darker();
15 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
16 | private int hedgeHeight = (int) (hedgeWidth / 2);
17 |
18 | // Boundary helpers
19 | private Rectangle boundingBox;
20 |
21 | @Override
22 | public void setPosition(int x, int y) {
23 | this.x = x;
24 | this.y = y;
25 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
26 | }
27 |
28 | @Override
29 | public int getPositionX() {
30 | return x;
31 | }
32 |
33 | @Override
34 | public int getPositionY() {
35 | return y;
36 | }
37 |
38 | @Override
39 | public Rectangle getBoundingBox() {
40 | return boundingBox;
41 | }
42 |
43 | @Override
44 | public void draw(Graphics g) {
45 | g.setColor(hedgeColor);
46 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
47 | }
48 |
49 | @Override
50 | public boolean isTouching(GamePiece otherPiece) {
51 | // We don't really have any collisions to detect yet, so just return "no".
52 | // As we fill out all of the game pieces, we'll come back to this method
53 | // and provide a more useful response.
54 | return false;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ch12/exercises/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch12.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color leafColor = Color.GREEN.darker();
15 | private Color trunkColor = new Color(101, 67, 33);
16 | private int trunkWidth = (int) (Field.TREE_WIDTH_IN_PIXELS * 0.2);
17 | private int trunkHeight = (int) (Field.TREE_WIDTH_IN_PIXELS * 1.1);
18 | private int trunkX, trunkY;
19 |
20 | // Boundary helpers
21 | private Rectangle boundingBox;
22 |
23 | @Override
24 | public void setPosition(int x, int y) {
25 | this.x = x;
26 | this.y = y;
27 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
28 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
29 | boundingBox =
30 | new Rectangle(
31 | x,
32 | y,
33 | Field.TREE_WIDTH_IN_PIXELS,
34 | Field.TREE_HEIGHT_IN_PIXELS
35 | );
36 | }
37 |
38 | @Override
39 | public int getPositionX() {
40 | return x;
41 | }
42 |
43 | @Override
44 | public int getPositionY() {
45 | return y;
46 | }
47 |
48 | @Override
49 | public Rectangle getBoundingBox() {
50 | return boundingBox;
51 | }
52 |
53 | @Override
54 | public void draw(Graphics g) {
55 | g.setColor(trunkColor);
56 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
57 | g.setColor(leafColor);
58 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
59 | }
60 |
61 | @Override
62 | public boolean isTouching(GamePiece otherPiece) {
63 | if (this == otherPiece) {
64 | // By definition we don't collide with ourselves
65 | return false;
66 | }
67 | return GameUtilities.doBoxesIntersect(
68 | boundingBox,
69 | otherPiece.getBoundingBox()
70 | );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/ch12/solutions/Calculator.java:
--------------------------------------------------------------------------------
1 | package ch12.solutions;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 | import java.awt.event.*;
6 |
7 | public class Calculator extends JFrame implements ActionListener {
8 | JLabel display;
9 | String buttonLabels = "789/456*123-.0=+";
10 | Font displayFont = new Font(Font.MONOSPACED, Font.BOLD, 36);
11 | Font buttonFont = new Font(Font.MONOSPACED, Font.BOLD, 20);
12 |
13 | public Calculator() {
14 | super("Ex. 12.1");
15 | setSize(300,450);
16 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
17 |
18 | JPanel content = (JPanel)getContentPane();
19 |
20 | // Set up our display label with a nice, readable font
21 | display = new JLabel("0", SwingConstants.RIGHT);
22 | display.setFont(displayFont);
23 | display.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
24 | content.add(display, BorderLayout.NORTH);
25 |
26 | // Set up our buttons
27 | JPanel buttonPane = new JPanel(new GridLayout(4,4));
28 | for (String label : buttonLabels.split("")) {
29 | JButton b = new JButton(label);
30 | b.setFont(buttonFont);
31 | b.addActionListener(this);
32 | buttonPane.add(b);
33 | }
34 | content.add(buttonPane, BorderLayout.CENTER);
35 | }
36 |
37 | public void actionPerformed(ActionEvent ae) {
38 | System.out.println(ae.getActionCommand());
39 | }
40 |
41 | public static void main(String args[]) {
42 | Calculator calc = new Calculator();
43 | SwingUtilities.invokeLater(() -> calc.setVisible(true));
44 | }
45 | }
--------------------------------------------------------------------------------
/ch12/solutions/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch12.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 | public interface GamePiece {
14 | /**
15 | * Sets the position of the piece on the playing field.
16 | * (0,0) is the upper left per standard Java drawing methods.
17 | *
18 | * @param x
19 | * @param y
20 | */
21 | void setPosition(int x, int y);
22 |
23 | /**
24 | * Gets the current horizontal position of the piece on the field.
25 | *
26 | * @return current X position of the piece
27 | */
28 | int getPositionX();
29 |
30 | /**
31 | * Gets the current vertical position of the piece on the field.
32 | *
33 | * @return current Y position of the piece
34 | */
35 | int getPositionY();
36 |
37 | /**
38 | * Gets the bounding box of this piece.
39 | *
40 | * @return a Rectangle encompassing the visual elements of the piece
41 | */
42 | Rectangle getBoundingBox();
43 |
44 | /**
45 | * Draws the piece inside the given graphics context.
46 | * Do not assume anything about the state of the context.
47 | *
48 | * @param g
49 | */
50 | void draw(Graphics g);
51 |
52 | /**
53 | * Detect a collision with another piece on the field.
54 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
55 | *
56 | * @param otherPiece
57 | * @return
58 | */
59 | boolean isTouching(GamePiece otherPiece);
60 | }
61 |
--------------------------------------------------------------------------------
/ch12/solutions/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch12.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color hedgeColor = Color.GREEN.darker();
15 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
16 | private int hedgeHeight = (int) (hedgeWidth / 2);
17 |
18 | // Boundary helpers
19 | private Rectangle boundingBox;
20 |
21 | @Override
22 | public void setPosition(int x, int y) {
23 | this.x = x;
24 | this.y = y;
25 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
26 | }
27 |
28 | @Override
29 | public int getPositionX() {
30 | return x;
31 | }
32 |
33 | @Override
34 | public int getPositionY() {
35 | return y;
36 | }
37 |
38 | @Override
39 | public Rectangle getBoundingBox() {
40 | return boundingBox;
41 | }
42 |
43 | @Override
44 | public void draw(Graphics g) {
45 | g.setColor(hedgeColor);
46 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
47 | }
48 |
49 | @Override
50 | public boolean isTouching(GamePiece otherPiece) {
51 | // We don't really have any collisions to detect yet, so just return "no".
52 | // As we fill out all of the game pieces, we'll come back to this method
53 | // and provide a more useful response.
54 | return false;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ch12/solutions/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch12.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * An obstacle for our game. Trees includ a simple circle and rectangle shape.
7 | * They are built using sizes determined by the constants in the Field class.
8 | */
9 | public class Tree implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color leafColor = Color.GREEN.darker();
15 | private Color trunkColor = new Color(101, 67, 33);
16 | private int trunkWidth = (int) (Field.TREE_WIDTH_IN_PIXELS * 0.2);
17 | private int trunkHeight = (int) (Field.TREE_WIDTH_IN_PIXELS * 1.1);
18 | private int trunkX, trunkY;
19 |
20 | // Boundary helpers
21 | private Rectangle boundingBox;
22 |
23 | @Override
24 | public void setPosition(int x, int y) {
25 | this.x = x;
26 | this.y = y;
27 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
28 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
29 | boundingBox =
30 | new Rectangle(
31 | x,
32 | y,
33 | Field.TREE_WIDTH_IN_PIXELS,
34 | Field.TREE_HEIGHT_IN_PIXELS
35 | );
36 | }
37 |
38 | @Override
39 | public int getPositionX() {
40 | return x;
41 | }
42 |
43 | @Override
44 | public int getPositionY() {
45 | return y;
46 | }
47 |
48 | @Override
49 | public Rectangle getBoundingBox() {
50 | return boundingBox;
51 | }
52 |
53 | @Override
54 | public void draw(Graphics g) {
55 | g.setColor(trunkColor);
56 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
57 | g.setColor(leafColor);
58 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
59 | }
60 |
61 | @Override
62 | public boolean isTouching(GamePiece otherPiece) {
63 | if (this == otherPiece) {
64 | // By definition we don't collide with ourselves
65 | return false;
66 | }
67 | return GameUtilities.doBoxesIntersect(
68 | boundingBox,
69 | otherPiece.getBoundingBox()
70 | );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/ch13/examples/DateAtHost.java:
--------------------------------------------------------------------------------
1 | package ch13.examples;
2 |
3 | import java.net.Socket;
4 | import java.io.*;
5 |
6 | public class DateAtHost extends java.util.Date {
7 | static int timePort = 37;
8 | // seconds from start of 20th century to Jan 1, 1970 00:00 GMT
9 | static final long offset = 2208988800L;
10 |
11 | public DateAtHost( String host ) throws IOException {
12 | this( host, timePort );
13 | }
14 |
15 | public DateAtHost( String host, int port ) throws IOException {
16 | Socket server = new Socket( host, port );
17 | DataInputStream din =
18 | new DataInputStream( server.getInputStream( ) );
19 | int time = din.readInt( );
20 | server.close( );
21 |
22 | setTime( (((1L << 32) + time) - offset) * 1000 );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ch13/examples/IconLabel.java:
--------------------------------------------------------------------------------
1 | package ch13.examples;
2 |
3 | import javax.swing.*;
4 | import java.net.*;
5 |
6 | public class IconLabel extends JFrame {
7 | public IconLabel() {
8 | super("Web Icon Demo");
9 | setSize(400,220);
10 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
11 |
12 | try {
13 | URL favUrl = new URL("https://www.oracle.com/asset/web/favicons/favicon-192.png");
14 | ImageIcon image1 = new ImageIcon(favUrl);
15 | JLabel iconLabel = new JLabel(image1);
16 | add(iconLabel);
17 | } catch (MalformedURLException mfe) {
18 | add(new JLabel("Error: " + mfe));
19 | }
20 | }
21 |
22 | public static void main(String args[]) {
23 | IconLabel demo = new IconLabel();
24 | SwingUtilities.invokeLater(() -> demo.setVisible(true));
25 | }
26 | }
--------------------------------------------------------------------------------
/ch13/examples/ReadUrl.java:
--------------------------------------------------------------------------------
1 | package ch13.examples;
2 |
3 | import java.io.*;
4 | import java.net.*;
5 |
6 | /**
7 | * A simple command line demonstration of reading from a URL.
8 | * The URL to read must be passed as the only argument on the command line.
9 | */
10 | public class ReadUrl {
11 | public static void main(String args[]) {
12 | // Did we get an argument to use as the URL?
13 | if (args.length != 1) {
14 | System.err.println("Must specify URL on command line. Exiting.");
15 | System.exit(1);
16 | }
17 | // Great! Let's try to read it and dump the contents to the terminal.
18 | try {
19 | URL url = new URL(args[0]);
20 |
21 | BufferedReader bin = new BufferedReader (
22 | new InputStreamReader( url.openStream() ));
23 | String line;
24 | while ( (line = bin.readLine()) != null ) {
25 | System.out.println( line );
26 | }
27 | bin.close();
28 | } catch (Exception e) {
29 | System.err.println("Error occurred while reading:" + e);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ch13/examples/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch13.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch13/examples/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch13.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color hedgeColor = Color.GREEN.darker();
15 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
16 | private int hedgeHeight = (int) (hedgeWidth / 2);
17 |
18 | // Boundary helpers
19 | private Rectangle boundingBox;
20 |
21 | @Override
22 | public void setPosition(int x, int y) {
23 | this.x = x;
24 | this.y = y;
25 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
26 | }
27 |
28 | @Override
29 | public int getPositionX() {
30 | return x;
31 | }
32 |
33 | @Override
34 | public int getPositionY() {
35 | return y;
36 | }
37 |
38 | @Override
39 | public Rectangle getBoundingBox() {
40 | return boundingBox;
41 | }
42 |
43 | @Override
44 | public void draw(Graphics g) {
45 | g.setColor(hedgeColor);
46 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
47 | }
48 |
49 | @Override
50 | public boolean isTouching(GamePiece otherPiece) {
51 | if (this == otherPiece) {
52 | // By definition we don't collide with ourselves
53 | return false;
54 | }
55 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ch13/examples/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch13.examples.game;
2 |
3 | import java.awt.*;
4 |
5 | public class Tree implements GamePiece {
6 | int x, y;
7 |
8 | // Drawing helpers
9 | private Color leafColor = Color.GREEN.darker();
10 | private Color trunkColor = new Color(101, 67, 33);
11 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
12 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
13 | private int trunkX, trunkY;
14 |
15 | // Boundary helpers
16 | private Rectangle boundingBox;
17 |
18 | @Override
19 | public void setPosition(int x, int y) {
20 | this.x = x;
21 | this.y = y;
22 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
23 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
24 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(trunkColor);
45 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
46 | g.setColor(leafColor);
47 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
48 | }
49 |
50 | @Override
51 | public boolean isTouching(GamePiece otherPiece) {
52 | if (this == otherPiece) {
53 | // By definition we don't collide with ourselves
54 | return false;
55 | }
56 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ch13/exercises/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch13.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch13/exercises/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch13.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color hedgeColor = Color.GREEN.darker();
15 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
16 | private int hedgeHeight = (int) (hedgeWidth / 2);
17 |
18 | // Boundary helpers
19 | private Rectangle boundingBox;
20 |
21 | @Override
22 | public void setPosition(int x, int y) {
23 | this.x = x;
24 | this.y = y;
25 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
26 | }
27 |
28 | @Override
29 | public int getPositionX() {
30 | return x;
31 | }
32 |
33 | @Override
34 | public int getPositionY() {
35 | return y;
36 | }
37 |
38 | @Override
39 | public Rectangle getBoundingBox() {
40 | return boundingBox;
41 | }
42 |
43 | @Override
44 | public void draw(Graphics g) {
45 | g.setColor(hedgeColor);
46 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
47 | }
48 |
49 | @Override
50 | public boolean isTouching(GamePiece otherPiece) {
51 | if (this == otherPiece) {
52 | // By definition we don't collide with ourselves
53 | return false;
54 | }
55 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ch13/exercises/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch13.exercises.game;
2 |
3 | import java.awt.*;
4 |
5 | public class Tree implements GamePiece {
6 | int x, y;
7 |
8 | // Drawing helpers
9 | private Color leafColor = Color.GREEN.darker();
10 | private Color trunkColor = new Color(101, 67, 33);
11 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
12 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
13 | private int trunkX, trunkY;
14 |
15 | // Boundary helpers
16 | private Rectangle boundingBox;
17 |
18 | @Override
19 | public void setPosition(int x, int y) {
20 | this.x = x;
21 | this.y = y;
22 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
23 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
24 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(trunkColor);
45 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
46 | g.setColor(leafColor);
47 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
48 | }
49 |
50 | @Override
51 | public boolean isTouching(GamePiece otherPiece) {
52 | if (this == otherPiece) {
53 | // By definition we don't collide with ourselves
54 | return false;
55 | }
56 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ch13/solutions/FDClient.java:
--------------------------------------------------------------------------------
1 | package ch13.solutions;
2 |
3 | import java.net.Socket;
4 | import java.io.*;
5 |
6 | public class FDClient {
7 | static int fdPort = 3283; // D-A-T-E on a phonepad :)
8 |
9 | public static void printDateAndTime(String host) {
10 | try (Socket fdSocket = new Socket(host, fdPort)) {
11 | InputStreamReader isr =
12 | new InputStreamReader(fdSocket.getInputStream());
13 | BufferedReader br = new BufferedReader(isr);
14 | String dt = br.readLine();
15 | System.out.println(host + ": " + dt);
16 | br.close();
17 | } catch(IOException ioe) {
18 | System.err.println("Failed to retrieve date and time: " + ioe);
19 | }
20 | }
21 |
22 | public static void main(String args[]) {
23 | if (args.length != 1) {
24 | System.err.println("Please provide a host to contact.");
25 | System.exit(1);
26 | }
27 | printDateAndTime(args[0]);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ch13/solutions/FDServer.java:
--------------------------------------------------------------------------------
1 | package ch13.solutions;
2 |
3 | import java.io.*;
4 | import java.net.*;
5 | import java.time.LocalDateTime;
6 | import java.time.format.DateTimeFormatter;
7 |
8 | public class FDServer {
9 | static int fdPort = 3283; // D-A-T-E on a phonepad :)
10 | static DateTimeFormatter shortish = DateTimeFormatter.ofPattern("MM/dd/yy hh:mm a");
11 | public static void serveDateAndTime() {
12 | for (;;) { // this is sometimes called the "forever" loop
13 | System.out.println("Waiting ...");
14 | try (ServerSocket listener = new ServerSocket(fdPort)) {
15 | Socket fdClient = listener.accept();
16 | System.out.println("Incoming request from " + fdClient.getInetAddress());
17 | OutputStreamWriter osw = new OutputStreamWriter(fdClient.getOutputStream());
18 | PrintWriter pw = new PrintWriter(osw);
19 | pw.println(shortish.format(LocalDateTime.now()));
20 | pw.close();
21 | } catch(Exception e) {
22 | // We're being a bit lazy here, but this server is so
23 | // simple, there's not much else to do.
24 | System.err.println("Oh no! Server error: " + e);
25 | }
26 | }
27 | }
28 |
29 | public static void main(String args[]) {
30 | serveDateAndTime();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ch13/solutions/FDServer2.java.preview:
--------------------------------------------------------------------------------
1 | package ch13.solutions;
2 |
3 | import java.io.*;
4 | import java.net.*;
5 | import java.time.LocalDateTime;
6 | import java.time.format.DateTimeFormatter;
7 |
8 | public class FDServer2 {
9 | static int fdPort = 3283; // D-A-T-E on a phonepad :)
10 | static DateTimeFormatter shortish = DateTimeFormatter.ofPattern("MM/dd/yy hh:mm a");
11 | public static void serveDateAndTime() {
12 | for (;;) { // this is sometimes called a "forever" loop
13 | System.out.println("Waiting ...");
14 | try (ServerSocket listener = new ServerSocket(fdPort)) {
15 | Socket fdClient = listener.accept();
16 | System.out.println("Incoming request from " + fdClient.getInetAddress());
17 | Thread.startVirtualThread(() -> {
18 | try {
19 | OutputStreamWriter osw = new OutputStreamWriter(fdClient.getOutputStream());
20 | PrintWriter pw = new PrintWriter(osw);
21 | pw.println(shortish.format(LocalDateTime.now()));
22 | pw.close();
23 | fdClient.close();
24 | } catch(Exception e) {
25 | System.err.println("Problem handling client: " + e);
26 | }
27 | });
28 | } catch(Exception e) {
29 | // We're being a bit lazy here, but this server is so
30 | // simple, there's not much else to do.
31 | System.err.println("Oh no! Server error: " + e);
32 | }
33 | }
34 | }
35 |
36 | public static void main(String args[]) {
37 | serveDateAndTime();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ch13/solutions/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package ch13.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/ch13/solutions/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package ch13.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color hedgeColor = Color.GREEN.darker();
15 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
16 | private int hedgeHeight = (int) (hedgeWidth / 2);
17 |
18 | // Boundary helpers
19 | private Rectangle boundingBox;
20 |
21 | @Override
22 | public void setPosition(int x, int y) {
23 | this.x = x;
24 | this.y = y;
25 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
26 | }
27 |
28 | @Override
29 | public int getPositionX() {
30 | return x;
31 | }
32 |
33 | @Override
34 | public int getPositionY() {
35 | return y;
36 | }
37 |
38 | @Override
39 | public Rectangle getBoundingBox() {
40 | return boundingBox;
41 | }
42 |
43 | @Override
44 | public void draw(Graphics g) {
45 | g.setColor(hedgeColor);
46 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
47 | }
48 |
49 | @Override
50 | public boolean isTouching(GamePiece otherPiece) {
51 | if (this == otherPiece) {
52 | // By definition we don't collide with ourselves
53 | return false;
54 | }
55 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ch13/solutions/game/Tree.java:
--------------------------------------------------------------------------------
1 | package ch13.solutions.game;
2 |
3 | import java.awt.*;
4 |
5 | public class Tree implements GamePiece {
6 | int x, y;
7 |
8 | // Drawing helpers
9 | private Color leafColor = Color.GREEN.darker();
10 | private Color trunkColor = new Color(101, 67, 33);
11 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
12 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
13 | private int trunkX, trunkY;
14 |
15 | // Boundary helpers
16 | private Rectangle boundingBox;
17 |
18 | @Override
19 | public void setPosition(int x, int y) {
20 | this.x = x;
21 | this.y = y;
22 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
23 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
24 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(trunkColor);
45 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
46 | g.setColor(leafColor);
47 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
48 | }
49 |
50 | @Override
51 | public boolean isTouching(GamePiece otherPiece) {
52 | if (this == otherPiece) {
53 | // By definition we don't collide with ourselves
54 | return false;
55 | }
56 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/game/GamePiece.java:
--------------------------------------------------------------------------------
1 | package game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Interface to hold common elements for our apples, trees, and physicists
7 | * From the README:
8 | * GamePiece
9 | * - methods for positioning on a PlayingField
10 | * - methods for Drawing
11 | * - methods for detecting a collision with other GamePieces
12 | */
13 |
14 | public interface GamePiece {
15 | /**
16 | * Sets the position of the piece on the playing field.
17 | * (0,0) is the upper left per standard Java drawing methods.
18 | *
19 | * @param x
20 | * @param y
21 | */
22 | void setPosition(int x, int y);
23 |
24 | /**
25 | * Gets the current horizontal position of the piece on the field.
26 | *
27 | * @return current X position of the piece
28 | */
29 | int getPositionX();
30 |
31 | /**
32 | * Gets the current vertical position of the piece on the field.
33 | *
34 | * @return current Y position of the piece
35 | */
36 | int getPositionY();
37 |
38 | /**
39 | * Gets the bounding box of this piece.
40 | *
41 | * @return a Rectangle encompassing the visual elements of the piece
42 | */
43 | Rectangle getBoundingBox();
44 |
45 | /**
46 | * Draws the piece inside the given graphics context.
47 | * Do not assume anything about the state of the context.
48 | *
49 | * @param g
50 | */
51 | void draw(Graphics g);
52 |
53 | /**
54 | * Detect a collision with another piece on the field.
55 | * By definition, a piece does NOT touch itself (i.e. it won't collide with itself).
56 | *
57 | * @param otherPiece
58 | * @return
59 | */
60 | boolean isTouching(GamePiece otherPiece);
61 | }
62 |
--------------------------------------------------------------------------------
/game/Hedge.java:
--------------------------------------------------------------------------------
1 | package game;
2 |
3 | import java.awt.*;
4 |
5 | /**
6 | * Another obstacle for our game. Hedges are simple boxes.
7 | * We'll reuse the tree size constants for our hedges.
8 | */
9 | public class Hedge implements GamePiece {
10 |
11 | int x, y;
12 |
13 | // Drawing helpers
14 | private Color hedgeColor = Color.GREEN.darker();
15 | private int hedgeWidth = Field.TREE_WIDTH_IN_PIXELS;
16 | private int hedgeHeight = (int) (hedgeWidth / 2);
17 |
18 | // Boundary helpers
19 | private Rectangle boundingBox;
20 |
21 | @Override
22 | public void setPosition(int x, int y) {
23 | this.x = x;
24 | this.y = y;
25 | boundingBox = new Rectangle(x, y, hedgeWidth, hedgeHeight);
26 | }
27 |
28 | @Override
29 | public int getPositionX() {
30 | return x;
31 | }
32 |
33 | @Override
34 | public int getPositionY() {
35 | return y;
36 | }
37 |
38 | @Override
39 | public Rectangle getBoundingBox() {
40 | return boundingBox;
41 | }
42 |
43 | @Override
44 | public void draw(Graphics g) {
45 | g.setColor(hedgeColor);
46 | g.fillRect(x, y, hedgeWidth, hedgeHeight);
47 | }
48 |
49 | @Override
50 | public boolean isTouching(GamePiece otherPiece) {
51 | if (this == otherPiece) {
52 | // By definition we don't collide with ourselves
53 | return false;
54 | }
55 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/game/Tree.java:
--------------------------------------------------------------------------------
1 | package game;
2 |
3 | import java.awt.*;
4 |
5 | public class Tree implements GamePiece {
6 | int x, y;
7 |
8 | // Drawing helpers
9 | private Color leafColor = Color.GREEN.darker();
10 | private Color trunkColor = new Color(101, 67, 33);
11 | private int trunkWidth = (int)(Field.TREE_WIDTH_IN_PIXELS * 0.2);
12 | private int trunkHeight = (int)(Field.TREE_WIDTH_IN_PIXELS * 1.1);
13 | private int trunkX, trunkY;
14 |
15 | // Boundary helpers
16 | private Rectangle boundingBox;
17 |
18 | @Override
19 | public void setPosition(int x, int y) {
20 | this.x = x;
21 | this.y = y;
22 | trunkX = x + (Field.TREE_WIDTH_IN_PIXELS - trunkWidth) / 2;
23 | trunkY = y + 2 * Field.TREE_WIDTH_IN_PIXELS - trunkHeight;
24 | boundingBox = new Rectangle(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_HEIGHT_IN_PIXELS);
25 | }
26 |
27 | @Override
28 | public int getPositionX() {
29 | return x;
30 | }
31 |
32 | @Override
33 | public int getPositionY() {
34 | return y;
35 | }
36 |
37 | @Override
38 | public Rectangle getBoundingBox() {
39 | return boundingBox;
40 | }
41 |
42 | @Override
43 | public void draw(Graphics g) {
44 | g.setColor(trunkColor);
45 | g.fillRect(trunkX, trunkY, trunkWidth, trunkHeight);
46 | g.setColor(leafColor);
47 | g.fillOval(x, y, Field.TREE_WIDTH_IN_PIXELS, Field.TREE_WIDTH_IN_PIXELS);
48 | }
49 |
50 | @Override
51 | public boolean isTouching(GamePiece otherPiece) {
52 | if (this == otherPiece) {
53 | // By definition we don't collide with ourselves
54 | return false;
55 | }
56 | return GameUtilities.doBoxesIntersect(boundingBox, otherPiece.getBoundingBox());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/quiz/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
--------------------------------------------------------------------------------
/quiz/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rm lj6review.jar
4 | cd src
5 | javac com/loyinc/*/*.java
6 | if [ $? -eq 0 ]
7 | then
8 | jar cvmf ../manifest.mf ../lj6review.jar res com/loyinc/*/*.class
9 | else
10 | echo "Compilation failed. Packaging skipped."
11 | fi
12 |
--------------------------------------------------------------------------------
/quiz/lj6review.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/lj6review.jar
--------------------------------------------------------------------------------
/quiz/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: com.loyinc.quiz.Review
3 |
4 |
--------------------------------------------------------------------------------
/quiz/quizgen.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 |
3 | #
4 | # Usage is: $0 chapnum qcount
5 | #
6 | if ($#ARGV != 1) {
7 | die "Usage is: $0 chNum quCount\n";
8 | }
9 |
10 | $chNum = $ARGV[0];
11 | $quCount = $ARGV[1];
12 |
13 | print "###\n# Chapter $chNum\n###\n";
14 |
15 | printf "%X0-ti Chapter %d Title\n", $chNum, $chNum;
16 | printf "%X0-in Chapter %d Intro\n\n", $chNum, $chNum;
17 |
18 | for ($q = 1; $q <= $quCount; $q++) {
19 | printf "%X%X-tx Question %d text\n", $chNum, $q, $q;
20 | printf "%X%X-se (Select one)\n", $chNum, $q;
21 | for ($a = 65; $a <= 68; $a++) {
22 | printf "%X%X%ctw Answer %c\n", $chNum, $q, $a, $a;
23 | printf "%X%X%cex Explanation %c\n", $chNum, $q, $a, $a;
24 | }
25 | printf "\n";
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/quiz/src/com/loyinc/quiz/Answer.java:
--------------------------------------------------------------------------------
1 | package com.loyinc.quiz;
2 |
3 | public class Answer {
4 | String answer;
5 | String explanation;
6 | boolean correct;
7 | boolean selected;
8 |
9 | public Answer(String answer) {
10 | this(answer, "", false);
11 | }
12 |
13 | public Answer(String answer, boolean correct) {
14 | this(answer, "", correct);
15 | }
16 |
17 | public Answer(String answer, String explanation, boolean correct) {
18 | this.answer = answer;
19 | this.explanation = explanation;
20 | this.correct = correct;
21 | this.selected = false;
22 | }
23 |
24 | public boolean matches() {
25 | return correct == selected;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/quiz/src/com/loyinc/quiz/Review.java:
--------------------------------------------------------------------------------
1 | package com.loyinc.quiz;
2 |
3 | import java.util.*;
4 |
5 | import javax.swing.SwingUtilities;
6 |
7 | public class Review {
8 | QuizFrame quiz;
9 | List chapterList = new ArrayList<>();
10 |
11 | // Hard-coded options for now. Could certainly move these to command-line
12 | // arguments if more quizzes get built.
13 | // Production, use the bundled quiz content
14 | String buildMode = Quizzes.JAR;
15 | String quizFile = "res/quiz-data.txt";
16 |
17 | // Late-stage development, use a file from the local filesystem
18 | //String buildMode = Quizzes.FILE;
19 | //String quizFile = "/Users/marc/work/books/examples/learnjava6e/quiz/rez/quiz-data.txt";
20 |
21 | // Early development, use mock data
22 | //String buildMode = Quizzes.MOCKUP;
23 | //String quizFile = null;
24 |
25 | public Review() {
26 | // Follow global switch to pick either mockup data or the real thing
27 | chapterList = Quizzes.buildList(buildMode, quizFile);
28 | if (chapterList == null || chapterList.size() == 0) {
29 | // No errors, but no chapters either; must be in test mode
30 | quiz = new QuizFrame(null);
31 | } else {
32 | quiz = new QuizFrame(chapterList);
33 | }
34 | }
35 |
36 | public boolean loadChapters(String quizFile) {
37 | // Return true on successful load
38 |
39 | return chapterList != null;
40 | }
41 |
42 | public void start() {
43 | if (quiz != null) {
44 | quiz.setVisible(true);
45 | } else {
46 | System.err.println("Review quizzes are not yet initialized.");
47 | }
48 | }
49 |
50 | public static void main(String[] args) {
51 | System.setProperty("awt.useSystemAAFontSettings","on");
52 | System.setProperty("swing.aatext", "true");
53 | Review r = new Review();
54 | SwingUtilities.invokeLater(() -> r.start());
55 | }
56 | }
--------------------------------------------------------------------------------
/quiz/src/com/loyinc/util/CWButton.java:
--------------------------------------------------------------------------------
1 | package com.loyinc.util;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | /**
7 | * A constant-width label for use in layout managers that query
8 | * their components to determine sizes.
9 | */
10 | public class CWButton extends JButton {
11 | protected int width;
12 |
13 | public CWButton(int width) {
14 | this(width, null, null);
15 | }
16 |
17 | public CWButton(int width, String text) {
18 | this(width, text, null);
19 | }
20 |
21 | public CWButton(int width, Icon icon) {
22 | this(width, null, icon);
23 | }
24 |
25 | public CWButton(int width, String text, Icon icon) {
26 | super(text, icon);
27 | this.width = width;
28 | tailor();
29 | }
30 |
31 | public CWButton(int width, Action action) {
32 | super(action);
33 | this.width = width;
34 | tailor();
35 | }
36 |
37 | /**
38 | * Use this method to apply any app-wide adjustments to instances
39 | * of this constant-width button, regardless of how it was constructed.
40 | */
41 | protected void tailor() {
42 | Config.applyPrefs(this);
43 | }
44 |
45 | public Dimension getPreferredSize() {
46 | return new Dimension(width, this.getHeight());
47 | }
48 | public Dimension getMinimumSize() { return getPreferredSize(); }
49 | public Dimension getMaximumSize() { return getPreferredSize(); }
50 | }
51 |
--------------------------------------------------------------------------------
/quiz/src/com/loyinc/util/CWLabel.java:
--------------------------------------------------------------------------------
1 | package com.loyinc.util;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | /**
7 | * A constant-width label for use in layout managers that query
8 | * their components to determine sizes.
9 | */
10 | public class CWLabel extends JLabel {
11 | protected int width;
12 |
13 | public CWLabel(int width) {
14 | this(width, null, null, SwingConstants.LEADING);
15 | }
16 |
17 | public CWLabel(int width, String text) {
18 | this(width, text, null, SwingConstants.LEADING);
19 | }
20 |
21 | public CWLabel(int width, String text, int horizontalAlignment) {
22 | this(width, text, null, horizontalAlignment);
23 | }
24 |
25 | public CWLabel(int width, Icon icon) {
26 | this(width, null, icon, SwingConstants.CENTER);
27 | }
28 |
29 | public CWLabel(int width, Icon icon, int horizontalAlignment) {
30 | this(width, null, icon, horizontalAlignment);
31 | }
32 |
33 | public CWLabel(int width, String text, Icon icon, int horizontalAlignment) {
34 | super(text, icon, horizontalAlignment);
35 | this.width = width;
36 | Config.applyPrefs(this);
37 | }
38 |
39 | public Dimension getPreferredSize() {
40 | return new Dimension(width, this.getHeight());
41 | }
42 | public Dimension getMinimumSize() { return getPreferredSize(); }
43 | public Dimension getMaximumSize() { return getPreferredSize(); }
44 | }
45 |
--------------------------------------------------------------------------------
/quiz/src/com/loyinc/util/Config.java:
--------------------------------------------------------------------------------
1 | package com.loyinc.util;
2 |
3 | import com.loyinc.quiz.Review;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 | import java.util.prefs.Preferences;
8 |
9 | public class Config {
10 | // Internal Preference node and key names
11 | static final String PREFS_NODE = "/com/loyinc/util/Review";
12 | static final String FONT_SIZE_ADJ_KEY = "font.size.adjustment";
13 |
14 | static final String osName = System.getProperty("os.name");
15 |
16 | // Public defaults for some common preferences
17 | public static final float DEFAUlT_ADJUSTMENT = 2.0f;
18 |
19 | public static void applyPrefs(JComponent uiComp) {
20 | Preferences prefs = Preferences.userRoot().node(PREFS_NODE);
21 | float adjustment = prefs.getFloat(FONT_SIZE_ADJ_KEY, DEFAUlT_ADJUSTMENT);
22 | Font f = uiComp.getFont();
23 | uiComp.setFont(f.deriveFont(f.getSize() + adjustment));
24 | }
25 |
26 | /**
27 | * Helper to get the font size adjustment value for use in manually
28 | * configuring a component.
29 | */
30 | public float getFontSizeAdjustment() {
31 | Preferences prefs = Preferences.userRoot().node(PREFS_NODE);
32 | return prefs.getFloat(FONT_SIZE_ADJ_KEY, DEFAUlT_ADJUSTMENT);
33 | }
34 |
35 | public static boolean isMacOS() {
36 | return osName.startsWith("Mac");
37 | }
38 |
39 | public static boolean isLinux() {
40 | return osName.equalsIgnoreCase("linux");
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/quiz/src/com/loyinc/util/StateProvider.java:
--------------------------------------------------------------------------------
1 | package com.loyinc.util;
2 |
3 | public interface StateProvider {
4 | public int getState();
5 | public String getStateText();
6 | public String getStateIconName(boolean expanded);
7 | }
8 |
--------------------------------------------------------------------------------
/quiz/src/res/ch_done_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/ch_done_ok.png
--------------------------------------------------------------------------------
/quiz/src/res/ch_filled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/ch_filled.png
--------------------------------------------------------------------------------
/quiz/src/res/ch_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/ch_list.png
--------------------------------------------------------------------------------
/quiz/src/res/ch_list_inv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/ch_list_inv.png
--------------------------------------------------------------------------------
/quiz/src/res/ch_not_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/ch_not_ok.png
--------------------------------------------------------------------------------
/quiz/src/res/ch_open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/ch_open.png
--------------------------------------------------------------------------------
/quiz/src/res/correct01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/correct01.png
--------------------------------------------------------------------------------
/quiz/src/res/cover-480.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/cover-480.png
--------------------------------------------------------------------------------
/quiz/src/res/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/cover.png
--------------------------------------------------------------------------------
/quiz/src/res/notquite01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/notquite01.png
--------------------------------------------------------------------------------
/quiz/src/res/unknown01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/l0y/learnjava6e/0493242cdd822c00470a5ff14dbcb45aea0b2a41/quiz/src/res/unknown01.png
--------------------------------------------------------------------------------