Apr 28, 2017

JavaFX: Bloom and Glow Classes

Here, you find out how to make your ordinary JavaFX shapes bloom and glow, all with the help of two simple classes, unsurprisingly named Bloom and Glow. This table shows the members of these two classes.

The Bloom and Glow Classes
Constructor Explanation
Bloom() Creates a new Bloom effect with default parameters.
Glow() Creates a new Glow effect with default parameters.
Bloom Method Explanation
void setThreshhold(double value) Sets the luminosity threshold. The bloom effect will be applied
to portions of the shape that are brighter than the threshold. The
value can be 0.0 to 1.0. The default value is 0.3.
Glow Method Explanation
void setLevel(double value) Sets the intensity of the effect’s glow level. The value
can be 0.0 to 1.0. The default value is 0.3.

The figure shows the effect of the Bloom and Glow effects. All three of the text shapes shown in the figure are combined with a rectangle in a group. The following code was used to create the first group (shown at the top of the figure):

Rectangle r1 = new Rectangle(50, 50, 400, 100);r1.setFill(Color.BLACK);r1.setStroke(Color.BLACK);Text t1 = new Text("Plain Text");t1.setX(130);t1.setY(125);t1.setFont(new Font("Times New Roman", 60));t1.setFill(Color.LIGHTGRAY);Group g1 = new Group();g1.getChildren().addAll(r1, t1);

Similar code was used to create the second group (shown in the middle of the figure), but a Bloom effect was added:

Rectangle r2 = new Rectangle(50, 50, 400, 100);r2.setFill(Color.BLACK);r2.setStroke(Color.BLACK);Text t2 = new Text("Blooming Text");t2.setX(70);t2.setY(125);t2.setFont(new Font("Times New Roman", 60));t2.setFill(Color.LIGHTGRAY);Group g2 = new Group();g2.getChildren().addAll(r2, t2);Bloom e1 = new Bloom();e1.setThreshold(0.3);g2.setEffect(e1);

For the third group, a Glow effect was added instead:

Three texts with bloom and glow effects created on JavaFX.

Rectangle r3 = new Rectangle(50, 50, 400, 100);r3.setFill(Color.BLACK);r3.setStroke(Color.BLACK);Text t3 = new Text("Glowing Text");t3.setX(80);t3.setY(125);t3.setFont(new Font("Times New Roman", 60));t3.setFill(Color.LIGHTGRAY);Group g3 = new Group();g3.getChildren().addAll(r3, t3);Glow e2 = new Glow();e2.setLevel(1.0);g3.setEffect(e2);

The difference between the bloom and glow effect is subtle. To be honest, it’s barely noticeable. If you look very closely, you’ll see that the glowing text is just a tad brighter than the blooming text. (The distinction between glow and bloom is more noticeable when colors other than black and white are used.)

JavaFX Controls: ScrollBar

The ScrollBar control in JavaFX is not usually used by itself; instead, it is used by other controls such as ScrollPane or ListView to display the scroll bar that lets the user scroll the contents of a panel or other region.

However, there are occasions when you might want to use a scroll bar for some purpose other than scrolling a region. In fact, you can actually use a scroll bar in much the same way as you use a slider, as the two are very similar.

One difference is that unlike a slider, a scroll bar does not allow tick marks. But on the other hand, a scroll bar has increment and decrement buttons on either end of the bar, which allows the user to set the scroll bar’s value up or down in fixed increments.

This figure shows a version of an audio mixer, only implemented with scroll bars. As in the slider version, each scroll bar is paired with a Text object that displays the scroll bar’s value whenever the user manipulates the control.

You can use the following helper method to create each combined scroll bar and Text object:

Using JavaFX scroll bars to create a mixer board.
Using JavaFX scroll bars to create a mixer board.
private Node makeScrollBar(int value){    Text text = new Text();    text.setFont(new Font("sans-serif", 10));    ScrollBar sb = new ScrollBar();    sb.setOrientation(Orientation.VERTICAL);    sb.setPrefHeight(150);    sb.valueProperty().addListener(        (observable, oldvalue, newvalue) ->        {            int i = newvalue.intValue();            text.setText(Integer.toString(100-i));        }        );    sb.setValue(value);    VBox box = new VBox(10, sb, text);    box.setPadding(new Insets(10));    box.setAlignment(Pos.CENTER);    box.setMinWidth(30);    box.setPrefWidth(30);    box.setMaxWidth(30);    return box;}

Repeat Instructions: Java while Statements

Here’s a guessing game for you to test out your understanding of Java. The computer generates a random number from 1 to 10. The computer asks you to guess the number. If you guess incorrectly, the game continues. As soon as you guess correctly, the game is over. This listing shows the program to play the game, and the figure shows a round of play.

A round of a game created on Java.

import static java.lang.System.out;import java.util.Scanner;import java.util.Random;public class GuessAgain {    public static void main(String args[]) {        Scanner keyboard = new Scanner(System.in);        int numGuesses = 0;        int randomNumber = new Random().nextInt(10) + 1;        out.println("       ************         ");        out.println("Welcome to the Guessing Game");        out.println("       ************         ");        out.println();        out.print("Enter an int from 1 to 10: ");        int inputNumber = keyboard.nextInt();        numGuesses++;        while (inputNumber != randomNumber) {            out.println();            out.println("Try again...");            out.print("Enter an int from 1 to 10: ");            inputNumber = keyboard.nextInt();            numGuesses++;        }        out.print("You win after ");        out.println(numGuesses + " guesses.");        keyboard.close();    }}

In the figure, the user makes four guesses. Each time around, the computer checks to see whether the guess is correct. An incorrect guess generates a request to try again. For a correct guess, the user gets a rousing You win, along with a tally of the number of guesses he or she made.

The computer repeats several statements, checking each time through to see whether the user’s guess is the same as a certain randomly generated number. Each time the user makes a guess, the computer adds 1 to its tally of guesses. When the user makes the correct guess, the computer displays that tally. The figure illustrates the flow of action.

The flow of action in a game created on Java.

