CobianuA CobianuA - 3 months ago 9
Java Question

Can't set different values for my TableColumn in JavaFX

I tried to set a

Button
in a
TableView
column, but I didn't succeed in setting different buttons. It shows me the same buttons on all the columns.

The idea is that the name is set correctely, but my problem is when I set
cellValueFactory
. This is my code:

for (int i = 0; i < listaPatchuriPerBaza.length; i++) {

if (listaPatchuriPerBaza[i].contains(".sql")) {
k = i;
pozitie = poz;
Patch pt = new Patch(listaPatchuriPerBaza[i], "Run" + " " + listaPatchuriPerBaza[i]);
listaPatchuri.add(pt);
masterData.add(pt);
patchColumn.setCellValueFactory(new PropertyValueFactory<Patch, String>("denumire"));
runColumn.setCellValueFactory(new PropertyValueFactory<Patch, String>("btnText"));
runColumn.setCellFactory(new Callback<TableColumn<Patch, String>, TableCell<Patch, String>>() {

@Override
public TableCell<Patch, String> call(TableColumn<Patch, String> param) {

Button btn = new Button(pt.getBtnText());

//Set up the Table
TableCell<Patch, String> cell = new TableCell<Patch, String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
//actioneaza butonul de run
btn.setOnAction((ActionEvent event) -> {
btn.setDisable(true);
Tooltip tool = new Tooltip("Running");
setTooltip(tool);
System.out.println("ruleaza");
try {
SmbFile script = new SmbFile(path + pt.getDenumire(), userCred);

} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {

SmbFile smbFromFile = new SmbFile(path + pt.getDenumire(), userCred);
SmbFile smbToFile = new SmbFile(path + "Aplicate/" + pt.getDenumire(), userCred);
smbFromFile.renameTo(smbToFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
setGraphic(btn);

}
}

};

return cell;
}
});

}

tableView.setItems(masterData);

}



Answer

It makes no sense to set the cell value factory and the cell factory once for each row in the table: all you do is replace the factory each time you iterate through your loop. These are factories: i.e. objects that create other objects. The table column will call their call methods as needed to create multiple cells etc.

So just set them once and update the button's text in the updateItem() method. The button needs to be a property of the cell (so that each cell has its own button, with its own text), not of the cell factory (because there is only one cell factory for the entire column).

runColumn.setCellValueFactory(new PropertyValueFactory<Patch, String>("btnText"));
runColumn.setCellFactory(column -> new TableCell<Patch, String>() {
    Button btn = new Button();

    {
        btn.setOnAction(e -> {
            Patch pt = getTableView().getItems().get(getIndex());
            btn.setDisable(true);
            Tooltip tool = new Tooltip("Running");
            setTooltip(tool);
            System.out.println("ruleaza");
            try {
                SmbFile script = new SmbFile(path + pt.getDenumire(), userCred);

            } catch (MalformedURLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {

                SmbFile smbFromFile = new SmbFile(path + pt.getDenumire(), userCred);
                SmbFile smbToFile = new SmbFile(path + "Aplicate/" + pt.getDenumire(), userCred);
                smbFromFile.renameTo(smbToFile);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        });
    }

    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (item == null) {
            setGraphic(null);
        } else {
            btn.setText(item);
            setGraphic(btn);
        }
    }
});