Sunday, August 24, 2014

Update JavaFX BarChart in background thread, to display /proc/meminfo.

Similar to previous post "Display /proc/meminfo on JavaFX PieChart", this example show how to display memory usage, retrieved from /proc/meminfo, on JavaFX BarChart.



Another main point of this post is to show the different of loading data in various stage. There are three position in the code to load barchart data.
  • At position A: call prepareMemInfo() to load barchart data in JavaFX Application Thread, before UI show.
  • At position B, call prepareMemInfo() to load barchart data in JavaFX Application Thread, after UI show.
  • At position C, start another thread to load barchart data.
    In this case, another question rised: in prepareMemInfo(), the file /proc/meminfo is parsed in sequency, but add data to series2 in Application Thread by calling Platform.runLater(). May be it will not in the same sequency. <- I'm not sure here.
Check this video to know the different:


package javafx_meminfo;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_meminfo extends Application {

    final static String FILE_MEMINFO = "/proc/meminfo";

    private final TableView<Record> tableMem = new TableView<>();
    ObservableList<Record> listRecords = FXCollections.observableArrayList();

    XYChart.Series series1 = new XYChart.Series();  //load in Application Thread
    XYChart.Series series2 = new XYChart.Series();  //load in Background Thread
    final CategoryAxis xAxis = new CategoryAxis();
    final NumberAxis yAxis = new NumberAxis();
    final BarChart<String, Number> barChart = new BarChart<>(xAxis, yAxis);

    @Override
    public void start(Stage primaryStage) {

        //position A - run in UI Thread, before UI show
        //prepareMemInfo();
        
        tableMem.setEditable(false);

        TableColumn colMemField = new TableColumn("Field");
        colMemField.setMinWidth(150);
        colMemField.setCellValueFactory(
            new PropertyValueFactory<>("memField"));

        TableColumn colMemValue = new TableColumn("Value");
        colMemValue.setMinWidth(100);
        colMemValue.setCellValueFactory(
            new PropertyValueFactory<>("memValue"));

        TableColumn colMemUnit = new TableColumn("Unit");
        colMemUnit.setMinWidth(50);
        colMemUnit.setCellValueFactory(
            new PropertyValueFactory<>("memUnit"));

        TableColumn colMemQty = new TableColumn("Qty");
        colMemQty.setMinWidth(200);
        colMemQty.setCellValueFactory(
            new PropertyValueFactory<>("memQty"));

        tableMem.setItems(listRecords);
        tableMem.getColumns().addAll(colMemField,
            colMemValue, colMemUnit, colMemQty);
        
        //Create a dummy ProgressBar running 
        ProgressTask progressTask = new ProgressTask();
        ProgressBar progressBar = new ProgressBar();
        progressBar.setProgress(0);
        progressBar.progressProperty().bind(progressTask.progressProperty());
        
        new Thread(progressTask).start();
        //---
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(tableMem, progressBar);

        StackPane root = new StackPane();
        root.getChildren().add(vBox);

        Scene scene = new Scene(root, 500, 250);

        primaryStage.setTitle("java-buddy");
        primaryStage.setScene(scene);
        primaryStage.show();

        //Open second window
        barChart.setTitle(FILE_MEMINFO);
        xAxis.setLabel("Field");
        yAxis.setLabel("Qty");
        barChart.getData().addAll(series1, series2);

        StackPane secondaryLayout = new StackPane();
        secondaryLayout.getChildren().add(barChart);

        Scene secondScene = new Scene(secondaryLayout, 500, 400);

        Stage secondStage = new Stage();
        secondStage.setTitle("Second Stage");
        secondStage.setScene(secondScene);

        //Set position of second window, related to primary window.
        secondStage.setX(primaryStage.getX() + 250);
        secondStage.setY(primaryStage.getY() + 20);
        secondStage.show();

        //position B - run in UI Thread, after UI show
        //prepareMemInfo();
        
        //position C - run in background Thread
        new Thread(BackgroundPrepareMemoInfo).start();
    }

    public static void main(String[] args) {
        launch(args);
    }

    Runnable BackgroundPrepareMemoInfo = () -> {
        prepareMemInfo();
    };

    private void prepareMemInfo() {
        
        //dummy delay
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(JavaFX_meminfo.class.getName()).log(Level.SEVERE, null, ex);
        }

        Stream<String> streamMemInfo = readFile(FILE_MEMINFO);
        streamMemInfo.forEach((line) -> {
            System.out.println(line);

            //split one line by whitespace/grouped whitespaces
            String[] oneLine = line.split("\\s+");

            for (String ele : oneLine) {
                System.out.println(ele);
            }

            System.out.println("---");

            String rField = "";
            int rMemValue = 0;
            String rMemUnit = "";

            if (oneLine.length <= 3) {
                if (oneLine.length == 3) {
                    rField = oneLine[0];
                    rMemValue = Integer.parseInt(oneLine[1]);
                    rMemUnit = oneLine[2];
                } else if (oneLine.length == 2) {
                    rField = oneLine[0];
                    rMemValue = Integer.parseInt(oneLine[1]);
                    rMemUnit = "B";
                } else if (oneLine.length == 1) {
                    rField = oneLine[0];
                    rMemValue = 0;
                    rMemUnit = "B";
                }

                Record record = new Record(
                    rField, rMemValue, rMemUnit);
                listRecords.add(record);

                if (Platform.isFxApplicationThread()) {
                    //It's running in UI Thread
                    series1.getData().add(new XYChart.Data(record.getMemField(), record.getMemQty()));
                } else {
                    //It's running in background Thread
                    Platform.runLater(() -> {
                        series2.getData().add(new XYChart.Data(record.getMemField(), record.getMemQty()));
                    });
                }

            }

        });
    }

    private Stream<String> readFile(String filePath) {
        Path path = Paths.get(filePath);

        Stream<String> fileLines = null;
        try {
            fileLines = Files.lines(path);
        } catch (IOException ex) {
            Logger.getLogger(JavaFX_meminfo.class.getName()).log(Level.SEVERE, null, ex);
        }

        return fileLines;
    }

    public static class Record {

        private final SimpleStringProperty memField;
        private final SimpleIntegerProperty memValue;
        private final SimpleStringProperty memUnit;
        private final SimpleFloatProperty memQty;

        private Record(String memField, int memValue, String memUnit) {
            this.memField = new SimpleStringProperty(memField);

            this.memValue = new SimpleIntegerProperty(memValue);
            this.memUnit = new SimpleStringProperty(memUnit);
            if (memValue == 0) {
                this.memQty = new SimpleFloatProperty(0.0f);
            } else if (memUnit.equalsIgnoreCase("MB")) {
                this.memQty = new SimpleFloatProperty((float) memValue * 1000000.0f);
            } else if (memUnit.equalsIgnoreCase("kB")) {
                this.memQty = new SimpleFloatProperty((float) memValue * 1000.0f);
            } else {
                this.memQty = new SimpleFloatProperty((float) memValue);
            }
        }

        public String getMemField() {
            return memField.get();
        }

        public int getMemValue() {
            return memValue.get();
        }

        public String getMemUnit() {
            return memUnit.get();
        }

        public float getMemQty() {
            return memQty.get();
        }

    }
    
    final int MAX_PROGRESS = 50;
    class ProgressTask extends Task<Void>{
         
        @Override
        protected Void call() throws Exception {
            for (int i = 1; i <= MAX_PROGRESS; i++) {
                updateProgress(i, MAX_PROGRESS);
                Thread.sleep(200);
            }
            return null;
        }
         
    }

}


