您的位置:首页 > 其它

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

2017-04-11 09:49 465 查看
 
JFace的TableViewer中,通过方法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(如下图),在单击按钮时弹出对话框(对话框的内容自定义),是如何实现的?
 



 
 
eclipse中已经提供了用于dialog的celleditor类:
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);

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





大小: 31.5 KB

查看图片附件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: