1919import java .util .concurrent .CountDownLatch ;
2020import java .util .concurrent .ScheduledFuture ;
2121import java .util .concurrent .TimeUnit ;
22+ import java .util .concurrent .atomic .AtomicBoolean ;
2223import java .util .concurrent .atomic .AtomicReference ;
2324import java .util .logging .Level ;
2425import java .util .stream .Collectors ;
2526
27+ import javafx .collections .FXCollections ;
2628import org .phoebus .applications .alarm .AlarmSystem ;
2729import org .phoebus .applications .alarm .client .AlarmClient ;
2830import org .phoebus .applications .alarm .client .AlarmClientLeaf ;
@@ -127,6 +129,9 @@ public class AlarmTreeView extends BorderPane implements AlarmClientListener
127129 /** Is change indicator shown, and future been submitted to clear it? */
128130 private final AtomicReference <ScheduledFuture <?>> ongoing_change = new AtomicReference <>();
129131
132+ /** A flag used to help reserve selections during updates, it flags if any of the selections are to be updated */
133+ private final AtomicBoolean selectionChanged = new AtomicBoolean (false );
134+
130135 /** Clear the change indicator */
131136 private final Runnable clear_change_indicator = () ->
132137 Platform .runLater (() ->
@@ -529,6 +534,11 @@ private void performUpdates()
529534 items_to_update .clear ();
530535 }
531536
537+ // Remember selection
538+ final ObservableList <TreeItem <AlarmTreeItem <?>>> updatedSelectedItems =
539+ FXCollections .observableArrayList (tree_view .getSelectionModel ().getSelectedItems ());
540+ selectionChanged .set (false );
541+
532542 // How to update alarm tree cells when data changed?
533543 // `setValue()` with a truly new value (not 'equal') should suffice,
534544 // but there are two problems:
@@ -552,6 +562,11 @@ private void performUpdates()
552562 // Create new TreeItem for that value
553563 final AlarmTreeItem <?> value = view_item .getValue ();
554564 final TreeItem <AlarmTreeItem <?>> update = new TreeItem <>(value );
565+ if (updatedSelectedItems .contains (view_item )) {
566+ updatedSelectedItems .remove (view_item );
567+ updatedSelectedItems .add (update );
568+ selectionChanged .set (true );
569+ }
555570 // Move child links to new item
556571 final ArrayList <TreeItem <AlarmTreeItem <?>>> children = new ArrayList <>(view_item .getChildren ());
557572 view_item .getChildren ().clear ();
@@ -561,6 +576,12 @@ private void performUpdates()
561576 path2view .put (value .getPathName (), update );
562577 parent .getChildren ().set (index , update );
563578 }
579+ // Restore selection
580+ if (selectionChanged .get ()) {
581+ tree_view .getSelectionModel ().clearSelection ();
582+ updatedSelectedItems .forEach (item -> tree_view .getSelectionModel ().select (item ));
583+ selectionChanged .set (false );
584+ }
564585 }
565586
566587 /** Context menu, details depend on selected items */
0 commit comments