Community
Participate
Working Groups
Build Identifier: 20110218-0911 If there are multiple StringFieldEditor on a preference page and more than one of them have an error, then the error message shown is that of the field that has already lost focus versus the error message of the field that currently has focus. This can be confusing to users because they are relying on the error message to guide them in fixing the problem in the current field. Reproducible: Always Steps to Reproduce: 1. Open a preference page with more than one StringFieldEditor (e.g. General > Editors preference page) 2. Introduce an error in more than one of the fields (e.g. in the General > Editors preference page, introduce an error in the "Size of recently opened files list" and "Number of opened editors before closing") 3. Click between the two fields with errors and notice that the error message shown is for the field that has just lost focus versus showing the error message of the current field.
This seems to be a problem only if I use mouse clicks to navigate the fields. If I tab through the fields, it works fine -- the error message shown is that of the field that I have currently tabbed to.
FieldEditors and PreferencePage doesn't prioritize the active field editor when showing an error message. Although that might seem to make sense, there could be some additional flicker when switching between fields. It might be better to integrate JFace's Field Assist decorations with the field editors.
This is more than just a matter of the error message not being shown for the editor with the focus. It is possible for the error message to be cleared from the page, even though the page is still invalid. This can be demonstrated using steps similar to those in the initial bug description, using the General -> Editors preference page. 1. Open the General -> Editors preference page. 2. Introduce an error in at least 2 StringFieldEditors on the preference page. a. Click into and clear the "Size of recently opened files list" preference. b. Click into and clear the "Number of opened editors before closing" preference. The error for the "Size of recently opened files list" preference is displayed in the page. 3. Click into the "Size of recently opened files list" field. The error for the "Number of opened editors before closing" preference is displayed in the page. 4. Input a valid value for the "Size of recently opened files list" preference (i.e. 5). The error for the "Number of opened editors before closing" preference is displayed in the page, which is expected. 5. Click into the "Number of opened editors before closing" field. The error message for the page is cleared, even though the "Number of opened editors before closing" preference is invalid (empty) and the "Apply/Apply and Close" buttons are disabled. StringFieldEditor does the following on key-up or focus-lost: 1. valueChanged() is called, which calls refreshValidState() 2. refreshValidState() sets the 'isValid' field to the result of checkState() 3. checkState() clears the page error (clearErrorMessage()) if the editor is valid or displays the page error (showErrorMessage()) if the editor is invalid FieldEditorPreferencePage listens for the IS_VALID FieldEditor property to change. When a FieldEditor transitions to a valid state, the page checks the valid state of its other FieldEditors and sets the page's valid state appropriately (this is good). However, the page does not set/update its error message when checking the other FieldEditors. So when you have 2 StringFieldEditors on a page and at least one of them is invalid, either of the following will clear the page error while it is still invalid: 1. StringFieldEditor with valid value loses focus 2. StringFieldEditor with valid value is modified to another valid value It seems like FieldEditorPreferencePage should also set/update the page error message in checkState() when it updates its valid state. This would probably require FieldEditor to be updated to include a getErrorMessage() method (that returns null by default) so that it can be used like the isValid() method.