最近都在学写netbeans的插件,感觉这个例子比较好。现在翻译后贴出来共享下。
例子简介:从palette中选择下列三个图形中的任意一个,左键拖动到主面板上,并可进行适量缩放及修改图形的ID。
建立Module
首先我们需要创建一个mudule工程和一个用户window component。- 选择 文件 > 新建项目. 在新建项目的向导中,左边选择NetBeans Modules,右边选择 Module.点击下一步.在项目名处输入ShapeSample 并设置保存在本机上的位置。最后选择Standalone Module and Set as Main Project.点击下一步步.
- 在代码名处输入org.netbeans.shapesample,在模块显示名处输入 Shape Sample. 点击完成.
- 右键点击新建好的项目,选择Properties, 点击 Libraries,添加以下lib:
- Visual Library API
- Action APIs
- Command Line Parsing API
- Common Palette
- Nodes API
- Swing Layout Extensions integration
- UI Utilities API
- Utilities API
- Windows System API
点击确定。
- 右键点击该项目,选择新建 New > Other 并在NetBeans Module Development category 中选择 Window Component . 点击下一步. 在第一个下拉列表中选择 editor 并选择 Open on Application Start. 点击下一步.
- 在类名中输入 Shape. 最好选择一副16px×16px的图片做图标,以便识别和更加专业:)。 点击完成. 这样多个文件将会被自动创建。其中有一个叫ShapeTopComponent. 打开它后你将看到如下视图:
- 右键点击ShapeTopComponent的面板中心, 选择Set Layout, 选咋 Border Layout.
创建Editor
- 选则ShapeTopComponent,从 Palette (Ctrl-Shift-8) 中途一个JScrollPane 到 TopComponent上. 选择属性中的名字,把它修改为shapePane.并在inspector面板中双击JScrollPane,把名字改为shapePane。
- 在包 org.netbeans.shapesample 中创建一个 GraphSceneImpl.java
/*
* This is just a exercise to hoe to use JTable.
*/
package org.netbeans.shapesample;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import javax.swing.JComponent;
import org.netbeans.api.visual.action.AcceptProvider;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.ConnectorState;
import org.netbeans.api.visual.action.TextFieldInplaceEditor;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.widget.LabelWidget;
import org.netbeans.api.visual.widget.LayerWidget;
import org.netbeans.api.visual.widget.Widget;
import org.netbeans.api.visual.widget.general.IconNodeWidget;
import org.netbeans.shapesample.palette.MyNode;
import org.openide.util.Utilities;
/**
*
* @author Vanessa <liyuan.li at Yunnan University>
* @version 1.0.0.0
*/
public class GraphSceneImpl extends GraphScene<MyNode, String> {
private LayerWidget mainLayer;
private WidgetAction editorAction = ActionFactory.createInplaceEditorAction(new LabelTextFieldEditor());
private class LabelTextFieldEditor implements TextFieldInplaceEditor {
public boolean isEnabled(Widget widget) {
return true;
}
public String getText(Widget widget) {
return ((LabelWidget) widget).getLabel();
}
public void setText(Widget widget, String text) {
((LabelWidget) widget).setLabel(text);
}
}
public GraphSceneImpl() {
mainLayer = new LayerWidget(this);
addChild(mainLayer);
getActions().addAction(ActionFactory.createAcceptAction(new AcceptProvider() {
public ConnectorState isAcceptable(Widget widget, Point point, Transferable transferable) {
Image dragImage = getImageFromTransferable(transferable);
JComponent view = getView();
Graphics2D g2 = (Graphics2D) view.getGraphics();
Rectangle visRect = view.getVisibleRect();
view.paintImmediately(visRect.x, visRect.y, visRect.width, visRect.height);
g2.drawImage(dragImage,
AffineTransform.getTranslateInstance(point.getLocation().getX(),
point.getLocation().getY()),
null);
return ConnectorState.ACCEPT;
}
public void accept(Widget widget, Point point, Transferable transferable) {
Image image = getImageFromTransferable(transferable);
Widget w = GraphSceneImpl.this.addNode(new MyNode(image));
w.setPreferredLocation(widget.convertLocalToScene(point));
}
}));
getActions().addAction(ActionFactory.createZoomAction());
getActions().addAction(ActionFactory.createPanAction());
}
private Image getImageFromTransferable(Transferable transferable) {
Object o = null;
try {
o = transferable.getTransferData(DataFlavor.imageFlavor);
} catch (IOException ex) {
ex.printStackTrace();
} catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
return o instanceof Image ? (Image) o : Utilities.loadImage("org/netbeans/shapesample/palette/shape1.png");
}
@Override
protected Widget attachNodeWidget(MyNode node) {
IconNodeWidget widget = new IconNodeWidget(this);
widget.setImage(node.getImage());
widget.setLabel(Long.toString(node.hashCode()));
//double-click, the event is consumed while double-clicking only:
widget.getLabelWidget().getActions().addAction(editorAction);
//single-click, the event is not consumed:
widget.getActions().addAction(createSelectAction());
//mouse-dragged, the event is consumed while mouse is dragged:
widget.getActions().addAction(ActionFactory.createMoveAction());
//mouse-over, the event is consumed while the mouse is over the widget:
widget.getActions().addAction(createObjectHoverAction());
mainLayer.addChild(widget);
return widget;
}
@Override
protected Widget attachEdgeWidget(String edge) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void attachEdgeSourceAnchor(String edge, MyNode oldSourceNode, MyNode sourceNode) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void attachEdgeTargetAnchor(String edge, MyNode oldTargetNode, MyNode targetNode) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
在红线处右键选择Fix Imports。 在ShapeTopComponent.java中修改 getPersistenceType()如下
public int getPersistenceType() {
return TopComponent.PERSISTENCE_NEVER;
}
创建 Component Palette
- 新建org.netbeans.shapesample.palette包,并在其中船舰一下类:
<ul><li><a href="http://platform.netbeans.org/images/tutorials/vislib/Category.java">Category.java</a></li></ul>/*<br> * Category.java<br> *<br> * Created on September 21, 2006, 9:00 PM<br> *<br> * To change this template, choose Tools | Template Manager<br> * and open the template in the editor.<br> *<br> * To understand this class, see http://platform.netbeans.org/tutorials/nbm-nodesapi3.html<br> */<br><br>package org.netbeans.shapesample.palette;<br><br>/**<br> *<br> * @author Geertjan Wielenga<br> */<br><br>public class Category {<br> <br> private String name;<br> <br> /** Creates a new instance of Category */<br> public Category() {<br> }<br> <br> public String getName() {<br> return name;<br> }<br> <br> public void setName(String name) {<br> this.name = name;<br> }<br> <br>}<br><ul><li><a href="http://platform.netbeans.org/images/tutorials/vislib/CategoryChildren.java">CategoryChildren.java</a></li></ul>/*<br> * CategoryChildren.java<br> *<br> * Created on September 21, 2006, 9:00 PM<br> *<br> * To change this template, choose Tools | Template Manager<br> * and open the template in the editor.<br> *<br> * To understand this class, see http://platform.netbeans.org/tutorials/nbm-nodesapi3.html<br> */<br><br>package org.netbeans.shapesample.palette;<br><br>import org.openide.nodes.Children;<br>import org.openide.nodes.Node;<br><br>/**<br> *<br> * @author Geertjan Wielenga<br> */<br>public class CategoryChildren extends Children.Keys {<br><br> private String[] Categories = new String[]{<br> "Shapes"};<br><br> public CategoryChildren() {<br> }<br><br> protected Node[] createNodes(Object key) {<br> Category obj = (Category) key;<br> return new Node[] { new CategoryNode(obj) };<br> }<br><br> protected void addNotify() {<br> super.addNotify();<br> Category[] objs = new Category[Categories.length];<br> for (int i = 0; i < objs.length; i++) {<br> Category cat = new Category();<br> cat.setName(Categories[i]);<br> objs[i] = cat;<br> }<br> setKeys(objs);<br> }<br><br>}<br><ul><li><a href="http://platform.netbeans.org/images/tutorials/vislib/CategoryNode.java">CategoryNode.java</a></li></ul>/*<br> * CategoryNode.java<br> *<br> * Created on September 21, 2006, 9:02 PM<br> *<br> * To change this template, choose Tools | Template Manager<br> * and open the template in the editor.<br> *<br> * To understand this class, see http://platform.netbeans.org/tutorials/nbm-nodesapi3.html<br> */<br><br>package org.netbeans.shapesample.palette;<br><br>import org.openide.nodes.AbstractNode;<br>import org.openide.util.lookup.Lookups;<br><br>/**<br> *<br> * @author Geertjan Wielenga<br> */<br>public class CategoryNode extends AbstractNode {<br><br> /** Creates a new instance of CategoryNode */<br> public CategoryNode( Category category ) {<br> super( new ShapeChildren(category), Lookups.singleton(category) );<br> setDisplayName(category.getName());<br> }<br>}<br><ul><li><a href="http://platform.netbeans.org/images/tutorials/vislib/PaletteSupport.java">PaletteSupport.java</a></li></ul>/*<br> * PaletteSupport.java<br> *<br> * Created on September 25, 2006, 2:22 PM<br> *<br> * To change this template, choose Tools | Template Manager<br> * and open the template in the editor.<br> *<br> * To understand this class, see http://platform.netbeans.org/tutorials/nbm-nodesapi3.html<br> */<br><br>package org.netbeans.shapesample.palette;<br><br>import java.awt.Image;<br>import java.awt.datatransfer.DataFlavor;<br>import java.awt.datatransfer.UnsupportedFlavorException;<br>import java.beans.BeanInfo;<br>import java.io.IOException;<br>import javax.swing.Action;<br>import org.netbeans.spi.palette.DragAndDropHandler;<br>import org.netbeans.spi.palette.PaletteActions;<br>import org.netbeans.spi.palette.PaletteController;<br>import org.netbeans.spi.palette.PaletteFactory;<br>import org.openide.nodes.AbstractNode;<br>import org.openide.nodes.Node;<br>import org.openide.util.Lookup;<br>import org.openide.util.datatransfer.ExTransferable;<br><br>/**<br> *<br> * @author dave<br> */<br>public class PaletteSupport {<br> <br> public static PaletteController createPalette() {<br> AbstractNode paletteRoot = new AbstractNode(new CategoryChildren());<br> paletteRoot.setName("Palette Root");<br> return PaletteFactory.createPalette( paletteRoot, new MyActions(), null, new MyDnDHandler() );<br> }<br> <br> private static class MyActions extends PaletteActions {<br> public Action[] getImportActions() {<br> return null;<br> }<br> <br> public Action[] getCustomPaletteActions() {<br> return null;<br> }<br> <br> public Action[] getCustomCategoryActions(Lookup lookup) {<br> return null;<br> }<br> <br> public Action[] getCustomItemActions(Lookup lookup) {<br> return null;<br> }<br> <br> public Action getPreferredAction(Lookup lookup) {<br> return null;<br> }<br> <br> }<br> <br> private static class MyDnDHandler extends DragAndDropHandler {<br><br> public void customize(ExTransferable exTransferable, Lookup lookup) {<br> Node node = lookup.lookup(Node.class);<br> final Image image = (Image) node.getIcon(BeanInfo.ICON_COLOR_16x16);<br> exTransferable.put(new ExTransferable.Single (DataFlavor.imageFlavor) {<br> <br> protected Object getData() throws IOException, UnsupportedFlavorException {<br> return image;<br> }<br> <br> });<br> }<br> <br> }<br><br>}<br><br><ul><li><a href="http://platform.netbeans.org/images/tutorials/vislib/Shape.java">Shape.java</a></li></ul>/*<br> * Shape.java<br> *<br> * Created on September 21, 2006, 9:09 PM<br> *<br> * To change this template, choose Tools | Template Manager<br> * and open the template in the editor.<br> *<br> * To understand this class, see http://platform.netbeans.org/tutorials/nbm-nodesapi3.html<br> */<br><br>package org.netbeans.shapesample.palette;<br><br>/**<br> *<br> * @author Geertjan Wielenga<br> */<br>public class Shape {<br><br> private Integer number;<br> private String category;<br> private String title;<br> private String image;<br><br> /** Creates a new instance of Instrument */<br> public Shape() {<br> }<br><br> public Integer getNumber() {<br> return number;<br> }<br><br> public void setNumber(Integer number) {<br> this.number = number;<br> }<br><br> public String getCategory() {<br> return category;<br> }<br><br> public void setCategory(String category) {<br> this.category = category;<br> }<br><br> public String getImage() {<br> return image;<br> }<br><br> public void setImage(String image) {<br> this.image = image;<br> }<br><br>}<br><ul><li><a href="http://platform.netbeans.org/images/tutorials/vislib/ShapeChildren.java">ShapeChildren.java</a></li></ul>/*<br>
* ShapeChildren.java
Created on September 21, 2006, 9:10 PM
To change this template, choose Tools | Template Manager
* and open the template in the editor.
To understand this class, see http://platform.netbeans.org/tutorials/nbm-nodesapi3.html
/
package org.netbeans.shapesample.palette;
import java.util.ArrayList;
import org.openide.nodes.Index;
import org.openide.nodes.Node;
/**
* @author Geertjan Wielenga
/
public class ShapeChildren extends Index.ArrayChildren {
private Category category;
private String[][] items = new String[][]{
{"0", "Shapes", "org/netbeans/shapesample/palette/image1.png"},
{"1", "Shapes", "org/netbeans/shapesample/palette/image2.png"},
{"2", "Shapes", "org/netbeans/shapesample/palette/image3.png"},
};
public ShapeChildren(Category Category) {
this.category = Category;
}
protected java.util.List<Node> initCollection() {
ArrayList childrenNodes = new ArrayList( items.length );
for( int i=0; i<items.length; i++ ) {
if( category.getName().equals( items[i][1] ) ) {
Shape item = new Shape();
item.setNumber(new Integer(items[i][0]));
item.setCategory(items[i][1]);
item.setImage(items[i][2]);
childrenNodes.add( new ShapeNode( item ) );
}
}
return childrenNodes;
}
}- MyNode.java
* This is just a exercise to hoe to use JTable.
/
package org.netbeans.shapesample.palette;
import java.awt.Image;
/**
* @author Vanessa <liyuan.li at Yunnan University>
* @version 1.0.0.0
/
public class MyNode {
private Image image;
public MyNode(Image image) {
this.image = image;
}
public Image getImage() {
return image;
}
}
/
* ShapeNode.java
Created on September 21, 2006, 9:18 PM
To change this template, choose Tools | Template Manager
* and open the template in the editor.
To understand this class, see http://platform.netbeans.org/tutorials/nbm-nodesapi3.html
/
package org.netbeans.shapesample.palette;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.util.lookup.Lookups;
/**
* @author Geertjan Wielenga
*/
public class ShapeNode extends AbstractNode {
private Shape shape;
/** Creates a new instance of InstrumentNode */
public ShapeNode(Shape key) {
super(Children.LEAF, Lookups.fixed( new Object[] {key} ) );
this.shape = key;
setIconBaseWithExtension(key.getImage());
}
} - 在ShapeTopComponent.java的构造器中添加如下代码:
<pre class="examplecode">associateLookup( Lookups.fixed( new Object[] { PaletteSupport.createPalette() } ) );</pre> </li><li><p>项目结构如下。<br></p> <p><img src="http://platform.netbeans.org/images/tutorials/vislib/proj-window.png" border="1"></p></li></ol><br><br>示例演示:<br>
- CTRL+鼠标滚轮
备注:
1。以上是总结后的简略方法,原文参见http://platform.netbeans.org/tutorials/60/nbm-visual_library.html
从原文中可以体会到每部分代码的作用。从而对netbeans platform有更加深刻的认识。
2.有红线的地方请使用右键 选择Fix Imports。