4

I'm testing out the SwingX AutoCompleteDecorator, the code I'm using is this:

import javax.swing.text.JTextComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.JList;

import org.jdesktop.swingx.autocomplete.*;

public class Test extends JFrame
{
    public Test()
    {
        this.setTitle("Testing");
        JPanel pan = new JPanel();
        JTextComponent test = new JTextField();
        ((JTextField)test).setColumns(20);
        String[] data = {"one", "two", "three", "four"}; 
        JList dataList = new JList(data); 
        AutoCompleteDecorator.decorate(dataList, test);
        pan.add(test);
        this.setContentPane(pan);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setBounds(280,150,500,200);

    }
    public static void main(String[] args)
    {
        Test t = new Test();
    }
}     

I wind up getting a massive runtime error message that I don't really want to post the stack trace for about an Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at org.jdesktop.swingx.autocomplete.ListAdaptor.valueChanged(ListAdaptor.java:77)
    at javax.swing.JList.fireSelectionValueChanged(JList.java:1798)
    at javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1812)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:184)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:164)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:211)
    at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:405)
    at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:415)
    at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:459)
    at javax.swing.JList.setSelectedIndex(JList.java:2212)
    at javax.swing.JList.setSelectedValue(JList.java:2362)
    at org.jdesktop.swingx.autocomplete.ListAdaptor.setSelectedItem(ListAdaptor.java:99)
    at org.jdesktop.swingx.autocomplete.AutoCompleteDocument.setSelectedItem(AutoCompleteDocument.java:355)
    at org.jdesktop.swingx.autocomplete.AutoCompleteDocument.insertString(AutoCompleteDocument.java:303)
    at javax.swing.text.JTextComponent.replaceSelection(JTextComponent.java:1386)
    at javax.swing.text.DefaultEditorKit$DefaultKeyTypedAction.actionPerformed(DefaultEditorKit.java:884)
    at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1664)
    at javax.swing.JComponent.processKeyBinding(JComponent.java:2879)
    at javax.swing.JComponent.processKeyBindings(JComponent.java:2926)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2842)
    at java.awt.Component.processEvent(Component.java:6282)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:762)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1027)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:899)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:727)
    at java.awt.Component.dispatchEventImpl(Component.java:4731)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:688)
    at java.awt.EventQueue$3.run(EventQueue.java:686)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:702)
    at java.awt.EventQueue$4.run(EventQueue.java:700)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

What have I missed?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
JustAnotherSoul
  • 350
  • 3
  • 14
  • I have read http://stackoverflow.com/questions/11928999/jtextfield-autocompletion-error?rq=1, and the answer to it doesn't resolve the issue I'm currently having. – JustAnotherSoul Jul 30 '13 at 20:23
  • hmm .. could be a bug, can reproduce it with your example and swinglabs-demos - you might consider reporting it in the swingx issue tracker so we don't forget to look into it (make it highest priority to kick us into actually tackling it :-) – kleopatra Jul 30 '13 at 22:09
  • I think I'll sit on it for a day or so, just in case someone sees something subtle I managed to break. – JustAnotherSoul Jul 31 '13 at 02:32
  • thanks for bringing up the issue :-) – kleopatra Jul 31 '13 at 07:07

2 Answers2

4

It's a bug: the culprit is a null ObjectToStringConverter in decorating a textComponent with the items of a JList, using the two-parameter method:

public static void decorate(JList list, JTextComponent textComponent) {
    decorate(list, textComponent, null);
}

A quick fix is to use the three-parameter method and pass-in the default converter:

JTextComponent test = new JTextField(20);
String[] data = {"one", "two", "three", "four"}; 
JList dataList = new JList(data); 
AutoCompleteDecorator.decorate(dataList, test, ObjectToStringConverter.DEFAULT_IMPLEMENTATION);

Filed Issue #1570 - fixed as of revision #4305


Morning Musings (can safely be ignored :-)

The technical reason is improper constructor chaining: inserting the default should be handled by the do-it-all constructor (alternatively it should throw a NPE)

public ListAdaptor(JList list, JTextComponent textComponent) {
    this(list, textComponent, ObjectToStringConverter.DEFAULT_IMPLEMENTATION);
}

public ListAdaptor(JList list, JTextComponent textComponent, ObjectToStringConverter stringConverter) {
    this.list = list;
    this.textComponent = textComponent;
    this.stringConverter = stringConverter;
    // when a new item is selected set and mark the text
    list.addListSelectionListener(this);
}

The underlying reason is a subtle shift in ownership of the converter: its usual owner is the custom document which handles the autoComplete, this document guards itself against a null. With a JList variant, its the ListAdaptor which is not accustomed to that burden ... The shift is not incorrect (in fact, the exact way to go), just introduces an ever so slight inconsistency which is easy to overlook.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
0
AutoCompleteDecorator.decorate(dataList, test, false)

just add false settings

or just like these

boolean strictMatching = false;  
AutoCompleteDecorator.decorate(UName,items,strictMatching);
kelvz
  • 87
  • 1
  • 2
  • 13