Eclipse插件(RCP)自定义编辑器

前言

Eclipse 提供了文本编辑器(org.eclipse.ui.editors.text.TextEditor),这类编辑器很适合文本类编辑。但是RCP中,并不是所有的资源都是通过文本编辑的,我们需要定制出客户业务相关的、简洁直观的表单类编辑器。本文给出这样一个案例。简图如下
在这里插入图片描述
以下是创建该编辑器过程

一、在plugin.xml中扩展Editor

编辑器扩展自Eclipse插件扩展点 org.eclipse.ui.editors ,代码如下:

<!--  编辑器扩展 -->
   <extension
         id="XzbdEditor"
         point="org.eclipse.ui.editors">
      <editor
            class="com.xzbd.editor.FormEditor"
            default="false"
            extensions="pconf"
            icon="icons/message.png"
            id="com.xzbd.editor.FormEditor"
            name="表单编辑">
      </editor>
   </extension>

二、创建编辑器类FormEditor

  • 继承 EditorPart
  • 实现父类定义的抽象方法或接口
  • init 方法中添加 this.setSite(site); this.setInput(input);
  • 定义 isDirty 变量,并完善方法isDirty,该变量表示编辑器内容是否修改过,false/ 没有修改过,true / 修改过。
  • 添加 changeDirtyStatetoDirtyclearDirty 方法,备用。
  • 完善createPartControl方法,该方法用于创建编辑器内容, 为了代码整洁我们新建一个类 FormEditViewer 完成编辑器 UI 部分,并将编辑器传入其中,以便后期调用编辑器方法。

FormEditor代码如下

package com.xzbd.editor;

/**
 * 表单编辑器
 */
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

import com.xzbd.view.demos.FormEditViewer;

public class FormEditor extends EditorPart {

	public static String ID = "com.xzbd.editor.FormEditor";

	public boolean isDirty = false;
	private FormEditViewer viewer;

	@Override
	public void doSave(IProgressMonitor monitor) {
		
		clearDirty();
	}

	@Override
	public void doSaveAs() {

	}

	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		this.setSite(site);
		this.setInput(input);
	}

	@Override
	public boolean isDirty() {
		return isDirty;
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	@Override
	public void createPartControl(Composite parent) {
		viewer = new FormEditViewer(parent,this);
	}

	@Override
	public void setFocus() {

	}

	/**
	 * 转换编辑器状态
	 * 
	 * @param isDirty
	 */
	public void changeDirtyState(boolean isDirty) {
		this.isDirty = true;
		firePropertyChange(PROP_DIRTY);
	}
	
	public void toDirty() {
		changeDirtyState(true);
	}

	public void clearDirty() {
		changeDirtyState(false);
	}
}

三、创建编辑器UIFormEditViewer

FormEditViewer 是一个普通类,代码可以自己随便组织,其中 UI 部分源自 理解SWT布局(第一部分) 一文中最后一个demo,该文章对RCP布局做了非常精彩的讲解,需要学习布局的同学可以移步去看看。

package com.xzbd.view.demos;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;

import com.xzbd.editor.FormEditor;

/**
 * 
 * 编辑器视图
 *
 */
public class FormEditViewer {
private ProjectConfigEditor editor;
	private Composite parent;

	private Text dogName;
	private Combo dogBreed;
	private Canvas dogPhoto;
	private Image dogImage;
	private List categories;
	private Text ownerName;
	private Text ownerPhone;

	public ProjectConfigEditViewer(Composite parent, ProjectConfigEditor editor) {
		this.parent = parent;
		// 缓存 Editor
		setEditor(editor);

		// 绘制UI
		buildPageUI();
	}

