netbeans.org : NetBeans Visual Library 2.0 - Documentation
Author: david.kaspar@sun.com

# Visual Library 2.0 - Documentation

## Index

- Index
- Installation
- Introduction
  - Example: First Scene
- Widget
  - Widget Methods
  - LabelWidget
  - ImageWidget
  - Widget Dependency
  - Example: Icon Node Widget
- Border
- Scene
  - Scene Methods
  - SceneListener
- Coordination System
- Layout
  - AbsoluteLayout
  - FlowLayout
  - CardLayout
  - OverlayLayout
- Validation Process
  - Revalidation
  - Scene Validation
  - Repainting
  - SceneLayout
- WidgetAction
  - Assignment
  - Action Tools
  - AWT Event Processing
  - Event Processing Types
  - Action State
  - ActionMapAction
  - AcceptAction
  - AddRemoveControlPointAction
  - AlignWithMoveAction
  - AlignWithResizeAction
  - CycleFocusAction
  - ConnectAction
  - EditAction
  - HoverAction
    - HoverAction vs. ObjectSceneHoverAction
  - InplaceEditorAction
  - MoveAction
  - MoveControlPointAction
  - PanAction
  - PopupMenuAction
  - RectangularSelectAction
  - ReconnectAction
  - ResizeAction
  - SelectAction
  - ZoomAction
  - Example: Using Actions
  - Order of Actions
  - Action Creation
  - Strategies
- ConnectionWidget
  - Router
  - ConnectionWidgetLayout
  - Routing Policy
  - ConnectionWidget Methods
- Anchor
  - FixedAnchor
  - CenterAnchor
  - RectangularAnchor
  - CircularAnchor
  - DirectionalAnchor
  - ProxyAnchor
  - Anchor Dependency
  - Example: ConnectionWidget with Anchors
  - Loop Edge
  - Parallel Edges
- LayerWidget
  - Example: Layers
- ObjectScene
  - ObjectState
  - ObjectScene Methods
  - ObjectSceneListener
  - Object Identity Code
- Graph Support
  - Graph UI Binding
  - Example: GraphScene UI
  - GraphScene Methods
  - GraphPinScene Methods
  - Universal Graph
  - Graph-oriented Layout
  - GraphLayoutListener
  - TreeGraphLayout
  - GridGraphLayout
- ComponentWidget
- Scrollable Widget
- In-place Editor
  - Example: In-place Editor
- Level of Details
- Look and Feel
- Animator
  - SceneAnimator Methods
  - Example: Animator
- Custom Development
  - Custom Widget
  - Example: Circle Widget
  - Custom Action
  - Custom Layout
  - Custom Border
  - Custom Anchor
  - Custom Animator
  - Custom Router
  - Custom Graph-oriented Layout
- General Widgets
  - IconNodeWidget
  - ListWidget
- VMD plug-in
  - Minimize Ability
- Printing and Exporting Scene
  - Export to PNG
  - Exporting without Offscreen Buffer
- Effects
  - Convolution
  - Antialiasing
- Serialization
  - Example: Nodes Location Serialization
- Visual Library vs. Swing
- Notes

## Abstract

This is a documentation for the Visual Library 2.0 API. The library is a successor of the Graph Library 1.0. Its provides general-purpose (not graph-oriented only) visualization.

WWW: http://graph.netbeans.org
CVS: :pserver:anoncvs@cvs.netbeans.org:/cvs checkout graph
Issues: NetBeans Issuezilla - graph component

## Installation

To install the library, just set a dependency on org.netbeans.api.visual module. The source code of Visual Library API is located at graph/lib directory in the NetBeans CVS repository.

## Introduction

The programming style is similar to Swing. You are building and modifying a tree of visual elements that are called `Widget`s. The root of the tree is represented by a `Scene` class which holds all visual data of the scene. Since neither Widget nor Scene is an AWT/Swing component you have to call `Scene.createView` method for creating a Swing component which renders the scene. The created JComponent could be used anywhere.

### Example: First Scene

Following code creates an empty scene, creates a JComponent view of the scene and embeds it into a dialog with scrollable view.

    Scene scene = new Scene ();
    JComponent sceneView = scene.createView ();
    JScrollPane panel = new JScrollPane (sceneView);

    JDialog dia = new JDialog (new JDialog (), true);
    dia.add (panel, BorderLayout.CENTER);
    dia.setSize (800, 600);
    dia.setVisible (true);
    dia.dispose ();

## Widget

Widget is a primitive visual element - similar to what JComponent is for Swing. It holds information about its location, boundary, preferred location/boundary, preferred/minimal/maximal sizes, layout, border, foreground, background, font, cursor, tooltip , accessible context, ...

Widget placement is defined by:

- its location point that is specified relatively to its parent widget location and
- its boundary rectangle that is specified relatively to the widget location.

Note that the boundary is specified as a rectangle (and not as Swing-like Dimension). This allows to have baseline ability by the definition.

A widget placement is resolved by a layout associated to its parent widget. The placement is usually based on a preferred location and boundary. The preferred boundary can be set or calculated from the widget needs. Then it can be processed by preferred/minimum/maximum size. See Layout section for details.

### Widget Methods

Method | Description
--- | ---
getScene | Returns a scene where the widget belongs. The scene instance is assigned in the constructor and could not be changed anymore.
getParentWidget getChildren addChild removeChild removeFromParent addChildren removeChildren bringToFront bringToBack | Methods for manipulation with the tree hierarchy of widgets.
getChildConstraint setChildConstraint | Controls constraints assigned to child widgets. Used by Layouts similarly to Swing. See Layout section.
isEnabled setEnabled | Controls whether events are processed by actions assigned to the widget or any of its children. If the widget is disabled, then events are not processed by children widgets too.
getActions() | Returns a default actions chain. See WidgetAction section.
getActions(String tool) createActions(String tool) | Returns (and optionally creates) a actions chain for an appropriate tool. See Action Tools section.
getLookup | Returns lookup. Not used right now - it will be used later for extending the Widget functionality when the API is stable and incompatible API changes are forbidden.
addDependency removeDependency getDependencies | Allows to assigned a `Widget.Dependency` listener to the widget for notifying about widget location or boundary changes. Widely used by Anchors. See: Widget Dependency section.
isVisible setVisible | Controls visibility of the widget. If not visible, then the widget is not painted and do not process events. `True` by default.
isOpaque setOpaque | Controls opacity of the widget. If opaque, then background is not painted. `False` by default.
getBackground setBackground getForeground setForeground | Controls the background paint and foreground color. Solid white background and black foreground by default.
getFont setFont | Controls the font. By default or if set to `null`, then `getFont` returns value of `Scene.getDefaultFont` method.
getBorder setBorder | Controls the widget border. `EmptyBorder` by default. See Border section.
getCursor setCursor | Controls the widget cursor. `null` by default.
getLayout setLayout | Controls the widget layout. The layout defines placement of children. `AbsoluteLayout` by default. See Layout section.
getMinimumSize setMinimumSize getMaximumSize setMaximumSize getPreferredSize setPreferredSize | Controls minimum, maximum and preferred size. `Null` (means not set) by default. See Layout section.
getPreferredLocation setPreferredLocation | Controls preferred location. Widely used when parent widget has `AbsoluteLayout`, then the preferred location is used as the evaluated location. See Layout section. `Null` (means not set) by default.
getPreferredBounds setPreferredBounds isPreferredBoundsSet | Controls preferred boundaries. Not set by default not set. `getPreferredBounds` method always returns non-null boundaries - if the preferred bounds are not set, then it automatically calculate the boundaries from boundaries of its children, assigned layout and internal boundaries. The returned boundaries are checked for minimum, maximum and preferred sizes. See Layout section.
isCheckClipping setCheckClipping | Defines whether the clipping should be used for widget painting. `False` by default.
getToolTipText setToolTipText | Controls the tool tip text.
getState setState | Defines the widget state. `State.createNormal` by default. See Object State section.
convertLocalToScene convertSceneToLocal | Converts local coordination system to scene coordination system and vice versa. See Coordination System section.
getLocation | Returns evaluated widget location specified relatively to the parent widget coordination system. `[0,0]` by default. See Layout and Coordination System section.
getBounds | Returns evaluated widget boundaries specified relatively to the widget (local) coordination system. `Null` by default. See Layout and Coordination System section.
resolveBounds (Point location, Rectangle bounds) | Sets evaluated widget location and boundary. If location is `null`, then `[0,0]` is automatically used instead. If bounds are `null`, then return from `getPreferredBounds` is automatically used instead. This method should be called from implementation of `Layout.layout` method only. See Layout and Coordination System section.
getClientArea | Returns boundary from `getBounds` without (means: decreased by) insets of a border assigned to the widget.
isHitAt | Returns whether the widget is "hit" at specified location in local coordination system. The "hit" usually means that there is a pixel at the location controlled/painted by the widget. Widely used for mouse event processing. E.g. A circle-shape widget has rectangular boundary but it is hit on at points that are located inside the circle area.
repaint | Schedules the widget for painting. Usually called from setters method of the Widget. Usually the developer should call setter methods and the setter methods should call `repaint` or `revalidate` (depends whether they affect widget location/boundary). See Validation Process section.
isValidated | Returns whether the widget is validated. See Validation Process section.
revalidate() | Schedules the widget for validation. Usually called from setter methods of the Widget. Usually the developer should call setter methods and the setter methods should call `repaint` or `revalidate` (depends whether they affect widget location/boundary). See Validation Process section.
revalidate(boolean repaintOnly) | Calls `repaint` or `revalidate` method based on `repaintOnly` parameter.
paint | Paints the widget using the `Graphics2D` instance acquired by `getGraphics` method. Usually you should not call this method directly. It is called automatically by the library. For repainting the widget, use `repaint` method instead.
protected getGraphics | Returns `Graphics2D` instance that could be used for painting and calculating internal boundary. It is non-null only when the scene has a JComponent view created and it is added into AWT components hierarchy (means: after JComponent.addNotify method call). See Custom Widget section.
protected calculateClientArea | Returns calculated client area required by the widget itself without children. E.g. LabelWidget has the client area equal to the boundary of its label. Do not include children location and boundary - they are included automatically later. See Custom Widget section.
protected paintBackground | Paints the widget background only. Do not invoke painting of children in this method. See Custom Widget section.
protected paintBorder | Paints the widget border only. Do not invoke painting of children in this method. See Custom Widget section.
protected paintWidget | Paints the widget only. Do not invoke painting of children in this method. See Custom Widget section.
protected paintChildren | Paints the widget children. Default implementation of `Widget.paintChildren` method should to be called to for invoke painting of the children. You can also selectively call `paint` method on each child. Usually this is used for introducing painting effects on children. E.g. smooth alpha blending in `LevelOfDetailsWidget` or applying convolution in `ConvolveWidget`. See Custom Widget section.
protected notifyStateChanged | Called by `setState` method when the state is changed. This method should control the widget appearance based on the widget-specific state. E.g. change the background color based on the result of `ObjectState.isSelected` method. See ObjectState and Custom Widget sections.
protected isRepaintRequiredForRevalidating | Returns whether the repaint of the whole widget (specified by the widget boundaries) has to be repainted during validation. Used for speed optimalization. By default return `true` for everything except Scene and LayerWidget. See Custom Widget section.
protected notifyAdded protected notifyRemoved | Called to notify that a widget is being show or hidden in the view. Within these methods, do not modify the tree hierarchy of scene.
protected getCursorAt(Point localLocation) | Called to get a cursor of a specified local location of the widget.

### LabelWidget

The `LabelWidget` represents a single line text. You can manipulate with the text using `getLabel` and `setLabel` methods or using a constructor parameter. The widget is not-opaque by default and uses foreground, background and font properties for rendering. The text could be aligned to the left (by default), right or center within the widget. The widget origin is a point on the left side of the baseline of the text.

Since version 2.1 the LabelWidget allows rendering vertical labels. It can be set by calling `LabelWidget.setOrientation` method. Default value is `LabelWidget.Orientation.NORMAL` which renders labels horizontally. The other value is `LabelWidget.Orientation.ROTATE_90` which makes the label to render vertically.

Since version 2.7 the LabelWidget allows to use glyph-vector for rendering. This allows accurate text rendering independently on a scene zoom-factor (no more clipped text while zooming onto a scene).

### ImageWidget

The `ImageWidget` represents an image. You can manipulate with the image using `getImage` and `setImage` methods or using a constructor parameter. The widget is not-opaque by default. The widget origin is top-left corner of the image.

The `ImageWidget` supports animated images. For proper work, do not load images using `Utilities.loadImage` because the method is producing static images. Instead use standard `Toolkit.createImage` method for loading.

### Widget Dependency

Sometimes you want to listen on a widget move or resize changes. The listener is defined by `Widget.Dependency` interface. Listener could be (un)registered using `Widget.addDependency` and `Widget.removeDependency` methods.

Note 1: The `Widget.Dependency.revalidateDependency` method is not called directly from `Widget.resolveBounds` method. Instead it is called indirectly during widget or scene revalidation process (means from `Widget.revalidate` and `Scene.validate` method). See Validation Process and Layout sections for details.

Note 2: `Widget.Dependency.revalidateDependency` method is called to notify all dependent objects that the widget is scheduled for revalidation and therefore all dependent objects should schedule their revalidation using `dependentWidget.revalidate` method call too.
E.g.: An anchor depends on a widget where it is assigned. When `Widget.Dependency.revalidateDependency` is called, then the anchor clears its caches and invokes `Widget.revalidate` method on all `ConnectionWidget`s (resp. `Anchor.Entry`).
Therefore no bounds of any widget is valid at the time of the method call. The valid bounds can be obtained only in `Layout` interface:

