Continuation from yesterday's blog entry, with a more relevant sample, based on applications I've seen on the NetBeans Platform. It is very common to want to let the user click in a window causing a dialog to be displayed followed by a widget being created, with properties and the possibility of being connected to each other (via Ctrl plus left mousebutton movement):

To achieve the above, create a new module, use the Window component wizard to create a new window, with "ToolVisualizer" as the class name prefix, set dependencies on the Visual Library, Nodes API, and the Dialogs API, and then paste the code below into the TopComponent:private final Scene scene;private final LayerWidget layer;private final LayerWidget connectionLayer;//Constructor:public ToolVisualizerTopComponent() { initComponents(); ... ... ... scene = new Scene(); layer = new LayerWidget(scene); connectionLayer = new LayerWidget(scene); scene.addChild(layer); scene.addChild(connectionLayer); scene.getActions().addAction(ActionFactory.createS electAction(new SelectProvider() { @Override public boolean isAimingAllowed(Widget widget, Point point, boolean bln) { return true; } @Override public boolean isSelectionAllowed(Widget widget, Point point, boolean bln) { return true; } @Override public void select(Widget widget, Point point, boolean bln) { NotifyDescriptor.InputLine desc = new NotifyDescriptor.InputLine("Name:", "Set a Name"); DialogDisplayer.getDefault().notify(desc); Shape shape = new Shape(desc.getInputText(), new Date()); ShapeWidget tw = new ShapeWidget(scene, point, shape); layer.addChild(tw); scene.repaint(); scene.validate(); } })); jScrollPane1.setViewportView(scene.createView());} class Shape { String type; Date date; public Shape(String type, Date date) { this.type = type; this.date = date; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getType() { return type; } public void setType(String type) { this.type = type; }}class ShapeWidget extends IconNodeWidget { public ShapeWidget(Scene scene, Point loc, final Shape shape) { super(scene); setPreferredLocation(loc); setLabel(shape.getType()); setImage(ImageUtilities.loadImage("org/vislib/scene/circlered.png", true)); getActions().addAction(ActionFactory.createExtende dConnectAction(connectionLayer, new MyConnectProvider())); getActions().addAction(ActionFactory.createMoveAct ion()); getActions().addAction(ActionFactory.createPopupMe nuAction(new PopupMenuProvider() { @Override public JPopupMenu getPopupMenu(final Widget widget, Point localLocation) { JPopupMenu popup = new JPopupMenu(); JMenuItem propsMenu = new JMenuItem("Properties"); propsMenu.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { AbstractNode node = new AbstractNode(Children.LEAF) { @Override protected Sheet createSheet() { Sheet sheet = super.createSheet(); Set set = sheet.createPropertiesSet(); set.put(new TypeProperty(shape)); set.put(new DateProperty(shape)); sheet.put(set); return sheet; } }; node.setDisplayName(shape.getType()); node.setShortDescription("Description of " + shape.getType()); NodeOperation.getDefault().showProperties(node); } }); popup.add(propsMenu); return popup; } })); }}private static class TypeProperty extends PropertySupport.ReadOnly { private final Shape shape; public TypeProperty(Shape shape) { super("shapeType", String.class, "Type", "Displays shape type"); this.shape = shape; } @Override public String getValue() throws IllegalAccessException, InvocationTargetException { return shape.getType(); }}private static class DateProperty extends PropertySupport.ReadOnly { private final Shape shape; public DateProperty(Shape shape) { super("shapeDate", Date.class, "Date", "Displays shape date"); this.shape = shape; } @Override public Date getValue() throws IllegalAccessException, InvocationTargetException { return shape.getDate(); }}private class MyConnectProvider implements ConnectProvider { public boolean isSourceWidget(Widget source) { return source instanceof IconNodeWidget && source != null ? true : false; } public ConnectorState isTargetWidget(Widget src, Widget trg) { return src != trg && trg instanceof IconNodeWidget ? ConnectorState.ACCEPT : ConnectorState.REJECT; } public boolean hasCustomTargetWidgetResolver(Scene arg0) { return false; } public Widget resolveTargetWidget(Scene arg0, Point arg1) { return null; } public void createConnection(Widget source, Widget target) { ConnectionWidget conn = new ConnectionWidget(scene); conn.setTargetAnchorShape(AnchorShape.TRIANGLE_FIL LED); conn.setTargetAnchor(AnchorFactory.createRectangul arAnchor(target)); conn.setSourceAnchor(AnchorFactory.createRectangul arAnchor(source)); connectionLayer.addChild(conn); }}
That's all, now you can display the properties of the current widget and you're also able to connect widgets to each other.


Read More about [Connecting Shapes & Showing Properties...