前些日子,开发了一个插件。初次开发Eclipse插件,并不是很顺手,现在项目已经接近尾声,所以把心得体验写一点出来,便于自己和他人参考。
这个项目是事件树的开发。即要实现事件树的绘制,修改,增加,删除,计算概率等操作。考虑到所有的东西都从底层做起,十分的麻烦,于是我查了些资料,得知Jgraph,GEF都可以用来绘制图形,于是我选了JGraph。
我扩展了Eclipse的编辑器与视图,因为编辑器上的GUI是基于SWT的,而JGraph是基于Swing的,所以我通过桥接器使得其能放上Jpanel。(代码如下)
Composite container = new Composite(parent, SWT.EMBEDDED);
container.setLayout(new FillLayout(SWT.VERTICAL));
final Frame frame = SWT_AWT.new_Frame(container);
System.setProperty("sun.java2d.d3d", "false");
frame.add(new PaintingView());
然后么在上方添加了一个工具栏,添加了一些按钮。其中涉及了不少Jgraph的东西,很可惜,网上,书本上关于Jgraph的资料并不是特别多,许多地方都要自己探索,研究。还好有些网友在自己的搏客上写了不少心得,体会,对我的帮助很大~~
我就挑一些难点,或者是自己想了许久才解决的东西和大家探讨下,也许是通过桥接器吧,原先双击JGraph的Cell,会跳出窗口,能对其进行修改,但我以Eclipse插件的形式运行,却跳出一个不能编辑的窗口,这是为什么呢?我想大概还是与桥接器有关。通过同学的帮助,我才解决了这个问题。(代码如下)
public class MyGraph extends JGraph {
。。。。。。
@SuppressWarnings("unchecked")
protected void completeEditing(boolean messageStop,
boolean messageCancel,
boolean messageGraph) {
if(stopEditingInCompleteEditing && editingComponent != null &&
editDialog != null) {
Component oldComponent = editingComponent;
Object oldCell = editingCell;
GraphCellEditor oldEditor = cellEditor;
Object newValue = oldEditor.getCellEditorValue();
//if(Double.isNaN(v))
Rectangle2D editingBounds = graph.getCellBounds(editingCell);
boolean requestFocus = (graph != null &&
(graph.hasFocus() || editingComponent.hasFocus()));
editingCell = null;
editingComponent = null;
if(messageStop){
oldEditor.stopCellEditing();
}
else if(messageCancel){
oldEditor.cancelCellEditing();
}
editDialog.dispose();
if(requestFocus)
graph.requestFocus();
if (messageGraph) {
。。。。//添加你需要的操作。
}
}
}
protected boolean startEditing(Object cell, MouseEvent event) {
if(graph.isCellEditable(cell) && editDialog == null) {
if(graph.getModel().isEdge(cell)){
name=false;
}
else{
name=true;
}
CellView tmp = graphLayoutCache.getMapping(cell, false);
cellEditor = tmp.getEditor();
editingComponent = cellEditor.getGraphCellEditorComponent(graph, cell,
graph.isCellSelected(cell));
if(cellEditor.isCellEditable(event)) {
System.out.println("zxc1");
editingCell = cell;
Dimension editorSize = editingComponent.getPreferredSize();
editDialog = new JFrame("Edit "+graph.convertValueToString(cell));
//new JDialog(myFrame, "Edit "+graph.convertValueToString(cell), true);
editDialog.setSize(editorSize.width, editorSize.height);
editDialog.getContentPane().add(editingComponent);
editingComponent.validate();
editDialog.pack();
editDialog.show();
// Add Editor Listener
if(cellEditorListener == null)
cellEditorListener = createCellEditorListener();
if(cellEditor != null && cellEditorListener != null)
cellEditor.addCellEditorListener(cellEditorListener);
if(cellEditor.shouldSelectCell(event)) {
stopEditingInCompleteEditing = false;
try {
graph.setSelectionCell(cell);
} catch (Exception e) {
System.err.println("Editing exception: " + e);
}
stopEditingInCompleteEditing = true;
}
if(event instanceof MouseEvent) {
Point componentPoint = SwingUtilities.convertPoint
(graph, new Point(event.getX(), event.getY()),
editingComponent);
Component activeComponent = SwingUtilities.
getDeepestComponentAt(editingComponent,
componentPoint.x, componentPoint.y);
if (activeComponent != null) {
new MouseInputHandler(graph, activeComponent, event);
}
}
return true;
}
else{
editingComponent = null;
return true;
}
}
else{
return false;
}
}
。。。。。
}
这样之后,你双击Cell,会先调用startEditing方法进行判断,然后会调用 completeEditing方法。
Jgraph还实现了导出图片的函数,(代码如下)
FileOutputStream out = new FileOutputStream(nn + ".jpg");
Color bg = graph.getBackground();
BufferedImage img = graph.getImage(bg, 0);
ImageIO.write(img, "png", out);
后来我还遇到了一个问题,即怎么在工具栏上点击一个按钮后,与视图类交互,因为我是要计算概率后,把结果显示在视图类上的。网上找了一会儿,见到的东西往往是与继承了ViewPart的类有关的,而我是桥接的一个Jpanel,往往用不上。后来实在没办法,只好把视图类的方法设置成static的,这样我就能调用了,还要注意一个问题,就是Swt不能支持两个线程同时修改界面,解决此问题的代码如下。
Display.getDefault().syncExec (new Runnable () {
public void run () {
。。。。。//要做的操作
}
}
)
现在想到的问题就是这么多了,感觉JGraph用在Java的图形开发上还是不错的,如果能支持现在比较流行的Swt就更好了!