When you look over the listing, you see the code that does all this work. At the core of the code is a thing called a while statement (also known as a while loop). Rephrased in English, the while statement says:

while the inputNumber is not equal to the randomNumberkeep doing all the stuff in curly braces: {}

The stuff in curly braces (the stuff that repeats) is the code that prints Try again and Enter an int . . ., gets a value from the keyboard, and adds 1 to the count of the user’s guesses.

When you’re dealing with counters, like numGuesses in the listing, you may easily become confused and be off by 1 in either direction. You can avoid this headache by making sure that the ++ statements stay close to the statements whose events you’re counting.

For example, in the listing, the variable numGuesses starts with a value of 0. That’s because, when the program starts running, the user hasn’t made any guesses. Later in the program, right after each call to keyboard.nextInt, is a numGuesses++ statement. That’s how you do it — you increment the counter as soon as the user enters another guess.

The statements in curly braces are repeated as long as inputNumber != randomNumber is true. Each repetition of the statements in the loop is called an iteration of the loop. In the figure, the loop undergoes three iterations. (If you don’t believe that the figure has exactly three iterations, count the number of Try again printings in the program’s output. A Try again appears for each incorrect guess.)

When, at long last, the user enters the correct guess, the computer goes back to the top of the while statement, checks the condition in parentheses, and finds itself in double double-negative land. The not equal (!=) relationship between inputNumber and randomNumber no longer holds.

In other words, the while statement’s condition, inputNumber != randomNumber, is false. Because the while statement’s condition is false, the computer jumps past the while loop and goes on to the statements just below the while loop. In these two statements, the computer prints You win after 4 guesses.

With code of the kind shown in the listing, the computer never jumps out in mid-loop. When the computer finds that inputNumber isn’t equal to randomNumber, the computer marches on and executes all five statements inside the loop’s curly braces. The computer performs the test again (to see whether inputNumber is still not equal to randomNumber) only after it fully executes all five statements in the loop.

JavaFX Programming Example: 3D Box

JavaFX has built-in support for realistic 3D modeling. In fact, the JavaFX scene graph is three-dimensional in nature. Most JavaFX programs work in just two dimensions, specifying just x- and y-coordinates. But all you __have to do to step into the third dimension is specify z-coordinates to place the nodes of your scene graph in three-dimensional space.

JavaFX includes a rich set of classes that are dedicated to creating and visualizing 3D objects in 3D worlds. You can create three-dimensional shapes, such as cubes and cylinders. You can move the virtual camera around within the 3D space to look at your 3D objects from different angles and different perspectives.

And you can even add lighting sources to carefully control the final appearance of your virtual worlds. In short, JavaFX is capable of producing astonishing 3D scenes.

Add a 3D box to your Java world

In this step, add an object to the 3D world: In this case, a box, represented by the Box class. Here’s the code:

Box box = new Box(100, 100, 100);box.setMaterial(blueStuff);box.setTranslateX(150);box.setTranslateY(-100);box.setTranslateZ(-100);root.getChildren().add(box);

The Box constructor accepts three arguments representing the width, height, and depth of the box. In this example, all three are set to 100. Thus, the box will be drawn as a cube with each side measuring 100 units.

The box is given the same material as the cylinder; then, it is translated on all three axes so that you can __have a perspective view of the box. The figure shows how the box appears when rendered. As you can see, the left and bottom faces of the box are visible because you translated the position of the box up and to the right so that the camera can gain some perspective.

A 3D box created on JavaFX.

Rotate the 3D box

In this step, rotate the box to create an even more interesting perspective view. There are two ways to rotate a 3D object. The simplest is to call the object’s setRotate method and supply a rotation angle:

box.setRotate(25);

By default, this will rotate the object on its z-axis. If this is difficult to visualize, imagine skewering the object with a long stick that is parallel to the z-axis. Then, spin the object on the skewer.

If you want to rotate the object along a different axis, first call the setRotationAxis. For example, to spin the object on its x-axis, use this sequence:

box.setRotationAxis(Rotate.X_AXIS);box.setRotate(25);

Imagine running the skewer through the box with the skewer parallel to the x-axis and then spinning the box 25 degrees.

The only problem with using the setRotate method to rotate a 3D object is that it works only on one axis at a time. For example, suppose you want to rotate the box 25 degrees on both the z- and the x-axis. The following code will not accomplish this:

box.setRotationAxis(Rotate.X_AXIS);box.setRotate(25);box.setRotationAxis(Rotate.Z_AXIS);box.setRotate(25);

When the setRotate method is called the second time to rotate the box on the z-axis, the x-axis rotation is reset.

To rotate on more than one axis, you must use the Rotate class instead. You create a separate Rotate instance for each axis you want to rotate the object on and then add all the Rotate instances to the object’s Transforms collection via the getTransforms().addAll method, like this:

Rotate rxBox = new Rotate(0, 0, 0, 0, Rotate.X_AXIS);Rotate ryBox = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);Rotate rzBox = new Rotate(0, 0, 0, 0, Rotate.Z_AXIS);rxBox.setAngle(30);ryBox.setAngle(50);rzBox.setAngle(30);box.getTransforms().addAll(rxBox, ryBox, rzBox);

The Rotate constructor accepts four parameters. The first three are the x-, y-, and z-coordinates of the point within the object through which the rotation axis will pass. Typically, you specify zeros for these parameters to rotate the object around its center point. The fourth parameter specifies the rotation axis.

This figure shows how the box appears after it’s been rotated.

A rotated 3d box made on JavaFX
The box after it’s been rotated.

Using JUnit

JUnit is a standardized framework for testing Java units (that is, Java classes). JUnit can be automated to take the some of the work out of testing.

Imagine you’ve created an enum type with three values: GREEN, YELLOW, and RED. Listing 1 contains the code:

Listing 1

public enum SignalColor {  GREEN, YELLOW, RED}

A traffic light has a state (which is a fancy name for the traffic light’s color).