	// 创建UI
	private void buildPageUI() {
		// 设置 parent 布局,采用3列 GridLayout 方式布局
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		parent.setLayout(gridLayout);

		new Label(parent, SWT.NONE).setText("Dog's Name:");
		dogName = new Text(parent, SWT.SINGLE | SWT.BORDER);
		// 设置 label 布局,横向占两列满填充
		GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gridData.horizontalSpan = 2;
		dogName.setLayoutData(gridData);

		new Label(parent, SWT.NONE).setText("Breed:");
		dogBreed = new Combo(parent, SWT.NONE);
		dogBreed.setItems(new String[] { "Collie", "Pitbull", "Poodle", "Scottie" });
		dogBreed.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		Label label = new Label(parent, SWT.NONE);
		label.setText("Categories");
		label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));

		new Label(parent, SWT.NONE).setText("Photo:");
		dogPhoto = new Canvas(parent, SWT.BORDER);
		gridData = new GridData(GridData.FILL_BOTH);
		gridData.widthHint = 80;
		gridData.heightHint = 80;
		gridData.verticalSpan = 3;
		dogPhoto.setLayoutData(gridData);
		dogPhoto.addPaintListener(new PaintListener() {
			public void paintControl(final PaintEvent event) {
				if (dogImage != null) {
					event.gc.drawImage(dogImage, 0, 0);
				}
			}
		});
		categories = new List(parent, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
		categories.setItems(new String[] { "Best of Breed", "Prettiest Female", "Handsomest Male", "Best Dressed",
				"Fluffiest Ears", "Most Colors", "Best Performer", "Loudest Bark", "Best Behaved", "Prettiest Eyes",
				"Most Hair", "Longest Tail", "Cutest Trick" });
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		gridData.verticalSpan = 4;
		int listHeight = categories.getItemHeight() * 12;
		Rectangle trim = categories.computeTrim(0, 0, 0, listHeight);
		gridData.heightHint = trim.height;
		categories.setLayoutData(gridData);
		Button browse = new Button(parent, SWT.PUSH);
		browse.setText("Browse...");
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gridData.horizontalIndent = 5;
		browse.setLayoutData(gridData);
		browse.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				String fileName = new FileDialog(parent.getShell()).open();
				if (fileName != null) {
					dogImage = new Image(parent.getDisplay(), fileName);
				}
			}
		});
		Button delete = new Button(parent, SWT.PUSH);
		delete.setText("Delete");
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
		gridData.horizontalIndent = 5;
		delete.setLayoutData(gridData);
		delete.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				if (dogImage != null) {
					dogImage.dispose();
					dogImage = null;
					dogPhoto.redraw();
				}
			}
		});
		Group ownerInfo = new Group(parent, SWT.NONE);
		ownerInfo.setText("Owner Info");
		gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		ownerInfo.setLayout(gridLayout);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gridData.horizontalSpan = 2;
		ownerInfo.setLayoutData(gridData);
		new Label(ownerInfo, SWT.NONE).setText("Name:");
		ownerName = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER);
		ownerName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		new Label(ownerInfo, SWT.NONE).setText("Phone:");
		ownerPhone = new Text(ownerInfo, SWT.SINGLE | SWT.BORDER);
		ownerPhone.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		Button enter = new Button(parent, SWT.PUSH);
		enter.setText("Enter");
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
		gridData.horizontalSpan = 3;
		enter.setLayoutData(gridData);
		enter.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				System.out.println("/nDog Name: " + dogName.getText());
				System.out.println("Dog Breed: " + dogBreed.getText());
				System.out.println("Owner Name: " + ownerName.getText());
				System.out.println("Owner Phone: " + ownerPhone.getText());
				System.out.println("Categories:");
				String cats[] = categories.getSelection();
				for (int i = 0; i < cats.length; i++) {
					System.out.println("/t" + cats[i]);
				}
			}
		});
		if (dogImage != null) {
			dogImage.dispose();
		}

	}

	public ProjectConfigEditor getEditor() {
		return editor;
	}

	public void setEditor(ProjectConfigEditor editor) {
		this.editor = editor;
	}
}

布局部分讲解
注意下面这些问题:
• 这里有3列7行。
dogPhoto这个Canvas会变宽和变高同,这是因为它是填充的并且水平地和垂直的抢占的(虽然我们本应该缩放图片,但我们没有对图片进行缩放)。
dogBreed这个Combo会变宽,因为它是水平的填充的,并且它和Canvans在同一列。
dogName这个Text会变宽,那是因为它是水平填充的,并且它所跨越的其中一列包含有Canvas。
Categories这个List会变高,这是因为它是垂直填充的,并且它和Canvas跨越了相同的行。
• 因为categories这个List变高了,它的垂直滚动条消失了(它并没有变宽)。
ownerInfo这个Group会变宽,这是因为它是水平的填充的,并且它所跨越的其中一列包含有Canvas。
• 作为Composite的子类,ownerInfo这个Group有它自己的2列2行的GridLayout
ownerNameownerPhone这两个Text会变宽,这是因为Group会变宽,并且它们在Group的GridLayout中是填充的和水平抢占的。
browsedelete这两个Button会稍微的缩进,而且因为它们都是水平填充的,它们有相同的宽度。
delete这个Button在它的行的顶部垂直的对齐。
Categories这个Label在categories这个List的顶端居中。
enter这个Button是水平地对齐到它所跨越的3列的最右边。
dogPhoto这个Canvas用宽度和高度hint来创建,这是因为如果可能的话,我们要让Image有80象素×80象素的大小。
categories这个List用List的字体的12倍的高度hint值来创建,这是因为我们要让List在初始状态下显示十二个项。

作者:贱小得
链接:https://www.jianshu.com/p/d7c17559f349
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

四、运行

  • 运行 RCP 应用
  • RCP中建一个以pconf为后缀的文件
  • 双击打开该文件,即刻看到编辑器正常打开了

总结

以上就是RCP创建表单UI内容,本文仅仅简单介绍了RCP自定义编辑器的创建,后续会继续完善。
Eclipse插件(RCP)自定义编辑器添加Dirty效果

致谢

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值