eclipse 自定义一个后缀名为.xxxx的文件编辑器 插件开发
2018-02-09 16:33
671 查看
1.首先创建一个插件工程
![](https://img-blog.csdn.net/20180228125312178?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
创建一个Plug-in Project工程
然后next,输入工程名,然后再next,最后finish
然后打开工程中的MANIFEST.MF文件,在同一行找到Extensions打开
![](https://img-blog.csdn.net/20180228125705748?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
点击add按钮,新建一个扩展点,因为我们要做的是文件编辑器,所以选择org.eclipse.ui.editors模板
![](https://img-blog.csdn.net/20180228130016851?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
然后点击finish
![](https://img-blog.csdn.net/20180228130259621?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
右键选择New 再选择editor
![](https://img-blog.csdn.net/20180228130540695?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
双击 Sample ini Editor(editor)这里Sample ini Editor是你扩展点的名字
![](https://img-blog.csdn.net/2018022813074426?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
右侧会出现你所见扩展点的基本信息,上图是我已经建好的
id 栏是你给扩展点的一个标识,可以随意写
name 栏是你扩展点的名字
extensions 栏是你编辑器编辑后缀名为什么的文件,我这里以后缀为.ini文件为例。
class 栏是你扩展点具体功能实现的类(包名加类名)
其余没有说到的可以先不必去管
这时候你会发现底下出现一个plugin.xml文件
![](https://img-blog.csdn.net/20180228131342281?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
他的内容其实跟你刚才配的内容相同
2.右键选中工程,Run As运行Eclipse Applocation
启动进去后就相当于另一个eclipse
你随便建一个工程,在工程中放一个.ini文件
双击.ini文件,他就会从你具体功能的实现类里面进去
所以你现在需要完成你的实现类
你的实现类必须要实现EditorPart父类
package com.tmstudio.hmi.ini;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.EditorPart;
public class TMHmiIniEditor extends EditorPart {
private boolean isDirty;
private Composite composite;
private TMHmiIni ini;
private Map<String,Map<String, String>> map;
@Override
public void doSave(IProgressMonitor monitor) {
//存储所有的从容器中去读
/* Control[] children = composite.getChildren();
for (Control control : children) {
if(control instanceof Label) {
Label label = (Label) control;
System.out.println(label.getText());
} else if(control instanceof Text) {
Text text = (Text) control;
System.out.println(text.getText());
}
}
*/
ini.writeConfig();
isDirty=false;
firePropertyChange(IEditorPart.PROP_DIRTY);
}
@Override
public void doSaveAs() {
// TODO Auto-generated method stub
}
4000
/span>@Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
isDirty=false;
setSite(site);
setInput(input);
setPartName(input.getName());
}
@Override
public boolean isDirty() {
// TODO Auto-generated method stub
return this.isDirty;
}
@Override
public boolean isSaveAsAllowed() {
// TODO Auto-generated method stub
return false;
}
//然后进来createPartControl这个方法,Composite parent其中parent指的是你工作空间的那一片区域
@Override
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout(SWT.HORIZONTAL));
ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);
composite = new Composite(scrolledComposite, SWT.NONE);
composite.setLayoutData(new GridData());
GridLayout gridLayout = new GridLayout() ;
gridLayout.numColumns=2;
composite.setLayout(gridLayout);
IFile file = (IFile) this.getEditorInput().getAdapter(IFile.class);
File newFile = new File(file.getLocation().toString());
String path2 = newFile.getPath();
//System.out.println(path2);
String path =path2.replaceAll( "\\\\", "\\\\\\\\");
if(file != null) {
ini=new TMHmiIni(path);
map = ini.get();
for (String string : map.keySet()) {
Label l=new Label(composite, SWT.NONE);
l.setText("["+string+"]");
GridData grid=new GridData();
grid.horizontalSpan=2;
l.setLayoutData(grid);
//System.out.println("节点:"+string);
Map<String, String> section = map.get(string);
for(String key:section.keySet()) {
Label ll=new Label(composite, SWT.LEFT);
ll.setText(key+" = ");
Text text=new Text(composite, SWT.SINGLE|SWT.BORDER);
text.setData("node", string);
text.setData("property",key);
text.setText(section.get(key));
GridData gridd=new GridData();
gridd.horizontalAlignment=GridData.FILL;
gridd.grabExcessHorizontalSpace=true;
text.setLayoutData(gridd);
//System.out.println(key+"="+section.get(key));
text.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
Text text = (Text) e.widget;
/*System.out.println(text.getData("node"));
System.out.println(text.getData("property"));
System.out.println(text.getText());*/
ini.setValue((String)text.getData("node"), (String)text.getData("node"), text.getText());
isDirty=true;
firePropertyChange(IEditorPart.PROP_DIRTY);
}
});
}
}
}
scrolledComposite.setContent(composite);
scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
public TMHmiIniEditor() {
super();
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class TMHmiIni {
/**
* 整个ini的引用
*/
private Map<String,Map<String, String>> map = null;
/**
* 当前Section的引用
*/
private String currentSection = null;
/**
* 保存传进来的路径
*/
private String pathIni;
/**
* 读取
* @param path
*/
public TMHmiIni(String path) {
pathIni=path;
map = new HashMap<String, Map<String,String>>();
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
read(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("IO Exception:" + e);
}
}
public void save(String text){
String[] split = text.split("\n");
for (int i = 0; i < split.length; i++) {
parseLine(split[i]);
System.out.println(split[i]);
}
}
/**
* 读取文件
* @param reader
* @throws IOException
*/
private void read(BufferedReader reader) throws IOException {
String line = null;
while((line=reader.readLine())!=null) {
parseLine(line);
}
}
/**
* 转换
* @param line
*/
private void parseLine(String line) {
line = line.trim();
// 此部分为注释
if(line.matches("^\\#.*$")) {
return;
}else if (line.matches("^\\[\\S+\\]$")) {
// section
String section = line.replaceFirst("^\\[(\\S+)\\]$","$1");
addSection(map,section);
}else if (line.matches("^\\S+=.*$")) {
// key ,value
int i = line.indexOf("=");
String key = line.substring(0, i).trim();
String value =line.substring(i + 1).trim();
addKeyValue(map,currentSection,key,value);
}
}
/**
* 增加新的Key和Value
* @param map
* @param currentSection
* @param key
* @param value
*/
private void addKeyValue(Map<String, Map<String, String>> map,
String currentSection,String key, String value) {
if(!map.containsKey(currentSection)) {
return;
}
Map<String, String> childMap = map.get(currentSection);
if(!childMap.containsKey(key)) {
childMap.put(key, value);
} else {
}
}
/**
* 增加Section
* @param map
* @param section
*/
private void addSection(Map<String, Map<String, String>> map,
String section) {
if (!map.containsKey(section)) {
currentSection = section;
Map<String,String> childMap = new HashMap<String, String>();
map.put(section, childMap);
}
}
/**
* 获取配置文件指定Section和指定子键的值
* @param section
* @param key
* @return
*/
public String get(String section,String key){
if(map.containsKey(section)) {
return get(section).containsKey(key) ?
get(section).get(key): null;
}
return null;
}
/**
* 获取配置文件指定Section的子键和值
* @param section
* @return
*/
public Map<String, String> get(String section){
return map.containsKey(section) ? map.get(section) : null;
}
/**
* 获取这个配置文件的节点和值
* @return
*/
public Map<String, Map<String, String>> get(){
return map;
}
/**
* 设置这个配置某个节点下的某个键的值
* @return
*/
public void setValue(String section,String key,String value) {
Map<String, String> sectionmap = map.get(section);
sectionmap.remove(key);
sectionmap.put(key, value);
writeConfig();
}
/**
* 将这个配置的保存
* @return
*/
public void writeConfig() {
File file=new File(pathIni);
if(file.exists()) {
file.delete();
}
try {
file.createNewFile();
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter fileWritter = new BufferedWriter(fw);
for(String key:map.keySet()) {
fileWritter.write("["+key+"]\n");
Map<String, String> section = map.get(key);
for(String sectionKey:section.keySet()) {
fileWritter.write(sectionKey+"="+section.get(sectionKey)+"\n");
}
}
fileWritter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在完成后代码后,运行插件
双击.ini文件,你会看到如下图
![](https://img-blog.csdn.net/20180228134447343?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGxfU2VjcmV0YXJ5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
文本框中的值可以随意修改,修改之后点击eclipse中的保存就会存储
创建一个Plug-in Project工程
然后next,输入工程名,然后再next,最后finish
然后打开工程中的MANIFEST.MF文件,在同一行找到Extensions打开
点击add按钮,新建一个扩展点,因为我们要做的是文件编辑器,所以选择org.eclipse.ui.editors模板
然后点击finish
右键选择New 再选择editor
双击 Sample ini Editor(editor)这里Sample ini Editor是你扩展点的名字
右侧会出现你所见扩展点的基本信息,上图是我已经建好的
id 栏是你给扩展点的一个标识,可以随意写
name 栏是你扩展点的名字
extensions 栏是你编辑器编辑后缀名为什么的文件,我这里以后缀为.ini文件为例。
class 栏是你扩展点具体功能实现的类(包名加类名)
其余没有说到的可以先不必去管
这时候你会发现底下出现一个plugin.xml文件
他的内容其实跟你刚才配的内容相同
2.右键选中工程,Run As运行Eclipse Applocation
启动进去后就相当于另一个eclipse
你随便建一个工程,在工程中放一个.ini文件
双击.ini文件,他就会从你具体功能的实现类里面进去
所以你现在需要完成你的实现类
你的实现类必须要实现EditorPart父类
package com.tmstudio.hmi.ini;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.EditorPart;
public class TMHmiIniEditor extends EditorPart {
private boolean isDirty;
private Composite composite;
private TMHmiIni ini;
private Map<String,Map<String, String>> map;
@Override
public void doSave(IProgressMonitor monitor) {
//存储所有的从容器中去读
/* Control[] children = composite.getChildren();
for (Control control : children) {
if(control instanceof Label) {
Label label = (Label) control;
System.out.println(label.getText());
} else if(control instanceof Text) {
Text text = (Text) control;
System.out.println(text.getText());
}
}
*/
ini.writeConfig();
isDirty=false;
firePropertyChange(IEditorPart.PROP_DIRTY);
}
@Override
public void doSaveAs() {
// TODO Auto-generated method stub
}
//点击.ini文件后先进来这个初始化方法
<4000
/span>@Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
isDirty=false;
setSite(site);
setInput(input);
setPartName(input.getName());
}
@Override
public boolean isDirty() {
// TODO Auto-generated method stub
return this.isDirty;
}
@Override
public boolean isSaveAsAllowed() {
// TODO Auto-generated method stub
return false;
}
//然后进来createPartControl这个方法,Composite parent其中parent指的是你工作空间的那一片区域
@Override
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout(SWT.HORIZONTAL));
ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);
composite = new Composite(scrolledComposite, SWT.NONE);
composite.setLayoutData(new GridData());
GridLayout gridLayout = new GridLayout() ;
gridLayout.numColumns=2;
composite.setLayout(gridLayout);
IFile file = (IFile) this.getEditorInput().getAdapter(IFile.class);
File newFile = new File(file.getLocation().toString());
String path2 = newFile.getPath();
//System.out.println(path2);
String path =path2.replaceAll( "\\\\", "\\\\\\\\");
if(file != null) {
ini=new TMHmiIni(path);
map = ini.get();
for (String string : map.keySet()) {
Label l=new Label(composite, SWT.NONE);
l.setText("["+string+"]");
GridData grid=new GridData();
grid.horizontalSpan=2;
l.setLayoutData(grid);
//System.out.println("节点:"+string);
Map<String, String> section = map.get(string);
for(String key:section.keySet()) {
Label ll=new Label(composite, SWT.LEFT);
ll.setText(key+" = ");
Text text=new Text(composite, SWT.SINGLE|SWT.BORDER);
text.setData("node", string);
text.setData("property",key);
text.setText(section.get(key));
GridData gridd=new GridData();
gridd.horizontalAlignment=GridData.FILL;
gridd.grabExcessHorizontalSpace=true;
text.setLayoutData(gridd);
//System.out.println(key+"="+section.get(key));
text.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
Text text = (Text) e.widget;
/*System.out.println(text.getData("node"));
System.out.println(text.getData("property"));
System.out.println(text.getText());*/
ini.setValue((String)text.getData("node"), (String)text.getData("node"), text.getText());
isDirty=true;
firePropertyChange(IEditorPart.PROP_DIRTY);
}
});
}
}
}
scrolledComposite.setContent(composite);
scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
public TMHmiIniEditor() {
super();
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
这个类是辅助读取你所选中的.ini文件,这两个类放在同一个包下即可
package com.tmstudio.hmi.ini;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class TMHmiIni {
/**
* 整个ini的引用
*/
private Map<String,Map<String, String>> map = null;
/**
* 当前Section的引用
*/
private String currentSection = null;
/**
* 保存传进来的路径
*/
private String pathIni;
/**
* 读取
* @param path
*/
public TMHmiIni(String path) {
pathIni=path;
map = new HashMap<String, Map<String,String>>();
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
read(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("IO Exception:" + e);
}
}
public void save(String text){
String[] split = text.split("\n");
for (int i = 0; i < split.length; i++) {
parseLine(split[i]);
System.out.println(split[i]);
}
}
/**
* 读取文件
* @param reader
* @throws IOException
*/
private void read(BufferedReader reader) throws IOException {
String line = null;
while((line=reader.readLine())!=null) {
parseLine(line);
}
}
/**
* 转换
* @param line
*/
private void parseLine(String line) {
line = line.trim();
// 此部分为注释
if(line.matches("^\\#.*$")) {
return;
}else if (line.matches("^\\[\\S+\\]$")) {
// section
String section = line.replaceFirst("^\\[(\\S+)\\]$","$1");
addSection(map,section);
}else if (line.matches("^\\S+=.*$")) {
// key ,value
int i = line.indexOf("=");
String key = line.substring(0, i).trim();
String value =line.substring(i + 1).trim();
addKeyValue(map,currentSection,key,value);
}
}
/**
* 增加新的Key和Value
* @param map
* @param currentSection
* @param key
* @param value
*/
private void addKeyValue(Map<String, Map<String, String>> map,
String currentSection,String key, String value) {
if(!map.containsKey(currentSection)) {
return;
}
Map<String, String> childMap = map.get(currentSection);
if(!childMap.containsKey(key)) {
childMap.put(key, value);
} else {
}
}
/**
* 增加Section
* @param map
* @param section
*/
private void addSection(Map<String, Map<String, String>> map,
String section) {
if (!map.containsKey(section)) {
currentSection = section;
Map<String,String> childMap = new HashMap<String, String>();
map.put(section, childMap);
}
}
/**
* 获取配置文件指定Section和指定子键的值
* @param section
* @param key
* @return
*/
public String get(String section,String key){
if(map.containsKey(section)) {
return get(section).containsKey(key) ?
get(section).get(key): null;
}
return null;
}
/**
* 获取配置文件指定Section的子键和值
* @param section
* @return
*/
public Map<String, String> get(String section){
return map.containsKey(section) ? map.get(section) : null;
}
/**
* 获取这个配置文件的节点和值
* @return
*/
public Map<String, Map<String, String>> get(){
return map;
}
/**
* 设置这个配置某个节点下的某个键的值
* @return
*/
public void setValue(String section,String key,String value) {
Map<String, String> sectionmap = map.get(section);
sectionmap.remove(key);
sectionmap.put(key, value);
writeConfig();
}
/**
* 将这个配置的保存
* @return
*/
public void writeConfig() {
File file=new File(pathIni);
if(file.exists()) {
file.delete();
}
try {
file.createNewFile();
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter fileWritter = new BufferedWriter(fw);
for(String key:map.keySet()) {
fileWritter.write("["+key+"]\n");
Map<String, String> section = map.get(key);
for(String sectionKey:section.keySet()) {
fileWritter.write(sectionKey+"="+section.get(sectionKey)+"\n");
}
}
fileWritter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在完成后代码后,运行插件
双击.ini文件,你会看到如下图
文本框中的值可以随意修改,修改之后点击eclipse中的保存就会存储
相关文章推荐
- eclipse插件开发:把自定义的文件类型使用xml编辑器打开
- Eclipse插件开发-调用默认编辑器打开指定文件
- rcp(插件开发)如何根据不同后缀文件打开不同编辑器?
- Myeclipse ,开发一个ECLIPSE插件,可以开发AJAX,WEBSERVICE
- VTP一个Eclipse开发Voice Xml的插件
- Eclipse插件开发中对于外部Jar包和类文件引用的处理(彻底解决插件开发中的NoClassDefFoundError问题)
- 一个调试JSP的Eclipse插件的开发
- 开发一个调试 JSP 的 Eclipse 插件
- 使用Eclipse CDT插件开发C/C++时设置保存时编译文件
- Eclipse 开发 Android 应用程序关于SVN插件的一个小事项
- 一个可以直接拖拽文件到Eclipse中使用Eclipse打开的插件
- 插件开发为Java透视图贡献新建向导时的一个bug(org.eclipse.ui.perspectiveExtensions)
- [Eclipse笔记]Back to the old days - Eclipse下的二进制文件编辑器插件EHEP
- eclipse开发一个文件向导
- Eclipse插件开发中对于Jar包和类文件引用的处理(彻底解决插件开发中的NoClassDefFoundError问题)
- 一个spring+hibernate开发的小程序的修改(其中配置文件使用的是HibernateSynchronizer插件生成)
- 一个简单的Eclipse插件开发的例子——HelloWorld【转载】
- 一个调试JSP的Eclipse插件的开发
- 我用myeclipse导入了一个用eclipse开发的项目,项目上有个差报错,是里面几个页面报的假错,部署到tomcat后,tomcat配置里这个项目的running值是false,访问就报404错误,而且不编译class文件
- pydev-一个Eclipse的python开发插件