/* * This is called when we think that the data within this TableCell may have * changed. You'll note that this is a private function - it is only called * when one of the triggers above call it. */ private void updateItem() { if (currentObservableValue != null) { currentObservableValue.removeListener(weaktableRowUpdateObserver); } // get the total number of items in the data model final TableView tableView = getTableView(); final List<T> items = tableView == null ? FXCollections.<T>emptyObservableList() : tableView.getItems(); final TableColumn tableColumn = getTableColumn(); final int itemCount = items == null ? -1 : items.size(); final int index = getIndex(); final boolean isEmpty = isEmpty(); final T oldValue = getItem(); final boolean indexExceedsItemCount = index >= itemCount; // there is a whole heap of reasons why we should just punt... if (indexExceedsItemCount || index < 0 || columnIndex < 0 || !isVisible() || tableColumn == null || !tableColumn.isVisible()) { // RT-30484 We need to allow a first run to be special-cased to allow // for the updateItem method to be called at least once to allow for // the correct visual state to be set up. In particular, in RT-30484 // refer to Ensemble8PopUpTree.png - in this case the arrows are being // shown as the new cells are instantiated with the arrows in the // children list, and are only hidden in updateItem. // RT-32621: There are circumstances where we need to updateItem, // even when the index is greater than the itemCount. For example, // RT-32621 identifies issues where a TreeTableView collapses a // TreeItem but the custom cells remain visible. This is now // resolved with the check for indexExceedsItemCount. if ((!isEmpty && oldValue != null) || isFirstRun || indexExceedsItemCount) { updateItem(null, true); isFirstRun = false; } return; } else { currentObservableValue = tableColumn.getCellObservableValue(index); final T newValue = currentObservableValue == null ? null : currentObservableValue.getValue(); // There used to be conditional code here to prevent updateItem from // being called when the value didn't change, but that led us to // issues such as RT-33108, where the value didn't change but the item // we needed to be listening to did. Without calling updateItem we // were breaking things, so once again the conditionals are gone. updateItem(newValue, false); } if (currentObservableValue == null) { return; } // add property change listeners to this item currentObservableValue.addListener(weaktableRowUpdateObserver); }
public <T> void bind(final Property<T> property, final ObservableValue<? extends T> dest) { InvalidationListener invalidationListener = new InvalidationListener() { @Override public void invalidated(Observable observable) { property.setValue(dest.getValue()); } }; WeakInvalidationListener weakInvalidationListener = new WeakInvalidationListener(invalidationListener); listeners.put(dest, weakInvalidationListener); dest.addListener(weakInvalidationListener); property.setValue(dest.getValue()); hardRefs.add(invalidationListener); }