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


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


No comments:

Post a Comment

[フレーム]

Subscribe to: Post Comments (Atom)

AltStyle によって変換されたページ (->オリジナル) /