diff --git a/Chapter_11.adoc b/Chapter_11.adoc index 8787cf5..30f1534 100644 --- a/Chapter_11.adoc +++ b/Chapter_11.adoc @@ -175,7 +175,7 @@ public class MyBufferedByteReader { } } ---- -<1> Here we use the try-with-resources syntax again. This time we create an instance of `FileInputReader` and then and instance of `BufferedInputReader` providing the `FileInputReader` as an argument. This is how we connect to fragments of the pipe that uses the file _abc.dat_ as the source of data. +<1> Here we use the try-with-resources syntax again. This time we create an instance of `FileInputReader` and then an instance of `BufferedInputReader` providing the `FileInputReader` as an argument. This is how we connect to fragments of the pipe that uses the file _abc.dat_ as the source of data. <2> Under the hood the `BufferedInputReader` reads bytes from the disk in chunks into a memory buffer, and then the method `read` reads one byte at time from memory. @@ -254,7 +254,7 @@ If you want to read a text file into a collection, where each element contains o List myFileLines = Files.readAllLines(Paths.get("abc.dat")); ---- -Both `readAllBytes` and `readAllLines` do not use buffers, but for small files is not important. For more efficient reading you can ask the class `Files` to create a buffered stream. For example, the program `MyTextFileReader` uses the method `newBufferedReader` for more efficient reading. Here I used the same file _abc.dat_ located in the root directory of our IDEA project Chapter11. +Both `readAllBytes` and `readAllLines` do not use buffers, but for small files it is not important. For more efficient reading you can ask the class `Files` to create a buffered stream. For example, the program `MyTextFileReader` uses the method `newBufferedReader` for more efficient reading. Here I used the same file _abc.dat_ located in the root directory of our IDEA project Chapter11. [source, java] ---- @@ -334,7 +334,7 @@ This output was produced by the `catch` section from `MyTextFileReader` where th ==== Writing Into a File -Writing into a file is as reading one. Start with creating create an instance of the `Path` object. If you want to write bytes, create a byte array, populate it with data and call the method `write` on the class `Files`. If you want to write some text into a file, just convert the text from a `String` into a byte array and then call the method `write`, for example: +Writing into a file is as reading one. Start with creating an instance of the `Path` object. If you want to write bytes, create a byte array, populate it with data and call the method `write` on the class `Files`. If you want to write some text into a file, just convert the text from a `String` into a byte array and then call the method `write`, for example: [source, java] ---- @@ -539,10 +539,10 @@ The program will print the following: ---- I've got Mary I've got Smith -I've got 123 +I've got 123.5 ---- -The JVM placed `Mary` into the array element `args[0]`, `Smith` into `args[1]`, and `123` into `args[2]`. +The JVM placed `Mary` into the array element `args[0]`, `Smith` into `args[1]`, and `123.5` into `args[2]`. Command-line arguments are always being passed to a program as strings. It’s the responsibility of a program to convert the data to the appropriate data type, for example: @@ -587,7 +587,7 @@ public class FileCopy { if (args.length != 2) { System.out.println( "Please provide source and destination file names, for example:"); - System.out.println("java FIleCopy abc.datcopyOfabc.dat"); + System.out.println("java FileCopy abc.dat copyOfabc.dat"); // Exit the program System.exit(0); diff --git a/Chapter_13.adoc b/Chapter_13.adoc index a56ee9d..71358a9 100644 --- a/Chapter_13.adoc +++ b/Chapter_13.adoc @@ -45,7 +45,7 @@ In this section our goal is to draw a 2D ping-pong table, which should look as a Let's start with creating a new JavaFX project in IntelliJ IDEA. Select JavaFX as a project type. Press Next, and enter PingPong as a project name on the next popup window. Press the button Finish and IDEA will generate a new project for you. Rename (right-click | Refactor | Rename) the file _sample.fxml_ into _pingpong.fxml_, the `Main` class into `PingPong`, and `Controller` into `PingPongController`. Change the name of the package from _sample_ to _pong_ in the same fashion. -Now let's draw the ping-pong table in Scene Builder. Right-click on the file _pingpong.fxml_ and open it in Scene Builder. As you've seen in Chapter 7, the generated FXML uses the `` as a default container. You'll see an empty `GridBag` in the Hierarchy pane. The left side of the Scene Builder panels will look as follows: +Now let's draw the ping-pong table in Scene Builder. Right-click on the file _pingpong.fxml_ and open it in Scene Builder. As you've seen in Chapter 7, the generated FXML uses the `` as a default container. You'll see an empty `GridPane` in the Hierarchy pane. The left side of the Scene Builder panels will look as follows: [[FIG13-2]] image::images/fig_13_Group.png[] @@ -183,7 +183,7 @@ To enable our GUI to react on keyboard events right after the program starts, we To set the focus to the `Group` container we'll need to do two things: -1. Enable the `Group` to receive the focus by useing the attribute `focusTraversable="true"` in _pingpong.fxml_. +1. Enable the `Group` to receive the focus by using the attribute `focusTraversable="true"` in _pingpong.fxml_. 2. Right after the stage is displayed in the `PingPong` class, we'll call the method `requestFocus` on the `Group` container. The method `start` in `PingPong` will look like this (I've added just the last line to the code generated by IDEA): + @@ -350,7 +350,7 @@ Now let's teach the keys Up and Down to move the Kid's paddle vertically. Pressi ---- final int PADDLE_MOVEMENT_INCREMENT = 6; ---- -Pressing the key once will change the vertical position of the paddle by 7 pixels. Seven is not a magical number, and you can use any other integer here. +Pressing the key once will change the vertical position of the paddle by 6 pixels. Six is not a magical number, and you can use any other integer here. The new version of the controller will use the `@FXML` annotations to inject the references to the GUI components. To update the position of the kid's paddle on the GUI we'll use data binding explained in Chapter 8. We'll also add the method `initialize` that is invoked by the Java runtime once when the controller object is created. Finally, we'll write the code in the methods `process_key_Down` and `process_key_Up` to move the kid's paddle vertically. @@ -838,7 +838,7 @@ To check for the ball contact with the Kid's paddle you'd write this line: checkForBallPaddleContact(kidPaddle); ---- -Now let's write the method `bounceTheBall`, which should be very similar to `moveTheBall`. The ball should move from left to write, if you've been decreasing the x-coordinate in `moveTheBall`, you'll need to decrease it now. If you've been stopping the game where the coordinate of the ball was less than -20, now it has to be more than the table width plus 20. I could refactor the method `moveTheBall` to introduce these values as methods arguments, but let's keep it as a small project for you. As long as you understand how the code works, you should be able to do it on your own. Here's the code of the method `bounceTheBall`: +Now let's write the method `bounceTheBall`, which should be very similar to `moveTheBall`. The ball should move from left to right, if you've been decreasing the x-coordinate in `moveTheBall`, you'll need to decrease it now. If you've been stopping the game where the coordinate of the ball was less than -20, now it has to be more than the table width plus 20. I could refactor the method `moveTheBall` to introduce these values as methods arguments, but let's keep it as a small project for you. As long as you understand how the code works, you should be able to do it on your own. Here's the code of the method `bounceTheBall`: [source, java] ---- diff --git a/Chapter_14.adoc b/Chapter_14.adoc index 914e459..36f830e 100644 --- a/Chapter_14.adoc +++ b/Chapter_14.adoc @@ -13,7 +13,7 @@ Software developers make changes in their local copies of the application's code Now Joe has the latest Mary's code, but she doesn't have the latest Joe's code changes. When Joe decides to commit his latest code to the shared repository, Mary can check them out to her computer. -In this chapter I'll introduce you to a popular VCS called Git and to the code hosting facility called GitHub. VCS's are used by programmers writing code in any languages, not only in Java. As a matter of fact you can keep track of any files using Git and store them in GitHub or other hosts. If your computer gets lost or stolen you can always recover the code by _pulling_ it from GitHub. +In this chapter I'll introduce you to a popular VCS called Git and to the code hosting facility called GitHub. VCSs are used by programmers writing code in any languages, not only in Java. As a matter of fact you can keep track of any files using Git and store them in GitHub or other hosts. If your computer gets lost or stolen you can always recover the code by _pulling_ it from GitHub. I was using Git as a VCS and GitHub as a shared repository of the drafts of all chapters of this book, and you can find them on the GitHub at https://github.com/yfain/Java4Kids[https://github.com/yfain/Java4Kids]. @@ -85,7 +85,7 @@ Typically, my work with Git-controlled projects consists of the following activi ==== The status Command -I always start working with Git by opening my project directory and typing _git status_ to see which files I've modified since the last time I've committed the changes to Git repository. Let's do it in the directory _gitIntro_. I havn't committed any files to my brand new code repository just yet, and Git will respond with the following status: +I always start working with Git by opening my project directory and typing _git status_ to see which files I've modified since the last time I've committed the changes to Git repository. Let's do it in the directory _gitIntro_. I haven't committed any files to my brand new code repository just yet, and Git will respond with the following status: [[FIG14-4]] image::images/fig_14_git_status.png[] diff --git a/Chapter_3.adoc b/Chapter_3.adoc index cd83a50..5aa7f51 100644 --- a/Chapter_3.adoc +++ b/Chapter_3.adoc @@ -261,7 +261,7 @@ Java also has a special keyword `final`, and if it’s used in a declaration of ==== How Much Memory is Needed -Variables are stored in a computer's memory and occupy more or less space depending on the data type. We measure memory in bits, bytes, kilobytes (1024 bytes), megabytes (1024 kilobytes or Kb), gigabytes (1024 Mb) and so on. A bit is the smallest piece of data that can be stored in memory. It can hold either 1 or 0. A byte consists of eight bits. +Variables are stored in a computer's memory and occupy more or less space depending on the data type. We measure memory in bits, bytes, kibibytes (1024 bytes), mebibytes (1024 kibibytes or KiB), gibibytes (1024 MiB) and so on. A bit is the smallest piece of data that can be stored in memory. It can hold either 1 or 0. A byte consists of eight bits. * A `char` variable occupies two bytes in memory. diff --git a/Chapter_5.adoc b/Chapter_5.adoc index 56e8dfd..806d950 100644 --- a/Chapter_5.adoc +++ b/Chapter_5.adoc @@ -5,7 +5,7 @@ In this chapter I'll focus on discussing how you can program _behavior_ in Java. Classes have attributes (e.g. color, number of doors) and exhibit behavior (e.g. eat, sleep, or dive). There is a special group of programming languages that are called _functional_ (e.g. JavaScript, Scala et al). In these languages you can simply write functions like `eat`, `sleep`, or `dive`, and these functions can live their independent lives and don't have to be declared in classes. In _object-oriented_ languages behavior is implemented in methods defined in classes. -The phrase _to implement a method_ simply means _to write code in a method_. Starting from Java 8 you can also program behavior in so called _lambda expressions_ covered later in this chapter. +The phrase _to implement a method_ simply means _to write code in a method_. Starting from Java 8 you can also program behavior in so-called _lambda expressions_ covered later in this chapter. So far I was declaring and implementing behavior in methods located inside Java classes. But there is a way and a reason to separate the method declaration from its implementation. Such separation can be done using _interfaces_. @@ -13,11 +13,11 @@ So far I was declaring and implementing behavior in methods located inside Java While you can just create a Java class and implement all its methods there, a more formal way of declaring the behavior of the class in a separate `interface`. Then a class declaration would include the keyword `implements` followed by the name of the interface. This is a way to declare an application program interface (API) - what the class can do - so the programmer can quickly look at the short declaration of the interface rather than going through a longer code of the class. -For years, Java _interfaces_ were used mainly for holding method declarations and `final` `static` variables. For example, the interface `Talkable` contains the declaration of just one method `talk`: +For years, Java _interfaces_ were used mainly for holding method declarations and `final` `static` variables. For example, the interface `Talkative` contains the declaration of just one method `talk`: [source, java] ---- -interface Talkable{ +interface Talkative { public void talk(); } ---- @@ -53,7 +53,7 @@ public class Cat implements Talkative { } ---- -These three classes use the Java keyword `implements`, which means they promise to implement all abstract methods in the interface(s) listed after the keyword `implements` otherwise the Java compiler will complain: "You promised to implement all abstract methods from `Talkable`, where are they? Keep your promise!" +These three classes use the Java keyword `implements`, which means they promise to implement all abstract methods in the interface(s) listed after the keyword `implements` otherwise the Java compiler will complain: "You promised to implement all abstract methods from `Talkative`, where are they? Keep your promise!" What if we need to create the class `Fish` that uses interfaces? Fish don't talk. But they swim. Dogs can talk (bark) and swim, right? Why won't we declare yet another interface `Swimmable` with the methods `swim` and `dive`? @@ -512,7 +512,7 @@ public class CalculatorWithLambdas { The difference between `CalculatorWithAnonymousClasses` from the previous section and `CalculatorWithLambdas` is that the former implements the functional interface as anonymous classes and the latter as lambdas. Lambda expressions offer a concise way of implementation of functional interfaces. To write a lambda expression you need the play by the rules: -1. Declare an the interface that has only one abstract method. +1. Declare an interface that has only one abstract method. 2. Make sure that the arguments of your lambda expression match the arguments of the abstract method. 3. Make sure that the return value of your lambda expression matches the return value of the abstract method. @@ -603,11 +603,11 @@ In Chapter 9 I'll show you more lambda expressions while explaining how to proce 2. Create a package named _pets_. -3. In the package _pets_ recreate the final versions of classes `Dog`, `Fish` and interfaces `Swimmable` and `Talkable` from the section Interfaces. +3. In the package _pets_ recreate the final versions of classes `Dog`, `Fish` and interfaces `Swimmable` and `Talkative` from the section Interfaces. 4. In the package _pets_ create a new class `Pet` with a constructor that will take the name of the pet (of type `String`) as an argument. -5. Change the declarations of the classes `Dog` and `Fish` so each of them extend `Pet` while implementing `Talkable` and `Swimable` interfaces. +5. Change the declarations of the classes `Dog` and `Fish` so each of them extend `Pet` while implementing `Talkative` and `Swimable` interfaces. 6. Create the class `PetMaster` from the section "Interfaces", but give pets names while instantiating classes `Dog` and `Fish`. diff --git a/Chapter_6.adoc b/Chapter_6.adoc index 06e0b32..0e87c85 100644 --- a/Chapter_6.adoc +++ b/Chapter_6.adoc @@ -3,7 +3,7 @@ == Access Levels, Collections, Generics, and Multi-Threading -I'll start this chapter with the explanation of how to hide and protect data using so called access level qualifiers. After that we'll experiment with Java collections - the language elements that can store multiple objects of the same type. Remember arrays and their limitations? Java collections offer alternative ways of storing similar objects. Then you'll get familiar with the mechanism of _generics_ that allows Java compiler to ensure that you won't be using the wrong data types with data collections or other objects. +I'll start this chapter with the explanation of how to hide and protect data using so-called access level qualifiers. After that we'll experiment with Java collections - the language elements that can store multiple objects of the same type. Remember arrays and their limitations? Java collections offer alternative ways of storing similar objects. Then you'll get familiar with the mechanism of _generics_ that allows Java compiler to ensure that you won't be using the wrong data types with data collections or other objects. Finally, I'll give you a very light introduction to parallel computing using multi-threading. @@ -137,7 +137,7 @@ theFish = (Fish) fishTank.get(i); Now let's see how to work with collections of data. Say you have a hundred songs in your MP3 player. It's a collection. If you'll create a class `Song` you can create a hundred of instances of this class (one for each song) and put it in a one of the special data structures called Java collections. -Java packages `java.util` and `java.util.concurrent` include classes that are quite handy when a program needs to store several instances of some objects in memory. There are dozens of collection classes in Java, but I'll just show you a couple of them. Some of the popular collection classes from the package `java.util` are `ArrayList`, `HashTable`, `HashMap`, and `List`. +Java packages `java.util` and `java.util.concurrent` include classes that are quite handy when a program needs to store several instances of some objects in memory. There are dozens of collection classes in Java, but I'll just show you a couple of them. Some of the popular collection classes from the package `java.util` are `ArrayList`, `Hashtable`, `HashMap`, and `List`. The package `java.util.concurrent` has collections useful in programs that require concurrent (simultaneous) access to some data by different parts of a program (by multiple _threads_). I'll introduce you briefly to the concept of multi-threading later in this chapter, but the coverage of concurrent collections doesn't belong to the introductory book like this one. @@ -274,7 +274,7 @@ The `ArrayList` collection uses Java arrays internally and initially creates an ==== The Class Hashtable -While the `ArrayList` collection only allows referencing its elements by index (e.g. `fishTank.get(i)`), sometimes it would be easier to reference collection elements by names as _key/value_ pairs. I'll illustrate by storing my friends' contact information in a `HashTable` collection that allows accessing objects by key names. Let's declare a simple class `ContactDetail`, which can store contact details of one person. +While the `ArrayList` collection only allows referencing its elements by index (e.g. `fishTank.get(i)`), sometimes it would be easier to reference collection elements by names as _key/value_ pairs. I'll illustrate by storing my friends' contact information in a `Hashtable` collection that allows accessing objects by key names. Let's declare a simple class `ContactDetail`, which can store contact details of one person. [source, java] ---- @@ -286,13 +286,13 @@ public class ContactDetail { } ---- -The program `HashTableDemo` will create and populate two instances of `ContactDetail`, will add them to the `Hashtable` collection by names (the keys), and then will print the phone number of the second contact. +The program `HashtableDemo` will create and populate two instances of `ContactDetail`, will add them to the `Hashtable` collection by names (the keys), and then will print the phone number of the second contact. [source, java] ---- import java.util.Hashtable; -public class HashTableDemo { +public class HashtableDemo { public static void main(String[] args) { ContactDetail friend1 = new ContactDetail(); @@ -326,13 +326,13 @@ In this example I used the first name as the key in the method `put` that adds e image::images/fig_6-04-1.png[] -`HashTable` requires each key to be unique. Say you have another contact named `Art` and will create a new instance of the `ContactDetail` object. If you'll add it to the same collection under the same key - `friends.put("Art", friend3);` it'll replace the contact details of the first Art with the data of the second one. This happens because Java `Hashtable` internally generates a hash key (the number) from your key and uses it as an index to find the element when need be.The same names will generate the same hash keys. So either give the second Art a nickname like `ArtFromNYC` or use another Java collection like `ArrayList` to store your contacts. By the way, `ArrayList` even allows you to store duplicates (objects with the same values) while `Hashtable` doesn't. +`Hashtable` requires each key to be unique. Say you have another contact named `Art` and will create a new instance of the `ContactDetail` object. If you'll add it to the same collection under the same key - `friends.put("Art", friend3);` it'll replace the contact details of the first Art with the data of the second one. This happens because Java `Hashtable` internally generates a hash key (the number) from your key and uses it as an index to find the element when need be.The same names will generate the same hash keys. So either give the second Art a nickname like `ArtFromNYC` or use another Java collection like `ArrayList` to store your contacts. By the way, `ArrayList` even allows you to store duplicates (objects with the same values) while `Hashtable` doesn't. I'm not going to cover other Java collections here, but if you'd like to do your own research, read about such collections from the `java.util` package as `HashMap`, `HashSet`, and `LinkedList`. There is also a class `Collections` that has a bunch of useful static methods to operate on your data collections (e.g. `sort`, `copy`, `binarySearch` et al.). === Introduction to Generics -Java generics is a feature that allows you to create so called `parameterized data types`. For example, instead of just declaring a collection that can store any data you can pass it a parameter to allow only the objects of certain data types. Instead of declaring and instantiating a general collection to store friends like this: +Java generics is a feature that allows you to create so-called `parameterized data types`. For example, instead of just declaring a collection that can store any data you can pass it a parameter to allow only the objects of certain data types. Instead of declaring and instantiating a general collection to store friends like this: [source, java] ---- @@ -346,7 +346,7 @@ you can do it with a parameter so it can store only `String` objects like this: ArrayList friends = new ArrayList<>(); ---- -The parameter(s) goes in the angle brackets right after the data type. Note the so called _diamond operator <>_ on the right. Since you already declared the required data type on the left, there is no need to repeat it on the right - compiler will guess the type. It's also an example of type inference introduced in the previous lesson about lambda expressions. Now, if by mistake you'll try to add an object of another type to `friends` the Java compiler will complain. +The parameter(s) goes in the angle brackets right after the data type. Note the so-called _diamond operator <>_ on the right. Since you already declared the required data type on the left, there is no need to repeat it on the right - compiler will guess the type. It's also an example of type inference introduced in the previous lesson about lambda expressions. Now, if by mistake you'll try to add an object of another type to `friends` the Java compiler will complain. I was able to specify a parameter for `ArrayList` only because it was created with this ability. If you'll read the http://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html[online documentation] for `ArrayList` you'll see that it's declared as follows: @@ -369,13 +369,13 @@ implements Map, Cloneable, Serializable But `` simply means that you can specify two parameters: `K` is the the key data type, and `V` for value. -Let's write a program that illustrates the advantages of using generics. I'll reuse the example from the previous section called `HashTableDemo` that stored `ContactDetail` instances. Actually, I'll create two new versions of this program. The first one will be called `HashTableBrokenDemo`, and I'll show how to break this program so it crashes during the runtime if we don't use generics. After that, I'll rewrite it as `HashTableGenericsDemo`, where I'll use generics to show how to prevent the runtime errors from happening. Here's the broken program: +Let's write a program that illustrates the advantages of using generics. I'll reuse the example from the previous section called `HashtableDemo` that stored `ContactDetail` instances. Actually, I'll create two new versions of this program. The first one will be called `HashtableBrokenDemo`, and I'll show how to break this program so it crashes during the runtime if we don't use generics. After that, I'll rewrite it as `HashtableGenericsDemo`, where I'll use generics to show how to prevent the runtime errors from happening. Here's the broken program: [source, java] ---- import java.util.Hashtable; -public class HashTableBrokenDemo { +public class HashtableBrokenDemo { public static void main(String[] args) { ContactDetail friend1 = new ContactDetail(); @@ -399,7 +399,7 @@ public class HashTableBrokenDemo { } ---- -The `HashTableBrokenDemo` adds the first object (for Jackie) of type `ContactDetail` to the `friends` collection, but the contact details for Art are added in the form of a `String`: +The `HashtableBrokenDemo` adds the first object (for Jackie) of type `ContactDetail` to the `friends` collection, but the contact details for Art are added in the form of a `String`: [source, java] ---- @@ -414,18 +414,18 @@ image::images/fig_6_06.png[] The program failed on line 24 with the error `ClassCastException`. The runtime errors are called exceptions in Java, and I'll explain error handling in Chapter 10. But my main point is that this program has crashed during the runtime just because I "forgot" that only the objects of type `ContactDetail` should be stored in the collection `friends`. -Now I'll copy the code of `HashTableBrokenDemo` into the new class called `HashTableGenericsDemo`. I'll make a small change there - I will declare the collection `friends` with parameters: +Now I'll copy the code of `HashtableBrokenDemo` into the new class called `HashtableGenericsDemo`. I'll make a small change there - I will declare the collection `friends` with parameters: [source, java] ---- Hashtable friends = new Hashtable<>(); ---- -Now I'm explicitly stating that my intention is to use the `String` objects for keys, and `ContactDetail` objects as values. The program `HashTableGenericsDemo` is shown next - it won't even compile! +Now I'm explicitly stating that my intention is to use the `String` objects for keys, and `ContactDetail` objects as values. The program `HashtableGenericsDemo` is shown next - it won't even compile! [source, java] ---- -public class HashTableGenericsDemo { +public class HashtableGenericsDemo { public static void main(String[] args) { ContactDetail friend1 = new ContactDetail(); @@ -452,7 +452,7 @@ The compiler will complain about the line, where I'm trying to call the method ` Another important thing to note is that there is no casting needed when the program gets the information about Jackie's phone. Now the `friends` collection knows from the very beginning that it stores not just some `Object` types, but the `ContactDetail` instances. -What have we achieved? The program `HashTableBrokenDemo` allowed us to store anything in the collection but crashed during the runtime, but `HashTableGenericsDemo` prevented this error from happening. Having a compiler's error it's a lot better than getting surprises during the runtime, isn't it? Besides, with generics we've eliminated the need to cast objects. +What have we achieved? The program `HashtableBrokenDemo` allowed us to store anything in the collection but crashed during the runtime, but `HashtableGenericsDemo` prevented this error from happening. Having a compiler's error it's a lot better than getting surprises during the runtime, isn't it? Besides, with generics we've eliminated the need to cast objects. I've been using the parameterized data type `Hashtable` that was conveniently offered by the creators of Java, but you can define your own classes with parameters too. Creating your own parameterized classes is one of the more advanced topics, and I won't be covering it in this book. Check out https://docs.oracle.com/javase/tutorial/java/generics/types.html[Oracle's tutorial] if interested. @@ -477,7 +477,7 @@ A good example of a program that creates multiple threads is a Web browser. For ==== How to Create a Thread -All Java applications that we've created so far (even Hello World) were running in so called _main thread_. We didn't need to do any special programming to create a main thread - Java runtime always creates one thread to each program. But if you want your application code to run in parallel thread, you need to write code to request Java runtime to create a separate thread(s) and execute some code there in parallel with the main thread. +All Java applications that we've created so far (even Hello World) were running in so-called _main thread_. We didn't need to do any special programming to create a main thread - Java runtime always creates one thread to each program. But if you want your application code to run in parallel thread, you need to write code to request Java runtime to create a separate thread(s) and execute some code there in parallel with the main thread. There are different ways of creating threads. I won't be explaining details of each method because it's a pretty advanced topic and is not a good fit for this book. But I'll just list some of the ways of creating threads and will illustrate it with one simple example. These are the main methods of writing code to be executed in a separate thread: diff --git a/Chapter_7.adoc b/Chapter_7.adoc index ca0a58d..2eeaa8d 100644 --- a/Chapter_7.adoc +++ b/Chapter_7.adoc @@ -120,7 +120,7 @@ On the left panel you can select containers, controls, menus, shapes and drag an .Adding a button to the scene image::images/fig_7_05.png[] -The right panel allows you to change the properties of this button. These little boxes with the digit one represent so called row and column constraints - we'll discuss them shortly. +The right panel allows you to change the properties of this button. These little boxes with the digit one represent so-called row and column constraints - we'll discuss them shortly. The Scene Builder's menu Preview | Show Preview in Window will show how your GUI will look during the runtime. So far our one-button screen is not too fancy, and this is how it's preview looks like: @@ -373,12 +373,13 @@ If you want to apply a style to several components of the same type, you need to } ---- -Note that CSS type selectors start with the dot. To create a _CSS class selector_ that can be applied to any component, define the selector with an arbitrary name and apply it programmatically to the components of your choice. For example, you can specify the class selector `.blueLable`: +Note that CSS type selectors start with the dot. To create a _CSS class selector_ that can be applied to any component, define the selector with an arbitrary name and apply it programmatically to the components of your choice. For example, you can specify the class selector `.bluelabel`: [source, xml] ---- .bluelabel{ -fx-text-fill: blue; + -fx-font-weight: bold; -fx-font-family:verdana; -fx-font-style:italic; } diff --git a/Chapter_8.adoc b/Chapter_8.adoc index 8bf5659..1a327f9 100644 --- a/Chapter_8.adoc +++ b/Chapter_8.adoc @@ -7,7 +7,7 @@ After the GUI design is done, we need to hook it up with the application code w When IDEA creates a new JavaFX project it generates an empty class `Controller`, which is the right place for the code that communicates with GUI components. In this chapter we'll establish a link between GUI and the controller. We'll also add event handlers and will write code to modify the GUI. I'll continue working with FXML samples created in the previous chapter, but this time the GUI events will be handled by the code from the controller class. -You'll learn how data binding can automatically update the properties of a GUI component if a property of a Java controller class changes. I'll also show the difference between wrong and the right way of updating the GUI to make the used interaction more responsive. +You'll learn how data binding can automatically update the properties of a GUI component if a property of a Java controller class changes. I'll also show the difference between wrong and the right way of updating the GUI to make the user interaction more responsive. === Events @@ -22,7 +22,7 @@ You can create an instance of your controller class either with the `new` operat Scene Builder allows you to not only design and arrange the GUI components on the scene, but also assign the Java code that will be handing events. We'll stick to our principles of separating GUI and application logic, and will keep the GUI in `.fxml` file, meanwhile application logic will be programmed in Java. -In Scene Builder you may have noticed the _Controller_ bar in the bottom left corner. This is the place were you can specify a Java class that will contain event handling code and may use other classes implementing application logic. You can also open your `.fxml` file in the text editor and type in the name of the controller class there. If you'll look at any of the FXML files from Chapter 7, you'll see that the name of the controller was specified there when IDEA generated the project for us. +In Scene Builder you may have noticed the _Controller_ bar in the bottom left corner. This is the place where you can specify a Java class that will contain event handling code and may use other classes implementing application logic. You can also open your `.fxml` file in the text editor and type in the name of the controller class there. If you'll look at any of the FXML files from Chapter 7, you'll see that the name of the controller was specified there when IDEA generated the project for us. ==== Adding Controller to Sign In application @@ -34,7 +34,7 @@ To illustrate the use of controllers, I'll continue working on the sample Sign I xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="signin.Controller"> ---- -The `hgap` and `vgap` attributes specify the padding between the grid columns and rows. The `xmlns` attributes specify so called namespaces required for proper parsing of FXML files. And the attribute `fx:controller` specifies the full name of the class `Controller`, which in our project is located in the package `signin`. +The `hgap` and `vgap` attributes specify the padding between the grid columns and rows. The `xmlns` attributes specify so-called namespaces required for proper parsing of FXML files. And the attribute `fx:controller` specifies the full name of the class `Controller`, which in our project is located in the package `signin`. When the file `signin.fxml` is loaded, `FXMLLoader` creates an instance of the Java class based on the FXML content and then instantiates and injects the`signin.Controller` object into the GUI object. The word _inject_ describes the process when a runtime automatically instantiates a class B and makes it available in class A. For us it means that there is no need to manually create an instance of the `signin.Controller` by using the `new` operator. @@ -91,7 +91,7 @@ image::images/fig_8_04.png[] Now that we know how to link the controller's event handlers to FXML components, the next question is how to read/write data from/to these components. In the case of the sign in application we need to know what ID/password the user entered and update the GUI from the controller accordingly. -To read the values from GUI components we'll need to give them unique id's in the FXML file. We don't need to give id's to all components - only to those that we want to process in the controller's code. Take a look at the `` section of `signin.fxml`: +To read the values from GUI components we'll need to give them unique ids in the FXML file. We don't need to give id's to all components - only to those that we want to process in the controller's code. Take a look at the `` section of `signin.fxml`: [source, xml] ---- @@ -115,7 +115,7 @@ Only the `TextField` and `PasswordField` have the attribute `fx:id` - this is ho @FXML private PasswordField pwd; ---- -Java has so called http://docs.oracle.com/javase/tutorial/java/annotations/[annotations] (not covered in this book). They start with the `@` sign and can be placed in front of the variable, class, or a method declaration depending on how the annotation was defined. Some annotations are used by Java compiler, and some by the JVM. The JavaFX annotation `@FXML` instructs runtime to inject the references to the specifies GUI objects into the variables. +Java has so-called http://docs.oracle.com/javase/tutorial/java/annotations/[annotations] (not covered in this book). They start with the `@` sign and can be placed in front of the variable, class, or a method declaration depending on how the annotation was defined. Some annotations are used by Java compiler, and some by the JVM. The JavaFX annotation `@FXML` instructs runtime to inject the references to the specified GUI objects into the variables. In other words, JavaFX runtime will read the first line as follows: _"I need to get the object that I created after loading `signin.fxml` file, and find the component with `fx:id="id"` inside this object. Finally, I need to insert the reference to this component into the Java variable ``id``"_. The same applies to the variable `pwd`. @@ -162,7 +162,7 @@ image::images/fig_8_05.png[] ==== Assigning Event Handlers in Java -If your program is written completely in Java without any use of FXML, you'll be assigning event handlers using so called http://docs.oracle.com/javafx/2/events/convenience_methods.htm[convenience methods] that have names that start with `setOn` like `setOnAction`, `setOnKeyTyped`, `setOnEditStart` etc. Each of the GUI components have several of such methods. +If your program is written completely in Java without any use of FXML, you'll be assigning event handlers using so-called http://docs.oracle.com/javafx/2/events/convenience_methods.htm[convenience methods] that have names that start with `setOn` like `setOnAction`, `setOnKeyTyped`, `setOnEditStart` etc. Each of the GUI components have several of such methods. You can provide event handling code to the convenience methods using anonymous inner classes, lambda expressions, or http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html[method references] (not covered in this book). Implementing event handlers as lambda expressions is easier than with anonymous inner classes. Typically, you'll be writing code to react if an event has happened. For example, if you have a button represented by a variable `myButton` you can write an event handler for the click event: @@ -270,7 +270,7 @@ public class MainPureJava extends Application { <7> This lambda expression implements the application logic to be invoked as a reaction to the `ActionEvent`. -<8> We create a scene object and apply the CSS to it. This is probably the first time you see so called _method chaining_. All these lines that starts with dots are methods chained together - all of them are sequentially invoked on the scene object. +<8> We create a scene object and apply the CSS to it. This is probably the first time you see so-called _method chaining_. All these lines that starts with dots are methods chained together - all of them are sequentially invoked on the scene object. <9> Finally, the scene is added to the stage and the curtain goes up. @@ -294,7 +294,7 @@ Over the years software developers have come up with a number of _design pattern *MVC* stands for Mode View Controller. This design pattern recommends separating the code that stores application data (Model) from the code implementing the user interface (View) and from the code that controls the data exchange and implements application logic (Controller). As a matter of fact we've almost implemented MVC in one of the versions of the Sign In application. The file `signin.fxml` was a view, and the class `Controller` played a role of a controller. Since this example had just two variables (`id` and `pwd`) we didn't create a special model class for them. -*Observer* design pattern is used to implement scenarios when one object, a.k.a. the observer needs to watch changes in other object(s), the observables. For example, if a Twitter user (the observable) posts a twit all of his followers (observers) will get notified. If a programming language or a library supports data binding, implementing the observer design pattern becomes pretty easy, which you'll see later in this chapter. +*Observer* design pattern is used to implement scenarios when one object, a.k.a. the observer needs to watch changes in other object(s), the observables. For example, if a Twitter user (the observable) posts a tweet all of his followers (observers) will get notified. If a programming language or a library supports data binding, implementing the observer design pattern becomes pretty easy, which you'll see later in this chapter. If you're interested in detailed coverage of design patterns, get the book "Head First Design Patterns" published by O'Reilly Media. **************************** @@ -305,7 +305,7 @@ As we always do in this book, let's learn by coding. I'll continue adding featur The next step is to declare a _bindable_ property `signinError` in the class `Controller` that will get the value of the error message if any. But since a regular `String` can't be bindable, we'll use the data type `SimpleStringProperty` -Finally, I'll bind the label to the variable to insure that an error message is immediately displayed on the screen as soon as its value changes. +Finally, I'll bind the label to the variable to ensure that an error message is immediately displayed on the screen as soon as its value changes. Let's place an additional `Label` component at the bottom of the Sign In window. I'll add another row to the `GridPane` and place a `Label` there that will span two columns. This label will have `fx:id="errMsg"` and initially won't have any text - it'll be invisible. The `` section of the FXML file will look as follows: @@ -403,11 +403,11 @@ In Chapter 6 I gave you a light introduction to multi-threading. When you work w Imagine a program with a GUI that's constantly being updated based on some intensive calculations. It could be a game with multiple moving shapes. It could be an application for a TV channel that may show a video stream, commercials, viewers polls and more. It could be a business application that displays several pieces of constantly changing information in different parts of the window like prices on eBay auction. -Updates of the GUI in JavaFX are done in so called _application thread_. The idea is to separate calculations from the GUI updates. Say, the user clicked on the button Play on a JavaFX video streaming application like Netflix. If the requests for the remote video and actual playing of the video (GUI updates) would be done in the same application thread, the video would be choppy - it would be interrupted by running business logic that prepares the GUI content. The screen would be "frozen" and the user wouldn't be able to use any screen components. +Updates of the GUI in JavaFX are done in so-called _application thread_. The idea is to separate calculations from the GUI updates. Say, the user clicked on the button Play on a JavaFX video streaming application like Netflix. If the requests for the remote video and actual playing of the video (GUI updates) would be done in the same application thread, the video would be choppy - it would be interrupted by running business logic that prepares the GUI content. The screen would be "frozen" and the user wouldn't be able to use any screen components. ==== The Frozen Screen Demo -I will demonstrate for you a "frozen GUI" effect by making a small change in the class `Controller` in our Sign In application. The simplest way to emulate a long running process is to place the currently running thread to sleep, as if there is an application logic that takes some time to complete. For example, to put the current thread to sleep for 10 second, you can write the following: +I will demonstrate for you a "frozen GUI" effect by making a small change in the class `Controller` in our Sign In application. The simplest way to emulate a long running process is to place the currently running thread to sleep, as if there is an application logic that takes some time to complete. For example, to put the current thread to sleep for 10 seconds, you can write the following: [source, java] ---- @@ -524,7 +524,7 @@ In the chapter on Ping-Pong game we'll use multiple threads too. One thread will How do you start a JavaFX application? Well, you can start it either from the IDE or from a command line as any other Java application. But if you want to give your application to your grandma, who may not be as good at Java as you are? Of course, you can pay her a visit, install the Java runtime on her computer, and teach her how to open a command or Terminal window and enter `java signin.Main`. -You may learn how to use scripting languages and create a file `signin.bat` in Windows or `signin.sh` in MAC OS that will have the `java signin.Main` command inside. You can even create an icon that will run this script. But what if everyone in your school wants to have your program installed on their computers? Now if becomes a time-consuming task. +You may learn how to use scripting languages and create a file `signin.bat` in Windows or `signin.sh` in MAC OS that will have the `java signin.Main` command inside. You can even create an icon that will run this script. But what if everyone in your school wants to have your program installed on their computers? Now it becomes a time-consuming task. But the best way to prepare your JavaFX application for distribution is to create a self-contain file `signin.exe` for Windows or `signin.dmg` for MAC OS. This file will contain both the Java runtime and your application code. This process is described in details in Oracle's tutorial titled http://docs.oracle.com/javafx/2/deployment/self-contained-packaging.htm#BCGIBBCI["Self-Contained Application Packaging]. I'm not going to repeat this tutorial here, but will leave it for you as a self-study project. @@ -546,7 +546,7 @@ The goal of this project is to complete the calculator program. If you completed 1. Create a Java class `CalculatorController` in the same IDEA project where the calculator's GUI is located. -2. Modify the file `calculator.fxml`: add the attribute `fx:controller="CalculatorController"` so it knows the name of the class with the application logic. Use the code of `signing.fxml` from this chapter as reference. +2. Modify the file `calculator.fxml`: add the attribute `fx:controller="CalculatorController"` so it knows the name of the class with the application logic. Use the code of `signin.fxml` from this chapter as reference. 3. Create two separate event handler methods in the class `CalculatorController`. Name the first method `digitClickedHandler` - it will contain the code to process clicks on the digit buttons. Name the second method `operationClickHandler` - it will contain the code to process clicks on such buttons as Plus, Minus, et al. diff --git a/Chapter_9.adoc b/Chapter_9.adoc index 48c5ead..64e3e26 100644 --- a/Chapter_9.adoc +++ b/Chapter_9.adoc @@ -5,11 +5,11 @@ In this chapter I'll explain to you how to handle run-time errors, which in Java are called _exceptions_. -Say you forgot to write one closing curly brace in your Java code. This will result in a compilation error that can be fixed easily. But there are so called _run-time errors_, when your program stops working properly and prints error messages. +Say you forgot to write one closing curly brace in your Java code. This will result in a compilation error that can be fixed easily. But there are so-called _run-time errors_, when your program stops working properly and prints error messages. For example, a Java class reads a file with the game scores. What’s going to happen if someone will delete this file? Will the program crash with a scary error message, or will it stay alive displaying a user friendly message like this one: _Dear friend, for some reason I could not read the file scores.txt. Please make sure that the file exists?_ This is an example of a situation when Java compiler won't be able to help - the Java syntax was written properly. -You should make your programs ready for unexpected situations. you should foresee what might go wrong when the program will be running, and what to do if something went wrong. In many programming languages the programmer decides if he wants to add error processing code to a program. But in many cases Java forces you to include error processing code, otherwise the programs will not even compile. +You should make your programs ready for unexpected situations. You should foresee what might go wrong when the program will be running, and what to do if something went wrong. In many programming languages the programmer decides if he wants to add error processing code to a program. But in many cases Java forces you to include error processing code, otherwise the programs will not even compile. Runtime errors in Java are called exceptions, and error processing is called _exception handling_. You have to place code that may produce errors in so-called `try/catch` block. It’s as if you’re saying to JVM the following: _Try to read the file with scores, but if something happens, catch the error and execute the code that will deal with it:_ @@ -29,7 +29,7 @@ The `ioe` in the above code fragment is a variable that represents the `IOExcept We’ll learn how to work with files in Chapter 11, but at this point I'd like to introduce a new term _I/O_ or _input/output_. Read and write operations (from/to disk or other device) are also known as I/O operations, and the class `IOException` is a class that contains information about input/output errors. -In the Java world, a method _throws an exception_ in case of a runtime error. Different exceptions will be thrown for different type of errors. If the `catch` block exists in the program for this particular type of an error, it will be caught and the program will jump into the `catch` block to execute the code located there. The program will stay alive, and this exception is considered to be taken care of. +In the Java world, a method _throws an exception_ in case of a runtime error. Different exceptions will be thrown for different types of errors. If the `catch` block exists in the program for this particular type of an error, it will be caught and the program will jump into the `catch` block to execute the code located there. The program will stay alive, and this exception is considered to be taken care of. The print statement from the code above will be executed only in case of a file read error. @@ -100,20 +100,20 @@ Of course you are welcome to read Java documentation that describes exceptions t There are five Java keywords that can be used for error handling: `try`, `catch`, `finally`, `throw`, and `throws`. -After one `try` block you may put several `catch` blocks, if you believe that more than one error may happen. For example, when a program tries to read a file, the file may not be there, and you’ll get the `FileNotFoundException`, or the file is there, but the code keeps reading the file after reaching the end of file – this generates `EOFException`. The next code fragment will print messages in plain English if the program can’t find a file with game scores or reached the end of the file. For any other read errors it’ll print the message _Problem reading_ file and a technical description of the error. +After one `try` block you may put several `catch` blocks, if you believe that more than one error may happen. For example, when a program tries to read a file, the file may not be there, and you’ll get the `FileNotFoundException`, or the file is there, but the code keeps reading the file after reaching the end of file – this generates `EOFException`. The next code fragment will print messages in plain English if the program can’t find a file with game scores or reached the end of the file. For any other read errors it’ll print the message _Problem reading file_ and a technical description of the error. [source, java] ---- public void getScores(){ try{ fileScores.read(); - System.out.println(“Scores loaded successfully”); + System.out.println("Scores loaded successfully"); }catch(FileNotFoundException e){ - System.out.println(“Can not find file Scores”); + System.out.println("Can not find file Scores"); }catch(EOFException e1){ - System.out.println(“Reached end of file”); + System.out.println("Reached end of file"); }catch(IOException e2){ - System.out.println(“Problem reading file “ + + System.out.println("Problem reading file " + e2.getMessage()); } } @@ -131,7 +131,7 @@ public void getScores(){ try{ fileScores.read(); }catch(Exception e){ - System.out.println(“Problem reading file ”+ + System.out.println("Problem reading file " + e.getMessage()); } } @@ -144,11 +144,11 @@ Catch blocks receive an instance of the object `Exception` that contains a short [source, java] ---- catch(Exception e){ - System.out.println(“Problem reading file ”+ e.toString()); + System.out.println("Problem reading file " + e.toString()); } ---- -If you need more detailed information about the exception, use the method `printStackTrace`. It will print the sequence of method calls that lead to this exception similar to an example from the section _Reading Stack Trace_. +If you need more detailed information about the exception, use the method `printStackTrace`. It will print the sequence of method calls that lead to this exception similarly to an example from the section _Reading Stack Trace_. === The keyword `throws` @@ -168,7 +168,7 @@ class MySuperGame{ public static void main(String[] args){ MySuperGame msg = new MySuperGame(); - System.out.println(“List of Scores”); + System.out.println("List of Scores"); try{ // Since the getAllScores()declares exception, @@ -189,7 +189,7 @@ Imagine that the `MySuperGame` program invokes multiple methods that read or wri Any code within a `try/catch` block can end in one of the following ways: * The code inside the `try` block successfully ended and the program continues. -* The code inside the `try` block runs into a `return` statement and the method is exited.For example, you may read a file line by line, and if the line contains a certain text, you may want to stop reading the file. Just write a return statement, and the method is exited, e.g. +* The code inside the `try` block runs into a `return` statement and the method is exited. For example, you may read a file line by line, and if the line contains a certain text, you may want to stop reading the file. Just write a return statement, and the method is exited, e.g. + [source, java] ---- @@ -234,11 +234,11 @@ If the myMethod will throw an exception it will be handled in the calling method === The Keyword `throw` -When you read in Java documentation that some methods may throw an exception, it means that the programmer who wrote this method used a special throw keyword to do this. The `throw` keyword is used to throw Java objects, which are throwable. You can only throw objects that are direct or indirect subclasses of the class `Throwable`. We can guess, that the author of the method that reads a file used the `throw` keyword in the method `read`. This could have been done as follows: +When you read in Java documentation that some methods may throw an exception, it means that the programmer who wrote this method used a special throw keyword to do this. The `throw` keyword is used to throw Java objects, which are throwable. You can only throw objects that are direct or indirect subclasses of the class `Throwable`. We can guess, that the author of the method that reads a file used the `throw` keyword in the method `read`. This could have been done as follows: [source, java] ---- -throw new IOException(“The file scores.txt contains invalid characters”); +throw new IOException("The file scores.txt contains invalid characters"); ---- The constructor of any exception should get a message that describes the error as an argument. When you’ll be invoking the `getMessage` method on the exception object in the catch block, it’ll print the message that was given to the constructor in the code that has thrown the exception. @@ -248,11 +248,11 @@ The constructor of any exception should get a message that describes the error a .Throwing exceptions image::images/fig_9_02.png[] -In the next section I’ll show you how create your own exception classes and throw them with the throw keyword. +In the next section I’ll show you how to create your own exception classes and throw them with the throw keyword. === Creating Custom Exceptions -Programmers could also create new exception classes that did not exist in Java before. Such classes have to derive from one of the Java exception classes. Let’s say you are in business of selling bikes and need to _validate_ customer orders. Different number of bikes can fit in your small truck depending on the model. For example, you can fit no more than three FireBird bikes in your truck. You can create a new subclass of `Exception` called `TooManyBikesException`, and if someone tries to order more than three of these bikes, throw this exception: +Programmers could also create new exception classes that did not exist in Java before. Such classes have to derive from one of the Java exception classes. Let’s say you are in business of selling bikes and need to _validate_ customer orders. Different number of bikes can fit in your small truck depending on the model. For example, you can fit no more than three FireBird bikes in your truck. You can create a new subclass of `Exception` called `TooManyBikesException`, and if someone tries to order more than three of these bikes, throw this exception: [source, java] ----