0

I am using an ObservableList to control the items and every time I delete an item, the TableView removes it from the datasource. But the view is not being updated as I'm still seeing all the items. The only difference is that the removed item can not be selected anymore.

Similar problem: javafx listview and treeview controls are not repainted correctly

In the following the code:

final TableColumn<TMachineType, String> testerType = new TableColumn<TMachineType, String>(
            bundle.getString("table.testerType"));

    testerType
            .setCellValueFactory(new PropertyValueFactory<TMachineType, String>(
                    "testerType"));

    testerType
            .setCellFactory(new Callback<TableColumn<TMachineType, String>, TableCell<TMachineType, String>>() {

                @Override
                public TableCell<TMachineType, String> call(
                        final TableColumn<TMachineType, String> param) {
                    final TableCell<TMachineType, String> cell = new TableCell<TMachineType, String>() {
                        @Override
                        protected void updateItem(final String item,
                                final boolean empty) {
                            super.updateItem(item, empty);
                            textProperty().unbind();
                            if (empty || item == null) {
                                setGraphic(null);
                                setText(null);
                            }
                            if (!empty) {
                                    final TMachineType row = (TMachineType) getTableRow().getItem();
                                    textProperty().bind(
                                            row.testerTypeProperty());
                                }

                        }
                    };
                    return cell;
                }
            });

TMachineType class:

private final SimpleStringProperty testerType = new SimpleStringProperty();

    @Column(name = "TESTER_TYPE")
public String getTesterType() {
    return testerType.get();
}

public void setTesterType(String testerType) {
    this.testerType.set(testerType);
}

public StringProperty testerTypeProperty() {
    return testerType;
}

Observable List: 1. DB entities:

final Query q = em.createQuery("SELECT t FROM TMachineType t");
final List resultList = q.getResultList();

2. Obs. list setup:

    ObservableList<TMachineType> observableList;
...
    observableList = FXCollections.observableArrayList(resultList);
    tableMachineType.setItems(observableList);
    FXCollections.sort(observableList);
  1. Row removal:

    @FXML
    private void handleOnRemove(final ActionEvent event) {
    
    final ObservableList<TMachineType> selectedIndices = tableMachineType
            .getSelectionModel().getSelectedItems();
    final String infoTxt = selectedIndices.size() + " "
            + bundle.getString("message.records_removed");
    
    final List<TMachineType> deleteBuffer = new ArrayList<TMachineType>();
    deleteBuffer.addAll(selectedIndices);
    
    for (final TMachineType selectedIdx : deleteBuffer) {
    
        selectedIdx.manufacturerProperty().unbind();
        selectedIdx.testerTypeProperty().unbind();
    
        deleted.add(selectedIdx);
        observableList.remove(selectedIdx);
        // tableMachineType.getItems().remove(selectedIdx);
    
    }
    ..
    

    }

Robb1
  • 4,587
  • 6
  • 31
  • 60
  • Have you tested the solution proposed in the question you mention? – José Pereda Dec 16 '14 at 12:06
  • yes, see the edited code below.. – Kübramiis Dec 16 '14 at 12:07
  • `updateItem()` should be called first – José Pereda Dec 16 '14 at 12:09
  • Your `if (! isEmpty())` is inside your `if (empty || item == null)`. Is that the same in your actual code? – James_D Dec 16 '14 at 12:11
  • do you mean before textProperty().unbind(); ? – Kübramiis Dec 16 '14 at 12:13
  • Yes. And also check @James_D comment – José Pereda Dec 16 '14 at 12:14
  • ok i have check, but the problem is still there.. :( – Kübramiis Dec 16 '14 at 12:19
  • I have a couple of guesses... Try replacing `if (! isEmpty() )` with `if (! empty)`, though I think your `super.updateItem(...)` should ensure those are the same. Second, it's never a good idea to rely on both the `updateItem(...)` and `getIndex(...)`: you have no idea which is updated first. See if you can avoid calling `getIndex()` - perhaps use `getTableRow().getItem()` to get the "row item". – James_D Dec 16 '14 at 12:20
  • Can you show a little more of how this is set up: just some of your `TMachineType` class (the relevant bits for this column) and the `cellValueFactory` you use? It seems like this cell factory is more complex than it needs to be. – James_D Dec 16 '14 at 12:30
  • Thanks. Tried to replace getIndex(..) with getTableRow().getItem(). Still doesn't work. Funny thing: it works perfectly fine in Java7. Somehow Java8_25 is not handing it properly. Any ideas? – Kübramiis Dec 16 '14 at 12:34
  • @James_D look at the updated code – Kübramiis Dec 16 '14 at 12:41
  • What happens if you remove the `cellFactory` entirely? It seems like it isn't doing anything that doesn't happen by default. – James_D Dec 16 '14 at 12:48
  • @James_D I need it to perform the binding: textProperty().bind(row.testerTypeProperty()); Here's how it goes: above the table of rows there's a tiny form to edit the currently selected row. Once a row is selected, its values are displayed in the form (binding is created). When you edit the form, the binding form->row is being applied. Since the table cell text property is also binded with the row, changes applied to the row (in the form) are immediately applied to the text value of the selected cell. Hence, I cannot remove the cellFactory. – Kübramiis Dec 16 '14 at 13:07
  • That is default behavior. – James_D Dec 16 '14 at 13:09
  • yes you are right ! The cellFactory was actually redundant :) I removed it. Unfortunately the original error is still there. Perhaps the fact that it works fine in Java7 is a clue? – Kübramiis Dec 16 '14 at 13:17
  • Hard to tell. If it's not the cell factory that is causing the issue, it's probably something to do with your observable list. Show the code where you create the list and the code where you remove items from it. I suspect you are wrapping a regular list and manipulating the regular list instead of the observable list. – James_D Dec 16 '14 at 13:29
  • @James_D I've updated the code part. I posted the creation and removal of the rows in the list. – Kübramiis Dec 16 '14 at 13:53
  • @James_D i have fixed the problem. it was really the cell factory that is causing the issue !! Thank you, good job ! – Kübramiis Dec 16 '14 at 14:57

1 Answers1

0

removing the cellFactory fix this problem ! YEHU :)

testerType
        .setCellFactory(new Callback<TableColumn<TMachineType, String>, TableCell<TMachineType, String>>() {

            @Override
            public TableCell<TMachineType, String> call(
                    final TableColumn<TMachineType, String> param) {
                final TableCell<TMachineType, String> cell = new TableCell<TMachineType, String>() {
                    @Override
                    protected void updateItem(final String item,
                            final boolean empty) {
                        super.updateItem(item, empty);
                        textProperty().unbind();
                        if (empty || item == null) {
                            setGraphic(null);
                            setText(null);
                        }
                        if (!empty) {
                                final TMachineType row = (TMachineType) getTableRow().getItem();
                                textProperty().bind(
                                        row.testerTypeProperty());
                            }

                    }
                };
                return cell;
            }
        });