Saturday, August 23, 2014

Beginning Java 8 Fundamentals: Language Syntax, Arrays, Data Types, Objects, and Regular Expressions

Beginning Java 8 Fundamentals: Language Syntax, Arrays, Data Types, Objects, and Regular Expressions

Beginning Java 8 Fundamentals provides a comprehensive approach to learning the Java programming language, especially the object-oriented fundamentals necessary at all levels of Java development.

Author Kishori Sharan provides over 90 diagrams and 240 complete programs to help beginners and intermediate level programmers learn the topics faster. Starting with basic programming concepts, the author walks you through writing your first Java program step-by-step. Armed with that practical experience, you'll be ready to learn the core of the Java language.

The book continues with a series of foundation topics, including using data types, working with operators, and writing statements in Java. These basics lead onto the heart of the Java language: object-oriented programming. By learning topics such as classes, objects, interfaces, and inheritance you'll have a good understanding of Java's object-oriented model.

The final collection of topics takes what you've learned and turns you into a real Java programmer. You'll see how to take the power of object-oriented programming and write programs that can handle errors and exceptions, process strings and dates, format data, and work with arrays to manipulate data.

What you’ll learn
  • How to write your first Java programs with an emphasis on learning object-oriented programming in Java
  • What are data types, operators, statements, classes and objects
  • How to do exception handling, assertions, strings and dates, and object formatting
  • What are regular expressions and how to use them
  • How to work with arrays, interfaces, enums, and inheritance
  • How to deploy Java applications on memory-constrained devices using compact profiles
Who this book is for
This book is for those who are new to Java programming, who may have some or even no prior programming experience.

Table of Contents
1. Programming Concepts
2. Writing Java Programs
3. Data Types
4. Operators
5. Statements
6. Classes and Objects
7. Object and Objects Classes
8. Wrapper Classes
9. Exception Handling
10. Assertions
11. Strings
12. Dates and Times
13. Formatting Data
14. Regular Expressions
15. Arrays
16. Inheritance
17. Interfaces
18. Enum Types
19. ASCII Character Set
20. Writing Documentation Comments
21. Compact Profiles

Display /proc/meminfo on JavaFX PieChart

Last post "Display /proc/meminfo on JavaFX TableView", it will be shown in PieChart form.


Please notice that this example aim to show data in chart form, not the actual presentation of memory allocation; for example, memFree should be a sub-set of memFree, not anoth section as shown on the piechart.

