It seems to me that you may need to reconsider your object model. It seems that your Product has two different values ββthat you name amount : the one that appears in table1, and the one that appears in table2. If you create these two different fields of the Product class, all this will become much simpler, since you can represent elements in both tables with the same actual objects (only with different properties displayed in the columns); and then the criteria for disconnecting a row becomes only a function of the object you are looking at (along with table2.getItems().contains(...) ).
Another option might be the SKU class:
public class SKU { private final StringProperty sku = ... ;
Then both tables can be a TableView<SKU> with factories of cell values ββin columns, just looking at the properties from the correct product. Thus, row.getItem() in table1, the row factory returns an SKU object and can, if necessary, look for the properties of table2.
If you really cannot do this, then one way to do this is to support ObservableMap<String, Double> , which maps the SKU to the amount displayed in table2. This is a little work, but not so bad:
ObservableMap<String, Double> skuAmountLookup = table2.getItems().stream().collect( Collectors.toMap(Product::getSKU, Product::getAmount,
Now you need to update the map when changing the contents of the table:
table2.getItems().addListener((ListChangeListener.Change<? extends Product> change) -> { // can just do skuAmountLookup.clear(); followed by skuAmountLookup.putAll(...) // passing in the same data used above to initialize it // That pretty inefficient though, the following will just update what needed. // This assumes SKUs are unique in table 2: while (change.next()) { if (change.wasAdded()) { change.getAddedSubList().forEach(product -> skuAmountLookup.put(product.getSKU(), product.getAmount())); } if (change.wasRemoved()) { change.getRemoved().forEach(product -> skuAmountLookup.remove(product.getSKU())); } } });
And then the disconnection criteria may be similar to
row.disableProperty().bind(Bindings.createBooleanBinding( () -> row.getItem() != null && skuAmountLookup.containsKey(row.getItem().getSKU()) && skuAmountLookup.get(row.getItem().getSKU()) < 0, skuAmountLookup, row.itemProperty()));
I have not tried any of this, but it should work. There are two assumptions here:
- SKUs are unique in table 2
- The amount in table 2 will not change, except by adding or removing items from the table. If necessary, this can be processed, but adds another level of complexity to the listener on table2 elements.