public class TrafficLight {  SignalColor state = SignalColor.RED;

If you know the traffic light’s current state, you can decide what the traffic light’s next state will be.

public void nextState() {  switch (state) {  case RED:    state = SignalColor.GREEN;    break;  case YELLOW:    state = SignalColor.RED;    break;  case GREEN:    state = SignalColor.YELLOW;    break;  default:    state = SignalColor.RED;    break;  }}

You can also change the traffic light’s state a certain number of times:

public void change(int numberOfTimes) {  for (int i = 0; i < numberOfTimes; i++) {    nextState();  }}

Putting it all together, you __have the TrafficLight class in Listing 2.

Listing 2

public class TrafficLight {  SignalColor state = SignalColor.RED;  public void nextState() {    switch (state) {    case RED:      state = SignalColor.GREEN;      break;    case YELLOW:      state = SignalColor.RED;      break;    case GREEN:      state = SignalColor.YELLOW;      break;    default:      state = SignalColor.RED;      break;    }  }  public void change(int numberOfTimes) {    for (int i = 0; i < numberOfTimes; i++) {      nextState();    }  }}

In the olden days you might __have continued writing code, creating more classes, calling the nextState and change methods in Listing 2. Then, after several months of coding, you’d pause to test your work.

And what a surprise! Your tests would fail miserably! You should never delay testing for more than a day or two. Test early and test often!

One philosophy about testing says you should test each chunk of code as soon as you’ve written it. Of course, the phrase “chunk of code” doesn’t sound very scientific. It wouldn’t do to have developers walking around talking about the “chunk-of-code testing” that they did this afternoon. It’s better to call each chunk of code a unit, and get developers to talk about unit testing.

The most common unit for testing is a class. So a typical Java developer tests each class as soon as the class’s code is written.

So how do you go about testing a class? A novice might test the TrafficLight class by writing an additional class — a class containing a main method. The main method creates an instance of TrafficLight, calls the nextState and change methods, and displays the results. The novice examines the results and compares them with some expected values.

After writing main methods for dozens, hundreds, or even thousands classes, the novice (now a full-fledged developer) becomes tired of the testing routine and looks for ways to automate the testing procedure. Tired or not, one developer might try to decipher another developer’s hand-coded tests. Without having any standards or guidelines for constructing tests, reading and understanding another developer’s tests can be difficult and tedious.

So JUnit comes to the rescue!.

To find out how Eclipse automates the use of JUnit, do the following:

  1. Create an Eclipse project containing Listings 1 and 2.

    The package explorer with an open project.

  2. In Windows, right-click the Package Explorer’s TrafficLight.java branch. On a Mac, control-click the Package Explorer’s TrafficLight.java branch.

    A context menu appears.

  3. In the context menu, select New→JUnit Test Case.

    As a result, the New JUnit Test Case dialog box appears.

    the New JUnit Test Case dialog box

  4. Click Next at the bottom of the New JUnit Test Case dialog box.

    As a result, you see the second page of the New JUnit Test Case dialog box. The second page lists methods belonging (either directly or indirectly) to the TrafficLight class.

    the second page of the New JUnit Test Case dialog box

  5. Place a checkmark in the checkbox labeled Traffic Light.

    As a result, Eclipse places checkmarks in the nextState() and change(int) checkboxes.

  6. Click Finish at the bottom of the New JUnit Test Case dialog box.

    JUnit isn’t formally part of Java. Instead comes with its own set of classes and methods to help you create tests for your code. After you click Finish, Eclipse asks you if you want to include the JUnit classes and methods as part of your project.

    Eclipse asks you if you want to include the JUnit classes and methods as part of your JUnit test case.

  7. Select Perform the Following Action and Add JUnit 4 Library to the Build Path. Then click OK.

    Eclipse closes the dialog boxes and your project has a brand new TrafficLightTest.java file. The file’s code is shown in Listing 3.

    The code in Listing 3 contains two tests, and both tests contain calls to an unpleasant sounding fail method. Eclipse wants you to add code to make these tests pass.

  8. Remove the calls to the fail method. In place of the fail method calls, type the code shown in bold in Listing 4.

  9. In the Package Explorer, right-click (in Windows) or control-click (on a Mac) the TrafficLightTest.java branch. In the resulting context menu, select Run As→JUnit Test.

    Eclipse might have more than one kind of JUnit testing framework up its sleeve. If so, you might see a dialog box like the one below. If you do, select the Eclipse JUnit Launcher, and then click OK.

    The Select the preferred launcher dialog box in Eclipse.

    As a result, Eclipse runs your TrafficLightTest.java program. Eclipse displays the result of the run in front of its own Package Explorer. The result shows no errors and no failures. Whew!

    The results of a JUnit test

Listing 3

import static org.junit.Assert.*;import org.junit.Test;public class TrafficLightTest {  @Test  public void testNextState() {    fail("Not yet implemented");  }  @Test  public void testChange() {    fail("Not yet implemented");  }}

Listing 4

import static org.junit.Assert.*;import org.junit.Test;public class TrafficLightTest {  @Test  public void testNextState() {    TrafficLight light = new TrafficLight();    assertEquals(SignalColor.RED, light.state);    light.nextState();    assertEquals(SignalColor.GREEN, light.state);    light.nextState();    assertEquals(SignalColor.YELLOW, light.state);    light.nextState();    assertEquals(SignalColor.RED, light.state);  }  @Test  public void testChange() {    TrafficLight light = new TrafficLight();    light.change(5);      assertEquals(SignalColor.YELLOW, light.state);  }}

When you select Run As→JUnit Test, Eclipse doesn’t look for a main method. Instead, Eclipse looks for methods starting with @Test and other such things. Eclipse executes each of the @Test methods.

Things like @Test are Java annotations.

Listing 4 contains two @Test methods: testNextState and testChange. The testNextState method puts the TrafficLight nextState method to the test. Similarly, the testChange method flexes the TrafficLight change method’s muscles.

Consider the code in the testNextState method. The testNextState method repeatedly calls the TrafficLight class’s nextState method and JUnit’s assertEquals method. The assertEquals method takes two parameters: an expected value and an actual value.