package javafx_meminfo;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_meminfo extends Application {

    final static String FILE_MEMINFO = "/proc/meminfo";

    private final TableView<Record> tableMem = new TableView<>();
    ObservableList<Record> listRecords = FXCollections.observableArrayList();
    
    ObservableList<PieChart.Data> pieChartData =
                FXCollections.observableArrayList();
    PieChart chart = new PieChart(pieChartData);

    @Override
    public void start(Stage primaryStage) {

        prepareMemInfo();
        tableMem.setEditable(false);

        TableColumn colMemField = new TableColumn("Field");
        colMemField.setMinWidth(150);
        colMemField.setCellValueFactory(
            new PropertyValueFactory<>("memField"));
        
        TableColumn colMemValue = new TableColumn("Value");
        colMemValue.setMinWidth(100);
        colMemValue.setCellValueFactory(
            new PropertyValueFactory<>("memValue"));
        
        TableColumn colMemUnit = new TableColumn("Unit");
        colMemUnit.setMinWidth(50);
        colMemUnit.setCellValueFactory(
            new PropertyValueFactory<>("memUnit"));
        
        TableColumn colMemQty = new TableColumn("Qty");
        colMemQty.setMinWidth(200);
        colMemQty.setCellValueFactory(
            new PropertyValueFactory<>("memQty"));
        
        tableMem.setItems(listRecords);
        tableMem.getColumns().addAll(colMemField, 
            colMemValue, colMemUnit, colMemQty);

        StackPane root = new StackPane();
        root.getChildren().add(tableMem);

        Scene scene = new Scene(root, 500, 250);

        primaryStage.setTitle("java-buddy");
        primaryStage.setScene(scene);
        primaryStage.show();
        
        //Open second window
        chart.setTitle(FILE_MEMINFO);
        
        StackPane secondaryLayout = new StackPane();
        secondaryLayout.getChildren().add(chart);
                 
        Scene secondScene = new Scene(secondaryLayout, 400, 300);
 
        Stage secondStage = new Stage();
        secondStage.setTitle("Second Stage");
        secondStage.setScene(secondScene);
                 
        //Set position of second window, related to primary window.
        secondStage.setX(primaryStage.getX() + 250);
        secondStage.setY(primaryStage.getY() + 100);
        secondStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void prepareMemInfo() {

        Stream<String> streamMemInfo = readFile(FILE_MEMINFO);
        streamMemInfo.forEach((line) -> {
            System.out.println(line);

            //split one line by whitespace/grouped whitespaces
            String[] oneLine = line.split("\\s+");

            for (String ele : oneLine) {
                System.out.println(ele);
            }

            System.out.println("---");

            String rField = "";
            int rMemValue = 0;
            String rMemUnit = "";

            if (oneLine.length <= 3) {
                if (oneLine.length == 3) {
                    rField = oneLine[0];
                    rMemValue = Integer.parseInt(oneLine[1]);
                    rMemUnit = oneLine[2];
                } else if (oneLine.length == 2) {
                    rField = oneLine[0];
                    rMemValue = Integer.parseInt(oneLine[1]);
                    rMemUnit = "B";
                } else if (oneLine.length == 1) {
                    rField = oneLine[0];
                    rMemValue = 0;
                    rMemUnit = "B";
                }

                Record record = new Record(
                    rField, rMemValue, rMemUnit);
                listRecords.add(record);
                
                pieChartData.add(new PieChart.Data(
                    record.getMemField(), record.getMemQty()));
            }

        });
    }

    private Stream<String> readFile(String filePath) {
        Path path = Paths.get(FILE_MEMINFO);

        Stream<String> fileLines = null;
        try {
            fileLines = Files.lines(path);
        } catch (IOException ex) {
            Logger.getLogger(JavaFX_meminfo.class.getName()).log(Level.SEVERE, null, ex);
        }

        return fileLines;
    }

    public static class Record {

        private final SimpleStringProperty memField;
        private final SimpleIntegerProperty memValue;
        private final SimpleStringProperty memUnit;
        private final SimpleFloatProperty memQty;

        private Record(String memField, int memValue, String memUnit) {
            this.memField = new SimpleStringProperty(memField);
            
            this.memValue = new SimpleIntegerProperty(memValue);
            this.memUnit = new SimpleStringProperty(memUnit);
            if (memValue == 0) {
                this.memQty = new SimpleFloatProperty(0.0f);
            } else if (memUnit.equalsIgnoreCase("MB")) {
                this.memQty = new SimpleFloatProperty((float)memValue * 1000000.0f);
            } else if (memUnit.equalsIgnoreCase("kB")) {
                this.memQty = new SimpleFloatProperty((float)memValue * 1000.0f);
            }else {
                this.memQty = new SimpleFloatProperty((float)memValue);
            }
        }

        public String getMemField() {
            return memField.get();
        }

        public int getMemValue() {
            return memValue.get();
        }

        public String getMemUnit() {
            return memUnit.get();
        }

        public float getMemQty() {
            return memQty.get();
        }

    }

}


Thursday, August 21, 2014

Display /proc/meminfo on JavaFX TableView

This example show how to display data retrieved from /proc/meminfo on JavaFX TableView.



package javafx_meminfo;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_meminfo extends Application {

    final static String FILE_MEMINFO = "/proc/meminfo";

    private final TableView<Record> tableMem = new TableView<>();
    ObservableList<Record> listRecords = FXCollections.observableArrayList();

    @Override
    public void start(Stage primaryStage) {

        prepareMemInfo();
        tableMem.setEditable(false);

        TableColumn colMemField = new TableColumn("Field");
        colMemField.setMinWidth(150);
        colMemField.setCellValueFactory(
            new PropertyValueFactory<>("memField"));
        
        TableColumn colMemValue = new TableColumn("Value");
        colMemValue.setMinWidth(100);
        colMemValue.setCellValueFactory(
            new PropertyValueFactory<>("memValue"));
        
        TableColumn colMemUnit = new TableColumn("Unit");
        colMemUnit.setMinWidth(50);
        colMemUnit.setCellValueFactory(
            new PropertyValueFactory<>("memUnit"));
        
        TableColumn colMemQty = new TableColumn("Qty");
        colMemQty.setMinWidth(200);
        colMemQty.setCellValueFactory(
            new PropertyValueFactory<>("memQty"));
        
        tableMem.setItems(listRecords);
        tableMem.getColumns().addAll(colMemField, 
            colMemValue, colMemUnit, colMemQty);

        StackPane root = new StackPane();
        root.getChildren().add(tableMem);

        Scene scene = new Scene(root, 500, 250);

        primaryStage.setTitle("java-buddy");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void prepareMemInfo() {

        Stream<String> streamMemInfo = readFile(FILE_MEMINFO);
        streamMemInfo.forEach((line) -> {
            System.out.println(line);

            //split one line by whitespace/grouped whitespaces
            String[] oneLine = line.split("\\s+");

            for (String ele : oneLine) {
                System.out.println(ele);
            }

            System.out.println("---");

            String rField = "";
            int rMemValue = 0;
            String rMemUnit = "";

            if (oneLine.length <= 3) {
                if (oneLine.length == 3) {
                    rField = oneLine[0];
                    rMemValue = Integer.parseInt(oneLine[1]);
                    rMemUnit = oneLine[2];
                } else if (oneLine.length == 2) {
                    rField = oneLine[0];
                    rMemValue = Integer.parseInt(oneLine[1]);
                    rMemUnit = "B";
                } else if (oneLine.length == 1) {
                    rField = oneLine[0];
                    rMemValue = 0;
                    rMemUnit = "B";
                }

                Record record = new Record(
                    rField, rMemValue, rMemUnit);
                listRecords.add(record);
            }

        });
    }

    private Stream<String> readFile(String filePath) {
        Path path = Paths.get(FILE_MEMINFO);

        Stream<String> fileLines = null;
        try {
            fileLines = Files.lines(path);
        } catch (IOException ex) {
            Logger.getLogger(JavaFX_meminfo.class.getName()).log(Level.SEVERE, null, ex);
        }

        return fileLines;
    }

    public static class Record {

        private final SimpleStringProperty memField;
        private final SimpleIntegerProperty memValue;
        private final SimpleStringProperty memUnit;
        private final SimpleFloatProperty memQty;

        private Record(String memField, int memValue, String memUnit) {
            this.memField = new SimpleStringProperty(memField);
            
            this.memValue = new SimpleIntegerProperty(memValue);
            this.memUnit = new SimpleStringProperty(memUnit);
            if (memValue == 0) {
                this.memQty = new SimpleFloatProperty(0.0f);
            } else if (memUnit.equalsIgnoreCase("MB")) {
                this.memQty = new SimpleFloatProperty((float)memValue * 1000000.0f);
            } else if (memUnit.equalsIgnoreCase("kB")) {
                this.memQty = new SimpleFloatProperty((float)memValue * 1000.0f);
            }else {
                this.memQty = new SimpleFloatProperty((float)memValue);
            }
        }

        public String getMemField() {
            return memField.get();
        }

        public int getMemValue() {
            return memValue.get();
        }

        public String getMemUnit() {
            return memUnit.get();
        }

        public float getMemQty() {
            return memQty.get();
        }

    }

}



next:
Display /proc/meminfo on JavaFX PieChart

Parse /proc/meminfo using Java code

The example "Read text file using Stream" return result as String. It is hard to use. To make use of it, we always have to parse as meanful items. This example show how to parse the file "/proc/meminfo".



package java_meminfo;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class Java_meminfo {
    
    final static String FILE_MEMINFO = "/proc/meminfo";

    public static void main(String[] args) {

        Stream<String> streamMemInfo = readFile(FILE_MEMINFO);
        streamMemInfo.forEach((line) -> {
            System.out.println(line);
            
            //split one line by whitespace/grouped whitespaces
            String[] oneLine = line.split("\\s+");

            for (String ele : oneLine) {
                System.out.println(ele);
            }

            System.out.println("---");
        });

    }
    
    static private Stream<String> readFile(String filePath){
        Path path = Paths.get(FILE_MEMINFO);
        
        Stream<String> fileLines = null;
        try {
            fileLines = Files.lines(path);
        } catch (IOException ex) {
            Logger.getLogger(Java_meminfo.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return fileLines;
    }
    
}


Next post show how to display it on TableView.

Monday, August 18, 2014

Example of using ExecutorService/Executors

This example show how to use ExecutorService/Executors.


Executor is an object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An Executor is normally used instead of explicitly creating threads.

ExecutorService is an Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.

An ExecutorService can be shut down, which will cause it to reject new tasks. Two different methods are provided for shutting down an ExecutorService. The shutdown() method will allow previously submitted tasks to execute before terminating, while the shutdownNow() method prevents waiting tasks from starting and attempts to stop currently executing tasks. Upon termination, an executor has no tasks actively executing, no tasks awaiting execution, and no new tasks can be submitted. An unused ExecutorService should be shut down to allow reclamation of its resources.


Example:
package javafxexecutorservice;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXExecutorService extends Application {
    
    ExecutorService executorService = null;

    @Override
    public void start(Stage primaryStage) {
        
        CountDownLatch countDownLatch1 = new CountDownLatch(5);
        CountThread countThread1 = new CountThread("A", countDownLatch1, 5);
        ProgressBar progressBar1 = new ProgressBar();
        progressBar1.progressProperty().bind(countThread1.processProperty);
        
        CountDownLatch countDownLatch2 = new CountDownLatch(10);
        CountThread countThread2 = new CountThread("B", countDownLatch2, 10);
        ProgressBar progressBar2 = new ProgressBar();
        progressBar2.progressProperty().bind(countThread2.processProperty);
        
        CountDownLatch countDownLatch3 = new CountDownLatch(5);
        CountThread countThread3 = new CountThread("C", countDownLatch3, 5);
        ProgressBar progressBar3 = new ProgressBar();
        progressBar3.progressProperty().bind(countThread3.processProperty);
        
        CountDownLatch countDownLatch4 = new CountDownLatch(5);
        CountThread countThread4 = new CountThread("D", countDownLatch4, 5);
        ProgressBar progressBar4 = new ProgressBar();
        progressBar4.progressProperty().bind(countThread4.processProperty);
        
        CountDownLatch countDownLatch5 = new CountDownLatch(5);
        CountThread countThread5 = new CountThread("E", countDownLatch5, 5);
        ProgressBar progressBar5 = new ProgressBar();
        progressBar5.progressProperty().bind(countThread5.processProperty);

        Button btnStart = new Button();
        btnStart.setText("Start");
        btnStart.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Start");
                executorService = Executors.newFixedThreadPool(2);
                executorService.execute(countThread1);
                executorService.execute(countThread2);
                executorService.execute(countThread3);
                executorService.execute(countThread4);
                executorService.execute(countThread5);
            }
        });
        
        Button btnShutdown = new Button();
        btnShutdown.setText("Shut Down");
        btnShutdown.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                if(executorService != null){
                    System.out.println("Shut Down");
                    executorService.shutdown();
                }
            }
        });
        
        Button btnShutdownNow = new Button();
        btnShutdownNow.setText("Shut Down Now");
        btnShutdownNow.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                if(executorService != null){
                    System.out.println("Shut Down Now");
                    executorService.shutdownNow();
                }
            }
        });
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(btnStart, btnShutdown, 
            btnShutdownNow, progressBar1, progressBar2, 
            progressBar3, progressBar4, progressBar5);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
}

