You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个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;
  }

}

验证异常场景

场景一

  1. 当地面纹理路径错误时,错误消息正常显示→符合预期
  2. 将焦点切换到背景纹理字段后切回地面纹理,错误消息消失,原因是仅触发了背景纹理字段的验证(由StringFieldEditor.getTextControl的失焦事件触发)→不符合预期

场景二

  1. 当地面纹理路径错误时,错误消息正常显示→符合预期
  2. 设置错误的背景纹理路径,错误消息正常显示→符合预期
  3. 删除背景纹理路径(允许空字符串),错误消息消失,但地面路径的错误未被重新提示→不符合预期

注: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 12:22:02