  • In the topmost assertEquals call, the expected value is SignalColor.RED. You expect the traffic light to be RED because, in Listing 2, you initialize the light’s state with the value SignalColor.RED.

  • In the topmost assertEquals call, the actual value is light.state (the color that’s actually stored in the traffic light’s state variable).

If the actual value equals the expected value, the call to assertEquals passes and JUnit continues executing the statements in the testNextState method.

But if the actual value is different from the expected value, the assertEquals fails and the result of the run displays the failure. For example, consider what happens when you change the expected value in the first assertEquals call in Listing 4:

@Testpublic void testNextState() {  TrafficLight light = new TrafficLight();  assertEquals(SignalColor.YELLOW, light.state);

Immediately after its construction, a traffic light’s color is RED, not YELLOW. So the testNextState method contains a false assertion and the result of doing Run As→JUnit looks like a child’s bad report card.

Results of a JUnit test when there is an error in the code.

Having testNextState before testChange in Listing 4 does not guarantee that JUnit will execute testNextState before executing testChange. If you have three @Test methods, JUnit might execute them from topmost to bottommost, from bottommost to topmost, from the middle method to the topmost to the bottommost, or in any order at all. JUnit might even pause in the middle of one test to execute parts of another test. That’s why you should never make assumptions about the outcome of one test when you write another test.

You might want certain statements to be executed before any of the tests begin. If you do, put those statements in a method named setUp, and preface that method with a @Before annotation. (See the setUp() checkbox in the figure at Step 3 in Listing 2, above.)

Here’s news: Not all assertEquals methods are created equal! Imagine adding a Driver class to your project’s code. “Driver class” doesn’t mean a printer driver or a pile driver. It means a person driving a car — a car that’s approaching your traffic light. For the details, see Listing 5.

Listing 5

public class Driver {  public double velocity(TrafficLight light) {    switch (light.state) {    case RED:      return 0.0;    case YELLOW:      return 10.0;    case GREEN:      return 30.0;    default:      return 0.0;    }  }}

When the light is red, the driver’s velocity is 0.0. When the light is yellow, the car is slowing to a safe 10.0. When the light is green, the car cruises at a velocity of 30.0.

(In this example, the units of velocity don’t matter. They could be miles per hour, kilometers per hour, or whatever. The only way it matters is if the car is in Boston or New York City. In that case, the velocity for YELLOW should be much higher than the velocity for GREEN, and the velocity for RED shouldn’t be 0.0.)

To create JUnit tests for the Driver class, follow Steps 1 to 9 listed previously in this article, but be sure to make the following changes:

  • In Step 2, right-click or control-click the Driver.java branch instead of the TrafficLight.java branch.

  • In Step 5, put a check mark in the Driver branch.

  • In Step 8, remove the fail method calls to create the DriverTest class shown in Listing 6. (The code that you type is shown in bold.)

Listing 6

import static org.junit.Assert.*;import org.junit.Test;public class DriverTest {  @Test  public void testVelocity() {    TrafficLight light = new TrafficLight();    light.change(7);    Driver driver = new Driver();    assertEquals(30.0, driver.velocity(light), 0.1);    }}

If all goes well, the JUnit test passes with flying colors. (To be more precise, the JUnit passes with the color green!) So the running of DriverTest isn’t new or exciting. What’s exciting is the call to assertEquals in Listing 6.

When you compare two double values in a Java program, you have no right to expect on-the-nose equality. That is, one of the double values might be 30.000000000 while the other double value is closer to 30.000000001. A computer has only 64 bits to store each double value, and inaccuracies creep in here and there. So in JUnit, the assertEquals method for comparing double values has a third parameter. The third parameter represents wiggle room.

In Listing 6, the statement

assertEquals(30.0, driver.velocity(light), 0.1);

says the following: “Assert that the actual value of driver.velocity(light) is within 0.1 of the expected value 30.0. If so, the assertion passes. If not, the assertion fails.”

When you call assertEquals for double values, selecting a good margin of error can be tricky. These figures illustrate the kinds of things that can go wrong.

error that occurs when the margin of the assertequals variable is too narrow.

Here, your margin of error is too small.

Error that appears when the margin of an AssertEquals variable is too large.

There, your margin of error is too large.

Fortunately, in this DriverTest example, the margin 0.1 is a very safe bet. Here’s why:

  • When the assertEquals test fails, it fails by much more than 0.1.

    Failure means having a driver.velocity(light) value such as 0.0 or 10.0.

    A correctly implemented margin of error for the AssertEquals variable.

  • In this example, when the assertEquals test passes, it probably represents complete, on-the-nose equality.

    The value of driver.velocity(light) comes directly from the return 30.0 code in Listing 5. No arithmetic is involved. So the value of driver.velocity(light) and the expected 30.0 value should be exactly the same (or almost exactly the same).

JavaFX: How to Use Property Events

JavaFX properties provide an addListener method that lets you add event handlers that are called whenever the value of a property changes. You can create two types of property event handlers:

  • A change listener, which is called whenever the value of the property has been recalculated. The change listener is passed three arguments: the property whose value has changed, the previous value of the property, and the new value.

  • An invalidation listener, which is called whenever the value of the property becomes unknown. This event is raised when the value of the property needs to be recalculated, but has not yet been recalculated. An invalidation event listener is passed just one argument: the property object itself.

Change and invalidation listeners are defined by functional interfaces named ChangeListener and InvalidationListener. Because these interfaces are functional interfaces, you can use Lambda expressions to implement them. Here’s how you use a Lambda expression to register a change listener on the text property of a text field named text1:

text1.textProperty().addListener(    (observable, oldvalue, newvalue) ->        // code goes here    );

Here’s an example that registers an invalidation listener:

text1.textProperty().addListener(    (observable) ->        // code goes here    );

The only way the addListener knows whether you are registering a change listener or an invalidation listener is by looking at the arguments you specify for the Lambda expression. If you provide three arguments, addListener registers a change listener. If you provide just one argument, an invalidation listener is installed.

This code listing shows a simple JavaFX application that uses change listeners to vary the size of a rectangle automatically with the size of the stack pane that contains it.

A change listener is registered with the stack pane’s width property so that whenever the width of the stack pane changes, the width of the rectangle is automatically set to half the new width of the stack pane. Likewise, a change listener is registered on the height property to change the rectangle’s height.

import javafx.application.*;import javafx.stage.*;import javafx.scene.*;import javafx.scene.layout.*;import javafx.scene.shape.*;import javafx.scene.paint.*;public class AutoRectangle extends Application{    public static void main(String[] args)    {        launch(args);    }    @Override public void start(Stage primaryStage)    {        Rectangle r = new Rectangle(100,100);    @@a18        r.setFill(Color.LIGHTGRAY);        r.setStroke(Color.BLACK);        r.setStrokeWidth(2);        StackPane p = new StackPane();    @@a23        p.setMinWidth(200);        p.setPrefWidth(200);        p.setMaxWidth(200);        p.setMinHeight(200);        p.setPrefHeight(200);        p.setMaxHeight(200);        p.getChildren().add(r);        p.widthProperty().addListener(    @@a33            (observable, oldvalue, newvalue) ->                  r.setWidth((Double)newvalue/2)            );        p.heightProperty().addListener(    @@a38            (observable, oldvalue, newvalue) ->                  r.setHeight((Double)newvalue/2)            );        Scene scene = new Scene(p);        primaryStage.setScene(scene);        primaryStage.setTitle("Auto Rectangle");        primaryStage.show();    }}

This figure shows this application in action. This figure shows the initial window displayed by the application as well as how the window appears after the user has made the window taller and wider. As you can see, the rectangle has increased in size proportionately.

An example of a responsive website.

The following paragraphs describe the highlights:

  • 18: These lines create a 100×100 rectangle and set the rectangle’s fill color, stroke color, and stroke width.

  • 23: These lines create a stack pane and set its width and height properties.

  • 33: These lines use a Lambda expression to register a change handler with the stack pane’s width parameter. When the stack pane’s width changes, the width of the rectangle is set to one half of the stack pane’s width.

  • 38: These lines use a Lambda expression to register a change handler with the stack pane’s height parameter. When the stack pane’s height changes, the height of the rectangle is set to one half of the stack pane’s height.

Apr 26, 2017

How to Set Up the Eclipse Integrated Development Environment for Java Programming

The Eclipse integrated development environment is the tool that you need for composing and testing your Java programs. You get Eclipse — an integrated development environment for Java. An integrated development environment (IDE) is a program that provides tools to help you create software easily and efficiently. You can create Java programs without an IDE, but the time and effort you save using an IDE makes the IDE worthwhile.

According to the Eclipse Foundation’s website, Eclipse is “a universal tool platform — an open extensible IDE for anything and nothing in particular.” Indeed, Eclipse is versatile. Programmers generally think of Eclipse as an IDE for developing Java programs, but Eclipse has tools for programming in C++, PHP, and many other languages.

Downloading Eclipse

Here’s how you download Eclipse:

  1. Visit Eclipse.org.

  2. Look for a way to download Eclipse for your operating system.

    You will see a big button displaying the words Get Started Now.

    After clicking the Download Eclipse button, you see a list of downloads for your computer’s operating system.

    Eclipse’s download page directs you to versions of Eclipse that are specific to your computer’s operating system. For example, if you visit the page on a Windows computer, the page shows you downloads for Windows only. If you’re downloading Eclipse for use on another computer, you may want to override the automatic choice of operating system.

    Look for a little drop-down list containing the name of your computer’s operating system. You can change the selected operating system in that drop-down list.

    The Download Eclipse button on Eclipse

  3. Choose an Eclipse package from the available packages.

    Regardless of your operating system, Eclipse comes in many shapes, sizes, and colors. The Eclipse website offers Eclipse IDE for Java Developers, Eclipse IDE for Java EE Developers, Eclipse Classic, and many other specialized downloads. You should select Eclipse IDE for Java Developers.

    The Eclipse packages available to download on Eclipse

  4. Choose between Eclipse’s 32-bit and 64-bit versions.

    If you know which Java version you __have (32-bit or 64-bit), be sure to download the corresponding Eclipse version. If you don’t know which Java version you have, download the 64-bit version of Eclipse and try to launch it. If you can launch 64-bit Eclipse, you’re okay. But if you get a No Java virtual machine was found error message, try downloading and launching the 32-bit version of Eclipse.

  5. Follow the appropriate links to get the download to begin.

    The links you follow depend on which of Eclipse’s many mirror sites is offering up your download. Just wade through the possibilities and get the download going.

Installing Eclipse

Precisely how you install Eclipse depends on your operating system and on what kind of file you get when you download Eclipse. Here’s a brief summary:

  • If you run Windows and the download is an .exe file:

    Double-click the .exe file’s icon.

  • If you run Windows and the download is a .zip file:

    Extract the file’s contents to the directory of your choice.

    In other words, find the .zip file’s icon in Windows Explorer (also known as File Explorer). Then double-click the .zip file’s icon. (As a result, Explorer displays the contents of the .zip file, which consists of only one folder — a folder named eclipse.) Drag the eclipse folder to a convenient place in your computer’s hard drive.

  • If you run Mac OS X:

    When you download Eclipse, you get either a .tar.gz file or a .dmg file.

    • A .tar.gz file is a compressed archive file. When you download the file, your web browser might automatically do some uncompressing for you. If so, you won’t find a .tar.gz file in your Downloads folder. Instead, you’ll find either a .tar file (because your web browser uncompressed the .gz part) or an eclipse folder (because your web browser uncompressed both the .tar and .gz parts).

      If you find a new .tar file or .tar.gz file in your Downloads folder, double-click the file until you see the eclipse folder. Drag this new eclipse folder to your Applications folder, and you’re all set.

    • If you download a .dmg file, your web browser may open the file for you. If not, find the .dmg file in your Downloads folder and double-click the file. Follow any instructions that appear after this double-click. If you’re expected to drag Eclipse into your Applications folder, do so.

  • If you run Linux:

    You may get a .tar.gz file, but there’s a chance you’ll get a self-extracting .bin file. Extract the .tar.gz file to your favorite directory or execute the self-extracting .bin file.

How to Create a Supervised Learning Model with Logistic Regression

After you build your first classification predictive model for analysis of the data, creating more models like it is a really straightforward task in scikit. The only real difference from one model to the next is that you may __have to tune the parameters from algorithm to algorithm.

How to load your data

This code listing will load the iris dataset into your session:

>>> from sklearn.datasets import load_iris>>> iris = load_iris()

How to create an instance of the classifier

The following two lines of code create an instance of the classifier. The first line imports the logistic regression library. The second line creates an instance of the logistic regression algorithm.

>>> from sklearn import linear_model>>> logClassifier = linear_model.LogisticRegression(C=1,   random_state=111)

Notice the parameter (regularization parameter) in the constructor. The regularization parameter is used to prevent overfitting. The parameter isn’t strictly necessary (the constructor will work fine without it because it will default to C=1). Creating a logistic regression classifier using C=150 creates a better plot of the decision surface. You can see both plots below.

How to run the training data

You’ll need to split the dataset into training and test sets before you can create an instance of the logistic regression classifier. The following code will accomplish that task:

>>> from sklearn import cross_validation>>> X_train, X_test, y_train, y_test =   cross_validation.train_test_split(iris.data,   iris.target, test_size=0.10, random_state=111)>>> logClassifier.fit(X_train, y_train)

Line 1 imports the library that allows you to split the dataset into two parts.

Line 2 calls the function from the library that splits the dataset into two parts and assigns the now-divided datasets to two pairs of variables.

Line 3 takes the instance of the logistic regression classifier you just created and calls the fit method to train the model with the training dataset.

How to visualize the classifier

Looking at the decision surface area on the plot, it looks like some tuning has to be done. If you look near the middle of the plot, you can see that many of the data points belonging to the middle area (Versicolor) are lying in the area to the right side (Virginica).

A decision surface made using a logistic regression C=1.

This image shows the decision surface with a C value of 150. It visually looks better, so choosing to use this setting for your logistic regression model seems appropriate.

A decision surface with a c value of 150.

How to run the test data

In the following code, the first line feeds the test dataset to the model and the third line displays the output:

>>> predicted = logClassifier.predict(X_test)>>> predictedarray([0, 0, 2, 2, 1, 0, 0, 2, 2, 1, 2, 0, 2, 2, 2])

How to evaluate the model

You can cross-reference the output from the prediction against the y_test array. As a result, you can see that it predicted all the test data points correctly. Here’s the code:

>>> from sklearn import metrics>>> predictedarray([0, 0, 2, 2, 1, 0, 0, 2, 2, 1, 2, 0, 2, 2, 2])>>> y_testarray([0, 0, 2, 2, 1, 0, 0, 2, 2, 1, 2, 0, 2, 2, 2])>>> metrics.accuracy_score(y_test, predicted)1.0   # 1.0 is 100 percent accuracy>>> predicted == y_testarray([ True, True, True, True, True, True, True,  True, True, True, True, True, True, True,  True], dtype=bool)

So how does the logistic regression model with parameter C=150 compare to that? Well, you can’t beat 100 percent. Here is the code to create and evaluate the logistic classifier with C=150:

>>> logClassifier_2 = linear_model.LogisticRegression(  C=150, random_state=111)>>> logClassifier_2.fit(X_train, y_train)>>> predicted = logClassifier_2.predict(X_test)>>> metrics.accuracy_score(y_test, predicted)0.93333333333333335>>> metrics.confusion_matrix(y_test, predicted)array([[5, 0, 0],  [0, 2, 0],  [0, 1, 7]])

We expected better, but it was actually worse. There was one error in the predictions. The result is the same as that of the Support Vector Machine (SVM) model.

Here is the full listing of the code to create and evaluate a logistic regression classification model with the default parameters:

>>> from sklearn.datasets import load_iris>>> from sklearn import linear_model>>> from sklearn import cross_validation>>> from sklearn import metrics>>> iris = load_iris()>>> X_train, X_test, y_train, y_test =   cross_validation.train_test_split(iris.data,   iris.target, test_size=0.10, random_state=111)>>> logClassifier = linear_model.LogisticRegression(,   random_state=111)>>> logClassifier.fit(X_train, y_train)>>> predicted = logClassifier.predict(X_test)>>> predictedarray([0, 0, 2, 2, 1, 0, 0, 2, 2, 1, 2, 0, 2, 2, 2])>>> y_testarray([0, 0, 2, 2, 1, 0, 0, 2, 2, 1, 2, 0, 2, 2, 2])>>> metrics.accuracy_score(y_test, predicted)1.0   # 1.0 is 100 percent accuracy>>> predicted == y_testarray([ True, True, True, True, True, True, True,  True, True, True, True, True, True, True,  True], dtype=bool)

The Windows 10 Creators Update Arrives

Windows 10 launched in July 2015, and on April 11, 2017, Microsoft released the third major update to their latest operating system. First announced in October with the Surface Studio, Microsoft has dubbed the latest update the Creators Update. Officially it is Windows 10 version 1703, OS build 15063. Naming it the Creators Update seems to signal some future intentions, but the actual release is less creative than the hardware they announced with it, and feels a bit like the company really just didn’t want to call it Windows 10 SP1 R2. Compared to the last major update, named the Anniversary Update, this version has less big features, but does bring a few new things to the OS along with some more polish.

With the new “Windows as a Service” model that came with Windows 10 in July 2015, more small updates seem like the proper method for servicing Windows, but Microsoft is definitely pulled between the consumer and business groups that they serve.  Consumers want more features, and sooner, but business needs to test everything before rolling it out. They must walk this tightrope between the two groups, and it’s not clear that they __have struck the right balance yet. With this update coming early in 2017, and an announcement of another event in New York City in early May, it does seem like there will be a second update later this year too.

Throughout it all, they __have kept their successful Windows Insider program running, and they are now citing over 10 million people in the Insider Program. This feedback driven change has been very successful, even if certain features which have been highly requested still haven’t seen their introduction yet. The number of builds being released has ramped up significantly from when the program first started, and now it is not uncommon to see several builds released in a week. The overall quality of some of those builds has degraded though, so people running in the Fast Ring carry much more risk than before, but there are less risky rings to be in as well. Microsoft has also opened up the Insider Program to business as well, since they are going to need to stay on top of the changes.

Windows 10 is going to keep evolving for the foreseeable future, with regular updates being first tested with the Insider Preview program, and then rolled out to the general public. With almost two years of Windows 10 behind us, we can take a look at what’s improved, what needs work, and where Microsoft can go from here.

Apr 25, 2017

5 Useful Linux Commands

Here are five useful Linux commands that will come in handy for your day-to-day Linux chores: tar, shutdown, free, df, and locate. After mastering these, check out our larger LIST OF BASIC LINUX COMMANDS to expand your skillset.

tar

The tar command was originally designed to be used to create backup copies of files on tape — in fact, tar actually stands for Tape ARchive. The tar command is the most common way to create a compressed archive of one or more files that you can easily move from one computer system to another.

You can use the tar command to create an archive of an entire directory like this:

tar –cvf archive.tar dirname/

In this example, the switch -cvf invokes three options: c, which creates a tar archive; v, which runs tar in verbose mode so that the files added to the archive are individually listed; and f, which provides the name of the archive file to be created. Next comes the name of the archive file (in this case, archive.tar). And finally comes the name of the folder that contains the files to be archived.

To extract files from an archive, use this command:

tar –xvf archive.tar

Here, the -x is specified instead of -c to extract rather than create the archive. The contents of the specified archive file (in this case, archive.tar) are extracted to the current working directory.

shutdown

An easy way to shut down a Linux system from a command prompt is to issue the shutdown command. To perform an immediate shutdown, enter this command:

shutdown now

To reboot a system immediately, enter this:

shutdown -r now

To schedule a reboot for a certain time, such as 2:00 a.m., enter this:

shutdown -r 2:00

To reboot an hour from now, enter this:

shutdown –r +60

free

The free command lets you know how much free memory is available on a Linux system. Simply type the command free and you’ll see output similar to the following:

        total   used     free shared  buff/cache  availableMem:  4030488 961888  1795920   2228     1272680    2803356Swap: 2097148      0  2097148

You can also use the -h switch to convert the numbers to KB, MB, or GB so they’re easier for a human to read:

      total   used    free   shared  buff/cache  availableMem:   3.8G   938M    1.7G     2.2M        1.3G       2.7GSwap:  2.0G     0B    2.0G

Here, you can see that the system has a total of 3.8GB of RAM, of which 938MB is used and 1.7GB is free.

df

The df command, short for disk free, lists the amount of free space available on all the disk volumes on a Linux system. For each mounted disk, df lists the total amount of disk space, the amount of space used, the amount of space that is free, and the percentage of used space.

For example, enter the command df with no switches and you’ll see output similar to this:

Filesystem  1K-blocks    Used Available Use% Mounted ondevtmpfs      2005408       0   2005408   0% /devtmpfs         2015244     228   2015016   1% /dev/shmtmpfs         2015244    1336   2013908   1% /runtmpfs         2015244       0   2015244   0% /sys/fs/cgroup/dev/sda5   154803352 5044044 149759308   4% /tmpfs         2015244      96   2015148   1% /tmp/dev/sda2      289293   92512    177325  35% /boottmpfs          403052       8    403044   1% /run/user/42tmpfs          403052      24    403028   1% /run/user/1000

Here, the disk space for each volume is listed in units of 1KB blocks, which translates to 2GB of disk space. Thus, the first drive (devtmpfs) has a total of 2,005,408 1KB blocks.

You can use the -h switch to get more readable results:

Filesystem      Size  Used Avail Use% Mounted ondevtmpfs        2.0G     0  2.0G   0% /devtmpfs           2.0G  228K  2.0G   1% /dev/shmtmpfs           2.0G  1.4M  2.0G   1% /runtmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup/dev/sda5       148G  4.9G  143G   4% /tmpfs           2.0G  112K  2.0G   1% /tmp/dev/sda2       283M   91M  174M  35% /boottmpfs           394M  8.0K  394M   1% /run/user/42tmpfs           394M   28K  394M   1% /run/user/1000

locate

The locate command can be very helpful if you can remember some or all of a filename but you’re not sure what directory the file is in. For example, suppose you need to find the directory that contains the file httpd.conf. To do so, enter this command:

locate httpd.conf

You’ll be rewarded with the location of any file in your system with named httpd.conf. On my Linux system, there are two:

/etc/httpd/conf/httpd.conf/usr/lib/tmpfiles.d/httpd.conf

You can use wildcards if you aren’t sure of the exact filename. For example, to find all files with the extension .conf, use this command:

locate *.conf

The result will be a listing of hundreds of files, which can be difficult to read. To limit the display to just one screen-full at a time, you can pipe the output to the more command, like this:

locate *.conf | more

The Intel Optane Memory (SSD) Preview: 32GB of Kaby Lake Caching

Last week, we took a look at Intel's first product based on their 3D XPoint non-volatile memory technology: the Optane SSD DC P4800X, a record-breaking flagship enterprise SSD. Today Intel launches the first consumer product under the Optane brand: the Intel Optane Memory, a far smaller device with a price that is 20 times cheaper. Despite having "Memory" in its name, this consumer Optane Memory product is not a NVDIMM nor is it in any other way a replacement for DRAM (those products will be coming to the enterprise market next year, even though the obvious name is now taken). Optane Memory also not a suitable replacement for mainstream flash-based SSDs, because Optane Memory is only available in 16GB and 32GB capacities. Instead, Optane Memory is Intel's latest attempt at an old idea that is great in theory but has struggled to catch on in practice: SSD caching.

Optane is Intel's brand name for products based on the 3D XPoint memory technology they co-developed with Micron. 3D XPoint is a new class of non-volatile memory that is not a variant of flash memory, the current mainstream technology for solid state drives. NAND flash memory—be it older planar NAND or newer 3D NAND flash—has fundamental limits to performance and write endurance, and many of the problems get worse as flash is shrunk to higher densities. 3D XPoint memory takes a radically different approach to non-volatile storage, and it makes different tradeoffs between density, performance, endurance and cost. Intel's initial announcement of 3D XPoint memory technology in 2015 came with general order of magnitude comparisons against existing memory technologies (DRAM and flash). Compared to NAND flash, 3D XPoint is supposed to be on the order of 1000x faster with 1000x higher write endurance. Compared to DRAM, 3D XPoint memory is supposed to be about 10x denser, which generally implies it'll be cheaper per GB by about the same amount. Those comparisons were about the raw memory itself and not about the performance of an entire SSD, and they were also projections based on memory that was still more than a year from hitting the market.

3D XPoint memory is not intended or expected to be a complete replacement for flash memory or DRAM in the foreseeable future. It offers substantially lower latency than flash memory but at a much higher price per GB. It still has finite endurance that makes it unsuitable as a drop-in replacement for DRAM without some form of wear-leveling. The natural role for 3D XPoint technology seems to be as a new tier in the memory hierarchy, slotting in between the smaller but faster DRAM and the larger but slower NAND flash. The Optane products released this month are using the first-generation 3D XPoint memory, along with first-generation controllers. Future generations should be able to offer substantial improvements to performance, endurance and capacity, but it's too soon to tell how those characteristics will scale.

The Intel Optane Memory is a M.2 NVMe SSD using 3D XPoint memory instead of NAND flash memory. 3D XPoint allows the Optane Memory to deliver far higher throughput than any flash SSD of equivalent capacity, and lower read latency than a NAND flash SSD of any capacity. The Optane Memory is intended both for OEMs to integrate into new systems and as an aftermarket upgrade for "Optane Memory ready" systems: those that meet the system requirements for Intel's new Optane caching software and __have motherboard firmware support for booting from a cached volume. However, the Optane Memory can also be treated as a small and fast NVMe SSD, because all of the work to enable its caching role is performed in software or by the PCH on the motherboard. 32GB is even (barely) enough to be used as a Windows boot drive, though doing so would not be useful for most consumers.

Gallery: Intel Optane Memory M.2 32GB

Intel Optane Memory uses a PCIe 3.0 x2 link, while most M.2 PCIe SSDs use the full 4 lanes the connector is capable of. The two-lane link allows the Optane Memory to use the same B and M connector key positions that are used by M.2 SATA SSDs, so there's no immediate visual giveaway that Optane Memory requires PCIe connectivity from the M.2 socket. The Optane Memory is a standard 22x80mm single-sided card but the components don't come close to using the full length. The controller chip is far smaller than a typical NVMe SSD controller, and the Optane Memory includes just one or two single-die packages of 3D XPoint memory. The Optane Memory module has labels on the front and back that contain a copper foil heatspreader layer, positioned to cool the memory rather than the controller. There is no DRAM visible on the drive.

Intel Optane Memory Specifications
Capacity 16 GB 32 GB
Form Factor M.2 2280 B+M key
Interface PCIe 3.0 x2
Protocol NVMe 1.1
Controller Intel
Memory 128Gb 20nm Intel 3D XPoint
Sequential Read 900 MB/s 1350 MB/s
Sequential Write 145 MB/s 290 MB/s
Random Read 190k IOPS 240k IOPS
Random Write 35k IOPS 65k IOPS
Read Latency 7µs 9 µs
Write Latency 18µs 30 µs
Active Power 3.5 W 3.5 W
Idle Power 1 W 1 W
Endurance 182.5 TB 182.5 TB
Warranty 5 years
MSRP $44 $77

The performance specifications of Intel Optane Memory __have been revised slightly since the announcement last month, with Intel now providing separate performance specs for the two capacities. Given the PCIe x2 link it's no surprise to see that sequential read speeds are substantially lower than we see from other NVMe SSDs, with 900 MB/s for the 16GB model and 1350 MB/s for the 32GB model. Sequential writes of 145 MB/s and 290 MB/s are far slower than consumer SSDs are usually willing to advertise, but are typical of the actual sustained sequential write speed of a good TLC NAND SSD. Random read throughput of 190k and 240k IOPS is in the ballpark for other NVMe SSDs. Random write throughput of 35k and 65k IOPS are also below the peak speeds advertised my most consumer SSDs, but on par with mainstream TLC and MLC SSDs respectively for actual performance at low queue depths.

Really it's the latency specifications where Optane Memory shines: the read latency of 7µs and 9µs for the 16GB and 32GB respectively are slightly better than even the enterprise Optane SSD DC P4800x, while write latency of 18µs and 30µs are just 2-3 times slower. The read latencies are completely untouchable for flash-based SSDs, but the write latencies can be matched by other NVMe controllers, but only because they cache write operations instead of performing them immediately.

The power consumption and endurance specifications don't look as impressive. 3.5W active power is lower than many M.2 PCIe SSDs and low enough that thermal throttling is unlikely to be a problem. The 1W idle power is unappealing, if not a bit problematic. Many M.2 NVMe SSDs will idle at 1W or more if the system is not using PCIe Active State Power Management and NVMe Power States. The Optane Memory doesn't even support the latter and will apparently draw the full 1W even in a well-tuned laptop. Since these power consumption numbers are typically going to be in addition to the power consumption of a mechanical hard drive, an Optane caching configuration is not going to offer decent power efficiency.

Meanwhile write endurance is rated at the same 100GB/day or 182.5 TB total for both capacities. Even though a stress test could burn through all of that in a week or two, 100GB/day is usually plenty for ordinary consumer use. However, a cache drive will likely experience a higher than normal write load as data and applications will tend to get evicted from the cache only to be pulled back in the next time they are loaded. More importantly, Intel promised that 3D XPoint would have on the order of 1000x the endurance of NAND flash, which should put these drives beyond the write endurance of any other consumer SSDs even after accounting for their small capacity.