前些日子,開發了一個插件。初次開發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就更好了!