Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 4

Request focus tester
While most of the code (the BadRequestFocus constructor) creates the user interface (UI), the pitfall lies in the focusLost() method, which tries to request focus inside the focus notification.
In focusLost(), you first retrieve the field name associated with the JTextField so you know how to validate the field. That is done via the map HashMap. In the example above, I validate only the age field and validate that the value entered in the field is an integer. If the
validation fails, I set the text field to an empty string and call requestFocus() to return the cursor to the component I am validating. Unfortunately, due to the complexity of event handling in a Swing
UI, requestFocus() does not in fact obtain the focus when called inside the lostFocus() method.
You cannot request an event at any time without regard to the current states of both the Swing interface and the event-dispatcher
thread. Luckily, we don't need to examine the Swing implementation source code to find a solution to this problem; Swing provides
a utility method called invokeLater() that executes code on the event-dispatching thread at a later time. In our case, making use of this method properly invokes
the requestFocus() method. Listing 7.2, GoodRequestFocus.java, uses that approach:
Listing 7.2: GoodRequestFocus.java
package com.javaworld.jpitfalls.article4;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class FocusRequester implements Runnable
{
private Component comp;
public FocusRequester(Component comp)
{
this.comp = comp;
try
{
SwingUtilities.invokeLater(this);
} catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
comp.requestFocus();
}
}
public class GoodRequestFocus extends JFrame implements FocusListener
{
// data members identical to BadRequestFocus class ...
public GoodRequestFocus()
{
// this code identical to BadRequestFocus() ...
}
public void focusGained(FocusEvent fevt)
{
System.out.println("Focus Gained.");
}
public void focusLost(FocusEvent fevt)
{
Component c = fevt.getComponent();
if (c instanceof JTextField)
{
JTextField tf = (JTextField) c;
String val = tf.getText();
// get the field name
String fieldName = (String) map.get(tf);
if (fieldName != null)
{
if (fieldName.equals(AGE))
{
try
{
int i = Integer.parseInt(val);
status.setText("Age is Valid.");
} catch (NumberFormatException nfe)
{
// FAILED VALIDATION
// empty field
tf.setText("");
status.setText("Failed Field Validation.
Re-enter.");
// get the focus back to try again
new FocusRequester(c);
}
}
else if (fieldName.equals(BIRTHDAY))
{
// validate the date...
}
}
else
status.setText("Unable to Validate. Unknown field");
}
}
public static void main(String args[])
{
try
{
new GoodRequestFocus();
} catch (Throwable t)
{
t.printStackTrace();
}
}
}
The key that makes the focus request work is the added FocusRequester class, which invokes SwingUtilities.invokeLater(). The FocusRequester class implements Runnable and thus has a run() method that calls requestFocus() on the Component passed in to its constructor.