class CountThread implements Runnable {

    int num_of_count = 5;
    CountDownLatch counter;
    String name;
    
    DoubleProperty processProperty;

    CountThread(String n, CountDownLatch c, int num) {
        name = n;
        counter = c;
        num_of_count = num;
        processProperty = new SimpleDoubleProperty(num_of_count);
    }

    @Override
    public void run() {

        for (int i = 0; i < num_of_count; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(CountThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            processProperty.set((double)(counter.getCount())/(double)num_of_count);
            System.out.println(name + " : " + counter.getCount());
            counter.countDown();
            
        }
    }

}

Bind JavaFX ProgressBar.progressProperty() to DoubleProperty in Thread

It's JavaFX version of last example "Java CountDownLatch and Thread" with ProgressBars. It show how to bind ProgressBar.progressProperty() to DoubleProperty in Thread, and update the DoubleProperty in Thread; such that it update ProgressBar automatically.


package javafxexecutorservice;

import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXExecutorService extends Application {

    @Override
    public void start(Stage primaryStage) {
        
        CountDownLatch countDownLatch1 = new CountDownLatch(5);
        CountThread countThread1 = new CountThread("A", countDownLatch1, 5);
        ProgressBar progressBar1 = new ProgressBar();
        progressBar1.progressProperty().bind(countThread1.processProperty);
        
        CountDownLatch countDownLatch2 = new CountDownLatch(10);
        CountThread countThread2 = new CountThread("B", countDownLatch2, 10);
        ProgressBar progressBar2 = new ProgressBar();
        progressBar2.progressProperty().bind(countThread2.processProperty);
        
        Button btn = new Button();
        btn.setText("Start");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Start");
                new Thread(countThread1).start();
                new Thread(countThread2).start();
            }
        });
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(btn, progressBar1, progressBar2);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
}

