99
1010import static org .phoebus .applications .alarm .AlarmSystem .logger ;
1111
12+ import java .util .ArrayList ;
1213import java .util .Arrays ;
1314import java .util .Collections ;
1415import java .util .LinkedHashSet ;
4142import org .phoebus .ui .javafx .PrintAction ;
4243import org .phoebus .ui .javafx .Screenshot ;
4344import org .phoebus .ui .javafx .ToolbarHelper ;
44- import org .phoebus .ui .javafx .TreeHelper ;
4545import org .phoebus .ui .javafx .UpdateThrottle ;
4646import org .phoebus .ui .selection .AppSelection ;
4747import org .phoebus .ui .spi .ContextMenuEntry ;
@@ -466,9 +466,10 @@ public void itemUpdated(final AlarmTreeItem<?> item)
466466 }
467467
468468 /** Called by throttle to perform accumulated updates */
469+ @ SuppressWarnings ("unchecked" )
469470 private void performUpdates ()
470471 {
471- final TreeItem <? >[] view_items ;
472+ final TreeItem <AlarmTreeItem <?> >[] view_items ;
472473 synchronized (items_to_update )
473474 {
474475 // Creating a direct copy, i.e. another new LinkedHashSet<>(items_to_update),
@@ -480,8 +481,38 @@ private void performUpdates()
480481 items_to_update .clear ();
481482 }
482483
483- for (final TreeItem <?> view_item : view_items )
484- TreeHelper .triggerTreeItemRefresh (view_item );
484+ // How to update alarm tree cells when data changed?
485+ // `setValue()` with a truly new value (not 'equal') should suffice,
486+ // but there are two problems:
487+ // Since we're currently using the alarm tree model item as a value,
488+ // the value as seen by the TreeView remains the same.
489+ // We use a model item wrappers class as the cell value
490+ // and replace it (still referencing the same model item!)
491+ // for the TreeView to see a different wrapper value, but
492+ // as shown in org.phoebus.applications.alarm.TreeItemUpdateDemo,
493+ // replacing a tree cell value fails to trigger refreshes
494+ // for certain hidden items.
495+ // Only replacing the TreeItem gives reliable refreshes.
496+ for (final TreeItem <AlarmTreeItem <?>> view_item : view_items )
497+ // Top-level item has no parent, and is not visible, so we keep it
498+ if (view_item .getParent () != null )
499+ {
500+ // Locate item in tree parent
501+ final TreeItem <AlarmTreeItem <?>> parent = view_item .getParent ();
502+ final int index = parent .getChildren ().indexOf (view_item );
503+
504+ // Create new TreeItem for that value
505+ final AlarmTreeItem <?> value = view_item .getValue ();
506+ final TreeItem <AlarmTreeItem <?>> update = new TreeItem <>(value );
507+ // Move child links to new item
508+ final ArrayList <TreeItem <AlarmTreeItem <?>>> children = new ArrayList <>(view_item .getChildren ());
509+ view_item .getChildren ().clear ();
510+ update .getChildren ().addAll (children );
511+ update .setExpanded (view_item .isExpanded ());
512+
513+ path2view .put (value .getPathName (), update );
514+ parent .getChildren ().set (index , update );
515+ }
485516 }
486517
487518 /** Context menu, details depend on selected items */
0 commit comments