United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6480545 : InputVerifier behavior change in 1.5+

Details
Type:
Bug
Submit Date:
2006-10-11
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
client-libs
OS:
windows_xp
Sub-Component:
javax.swing
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:

Related Reports
Backport:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.5.0_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b01)
Java HotSpot(TM) Client VM (build 1.5.0_09-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
The behavior of the InputVerifier has dramatically chagned in version 1.5+ which precludes two (or more) JComponents from having active InputVerifiers in the same JVM.

We have JComponets which use an InputVerifier to invoke a JDialog to assist the user in further qualifying bad entries.  These JDialogs in turn have JComponents which also use different InputVerifiers.  Since 1.5 the subsequent (nested) InputVerifiers have stopped working.

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
Found the following code in JComponent 1.5:
    private boolean runInputVerifier() {
        if (inInputVerifier) {
            // We're already running the InputVerifier, assume the
            // developer knows what they're doing.
            return true;
        }

By commenting out the conditional test of "inInputVerifier", the original behavior returns.
Because "inInputVerifier" is a private variable, it cannot be over-ridden by an descendant class.  Also because it is static, all JComponents across the JVM are limited.
Because method "runInputVerifer()" is private, it cannot be over-ridden by an ancestor class.

                                    

Comments
EVALUATION

On thinking about this more, it seems probable that folks are relying on changing focus in the same window from the InputVerifier. As such, it's worth keeping this logic around, without the hacky invokeLater.

The fix is to move from the static field inInputVerifier to an AppContext value. The AppContext value identifies the component the InputVerifier is running for. If we're in the code where we attempt to run the InputVerifier, and the AppContext value identifies the same component, we now we're in a loop, and don't notify the InputVerifier again.

To deal with the case of showing a modal dialog, with it's own InputVerifier, and after the modal dialog is hidden trasfering focus, the AppContext value is treated like a stack. That is, after the InputVerifier has run, rather than setting the AppContext value to null, it's set to the last value contained in the AppContext. This enables avoiding loops when InputVerifiers are run from within InputVerifiers.
                                     
2006-11-09
EVALUATION

This regression resulted from 4532517, which centered around a
limitation of the InputVerifier. Prior to the fix for 4532517
developers could not (unless they did the work around) show an option
pane from an InputVerifier. This happened because we would get stuck
in an infinite loop showing the option pane; focus continually kept
trying to get taken from the button, which triggered IV to run, which
triggered another dialog ...

The fix for 4532517 was to remember if we were calling into the
InputVerifier, and if so, don't call into it until the call
returns. Roughly:

static boolean inInputVerifier;

inInputVerifier = true;
callInputVerifier();
inInputVerifier = false;

This resulted in the regression 6480545. The problem with the fix is
that if you show a modal dialog that also has an InputVerifier, we'll
still be blocked in callInputVerifier and inInputVerifier will be true
so that the InputVerifier attached to a child of the modal dialog
never gets run.

This is intimately related to 6401036 (and 6378278). When fixing 6401036 we came to the
conclusion that the InputVerifier shouldn't be notified when focus
changes occur across windows. As such, it seems to me the fix for
4532517 is no longer needed, and can be backed out.

The one case where 4532517 is still needed, is if for some reason the
InputVerifier wanted to change focus within the same window. This
seems like an odd case. Given the current fix, I can't say if folks
are relying on this working now (it would). The only way I could seem
accommodating this desire along with 6480545 is to do something like:

inInputVerifier = true;
SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    inInputVerifier = false;
  }
});
callInputVerifier();
inInputVerifier = false;

YUCK!

I'm inclined to back out 4532517, and be done with it. If folks want
the odd behavior of changing focus in the IV to some where in the same
window, they should be responsible for toggling
VerifyInputWhenFocusTarget.
                                     
2006-11-02
EVALUATION

Received test case from customer (attached). Will futher evaluate shortly.
                                     
2006-10-30
EVALUATION

This was introduced as a result of fixing 4532517. The fix seems good to me, but I need a test case to verify that. Contacting submitter for more info.
                                     
2006-10-11



Hardware and Software, Engineered to Work Together