Tuesday, March 26, 2013

Java Magazine March/April 2013 published

Java Magazine is one of Oracle’s newest and most significant investments in the continuing health and growth of the Java technology ecosystem. It is published on a bi-monthly basis in digital and mobile formats.

Download:
Java Magazine March/April 2013
Java Magazine March/April 2013


Start application to open PDF file using HostServices

The javafx.application.HostServices class provides HostServices for an Application. Its showDocument() method opens the specified URI in a new browser window or tab.

Example:

package javafx_pdf;

import java.io.File;
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

/**
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_Pdf extends Application {
    
    @Override
    public void start(final Stage primaryStage) {
        Button btn = new Button();
        btn.setText("Load PDF");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                FileChooser fileChooser = new FileChooser();
                 
                //Set extension filter
                FileChooser.ExtensionFilter extFilter = 
                        new FileChooser.ExtensionFilter("PDF files (*.pdf)", "*.pdf");
                fileChooser.getExtensionFilters().add(extFilter);
                 
                //Show open file dialog
                File file = fileChooser.showOpenDialog(primaryStage);

                HostServices hostServices = getHostServices();
                hostServices.showDocument(file.getAbsolutePath());
            }
        });
        
        StackPane root = new StackPane();
        root.getChildren().add(btn);
        
        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);
    }
}




JavaFX: simple example of DirectoryChooser

javafx.stage.DirectoryChooser provides support for standard directory chooser dialogs. On some platforms where file access may be restricted or not part of the user model (for example, on some mobile devices), opening a directory dialog may always result in a no-op (that is, null file being returned).

Simple example of javafx.stage.DirectoryChooser
Simple example of javafx.stage.DirectoryChooser
java.io.File return from DirectoryChooser.showDialog()
java.io.File return from DirectoryChooser.showDialog()


package javafx_directorychooser;

import java.io.File;
import javafx.application.Application;
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.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_DirectoryChooser extends Application {
    
    @Override
    public void start(final Stage primaryStage) {
        
        final Label labelSelectedDirectory = new Label();
        
        Button btnOpenDirectoryChooser = new Button();
        btnOpenDirectoryChooser.setText("Open DirectoryChooser");
        btnOpenDirectoryChooser.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                DirectoryChooser directoryChooser = new DirectoryChooser();
                File selectedDirectory = 
                        directoryChooser.showDialog(primaryStage);
                
                if(selectedDirectory == null){
                    labelSelectedDirectory.setText("No Directory selected");
                }else{
                    labelSelectedDirectory.setText(selectedDirectory.getAbsolutePath());
                }
            }
        });

        VBox vBox = new VBox();
        vBox.getChildren().addAll(
                labelSelectedDirectory,
                btnOpenDirectoryChooser);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("http://java-buddy.blogspot.com/");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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


Related:
- FileChooser - Open File Dialog


Friday, March 22, 2013

Embed Youtube video in JavaFX WebView

The code embed Youtube view in JavaFX WebView.

Embed Youtube video in JavaFX WebView
Embed Youtube video in JavaFX WebView


package javafx_webviewyoutube;

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

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

    String content_Url = "<iframe width=\"560\" height=\"315\" src=\"http://www.youtube.com/embed/9bZkp7q19f0\" frameborder=\"0\" allowfullscreen></iframe>";

    @Override
    public void start(Stage primaryStage) {
        WebView webView = new WebView();
        WebEngine webEngine = webView.getEngine();
        webEngine.loadContent(content_Url);

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

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

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

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

To load the html code from YouTube, open a browser to load Youtube with the target video, select Share -> Embed to copy the html code into content_Url.


Wednesday, March 20, 2013

Setting up your Java Dev Environment


YouTube Developers Live: Setting up your Java Dev Environment

Want to learn how to setup your IDE and Maven for YouTube API Java development? Join +Ikai Lan and +Ibrahim Ulukaya as they start from scratch and end up with a productive YouTube API Java development environment.

They will cover IDE setup, Maven integration and go over Java code samples of the YouTube Data API v3. Whether you are an experienced developer working through initial YouTube API library setup or a new developer ready to get started, this show will be great DIY guide!


Saturday, March 16, 2013

JavaFX: Delete row from a table

caution@2014-08-08:

This example not work correctly when compile with JDK 1.8/JavaFX 8. Please read: http://goo.gl/IRCaz4



Previous articles demonstrate how to "embed Button in TableView" and "Get row data from TableView".

To delete a row in the table, or delete a record in ObservableList (data), call the method:

data.remove(selectdIndex);

Delete row from a table
Delete row from a table


In the original approach, the record ID is assigned as the size of ObservableList data. In order to keep track of the id number, variable data_nextId is introduced.

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.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.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();
    int data_nextId = 0;
    
    @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);
        }
        
        //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);
    }
    
    //Define the button cell
    private class ButtonCell extends TableCell<Record, Boolean> {
        final Button cellButton = new Button("Delete");
        
        ButtonCell(final TableView tblView){
            
            cellButton.setOnAction(new EventHandler<ActionEvent>(){

                @Override
                public void handle(ActionEvent t) {
                    int selectdIndex = getTableRow().getIndex();
                    
                    //delete the selected item in data
                    data.remove(selectdIndex);
                }
            });
        }

        //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
            Record newRec = new Record(
                    data_nextId,
                    random.nextInt(100), 
                    random.nextInt(100), 
                    random.nextInt(100), 
                    random.nextInt(100), 
                    random.nextInt(100));
            data.add(newRec);
            data_nextId++;
            
        }
    };
    
    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();
        }
    }

}


Friday, March 15, 2013

Play plugin for NetBeans IDE 7.3

The NetBeans plugin for Play, is now available in the NetBeans Plugin Portal, ready to use in NetBeans IDE 7.3.

http://plugins.netbeans.org/plugin/47637/?show=true

Install the plugin into 7.3 and then you're able to create new Play projects via the New Project dialog or open any existing Play project.

Play plugin for NetBeans IDE 7.3
Play plugin for NetBeans IDE 7.3


Know more: https://blogs.oracle.com/geertjan/entry/play_in_netbeans_ide_7

Play Framework - Build Modern and Scalable Web Apps with Java and Scala

Play is a high-productivity Java and Scala web application framework that integrates the components and APIs you need for modern web application development.

Play is based on a lightweight, stateless, web-friendly architecture and features predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications thanks to its reactive model, based on Iteratee IO.



Website: http://www.playframework.com/

JavaFX: Get row data from TableView

caution@2014-08-08:

This example not work correctly when compile with JDK 1.8/JavaFX 8. Please read: http://goo.gl/IRCaz4


To get individual record in a TableView, using the code:

Record selectedRecord = (Record)tableView.getItems().get(selectdIndex);

where selectedIndex is the index in the TableView interested.

Extend from last article of "Embed Button in TableView", implement EventHandler of the embedded button, th read data of the selected row and display on another TableView within dialog.

Get row data from TableView
Get row data from TableView


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);
        }
        
        //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();
        }
    }

}


JavaFX: embed Button in TableView

caution@2014-08-08:

This example not work correctly when compile with JDK 1.8/JavaFX 8. Please read: http://goo.gl/IRCaz4



Embed Button in JavaFX TableView


Modify from last article "Editable TableView with dynamic row".

To create button in TableView, custom TableCell (ButtonCell in the code) have to be defined. Override updateItem() method to call setGraphic() to prepare the view if not empty. Insert your code in handle() of button action EventHandler to achieve your action.

Then you can create TableColumn (col_action in the code) for the new column, also implement your custom callback for CellValueFactory and CellFactory.

Finally add the button column to TableView, tableView.getColumns().add(col_action).

package javafxdyntable;

import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
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.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(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);
        }
        
        //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.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);
    }
    
    //Define the button cell
    private class ButtonCell extends TableCell<Record, Boolean> {
        final Button cellButton = new Button("Action");
        
        ButtonCell(){
            
            cellButton.setOnAction(new EventHandler<ActionEvent>(){

                @Override
                public void handle(ActionEvent t) {
                    // do something when button clicked
                    //...
                }
            });
        }

        //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();
        }
    }

}


Next:
- JavaFX: Get row data from TableView


Wednesday, March 13, 2013

JavaFX: Editable TableView with dynamic row

The article "JavaFX: Editable multi-column TableView" implement TableView with fixed number of row and column. This article demonstrate how to implement editable TableView with dynamic number of row.



package javafxdyntable;

import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
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.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(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);
        }
        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, 500, 400));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
    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();
        }
    }

}


Next : embed Button in TableView


Saturday, March 9, 2013

Java Tutorials website updated with early access information on some Java SE 8 features



The Java Tutorials are practical guides for programmers who want to use the Java programming language to create applications. They include hundreds of complete, working examples, and dozens of lessons. Groups of related lessons are organized into "trails".

An update of the Java Tutorial has gone live. This March 1st, 2013 edition of the tutorial contains early access information on some upcoming Java SE 8 features.

Visit The Java Tutorials.

Thursday, March 7, 2013

JavaFX 3D Early Access Available


Container terminal monitoring with 3D JavaFX
This applications was jointly created by Navis (CargoTec), Oracle, and Canoo.

The video has been presented at the 2012 JavaOne conference in San Francisco as part of the Oracle strategy keynote

Download the latest JDK™ 8 Early Access Releases, currently 8 Build b79.

This page contains the list of 3D features schedule for JavaFX 8.0.


Java SE 7u17, Java SE 6 Update 43 and JDK8(Early Access)

Java SE 7u17, Java SE 6 Update 43 is now available: http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html

Java SE Download
Java SE Download

And also, you can download the latest preview updates JDK 8, the next generation of the Java Development Kit. Source code may be found through the OpenJDK jdk8 project.

Oracle releases periodic early access snapshots of the binaries and documentation for JDK 8 snapshots on java.net. These raw snapshots let you review and contribute to the Java SE platform as it is being developed.

JDK 8 snapshots on java.net
JDK 8 snapshots on java.net


Tuesday, March 5, 2013

Building OpenJFX on Mac with JDK



Building OpenJFX on Mac with JDK b78
Step by step instructions (with some gotcha's!) in building OpenJFX on Mac OS X with JDK b78

Saturday, March 2, 2013

JavaFX: Interaction between table and charts

Last article demonstrate "Update StackedBarChart dynamically, with TableView". It's another example to make PieChart and LineChart update dynamically with TableView.



package javafxmulticolumnchart;

import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.XYChart;
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.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXMultiColumnChart extends Application {
    
    public class Record{
        private SimpleStringProperty fieldDay;
        private SimpleDoubleProperty fieldValue1;
        private SimpleDoubleProperty fieldValue2;
        
        Record(String fDay, double fValue1, double fValue2){
            this.fieldDay = new SimpleStringProperty(fDay);
            this.fieldValue1 = new SimpleDoubleProperty(fValue1);
            this.fieldValue2 = new SimpleDoubleProperty(fValue2);
        }
        
        public String getFieldDay() {
            return fieldDay.get();
        }
        
        public double getFieldValue1() {
            return fieldValue1.get();
        }
        
        public double getFieldValue2() {
            return fieldValue2.get();
        }
        
        public void setFieldDay(String fDay) {
            fieldDay.set(fDay);
        }
     
        public void setFieldValue1(Double fValue1) {
            fieldValue1.set(fValue1);
        }
        
        public void setFieldValue2(Double fValue2) {
            fieldValue2.set(fValue2);
        }
    }
    
    class MyList {
        
        ObservableList<Record> dataList;
        ObservableList<PieChart.Data> pieChartData1;
        ObservableList<XYChart.Data> xyList2;
        
        MyList(){
            dataList = FXCollections.observableArrayList();
            pieChartData1 = FXCollections.observableArrayList();
            xyList2 = FXCollections.observableArrayList();
        }
        
        public void add(Record r){
            dataList.add(r);
            pieChartData1.add(new PieChart.Data(r.getFieldDay(), r.getFieldValue1()));
            xyList2.add(new XYChart.Data(r.getFieldDay(), r.getFieldValue2()));
        }
        
        public void update1(int pos, Double val){
            pieChartData1.set(pos, new PieChart.Data(pieChartData1.get(pos).getName(), val));
        }
        
        public void update2(int pos, Double val){
            xyList2.set(pos, new XYChart.Data(xyList2.get(pos).getXValue(), val));
        }
    }
    
    MyList myList;
    
    private TableView<Record> tableView = new TableView<>();
    
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("java-buddy.blogspot.com");
        
        //prepare myList
        myList = new MyList();
        myList.add(new Record("Sunday", 100, 120));
        myList.add(new Record("Monday", 200, 210));
        myList.add(new Record("Tuesday", 50, 70));
        myList.add(new Record("Wednesday", 75, 50));
        myList.add(new Record("Thursday", 110, 120));
        myList.add(new Record("Friday", 300, 200));
        myList.add(new Record("Saturday", 111, 100));
        
        Group root = new Group();
        
        tableView.setEditable(true);

        Callback<TableColumn, TableCell> cellFactory = 
                new Callback<TableColumn, TableCell>() {
                          
                          @Override
                          public TableCell call(TableColumn p) {
                              return new EditingCell();
                          }
                      };
        
        TableColumn columnDay = new TableColumn("Day");
        columnDay.setCellValueFactory(
                new PropertyValueFactory<Record,String>("fieldDay"));
        columnDay.setMinWidth(60);
        
        TableColumn columnValue1 = new TableColumn("Value 1");
        columnValue1.setCellValueFactory(
                new PropertyValueFactory<Record,Double>("fieldValue1"));
        columnValue1.setMinWidth(60);
        
        TableColumn columnValue2 = new TableColumn("Value 2");
        columnValue2.setCellValueFactory(
                new PropertyValueFactory<Record,Double>("fieldValue2"));
        columnValue2.setMinWidth(60);
     
        //--- Add for Editable Cell of Value field, in Double
        columnValue1.setCellFactory(cellFactory);
        columnValue1.setOnEditCommit(
                new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
                    
                    @Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
                        ((Record)t.getTableView().getItems().get(
                                t.getTablePosition().getRow())).setFieldValue1(t.getNewValue());
                        
                        int pos = t.getTablePosition().getRow();
                        myList.update1(pos, t.getNewValue());
                    }
                });
        
        columnValue2.setCellFactory(cellFactory);
        columnValue2.setOnEditCommit(
                new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
                    
                    @Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
                        ((Record)t.getTableView()
                                .getItems()
                                .get(t.getTablePosition().getRow())).setFieldValue2(t.getNewValue());
                        
                        int pos = t.getTablePosition().getRow();
                        myList.update2(pos, t.getNewValue());
                    }
                });
      
        //--- Prepare StackedBarChart
        
        List<String> dayLabels = Arrays.asList(
                "Sunday", 
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday",
                "Saturday");

        final PieChart pieChart1 = new PieChart(myList.pieChartData1);
        pieChart1.setPrefWidth(200);
        pieChart1.setTitle("Pie Chart 1");
        
        final CategoryAxis xAxis2 = new CategoryAxis();
        final NumberAxis yAxis2 = new NumberAxis();
        xAxis2.setLabel("Day");
        xAxis2.setCategories(FXCollections.<String> observableArrayList(dayLabels));
        yAxis2.setLabel("Value 2");
        XYChart.Series XYSeries2 = new XYChart.Series(myList.xyList2);
        XYSeries2.setName("XYChart.Series 2");
        
        final LineChart<String,Number> lineChart2 = 
                new LineChart<>(xAxis2,yAxis2);
        lineChart2.setTitle("Line Chart 2");
        lineChart2.setPrefWidth(250);
        lineChart2.getData().add(XYSeries2);

        //---
        tableView.setItems(myList.dataList);
        tableView.getColumns().addAll(columnDay, columnValue1, columnValue2);
        tableView.setPrefWidth(200);
        
        HBox hBox = new HBox();
        hBox.setSpacing(10);
        hBox.getChildren().addAll(tableView, pieChart1, lineChart2);
 
        root.getChildren().add(hBox);
     
      primaryStage.setScene(new Scene(root, 750, 400));
      primaryStage.show();
    }

    class EditingCell extends TableCell<Record, Double> {
        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(Double 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(Double.parseDouble(textField.getText()));
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }
     
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }
    
}


JavaFX 2: Update StackedBarChart dynamically, with TableView.

In the former article "Create dynamic StackedBarChart of JavaFX 2" demonstrate how to update StackedBarChart dynamically, with TableView. BUT it's not a good example! Both the TableView and one data series of the StackedBarChart work with the same ObservableList<XYChart.Data>, only one data series of the StackedBarChart can be modified with the TableView. And hard to extend to update more data series.

Last article demonstrate how to implement "Editable multi-column TableView". It's modified to work with StackedBarChart, all the data series in StackedBarChart can be changed with the TableView.


Instead of share a common ObservableList<XYChart.Data>, a class MyList is implemented. It hold a ObservableList<Record> for TableView, and two ObservableList<XYChart.Data> for StackedBarChart, and also keep their content consistency.

Once editing of the table committed, the handler update the ObservableList<Record> for TableView, and also the corresponding ObservableList<XYChart.Data> for StackedBarChart.

package javafxmulticolumnchart;

import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.StackedBarChart;
import javafx.scene.chart.XYChart;
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.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXMultiColumnChart extends Application {
    
    public class Record{
        private SimpleStringProperty fieldMonth;
        private SimpleDoubleProperty fieldValue1;
        private SimpleDoubleProperty fieldValue2;
        
        Record(String fMonth, double fValue1, double fValue2){
            this.fieldMonth = new SimpleStringProperty(fMonth);
            this.fieldValue1 = new SimpleDoubleProperty(fValue1);
            this.fieldValue2 = new SimpleDoubleProperty(fValue2);
        }
        
        public String getFieldMonth() {
            return fieldMonth.get();
        }
        
        public double getFieldValue1() {
            return fieldValue1.get();
        }
        
        public double getFieldValue2() {
            return fieldValue2.get();
        }
        
        public void setFieldMonth(String fMonth) {
            fieldMonth.set(fMonth);
        }
     
        public void setFieldValue1(Double fValue1) {
            fieldValue1.set(fValue1);
        }
        
        public void setFieldValue2(Double fValue2) {
            fieldValue2.set(fValue2);
        }
    }
    
    class MyList {
        
        ObservableList<Record> dataList;
        ObservableList<XYChart.Data> xyList1;
        ObservableList<XYChart.Data> xyList2;
        
        MyList(){
            dataList = FXCollections.observableArrayList();
            xyList1 = FXCollections.observableArrayList();
            xyList2 = FXCollections.observableArrayList();
        }
        
        public void add(Record r){
            dataList.add(r);
            xyList1.add(new XYChart.Data(r.getFieldMonth(), r.getFieldValue1()));
            xyList2.add(new XYChart.Data(r.getFieldMonth(), r.getFieldValue2()));
        }
        
        public void update1(int pos, Double val){
            xyList1.set(pos, new XYChart.Data(xyList1.get(pos).getXValue(), val));
        }
        
        public void update2(int pos, Double val){
            xyList2.set(pos, new XYChart.Data(xyList2.get(pos).getXValue(), val));
        }
    }
    
    MyList myList;
    
    private TableView<Record> tableView = new TableView<>();
    
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("java-buddy.blogspot.com");
        
        //prepare myList
        myList = new MyList();
        myList.add(new Record("January", 100, 120));
        myList.add(new Record("February", 200, 210));
        myList.add(new Record("March", 50, 70));
        myList.add(new Record("April", 75, 50));
        myList.add(new Record("May", 110, 120));
        myList.add(new Record("June", 300, 200));
        myList.add(new Record("July", 111, 100));
        myList.add(new Record("August", 30, 50));
        myList.add(new Record("September", 75, 70));
        myList.add(new Record("October", 55, 50));
        myList.add(new Record("November", 225, 225));
        myList.add(new Record("December", 99, 100));
        
        Group root = new Group();
        
        tableView.setEditable(true);

        Callback<TableColumn, TableCell> cellFactory = 
                new Callback<TableColumn, TableCell>() {
                          
                          @Override
                          public TableCell call(TableColumn p) {
                              return new EditingCell();
                          }
                      };
        
        TableColumn columnMonth = new TableColumn("Month");
        columnMonth.setCellValueFactory(
                new PropertyValueFactory<Record,String>("fieldMonth"));
        columnMonth.setMinWidth(60);
        
        TableColumn columnValue1 = new TableColumn("Value 1");
        columnValue1.setCellValueFactory(
                new PropertyValueFactory<Record,Double>("fieldValue1"));
        columnValue1.setMinWidth(60);
        
        TableColumn columnValue2 = new TableColumn("Value 2");
        columnValue2.setCellValueFactory(
                new PropertyValueFactory<Record,Double>("fieldValue2"));
        columnValue2.setMinWidth(60);
     
        //--- Add for Editable Cell of Value field, in Double
        columnValue1.setCellFactory(cellFactory);
        columnValue1.setOnEditCommit(
                new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
                    
                    @Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
                        ((Record)t.getTableView().getItems().get(
                                t.getTablePosition().getRow())).setFieldValue1(t.getNewValue());
                        
                        int pos = t.getTablePosition().getRow();
                        myList.update1(pos, t.getNewValue());
                    }
                });
        
        columnValue2.setCellFactory(cellFactory);
        columnValue2.setOnEditCommit(
                new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
                    
                    @Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
                        ((Record)t.getTableView()
                                .getItems()
                                .get(t.getTablePosition().getRow())).setFieldValue2(t.getNewValue());
                        
                        int pos = t.getTablePosition().getRow();
                        myList.update2(pos, t.getNewValue());
                    }
                });
      
        //--- Prepare StackedBarChart
        
        List<String> monthLabels = Arrays.asList(
                "January", 
                "February",
                "March",
                "April",
                "May",
                "June",
                "July",
                "August",
                "September",
                "October",
                "November",
                "December");
                
        final CategoryAxis xAxis1 = new CategoryAxis();
        final NumberAxis yAxis1 = new NumberAxis();
        xAxis1.setLabel("Month");
        xAxis1.setCategories(FXCollections.<String> observableArrayList(monthLabels));
        yAxis1.setLabel("Value 1");
        XYChart.Series XYSeries1 = new XYChart.Series(myList.xyList1);
        XYSeries1.setName("XYChart.Series 1");
        
        final CategoryAxis xAxis2 = new CategoryAxis();
        final NumberAxis yAxis2 = new NumberAxis();
        xAxis2.setLabel("Month");
        xAxis2.setCategories(FXCollections.<String> observableArrayList(monthLabels));
        yAxis2.setLabel("Value 2");
        XYChart.Series XYSeries2 = new XYChart.Series(myList.xyList2);
        XYSeries2.setName("XYChart.Series 2");
        
        final StackedBarChart<String,Number> stackedBarChart = new StackedBarChart<>(xAxis1,yAxis1);
        stackedBarChart.setTitle("StackedBarChart");
        stackedBarChart.getData().addAll(XYSeries1, XYSeries2);
        //---
        tableView.setItems(myList.dataList);
        tableView.getColumns().addAll(columnMonth, columnValue1, columnValue2);
        
        HBox hBox = new HBox();
        hBox.setSpacing(10);
        hBox.getChildren().addAll(tableView, stackedBarChart);
 
        root.getChildren().add(hBox);
     
      primaryStage.setScene(new Scene(root, 750, 400));
      primaryStage.show();
    }

    class EditingCell extends TableCell<Record, Double> {
        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(Double 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(Double.parseDouble(textField.getText()));
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }
     
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }
    
}


Another example to make PieChart and LineChart update dynamically with TableView.


JavaFX: Editable multi-column TableView

Example of Editable multi-column TableView of JavaFX.



package javafxmulticolumnchart;

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
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.stage.Stage;
import javafx.util.Callback;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXMultiColumnChart extends Application {
    
    public class Record{
        private SimpleStringProperty fieldMonth;
        private SimpleDoubleProperty fieldValue1;
        private SimpleDoubleProperty fieldValue2;
        
        Record(String fMonth, double fValue1, double fValue2){
            this.fieldMonth = new SimpleStringProperty(fMonth);
            this.fieldValue1 = new SimpleDoubleProperty(fValue1);
            this.fieldValue2 = new SimpleDoubleProperty(fValue2);
        }
        
        public String getFieldMonth() {
            return fieldMonth.get();
        }
        
        public double getFieldValue1() {
            return fieldValue1.get();
        }
        
        public double getFieldValue2() {
            return fieldValue2.get();
        }
        
        public void setFieldMonth(String fMonth) {
            fieldMonth.set(fMonth);
        }
     
        public void setFieldValue1(Double fValue1) {
            fieldValue1.set(fValue1);
        }
        
        public void setFieldValue2(Double fValue2) {
            fieldValue2.set(fValue2);
        }
    }
    
    private TableView<Record> tableView = new TableView<>();
    
    private ObservableList<Record> dataList =
        FXCollections.observableArrayList(
            new Record("January", 100, 120),
            new Record("February", 200, 210),
            new Record("March", 50, 70),
            new Record("April", 75, 50),
            new Record("May", 110, 120),
            new Record("June", 300, 200),
            new Record("July", 111, 100),
            new Record("August", 30, 50),
            new Record("September", 75, 70),
            new Record("October", 55, 50),
            new Record("November", 225, 225),
            new Record("December", 99, 100));
    
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("java-buddy.blogspot.com");
        
        Group root = new Group();
        
        tableView.setEditable(true);

        Callback<TableColumn, TableCell> cellFactory = 
                new Callback<TableColumn, TableCell>() {
                          
                          @Override
                          public TableCell call(TableColumn p) {
                              return new EditingCell();
                          }
                      };
        
        TableColumn columnMonth = new TableColumn("Month");
        columnMonth.setCellValueFactory(
                new PropertyValueFactory<Record,String>("fieldMonth"));
        columnMonth.setMinWidth(60);
        
        TableColumn columnValue1 = new TableColumn("Value 1");
        columnValue1.setCellValueFactory(
                new PropertyValueFactory<Record,Double>("fieldValue1"));
        columnValue1.setMinWidth(60);
        
        TableColumn columnValue2 = new TableColumn("Value 2");
        columnValue2.setCellValueFactory(
                new PropertyValueFactory<Record,Double>("fieldValue2"));
        columnValue2.setMinWidth(60);
     
        //--- Add for Editable Cell of Value field, in Double
        columnValue1.setCellFactory(cellFactory);
        columnValue1.setOnEditCommit(
                new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
                    
                    @Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
                        ((Record)t.getTableView().getItems().get(
                                t.getTablePosition().getRow())).setFieldValue1(t.getNewValue());
                    }
                });
        
        columnValue2.setCellFactory(cellFactory);
        columnValue2.setOnEditCommit(
                new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
                    
                    @Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
                        ((Record)t.getTableView().getItems().get(
                                t.getTablePosition().getRow())).setFieldValue2(t.getNewValue());
                    }
                });
      
        //---
        tableView.setItems(dataList);
        tableView.getColumns().addAll(columnMonth, columnValue1, columnValue2);
        
        VBox vBox = new VBox();
        vBox.setSpacing(10);
        vBox.getChildren().add(tableView);
 
        root.getChildren().add(vBox);
     
      primaryStage.setScene(new Scene(root, 300, 350));
      primaryStage.show();
    }

    class EditingCell extends TableCell<Record, Double> {
        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(Double 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(Double.parseDouble(textField.getText()));
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }
     
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }
    
}


Related:
- JavaFX: Editable TableView with dynamic row