/* * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any */ package test.scenegraph.app; import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; //import static javafx.scene.input.DataFormat.URL; import javafx.scene.layout.VBox; import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.util.Callback; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.StringProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.control.CheckBox; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn.CellEditEvent; 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.util.Callback; public class BugApp3 extends Application { private void init(Stage primaryStage) { Group root = new Group(); primaryStage.setScene(new Scene(root)); primaryStage.setHeight(800); final ObservableList data = FXCollections.observableArrayList( new Person(true, "Jacob", "Smith", "jacob.smith@example.com") //,new Person(false, "Isabella", "Johnson", "isabella.johnson@example.com") //,new Person(true, "Ethan", "Williams", "ethan.williams@example.com") // ,new Person(true, "Emma", "Jones", "emma.jones@example.com") // ,new Person(false, "Michael", "Brown", "michael.brown@example.com") ); //"Invited" column TableColumn invitedCol = new TableColumn(); invitedCol.setText("Invited"); invitedCol.setMinWidth(50); invitedCol.setCellValueFactory(new PropertyValueFactory("invited")); invitedCol.setCellFactory(new Callback, TableCell>() { public TableCell call(TableColumn p) { return new CheckBoxTableCell(); } }); //"First Name" column TableColumn firstNameCol = new TableColumn(); firstNameCol.setText("First"); firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); //"Last Name" column TableColumn lastNameCol = new TableColumn(); lastNameCol.setText("Last"); lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); //"Email" column TableColumn emailCol = new TableColumn(); emailCol.setText("Email"); emailCol.setMinWidth(200); emailCol.setCellValueFactory(new PropertyValueFactory("email")); //Set cell factory for cells that allow editing Callback cellFactory = new Callback() { public TableCell call(TableColumn p) { return new EditingCell(); } }; emailCol.setCellFactory(cellFactory); firstNameCol.setCellFactory(cellFactory); lastNameCol.setCellFactory(cellFactory); //Set handler to update ObservableList properties. Applicable if cell is edited updateObservableListProperties(emailCol, firstNameCol, lastNameCol); TableView tableView = new TableView(); tableView.setItems(data); //Enabling editing tableView.setEditable(true); tableView.getColumns().addAll(invitedCol, firstNameCol, lastNameCol, emailCol); vbx = new VBox(); root.getChildren().add(vbx); vbx.getChildren().add(tableView); } static VBox vbx = null; private void updateObservableListProperties(TableColumn emailCol, TableColumn firstNameCol, TableColumn lastNameCol) { //Modifying the email property in the ObservableList emailCol.setOnEditCommit(new EventHandler>() { @Override public void handle(CellEditEvent t) { ((Person) t.getTableView().getItems().get( t.getTablePosition().getRow())).setEmail(t.getNewValue()); } }); //Modifying the firstName property in the ObservableList firstNameCol.setOnEditCommit(new EventHandler>() { @Override public void handle(CellEditEvent t) { ((Person) t.getTableView().getItems().get( t.getTablePosition().getRow())).setFirstName(t.getNewValue()); } }); //Modifying the lastName property in the ObservableList lastNameCol.setOnEditCommit(new EventHandler>() { @Override public void handle(CellEditEvent t) { ((Person) t.getTableView().getItems().get( t.getTablePosition().getRow())).setLastName(t.getNewValue()); } }); } //Person object public static class Person { private BooleanProperty invited; private StringProperty firstName; private StringProperty lastName; private StringProperty email; private Person(boolean invited, String fName, String lName, String email) { this.invited = new SimpleBooleanProperty(invited); this.firstName = new SimpleStringProperty(fName); this.lastName = new SimpleStringProperty(lName); this.email = new SimpleStringProperty(email); this.invited = new SimpleBooleanProperty(invited); this.invited.addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { System.out.println(firstNameProperty().get() + " invited: " + t1); } }); } public BooleanProperty invitedProperty() { return invited; } public StringProperty firstNameProperty() { return firstName; } public StringProperty lastNameProperty() { return lastName; } public StringProperty emailProperty() { return email; } public void setLastName(String lastName) { this.lastName.set(lastName); } public void setFirstName(String firstName) { this.firstName.set(firstName); } public void setEmail(String email) { this.email.set(email); } } //CheckBoxTableCell for creating a CheckBox in a table cell public static class CheckBoxTableCell extends TableCell { private final CheckBox checkBox; private ObservableValue ov; public CheckBoxTableCell() { this.checkBox = new CheckBox(); this.checkBox.setAlignment(Pos.CENTER); setAlignment(Pos.CENTER); setGraphic(checkBox); } @Override public void updateItem(T item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(null); } else { setGraphic(checkBox); if (ov instanceof BooleanProperty) { checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov); } ov = getTableColumn().getCellObservableValue(getIndex()); if (ov instanceof BooleanProperty) { checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov); } } } } // EditingCell - for editing capability in a TableCell public static class EditingCell extends TableCell { private TextField textField; public EditingCell() { } @Override public void startEdit() { super.startEdit(); if (textField == null) { createTextField(); } setText(null); setGraphic(textField); textField.selectAll(); } @Override public void cancelEdit() { super.cancelEdit(); setText((String) getItem()); setGraphic(null); vbx.getChildren().add(new Text("+1")); } @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(null); } else { if (isEditing()) { if (textField != null) { textField.setText(getString()); } setText(null); setGraphic(textField); } else { setText(getString()); setGraphic(null); } } } private void createTextField() { textField = new TextField(getString()); textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); textField.setOnKeyReleased(new EventHandler() { @Override public void handle(KeyEvent t) { if (t.getCode() == KeyCode.ENTER) { commitEdit(textField.getText()); } else if (t.getCode() == KeyCode.ESCAPE) { cancelEdit(); } } }); } private String getString() { return getItem() == null ? "" : getItem().toString(); } } @Override public void start(Stage primaryStage) throws Exception { init(primaryStage); primaryStage.show(); } public static void main(String[] args) { launch(args); } }