- At the time when `Layout.layout` method is called, initial bounds of all child widgets of the widget (where the layout is assigned) are resolved.
- At the time when `Layout.justify` method is called, bounds of all parent widgets of the widget (where the layout is assigned) are resolved.
- At the end of validation process, scene bounds are finally calculated.

If you want to listen on scene boundary changes, the easiest way is to add scene-listener using `Scene.addSceneListener` method and put your code into `SceneListener.sceneValidated` method implementation.

### Example: Icon Node Widget

Following code creates the iconNode instance that has an image with a label.

    // create a scene
    Scene scene = new Scene ();
    // create the icon node widget
    Widget iconNode = new Widget (scene);
    // use a vertical layout
    iconNode.setLayout (LayoutFactory.createVerticalFlowLayout (LayoutFactory.SerialAlignment.CENTER, 4));
    // add a image child widget
    iconNode.addChild (new ImageWidget (scene, Utilities.loadImage ("path/to/my/image.png")));
    // add a label child widget
    iconNode.addChild (new LabelWidget (scene, "My Label"));
    // add it to the scene
    scene.addChild (iconNode);

## Border

Each widget have a border. By default it has EmptyBorder. The border could be set using `Widget.setBorder` method. The border is always painted after the clearing the widget background and before the `Widget.paintWidget` and `Widget.paintChildren` methods. Therefore the border could be used for painting complex widget backgrounds. The border can be usually created using `BorderFactory.create*Border` methods. Single instance of border class could be shared and assigned to more widgets. There are following borders available:

- EmptyBorder - renders an empty border.
- LineBorder - renders a border with 1px wide stroke.
- BevelBorder - renders a bevel border.
- ImageBorder - renders a border using border-image.
- RoundedBorder - renders a rounded-rectangle border.
- ResizeBorder - renders a border with 8 dragging-points - usually used for 8-direction object resizing.
- DashedBorder - renders a border with dashed stroke optionally with 8 dragging-points.
- SwingBorder - renders a border using Border class from Swing.
- CompositeBorder - renders a border that is composed with specified borders.

## Scene

This widget represents a root node of the tree hierarchy of widgets. It controls the whole scene, its views, repainting and tree validation. It is extended by `ObjectScene`, `GraphScene`, `GraphPinScene` class which adds additional functionally for object-oriented and graph-oriented modeling. `Scene` class is derived from `Widget` class and contains additional methods.

### Scene Methods

Method | Description
--- | ---
createView | Creates a single `JComponent`-based view of the scene. Could be called once only. The `JComponent` could be used anywhere in AWT/Swing. Scene and widgets starts to be validated/painted only when the view is created and added to the AWT/Swing components hierarchy (`JComponent.addNotify` is called).
getView | Returns the `JComponent` instance created by `createView`.
createSatelliteView | Creates a satellite view of the scene. It is showing an overview of the scene. In case the JComponent view is placed in a JScrollPane and the scene does not fit into the panel, then the satellite view paints an viewport rectangle which representing visible area. It also allows user to move with the actual viewport of the scene.
createBirdView | Creates a bird view of the scene. It is enough to create one bird view and reuse it all the time. The bird view is tracking mouse cursor and when the cursor is over visible area of the scene view, then an additional always-on-top window is shown and shows pointed part of the scene with specified zoom factor. The method returns `BirdViewController` which allows control over the bird view. When the bird view is enabled, then it consumes all events of the scene view.
getGraphics | Returns an instance of `Graphics2D` used by whole scene. The instance is the one that was available during the last JComponent.addNotify or JComponent.paint method call on the JComponent view.
paint(Graphics2D) | Paints the scene using `Graphics2D` instance. This method could be invoked in AWT-thread only.
isValidated | Returns `true` if it is validated as using `Widget.isValidated` and there is no region or widget scheduled for repainting. See Layout section.
validate | This method validates whole scene with all widgets. Usually it is called automatically e.g. at the end of event processing. See Validation Process section.
validate(Graphics2D) | This method validates whole scene with all widgets using specified Graphics2D. This is used for off-screen rendering when you do not have a main scene view created yet. Be aware that the scene is going to remain validated with specified font metrics after the method call. This may break scene layout when your main scene view is finally created and shown. See Validation Process section.
getMaximumBounds setMaximumBounds | Controls the maximum bounds of the scene. By default it is `[-Integer.MAX_VALUE/2,-Integer.MAX_VALUE/2,Integer.MAX_VALUE,Integer.MAX_VALUE]`. This is used to limit the scene bounds e.g. to positive values only.
getZoomFactor setZoomFactor | Controls the zoom factor of the scene.
getSceneAnimator | Returns a scene animator that controls animations on the scene. See Animator section.
getLookFeel setLookFeel | Controls the scene look and feel. `LookFeel.createDefaultLookFeel` by default. See Look and Feel section.
getInputBindinds | Returns input bindings used by the scene. See Look and Feel section.
getActiveTool setActiveTool | Controls the active action tool of the scene. See Action Tools section.
getKeyEventProcessingType setKeyEventProcessingType | Controls the processing type used for key events. See Event Processing Types section.
getPriorActions | Returns a chain of prior actions. These actions are executed because any other action of the scene. See AWT Event Processing section.
getFocusedWidget setFocusedWidget | Controls a focused widget of the scene. Only one widget could be focused at the same time. The focused widget could be used for key event processing. See Event Processing Types section.
addSceneListener removeSceneListener | (Un)registers scene listener for notification about scene validation and repaint. See SceneListener section.
convertSceneToView convertViewToScene | Converts location and boundary between scene coordination system and JComponent view coordination system. See Coordination System section.
createWidgetHoverAction | Creates a widget-specific hover action. See HoverAction section.

### SceneListener

This listener allows you to receive following events:

Method | Description
--- | ---
sceneRepaint | Called when scene should be repainted.
sceneValidating | Called at the beginning of `Scene.validate` method when the scene is going to be validated. See Validation Process section.
sceneValidated | Called at the end of `Scene.validate` method when the scene is validated. See Validation Process section.

This listener could be (un)registered using `Scene.addSceneListener` and `Scene.removeSceneListener` methods. Usually it is used by animators, scene layouts, Swing bindings and satellite views.

## Coordination System

There are 3 coordination systems used in the library:

- view - the system that is used by a JComponent view and has [0,0] point at the top-left corner of the JComponent.
- scene - the system that is used by a scene. Scene can expand to negative coordinates too.
- local - the system that is used by a widget and has [0,0] point at the widget location. The widget location is specified to the location of its parent widget. The widget boundary are specified/used relatively to the widget location.

Converting from local to scene coordination system:

    Point Widget.convertLocalToScene (Widget widget, Point localSystemPoint) {
        Point sceneSystemPoint = new Point (localSystemPoint);
        while (widget != null  &&  widget != widget.getScene ()) {
            sceneSystemPoint += widget.getLocation ();
            widget = widget.getParentWidget ();
        }
        return sceneSystemPoint;
    }

Converting from scene to view coordination system:

    Point Scene.convertSceneToView (Scene scene, Point sceneSystemPoint) {
        return new Point ((scene.getLocation () + sceneSystemPoint) * scene.getZoomFactor ());
    }

## Layout

Each widget has a layout assigned (`AbsoluteLayout` by default). `Layout` interface cares about placement of children widgets of the widget where the layout is assigned. For details how layout is involved in the validation process, see Validation Process section. Almost all layouts implementations can be reused by more widgets at the same time.

Widget also keeps constraints assigned to children widgets. Layout can obtain a constraint using `Widget.getChildConstraint (childWidget)` method call.

Widget could be invisible too. In that case, the layout assigned to its parent widget must act like the invisible widget is not there. It means it must resolve location and bounds to value which does not affect the parent widget boundary. If it is not possible, then the location and the boundary of invisible child must be resolved as [0,0] and [0,0,0,0].

### AbsoluteLayout

Created by: `LayoutFactory.createAbsoluteLayout`

Placement algorithm:

- For each child widget of the widget:
- It takes value of `childWidget.getPreferredLocation` and uses it as the evaluated childWidget location. If `null`, then it uses `[0,0]` point instead.
- It takes value of `childWidget.getPreferredBounds` and uses it as the evaluated childWidget boundary. If `null`, then it uses `[0,0,0,0]` rectangle instead.

### FlowLayout

Created by: `LayoutFactory.createVerticalFlowLayout`, `LayoutFactory.createHorizontalFlowLayout`

This layout places children serially in vertical or horizontal line - one widget after another. It allows top-left, center, bottom-right and justify alignments and specifying gaps between children. It used `childWidget.getPreferredBounds` for resolving boundary. The layout will use the widest/highest boundaries for a cell dimension.

The layout allows to work with Number-class constraints. The Number constraint has to be a positive number assigned to a child widget. Then it represents a ratio in with the remaining space (height for VerticalFlowLayout and width for HorizontalFlowLayout) is split and assigned to a particular widget. See `test.layout.WeightFlowLayoutTest` for example.

### CardLayout

Created by: `LayoutFactory.createCardLayout`

This layout has a single childWidget as active one. The active widget will be evaluated using `activeChildWidget.getPreferredLocation` (if `null`, then `[0,0]` point is used instead) and `activeChildWidget.getPreferredBounds`. The other children are evaluated with `[0,0,0,0]` rectangle as boundary and placed at the top-left corner of `activeChildWidget`.

For switching active child widget, use `LayoutFactory.setActiveCard (widget, newActiveChildWidget)` method.

### OverlayLayout

Created by: `LayoutFactory.createOverlayLayout`

It finds the "minimal-encapsulation" (ME) boundary which contains all the children boundaries. Then it sets boundary of each child as the calculated ME one. The widget boundary is set to ME boundary too. During justification, the boundary of each child is sets to the boundary of the widget. Children are placed one over another - the last child is painted on top and receives events as the first child.

## Validation Process

When any widget is added/removed in the tree hierarchy of a scene or a widget is changed the way that affects its placement or boundary, then the widget (and the scene too) has to be validated again.

The process is done in following steps:

1. Developer modifies a widget by directly (or indirectly) calling `Widget.revalidate` method. The method automatically schedules the widget for revalidation.
2. After all modifications, scene validation is invoked by calling `Scene.validate` method. Usually it is invoked automatically at the end of Swing event processing.
3. Validation process searches for invalid widgets.
4. All widget dependencies are notified about revalidation using `Widget.Dependency` interface.
5. Each modified widget evaluates its location and boundary using its layout.
6. Justification is invoked on each widget that need to justify its boundary using its layout.
7. If any new modification were introduced during the validation process, then the validation process is repeated again.

The process is described in details in next sub-sections.

### Revalidation

Each Widget has two flags: `requiresFullValidation` (marks modified widget) and `requiresPartValidation` (used for back-tracing the tree from the root/scene widget down to all modified widgets). When a widget is asked to be scheduled for revalidation using `Widget.revalidate` method, then the widget is marked with requiresFullValidation and requiresPartValidation. All widgets upto the scene are marked as a requiresPartValidation. Now the scene can trace-down all modified widgets without storing their references. Each widget with requiresPartValidation flag also fires an event on its Widget.Dependency listeners because they could be affected by a change of some child widget.

### Scene Validation

When `Scene.validate` method is invoked, then it repeatedly validates scene until there is no modification - means `Scene.isValidated` returns `true`.

The validation process deep dives into the tree hierarchy and evaluates location and boundary using assigned layout of widgets that have requiresPartValidation set to true. Then it fires an event on all Widget.Dependency listeners for all children (recursively) of the widget with requiredFullValidation set to true.

Now all widgets are evaluated for new data. Because of used layout algorithms, it resolves boundary as the minimal "packed" boundary of the widget and its children - because each widget calculates its boundaries from its children boundary too.

