针对 Java 应用程序的 NetBeans 可视库教程
在本教程中,您将学习如何使用 NetBeans 可视库 API 提供的一些主要功能。
目录

要学习本教程,您需要具备下表中列出的软件和资源。
| 软件或资源 | 要求的版本 |
|---|---|
| NetBeans IDE | 6.7 或更高版本 |
| Java Developer Kit (JDK) | 版本 6 或 版本 5 |
此外,您还将在本教程中使用以下 3 个图标。您可以在此处右键单击这些图标并将它们保存到本地,在本教程后面部分创建应用程序后,再将它们复制到应用程序中的相应位置。下面便是这 3 个图标:
设置应用程序
在此部分,我们将使用向导创建一个 Java 应用程序。
- 选择“文件”>“新建项目”(Ctrl+Shift+N)。在“类别”下选择 "Java"。在“项目”下,选择“Java 应用程序”。单击“下一步”。
- 在“名称和位置”面板的“项目名称”字段中键入 VisLibDemo:
单击“完成”。
IDE 即会创建 VisLibDemo 项目。将上面的三张图像添加到主包中。现在,您应看到如下所示的内容:
添加库
在此部分,我们将添加您使用可视库所需的两个库。
- 右键单击“库”节点,然后选择“添加 JAR/文件夹”。
- 浏览到 NetBeans IDE 安装目录。
- 在 platform9/lib 中,选择 org-openide-util.jar。
- 在 platform9/modules 中,选择 org-netbeans-api-visual.jar。
您现在只有两个所需的 JAR。现在,您应看到如下所示的内容:
创建容器
在此部分,我们将创建一个容器,该容器将用来保存来自可视库的 Scene。
- 定义 Main.java,如下所示:
public class Main extends JPanel { //Create the JFrame: public static void main(String[] args) { JFrame frame = new JFrame("Graph test"); frame.setMinimumSize(new Dimension(500, 400)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(new Main()); frame.pack(); frame.setVisible(true); } public Main() { initComponents(); } private void initComponents() { //Set the layout: setLayout(new BorderLayout()); //Create a JScrollPane: JScrollPane scrollPane = new JScrollPane(); //Add the JScrollPane to the JPanel: add(scrollPane, BorderLayout.CENTER); } } - 运行应用程序,您应看到一个简单的 JFrame:
现在您有了一个 JScrollPane,可以创建场景了!
创建小部件
在此部分,我们将创建一个包含场景的单独的类。然后将其关联到我们的 JPanel。
- 创建一个名为 GraphSceneImpl.java 的新类。
- 使其扩展 GraphScene<String, String>。
- 使用 IDE 一侧的灯泡图标添加 import 语句和抽象方法。现在,您应看到如下所示的内容:
package vislibdemo; import org.netbeans.api.visual.graph.GraphScene; import org.netbeans.api.visual.widget.Widget; public class GraphSceneImpl extends GraphScene<String, String> { @Override protected Widget attachNodeWidget(String arg0) { throw new UnsupportedOperationException("Not supported yet."); } @Override protected Widget attachEdgeWidget(String arg0) { throw new UnsupportedOperationException("Not supported yet."); } @Override protected void attachEdgeSourceAnchor(String arg0, String arg1, String arg2) { throw new UnsupportedOperationException("Not supported yet."); } @Override protected void attachEdgeTargetAnchor(String arg0, String arg1, String arg2) { throw new UnsupportedOperationException("Not supported yet."); } } - 我们将使用三个 LayerWidget,类似于 Swing 中的 JGlassPane。在类的顶部对其进行声明:
private LayerWidget mainLayer; private LayerWidget connectionLayer; private LayerWidget interactionLayer;
- 创建一个构造函数,初始化您的 LayerWidget 并将它们添加到 Scene 中:
public GraphSceneImpl() { mainLayer = new LayerWidget(this); connectionLayer = new LayerWidget(this); interactionLayer = new LayerWidget(this); addChild(mainLayer); addChild(connectionLayer); addChild(interactionLayer); } - 接下来,定义创建新的小部件时发生的情况:
@Override protected Widget attachNodeWidget(String arg) { IconNodeWidget widget = new IconNodeWidget(this); if (arg.startsWith("1")) { widget.setImage(ImageUtilities.loadImage("vislibdemo/red.gif")); } else if (arg.startsWith("2")) { widget.setImage(ImageUtilities.loadImage("vislibdemo/green.gif")); } else { widget.setImage(ImageUtilities.loadImage("vislibdemo/blue.gif")); } widget.setLabel(arg); mainLayer.addChild(widget); return widget; }在场景中调用 addNode 时,即会触发以上语句。
- 在构造函数末尾,触发上面的方法 4 次:
Widget w1 = addNode("1. Hammer"); w1.setPreferredLocation(new Point(10, 100)); Widget w2 = addNode("2. Saw"); w2.setPreferredLocation(new Point(100, 250)); Widget w3 = addNode("Nail"); w3.setPreferredLocation(new Point(250, 250)); Widget w4 = addNode("Bolt"); w4.setPreferredLocation(new Point(250, 350));在以上代码中,您创建了四个小部件,传递了一个字符串并且设置了小部件的位置。现在,触发上一步骤中定义的 attachNodeWidget 方法。attachNodeWidget 中的 arg 参数是您传递到 addNode 的字符串。因此,此字符串将会设置小部件的标签。然后,会将该小部件添加到 mainLayer 中。
- 返回到 Main.java 类,将下面以粗体显示的行添加到 initComponents 方法中:
private void initComponents() { //Set the layout: setLayout(new BorderLayout()); //Create a JScrollPane: JScrollPane scrollPane = new JScrollPane(); //Add the JScrollPane to the JPanel: add(scrollPane, BorderLayout.CENTER); //Create the GraphSceneImpl: GraphScene scene = new GraphSceneImpl(); //Add it to the JScrollPane: scrollPane.setViewportView(scene.createView()); //Add the SatellitView to the scene: add(scene.createSatelliteView(), BorderLayout.WEST); } - 运行应用程序,您应看到如下所示的内容:
现在您有了一个包含一些小部件的场景,我们可以开始集成一些操作了!
启用操作
在此部分,我们将在之前创建的小部件上启用一些操作。
- 通过添加下面以粗体显示的行来更改 attachNodeWidget:
@Override protected Widget attachNodeWidget(String arg) { IconNodeWidget widget = new IconNodeWidget(this); if (arg.startsWith("1")) { widget.setImage(ImageUtilities.loadImage("vislibdemo/red.gif")); } else if (arg.startsWith("2")) { widget.setImage(ImageUtilities.loadImage("vislibdemo/green.gif")); } else { widget.setImage(ImageUtilities.loadImage("vislibdemo/blue.gif")); } widget.getActions().addAction( ActionFactory.createAlignWithMoveAction( mainLayer, interactionLayer, ActionFactory.createDefaultAlignWithMoveDecorator())); widget.setLabel(arg); mainLayer.addChild(widget); return widget; } - 运行应用程序。拖动小部件,请注意,将出现对齐标记,它们可帮助用户将小部件放置到与其他小部件相对的位置。
- 通过在构造函数末尾添加以下行来更改 GraphSceneImpl 类:
getActions().addAction(ActionFactory.createZoomAction());
- 运行应用程序。滚动鼠标滚轮或执行任何操作系统规定的“缩放”操作,注意整个场景将会放大/缩小。
- 在 GraphSceneImpl 末尾添加一个定制的 ConnectProvider:
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(GraphSceneImpl.this); conn.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED); conn.setTargetAnchor(AnchorFactory.createRectangularAnchor(target)); conn.setSourceAnchor(AnchorFactory.createRectangularAnchor(source)); connectionLayer.addChild(conn); } }将定制的 ConnectProvider 关联到小部件,如下所示:
@Override protected Widget attachNodeWidget(String arg0) { IconNodeWidget widget = new IconNodeWidget(this); if (arg0.startsWith("1")) { widget.setImage(ImageUtilities.loadImage("vislibdemo/red.gif")); } else if (arg0.startsWith("2")) { widget.setImage(ImageUtilities.loadImage("vislibdemo/green.gif")); } else { widget.setImage(ImageUtilities.loadImage("vislibdemo/blue.gif")); } widget.getActions().addAction( ActionFactory.createExtendedConnectAction( connectionLayer, new MyConnectProvider())); widget.getActions().addAction( ActionFactory.createAlignWithMoveAction( mainLayer, interactionLayer, ActionFactory.createDefaultAlignWithMoveDecorator())); widget.setLabel(arg0); mainLayer.addChild(widget); return widget; } - 运行应用程序,选择一个小部件并按住 Ctrl 键,然后拖动鼠标至另一个小部件。这样即可将小部件彼此相连,如下所示:
现在您对可视库 API 提供的功能已经有了一个基本的了解,请参见 NetBeans 平台学习资源中的“用于可视化数据的 NetBeans API”部分。