class CountThread implements Runnable {

    int num_of_count = 5;
    CountDownLatch counter;
    String name;
    
    DoubleProperty processProperty;

    CountThread(String n, CountDownLatch c, int num) {
        name = n;
        counter = c;
        num_of_count = num;
        processProperty = new SimpleDoubleProperty(num_of_count);
    }

    @Override
    public void run() {

        for (int i = 0; i < num_of_count; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(CountThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            processProperty.set((double)(counter.getCount())/(double)num_of_count);
            System.out.println(name + " : " + counter.getCount());
            counter.countDown();
            
        }
    }

}

Saturday, August 16, 2014

Java CountDownLatch and Thread

Example to use java.util.concurrent.CountDownLatch, synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.


package javacountdownlatch;

import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaCountDownLatch {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        System.out.println("Start counting");
        
        CountDownLatch countDownLatch1 = new CountDownLatch(5);
        CountThread countThread1 = new CountThread("A", countDownLatch1, 5);
        CountDownLatch countDownLatch2 = new CountDownLatch(7);
        CountThread countThread2 = new CountThread("B", countDownLatch2, 7);

        try {
            countDownLatch1.await();
            System.out.println("A finished");
            countDownLatch2.await();
            System.out.println("B finished");
        } catch (InterruptedException ex) {
            Logger.getLogger(JavaCountDownLatch.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.toString());
        }
    }
}

class CountThread implements Runnable {

    int num_of_count = 5;
    CountDownLatch counter;
    String name;

    CountThread(String n, CountDownLatch c, int num) {
        name = n;
        counter = c;
        num_of_count = num;
        new Thread(this).start();
    }

    @Override
    public void run() {

        for (int i = 0; i < num_of_count; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(CountThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(name + " : " + counter.getCount());
            counter.countDown();
        }
    }

}


- Read JavaFX version, Bind JavaFX ProgressBar.progressProperty() to DoubleProperty in Thread.

Thursday, August 14, 2014

Read text file using Stream

This example show how to read text file using Stream<String> by calling Files.lines(path); to read the file /proc/cpuinfo, /proc/version or /proc/meminfo or Linux.

package java_streamreadtextfile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class Java_StreamReadTextFile {

    //final static String FILE_NAME = "/proc/cpuinfo";
    //final static String FILE_NAME = "/proc/version";
    final static String FILE_NAME = "/proc/meminfo";

    public static void main(String[] args) {
        
        Path path = Paths.get(FILE_NAME);
        try {
            Stream<String> fileLines = Files.lines(path);
            fileLines.forEach((line) -> System.out.println(line));

        } catch (IOException ex) {
            Logger.getLogger(Java_StreamReadTextFile.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
}



- Parse /proc/meminfo using Java code

Wednesday, August 13, 2014

Java 8 in Action: Lambdas, Streams, and functional-style programming

While the term "lambda expression" may sound abstract and academic, Java 8 Lambdas can have a big impact on every day programming. In simplest terms, a lambda expression is a function—a bit of code—that can be passed to another method as an argument. Thus, a requirement can be changed by using a behavior, represented by a lambda, as a parameter. Java 8's functional programming features, like lambdas and the new Stream API that enables a cleaner way to iterate through collections, can help programmers write concise, maintainable code that scales easily and performs well on multicore architectures.

Java 8 in Action: Lambdas, Streams, and functional-style programming

Java 8 in Action is a clearly-written guide to Java 8 lambdas and functional programming in Java. It begins with a practical introduction to the structure and benefits of lambda expressions in real-world Java code and then introduces the Stream API, showing how it can make collections-related code radically easier to understand and maintain. It looks at new FP-oriented design patterns with Java 8 for code reuse, code readability, exception handling, data manipulation, and concurrency and concludes with a quick survey of useful functional features in Scala.

Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications.


Add listener to StringProperty to monitor property change

Example to implement ChangeListener() to monitor StringProperty change.



package javafx_propertylistener;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_PropertyListener extends Application {
    
    @Override
    public void start(Stage primaryStage) {
        
        StringProperty stringProperty = new SimpleStringProperty();
        
        TextField textInput = new TextField();
        Label labelOutput1 = new Label();
        Label labelObservable = new Label();
        Label labelOldvalue = new Label();
        Label labelNewvalue = new Label();
        
        labelOutput1.textProperty().bind(textInput.textProperty());
        
        Button btn = new Button();
        btn.setText("Updated");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                stringProperty.set(textInput.getText());
            }
        });
        
        // add listener for stringProperty
        // to be called when stringProperty changed
        stringProperty.addListener(new ChangeListener(){

            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                labelObservable.setText((String)observable.getValue());
                labelOldvalue.setText((String)oldValue);
                labelNewvalue.setText((String)newValue);
            }
        });
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(textInput, labelOutput1, btn, 
            labelObservable, labelOldvalue, labelNewvalue);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("Java-Buddy");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
}

Tuesday, August 12, 2014

Example of using java.util.function.Consumer

Java 8 introduce java.util.function.Consumer, a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

This example show ways to print all elements in a List. Also show how to implement our Consumer.

package java8consumer;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class Java8Consumer {

    public static void main(String[] args) {
        List myList = new ArrayList();
        for(int i=0; i<=5; i++){
            myList.add(i);
        }
        
        for(int i=0; i<myList.size(); i++){
            System.out.println(myList.get(i));
        }
        
        for (Object ele : myList) {
            System.out.println(ele);
        }
        
        myList.forEach((ele) -> System.out.println(ele)); 
        
        //Use Consumer
        MyConsumer myConsumer = new MyConsumer();
        myList.forEach(myConsumer);
    }
    
}

class MyConsumer implements Consumer{

