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.createSelectAction(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.createExtendedConnectAction(connectionLayer, new MyConnectProvider()));
getActions().addAction(ActionFactory.createMoveAction());
getActions().addAction(ActionFactory.createPopupMenuAction(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_FILLED);
conn.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
conn.setSourceAnchor(AnchorFactory.createRectangularAnchor(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.
Hi The theme/coloring on these forms how was it acheived? thx
Hi,
I am a java programer, but when I read thses tutorial I found myself ignorant, I did not understand anything, what java version is this ? is there any tutorial on how to write these things ? can you plz put the whole code so I can run it in netbaens.
thanks, your help is appreciated
Thanks for this very informative tutorial.
Of note, on the Mac, I have to use CTRL + OPTION + LEFT-CLICK to make a connection.
Hi,
May I know is that possible for me to do the same thing on the connector?
I want to show properties of the line/connector too.
How?
Thanks
Hi Geertjan,
I am newbie in netbeans platform development, but I very interest to create an application on top of it.
Based on this tutorial/example,
Currently I have some issue about how to make the properties sheet automatically show in the properties when I select (one click) on the icon
without need to create some popup properties windows.
What should i do to make this happen?
Thanks
Feriyanto
Not sure I understand -- I advise that you purchase https://leanpub.com/nbp4beginners and let the authors know about any scenarios that are missing from the book so they can cover it in the next release of it.
Hi Geertjan,
Sorry for my unclear question.
I follow this tutorial to create some workflow
https://platform.netbeans.org/tutorials/nbm-visual_library.html
My issue is how to show the properties of IconNodeWidget not in the popup Properties, but in the propertySheetWindow when the icon is selected.
I just follow the tutorial
https://platform.netbeans.org/tutorials/nbm-nodesapi2.html to learn how the properties used and still not success.
I'am implement TopComponent with ExplorerManager.Provider, and extends node with AbstractNode but the behaviour between Node and IconNodeWidget is quite different.
Please show me what i have to use?Did i do the right thing?
Thanks for your help and info.
Feri