code: package io.github.contractautomata.catapp;
  
  import java.awt.BorderLayout;
  import java.awt.Point;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.event.MouseAdapter;
  import java.awt.event.MouseEvent;
  import java.awt.event.MouseMotionListener;
  import java.awt.event.MouseWheelEvent;
  import java.awt.event.MouseWheelListener;
  import java.io.File;
  import java.util.List;
  import java.util.Objects;
  
  import javax.swing.AbstractAction;
  import javax.swing.Action;
  import javax.swing.BorderFactory;
  import javax.swing.ImageIcon;
  import javax.swing.JCheckBoxMenuItem;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JMenuBar;
  import javax.swing.JOptionPane;
  import javax.swing.JPanel;
  import javax.swing.JPopupMenu;
  import javax.swing.JTabbedPane;
  import javax.swing.JToolBar;
  import javax.swing.SwingUtilities;
  import javax.swing.UIManager;
  
  import com.mxgraph.layout.mxCircleLayout;
  import com.mxgraph.layout.mxCompactTreeLayout;
  import com.mxgraph.layout.mxEdgeLabelLayout;
  import com.mxgraph.layout.mxIGraphLayout;
  import com.mxgraph.layout.mxOrganicLayout;
  import com.mxgraph.layout.mxParallelEdgeLayout;
  import com.mxgraph.layout.mxPartitionLayout;
  import com.mxgraph.layout.mxStackLayout;
  import com.mxgraph.layout.hierarchical.mxHierarchicalLayout;
  import com.mxgraph.swing.mxGraphComponent;
  import com.mxgraph.swing.mxGraphOutline;
  import com.mxgraph.swing.handler.mxKeyboardHandler;
  import com.mxgraph.swing.handler.mxRubberband;
  import com.mxgraph.swing.util.mxMorphing;
  import com.mxgraph.util.mxEvent;
  import com.mxgraph.util.mxEventObject;
  import com.mxgraph.util.mxEventSource.mxIEventListener;
  import com.mxgraph.util.mxRectangle;
  import com.mxgraph.util.mxResources;
  import com.mxgraph.util.mxUndoManager;
  import com.mxgraph.util.mxUndoableEdit;
  import com.mxgraph.util.mxUndoableEdit.mxUndoableChange;
  import com.mxgraph.view.mxGraph;
  
  public class BasicGraphEditor extends JPanel
  {
  
  	/**
  	 * 
  	 */
  	private static final long serialVersionUID = -6561623072112577140L;
  
  	static
  	{
  		try
  		{
  			mxResources.add("io/github/contractautomata/catapp/resources/editor");
  		}
  		catch (Exception e)
  		{
  			// ignore
  		}
  	}
  
  	/**
  	 * 
  	 */
  	protected mxGraphComponent graphComponent;
  
  	/**
  	 * 
  	 */
  	protected mxGraphOutline graphOutline;
  
  	/**
  	 * 
  	 */
  	protected JTabbedPane libraryPane;
  
  	/**
  	 * 
  	 */
  	protected mxUndoManager undoManager;
  
  	/**
  	 * 
  	 */
  	protected String appTitle;
  
  	/**
  	 * 
  	 */
  	protected JLabel statusBar;
  
  	/**
  	 * 
  	 */
  	protected File currentFile;
  
  	/**
  	 * Flag indicating whether the current graph has been modified 
  	 */
  	protected boolean modified = false;
  
  	/**
  	 * 
  	 */
  	protected mxRubberband rubberband;
  
  	/**
  	 * 
  	 */
  	protected mxKeyboardHandler keyboardHandler;
  
  	/**
  	 * 
  	 */
  	protected final mxIEventListener undoHandler = new mxIEventListener()
  	{
  		public void invoke(Object source, mxEventObject evt)
  		{
  			undoManager.undoableEditHappened((mxUndoableEdit) evt
  					.getProperty("edit"));
  		}
  	};
  
  	/**
  	 * 
  	 */
  	protected final mxIEventListener changeTracker = (source, evt) -> setModified(true);
  
  	/**
  	 * 
  	 */
  	public BasicGraphEditor(String appTitle, mxGraphComponent component)
  	{
  		// Stores and updates the frame title
  		this.appTitle = appTitle;
  
  		// Stores a reference to the graph and creates the command history
  		graphComponent = component;
  		final mxGraph graph = graphComponent.getGraph();
  		undoManager = createUndoManager();
  
  		// Do not change the scale and translation after files have been loaded
  		graph.setResetViewOnRootChange(false);
  
  		// Updates the modified flag if the graph model changes
  		graph.getModel().addListener(mxEvent.CHANGE, changeTracker);
  
  		// Adds the command history to the model and view
  		graph.getModel().addListener(mxEvent.UNDO, undoHandler);
  		graph.getView().addListener(mxEvent.UNDO, undoHandler);
  
  		// Keeps the selection in sync with the command history
  		mxIEventListener undoHandler = (source, evt) -> {
  			List<mxUndoableChange> changes = ((mxUndoableEdit) evt
  					.getProperty("edit")).getChanges();
  			graph.setSelectionCells(graph
  					.getSelectionCellsForChanges(changes));
  		};
  
  		undoManager.addListener(mxEvent.UNDO, undoHandler);
  		undoManager.addListener(mxEvent.REDO, undoHandler);
  
  		// Creates the graph outline component
  		graphOutline = new mxGraphOutline(graphComponent);
  
  		// 
  		// 	THE RIGHT PALETTE PANEL HAS BEEN MOVED TO THE TOOLBAR
  
  		// Creates the library pane that contains the tabs with the palettes
  		//	libraryPane = new JTabbedPane();
  
  		//		// Creates the inner split pane that contains the library with the
  		//		// palettes and the graph outline on the left side of the window
  		//		JSplitPane inner = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
  		//				libraryPane, graphOutline);
  		//		inner.setDividerLocation(320);
  		//		inner.setResizeWeight(1);
  		//		inner.setDividerSize(6);
  		//		inner.setBorder(null);
  
  		// Creates the outer split pane that contains the inner split pane and
  		// the graph component on the right side of the window
  		//		JSplitPane outer = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, libraryPane,
  		//				graphComponent);
  		//		outer.setOneTouchExpandable(true);
  		//		outer.setDividerLocation(200);
  		//		outer.setDividerSize(6);
  		//		outer.setBorder(null);
  
  		// Creates the status bar
  		statusBar = createStatusBar();
  
  		// Display some useful information about repaint events
  		installRepaintListener();
  
  		// Puts everything together
  		setLayout(new BorderLayout());
  
  		add(graphComponent, BorderLayout.CENTER);//previously was outer instead of graphComponent
  		add(statusBar, BorderLayout.SOUTH);
  		installToolBar();
  
  		// Installs rubberband selection and handling for some special
  		// keystrokes such as F2, Control-C, -V, X, A etc.
  		installHandlers();
  		installListeners();
  		updateTitle();
  	}
  
  	/**
  	 * 
  	 */
  	protected mxUndoManager createUndoManager()
  	{
  		return new mxUndoManager();
  	}
  
  	/**
  	 * 
  	 */
  	protected void installHandlers()
  	{
  		rubberband = new mxRubberband(graphComponent);
  		keyboardHandler = new EditorKeyboardHandler(graphComponent);
  	}
  
  	/**
  	 * 
  	 */
  	protected void installToolBar()
  	{
  		add(new EditorToolBar(this, JToolBar.HORIZONTAL), BorderLayout.NORTH);
  	}
  
  	/**
  	 * 
  	 */
  	protected JLabel createStatusBar()
  	{
  		JLabel statusBar = new JLabel(mxResources.get("ready"));
  		statusBar.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4));
  
  		return statusBar;
  	}
  
  	/**
  	 * 
  	 */
  	protected void installRepaintListener()
  	{
  		graphComponent.getGraph().addListener(mxEvent.REPAINT,
  				(source, evt) -> {
  					String buffer = (graphComponent.getTripleBuffer() != null) ? ""
  							: " (unbuffered)";
  					mxRectangle dirty = (mxRectangle) evt
  							.getProperty("region");
  
  					if (dirty == null)
  					{
  						status("Repaint all" + buffer);
  					}
  					else
  					{
  						status("Repaint: x=" + (int) (dirty.getX()) + " y="
  								+ (int) (dirty.getY()) + " w="
  								+ (int) (dirty.getWidth()) + " h="
  								+ (int) (dirty.getHeight()) + buffer);
  					}
  				});
  	}
  
  	//	public EditorPalette insertPalette(String title)
  //	{
  //		final EditorPalette palette = new EditorPalette();
  //		final JScrollPane scrollPane = new JScrollPane(palette);
  //		scrollPane
  //		.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
  //		scrollPane
  //		.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
  //		libraryPane.add(title, scrollPane);
  //
  //		// Updates the widths of the palettes if the container size changes
  //		libraryPane.addComponentListener(new ComponentAdapter()
  //		{
  //			public void componentResized(ComponentEvent e)
  //			{
  //				int w = scrollPane.getWidth()
  //						- scrollPane.getVerticalScrollBar().getWidth();
  //				palette.setPreferredWidth(w);
  //			}
  //
  //		});
  //
  //		return palette;
  //	}
  
  	/**
  	 * 
  	 */
  	protected void mouseWheelMoved(MouseWheelEvent e)
  	{
  		if (e.getWheelRotation() < 0)
  		{
  			graphComponent.zoomIn();
  		}
  		else
  		{
  			graphComponent.zoomOut();
  		}
  
  		status(mxResources.get("scale") + ": "
  				+ (int) (100 * graphComponent.getGraph().getView().getScale())
  				+ "%");
  	}
  
  	/**
  	 * 
  	 */
  	protected void showOutlinePopupMenu(MouseEvent e)
  	{
  		Point pt = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(),
  				graphComponent);
  		JCheckBoxMenuItem item = new JCheckBoxMenuItem(
  				mxResources.get("magnifyPage"));
  		item.setSelected(graphOutline.isFitPage());
  
  		item.addActionListener(new ActionListener()
  		{
  			/**
  			 * 
  			 */
  			public void actionPerformed(ActionEvent e)
  			{
  				graphOutline.setFitPage(!graphOutline.isFitPage());
  				graphOutline.repaint();
  			}
  		});
  
  		JCheckBoxMenuItem item2 = new JCheckBoxMenuItem(
  				mxResources.get("showLabels"));
  		item2.setSelected(graphOutline.isDrawLabels());
  
  		item2.addActionListener(new ActionListener()
  		{
  			/**
  			 * 
  			 */
  			public void actionPerformed(ActionEvent e)
  			{
  				graphOutline.setDrawLabels(!graphOutline.isDrawLabels());
  				graphOutline.repaint();
  			}
  		});
  
  		JCheckBoxMenuItem item3 = new JCheckBoxMenuItem(
  				mxResources.get("buffering"));
  		item3.setSelected(graphOutline.isTripleBuffered());
  
  		item3.addActionListener(new ActionListener()
  		{
  			/**
  			 * 
  			 */
  			public void actionPerformed(ActionEvent e)
  			{
  				graphOutline.setTripleBuffered(!graphOutline.isTripleBuffered());
  				graphOutline.repaint();
  			}
  		});
  
  		JPopupMenu menu = new JPopupMenu();
  		menu.add(item);
  		menu.add(item2);
  		menu.add(item3);
  		menu.show(graphComponent, pt.x, pt.y);
  
  		e.consume();
  	}
  
  	/**
  	 * 
  	 */
  	protected void showGraphPopupMenu(MouseEvent e)
  	{
  		Point pt = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(),
  				graphComponent);
  		EditorPopupMenu menu = new EditorPopupMenu(BasicGraphEditor.this, pt);
  		menu.show(graphComponent, pt.x, pt.y);
  
  		e.consume();
  	}
  
  	/**
  	 * 
  	 */
  	protected void mouseLocationChanged(MouseEvent e)
  	{
  		status(e.getX() + ", " + e.getY());
  	}
  
  	/**
  	 * 
  	 */
  	protected void installListeners()
  	{
  		// Installs mouse wheel listener for zooming
  		MouseWheelListener wheelTracker = new MouseWheelListener()
  		{
  			/**
  			 * 
  			 */
  			public void mouseWheelMoved(MouseWheelEvent e)
  			{
  				if (e.getSource() instanceof mxGraphOutline
  						|| e.isControlDown())
  				{
  					BasicGraphEditor.this.mouseWheelMoved(e);
  				}
  			}
  
  		};
  
  		// Handles mouse wheel events in the outline and graph component
  		graphOutline.addMouseWheelListener(wheelTracker);
  		graphComponent.addMouseWheelListener(wheelTracker);
  
  		// Installs the popup menu in the outline
  		graphOutline.addMouseListener(new MouseAdapter()
  		{
  
  			/**
  			 * 
  			 */
  			public void mousePressed(MouseEvent e)
  			{
  				// Handles context menu on the Mac where the trigger is on mousepressed
  				mouseReleased(e);
  			}
  
  			/**
  			 * 
  			 */
  			public void mouseReleased(MouseEvent e)
  			{
  				if (e.isPopupTrigger())
  				{
  					showOutlinePopupMenu(e);
  				}
  			}
  
  		});
  
  		// Installs the popup menu in the graph component
  		graphComponent.getGraphControl().addMouseListener(new MouseAdapter()
  		{
  
  			/**
  			 * 
  			 */
  			public void mousePressed(MouseEvent e)
  			{
  
  //				Object o=graphComponent.getCellAt(e.getX(),e.getY());
  //				if(o!=null && o instanceof mxCell) {
  //					mxCell edge =(mxCell)o;
  //					if (edge.isEdge())
  //					{
  //						mxGeometry eg = edge.getGeometry();
  //
  //						mxPoint source = (edge.getSource()!=null)?eg.getSourcePoint():eg.getTerminalPoint(true);
  //						mxPoint target = (edge.getTarget()!=null)?eg.getTargetPoint():eg.getTerminalPoint(false);
  //
  //
  //						List<mxPoint> l = eg.getPoints()!=null?new ArrayList<mxPoint>(eg.getPoints()):new ArrayList<mxPoint>();
  //
  //						Point pt = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(),graphComponent);
  //
  //						if (!l.stream().anyMatch(p->p.getX()==pt.x&&p.getY()==p.getY()))
  //						{
  //							l.add(new mxPoint(pt.x,pt.y));
  //							eg.setPoints(l);
  //							eg.setSourcePoint(source);
  //							eg.setTargetPoint(target);
  //						}
  //						e.consume();
  //						graphComponent.refresh();
  //
  //					}
  //				}
  //				else 
  					// Handles context menu on the Mac where the trigger is on mousepressed
  					mouseReleased(e);
  			}
  
  			/**
  			 * 
  			 */
  			public void mouseReleased(MouseEvent e)
  			{
  				if (e.isPopupTrigger())
  				{
  					showGraphPopupMenu(e);
  				}
  			}
  
  		});
  
  		// Installs a mouse motion listener to display the mouse location
  		graphComponent.getGraphControl().addMouseMotionListener(
  				new MouseMotionListener()
  				{
  
  					/*
  					 * (non-Javadoc)
  					 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
  					 */
  					public void mouseDragged(MouseEvent e)
  					{
  						mouseLocationChanged(e);
  					}
  
  					/*
  					 * (non-Javadoc)
  					 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
  					 */
  					public void mouseMoved(MouseEvent e)
  					{
  						mouseDragged(e);
  					}
  
  				});
  	}
  
  	/**
  	 * 
  	 */
  	public void setCurrentFile(File file)
  	{
  		File oldValue = currentFile;
  		currentFile = file;
  
  		firePropertyChange("currentFile", oldValue, file);
  
  		if (oldValue != file)
  		{
  			updateTitle();
  		}
  	}
  
  	/**
  	 * 
  	 */
  	public File getCurrentFile()
  	{
  		return currentFile;
  	}
  
  	/**
  	 *
  	 */
  	public void setModified(boolean modified)
  	{
  		boolean oldValue = this.modified;
  		this.modified = modified;
  
  		firePropertyChange("modified", oldValue, modified);
  
  		if (oldValue != modified)
  		{
  			updateTitle();
  		}
  	}
  
  	/**
  	 * 
  	 * @return whether or not the current graph has been modified
  	 */
  	public boolean isModified()
  	{
  		return modified;
  	}
  
  	/**
  	 * 
  	 */
  	public mxGraphComponent getGraphComponent()
  	{
  		return graphComponent;
  	}
  
  	/**
  	 * 
  	 */
  	public mxGraphOutline getGraphOutline()
  	{
  		return graphOutline;
  	}
  
  	/**
  	 * 
  	 */
  	public JTabbedPane getLibraryPane()
  	{
  		return libraryPane;
  	}
  
  	/**
  	 * 
  	 */
  	public mxUndoManager getUndoManager()
  	{
  		return undoManager;
  	}
  
  	/**
  	 * 
  	 * @return a new Action bound to the specified string name
  	 */
  	public Action bind(String name, final Action action)
  	{
  		return bind(name, action, null);
  	}
  
  	/**
  	 * 
  	 * @return a new Action bound to the specified string name and icon
  	 */
  	@SuppressWarnings("serial")
  	public Action bind(String name, final Action action, String iconUrl)
  	{
  		AbstractAction newAction = new AbstractAction(name, (iconUrl != null) ? new ImageIcon(
  				Objects.requireNonNull(BasicGraphEditor.class.getResource(iconUrl))) : null)
  		{
  			public void actionPerformed(ActionEvent e)
  			{
  				action.actionPerformed(new ActionEvent(getGraphComponent(), e
  						.getID(), e.getActionCommand()));
  			}
  		};
  
  		newAction.putValue(Action.SHORT_DESCRIPTION, action.getValue(Action.SHORT_DESCRIPTION));
  
  		return newAction;
  	}
  
  	/**
  	 *
  	 */
  	public void status(String msg)
  	{
  		statusBar.setText(msg);
  	}
  
  	/**
  	 * 
  	 */
  	public void updateTitle()
  	{
  		JFrame frame = (JFrame) SwingUtilities.windowForComponent(this);
  
  		if (frame != null)
  		{
  			String title = (currentFile != null) ? currentFile
  					.getAbsolutePath() : "new Automaton";//mxResources.get("newDiagram");
  
  					if (modified)
  					{
  						title += "*";
  					}
  
  					frame.setTitle(title + " - " + appTitle);
  		}
  	}
  
  	/**
  	 * 
  	 */
  	public void about()
  	{
  		JFrame frame = (JFrame) SwingUtilities.windowForComponent(this);
  
  		if (frame != null)
  		{
  			EditorAboutFrame about = new EditorAboutFrame(frame);
  			about.setModal(true);
  
  			// Centers inside the application frame
  			int x = frame.getX() + (frame.getWidth() - about.getWidth()) / 2;
  			int y = frame.getY() + (frame.getHeight() - about.getHeight()) / 2;
  			about.setLocation(x, y);
  
  			// Shows the modal dialog and waits
  			about.setVisible(true);
  		}
  	}
  
  	/**
  	 * 
  	 */
  	public void exit()
  	{
  		JFrame frame = (JFrame) SwingUtilities.windowForComponent(this);
  
  		if (frame != null)
  		{
  			frame.dispose();
  		}
  	}
  
  	/**
  	 * 
  	 */
  	public void setLookAndFeel(String clazz)
  	{
  		JFrame frame = (JFrame) SwingUtilities.windowForComponent(this);
  
  		if (frame != null)
  		{
  			try
  			{
  				UIManager.setLookAndFeel(clazz);
  				SwingUtilities.updateComponentTreeUI(frame);
  
  				// Needs to assign the key bindings again
  				keyboardHandler = new EditorKeyboardHandler(graphComponent);
  			}
  			catch (Exception e1)
  			{
  				e1.printStackTrace();
  			}
  		}
  	}
  
  	/**
  	 * 
  	 */
  	public JFrame createFrame(JMenuBar menuBar)
  	{
  		JFrame frame = new JFrame();
  		frame.getContentPane().add(this);
  		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  		frame.setJMenuBar(menuBar);
  		frame.setSize(870, 640);
  
  		// Updates the frame title
  		updateTitle();
  
  		return frame;
  	}
  
  	/**
  	 * Creates an action that executes the specified layout.
  	 * 
  	 * @param key Key to be used for getting the label from mxResources and also
  	 * to create the layout instance for the commercial graph editor example.
  	 * @return an action that executes the specified layout
  	 */
  	@SuppressWarnings("serial")
  	public Action graphLayout(final String key, boolean animate)
  	{
  		final mxIGraphLayout layout = createLayout(key);
  
  		if (layout != null)
  		{
  			return new AbstractAction(mxResources.get(key))
  			{
  				public void actionPerformed(ActionEvent e)
  				{
  					final mxGraph graph = graphComponent.getGraph();
  					Object cell = graph.getSelectionCell();
  
  					if (cell == null
  							|| graph.getModel().getChildCount(cell) == 0)
  					{
  						cell = graph.getDefaultParent();
  					}
  
  					graph.getModel().beginUpdate();
  					try
  					{
  						long t0 = System.currentTimeMillis();
  						layout.execute(cell);
  						status("Layout: " + (System.currentTimeMillis() - t0)
  								+ " ms");
  					}
  					finally
  					{
  						mxMorphing morph = new mxMorphing(graphComponent, 20,
  								1.2, 20);
  
  						morph.addListener(mxEvent.DONE, (sender, evt) -> graph.getModel().endUpdate());
  
  						morph.startAnimation();
  					}
  
  				}
  
  			};
  		}
  		else
  		{
  			return new AbstractAction(mxResources.get(key))
  			{
  
  				public void actionPerformed(ActionEvent e)
  				{
  					JOptionPane.showMessageDialog(graphComponent,
  							mxResources.get("noLayout"));
  				}
  
  			};
  		}
  	}
  
  	/**
  	 * Creates a layout instance for the given identifier.
  	 */
  	protected mxIGraphLayout createLayout(String ident)
  	{
  		mxIGraphLayout layout = null;
  
  		if (ident != null)
  		{
  			mxGraph graph = graphComponent.getGraph();
  
  			switch (ident) {
  				case "verticalHierarchical":
  					layout = new mxHierarchicalLayout(graph);
  					break;
  				case "horizontalHierarchical":
  					layout = new mxHierarchicalLayout(graph, JLabel.WEST);
  					break;
  				case "verticalTree":
  					layout = new mxCompactTreeLayout(graph, false);
  					break;
  				case "horizontalTree":
  					layout = new mxCompactTreeLayout(graph, true);
  					break;
  				case "parallelEdges":
  					layout = new mxParallelEdgeLayout(graph);
  					break;
  				case "placeEdgeLabels":
  					layout = new mxEdgeLabelLayout(graph);
  					break;
  				case "organicLayout":
  					layout = new mxOrganicLayout(graph);
  					break;
  			}
  			switch (ident) {
  				case "verticalPartition":
  					layout = new mxPartitionLayout(graph, false) {
  						/**
  						 * Overrides the empty implementation to return the size of the
  						 * graph control.
  						 */
  						public mxRectangle getContainerSize() {
  							return graphComponent.getLayoutAreaSize();
  						}
  					};
  					break;
  				case "horizontalPartition":
  					layout = new mxPartitionLayout(graph, true) {
  						/**
  						 * Overrides the empty implementation to return the size of the
  						 * graph control.
  						 */
  						public mxRectangle getContainerSize() {
  							return graphComponent.getLayoutAreaSize();
  						}
  					};
  					break;
  				case "verticalStack":
  					layout = new mxStackLayout(graph, false) {
  						/**
  						 * Overrides the empty implementation to return the size of the
  						 * graph control.
  						 */
  						public mxRectangle getContainerSize() {
  							return graphComponent.getLayoutAreaSize();
  						}
  					};
  					break;
  				case "horizontalStack":
  					layout = new mxStackLayout(graph, true) {
  						/**
  						 * Overrides the empty implementation to return the size of the
  						 * graph control.
  						 */
  						public mxRectangle getContainerSize() {
  							return graphComponent.getLayoutAreaSize();
  						}
  					};
  					break;
  				case "circleLayout":
  					layout = new mxCircleLayout(graph);
  					break;
  			}
  		}
  
  		return layout;
  	}
  
  }
  