    @Override
    public void accept(Object t) {
        System.out.println(t);
    }

}


java.util.function.Consumer example

Remote develop Java/JavaFX/Swing for Raspberry Pi using Netbeans 8

The posts show how to setup on PC to remote develop Java/JavaFX/Swing application for Raspbery Pi, using Netbeans 8.

Friday, August 8, 2014

JavaFX Dynamic TableView with button, something wrong on JDK 1.8/JavaFX 8

It's a updated version for my old example "JavaFX: Get row data from TableView" for JDK 1.7/JavaFX 2.

- In the original example, I haven't handle col.setOnEditCommit() to update the data in back-end. So when user click the Action button, it show the original data, not the updated data. It's added.

- This example work when compile with JDK 1.7 only, when compile with JDK 1.8, something wrong.
a) After edit a cell, then click to edit another cell below it, it show a wrong data.
b) Extra incorrect "Action" button added, when add New Record.

- If I ignore adding Action button, by commenting tableView.getColumns().add(col_action), problems seem temporarily fixed.

May be something changed in JDK 1.8/JavaFX 8 I haven't handle...! May be I have to re-check the updated documents...!

Work on JDK 1.7/JavaFX 2, under Windows 8.1, Netbeans 7.4:

Fail on Windows 8.1, Netbeans 7.4, JDK 1.8:

Fail on Ubuntu Linux 14.04, Netbeans 8, JDK 1.8:

Temporarily fixed by ignore the button:


Program code;
package javafxdyntable;

import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.scene.layout.VBoxBuilder;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXDynTable extends Application {

    private TableView tableView = new TableView();
    private Button btnNew = new Button("New Record");

    static Random random = new Random();

    static final String Day[] = {
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday"};

    public static class Record {

        private final SimpleIntegerProperty id;
        private final SimpleIntegerProperty value_0;
        private final SimpleIntegerProperty value_1;
        private final SimpleIntegerProperty value_2;
        private final SimpleIntegerProperty value_3;
        private final SimpleIntegerProperty value_4;

        Record(int i, int v0, int v1, int v2, int v3,
                int v4) {
            this.id = new SimpleIntegerProperty(i);
            this.value_0 = new SimpleIntegerProperty(v0);
            this.value_1 = new SimpleIntegerProperty(v1);
            this.value_2 = new SimpleIntegerProperty(v2);
            this.value_3 = new SimpleIntegerProperty(v3);
            this.value_4 = new SimpleIntegerProperty(v4);
        }

        public int getId() {
            return id.get();
        }

        public void setId(int v) {
            id.set(v);
        }

        public int getValue_0() {
            return value_0.get();
        }

        public void setValue_0(int v) {
            value_0.set(v);
        }

        public int getValue_1() {
            return value_1.get();
        }

        public void setValue_1(int v) {
            value_1.set(v);
        }

        public int getValue_2() {
            return value_2.get();
        }

        public void setValue_2(int v) {
            value_2.set(v);
        }

        public int getValue_3() {
            return value_3.get();
        }

        public void setValue_3(int v) {
            value_3.set(v);
        }

        public int getValue_4() {
            return value_4.get();
        }

        public void setValue_4(int v) {
            value_4.set(v);
        }

    };

    ObservableList<Record> data = FXCollections.observableArrayList();

    @Override
    public void start(final Stage primaryStage) {
        primaryStage.setTitle("java-buddy.blogspot.com");
        tableView.setEditable(true);
        Callback<TableColumn, TableCell> cellFactory
                = new Callback<TableColumn, TableCell>() {

                    @Override
                    public TableCell call(TableColumn p) {
                        return new EditingCell();
                    }
                };

        btnNew.setOnAction(btnNewHandler);

        //init table
        //Un-editable column of "id"
        TableColumn col_id = new TableColumn("ID");
        tableView.getColumns().add(col_id);
        col_id.setCellValueFactory(
                new PropertyValueFactory<Record, String>("id"));

        //Editable columns
        for (int i = 0; i < Day.length; i++) {
            TableColumn col = new TableColumn(Day[i]);
            col.setCellValueFactory(
                    new PropertyValueFactory<Record, String>(
                            "value_" + String.valueOf(i)));
            tableView.getColumns().add(col);
            col.setCellFactory(cellFactory);
            
            final int idx = i;
            col.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Record, Integer>>() {

                @Override
                public void handle(TableColumn.CellEditEvent<Record, Integer> event) {
                    Record rec = event.getTableView().getItems().get(event.getTablePosition().getRow());
                    Integer newValue = event.getNewValue();
                    
                    switch(idx){
                        case 0: rec.setValue_0(newValue);
                                break;
                        case 1: rec.setValue_1(newValue);
                                break;
                        case 2: rec.setValue_2(newValue);
                                break;
                        case 3: rec.setValue_3(newValue);
                                break;
                        case 4: rec.setValue_4(newValue);
                                break;
                    }
                }
            });

        }

        //Insert Button
        TableColumn col_action = new TableColumn("Action");
        col_action.setSortable(false);

        col_action.setCellValueFactory(
            new Callback<TableColumn.CellDataFeatures<Record, Boolean>, ObservableValue<Boolean>>() {

                @Override
                public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Record, Boolean> p) {
                    return new SimpleBooleanProperty(p.getValue() != null);
                }
            });

        col_action.setCellFactory(
            new Callback<TableColumn<Record, Boolean>, TableCell<Record, Boolean>>() {

                @Override
                public TableCell<Record, Boolean> call(TableColumn<Record, Boolean> p) {
                    return new ButtonCell(tableView);
                }

            });
        tableView.getColumns().add(col_action);

        tableView.setItems(data);

        Group root = new Group();
        VBox vBox = new VBox();
        vBox.setSpacing(10);
        vBox.getChildren().addAll(btnNew, tableView);
        root.getChildren().add(vBox);
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    public class SubRecord {

        private SimpleStringProperty fieldSubRecordName;
        private SimpleIntegerProperty fieldSubRecordValue;

        SubRecord(String sn, int sv) {
            this.fieldSubRecordName = new SimpleStringProperty(sn);
            this.fieldSubRecordValue = new SimpleIntegerProperty(sv);
        }

        public String getFieldSubRecordName() {
            return fieldSubRecordName.get();
        }

        public int getFieldSubRecordValue() {
            return fieldSubRecordValue.get();
        }

    }

    //Define the button cell
    private class ButtonCell extends TableCell<Record, Boolean> {

        final Button cellButton = new Button("Action");

        ButtonCell(final TableView tblView) {

            cellButton.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent t) {
                    int selectdIndex = getTableRow().getIndex();

                    //Create a new table show details of the selected item
                    Record selectedRecord = (Record) tblView.getItems().get(selectdIndex);
                    ObservableList<SubRecord> subDataList
                            = FXCollections.observableArrayList(
                                    new SubRecord("ID", selectedRecord.getId()),
                                    new SubRecord("Monday", selectedRecord.getValue_0()),
                                    new SubRecord("Tuesday", selectedRecord.getValue_1()),
                                    new SubRecord("Wednesday", selectedRecord.getValue_2()),
                                    new SubRecord("Thursday", selectedRecord.getValue_3()),
                                    new SubRecord("Friday", selectedRecord.getValue_4()));

                    TableColumn columnfield = new TableColumn("Field");
                    columnfield.setCellValueFactory(
                            new PropertyValueFactory<Record, String>("fieldSubRecordName"));

                    TableColumn columnValue = new TableColumn("Value");
                    columnValue.setCellValueFactory(
                            new PropertyValueFactory<SubRecord, Integer>("fieldSubRecordValue"));

                    TableView<SubRecord> subTableView = new TableView<>();
                    subTableView.setItems(subDataList);
                    subTableView.getColumns().addAll(columnfield, columnValue);

                    Stage myDialog = new Stage();
                    myDialog.initModality(Modality.WINDOW_MODAL);

                    Scene myDialogScene = new Scene(VBoxBuilder.create()
                            .children(subTableView)
                            .alignment(Pos.CENTER)
                            .padding(new Insets(10))
                            .build());

                    myDialog.setScene(myDialogScene);
                    myDialog.show();
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            super.updateItem(t, empty);
            if (!empty) {
                setGraphic(cellButton);
            }
        }
    }

    EventHandler<ActionEvent> btnNewHandler
        = new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {

                //generate new Record with random number
                int newId = data.size();
                Record newRec = new Record(
                    newId,
                    random.nextInt(100),
                    random.nextInt(100),
                    random.nextInt(100),
                    random.nextInt(100),
                    random.nextInt(100));
                data.add(newRec);
            }
        };

    class EditingCell extends TableCell<XYChart.Data, Number> {

        private TextField textField;

        public EditingCell() {
        }

        @Override
        public void startEdit() {

            super.startEdit();

            if (textField == null) {
                createTextField();
            }

            setGraphic(textField);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            textField.selectAll();
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();

            setText(String.valueOf(getItem()));
            setContentDisplay(ContentDisplay.TEXT_ONLY);
        }

        @Override
        public void updateItem(Number item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setGraphic(textField);
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                } else {
                    setText(getString());
                    setContentDisplay(ContentDisplay.TEXT_ONLY);
                }
            }
        }

        private void createTextField() {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            textField.setOnKeyPressed(new EventHandler<KeyEvent>() {

                @Override
                public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(Integer.parseInt(textField.getText()));
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }

        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }

}

