270
|
Chapter 7, Text
#50 Auto-Completing Text Fields
HACK
You can hide the window at this point and look at the selection value. Since
the
Completer just puts Strings in the list model, you can pull out the
selected value and set that as the text of the field. And you’re done.
Well, not quite. If you call
setText( )
directly in
valueChanged( )
, you’ll be
thrown an
IllegalStateException
. The problem is that you’re attempting to
change the value of the
Document
while it’s already being changed. In other
words, firing off the
DocumentEvent is part of the document edit that began
with the user’s keystroke that led to the completion menu appearing; this
edit needs to complete before another is attempted. As you can see in this
hack, the workaround is to create a worker thread to set the field with the
clicked text, and to invoke that worker on a later cycle through the event
loop. This arrangement returns immediately and lets the first edit finish,
then sets the field later.
Test Out Auto-Complete
To test this class, you need to put the CompletableJTextField in a GUI and
provide a way to give it some completions. The
TestCompletableJTextField
class in Example 7-5 does just that, offering a second JTextField where you
can enter strings that will be offered as completions to text typed into the
CompletableJTextField. When run, the test GUI originally looks like
Figure 7-3.
Example 7-5. A GUI to exercise the CompletableJTextField
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestCompletableJTextField extends JPanel
implements ActionListener {
CompletableJTextField completableField;
JTextField completionField;
public TestCompletableJTextField ( ) {
super( );
setLayout (new BoxLayout (this, BoxLayout.Y_AXIS));
completableField = new CompletableJTextField (75);
add (completableField);
JPanel bottom = new JPanel ( );
bottom.add (new JLabel ("Completion:"));
completionField = new JTextField (40);
completionField.addActionListener (this);
bottom.add (completionField);
JButton addButton = new JButton ("Add");
addButton.addActionListener (this);
Auto-Completing Text Fields #50
Chapter 7, Text
|
271
HACK
To test things out, I added the addresses of some of O’Reilly’s web sites:
www.onjava.com, www.onlamp.com, www.java.net, and webservices.xml.com.
Figure 7-4 shows that after I type
w, all four sites match.
In Figure 7-5, I type a second
w; webservices.xml.com no longer matches, so
it disappears from the list.
As I continue my typing (
www.on), only two matches remain, as seen in
Figure 7-6.
At this point, I clicked www.onjava.com. This text is placed into the field
and the list window disappears, as seen in Figure 7-7.
bottom.add (addButton);
add (bottom);
}
public void actionPerformed (ActionEvent e) {
completableField.addCompletion (completionField.getText( ));
completionField.setText ("");
}
public static void main (String[] main) {
JFrame f = new JFrame ("Completions...");
f.getContentPane().add (new TestCompletableJTextField( ));
f.pack( );
f.setVisible (true);
}
}
Figure 7-3. Empty CompletableJTextField
Figure 7-4. All completions showing after typing one character
Example 7-5. A GUI to exercise the CompletableJTextField (continued)

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.