SWT/JFace中Table相同列多种类型CellEditor以及参照类型编辑器的实现

 

JFaceTableViewer中,通过方法TableViewer.setCellEditors(…)方法可以设置每一列对应的CellEditor。但是如果这样做的话,就会导致无法根据当前行的信息来设置不同的CellEditor,这里介绍一种可以根据不同行设置同一列对应的CellEditor: EditingSupport

 

TableColumn paramNameColumn = new TableColumn(table, SWT.NONE);
paramNameColumn.setWidth(350);
paramNameColumn.setText("参数名");
TableColumn paramValueColumn = new TableColumn(table, SWT.NONE);
paramValueColumn.setWidth(400);
paramValueColumn.setText("参数值");
 
commonParamTableViewer.setColumnProperties(COMMON_PARAM_TITLE);
CellEditor[] cellEditors = new CellEditor[COMMON_PARAM_TITLE.length];
commonParamTableViewer.setCellEditors(cellEditors);
      
TableViewerColumn paramNameViewerColumn = new TableViewerColumn(commonParamTableViewer, paramNameColumn);
paramNameViewerColumn.setEditingSupport(new EmptyEditingSupport(commonParamTableViewer));
      
TableViewerColumn paramValueViewerColumn = new TableViewerColumn(commonParamTableViewer, paramValueColumn);
paramValueViewerColumn.setEditingSupport(new ConfigurableEditingSupport(commonParamTableViewer, ruleEditorListener));

      

而对于EditingSupport有哪些方法?顾名思义,EditingSupport就是为了能够提供编辑支持,该字段能否编辑(canEdit),编辑时得到的值(getValue),编辑后设置的值(setValue),以及使用哪种编辑器(CellEditor)

 

于是在getCellEditor方法中,就可以根据当前行值(方法中的参数element)设置对应不同的CellEditor

 

对于特殊的参照式的Editor(如下图),在单击按钮时弹出对话框(对话框的内容自定义),是如何实现的?

 
SWT/JFace中Table相同列多种类型CellEditor以及参照类型编辑器的实现_第1张图片
 

 

eclipse中已经提供了用于dialogcelleditor类:

org.eclipse.jface.viewers.DialogCellEditor

  

我们可以直接从这点入手,进行扩展,其中的openDialogBox方法就是建立弹出对话框中的内容面板,用户可以在上面进行编辑,并得到返回值结果,这里我们在该方法中直接打开一个RefPaneDialog用于打开对应的对话框。

 

@Override
   protected Object openDialogBox(Control cellEditorWindow) {
      if (dialogComposite == null) {
         MessageDialog.openError(cellEditorWindow.getShell(), "", "");
         returnnull;
      }
      // textEditorChanged = false;
      dialog = new RefPaneDialog(cellEditorWindow.getShell(), valueObj, dialogComposite);
      int result = dialog.open();
      if(result == IDialogConstants.OK_ID) {
         valueObj = dialogComposite.getResultValue();
         // if(valueObj != null){
         text.setText(valueObj == null ? "" : dialogComposite.getDisplayText(valueObj));
         text.setFocus();
      }
      // }
      returnvalueObj;
   }

 

    

而对于对话框中的内容,这里采用了策略模式,交给具体的IDialogComposite来扩展,其中的主要方法和说明如下:

package com.yonyou.nc.codevalidator.runtime.plugin.celleditor;

import java.util.List;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
 * 参照对话框中用于定义的界面处理接口,其中包括显示数据,获取最终结果值操作等
 * @author mazqa
 *
 */
public interface IDialogComposite {
	
	/**
	 * 创建对话框界面Area
	 * @param parent
	 * @param value
	 * @return
	 */
	public void createDialogArea(final Composite parent, Object value);
	
	/**
	 * 创建对话框内容方法,可以更改对话框的大小和显示标题
	 * @param parent
	 * @param value
	 * @return
	 */
	public void createContents(final Control parent, Object value);
	
	/**
	 * 得到对话框中显示的按钮
	 * @return
	 */
	public List<DialogButtonObj> getDialogButtons();
	
	/**
	 * 对按钮事件的处理方法
	 * @param buttonId
	 */
	public void buttonPressed(int buttonId);
	
	/**
	 * 获取最终的返回结果对象, 如果不是同一个对象,最好返回序列化复制后的对象,
	 * 以便能够在编辑完成后进行刷新
	 * @return
	 */
	public Object getResultValue();
	
	/**
	 * 在参照编辑状态中显示在左侧text中的值
	 * @param value
	 * @return
	 */
	public String getDisplayText(Object value);
	
	/**
	 * 从参照的text获得Object值,
	 * @param textValue
	 * @return
	 * @throws Exception 转换失败,格式不正确时
	 */
	public Object getObjectFromText(String textValue) throws Exception;
	
	/**
	 * 参照前面的文本框是否可用,如果不可用{@link #getObjectFromText(String)}方法也不会被调用到
	 * @return
	 */
	public boolean isTextEnable();
	
	/**
	 * 参照非编辑状态显示的值
	 * @param value
	 * @return
	 */
	public String getDisplayLabel(Object value);
	
	/**
	 * 得到TitleAreaDialog中的标题内容
	 * @return
	 */
	public String getTitle();
	
	/**
	 * 得到TitleAreaDialog中的描述内容
	 * @return
	 */
	public String getDescription();
	
	/**
	 * 显示在dialog中的button对象
	 * @author mazqa
	 *
	 */
	public static class DialogButtonObj{
		int id;
		String name;
		boolean defaultButton;
		public DialogButtonObj(int id, String name, boolean defaultButton) {
			super();
			this.id = id;
			this.name = name;
			this.defaultButton = defaultButton;
		}
		public int getId() {
			return id;
		}
		public String getName() {
			return name;
		}
		public boolean isDefaultButton() {
			return defaultButton;
		}
		
	}
}

 

 

RefPaneDialog对话框直接继承自org.eclipse.jface.dialogs.TitleAreaDialog,其中的所有创建按钮,面板,以及操作的方法都是委托对应的IDialogComposite实现的。

 

在创建对话框的过程中,加入了显示在屏幕中央的处理逻辑:

     createActualContents(parent, value);
     Rectangle displayBounds = Display.getCurrent().getPrimaryMonitor().getBounds();
      Rectangle shellBounds = parent.getShell().getBounds();
      int x = displayBounds.x + (displayBounds.width - shellBounds.width) >> 1;
      int y = displayBounds.y + (displayBounds.height - shellBounds.height) >> 1;
      parent.getShell().setLocation(x, y);

  

由上述步骤,简易的参照功能就已经能够实现了,并保证了良好的扩展性(本功能的扩展性是建立在本程序需求的基础之上,没有通用参考价值)。

 

 

你可能感兴趣的:(eclipse,RCP,jface,refpane)