In some cases you would like to extend boundary of some widgets e.g. when a widget with FlowLayout (with "justify" alignment) is a child of another widget with FlowLayout (with "justify" alignment). This can be done in this moment since all widgets are evaluated for minimal boundary and they can just expand. Therefore the validation process is deep-diving into the tree hierarchy (the depth is controlled by result of `Layout.requiresJustification` method of each widget. For each widget (from the root to the bottom) it reevaluates the boundary again and calculates children boundaries based on the widget boundary.

This 2-pass validation process allows to have similar layout support as Swing has.

### Repainting

When a widget is scheduled for repaint, then its current (before reevaluation) boundary in the view coordination system is scheduled for repaint and the widget itself is added into the list of widgets scheduled for repaint.

After the scene is validated completely, then all widgets in repaint-list are scheduled for repaint too. It takes their current (newly evaluated) view coordination system boundaries.

### SceneLayout

Layout (assigned to a widget) defines placement of its children widgets. But in some cases you would like to do a single-time layout based on different layout algorithm (it could be even high-level layout of graph-oriented data).

The possible solution could be to temporarily assign the desired layout to the widget and to start revalidation. The problem is that you cannot temporarily assign widget because you cannot assure when the layout and scene-validation will be invoked. Also you would not be able to invoke "initial" layout of a scene when the Scene is going to appear for the first time on the screen. It is because the JComponent is not initialized yet and therefore the scene is not validated yet and therefore widget boundaries (which are usually required by the layout algorithms) are not resolved yet too.

Therefore `SceneLayout` class has been introduced. When the SceneLayout is invoked by the developer, it starts listening on the scene to be validated (using `SceneListener`). When the `SceneListener.sceneValidated` method is called then the listener is removed and `SceneLayout.performLayout` method is invoked.

There is a `LayoutFactory.createDevolveWidgetLayout` method that creates a SceneLayout with `performLayout` method implementation which temporarily sets the desired layout and invokes the specified layout at the end of scene validation process. This allows you use a `LayerWidget` with default AbsoluteLayout, so the widgets inside will be able to freely move using `MoveAction` and from time to time (e.g. started by user action) the layer widget will be layout using the specified temporary layout to organize the layer.

## WidgetAction

The widgets are visual elements that just know where they are on the scene and how to draw themself. By default they do not know how to behave. For defining the behavior there are `WidgetAction`.

You can create various actions usually using `ActionFactory.create*Action` methods. For example: `ActionFactory.createMoveAction` method creates an action which allows user to move a widget (where the action is assigned to).

Factory methods usually requires some parameters. There are two kinds of parameters: Decorators and Providers. Decorator is used for specifying the visual appearance of objects temporarily created by an action. E.g. RectangularSelectAction has `RectangularSelectDecorator` for acquiring the widget that will represent actual selection rectangle. Provider is used for specifying the custom behavior of an action. E.g. EditAction has `EditProvider` with `edit` method which is called when an user double-clicks on a widget where the action assigned to. It is upto the `EditProvider` implementation whether it invokes an editor or run an application or does something totally different. Usually there are default implementations of the decorators and providers available in `ActionFactory` class.

Usually single instance of a particular action could be reused and assigned to more Widgets at the same time.

### Assignment

Actions could be grouped into chains. The chain is an action that distributes the user-events to appropriate actions that are stored inside. Each Widget has its own chain that can be acquired by calling `Widget.getActions` method. Chain allows to manage and query the list of its actions using `addAction`, `removeAction`, `getActions` methods.

### Action Tools

Sometimes you would like to have a scene which will behave differently based on a `scene state`. E.g. you have a toolbar with modes: "Select" (when active then user can only select object), "Connect" (when active then user can only create connection between objects), "Move" (when active then user can only move objects in a scene), ...

For this purpose there are action tools. A scene has a single active action tool specified. It is `null` by default and could be changed by `Scene.setActiveTool` method. The active tool specified as a `String` used for the tool identification. Each widget has `Widget.createActions (String tool)` method for creating an action chain for the specified tool. When a chain is created for particular tool, then you can use `Widget.getActions (String tool)` for faster access to the chain.

### AWT Event Processing

Each mouse/keyboard/drag'n'drop/focus event that comes from the AWT has to be processed. The processing it done by walking through the tree hierarchy of widgets. For mouse events, the widget boundaries and `Widget.isHitAt` methods are used for checking before dispatching the event. The AWT-event is converted into the library-specific event (which is very similar to AWT event. The library-specific event has `event.getPoint` method which location in local coordination system of the widget where an appropriate action is attached to. For each valid widget, all default actions (from `Widget.getActions ()`) are processed. The processing continues until an event is consumed by an action.

The walk through process for a widget is done by:

1. Take the widget (start it with Scene first) and check its boundary.
2. If the event is a mouse-event and mouse-cursor is NOT inside boundary, then return back.
3. Process the event for each its child widget (start from the last child to the first child) for the widget.
4. If the event is consumed by any of the children then stop processing the event and return back.
5. Check if `Widget.isHitAt (mouseCursor)` method returns true. If so, then process the event with default action chain of the widget and then optionally with an action chain appropriate for the tool returned by `Scene.getActiveTool` method.
6. If event is consumed then stop processing the event.
7. Return back.

There is the `Scene.getPriorActions` code which returns an actions chain. All actions in this prior chain are processing an AWT event before any other actions used in the scene. If any of these prior actions consumes the event, the event processing is stopped. A prior action cannot lock even processing for itself. For example: see `test.tool.CtrlKeySwitchToolTest` example which is switching active tool of a scene based on a state of Ctrl key.

The `Widget.isEnabled` controls whether events can be processed by actions assigned to the widget or its children. The same behavior implemented for all types of events.

It is important to have correct order of actions assigned to a widget because some actions requires locking. Usually the "locking" actions are the one that requires mouse-dragging e.g. MoveAction, ResizeAction, ConnectAction, ... Usually it is enough to put HoverAction and SelectAction as the first two actions and others.

Actions usually require various parameters including for their creation e.g. `LayerWidget`. See LayerWidget section for details.

### Action State

The action is processing library-specific events and returns the event status at the end. Based on the status the library decides whether the event is consumed, locked, ... There are following statuses:

- `WidgetAction.State.REJECTED` - The event is not processed by the action. Event-processing has to continue.
- `WidgetAction.State.CONSUMED` - The event is processed and consumed by the action. Event-processing is stopped.
- `WidgetAction.State.CHAIN_ONLY` - The event is processed and consumed by the action. The rest of actions in the same action chain should be invoked too and then the event-processing is stopped.
- `WidgetAction.State.createLocked (Widget, WidgetAction)` - The event is processed and consumed by the action. The next AWT event has to be processed by the specified `WidgetAction` and it has to take the specified `Widget` as a parameter. Only when the next AWT event is not consumed by the specified action, then the whole-tree event-processing (described in AWT Event Processing section) is invoked. This is used for locking event-processing by a specific action during processing multiple-events user-actions like moving (MoveAction), starting new connection (ConnectAction), ...

### Event Processing Types

All Swing events are processed by all widgets by default. Key-events has to processed differently because they do not contain a "location" information. Therefore all widgets would have to process those events.

Key events are usually not desired to be processed by all widgets. Therefore you can specify a type of event processing using `Scene.setKeyEventProcessingType` method. There are following types specified by `EventProcessingType` enum:

- `ALL_WIDGETS` - by default - Has the same behavior as the other events processing described previously.
- `FOCUSED_WIDGET_AND_ITS_PARENTS` - Based on the focused widget where a key event is processed by a focused widget and then its parents up to the root of the widget hierarchy. The scene has always a focused widget (if not specified or set to `null`, then the scene itself is taken as focused).
- `FOCUSED_WIDGET_AND_ITS_CHILDREN` - Based on the focused widget where a key event is processed by a focused widget and then by all its children.
- `FOCUSED_WIDGET_AND_ITS_CHILDREN_AND_ITS_PARENTS` - Combines FOCUSED_WIDGET_AND_ITS_CHILDREN and FOCUSED_WIDGET_AND_ITS_PARENTS types.

The focused widget is set by `Scene.setFocusedWidget` method. This method is not called automatically and it has to be called by a developer. Anyway there are a few places which are calling it automatically when:

- You call `ObjectScene.setFocusedObject` method to set an focused object. It automatically sets its related widget as focused one.
- You call `ObjectScene.setSelectedObjects` method to set selection objects. The first one is automatically set as a focused object too using `ObjectScene.setFocusedObject` method.
- You are using `CycleFocusAction` in your `ObjectScene`.

### ActionMapAction

Created by: `ActionFactory.createActionMapAction ()`, `ActionFactory.createActionMapAction (InputMap, ActionMap)`

The action handles key events and popup menu creation. The keys and actions are obtained from specified InputMap and ActionMap parameters. The method without parameters uses the InputMap and ActionMap assigned to a JComponent view of a scene.

### AcceptAction

Created by: `ActionFactory.createAcceptAction (AcceptProvider)`

The action allows to handle D'n'D drop operation. `AcceptProvider.isAcceptable` method is called for resolving whether the drop can happen and `AcceptProvider.accept` is called for handling the drop operation.

### AddRemoveControlPointAction

Created by: `ActionFactory.createAddRemoveControlPointAction`

The action allows user to add a control point by double-clicking on path or remove control point by double-clicking on it. The action has `routingPolicy` which is automatically set to `ConnectionWidget` to prevent discarding of user changes by router assigned to the connection widget. For fixing moving-anchor problem use `FreeRectangularAnchor`.

### AlignWithMoveAction

Created by: `ActionFactory.createAlignWithMoveAction (AlignWithMoveDecorator, AlignWithWidgetCollector)`

The action is similar to MoveAction but it allows snapping feature similar to Form Editor module. The `AlignWithMoveDecorator` supplies a graphic for snapping lines and the `AlignWithWidgetCollector` gathers all widgets that the snapping has to be checked against.

The outerBounds boolean parameter allows to specify whether client area or bounds of widgets is going to be checked.

### AlignWithResizeAction

Created by: `ActionFactory.createAlignWithResizeAction (AlignWithMoveDecorator, AlignWithWidgetCollector)`

The action is similar to `ResizeAction` but it allows snapping feature similar to Form Editor module. The `AlignWithMoveDecorator` supplies a graphic for snapping lines and the `AlignWithWidgetCollector` gathers all widgets that the snapping has to be checked against.

The outerBounds boolean parameter allows to specify whether client area or bounds of widgets is going to be checked.

### CycleFocusAction

Created by: `ActionFactory.createCycleFocusAction(CycleFocusProvider)`

The action is usually assigned to the scene widget and allows cycling focus using "Tab" key. The behavior of the cycling is defined by `CycleFocusProvider` interface which has two methods for cycling forward and backward.

If the action is created using `ActionFactory.createCycleObjectSceneFocusAction` method then using "Tab" key a focused object is cycling through all objects on an object scene. It is using the `ObjectScene.getIdentityCode` method for resolving the order of objects on a scene. For details, see Object Identity Code section.

### ConnectAction

Created by: `ActionFactory.createConnectAction (ConnectDecorator, ConnectProvider)`

The action should be assigned to the widget from which a connection should be created. The `ConnectDecorator` supplies the graphics for the guiding connection line. The `ConnectProvider` handles a connection creation and the connection source and target checking.

### EditAction

Created by: `ActionFactory.createEditAction (EditProvider)`

The action allows to handle double-clicking on assigned widget. `EditProvider` handles the edit.

### HoverAction

Created by: `ActionFactory.createHoverAction (HoverProvider)` or `ActionFactory.createHoverAction (TwoStatedHoverProvider)`

The action allows to handle "hovering" effect when a mouse is hovering a widget where the action is assigned to. The first method invokes `HoverProvider` always when a mouse-cursor moves over assigned widget. The `TwoStatedHoverProvider` allows handling of an old and a new hovered-widget and provides `unsetHovering (Widget)` and `setHovering (Widget)` methods.

Because there is no Widget-related focus event generated by the library, therefore the hover action is not unsetting the hover after the mouse cursor leaves the related widget space. For fixing this, the same instance of the hover action has to be assigned to the Scene instance too. This will tell the library that when you are over a widget with hover actions assigned, then it is set into hovered state. When there is no widget (with hover actions assigned) under mouse cursor, then the scene itself is in hovered state and therefore the unsetHovering method is called in the previous widget.

There is a `Scene.createWidgetHoverAction` method which creates a widget-specific hover action. The actual hovered widget is held by the `Scene` instance and it only calls `Widget.setState` method with an appropriate parameter.

There is also `ObjectScene.createObjectHoverAction` method which creates an object-specific hover action. The hovering is based actual hovered object (not a hovered widget) in the ObjectScene instance. It means the mouse cursor is changed against widget that are representing objects in `ObjectScene`. The actual hovered object is held by `ObjectScene` instance. See ObjectScene section.

#### HoverAction vs. ObjectSceneHoverAction

A regular `HoverAction` (with your own implementation of `HoverProvider` or `TwoStatedHoverProvider` interfaces) and `ObjectHoverAction` can be used exclusively only.

How to use `HoverAction`:

- Implement your own `HoverProvider` or `TwoStateProvider`.
- Create an `HoverAction` from it.
- Then assign the action to the scene (for reseting hover) and to all widgets that can be hovered.
- If a mouse-cursor is own a widget which HoverAction assigned, then the widgetHovered method is called with particular widget as argument.

How to use `ObjectSceneHoverAction`:

- You do not have to implement anything. You use an action created by the `ObjectScene.createObjectHoverAction` method.
- This action should be assigned to the widgets of objects (in an `ObjectScene`) that can be hovered.
- Note that you should not assign it to a scene - it is done automatically. If a mouse-cursor is over a widget which `ObjectHoverAction` assigned, then the `ObjectScene.hoveredObjectM` property is changed to an object which belongs to the widget and all widgets registered for the object are called using `Widget.notifyStateChanged` method where the new `ObjectState` is passed as an argument. Each widget itself is defining how it will change its apperance based on the provided `ObjectState`.

### InplaceEditorAction

Created by: `ActionFactory.createInplaceEditorAction (InplaceEditorProvider)`

The action is a specialized case of EditAction. `InplaceEditorProvider` is called to supply the in-place editor represented as a Swing JComponent. The editor can be controlled using `InplaceEditorProvider.EditorController` interface. There is also `ActionFactory.createTextFieldInplaceEditorAction (TextFieldInplaceEditor)` method that allows text in-place editor using `JTextField`.

Using `ActionFactory.getInplaceEditorController` method you can obtain an `EditorController` for a specific action. The `EditorController` allows e.g. to programatically open in-place editor using `EditorController.openEditor` method.

The action also allows to specify an expansion directions using `InplaceEditorProvider.getExpansionDirections` method. Everytime an editor component is changed, it should call `InplaceEditorProvider.EditorController.notifyEditorComponentBoundsChanged` method to invoke recalculation of editor placement based on the initial bounds and expansion directions. Expansion direction of for built-in text-field based in-place editor there is an additional `ActionFactory.createTextFieldInplaceEditorAction (TextFieldInplaceEditor,EnumSet<InplaceEditorProvider.ExpansionDirection>)` factory method created. In this case the initial bounds of the editor component are resolved as the bounds of the related widget.

### MoveAction

Created by: `ActionFactory.createMoveAction (MoveStrategy, MoveProvider)`

When the action is assigned to a widget, it allows to drag/move the widget. The movement is done by calling `Widget.setPreferredLocation`. It usually requires to have AbsoluteLayout to be set on the parent widget. `MoveStrategy` allows processing of the new suggested location and therefore supplying snap-to-grid or lock axis movement strategy. The `MoveProvider` interface allows to define behavior of movement e.g. you can move another widget than the widget that has the MoveAction assigned. There are built-in strategies and providers in `ActionFactory` too. For more details, see Strategies section.

### MoveControlPointAction

Created by: `ActionFactory.createMoveControlPointAction (MoveControlPointProvider)`

The action allows to move control points of a ConnectionWidget. There are built-in providers in `ActionFactory` too.

### PanAction

Created by: `ActionFactory.createPanAction ()`, `ActionFactory.createWheelPanAction ()`

The action allows to scroll the view using mouse movement while mouse-middle-button is pressed. It requires to have JComponent view placed into a JScrollPane. This action is usually assigned to a Scene only.

The `WheelPanAction` allows to scroll ascene view using mouse-wheel. Then no key modifier is pressed, then the view is scrolled vertically. If shift key is held, then the view is scrolled horizontally.

### PopupMenuAction

Created by: `ActionFactory.createPopupMenuAction (PopupMenuProvider)`

The action allows to invoke popup-menu that is supplied by the provider.

### RectangularSelectAction

Created by: `ActionFactory.createRectangularSelectAction (ObjectScene, LayerWidget)`

The action allows to handle object-selection using a rectangle that is created by dragging the widget where the action is supplied. This action is usually assigned to an `ObjectScene` or `LayerWidget`. See ObjectScene section.

### ReconnectAction

Created by: `ActionFactory.createReconnectAction (ReconnectDecorator, ReconnectProvider)`

The action should be assigned to the `ConnectionWidget` and allows reconnecting its source and target. `ReconnectDecorator` supplies the graphics of temporary reconnecting line. `ReconnectProvider` handles the reconnection and the connection source and target checking.

### ResizeAction

Created by: `ActionFactory.createResizeAction (ResizeStrategy, ResizeControlPointResolver, ResizeProvider)`

It is similar to MoveAction but used `Widget.setPreferredBounds`. Also there are `ResizeStrategy` and `ResizeProvider` interfaces. There are built-in providers in `ActionFactory` class too. For more details, see Strategies section.

`ResizeControlPointResolver` allows customization of control points for resize action - resolves what kind of resizing is available at particular location of related widget.

### SelectAction

Created by: `ActionFactory.createSelectAction (SelectProvider)`

The action allows to handle the single-click. It is similar to EditAction. It also allowed to condition the selection and allows using "aimed" object state.

### ZoomAction

Created by: `ActionFactory.createZoomAction (zoomFactorMultiplier, animated)`, `ActionFactory.createCenteredZoomAction (zoomFactorMultiplier)`, `ActionFactory.createMouseCenteredZoomAction (zoomFactorMultiplier)`

The action allows to zoom the view using scrolling mouse-middle-button. The action is usually assigned to a Scene only. For correct functionality of the action, the JComponent has to be put into scrollable panel like JScrollPane.

While the `CenteredZoomAction` is zooming, a view is still centered to the center of the view. While the `MouseCenteredZoomAction` is zooming, a view is still centered to mouse cursor.

### Example: Using Actions

Following example allows zooming and panning and allows to have a `IconNodeWidget` moving and widget-specific hovering.

    Scene scene = new Scene (); // has AbsoluteLayout by default
    IconNodeWidget iconNode = new IconNodeWidget (scene);
    iconNode.setImage (Utilities.loadImage ("path/to/my/image.png"));
    iconNode.setLabel ("MyIconNode");
    scene.addChild (iconNode);

    scene.getActions ().addAction (ActionFactory.createCenteredZoomAction (1.1));
    scene.getActions ().addAction (ActionFactory.createPanAction ());

    // assign HoverAction - the actual hovered widget is held by the scene
    iconNode.getActions ().addAction (scene.createWidgetHoverAction ());

    // MoveAction has to be after the hover action
    // otherwise MoveAction will always consume the event and HoverAction will never be invoked
    iconNode.getActions ().addAction (ActionFactory.createMoveAction ());

### Order of Actions

The actions are created with a specific invocation for users. For example: The MoveAction is invoked by pressing mouse button on a widget. Then the action consumes all the events until the mouse button is released. Therefore you have to be aware of the order of the actions that you are assigning to the widget.

Here is usually order when a select, in-place editor, hover, move actions.

    WidgetAction.Chain actions = nodeWidget.getActions ();

    // creates an in-place editor action
    // opens the in-place editor when user double-clicks on the node widget
    // this action consumes only double-click events
    actions.addAction (ActionFactory.createTextFieldInplaceEditor (...));

    // creates a object-based select action
    // just selects the node when mouse-button is pressed on the node widget
    // this action does not consume any event
    actions.addAction (myObjectScene.createSelectAction ());

    // creates a move action
    // this action moves the node widget
    // this action consumes all events when the mouse is dragged
    // (means: while the mouse button is pressed on the node widget)
    actions.addAction (ActionFactory.createMoveAction ());

    // creates a object-based hover action
    // this action controls the hover state of the node (and node widget)
    // this action consumes all events while the mouse is over the node widget
    // (means: almost everytime) - therefore use it as the last action.
    actions.addAction (myObjectScene.createObjectHoverAction ());

If you would like to use the connect action together with move action, you have to use the extended connect action. It is because the connect action is invoked exactly the same way as the move action and therefore the invocation is clashing. This means that the action, which is added first, locks the event processing to itself and the second action will not be invoked at any time. This could be prevented by making two different invocation. This is defined by the extended connect action. The extended connect action is invoked only if the Ctrl key is pressed while you are pressing the mouse button and then dragging the mouse. Now these two action invocations are clashing and you can use them both. Also in this case the order of the actions does not matter.

### Action Creation

There are various methods where instances of actions can be created. Usually it done by a method in the `ActionFactory` class. These actions are generic.

The `Scene` class has a `createWidgetHoverAction` method for creating a widget specific hover action. Call this method after you have assigned all actions to the scene (since this action is internally added to the actions chain of the scene and the nature of the action is that it consumes all events while a mouse cursor is over the scene which usually happens all the time).

The `ObjectScene` class has a few methods for creating object-specific actions that controls selection, hovering, ... They are defined on the object scene since they are tightly coupled with the object scene. The select action created by object scene also sets the focused object.

In the future, methods that are defined on a scene and object scene could be moved to the `ActionFactory` class too.

### Strategies

Sometimes you want to restrict the widget movement or resizing. For that purpose there is a `MoveStrategy` or `ResizeStrategy` interfaces which implementations could be passed as an argument to `ActionFactory.createMoveAction` and `ActionFactory.createResizeAction` methods.

The interfaces contains a single method which is called when a new location or boundary is going to be set. The suggested value is passed to the method as argument and developer has to implement the logic and return the location or boundary which is going to be set.

Following code shows a few examples for strategies:

    public final class SnapTo16x16GridMoveStrategy implements MoveStrategy {
        public Point locationSuggested (Widget widget, Point originalLocation, Point suggestedLocation) {
            return new Point (suggestedLocation.x - suggestedLocation.x % 16, suggestedLocation.y - suggestedLocation.y % 16);
        }
    }
    public final class PositiveCoordinatesOnlyMoveStrategy implements MoveStrategy {
        public Point locationSuggested (Widget widget, Point originalLocation, Point suggestedLocation) {
            return new Point (Math.max (suggestedLocation.x, 0), Math.max (suggestedLocation.y, 0));
        }
    }

## ConnectionWidget

This widget represents a connection/path between source and target point. The source and target point is defined by `Anchor`. The path is defined by control points which are resolved by assigned `Router`. By default it is `DirectRouter` which routes the path as a straight line between the source and target point. The source and target points are not specified directly but by using anchors.

The `ConnectionWidget` has properties for setting source and target point shapes, control points shape, ability to calculate which segment of path or control point is hit by a specific point, ...

Line color is defined by the `foregroundColor` property.
Note: If you are changing a state of a ConnectionWidget (e.g. using it as a representation of an object in ObjectScene, GraphScene or GraphPinScene classes, then the ConnectionWidget.notifyStateChanged method is automatically called. See ObjectScene section for details. The built-in implementation of this method overrides value of `foregroundColor` property based on a new state of the widget (the particular color is resolved by the LookFeel of the scene).

Also there is the `lineColor` property. By default it is `null`. If it is non-null value, then it overrides the object-state-based behavior of the ConnectionWidget. Therefore the lineColor value to be written foregroundColor property and uses as strictly defined color of the line.

A connection can have assigned a source and a target `AnchorShape` and a end-point and control-point `PointShape`. Source AnchorShape is used for defining a shape of a source point. Target anchor shape is used for defining a shape of a target point. An end point shape is used defining a shape of first or last control point. A control point shape is used for defining a shape of other control points except first and last. There are 4 predefined anchor shapes: `AnchorShape.NONE`, `AnchorShape.TRIANGLE_HOLLOW`, `AnchorShape.TRIANGLE_FILLED`, `AnchorShape.TRIANGLE_OUT`. Other built-in anchor shapes can be created by `AnchorShapeFactory` class. There are 2 predefined point shapes: `PointShape.SQUARE_FILLED_BIG`, `PointShape.SQUARE_FILLED_SMALL`. Other built-in point shapes can be created using `PointShapeFactory` class.

There is a `controlPointsCursor` property which defines a mouse cursor when the mouse is over a visible control point.

There is a `controlPointCutDistance` property. If set to positive number (by default 0), then the connection path is cut at each control point to make smoother corners. The smooth corners are not used during calculation whether a mouse-cursor hits the path.

### Router

`Router` cares about creating paths. There are following built-in implementations:

- `RouterFactory.createDirectRouter` creates a straight line between the source and the target anchor.
- `RouterFactory.createOrthogonalSeachRouter (CollisionsCollector)` creates an orthogonal path that tries to avoid overlapping areas specified by the `CollisionsCollector`. There is a built-in implementation `RouterFactory.createWidgetsCollisionCollector (LayerWidget...)` which collects all validated children widgets of the specified layer widgets and for each it gets the widget boundary and claims it as a vertical and horizontal collision. In case of ConnectionWidget, it takes the path (defined by its control points) and claims all horizontal and vertical segments as appropriate collisions.
- `RouterFactory.createOrthogonalSeachRouter (ConnectionWidgetCollisionsCollector)` creates an orthogonal path similarly as the previous case but the `ConnectionWidgetCollisionsCollector` gets a context of currently routed connection widget.
- `RouterFactory.createFreeRouter` is similar to `DirectRouter` but it modifies only the first and last point of the route. The "middle" control points stay the same. This effect is used by `AddRemoveControlPointAction` to maintain the control points created by user. From now this router is no longer useful, since it can be replaced by more flexible way: use any router that you like and set "Update-end-points-only" routing policy to the ConnectionWidget.

### ConnectionWidgetLayout

`ConnectionWidget` allows developer to attach children widgets too. Those children could be attached relatively to the path using constraints. The constraint could be set using `ConnectionWidget.setConstraint` method for each child widget. If a child widget has non-null preferred location then this preferred location will be added to the relative location.

See `test.connectionlabels.ConnectionLabelsTest` for details.

### Routing Policy

Since version 2.9, the ConnectionWidget class has additional `routingPolicy` property. It ease management of control points changed by users. There are 4 values:

1. `ALWAYS_ROUTE` - This is default value. The router is always invoked when a ConnectionWidget is changed and needs to be re-routed.
2. `UPDATE_END_POINTS_ONLY` - The router is not invoked. Instead location of the first and the last control points are changed/updated to location computed by source and target anchors.
3. `DISABLE_ROUTING_UNTIL_END_POINT_IS_MOVED` - The router is not invoked until the first or the last control points is moved (means it has different location from one computed by source or target anchor).
4. `DISABLE_ROUTING` - The router is not invoked. The control points are freezed at the same locations.

These routing policy are very useful when you are using modifying control points:

- You can specify `routingPolicy` value to factory method of `AddRemoveControlPointAction` and `MoveControlPointAction`. If not null, then the value is automatically set to a ConnectionWidget which control points are modified by the action. Usually `UPDATE_END_POINT_ONLY` is used.
- Some graph-oriented layout algorithms are resolving not only location of nodes on a scene but also routes path of edges. Then you can use `UPDATE_END_POINT_ONLY` or `DISABLE_ROUTING_UNTIL_END_POINT_IS_MOVED` to prevent discard of paths routed by the graph-oriented layout. For usages, see `test.routing.ActionsWithRoutingPolicyTest` and `test.routing.RoutingPolicyTest` examples.

  ### ConnectionWidget Methods

  Method | Description
  --- | ---
  getStroke setStroke | Controls a stroke that is used for painting the line.
  getLineColor setLineColor | Controls line color. If not set, then the line color is obtained from LookFeel of the scene.
  isPaintControlPoints setPaintControlPoints | Controls whether control-points has to be painted too.
  getSourceAnchor setSourceAnchor | Manipulates with the source anchor. This method calls: `Anchor.removeEntry` and `Anchor.addEntry` methods to register the usage on anchor (uses `ConnectionWidget.getSourceAnchorEntry` as an entry for registration).
  getTargetAnchor setTargetAnchor | Manipulates with the target anchor. This method calls: `Anchor.removeEntry` and `Anchor.addEntry` methods to register the usage on anchor (uses `ConnectionWidget.getTargetAnchorEntry` as an entry for registration).
  getSourceAnchorEntry getTargetAnchorEntry | Returns source and target entry of the connection widget.
  getSourceAnchorShape setSourceAnchorShape getTargetAnchorShape setTargetAnchorShape | Controls a shape of source and target anchor. Shape is defined by a `AnchorShape` interface.
  getControlPointShape setControlPointShape | Controls a shape of control points. Shape is defined by `PointShape` interface. The control points are painted only if `isPaintControlPoints` returns true.
  getEndPointShape setEndPointShape | Controls a shape of end points (source and target). Shape is defined by `PointShape` interface. The end points are painted only if `isPaintControlPoints` returns true.
  getControlPointCutDistance setControlPointCutDistance | Controls a cut distance where the line cut with half-angle line at every control point. See `test.widget.ConnectionWidgetCutDistanceTest` example.
  getRouter setRouter | Controls a router assigned to the connection widget. The routers is calculating a path and sets a new one using `setControlPoints` method.
  getRoutingPolicy setRoutingPolicy | Controls a routing policy assigned to the connection widget. It controls whether and how control points are re-routed. For details, see Routing Policy section.
  getControlPoints() setControlPoints(List<Point>controlPoints,boolean sceneLocations) getControlPoint(int index) | Manipulates with control points. If the `sceneLocations` is `true` then the `controlPoints` are recalculated relatively to the connection widget location otherwise controlPoints are taken as they are (and therefore they are taken as local locations). This method is usually called by the assigned router.
  setConstraint (childWidget, alignment, placementInPercentage) | This method sets a constraint to a child widget (of the connection widget). It uses the specified alignment. The placement is resolved by the placementInPercentage parameter: 0.0f is the source anchor location, 1.0f is the target anchor location.
  setConstraint (childWidget, alignment, placementAtDistance) | This method sets a constraint to the child widget (of the connection widget). It uses the specified alignment. The placement is resolved by the placementAtDistance (in pixels) parameter: <=0 is the source anchor location; if >=path-length means the target anchor location.
  removeConstraint (childWidget) | This method removes a constraint for the child Widget.
  calculateRouting | This method forces path re-routing. It is called automatically and developer does not have to call it.
  isValidated | Return `true` if the widget is validated and its path is routed.
  isRouted | Return `true` if the widget has its path routed.
  reroute | Schedules connection widget for routing its path.
  getFirstControlPoint getLastControlPoint | Returns local location of first or last control point.
  getSourceAnchorShapeRotation getTargetAnchorShapeRotation | Returns an angle of source or target anchor shape in radians. The rotation is calculated as a angle between first/last path segment to the x-axis counter-clockwise. It usually used by `AnchorShape` for painting.
  isHitAt(localLocation) | Checks whether the specified location hits (is a part of) the widget.
  isFirstControlPointHitAt(localLocation) | Checks whether the specified location hits (is a part of) the first control point of the widget. The checked area is specified by the end-point radius.
  isLastControlPointHitAt(localLocation) | Checks whether the specified location hits (is a part of) the last control point of the widget. The checked area is specified by the end-point radius.
  getControlPointHitAt(localLocation) | Checks whether the specified location hits (is part of) of a control point of the widget. The checked area is specified by the control-point radius. If hit, then it returns the control point index.

  ## Anchor

  Anchors are resolving the proper location of the point that they represent. Usually `Anchor` is attached to a `Widget` and listens on its placement changes using `Widget.Dependency` interface. If the widget is changed, then the anchor notifies (using `Anchor.Entry.revalidateEntry` method) all connection widgets that are using the anchor. Then all affect connection widgets schedule routing their paths. Anchor has possibility to use a widget reference or reference point of the opposite anchor that is assigned to the same connection widget. Anchor (set as the source anchor) has the target anchor as its opposite anchor and vice versa.

  ### FixedAnchor

  `AnchorFactory.createFixedAnchor (Point)` method creates an anchor with fixed location that is not changed.

  ### CenterAnchor

  `AnchorFactory.createCenterAnchor (Widget)` method creates an anchor which follows the center of the widget.

  ### RectangularAnchor

  `AnchorFactory.createRectangularAnchor (Widget)` method creates an anchor which resolves the point as a point on the widget boundary that the closest a widget of opposite anchor (assigned to the connection widget).

  ### CircularAnchor

  `AnchorFactory.createCircularAnchor (Widget, int radius)` method creates an anchor which resolves the point as a point on a circle with radius around the widget center that the closest a widget of opposite anchor (assigned to the connection widget).

  ### DirectionalAnchor

  `AnchorFactory.createDirectionalAnchor (Widget, DirectionalAnchorKind directions)` method creates an anchor which resolves the point as a point at the north-south-west-east center of side of the widget boundary that the closest a widget of opposite anchor (assigned to the connection widget).

  ### ProxyAnchor

  `AnchorFactory.createProxyAnchor (StateModel, Anchor...)` method creates an anchor that contains an array of anchor and forwards the point resolving to the single active anchor. The active anchor is defined by the index stored in the `StateModel` class. This is used in VMD plug-in for handling pin-anchors - there the pin could be hidden in a node and then the anchor placement resolving has to be forward from the pin to the anchor assigned to the node.

  ### Anchor Dependency

  Anchor is dependent on the related widget which is specified using a constructor parameter. The anchor automatically listen on the widget whether it is not changed. If the widget changes then anchor notifies all registered `Anchor.Entry` interface implementation (usually `ConnectionWidget.getSourceAnchorEntry` or `ConnectionWidget.getTargetAnchorEntry`). These entries are notifying connection widgets to schedule routing of their paths because the location of the anchor could be changed.

  Each time the connection widget sets its new source or target anchor. It also removes from old and adds to new `Anchor` an appropriate `Anchor.Entry`. A list of entries can be obtained using `Anchor.getEntries` method.

  This anchor dependency approach allows to have a `ProxyAnchor` that delegates the computation to one of its anchors. This mechanism is used for Minimize ability in VMD plug-in. See Minimize Ability section for details.

  ### Example: ConnectionWidget with Anchors

  The following code shows how to create a connection widget with 2 anchors - source anchor is `RectangularAnchor` bound to the `w1` widget and target anchor is `FixedAnchor` with a fixed location at scene origin `[0,0]`. A shape of target anchor will be filled-triangle.

      ConnectionWidget c = new ConnectionWidget (scene);
      c.setSourceAnchor (AnchorFactory.createRectangularAnchor (w1));
      c.setTargetAnchor (AnchorFactory.createFixedAnchor (new Point (0, 0)));
      c.setTargetAnchorShape (AnchorShape.TRIANGLE_FILLED);

  ### Loop Edge

  The loop connection is a connection where the source and the target has the same anchor/widget. The visualization of such connection should be a small loop attached to the widget. For making this you have to have:

  - source and target anchor that computes different locations or
  - Router that computes a loop path.

  The only built-in anchor implementation that is creating an anchor that generates different locations for source and target is `VMDNodeAnchor` class. You have to create a new instance for each Widget where the anchor has to be assigned. The best is to use it with `OrthogonalSearchRouter` that will create a small orthogonal "loop" path.

  ### Parallel Edges

  The structures used in the library supports parallel edges. Be aware of anchor used for source and target of connection widget. Almost all implementations are calculating the same location for the same widget where the anchor is attached too. The only built-in implementation that could be used for this visualization is `VMDNodeAnchor`.

  ## LayerWidget

  This widget represents a glass-pane - similarly to `JGlassPane` from Swing. It is transparent by default. Usually a set of `LayerWidget`s are used in a widget that does not have any layout assigned. Then all layers are placed one over another which could be used for various optimalizations.

  For example scene layers: You have a scene with `AbsoluteLayout` and you will add `LayerWidget` with `AbsoluteLayout` as the scene children. This allows to have independent panels.

  Usually following scene layers are used:

  - backgroundLayer for temporary background interaction widgets - like rectangular selection
  - mainLayer for main widgets,
  - connectionLayer for connections to speed up the scene validation when connection as dependent on placement of widgets in mainLayer - in that case the scene validation is done in a single pass
  - interactionLayer for temporary foreground interaction widgets created by decorators of interactive actions like ConnectAction or AlignWithMoveAction, ...

  ### Example: Layers

  Following code creates a scene with two layers: mainLayer for objects, connectionLayer for connections. This is usual implementation when there are `ConnectionWidget`s used in a scene. Because during validation the mainLayer is calculated completely first and then the connectionLayer is calculated completely. This allow the mentioned 1-pass calculation. If connection widgets would be in single mainLayer together with the main objects, then it can happen that `w1` and `w2` are calculated after `c` and therefore `c` would have to be calculated again. This means that at the end the connection widgets could be calculated twice. With the 2 layers approach it is always once.

      Scene scene = new Scene ();
      LayerWidget mainLayer = new LayerWidget (scene);
      scene.addChild (mainLayer);
      LayerWidget connectionLayer = new LayerWidget (scene);
      scene.addChild (connectionLayer);

      Widget w1 = new LabelWidget (scene, "Source");
      mainLayer.addChild (w1);
      Widget w2 = new LabelWidget (scene, "Target");
      mainLayer.addChild (w2);

      ConnectionWidget c = new ConnectionWidget (scene);
      c.setSourceAnchor (AnchorFactory.createRectangularAnchor (w1));
      c.setTargetAnchor (AnchorFactory.createRectangularAnchor (w2));
      connectionLayer.addChild (c);

  ## ObjectScene

  The tree of widgets is usually not enough for modeling. You would like to work with objects, control selection of objects, ... Everything is based on objects in a model. Scene on the other hand works with Widgets. Therefore there is an `ObjectScene` class. It manages the mapping between objects and widgets and allows object-oriented access to the scene including selection, highlighting (something like secondary selection), hovering, ... Each object can be mapped to multiple widgets.

  The `ObjectScene` does not create any widget or object. All objects and their widget peers has to be created by developer, placed in the tree hierarchy of widgets and then registered using `ObjectScene.addObject (Object, Widget...)` method.

  Internally objects are stored in `Map`, therefore `equals` method is used for comparing and identification. It is recommended to use objects which `equals` method implemented as `return object == this;`. Especially do not use `Array`s, `List`s, `Set`s, `Map`s, ... because:

      ObjectScene scene = new ObjectScene ();
      Map m1 = new HashMap ();
      // registers "m1" instance
      scene.addObject (m1);
      Map m2 = new HashMap ();
      // the m2 object is already in the scene because "m1.equals (m2)" is true
      scene.isObject (m2); // return true
      scene.addObject (m2); // ERROR - already added

  ### ObjectState

  Each widget at scene has its state (defined with `ObjectState` class). A state represents whether a widget has: selected, highlighted, widgetHovered, objectHovered, widgetFocused, objectFocused and aimed flags set. The default value is result of `ObjectScene.createNormal` method which does not have any flags raised.

  The state is stored at each widget. You can manipulate with it using `Widget.getState` and `Widget.setState` method. `Widget.notifyStateChanged` method is called after any state change on the widget. This allows to define state-specific behavior directly inside the widget implementation class.

  `ObjectScene` class manages similar states for its objects. The state is changed automatically when the selection, highlighting or hovering is changed in ObjectScene using `ObjectScene.setSelectedObjects`, `ObjectScene.setHoveredObject`, ... methods. When the state of an object is changed then the state of its widget peer is changed according to the object-state-change too. You can obtain the state of an object using `ObjectScene.getObjectState` method. When the state of a widget is changed, it does not affect the state of particular object.

  ### ObjectScene Methods

  Method | Description
  --- | ---
  addObject (Object, Widget...) | Registers an object with mapping to its widget peers. Widget array cannot contain `null` value. For backward compatibility the widgets array could be also a single `null` value array. Then it be takes as empty widgets array.
  removeObject (Object) | Unregisters an object.
  getObjects () | Returns a set of objects in the scene.
  isObject (Object) | Returns whether the specified object is registered.
  getSelectedObjects () setSelectedObjects (Set) | Controls the set of selected objects. The object state is propagated to a widget related to the object.
  getHighlightedObjects () setHighlightedObjects (Set) | Controls the set of highlighted objects. The object state is propagated to a widget related to the object.
  getHoveredObject () setHoveredObject (Object) | Controls a hovered object of the scene. Usually there is no need to call it. The object state is propagated to a widget related to the object. There could be only one focused object set at the same time.
  getFocusedObject () setFocusedObject (Object) | Controls a focused object of the scene. The object state is propagated to a widget related to the object. There could be only one focused object set at the same time.
  addObjectSceneListener(listener,eventTypes) removeObjectSceneListener(listener,eventTypes) | Registers and unregisters an object scene listener for a specified event types. See ObjectSceneListener section for details.
  createSelectAction () | Creates a object-specific select action. Usually assigned to a widget peer of an object which should be selected by user. The selected object is also set as focused object.
  createObjectHoverAction () | Creates object-specific hover action. This action controls the hovered object on a scene. It opposite to the widget-specific hover action.
  findWidget (Object) | Finds a widget peer for an object. It return a single widget only which is the first widget parameter passed to the `ObjectScene.addObject` method.
  findWidgets (Object) | Finds a list of all widget peers registered to an object.
  findObject (Widget) | Finds an object for a widget peer.
  findStoredObject (Object templateObject) | Returns the stored instance of an object where `storedObject.equals (templateObject)`.
  getObjectState (Object) | Returns an object state for a specified object. See ObjectState section.
  userSelectionSuggested (Set) | This method is called from select action (created by `ObjectScene.createSelectAction` method) and `RectangularSelectProvider` (created by `ActionFactory.createObjectSceneRectangularSelectProvider` method). It allows you to filter the selection done by an user. Default implementation of this method just calls `setSelectedObjects` method with the specified `Set` as a parameter.
  getIdentityCode (Object) | This method is called to get identity code for a specified object. The identity code is used for resolving an order of objects since objects are not sorted in an object scene. The method is meant to be overridden to provide. Default implementation just returns a system identity hash code of each object. See Object Identity Code section.

  ### ObjectSceneListener

  The ObjectScene allows to listen on a changed done inside. There are following event types:

  - ObjectSceneEventType.OBJECT_ADDED
  - ObjectSceneEventType.OBJECT_REMOVED
  - ObjectSceneEventType.OBJECT_STATE_CHANGED
  - ObjectSceneEventType.OBJECT_SELECTION_CHANGED
  - ObjectSceneEventType.OBJECT_HIGHLIGHTING_CHANGED
  - ObjectSceneEventType.OBJECT_HOVER_CHANGED
  - ObjectSceneEventType.OBJECT_FOCUS_CHANGED

  The listener could be (un)registered using `ObjectScene.add/removeObjectSceneListener(ObjectSceneListener,ObjectSceneEventType...)` methods. The listener is registered for a specified event types only. This is due to performance and API reasons. There is a single listener used for all event types to prevent heavy addition of `add/remove*Listener` methods in `Scene`-derived classes. Also the implementation of an event processing has to as fast as possible - especially processing objectAdded, objectRemoved and objectStateChanged.

  ObjectSceneListener could be reused for more object scenes. There is a ObjectSceneEvent instance passed as the first parameter of every listener method. You can acquire ObjectScene instance by calling `ObjectSceneEvent.getObjectScene()` method.

  ### Object Identity Code

  Objects in an object scene are not sorted - they are kept in an unsorted set. Therefore there is a `ObjectScene.getIdentityCode` method meant to be overridden, which defines an order of those objects. The order is defined the way that an identity code must exist for each object and it must be unique in an object scene. The identity code is represented by Comparable interface and therefore it can be used for sorting and comparing.

  The method is meant to be overridden to provider more accurate ordering identity code. Default implementation is returning an system identity hash-code of an object. If you are using Comparable-implementing classes for objects in an object scene, then they can represents/define identity code automatically and you can use directly as a return value of the `getIdentityCode` method.

  ## Graph Support

  The library has support for graph-oriented modeling. There are two models supported:

  - GraphScene manages a model with nodes and edges. Edge could be connected to a source and target node only.
  - GraphPinScene manages a model with nodes, pins and edges. A pin is always attached to a node. Edge could be connected to a source and a target pin only.

  Both are using generics and therefore developers can specify their classes that represents nodes, pins and edges. Following code contains examples for specifying the classes:

      // GraphScene class is abstract, it has to be extended to supply UI therefore MyGraphScene is used
      // MyNode class is used for node object. MyEdge class is used for edge object.
      GraphScene<MyNode, MyEdge> graph1 = new MyGraphScene<MyNode, MyEdge> ();
      graph1.addNode (new MyNode ());
      graph1.addEdge (new MyEdge ());

      // String class is used for node, pin and edge object.
      GraphPinScene<String, String, String> graph2 = new GraphPinScene<String, String, String> ();
      graph2.addNode ("node1");
      graph2.addPin ("node1", "pin1");
      graph2.addEdge ("edge1");

      graph2.addEdge ("pin1"); // ERROR - see next paragraph for explanation

  Both classes are derived from `ObjectScene` and therefore inherits its functionality. Also the same rule for object identification (using `equals` method) is applied. All nodes, pins and edges are objects and therefore each of them has to have unique identification across all nodes, pins and edges.

  ### Graph UI Binding

  Both class are using the similar approach for binding objects with widgets. When a node or an edge is added using `GraphScene.addNode` or `GraphScene.addEdge` method, then appropriate `protected GraphScene.attachNodeWidget (Node)` or `protected GraphScene.attachEdgeWidget (Edge)` method is called. These methods are meant to be implemented by a developer to supply the graphics. These methods are responsible for:

  - creating a widget peer for the specified node or edge,
  - add the created widget into the tree hierarchy of widgets and
  - return the widget instance, so the GraphScene class can use it for mapping.
  The methods can return `null` too - that would mean that object does not have a widget peer and therefore it is a non-visual object.

  Optionally the developer can override default implementation of `protected detachNodeWidget (Node, Widget)` and `protected detachEdgeWidget (Edge, Widget)` method. These methods are responsible for removing the graphics. Default implementation just removes the widget peer from its parent widget.

  Edges can have source node assigned using `GraphScene.setEdgeSource` method. When source is changed then `protected GraphScene.setEdgeSourceAnchor` method is called. The method is meant to be implemented by a developer to supply the graphics for applying the source node change. Usually it sets an anchor (related to the new source node) as a source anchor of a connection widget that represents the edge. Similarly it is done for target node of an edge with `GraphScene.setEdgeTarget` and `protected GraphScene.setEdgeTargetAnchor` methods.

  Now the UI is managed and implemented in a developer's class which derives from `GraphScene`. Therefore a developer does not have to care about the UI at all once the class is implemented and can just use the class using graph-oriented model approach.

  The `GraphPinScene` is similar - it just contains methods related to pins.

  ### Example: GraphScene UI

  The following code shows how to create a `GraphScene` with a node (represented as a `String` in a model and as a `IconNodeWidget` in a scene) and a edge (represented as a `String` in a model and as a `ConnectionWidget` in a scene). Nodes and edges will react on selection and hovering - the UI behavior of object-state is defined in `IconNodeWidget` and `ConnectionWidget` directly in their `notifyStateChanged` methods.

      public class MyGraphScene extends GraphScene<String, String> {

          private Widget mainLayer;
          private Widget connectionLayer;

          private WidgetAction moveAction = ActionFactory.createMoveAction ();

          public MyGraphScene () {
              mainLayer = new Widget (this);
              addChild (mainLayer);
              connectionLayer = new Widget (this);
              addChild (connectionLayer);
          }

          protected Widget attachNodeWidget (String node) {
              IconNodeWidget widget = new IconNodeWidget (this);
              widget.setLabel ("Node: " + node);

              WidgetAction.Chain actions = widget.getActions ();
              actions.addAction (createObjectHoverAction ());
              actions.addAction (createSelectAction ());
              actions.addAction (moveAction);

              mainLayer.addChild (widget);
              return widget;
          }

          protected Widget attachEdgeWidget (String edge) {
              ConnectionWidget widget = new ConnectionWidget (this);
              widget.setTargetAnchorShape (AnchorShape.TRIANGLE_FILLED);

              WidgetAction.Chain actions = widget.getActions ();
              actions.addAction (createObjectHoverAction ());
              actions.addAction (createSelectAction ());

              connectionLayer.addChild (widget);
              return widget;
          }

          protected void attachEdgeSourceAnchor (String edge, String oldSourceNode, String sourceNode) {
              ConnectionWidget edgeWidget = (ConnectionWidget) findWidget (edge);
              Widget sourceNodeWidget = findWidget (sourceNode);
              Anchor sourceAnchor = AnchorFactory.createRectangularAnchor (sourceNodeWidget);
              edgeWidget.setSourceAnchor (sourceAnchor);
          }

          protected void attachEdgeTargetAnchor (String edge, String oldTargetNode, String targetNode) {
              ConnectionWidget edgeWidget = (ConnectionWidget) findWidget (edge);
              Widget targetNodeWidget = findWidget (targetNode);
              Anchor targetAnchor = AnchorFactory.createRectangularAnchor (targetNodeWidget);
              edgeWidget.setTargetAnchor (targetAnchor);
          }

      }

  ### GraphScene Methods

  Method | Description
  --- | ---
  addNode (Node) addEdge (Edge) | Adds a node or an edge to the scene. The `attachNodeWidget` or `attachEdgeWidget` is called before the object and its widget peer is really registered. After the registration `notifyNodeAdded` or `notifyEdgeAdded` method is called.
  removeNode (Node) removeEdge (Edge) removeNodeWithEdges (Node) | Removes a node or an edge from the scene. The `detachNodeWidget` or `detachEdgeWidget` is called after the unregistering. While removing an edge, `setEdgeSource (edge, null)` and `setTargetSource (edge, null)` are called first. `removeNodeWithEdges` method removes all connected edges before removing the node.
  removeNodeWithEdges (Node) removePinWithEdges (Pin) | Similar to `removeNode` and `removePin` methods but also removes all edges that are connected to them.
  getNodes getEdges | Returns a collection of registered nodes or edges.
  setEdgeSource (Edge, Node) setEdgeTarget (Edge, Node) | Sets a source or a target to the edge. `attachEdgeSourceAnchor` or `attachEdgeTargetAnchor` method is called after the change is registered.
  getEdgeSource getEdgeTarget | Returns a source or target node of the edge.
  findNodeEdges (Node, allowOutputEdges, allowInputEdges) | Returns a collection of edges connected to the node. If `allowOutputEdges` is `true` then the collection contains edges where the node is as a source. If `allowInputEdges` is `true` then the collection contains edges where the node is as a target.
  findEdgesBetween (sourceNode, targetNode) | Returns a collection of edges that are connected to the `sourceNode` and the `targetNode`.
  isNode (object) isEdge(object) | Returns whether an object is registered as a node or an edge.
  protected attachNodeWidget (Node) protected attachEdgeWidget (Edge) | There methods are meant to be overridden to create a widget peer for a node or an edge. The method is responsible for creating a widget peer, adding it into the tree hierarchy of widgets and returning it from the method. This method is called at the beginning of `addNode` or `addEdge` method. It is not mandatory to create a widget - `null` can be returned too.
  protected attachEdgeSourceAnchor (Edge, oldSourceNode, newSourceNode) protected attachEdgeTargetAnchor (Edge, oldTargetNode, newTargetNode) | These methods are responsible to set a proper anchor to a widget (usually `ConnectionWidget`) peer of the edge. The anchor is usually related to a widget peer of the `newSourceNode` or the `newTargetNode`. This method is called at the end of `setEdgeSource` or `setEdgeTarget` method - the source and the target is registered already. It is not mandatory to assign an anchor - it can do nothing too.
  protected detachNodeWidget (Node, Widget) protected detachEdgeWidget (Edge, Widget) | These methods are called to at the end of `removeNode` or `removeEdge` methods - objects are unregistered already. Default implementation just removes the widget peer from its parent widget.
  protected notifyNodeAdded (Node, Widget) protected notifyEdgeAdded (Edge, Widget) | Called at the end of `addNode` or `addEdge` methods - objects are registered already.

  ### GraphPinScene Methods

  Method | Description
  --- | ---
  addNode (Node) addPin (Node, Pin) addEdge (Edge) | Adds a node, a pin or an edge to the scene. The `attachNodeWidget`, `attachPinWidget` or `attachEdgeWidget` is called before the object and its widget peer is really registered. After the registration `notifyNodeAdded`, `notifyPinAdded` or `notifyEdgeAdded` is called. Adding a pin requires to specify the node where the pin is attached to. There is no possibility to change it later.
  removeNode (Node) removePin (Pin) removeEdge (Edge) | Removes a node, a pin or an edge from the scene. The `detachNodeWidget`, `detachPinWidget` or `detachEdgeWidget` is called after the unregistering. While removing an edge, `setEdgeSource (edge, null)` and `setTargetSource (edge, null)` are called first. While removing a node, all attached pins are removed first using "removePin" method.
  getNodes getPins getEdges | Returns a collection of registered nodes, pins or edges.
  getPinNode | Returns a node where the pin is attached to.
  getNodePins | Returns a collection of pins that are attached to the node.
  setEdgeSource (Edge, Pin) setEdgeTarget (Edge, Pin) | Sets a source or a target to the edge. `attachEdgeSourceAnchor` or `attachEdgeTargetAnchor` is called after the change is registered.
  getEdgeSource getEdgeTarget | Returns a source or target pin of the edge.
  findPinEdges (Pin, allowOutputEdges, allowInputEdges) | Returns a collection of edges connected to the pin. If `allowOutputEdges` is `true` then the collection contains edges where the pin is as a source. If `allowInputEdges` is `true` then the collection contains edges where the pin is as a target.
  findEdgesBetween (sourcePin, targetPin) | Returns a collection of edges that are connected to the `sourcePin` and the `targetPin`.
  isNode (object) isPin (object) isEdge (object) | Returns whether an object is registered as a node, a pin or an edge.
  protected attachNodeWidget (Node) protected attachPinWidget (Pin) protected attachEdgeWidget (Edge) | These methods are meant to be overridden to create a widget peer for a node, a pin or an edge. The method is responsible for creating a widget peer, adding it into the tree hierarchy of widgets and returning it from the method. This method is called at the beginning of `addNode`, `addPin` or `addEdge` method. It is not mandatory to create a widget - `null` can be returned too.
  protected attachEdgeSourceAnchor (Edge, oldSourcePin, newSourcePin) protected attachEdgeTargetAnchor (Edge, oldTargetPin, newTargetPin) | These methods are responsible to set a proper anchor to a widget (usually `ConnectionWidget`) peer of the edge. The anchor is usually related the `newSourcePin` or `newTargetPin`. This method is called at the end of `setEdgeSource` or `setEdgeTarget` method - the source and the target is registered already. It is not mandatory to assign an anchor - it can do nothing too.
  protected detachNodeWidget (Node, Widget) protected detachPinWidget (Pin, Widget) protected detachEdgeWidget (Edge, Widget) | These methods are called to at the end of `removeNode`, `removePin` or `removeEdge` methods - objects are unregistered already. Default implementation just removes the widget peer from its parent widget.
  protected notifyNodeAdded (Node, Widget) protected notifyPinAdded (Pin, Widget) protected notifyEdgeAdded (Edge, Widget) | Called at the end of `addNode`, `addPin` or `addEdge` methods - objects are registered already.

  ## Universal Graph

  Part of the graph support is graph-oriented layout of nodes in a scene. Since the library contains two independent graph-oriented models, there is also a universal graph which unifies them and provides a read-only nodes-edges view on them. The universal graph is represented with `UniversalGraph` abstract class and contains methods: `getNodes`, `getEdges`, `findNodeEdges`, `getEdgeSource`, `getEdgeTarget`. These methods provides read-only access to the model.

  Even thought the UniversalGraph class is abstract, it does not have to be implemented by a developer. The library creates them automatically.

  ## Graph-oriented Layout

  All graph-oriented layout algorithms are implemented by classes based on `GraphLayout` class. The class contains `layoutGraph(GraphScene)` and `layoutGraph(GraphPinScene)` method for invoking the layout on a particular scene. These methods just converts the scene into an universal graph and calls `performGraphLayout(UniversalGraph)>` method which should implement and perform a particular graph-oriented layout.

  The `layoutGraph` method is performing the graph-oriented layout immediately. If the method is called before the scene validation, the algorithm may calculate with obsolete or uninitialized data. Therefore the `SceneLayout` should be used. Following example should how to invoke the layout correctly:

      GraphScene scene = ...;
      // instantiate particular layout e.g.: "new GridGraphLayout ();"
      GraphLayout layout = ...;
      SceneLayout sceneLayout = LayoutFactory.createSceneGraphLayout (scene, layout);
      // schedules the graph-oriented layout after the scene validation
      // it just schedules it but does not perform immediatelly
      sceneLayout.invokeLayout ();
      // or you can call "sceneLayout.invokeLayoutImmediatelly ();"
      // to schedule the layout and force immediate scene validation
      // so the layout will be performed in the "invokeLayoutImmediatelly" method

  Similarly there is a `layoutNodes` method which could be used to resolve location of a sub-set of nodes on a scene. The `UnsupportedOperationException` could be throws from `performLayoutNodes` then the implementation does not support it.

  The graph layout has `animated` which specifies whether a new node location is set directly to the widget or if a animation is used.

  When implementing your own GraphLayout, you have to use `GraphLayout.setResolvedNodeLocation` method call for setting node location.

  ### GraphLayoutListener

  The `GraphLayout` has possibility to attach a `GraphLayoutListener` which allows notification about: `graphLayoutStarted` (called when graph layout is started), `nodeLocationChanged` (called when a node location is changed, `graphLayoutFinished` (called when graph layout is finished).

  ### TreeGraphLayout

  The algorithm organizes nodes in to a tree. Nodes that are not in the tree (defined by a root node and connecting edges) are resolved at [0,0] location.

  The layout can be created using `GraphLayoutFactory.createTreeGraphLayout` factory method. For proper work, you have to specify a root node using `GraphLayoutSupport.setTreeGraphLayoutRootNode` method. See `test.graphlayout.TreeGraphLayoutTest` example for usages.

  Using `GraphLayoutSupport.setTreeGraphLayoutProperties` method you can set all parameters of the tree graph layout that has been specified in the factory method.

  ### GridGraphLayout

  The algorithm organizes nodes in to a grid.

  You can call `setChecker` method to enable checker style. If a parameter is true, that the layout uses only half of nodes on a grid like single color on a chess board.

  You can define horizontal and vertical gaps between nodes using the `setGaps` method.

  ## ComponentWidget

  Widgets are not implemented as AWT/Swing components and the library will never have a full replacement for them. Therefore there is a possibility to integrate Swing components together with the scene. You have to create an instance of `ComponentWidget` class and pass your AWT/Swing `Component` there as a parameter. When the widget is added to the tree, then the component will be shown in the JComponent view. When the widget is removed from the tree, then the component will be removed from the JComponent view.

  The component widget resolves it bounds as `preferred-size-of-Component / zoomFactor`. The size of `Component` is still the same in JComponent view - independent on zoom factor. Bounds of a component widget depends on zoom factor.

  ## Scrollable Widget

  The library contains two implementation of scrollable widget:

  - `ScrollWidget` which is created using widgets only.
  - `SwingScrollWidget` which is created using widgets and Swing `JScrollBar`s.

  In both implementations you can used `getView` and `setView` methods for supplying the inner view widget that should be scrolled.

  By default the scrollable widget takes the bounds of the inner view widget. If you want to have it scrollable, you have to limit the bounds of the scroll widget using `Widget.setPreferredBounds`, `Widget.setMaximumSize` or `Widget.setPreferredSize` method.

  ## In-place Editor

  For using in-place editor ability, you have to have an `InplaceEditorProvider` interface implemented first. Then you can create an action using `ActionFactory.createInplaceEditorAction (InplaceEditorProvider)` method. Then you can add the action to a widget where the in-place editor should be available. When an user double-clicks on the widget, the action is invoked and the provider is asked for creating in-place-editor `Component`. The editor is invoked by pressing Enter key too.

  The library contains a pre-defined `JTextField`-based editor. An action can be created using `ActionFactory.createInplaceEditorAction (TextFieldInplaceEditor)` method. The `TextFieldInplaceEditor` interface defines the initial text and how to set the text.

  If you want to open in-place editor programatically, you have to have particular in-place editor action. Then using `ActionFactory.getInplaceEditorController` method you can get `EditorController` instance which allows you to open the editor using `EditorController.openEditor(Widget)` method.

  The editor component boundary is resolved from the bounds of a widget where the in-place editor action is assigned. Then the bounds are processed by `InplaceEditorProvider.getInitialEditorComponentBounds` method. Then the boundary is expanded/collapsed based on expansion directions returned by `InplaceEditorProvider.getExpansionDirection` method.

  Everytime a `InplaceEditorProvider.EditorController.notifyEditorComponentBoundsChanged` method is called, then the boundary is recalculated again.

  ### Example: In-place Editor

  Following code creates an editable label widget:

      final LabelWidget label = new LabelWidget (scene, "Text");
      label.getActions ().addAction (ActionFactory.createInplaceEditorAction (
          new TextFieldInplaceEditor () {
              public boolean isEnabled (Widget widget) {
                  return true;
              }
              public String getText (Widget widget) {
                  return ((LabelWidget) widget).getLabel ();
              }
              public void setText (Widget widget, String text) {
                  ((LabelWidget) widget).setLabel (text);
              }
          }
      ), EnumSet.<InplaceEditorProvider.ExpansionDirection>of (InplaceEditorProvider.ExpansionDirection.RIGHT));
      scene.addChild (label);

  ## Level of Details

  The `LevelOfDetailsWidget` allows level-of-details feature based on 4 following parameters: hardMinimalZoom, softMinimalZoom, softMaximalZoom, hardMaximalZoom.

  Following table describes whether children widgets of the `LevelOfDetailsWidget` are visible or not - based on the zoom factor of a scene:

  zoom factor | hardMinimalZoom or less | between | softMinimalZoom to softMaximalZoom | between | hardMaximalZoom or more
  children are | invisible | partly visible | visible | partly visible | invisible

  The partial visibility is done by alpha blending.

  ## Look and Feel

  The library contains a preliminary look&feel support defined by `LookFeel` abstract class. Almost every method is dependent on `ObjectState` parameter. Usually the interface should be used in `Widget.notifyStateChanged` method implementation. The `Scene.getLookFeel` and `Scene.setLookFeel` methods allows manipulation with a look&feel assigned to a scene. The default `LookFeel` implementation can be obtained using `LookFeel.createDefaultLookFeel` method.

  There is also an InputBindings class which is assigned to a scene. It allows to manage action-related scene options e.g. `InputEvent` modifier of zoom actions used in the scene.

  ## Animator

  The library supports various 500ms-long animations. The animations are available on `SceneAnimator` class acquired by `Scene.getSceneAnimator` method call.

  Supported animations:

  - preferredLocation
  - preferredBounds
  - zoomFactor
  - backgroundColor
  - foregroundColor

  ### SceneAnimator Methods

  Method | Description
  --- | ---
  getScene | Returns a related scene instance.
  isAnimatingPreferredLocation (Widget) | Checks whether preferredLocation property of the widget is animated.
  animatePreferredLocation (Widget, Point targetLocation) | Starts preferredLocation animation for the widget.
  isAnimatingPreferredBounds (Widget) | Checks whether preferredBounds property of the widget is animated.
  animatePreferredBounds (Widget, Rectangle targetBounds) | Starts preferredBounds animation for the widget.
  isAnimatingZoomFactor () | Checks whether the zoomFactor property is animated.
  animateZoomFactor (double targetZoomFactor) | Starts zoomFactor animation.
  getTargetZoomFactor () | Returns a target zoom factor of animation.
  isAnimatingBackgroundColor (Widget) | Checks whether backgroundColor property of the widget is animated.
  animateBackgroundColor (Widget, Color targetBackgroundColor) | Starts backgroundColor animation for the widget.
  isAnimatingForegroundColor (Widget) | Checks whether foregroundColor property of the widget is animated.
  animateForegroundColor (Widget, Color targetForegroundColor) | Starts foregroundColor animation for the widget.
  getPreferredLocationAnimator | Returns the preferred location animator which controls animation of preferred location of all widgets in the scene.
  getPreferredBoundsAnimator | Returns the preferred bounds animator which controls animation of preferred bounds of all widgets in the scene.
  getZoomAnimator | Returns the zoom animator of the scene.
  getColorAnimator | Returns the color animator which controls backgorund and foreground animation of all widgets in the scene.

  Each animation is done by an `Animator` interface implementation. The `Animator` allows to listen to important events of an animator started, finished, reset, pre-tick and post-tick events using `AnimatorListener` interface. Instances of built-in animators can be obtained using getters of the `SceneAnimator` class.

  ### Example: Animator

  Following code sets a widget to `[100,100]` without animation and smoothly moves the widget to `[300,300]`.

      Scene scene = new Scene ();
      LayerWidget layer = new LayerWidget (scene);
      scene.addChild (layer);

      LabelWidget label = new LabelWidget (scene, "Label");
      layer.addChild (label);

      // non-animated move
      label.setPreferredLocation (new Point (100, 100));

      // animated move
      scene.getSceneAnimator ().animatePreferredLocation (label, new Point (300, 300));

  ## Custom Development

  The library can be extended on various places.

  ### Custom Widget

  A custom widget can be created by extending `Widget` class. For proper work you have to implement at least:

  - `calculateClientArea` method for resolving client-area (widget boundary without border insets) required by the widget itself. `Graphics2D` instance can be acquired by `getGraphics` method.
  - `paintWidget` method for painting the widget. `Graphics2D` instance can be acquired by `getGraphics` method with local coordination system - means: the `[0,0]` of the instance corresponds to `[0,0]` of the `Widget.getBounds`.
  - optionally `notifyStateChanged` method for specifying widget-state related UI.

  ### Example: CircleWidget

  Following example create a new custom widget that renders a circle:

      public class CircleWidget extends Widget {
          private int r;
          public CustomWidgetTest (Scene scene, int radius) {
              super (scene);
              r = radius;
          }
          protected Rectangle calculateClientArea () {
              return new Rectangle (- r, - r, 2 * r + 1, 2 * r + 1);
          }
          protected void paintWidget () {
              Graphics2D g = getGraphics ();
              g.setColor (getForeground ());
              g.drawOval (- r, - r, 2 * r, 2 * r);
          }
      }

  See that the `CircleWidget.paint` is not using `getLocation()` method since the graphics is automatically translated to a point where the [0,0] means the origin of the widget. Therefore the drawing area reserved for the widget is exactly the same as the one returned from the `CircleWidget.calculateClientArea`.

  ### Custom Action

  Custom action can be created by implementing `WidgetAction` interface. There is a `WidgetAction.Adapter` class similar to Swing adapters - all methods return `State.REJECTED` status.

  There is a `WidgetAction.LockedAction` abstract class. There all methods return `State.createLocked (widget, this)` or `State.REJECTED` depending on the result of `isLocked` abstract method call. This is used by actions which requires to lock the event processing for themselves - e.g. MoveAction, ConnectAction, ...

  ### Custom Layout

  Custom layout can be created by implementing `Layout` interface.

  The `layout (widget)` method should implement layout algorithm of children of the widget. It has to calculate the children boundaries based on `childWidget.getPreferredLocation` and `childWidget.getPreferredBounds` methods and optional constraints. Do not use values from `Widget.getLocation` and `Widget.getBounds` methods because there are not resolved yet. At the end it has to set evaluated children locations and bounds using `Widget.resolveBounds` methods.

  The `justify (widget)` method should implement justification of children of the widget. It has to justify location and boundary of the children based the specified Widget boundary. Now you can use theWidget.getBounds method because the widget is resolved already. Justification is invoked only when `requiresJustification` method returns `true`. This method is called after calling `layout` method.

  ### Custom Border

  Custom border can be created by implementing `Border` interface. Border insets are added to the client-area of a widget where the border is assigned. `paint` method has to paint the borders within the specified boundary. If `isOpaque` returns `true` then the border is responsible for painting every single pixel of the area specified by insets. Also only widget client-area will be painted by background paint. If `isOpaque` returns false then whole widget boundary will be painted by background paint (if the widget is opaque also) first and then the border will be called for painting.

  ### Custom Anchor

  Custom anchor can be created by implementing `Anchor` abstract class. `compute` method is responsible for computing the actual location of an anchor for the specified `ConnectionWidget`. For computation, you can use all widget properties (including getLocation and getBounds) and `Anchor.getOppositeSceneLocation` method. You have to return a `Result` object that specifies the computed anchor location and the supported directions for orthogonal routing.

  For connection widget there are also `AnchorShape` and `PointShape` interfaces that can be implemented and used for defining a shape of anchor and control points of a connection widget.

  AnchorShape.getCutDistance method allows you to specify how far a line path of a connection should be cut. This is e.g. important for a hollow triangle shape. It requires that a line is not painted to the target point. It requires to paint it just to the edge to the triangle.

  ### Custom Animator

  Custom animator could be implemented by extending `Animator` class. For creating an instance you need a `SceneAnimator` instance which can be acquired by calling `Scene.getSceneAnimator` method. For starting an animation, you have to call `start` method. For checking whether the animation is still running, call `isRunning` method. The animation algorithm has to be implemented in `tick (double progress)` method. The `progress` parameter value is in <0.0,1.0> interval where 0.0 is start (time=0ms) and 1.0 is end (time=500ms).

  ### Custom Router

  Custom router could be implemented by implementing `Router` interface. It has `routeConnection` method that is called for performing the routing. The routing could be done based on various information - usually based on:

  - `connectionWidget.getSourceAnchor ().compute(connectionWidget.getSourceAnchorEntry ()).getAnchorSceneLocation ()`
  - `connectionWidget.getTargetAnchor ().compute(connectionWidget.getTargetAnchorEntry ()).getAnchorSceneLocation ()`
  - optionally by location and bounds of widgets in scene e.g. in case of object collision detection.

  ### Custom Graph-oriented Layout

  A custom graph-oriented could be implemented by extending `GraphLayout` abstract class. The particular algorithms should be implemented in the `performGraphLayout` method which is invoked from layoutGraph methods only. The `performGraphLayout` takes a single parameter of an universal graph on which the layout should be performed.

  The node location is set using `GraphLayout.setResolvedNodeLocation(UniversalGraph graph, Node node, Point newLocation)` method. This method sets/animates node to a new location and invokes callback on all registered listeners.

  Following example should how to implement setting of a resolve location to a particular node:

      UniversalGraph<MyNode,?> graph = ...; // the graph from the "performGraphLayout" method
      MyNode node = ...;
      Point resolvedNodeLocation = ...;
      setResolvedNodeLocation (graph, node, resolvedNodeLocation); // performs the setting

  ## General Widgets

  All general-purpose widgets are located in api.widget.general package.

  ### IconNodeWidget

  The `IconNodeWidget` class represents an image with a label. It has a specific look defined in the notifyStateChanged method. You can specify the alignment (horizontal or vertical) of the image and the label. It is using a vertical/horizontal flow layout. You can set an image and a label using `setImage` and `setLabel` method. You can obtain the image and the label widgets using `getImageWidget` and `getLabelWidget` methods. This could be used for adding actions to the particular parts like InplaceEditor to the label.

  ### ListWidget

  This is an experimental widget which is not included into the public API packages. If you want to use them you have to set up an implementation dependency on org.netbeans.api.visual. Implementation dependency means that you have available all classes in the library. The `ListWidget` is included in `org.netbeans.modules.visual.experimental.widget.general` package. Please, do not use implementation dependency. If you need to use it, then use it only for classes in `org.netbeans.modules.visual.experimental` package or below.

  The `ListWidget` class represents a list and can hold multiple `ListItemWidget`s. This class is not stabilized yet and could be changed in the future.

  ## VMD plug-in

  The VMD plug-in used by the Visual Mobile Designer in NetBeans Mobility Pack. The package contains complex UI implementation for visualization of graphs using node, pin and edge objects. The plug-in is placed in vmd package. The API of this package is not stable and could be changed in the future.

  The scene is held by `VMDGraphScene` class. A node is represented by `VMDNodeWidget`. An edge is represented by `ConnectionWidget`. A pin is represented by `VMDPinWidget`.

  `VMDGraphScene` contains 4 layers: background (for rectangular selection), main (for nodes and pins), connection (for edges), interaction (for interaction like ConnectAction). VMDNodeWidget has nodeName, nodeType, nodeImage and glyphs properties. `VMDPinWidget` has pinName and glyphs properties. An edge is using OrthogonalSearchRouter and tries to not overlap valid objects in main and connection layers. Pin could be added to a node using `attachPinWidget` only, otherwise they are not registered correctly - do not use `VMDNodeWidget.addChild` method.

  The `VMDNodeWidget` allows to specify the order and categories of pins shown in the list. It is done using `VMDNodeWidget.sort` method. By default there are no categories and pins are sorted in the order where the have been attached to the node using `VMDNodeWidget.attachPinWidget`.

  The `VMDGraphScene.layoutGraph` method layouts nodes on a scene using `GridGraphLayout` class. After calling the method, you have to call `Scene.validate` method manually to trigger the scene validation and therefore graph-oriented layout of a scene.

  The VMDColorScheme class defines a UI of VMD widgets. There are two implementations available using `VMDFactory.createOriginalColorScheme`, `VMDFactory.createNetBeans60ColorScheme` method calls. The color scheme can be used as a parameter in widget constructors.

  ### Minimize Ability

  Question: Common problem of visualization is: What to do, when a scene become a little bit complicated because of many objects and connections between them?
  Answer: The answer is simple: Reduce the complexity, hide unimportant and expose important objects.

  A pattern for implementing this behavior is described in `test.expand` package in examples module. It just adds all the widgets that should be expanded/collapsed into a widget. When the details widget has to be collapsed, then set its `preferredBounds` property to `new Rectangle()`. When it has to be expanded, then set its `preferredBounds` property to `null`.

  `VMDNodeWidget` has ability to control minimize mode using `isMinimized`, `setMinimized` and `toogleMinimized` methods. When a node is minimized then the header is shown only and all pins are hidden.

  When an edge is attach to a pin and the node is going to be minimized, the pin is going to hidden and therefore the anchor of the pin has to be reattached to the anchor of the node. This is done automatically when you will:

  - Create an anchor for a pin widget.
  - Call `VMDNodeWidget.createAnchorPin (Anchor)` on an appropriate instance of node widget.
  - Use the returned anchor while setting an appropriate source and target of a connection widget.

  The `createAnchorPin` creates a proxy anchor that is driven by a minimized state of the node and automatically switches/uses the node or the pin anchor as the active anchor.

  ## Printing and Exporting Scene

  There is `Scene.paint (Graphics2D)` method that renders the scene into the specified `Graphics2D` instance. The instance could be taken from any device e.g. screen, printer, `BufferedImage`, PDF file writer, ...

  Be aware that it is completely different `Graphics2D` instance than the instance which is used for rendering the scene into the main view and which is used for calculating the scene (especially `FontMetrics`). Therefore fonts could be "broken", so they will not fit exactly as in the main view.

  ### Export to PNG

  Following code shows how to export the scene into PNG file.

      Scene scene = ...;

      BufferedImage bi = new BufferedImage (dim.width, dim.height, BufferedImage.TYPE_4BYTE_ABGR);
      Graphics2D graphics = bi.createGraphics ();
      scene.paint (graphics);
      graphics.dispose ();

      JFileChooser chooser = new JFileChooser ();
      chooser.setDialogTitle ("Export Scene As ..."));
      chooser.setDialogType (JFileChooser.SAVE_DIALOG);
      chooser.setMultiSelectionEnabled (false);
      chooser.setFileSelectionMode (JFileChooser.FILES_ONLY);
      chooser.setFileFilter (new FileFilter() {
          public boolean accept (File file) {
              if (file.isDirectory ())
              return true;
              return file.getName ().toLowerCase ().endsWith (".png"); // NOI18N
          }
          public String getDescription () {
              return "Portable Network Graphics (.png)"; // NOI18N
          }
      });
      if (chooser.showSaveDialog (view) != JFileChooser.APPROVE_OPTION)
          return;

      File file = chooser.getSelectedFile ();
      if (! file.getName ().toLowerCase ().endsWith (".png")) // NOI18N
          file = new File (file.getParentFile (), file.getName () + ".png"); // NOI18N
      if (file.exists ()) {
          DialogDescriptor descriptor = new DialogDescriptor (
                  "File (" + file.getAbsolutePath () + ") already exists. Do you want to overwrite it?",
                  "File Exists", true, DialogDescriptor.YES_NO_OPTION, DialogDescriptor.NO_OPTION, null);
          DialogDisplayer.getDefault ().createDialog (descriptor).setVisible (true);
          if (descriptor.getValue () != DialogDescriptor.YES_OPTION)
              return;
      }

      try {
          ImageIO.write (bi, "png", file); // NOI18N
      } catch (IOException e) {
          ErrorManager.getDefault ().notify (e);
      }

  ### Exporting without Offscreen Buffer

  The previous code uses a BufferedImage for storing the image in the memory. When the scene is big, it could happen that the image does not fit into the memory. Therefore you have to use your `Graphics2D` instance and `Scene.paint (Graphics2D)` method for exporting the scene on-the-fly e.g. PDF writer, SVG file writer or meta graphics file writer.

  ## Effects

  ### Convolution

  The library contains `ConvolveWidget` which takes a `ConvolveOp` parameter and uses it for processing its children. Therefore you can create effects like blur or drop-shadow.

  The `ConvolveWidget` is using `BufferedImage` as a off-screen image where the children widgets are rendered first and then the image is rendered to the scene. Because of the off-screen image it can significantly increase memory consumption. It reallocates the off-screen image only when the image is not able to contain all children. You can free the off-screen image manually using `ConvolveWidget.clearCache` method.

  The widget automatically assigns an `EmptyBorder` with appropriate size based on the size of kernel on ConvolveOp parameter.

  ### Antialiasing

  There is no API for enabling antialiasing. Anyway it can be implemented by overriding `Scene.paintChildren` method. See following code.

      class MyScene extends Scene {
          public void paintChildren () {
              Object anti = getGraphics ().getRenderingHint (RenderingHints.KEY_ANTIALIASING);
              Object textAnti = getGraphics ().getRenderingHint (RenderingHints.KEY_TEXT_ANTIALIASING);

              getGraphics ().setRenderingHint (
                      RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
              getGraphics ().setRenderingHint (
                      RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

              super.paintChildren ();

              getGraphics ().setRenderingHint (RenderingHints.KEY_ANTIALIASING, anti);
              getGraphics ().setRenderingHint (RenderingHints.KEY_TEXT_ANTIALIASING, textAnti);
          }
      }

  The same could be done for any class derived from a Widget class too.

  ## Serialization

  By default there is not (de)serialization support because the library cannot know which data should be serialized. Especially when you are integrating the library with an external data-model.

  For example: During serialization of external data-model, the external model is created from the data in the XML file. Then you are able recreate almost whole scene. Usually the only missing thing is locations of nodes and control-points of edges (in graph-oriented model). In this case these locations are the only serialized data related to the library.

  On the other hand, when users are using `GraphScene` as the only/main model in the application then they would like to store whole the scene. Also the serialization format is various - XML, JavaBinarySerialization, ...

  It is hard to create, reused or integrate universal description language for it. Instead, there is no support for serialization in the library and has to be done by developer.

  ### Example: Nodes Location Serialization

  Following code is (de)serializing a scene. This is usually used when you have an external model and you are using GraphPinScene for holding visual data. The most of the visual data can be recreated from an external model. The only stored data are locations of nodes.

      public class SceneDataSerializer {

          private static final String SCENE_NODE = "Scene"; // NOI18N
          private static final String VERSION_ATTR = "version"; // NOI18N
          private static final String NODE_NODE = "Node"; // NOI18N
          private static final String NODEID_ATTR = "nodeID"; // NOI18N
          private static final String X_NODE = "x"; // NOI18N
          private static final String Y_NODE = "y"; // NOI18N

          private static final String VERSION_VALUE_1 = "1"; // NOI18N

          // creates an sceneXMLNode that has to be placed to the XML file then
          public Node serializeData (GraphPinScene<String, String, String> scene, Document file) {
              Node sceneXMLNode = file.createElement (SCENE_NODE);
              setAttribute (file, sceneXMLNode, VERSION_ATTR, VERSION_VALUE_1); // NOI18N

              for (String node : scene.getNodes ()) {
                      Widget widget = scene.findWidget (node);
                      if (widget != null) {
                          Point location = widget.getPreferredLocation ();
                          if (location != null) {
                              Node dataXMLNode = file.createElement (NODE_NODE);
                              setAttribute (file, dataXMLNode, NODEID_ATTR, node);
                              setAttribute (file, dataXMLNode, X_NODE, Integer.toString (location.x));
                              setAttribute (file, dataXMLNode, Y_NODE, Integer.toString (location.y));
                              node.appendChild (dataXMLNode);
                          }
                      }
                  }
              }

              return node;
          }

          // Returns true if deserialization is successfull
          // sceneXMLNode has to be found in the XML file first
          public boolean deserializeData (final GraphPinScene<String, String, String> scene, final Node sceneXMLNode) {
              if (! VERSION_VALUE_1.equals (getAttributeValue (data, VERSION_ATTR)))
                  return false;

              SwingUtilities.invokeLater (new Runnable() {
                  public void run () {
                      deserializeDataVersion1 (scene, sceneXMLNode);
                      scene.validate ();
                  }
              });

              return true;
          }

          private void deserializeDataVersion1 (GraphPinScene<String, String, String> scene, Node data) {
              for (Node node : getChildNode (data)) {
                  if (NODE_NODE.equals (node.getNodeName ())) {
                      String nodeID = getAttributeValue (node, NODEID_ATTR));
                      int x = Integer.parseInt (getAttributeValue (node, X_NODE));
                      int y = Integer.parseInt (getAttributeValue (node, Y_NODE));
                      Widget widget = scene.findWidget (nodeID);
                      if (widget != null)
                          widget.setPreferredLocation (new Point (x, y));
                  }
              }
          }

          private static String getAttributeValue (Node node, String attr) {
              try {
                  if (node != null) {
                      NamedNodeMap map = node.getAttributes ();
                      if (map != null) {
                          node = map.getNamedItem (attr);
                          if (node != null)
                              return node.getNodeValue ();
                      }
                  }
              } catch (DOMException e) {
                  Debug.warning (e);
              }
              return null;
          }

          private static void setAttribute (Document xml, Node node, String name, String value) {
              NamedNodeMap map = node.getAttributes ();
              Attr attribute = xml.createAttribute (name);
              attribute.setValue (value);
              map.setNamedItem (attribute);
          }

          private static Node[] getChildNode (Node node) {
              NodeList childNodes = node.getChildNodes ();
              Node[] nodes = new Node[childNodes != null ? childNodes.getLength () : 0];
              for (int i = 0; i < nodes.length; i++)
                  nodes[i] = childNodes.item (i);
              return nodes;
          }

      }

  ## Visual Library vs. Swing

  Object / Feature / Method
  Swing | Visual Library
  --- | ---
  JComponent | Widget
  JDialog, JFrame | Scene
  EventListener | WidgetAction

  ## Notes

  For preventing deadlocks, use AWT-thread when manipulating with the library structures.

  If you have any comments, suggestions, or missing feature or documentation, please, send an email to users@graph.netbeans.org.