如何在单个Eclipse偏好页中验证多个StringFieldEditor实例?
Eclipse FieldEditorPreferencePage 多字段验证问题
我在FieldEditorPreferencePage中创建了两个CustomFileFieldEditor实例,分别用于地面纹理和背景纹理的路径设置,偏好页代码如下:
public class PrefPage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { final int MAX_NR_COLUMNS = 3; private List<FieldEditor> fields = null; public PrefPage() { super(GRID); setPreferenceStore(Activator.getDefault().getPreferenceStore()); } @Override protected void createFieldEditors() { Composite fieldEditorParent = getFieldEditorParent(); //types allowed for Ground and Background texture String[] pictureTypesAllowed = {"jpg","jpeg","png"}; String[] pictureTypesAllowedC = new String[]{"*.jpg;*.jpeg;*.png"}; // some settings // ground settings Group envGroup = new Group(fieldEditorParent, SWT.NULL); envGroup.setText("Ground"); envGroup.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false, MAX_NR_COLUMNS, 1)); ComboFieldEditor envControlFE = new ComboFieldEditor(PrefRayConstants.P_RT_GROUND, "Type", PrefRayConstants.GROUND_TYPES, envGroup); addField(envControlFE); CustomFileFieldEditor txtrControlFE = new CustomFileFieldEditor(PrefRayConstants.P_RT_GROUND_TEXTURE, "Texture", envGroup, pictureTypesAllowed); txtrControlFE.setFileExtensions(pictureTypesAllowedC);//allow only those file types addField(txtrControlFE); // background settings Group bgGroup = new Group(fieldEditorParent, SWT.NULL); bgGroup.setText("Background"); bgGroup.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false, MAX_NR_COLUMNS, 1)); FileFieldEditor bgTxtrControlFE = new CustomFileFieldEditor(PrefRayConstants.P_RT_BG_TEXTURE, "Texture", bgGroup, pictureTypesAllowed); bgTxtrControlFE.setFileExtensions(pictureTypesAllowedC);//allow only those file types addField(bgTxtrControlFE); } @Override protected void performApply() { super.performApply(); //Viewer.showReloadRestartMessage(this.getShell()); } @Override public boolean performOk() { boolean bol = super.performOk(); /*Viewer.showReloadRestartMessage(Activator.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell()); if (Viewer.getActiveViewer()!=null) Viewer.getActiveViewer().setRayLocalSettings();*/ return bol; } }
验证异常场景
场景一
- 当地面纹理路径错误时,错误消息正常显示→符合预期
- 将焦点切换到背景纹理字段后切回地面纹理,错误消息消失,原因是仅触发了背景纹理字段的验证(由
StringFieldEditor.getTextControl的失焦事件触发)→不符合预期
场景二
- 当地面纹理路径错误时,错误消息正常显示→符合预期
- 设置错误的背景纹理路径,错误消息正常显示→符合预期
- 删除背景纹理路径(允许空字符串),错误消息消失,但地面路径的错误未被重新提示→不符合预期
注:
FieldEditorPreferencePage.checkState方法可以正确验证整个页面的所有字段。
疑问
Eclipse是否有内置机制可以解决这个多字段联动验证的问题?如果没有,哪种方案更优:
- 自定义
StringFieldEditor.checkState,在其中添加所有字段的验证逻辑 - 在偏好页层面统一处理验证
自定义CustomFileFieldEditor代码
public class CustomFileFieldEditor extends FileFieldEditor { private List<String> allowedExtensions = null; private boolean enableValidation = true; public CustomFileFieldEditor(String name, String labelText, Composite parent) { //this(name, labelText, parent, true); init(name, labelText); setErrorMessage(JFaceResources.getString("FileFieldEditor.errorMessage")); setValidateStrategy(VALIDATE_ON_KEY_STROKE); createControl(parent); } public CustomFileFieldEditor(String name, String labelText, Composite parent, String[] allowedExtensions) { // this(name, labelText, parent, true); init(name, labelText); setErrorMessage(JFaceResources.getString("FileFieldEditor.errorMessage")); setValidateStrategy(VALIDATE_ON_KEY_STROKE); createControl(parent); this.allowedExtensions = Arrays.asList(allowedExtensions); } public CustomFileFieldEditor(String name, String labelText, Composite parent, boolean enableValidation) { //super(name, labelText, parent); init(name, labelText); setErrorMessage(JFaceResources.getString("FileFieldEditor.errorMessage")); enableValidation(enableValidation); //setEmptyStringAllowed(!enableValidation); setValidateStrategy(VALIDATE_ON_KEY_STROKE); createControl(parent); } public void enableValidation(boolean enableValidation) { this.enableValidation = enableValidation; } @Override protected boolean doCheckState() { return super.doCheckState(); } @Override protected boolean checkState() { return super.checkState(); } public void valueChanged() { super.valueChanged(); } // prepared method private boolean isSuffixAllowed(String txt) { if (allowedExtensions == null) return true; if (!allowedExtensions.isEmpty()) for (String suffix : allowedExtensions) if (txt.endsWith(suffix)) return true; return false; } @Override public boolean isValid() { return super.isValid(); } }
内容的提问来源于stack exchange,提问作者know
相关产品推荐
相关产品推荐

