| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml"> |
| <head> |
| <!-- -*- xhtml -*- --> |
| <title>针对 Java 应用程序的 NetBeans 可视库教程</title> |
| <link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <meta name="AUDIENCE" content="NBUSER"> |
| <meta name="TYPE" content="ARTICLE"> |
| <meta name="EXPIRES" content="N"> |
| <meta name="developer" content="geertjan.wielenga@sun.com"> |
| <meta name="indexed" content="y"> |
| <meta name="description" |
| content="A walk-through of the basic features of the Visual Library API."> |
| <!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> |
| <!-- Use is subject to license terms.--> |
| </head> |
| |
| <body> |
| |
| <h1>针对 Java 应用程序的 NetBeans 可视库教程</h1> |
| |
| <p>在本教程中,您将学习如何使用 <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-api-visual/overview-summary.html">NetBeans 可视库 API</a> 提供的一些主要功能。 |
| |
| <p><b>目录</b></p> |
| |
| <p><img src="../images/articles/69/netbeans-stamp7-8-9.png" class="stamp" width="114" height="114" alt="本页上的内容适用于 NetBeans IDE 6.5、6.7、6.8" title="本页上的内容适用于 NetBeans IDE 6.5、6.7、6.8" /></p> |
| <ul class="toc"> |
| <li><a href="#getting-started">设置应用程序</a> |
| <li><a href="#add">添加库</a> |
| <li><a href="#widget">创建小部件</a> |
| <li><a href="#action">启用操作</a> |
| </ul> |
| |
| <p><b>要学习本教程,您需要具备下表中列出的软件和资源。</b></p> |
| |
| <table> |
| <tbody> |
| <tr> |
| <th class="tblheader" scope="col">软件或资源</th> |
| <th class="tblheader" scope="col">要求的版本</th> |
| </tr> |
| <tr> |
| <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td> |
| <td class="tbltd1">6.7 或更高版本</td> |
| </tr> |
| <tr> |
| <td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td> |
| <td class="tbltd1">版本 6 或<br/>版本 5</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <p>此外,您还将在本教程中使用以下 3 个图标。您可以在此处右键单击这些图标并将它们保存到本地,在本教程后面部分创建应用程序后,再将它们复制到应用程序中的相应位置。下面便是这 3 个图标: |
| |
| <p><img src="../images/tutorials/vislib/red.gif"/> |
| <img src="../images/tutorials/vislib/blue.gif"/> |
| <img src="../images/tutorials/vislib/green.gif"/> |
| |
| <!-- ===================================================================================== --> |
| |
| <p><h2><a name="set"></a>设置应用程序</h2> |
| |
| <p>在此部分,我们将使用向导创建一个 Java 应用程序。 |
| |
| |
| <ol> |
| <li>选择“文件”>“新建项目”(Ctrl+Shift+N)。在“类别”下选择 "Java"。在“项目”下,选择“Java 应用程序”。单击“下一步”。</li> |
| <li>在“名称和位置”面板的“项目名称”字段中键入 <tt>VisLibDemo</tt>: |
| <p><p><img border="1" src="../images/tutorials/vislib/vislib-java-1.png"/> |
| <p>单击“完成”。</li> |
| </ol> |
| |
| <p>IDE 即会创建 <tt>VisLibDemo</tt> 项目。将上面的三张图像添加到主包中。现在,您应看到如下所示的内容: |
| <p><img border="1" src="../images/tutorials/vislib/vislib-java-2.png"/> |
| |
| |
| |
| <p><h2><a name="add"></a>添加库</h2> |
| |
| <p>在此部分,我们将添加您使用可视库所需的两个库。 |
| |
| <ol> |
| <li>右键单击“库”节点,然后选择“添加 JAR/文件夹”。</li> |
| <li>浏览到 NetBeans IDE 安装目录。</li> |
| <li>在 <tt>platform9/lib</tt> 中,选择 <tt>org-openide-util.jar</tt>。</li> |
| <li>在 <tt>platform9/modules</tt> 中,选择 <tt>org-netbeans-api-visual.jar</tt>。</li> |
| </ol> |
| |
| <p>您现在只有两个所需的 JAR。现在,您应看到如下所示的内容: |
| <p><img border="1" src="../images/tutorials/vislib/vislib-java-3.png"/> |
| |
| <p><h2><a name="container"></a>创建容器</h2> |
| |
| <p>在此部分,我们将创建一个容器,该容器将用来保存来自可视库的 <tt>Scene</tt>。 |
| |
| <ol> |
| <li>定义 <tt>Main.java</tt>,如下所示: |
| |
| <pre class=examplecode> |
| public class Main extends JPanel { |
| |
| <b>//Create the JFrame:</b> |
| 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() { |
| <b>//Set the layout:</b> |
| setLayout(new BorderLayout()); |
| <b>//Create a JScrollPane:</b> |
| JScrollPane scrollPane = new JScrollPane(); |
| <b>//Add the JScrollPane to the JPanel:</b> |
| add(scrollPane, BorderLayout.CENTER); |
| } |
| |
| } |
| </pre> |
| |
| </li> |
| |
| <li>运行应用程序,您应看到一个简单的 JFrame: |
| |
| <p><img border="1" src="../images/tutorials/vislib/vislib-java-4.png"/> |
| |
| </li> |
| </ol> |
| |
| <p>现在您有了一个 <tt>JScrollPane</tt>,可以创建场景了! |
| |
| <p><h2><a name="widget"></a>创建小部件</h2> |
| |
| <p>在此部分,我们将创建一个包含场景的单独的类。然后将其关联到我们的 <tt>JPanel</tt>。 |
| |
| <ol> |
| <li>创建一个名为 <tt>GraphSceneImpl.java</tt> 的新类。 |
| <li>使其扩展 GraphScene<String, String>。 |
| <li>使用 IDE 一侧的灯泡图标添加 import 语句和抽象方法。现在,您应看到如下所示的内容: |
| |
| <pre class=examplecode> |
| 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."); |
| } |
| |
| } |
| </pre> |
| </li> |
| |
| <li>我们将使用三个 <tt>LayerWidget</tt>,类似于 Swing 中的 <tt>JGlassPane</tt>。在类的顶部对其进行声明: |
| <pre class=examplecode> |
| private LayerWidget mainLayer;
|
| private LayerWidget connectionLayer;
|
| private LayerWidget interactionLayer; |
| </pre> |
| </li> |
| <li>创建一个构造函数,初始化您的 <tt>LayerWidget</tt> 并将它们添加到 <tt>Scene</tt> 中: |
| |
| <pre class=examplecode> |
| public GraphSceneImpl() {
|
| mainLayer = new LayerWidget(this);
|
| connectionLayer = new LayerWidget(this);
|
| interactionLayer = new LayerWidget(this);
|
| addChild(mainLayer);
|
| addChild(connectionLayer);
|
| addChild(interactionLayer);
|
| } |
| </pre> |
| |
| <li>接下来,定义创建新的小部件时发生的情况: |
| |
| <pre class=examplecode>@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;
|
| }</pre> |
| |
| <p class="tips"> 在场景中调用 <tt>addNode</tt> 时,即会触发以上语句。 |
| |
| <p><li>在构造函数末尾,触发上面的方法 4 次: |
| |
| <pre class=examplecode> |
| 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)); |
| </pre> |
| |
| <p>在以上代码中,您创建了四个小部件,传递了一个字符串并且设置了小部件的位置。现在,触发上一步骤中定义的 <tt>attachNodeWidget</tt> 方法。<tt>attachNodeWidget</tt> 中的 <tt>arg</tt> 参数是您传递到 <tt>addNode</tt> 的字符串。因此,此字符串将会设置小部件的标签。然后,会将该小部件添加到 <tt>mainLayer</tt> 中。 |
| |
| <li>返回到 <tt>Main.java</tt> 类,将下面以粗体显示的行添加到 <tt>initComponents</tt> 方法中: |
| |
| <pre class=examplecode> |
| 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); |
| <b>//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);</b> |
| } |
| </pre> |
| |
| <li>运行应用程序,您应看到如下所示的内容: |
| |
| <p><img border="1" src="../images/tutorials/vislib/vislib-java-5.png"/> |
| |
| </ol> |
| |
| <p>现在您有了一个包含一些小部件的场景,我们可以开始集成一些操作了! |
| |
| <p><h2><a name="action"></a>启用操作</h2> |
| |
| <p>在此部分,我们将在之前创建的小部件上启用一些操作。 |
| |
| <ol> |
| <li>通过添加下面以粗体显示的行来更改 <tt>attachNodeWidget</tt>: |
| |
| <pre class=examplecode> |
| @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")); |
| } |
| <b>widget.getActions().addAction( |
| ActionFactory.createAlignWithMoveAction( |
| mainLayer, interactionLayer, |
| ActionFactory.createDefaultAlignWithMoveDecorator()));</b> |
| widget.setLabel(arg); |
| mainLayer.addChild(widget); |
| return widget; |
| } |
| </pre> |
| </li> |
| |
| <li>运行应用程序。拖动小部件,请注意,将出现对齐标记,它们可帮助用户将小部件放置到与其他小部件相对的位置。 |
| |
| <p><p><img border="1" src="../images/tutorials/vislib/vislib-java-7.png"/> |
| |
| <li>通过在构造函数末尾添加以下行来更改 <tt>GraphSceneImpl</tt> 类: |
| |
| <pre class=examplecode> |
| getActions().addAction(ActionFactory.createZoomAction()); |
| </pre> |
| </li> |
| |
| <li>运行应用程序。滚动鼠标滚轮或执行任何操作系统规定的“缩放”操作,注意整个场景将会放大/缩小。 |
| |
| <li>在 <tt>GraphSceneImpl</tt> 末尾添加一个定制的 <tt>ConnectProvider</tt>: |
| |
| <pre class=examplecode> |
| 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);
|
| }
|
|
|
| } |
| </pre> |
| |
| <p>将定制的 <tt>ConnectProvider</tt> 关联到小部件,如下所示: |
| |
| <pre class=examplecode> |
| @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")); |
| } |
| <b>widget.getActions().addAction( |
| ActionFactory.createExtendedConnectAction( |
| connectionLayer, new MyConnectProvider()));</b> |
| widget.getActions().addAction( |
| ActionFactory.createAlignWithMoveAction( |
| mainLayer, interactionLayer, |
| ActionFactory.createDefaultAlignWithMoveDecorator())); |
| widget.setLabel(arg0); |
| mainLayer.addChild(widget); |
| return widget; |
| } |
| </pre> |
| |
| <li>运行应用程序,选择一个小部件并按住 Ctrl 键,然后拖动鼠标至另一个小部件。这样即可将小部件彼此相连,如下所示: |
| |
| <p><p><img border="1" src="../images/tutorials/vislib/vislib-java-6.png"/> |
| |
| </ol> |
| |
| <p>现在您对可视库 API 提供的功能已经有了一个基本的了解,请参见 <a href="https://netbeans.org/kb/trails/platform_zh_CN.html">NetBeans 平台学习资源</a>中的“用于可视化数据的 NetBeans API”部分。 |
| |
| </body> |
| </html> |