neeraj.sonar
neeraj.sonar

Reputation: 74

editable table in javafx

I'm trying to build a billing system in javafx, and I could build the table and everything. Now I want to change it, I want the table to be already editable, i.e the text fields in the table should be enabled to edit before onEditCommite. Also storing the data in the table is also giving a problem. The code is given below. In the below code, the rows are being added and can be deleted. But I want to make it editable when the "new bill" button in clicked. Also any method to calculate the Price by multiplying the this.rate and this.qty.

    public class abc extends Application {
private TableView<Billing> table = new TableView<Billing>();
private final ObservableList<Billing> data = FXCollections.observableArrayList();
final HBox hb = new HBox();
final HBox hb1=new HBox();
final HBox hb2= new HBox();
private IntegerProperty index = new SimpleIntegerProperty();

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

// Stage Start method. Whole Stage.
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Billing");
stage.setWidth(550);
stage.setHeight(650);
final Label label = new Label("Billing Trial 2 ");
label.setFont(new Font("Comic Sans", 26));

//Call EditingCell and set true to make it editable
table.setEditable(true);
Callback<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};

TableColumn srnoCol = new TableColumn("Sr. No. ");
srnoCol.setMinWidth(50);
srnoCol.setCellValueFactory(
new PropertyValueFactory<Billing, String>("srNo"));

srnoCol.setCellFactory(cellFactory);
TableColumn numCol = new TableColumn("Item Code ");
numCol.setMinWidth(50);
numCol.setCellValueFactory(
new PropertyValueFactory<Billing, String>("itemCode"));
numCol.setCellFactory(cellFactory);
numCol.setOnEditCommit(
new EventHandler<CellEditEvent<Billing, String>>() {
@Override
public void handle(CellEditEvent<Billing, String> t) {
((Billing) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setItemCode(t.getNewValue());
}
}
);
TableColumn nameCol = new TableColumn("Item Name ");
nameCol.setMinWidth(100);
nameCol.setCellValueFactory(
new PropertyValueFactory<Billing, String>("itemName"));
nameCol.setCellFactory(cellFactory);
nameCol.setOnEditCommit(
new EventHandler<CellEditEvent<Billing, String>>() {
@Override
public void handle(CellEditEvent<Billing, String> t) {
((Billing) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setItemName(t.getNewValue());
}
}
);

TableColumn qtyCol = new TableColumn("Qty ");
qtyCol.setMinWidth(100);
qtyCol.setCellValueFactory(
new PropertyValueFactory<Billing, String>("itemQty"));
qtyCol.setCellFactory(cellFactory);
qtyCol.setOnEditCommit(
new EventHandler<CellEditEvent<Billing, String>>() {
@Override
public void handle(CellEditEvent<Billing, String> t) {
((Billing) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setItemQty(t.getNewValue());
}
}
);

TableColumn rateCol = new TableColumn("Item Rate ");
rateCol.setMinWidth(50);
rateCol.setCellValueFactory(
new PropertyValueFactory<Billing, String>("itemRate"));
rateCol.setCellFactory(cellFactory);
rateCol.setOnEditCommit(
new EventHandler<CellEditEvent<Billing, String>>() {
@Override
public void handle(CellEditEvent<Billing, String> t) {
((Billing) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setItemRate(t.getNewValue());
}
}
);
TableColumn priceCol = new TableColumn("Item Price ");
priceCol.setMinWidth(50);
priceCol.setCellValueFactory(
new PropertyValueFactory<Billing, String>("itemPrice"));
priceCol.setCellFactory(cellFactory);
priceCol.setOnEditCommit(
new EventHandler<CellEditEvent<Billing, String>>() {
@Override
public void handle(CellEditEvent<Billing, String> t) {
((Billing) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setItemPrice(t.getNewValue());
}
}
);
table.setItems(data);

//indexing of elements for deleting function.
table.getSelectionModel().selectedItemProperty().addListener(newChangeListener<Object>() {
@Override
public void changed(ObservableValue<?>observable, Object oldvalue, Object newValue){
index.set(data.indexOf(newValue));
System.out.println("index: "+data.indexOf(newValue));
}
});

//Deleting
final Button deleteButton=new Button("Delete");
deleteButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent de){
int i = index.get();
if (i>-1){
data.remove(i);
table.getSelectionModel().clearSelection();
}
}
});

TableColumn amount = new TableColumn("Amount");
amount.getColumns().addAll(rateCol, priceCol);
table.setItems(data);
table.getColumns().addAll(srnoCol, numCol, nameCol, qtyCol, amount );



//add bill
final Button addButton = new Button("New Bill");
addButton.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent ae)
{
EditingCell ec = new EditingCell();
ec.getString();
ec.createTextField();
table.setEditable(true);
Callback<TableColumn, TableCell>  cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
ec.startEdit();
ec.cancelEdit();

data.add(new Billing(null,null,null,null,null,null));
}
});

hb.getChildren().addAll( addButton, deleteButton);
hb.setAlignment(Pos.BASELINE_LEFT);
hb.setSpacing(16);
final Label label2 = new Label();
label2.setAlignment(Pos.BASELINE_RIGHT);

final VBox vbox = new VBox();
vbox.setSpacing(15);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label,hb2, hb,  table,hb1);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}

//Class Billing
public  static class Billing {
private final SimpleStringProperty itemSrNo;
private final SimpleStringProperty itemCode;
private final SimpleStringProperty itemName;
private final SimpleStringProperty itemQty;
private final SimpleStringProperty itemRate;
private final SimpleStringProperty itemPrice;
private Billing(String iSrNo, String iCode, String iName, String iQty, String iRate,String iPrice) 
{
this.itemSrNo = new SimpleStringProperty(iSrNo);
this.itemCode = new SimpleStringProperty(iCode);
this.itemName = new SimpleStringProperty(iName);
this.itemPrice = new SimpleStringProperty(iPrice);
this.itemQty = new SimpleStringProperty(iQty);
this.itemRate = new SimpleStringProperty(iRate);
}
public String getItemSrNo() {
return itemSrNo.get();
}
public void setItemSrNo(String iSrNo) {
itemSrNo.set(iSrNo);
}

public String getItemCode() {
return itemCode.get();
}
public void setItemCode(String iCode) {
itemCode.set(iCode);
}
public String getItemName() {
return itemName.get();
}
public void setItemName(String iName) {
itemName.set(iName);
}
public String getItemQty() {
return itemQty.get();
}
public void setItemQty(String iQty) {
itemQty.set(iQty);
}
public String getItemPrice() {
return itemPrice.get();
}
public void setItemPrice(String iPrice) {
itemPrice.set(iPrice);
}
public String getItemRate() {
return itemRate.get();
}
public void setItemRate(String iRate) {
itemRate.set(iRate);
}
}

//CellEditing
public  class EditingCell extends TableCell<Billing, String> {
private TextField textField;
public EditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@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.focusedProperty().addListener(new ChangeListener<Boolean>(){
@Override
public void changed(ObservableValue<? extends Boolean> arg0, 
Boolean arg1, Boolean arg2) {
if (!arg2) {
commitEdit(textField.getText());
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
}

// calculation of Qty x Rate.
class Calculate {

public String sum(int iQty, int iRate)
{
 int sum =  iQty*iRate;
 String s =""+sum;
 return s;
}
}

Upvotes: 0

Views: 573

Answers (1)

Aakash
Aakash

Reputation: 1900

Old question but here is what I think should work : Dont use setGraphic(null) in your cellFactory. Always set it to TextField. Also for the calculation part you can add listeners to your properties in the data model and perform calculation on any change of values for those properties.

Upvotes: 1

Related Questions