DirectoryFieldEditor at dialogs.TitleAreaDialog not validated on key stroke

26 Views Asked by At

I do extend org.eclipse.jface.dialogs.TitleAreaDialog for creating preference dialog. Apart other fields, I create there org.eclipse.jface.preference.DirectoryFieldEditor. That one, I would like to validate after every key stroke, so I use StringFieldEditor.VALIDATE_ON_KEY_STROKE. But it seems validating only after focus lost, what is default value. IPropertyChangeListener is fired only on focus lost (I want to fire it after key stroke), at least validates values correctly. I added KeyListener, but isValid() is returning incorrect values. Those are fine after focus lost as well.

I have got something similar at MyPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage, where I have no problems with validating on key stroke.

As some workaround I tried to use dirFieldExportPath.load() inside KeyListener, but cursor is moved to the begging after every load (key stroke).

Code:

public class TestDialog extends TitleAreaDialog
{
  // code, fields

  private Viewer               view;
  private String               DialogTitle;
  private String               DialogHeader;
  private Composite            checkboxExportPathParent;
  private Composite            directoryExportPathParent;
  private DirectoryFieldEditor dirFieldExportPath;

  public testDialog(Shell parentShell, Viewer view)
  {
    super(parentShell);
    this.view = view;
  }

  @Override
  protected Control createButtonBar(Composite parent)
  {
    Control buttonBar = super.createButtonBar(parent);
    refreshButtonBarState();
    return buttonBar;
  }

  private void refreshButtonBarState()
  {
    // code
  }

  protected Control createDialogArea(Composite parent)
  {
    setTitle(DialogTitle);
    getShell().setText(DialogHeader);

    // code, setting layout

    createHtmlTab();

    return parent;
  }

  private void createHtmlTab()
  {
    TabFolder tabFolder;
    TabItem htmlTabItem = new TabItem(tabFolder, SWT.NONE);
    htmlTabItem.setText(TabHeader.html3d.getTabHeaderName());

    // insert scroll bar
    final ScrolledComposite sc = new ScrolledComposite(tabFolder, SWT.V_SCROLL);
    sc.setExpandHorizontal(true);// required
    sc.setExpandVertical(true);// required

    htmlTabItem.setControl(sc);

    Composite htmlContainer = new Composite(sc, SWT.None);
    htmlContainer.setLayout(new GridLayout(1, true));
    htmlContainer.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));

    sc.setContent(htmlContainer);

    // Export path

    checkboxExportPathParent = new Composite(htmlContainer, SWT.NONE);
    checkboxExportPathParent.setLayout(new GridLayout(1, false));
    GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, false);
    checkboxExportPathParent.setLayoutData(gridData);

    directoryExportPathParent = new Composite(htmlContainer, SWT.NONE);
    directoryExportPathParent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

    dirFieldExportPath = new DirectoryFieldEditor(ExportPathStr, ExportPathStr, directoryExportPathParent);
    dirFieldExportPath.setEnabled(enabled);
    // dirFieldExportPath.setPreferenceStore(Activator.getDefault().getPreferenceStore());
    dirFieldExportPath.setEmptyStringAllowed(!enabled);
    dirFieldExportPath.setValidateStrategy(StringFieldEditor.VALIDATE_ON_KEY_STROKE);
    dirFieldExportPath.setPreferenceName(PreferenceConstants.P_HTMLEXPORTPATH);

    String exportPath = ps.getString(PreferenceConstants.P_HTMLEXPORTPATH);
    if (exportPath != null && !exportPath.isEmpty())
      dirFieldExportPath.setStringValue(exportPath);

    if (!dirFieldExportPath.isValid())
      this.setErrorMessage("not valid");
    else
      this.setErrorMessage("valid");/**/

    dirFieldExportPath.getTextControl(directoryExportPathParent).addKeyListener(new KeyListener()
    {
      @Override
      public void keyReleased(KeyEvent e)
      {
        String eP = dirFieldExportPath.getStringValue();
        System.out.println("ExportAndPrintDialog.createHtmlTab()>keyReleased>eP:" + eP);
        Activator.getDefault().getPreferenceStore().setValue(PreferenceConstants.P_HTMLEXPORTPATH, eP);
        // dirFieldExportPath.setPreferenceStore(Activator.getDefault().getPreferenceStore());
        // dirFieldExportPath.load();
      }

      @Override
      public void keyPressed(KeyEvent e)
      {
        // TODO Auto-generated method stub
      }
    });

    dirFieldExportPath.setPropertyChangeListener(new IPropertyChangeListener()
    {
      @Override
      public void propertyChange(PropertyChangeEvent event)
      {
        System.out.println("ExportAndPrintDialog.createHtmlTab()>propertyChange>isValid:" + dirFieldExportPath.isValid());
        // code
      }
    });

    // required; set after all composites were added;
    sc.setMinSize(htmlContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT));
  }

}

What did I miss?

1

There are 1 best solutions below

0
know On

I came with the workaround, it seems to work as desired. I created custom DirectoryFieldEditor to have access to protected boolean checkState(). There I want also expand env. variables. Then after every ModifyEvent runs validation. I added the same logic to custom FileFieldEditor.

created new class:

public class DialogDirectoryFieldEditor extends DirectoryFieldEditor
{
  //private boolean isValid;

  public DialogDirectoryFieldEditor()
  {
    // TODO Auto-generated constructor stub
  }

  public DialogDirectoryFieldEditor(String name, String labelText, Composite parent)
  {
    super(name, labelText, parent);
  }

  @Override
  protected boolean doCheckState()
  {
    String fileName = getTextControl().getText();
    fileName = fileName.trim();
    if (fileName.length() == 0 && isEmptyStringAllowed())
      return true;
    if (fileName.length() == 0)
      return false;

    File file = new File(expandEnvironmentVariables(fileName));
    return file.isDirectory();
  }
}

and in TestDialog:

dirFieldExportPath = new DialogDirectoryFieldEditor(ExportPathStr, ExportPathStr, directoryExportPathParent);
dirFieldExportPath.setEnabled(ps.getBoolean(PreferenceConstants.P_HTML_USE_EXPORTPATH), directoryExportPathParent);
dirFieldExportPath.setEmptyStringAllowed(!ps.getBoolean(PreferenceConstants.P_HTML_USE_EXPORTPATH));
dirFieldExportPath.setPreferenceName(PreferenceConstants.P_HTMLEXPORTPATH);

String exportPath = ps.getString(PreferenceConstants.P_HTMLEXPORTPATH);
if (exportPath != null && !exportPath.isEmpty())
  dirFieldExportPath.setStringValue(exportPath);

// validate path after any input change
dirFieldExportPath.getTextControl(directoryExportPathParent).addModifyListener(new ModifyListener()
{
  @Override
  public void modifyText(ModifyEvent e)
  {
    ps.setValue(
        PreferenceConstants.P_HTMLEXPORTPATH, dirFieldExportPath.getStringValue());
    refreshButtonBarState();
  }
});

private void refreshButtonBarState() {
  // other code
  
    if (htmlTabSelected())
      String errorMessage = refreshValidState();
      
}

private String refreshValidState()
{
  if (htmlTabSelected())
  {
    if (dirFieldExportPath != null)
    {
      boolean dirFieldExportPathValid = 
          Activator.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_HTML_USE_EXPORTPATH) 
          ? dirFieldExportPath.doCheckState() : true;
      if (!dirFieldExportPathValid)
        return ExportPathStr + " " + dirFieldNotValid;
    }
    
    return null;// no error message displayed
  }
  return "";
}