Sunday, August 15, 2010

Connecting Shapes & Showing Properties

By: Geertjan Wielenga | Product Manager
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.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.

Join the discussion

Comments ( 7 )
  • Jay Bennie Sunday, August 15, 2010

    Hi The theme/coloring on these forms how was it acheived? thx


  • Kamal Monday, August 16, 2010

    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


  • guest Thursday, June 23, 2011

    Thanks for this very informative tutorial.

    Of note, on the Mac, I have to use CTRL + OPTION + LEFT-CLICK to make a connection.


  • CT Friday, March 1, 2013

    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


  • Fery Wednesday, March 12, 2014

    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


  • Geertjan Wednesday, March 12, 2014

    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.


  • guest Wednesday, March 19, 2014

    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


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
 

Visit the Oracle Blog

 

Contact Us

Oracle

Integrated Cloud Applications & Platform Services