Listening to Selection Changes Efficiently

Tips & Tricks

Summary

This article describes how to listen to selection changes efficiently.
For a better user experience, please go to the integrated documentation viewer to read this article.

Description

Listening to selection changes can easily be done by registering a Graph2DSelectionListener to the graph:

graph2D.addGraph2DSelectionListener(new Graph2DSelectionListener(){
  public void onGraph2DSelectionEvent(Graph2DSelectionEvent e) {
    //do something
  }
});

But there is one problem using this approach:
Listening to every single selection change that happens might be quite inefficient if you want to react on all changes at once. For example when using the marquee selection and thus selecting various nodes, a selection event is beeing fired for every single node selection.
To avoid this you can use one of the following solutions:

Using helper class Selections.SelectionStateObserver

You can avoid this by registering an implementation of class Selections.SelectionStateObserver as a selection listener and graph listener:

Graph2D graph2D = view.getGraph2D();
Selections.SelectionStateObserver listener = new Selections.SelectionStateObserver() {
  protected void updateSelectionState(Graph2D graph) {
    //handle all changes at once here
  }
};
graph2D.addGraph2DSelectionListener(listener);
graph2D.addGraphListener(listener);

This helper class will bracket all changes and thus allows to handle all changes at once. Simply add your code into method updateSelectionState of class SelectionsSelectionStateObserver.

Using SwingUtilities.invokeLater()

Another possibility is to wait for the marquee selection event to end and execute your selection handling code then. Therefor you can register a Graph2DSelectionListener to the graph as follows:

Graph2D graph2D = view.getGraph2D();
graph2D.addGraph2DSelectionListener(
new Graph2DSelectionListener(){
  List events;
  protected Runnable runnable = new Runnable(){
    public void run() {
      List eventsCopy = events;
      events = null;
      onGraph2DSelectionEvents(eventsCopy);
    }
  };

  public void onGraph2DSelectionEvent(Graph2DSelectionEvent e) {
    if (events == null){
      events = new ArrayList();
      SwingUtilities.invokeLater(runnable);
    }
    events.add(e);
  }
});

where onGraph2DSelectionEvents(List eventCopy) is the method where you can execute your code:

protected void onGraph2DSelectionEvents(List eventsCopy) {
  System.out.println("SelectionStateObserverDemo.onGraph2DSelectionEvents");
  for (Iterator iterator = eventsCopy.iterator(); iterator.hasNext();) {
    Graph2DSelectionEvent event = (Graph2DSelectionEvent) iterator.next();
    System.out.println("Selected " + event.getSubject());
  }
}
Find attached a simple demo application that uses both of the described approaches. To compile and run the demo, copy the attached file to the src/demo/view/ directory of your yFiles installation.

Resources

Categories this article belongs to:
yFiles for Java > yFiles Viewer > Displaying and Editing Graphs > Events and Listeners
Applies to:
yFiles for Java 2: 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 2.10, 2.11, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.18
Keywords:
selection - event - listener - addGraph2DSelectionListener