How to layout a graph in a separate thread
Applies to: yFiles for Java 2.8, 2.7, 2.6, 2.5, 2.4 print article email article

Type: Questions & Answers

Explains how to invoke a layout algorithm from within a desktop application so that the GUI stays responsive while the layout is being calculated.

Note
Starting with version 2.7 yFiles for Java Complete provides the new class Graph2DLayoutExecutor which eases performing a layout. It provides an easier way of running a layout in a separate thread than the one described below. We recommend using Graph2DLayoutExecutor, if your distribution includes it.

Since the calculation of a graph layout may take a long time, it is desirable to invoke a layout algorithm within a separate thread so that the GUI of the application stays responsive. Ensuring that the graph can be properly displayed while it is being laid out requires that the layout algorithm works on a copy of the graph. The layout result needs to be applied to the original graph in a synchronized manner.

The following code represents an action event code that invokes a layout algorithm within a separate thread.

class ThreadedLayoutAction extends AbstractAction {
  boolean layoutMorphingEnabled = true;

  public ThreadedLayoutAction() {
    super("Threaded Layout");
  }

  public void actionPerformed(ActionEvent ev) {
    final OrganicLayouter layouter = new OrganicLayouter();
    // Copy graph in AWT thread.
    final CopiedLayoutGraph cGraph = new CopiedLayoutGraph(view.getGraph2D());

    // Calculate a layout on the copy of the original graph within a separate 
    // thread.
    final Thread thread = new Thread() {
      public void run() {
        layouter.doLayout(cGraph);

        // Assign the calculated layout to the original graph within the AWT 
        // thread.
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            if (layoutMorphingEnabled) {
              // Perform an animated morphing on layout result.
              GraphLayout gl = cGraph.getLayoutForOriginalGraph();
              new LayoutMorpher(view, gl).execute();
            }
            else {
              // Assign the layout directly without morphing and display the 
              // result.
              cGraph.commitLayoutToOriginalGraph();
              view.fitContent();
              view.updateView();
            }
          }
        });
      }
    };
    // Assign minimum priority to the layout thread so that the GUI remains 
    // responsive.
    thread.setPriority(Thread.MIN_PRIORITY);
    // Start the layout thread.
    thread.start();
  }
}
Warning
When applying the calculated layout to the original graph it is important that no nodes or edges have been added or removed from the graph during the layout process.

Attached is an executable demo program that makes use of the ThreadedLayoutAction. It extends demo.view.ViewActionDemo and should be placed in the yFiles demo package demo.view to function properly.


Keywords: thread - background - responsive - GUI - layout - invocation - separate - priority

Provide feedback:
How useful was this article?    less 1 2 3 4 5 more
Email address (optional):
COPYRIGHT © 2012 yWorks · ALL RIGHTS RESERVED imprint | terms of use | privacy policy | home