Thursday, August 7, 2014

Pro JavaFX 8: A Definitive Guide to Building Desktop, Mobile, and Embedded Java Clients

In Pro JavaFX 8 expert authors show you how to use the JavaFX platform to create rich-client Java applications. You'll discover how you can use this powerful Java-based UI platform, which is capable of handling large-scale data-driven business applications for PC as well as now mobile and embedded devices.

Pro JavaFX 8: A Definitive Guide to Building Desktop, Mobile, and Embedded Java Clients

Covering the JavaFX API, development tools, and best practices, this book provides code examples that explore the exciting new features provided with JavaFX 8 which comes as part of Oracle's new Java (SE) 8 release. This book also contains engaging tutorials that cover virtually every facet of JavaFX development and reference materials on JavaFX that augment the JavaFX API documentation.

After reading and using this book, you'll have the authoritative knowledge that should give you an edge in your next JavaFX-based application projects for your job or your clients.

What you’ll learn

  • How to get started with JavaFX, including downloading the SDK and available tools
  • How to express user interfaces with SceneBuilder and FXML 
  • How to use property binding to keep the UI easily in sync with the model
  • How to use the rich set of JavaFX UI controls, charts, shapes, effects, transformations, and animations to create stunning, responsive, user interfaces
  • How to use the powerful JavaFX layout classes to define the user interface in a cross-platform fashion
  • How to leverage the observable collection classes to observe changes in, and bind to, Java collections
  • How to use the JavaFX media classes to play audio and video
  • How to interact with external application services to create an enterprise application with JavaFX
  • How to use the JavaFX API with alternative languages such as Scala and Groovy
  • How to use Java on embedded, mobile, and tablet devices

Who this book is for
Application developers, graphic designers, and IT decision makers. Not only does this book contain comprehensive technical information for developers and designers, it builds a compelling case for choosing JavaFX.

Table of Contents
1. Getting a Jump Start in JavaFX 8
2. Creating a User Interface in JavaFX 8
3. Using SceneBuilder to create a User Interface
4. Properties and Bindings
5. Building Dynamic UI Layouts in JavaFX
6. Using the JavaFX UI Controls
7.Collections and Concurrency
8. Creating Charts in JavaFX
9. Using the media classes
10. JavaFX 3D
11. Accessing Web Services
12. Java on Embedded, Mobile and Tablet
13. JavaFX languages and markup

Wednesday, August 6, 2014

DataPicker.setChronology(), set calendar system for DatePicker

The method DataPicker.setChronology(java.time.chrono.Chronology value) set calendar system for DatePicker. Available Chronology value can be found here: http://docs.oracle.com/javase/8/docs/api/java/time/chrono/AbstractChronology.html.


