InputVerifier goos into infinite loop for no discernible reason

I have a JFormattedTextField with an input verifier specified in the constructor as

this.setInputVerifier(new SecNameInputVerifier());

Here's the implementation of the InputVerifier:

publicclass SecNameInputVerifierextends InputVerifier{

private IOPanel ioContainer = FrameReference.requestIoPanel();

publicboolean verify(JComponent input){

String title ="Create Section Dialog";

String message =

"A Section with that name already exists. \n" +

"Please choose another name.";

if (inputinstanceof JFormattedTextField){

try{

JFormattedTextField ftf = (JFormattedTextField)input;

//check if section is valid for its heirarchical location in the tree

System.err.println("verify() invoked");// Line 1

if (ioContainer.sysConfigPanel.sysActionListener.validateAddSection(

ftf.getText(),true)){// Line 2

//check if section already exists

if (!secExists(ftf.getText())){

returntrue;

}

else{

//section already exists

JOptionPane.showMessageDialog(ioContainer, message, title,

JOptionPane.ERROR_MESSAGE);

}

}

}//end try

catch(Exception e){

e.printStackTrace();

}

}

returnfalse;

}

publicboolean shouldYieldFocus(JComponent input){

return verify(input);

}

privateboolean secExists(String secName){

if (ioContainer.sysConfigPanel.treePanel.numInstances(secName) > 0){

returntrue;

}

else{

returnfalse;

}

}

}

The program fails in the verify() method when the JFormattedTextField object loses focus. I've indicated Line 1 and Line 2 in the comments, which I'll reference here. Line 2 invokes a method that checks for validity of the text that was entered. In the failure scenario, this method returns false. Stepping through with the debugger, after Line 2 returns, the program then executes Line 1. Then it executes Line 2 again, returns false, goes back to Line 1, in an infinite loop until a stack overflow occurs.

It seems strange to execute the line above when it returns, but I'm going to assume that my IDE debugger is muddling things up a bit. The method should return false, but the debugger doesn't show the "return false" statement being executed. Then I'm going to assume that the shouldYieldFocus() method gets called again for some reason, which calls the verify() method, and for some reason the debugger skips all that and shows Line 1 as the next statement to execute. This is the only explanation I can think of for what otherwise would look like retrograde execution.

But if this is the case, I have no idea why shouldYiedlFocus() keeps getting called. Anyone know what I'm missing? I don't have any listeners on the JFormattedTextField, and I have no idea why the input verifier is being called repeatedly instead of just once when it loses focus.

Something else that's strange is that within the method invoked by Line 2 (validateAddSection()), there is code to open a JOptionPane. I see this code execute with the debugger, but the JOptionPane never shows up.

I'm completely at a dead end. I hope someone can shed some light on this.

[5201 byte] By [MidnightJavaa] at [2007-11-26 12:41:31]
# 1

Yes, its a know bug when a JOptionPane is used in the verify() method. The old tutorial showed a work around. I don't know why the new version doesn't. Basically you remove the verifier before displaying the option pane and then add it back after closing the option pane. This posting has a working example:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=776107

In the future post a [url http://homepage1.nifty.com/algafield/sscce.html]Short, Self Contained, Compilable and Executable, Example Program[/url] (SSCCE) that demonstrates the incorrect behaviour.

camickra at 2007-7-7 16:14:39 > top of Java-index,Desktop,Core GUI APIs...
# 2

Thanks. That sort of helped. I don't get the infinite loop anymore, but the JOptionPane doesn't show up, and the JFormattedTextField object is permitted to lose focus, even though I invoke

setFocusLostBehavior(JFormattedTextField.PERSIST);

on it after setting the InputVerifier.

I must have another problem somewhere. Here's how I changed my verify() method per the link you posted

public boolean verify(JComponent input) {

if (input instanceof JFormattedTextField) {

try{

JFormattedTextField ftf = (JFormattedTextField)input;

//check if section is valid for its heirarchical location in the tree

System.err.println("verify() invoked");

if (ioContainer.sysConfigPanel.sysActionListener.validateAddSection(

ftf.getText(), true)){//dialog handled by validateAddSection()

//check if section already exists

if (!secExists(ftf.getText())){

return true;

}

else{

//section already exists

input.setInputVerifier(null);

String title = "Create Section Dialog";

String message =

"A Section with that name already exists. \n" +

"Please choose another name.";

JOptionPane.showMessageDialog(ioContainer, message, title,

JOptionPane.ERROR_MESSAGE);

input.setInputVerifier(this);

}

}

}//end try

catch(Exception e){

e.printStackTrace();

}

}

return false;

}

MidnightJavaa at 2007-7-7 16:14:39 > top of Java-index,Desktop,Core GUI APIs...
# 3
No SSCCE, no help.
camickra at 2007-7-7 16:14:39 > top of Java-index,Desktop,Core GUI APIs...
# 4

Fair enough. It was late at night and I was tired, but I understand the need to provide something for prospective helpers to respond to.

I created a SSCCE and it worked. So then I went back to my app to see what was different, and I found some code I had commented out in the midst of troubleshooting and forgot to uncomment.

This was clearly a hardware error, specifically a loose nut on the keyboard.

Thanks for telling me about the not-so-well-documented bug with JOptionPane not playing well with InputVerify. The workaround you pointed me to solved my problem.

MidnightJavaa at 2007-7-7 16:14:39 > top of Java-index,Desktop,Core GUI APIs...