1

I'm creating an application in JavaFx. Right now I have two tableviews next to each other:

------------------------------------------------------------------------------
| TableView 1                        |  TableView 2                          |  
|                                    |                                       |
|                                    |  Entry 1                              |
|                                    |  Entry 2                              |
|                                    |  Entry 3                              |
|                                    |  Entry ...                            |
|                                    |  Entry N                              |
------------------------------------------------------------------------------

I would like to copy items from TableView 2 to TableView 1, but at the same time, the entries that have been copied from TableView 2 need to be disabled (disable the row with setDisable or something similar). I do know how to copy the items from one tableview to another. The problem is that I do not know how to disable multiple rows when one or multiple entries have been copied to TableView 1. I tried this with a RowFactory, like this:

productsInTransaction.setRowFactory(tv -> {
      TableRow<Product> row = new TableRow<>();
      row.disableProperty().bind(???);
      return row;
});

Any help is much appreciated!

Robin Trietsch
  • 1,662
  • 2
  • 19
  • 31

1 Answers1

1

I'm not quite sure of the logic you're wanting, but if your row factory is attached to table 1, and you are disabling the row when the item is present in table 2, do:

row.disableProperty().bind(Bindings.createBooleanBinding(() -> 
    table2.getItems().contains(row.getItem()), table2.getItems(), row.itemProperty()));
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Thank you! This seems to be the right solution, however, I want to compare the entries (which are Objects in my case) by one of its attributes. So for example, if I have TableViews that contain Person objects, which have Name and Age as attributes, I would like to disable a row based on Name (unique). How can I do this? – Robin Trietsch Oct 28 '14 at 16:51
  • 1
    My stock answer at this point is "Use the [EasyBind framework](https://github.com/TomasMikula/EasyBind)". You can do `ObservableList names = EasyBind.map(table2.getItems(), Person::getName);`, and then the binding is `createBooleanBinding( () -> names.contains(row.getItem().getName()), names, row.itemProperty())` – James_D Oct 28 '14 at 16:57
  • The quick and dirty way, of course, is to override `equals(...)` in the `Person` class to just compare names. Of course, you may need different semantics for `equals(...)` for the rest of your application. – James_D Oct 28 '14 at 16:58
  • It works with EasyBind, but it still gives a lot of errors. It looks like the row factory is checking every row, while there is only one row in the tableview – Robin Trietsch Oct 29 '14 at 09:11
  • 1
    Yes, a row factory will be called for every displayed row (not just the ones containing data). So you need a null check on `row.getItem()` before calling `getName()`: try `createBooleanBinding( () -> row.getItem() != null && names.contains(row.getItem().getName()), names, row.itemProperty())` – James_D Oct 29 '14 at 12:26