package javafx_datepicker;

import java.time.LocalDate;
import java.time.chrono.Chronology;
import java.time.chrono.HijrahChronology;
import java.time.chrono.IsoChronology;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.MinguoChronology;
import java.time.chrono.ThaiBuddhistChronology;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_DatePicker extends Application {

    @Override
    public void start(Stage primaryStage) {

        //New DataPicker init at now
        DatePicker datePicker = new DatePicker(LocalDate.now());
        datePicker.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                LocalDate date = datePicker.getValue();
                System.err.println("Selected date: " + date);
            }

        });

        //reload datePicker at now
        Button btnNow = new Button("Now");
        btnNow.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                datePicker.setValue(LocalDate.now());
            }

        });
        
        final ToggleGroup groupChronology = new ToggleGroup();
        RadioButton optDefault = new RadioButton("default");
        optDefault.setToggleGroup(groupChronology);
        optDefault.setSelected(true);
        optDefault.setUserData(null);
        
        RadioButton optHijrah = new RadioButton("HijrahChronology");
        optHijrah.setToggleGroup(groupChronology);
        optHijrah.setUserData(HijrahChronology.INSTANCE);
        
        RadioButton optIso = new RadioButton("IsoChronology");
        optIso.setToggleGroup(groupChronology);
        optIso.setUserData(IsoChronology.INSTANCE);
        
        RadioButton optJapanese = new RadioButton("JapaneseChronology");
        optJapanese.setToggleGroup(groupChronology);
        optJapanese.setUserData(JapaneseChronology.INSTANCE);
        
        RadioButton optMinguo = new RadioButton("MinguoChronology");
        optMinguo.setToggleGroup(groupChronology);
        optMinguo.setUserData(MinguoChronology.INSTANCE);
        
        RadioButton optThaiBuddhist = new RadioButton("ThaiBuddhistChronology");
        optThaiBuddhist.setToggleGroup(groupChronology);
        optThaiBuddhist.setUserData(ThaiBuddhistChronology.INSTANCE);
        
        groupChronology.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){

            @Override
            public void changed(ObservableValue<? extends Toggle> observable, 
                    Toggle oldValue, Toggle newValue) {
                if (groupChronology.getSelectedToggle() != null) {
                    datePicker.setChronology(
                        (Chronology)groupChronology.getSelectedToggle().getUserData());
                
                }else{
                    datePicker.setChronology(null);
                }
            }
        });
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(optDefault, 
            optHijrah, optIso, optJapanese, optMinguo, optThaiBuddhist,
            btnNow, datePicker);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

Tuesday, August 5, 2014

JavaFX 8 example: Preset/load DataPicker at now


package javafx_datepicker;

import java.time.LocalDate;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_DatePicker extends Application {

    @Override
    public void start(Stage primaryStage) {
        
        //New DataPicker init at now
        DatePicker datePicker = new DatePicker(LocalDate.now());
        datePicker.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                LocalDate date = datePicker.getValue();
                System.err.println("Selected date: " + date);
            }

        });

        //reload datePicker at now
        Button btnNow = new Button("Now");
        btnNow.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                datePicker.setValue(LocalDate.now());
            }

        });
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(btnNow, datePicker);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

Monday, August 4, 2014

JavaFX 8 example: DatePicker


Example code:

package javafx_datepicker;

import java.time.LocalDate;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_DatePicker extends Application {

    @Override
    public void start(Stage primaryStage) {
        DatePicker datePicker = new DatePicker();
        datePicker.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                LocalDate date = datePicker.getValue();
                System.err.println("Selected date: " + date);
            }

        });

        StackPane root = new StackPane();
        root.getChildren().add(datePicker);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

Friday, August 1, 2014

JavaFX 8: Introduction by Example, 2nd edition

JavaFX 8: Introduction by Example shows you how to use your existing Java skills to create graphically exciting client applications with the JavaFX 8 platform. The book is a new and much improved edition of JavaFX 2.0: Introduction by Example, taking you through a series of engaging, fun-to-work examples that bring you up to speed on the major facets of the platform. It will help you to create applications that look good, are fun to use, and that take advantage of the medium to present data of all types in ways that engage the user and lead to increased productivity.

Entirely example-based, JavaFX 8: Introduction by Example begins with the fundamentals of installing the software and creating a simple interface. From there, you'll move in progressive steps through the process of developing applications using JavaFX’s standard drawing primitives. You'll then explore images, animations, media, and web. This new edition incorporates the changes resulting from the switch to Java 8 SDK. It covers advanced topics such as custom controls, JavaFX 3D, gesture devices, and embedded systems.  Best of all, the book is full of working code that you can adapt and extend to all your future projects.

  • Entirely example-based
  • Filled with fun and practical code examples
  • Covers all that's new in Java 8 relating to JavaFX such as Lambda expressions and Streams
  • Covers gesture devices, 3D display, embedded systems, and other advanced topics

What you’ll learn
  • Install JavaFX 8 and configure your environment
  • Work with touch-based interfaces such as in Windows 8
  • Interpret gesture-based events the Leap Motion Controller and similar hardware
  • Integrate JavaFX with embedded systems such as Arduino and Raspberry Pi
  • Develop modern GUI implementations of business forms
  • Work with shapes, color, text, and animation
  • Add audio and video to your projects
  • Create custom controls using SVG and Canvas
  • Learn to style a user-interface via CSS
  • Communicate bidirectionally using Java and Javascript with HTML5

Who this book is for

JavaFX 8: Introduction by Example is for Java developers who are interested in developing rich, client-side applications to run on PCs, phones, tablets, Arduino controllers, the Raspberry Pi, and more. Whether enterprise developer or hobbyist, anyone wanting to develop a polished user-interface from Java will find much to like in this book.

Table of Contents
1. Getting started
2. JavaFX Fundamentals
3. Java 8 Lambda Expressions
4. Layout & UI Controls
5. Graphics with JavaFX
6. Custom Controls
7. Media with JavaFX
8. JavaFX on the Web
9. JavaFX 3D
10. JavaFX and Arduino
11. JavaFX on the Raspberry Pi
12. Gesture-based Interfaces
13. Appendix A. References