glazedlists
  1. glazedlists
  2. GLAZEDLISTS-458

AutoCompleteSupport causes IndexOutOfBoundsException

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.7.0
    • Fix Version/s: milestone 1
    • Component/s: swing
    • Labels:
      None
    • Environment:

      Operating System: Mac OS X
      Platform: Macintosh

    • Issuezilla Id:
      458

      Description

      I get the Exception when i erase with backspace after adding text that doesn't match any of the available options.

      Here is my simple test class that i used to reproduce the bug:

      import ca.odell.glazedlists.EventList;
      import ca.odell.glazedlists.GlazedLists;
      import ca.odell.glazedlists.swing.AutoCompleteSupport;
      import java.util.ArrayList;
      import java.util.List;
      import javax.swing.JComboBox;

      public class AutoCompleteBug extends javax.swing.JDialog {

      public AutoCompleteBug(java.awt.Frame parent, boolean modal)

      { super(parent, modal); JComboBox jComboBox1 = new JComboBox(); add(jComboBox1); jComboBox1.setVisible(true); pack(); AutoCompleteSupport<String> support; List<String> list = new ArrayList(); list.add("abc"); list.add("bcd"); list.add("cde"); EventList<String> eventList = GlazedLists.eventList(list); support = AutoCompleteSupport.install(jComboBox1, eventList); support.setStrict(false); }

      public static void main(String args[]) {
      java.awt.EventQueue.invokeLater(new Runnable() {

      public void run() {
      AutoCompleteBug dialog = new AutoCompleteBug(new javax.swing.JFrame(), true);
      dialog.addWindowListener(new java.awt.event.WindowAdapter() {

      @Override
      public void windowClosing(java.awt.event.WindowEvent e)

      { System.exit(0); }

      });
      dialog.setVisible(true);
      }
      });
      }
      }

      Here are my steps to reproduce the bug:

      1. Compile the class and then run it.
      2. Type "as" into the textfield
      3. Erase the "s" by pressing backspace key.
      4. In standard out i get:

      Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
      at java.util.ArrayList.RangeCheck(ArrayList.java:547)
      at java.util.ArrayList.get(ArrayList.java:322)
      at ca.odell.glazedlists.impl.gui.ThreadProxyEventList.applyChangeToCache(ThreadProxyEventList.java:146)
      at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.listChanged(ThreadProxyEventList.java:196)
      at ca.odell.glazedlists.event.ListEventAssembler$ListSequencePublisherAdapter$ListEventFormat.fire(ListEventAssembler.java:869)
      at ca.odell.glazedlists.event.ListEventAssembler$ListSequencePublisherAdapter$ListEventFormat.fire(ListEventAssembler.java:861)
      at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:435)
      at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:334)
      at ca.odell.glazedlists.event.ListEventAssembler$ListSequencePublisherAdapter.fireEvent(ListEventAssembler.java:855)
      at ca.odell.glazedlists.event.ListEventAssembler$AssemblerHelper.commitEvent(ListEventAssembler.java:389)
      at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:226)
      at ca.odell.glazedlists.FilterList.constrained(FilterList.java:375)
      at ca.odell.glazedlists.FilterList.changeMatcher(FilterList.java:277)
      at ca.odell.glazedlists.FilterList.changeMatcherWithLocks(FilterList.java:260)
      at ca.odell.glazedlists.FilterList.access$100(FilterList.java:45)
      at ca.odell.glazedlists.FilterList$PrivateMatcherEditorListener.changedMatcher(FilterList.java:428)
      at ca.odell.glazedlists.matchers.AbstractMatcherEditor.fireChangedMatcher(AbstractMatcherEditor.java:101)
      at ca.odell.glazedlists.matchers.AbstractMatcherEditor.fireConstrained(AbstractMatcherEditor.java:73)
      at ca.odell.glazedlists.matchers.TextMatcherEditor.setFilterText(TextMatcherEditor.java:163)
      at ca.odell.glazedlists.swing.AutoCompleteSupport.applyFilter(AutoCompleteSupport.java:984)
      at ca.odell.glazedlists.swing.AutoCompleteSupport.access$2200(AutoCompleteSupport.java:154)
      at ca.odell.glazedlists.swing.AutoCompleteSupport$AutoCompleteFilter.postProcessDocumentChange(AutoCompleteSupport.java:1169)
      at ca.odell.glazedlists.swing.AutoCompleteSupport$AutoCompleteFilter.remove(AutoCompleteSupport.java:1120)
      at javax.swing.text.AbstractDocument.remove(AbstractDocument.java:573)
      at javax.swing.text.DefaultEditorKit$DeletePrevCharAction.actionPerformed(DefaultEditorKit.java:1050)
      at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1641)
      at javax.swing.JComponent.processKeyBinding(JComponent.java:2849)
      at javax.swing.JComponent.processKeyBindings(JComponent.java:2884)
      at javax.swing.JComponent.processKeyEvent(JComponent.java:2812)
      at java.awt.Component.processEvent(Component.java:5903)
      at java.awt.Container.processEvent(Container.java:2102)
      at java.awt.Component.dispatchEventImpl(Component.java:4497)
      at java.awt.Container.dispatchEventImpl(Container.java:2160)
      at java.awt.Component.dispatchEvent(Component.java:4327)
      at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
      at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:697)
      at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:962)
      at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:834)
      at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:661)
      at java.awt.Component.dispatchEventImpl(Component.java:4369)
      at java.awt.Container.dispatchEventImpl(Container.java:2160)
      at java.awt.Window.dispatchEventImpl(Window.java:2440)
      at java.awt.Component.dispatchEvent(Component.java:4327)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:300)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:210)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:204)
      at java.awt.Dialog$1.run(Dialog.java:1045)
      at java.awt.Dialog$3.run(Dialog.java:1097)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.awt.Dialog.show(Dialog.java:1095)
      at java.awt.Component.show(Component.java:1422)
      at java.awt.Component.setVisible(Component.java:1375)
      at java.awt.Window.setVisible(Window.java:806)
      at java.awt.Dialog.setVisible(Dialog.java:985)
      at AutoCompleteBug$1.run(AutoCompleteBug.java:40)
      at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:300)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:210)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:200)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:195)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:187)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

        Activity

        Hide
        jplemieux added a comment -

        I am unable to reproduce this defect in the latest nightly build running on
        Windows (the only box I have). The OS is filled in as Mac OS, so I can't be
        certain this defect no longer exists unless someone tests the latest build on
        Mac OS. The jars can be found here:

        https://glazedlists.dev.java.net/servlets/ProjectDocumentList?folderID=3916&expandFolder=3916&folderID=0

        Show
        jplemieux added a comment - I am unable to reproduce this defect in the latest nightly build running on Windows (the only box I have). The OS is filled in as Mac OS, so I can't be certain this defect no longer exists unless someone tests the latest build on Mac OS. The jars can be found here: https://glazedlists.dev.java.net/servlets/ProjectDocumentList?folderID=3916&expandFolder=3916&folderID=0
        Hide
        niklass added a comment -

        Tested with the latest build on mac os x and the defect still excists.

        I also tried it under windows and this defect does not apply to windows, only for mac.

        Show
        niklass added a comment - Tested with the latest build on mac os x and the defect still excists. I also tried it under windows and this defect does not apply to windows, only for mac.
        Hide
        jplemieux added a comment -

        Jesse did some debugging on this defect tonight, but we haven't yet located the
        root cause of the problem. It appears to be related to a pair of ListEvents
        generated back-to-back when you delete the "s". But, if this is true, it is
        difficult to explain why it doesn't also blow up in the same way on Windows.

        Show
        jplemieux added a comment - Jesse did some debugging on this defect tonight, but we haven't yet located the root cause of the problem. It appears to be related to a pair of ListEvents generated back-to-back when you delete the "s". But, if this is true, it is difficult to explain why it doesn't also blow up in the same way on Windows.
        Hide
        jplemieux added a comment -

        Jesse and I did a bunch of pair debugging on his Mac last night. This issue is
        caused by behaviour found only the Mac LnF (which explains why the same code
        works fine on Windows).

        The bug occurs when typing the "s" character in the use case mentioned in this
        defect. Here is what happens:

        1) the FilterList is told to filter using the String "as" which filters away all
        items (since "abc", "bcd", "cde" do not contain the filter term "as")
        2) a ListDataEvent is broadcast from the AutoCompleteComboBoxModel
        3) the apple.laf.CUIAquaComboBoxPopup is notified that the
        AutoCompleteComboBoxModel is empty and it fires an event to
        PopupSizer.popupMenuWillBecomeInvisible
        4) PopupSizer.popupMenuWillBecomeInvisible responds by trying to unfilter the
        AutoCompleteComboBoxModel. We do this because the idea is that all items
        should be present in the AutoCompleteComboBoxModel if the popup is not trying to
        show those elements. This preserves programmatic access to the model's elements
        for our API users.

        So, in simpler terms, step 4) in the above chain is really a ListEvent that is
        triggering the start of ANOTHER ListEvent on the same pipeline before the FIRST
        ListEvent is completely fired. That's not a good thing. In fact, that's a pretty
        bad thing. Old GL code in ListEventAssembler used to just ignore the attempt to
        begin a new ListEvent but we have checked in a fast-fail check now that will
        throw an Exception if you attempt to build a new ListEvent while you are
        currently firing an existing ListEvent in the same pipeline.

        We've decided that we probably won't include whatever fix we design for this
        problem in the 1.8 release because the possbility of destabilizing the rest of
        the implementation is moderately high. We know, fully, that this leaves
        AutoCompleteSupport broken on the Mac for the time being, and we'll do our best
        to try to get a fix into a nightly build shortly after 1.8 is released.

        Show
        jplemieux added a comment - Jesse and I did a bunch of pair debugging on his Mac last night. This issue is caused by behaviour found only the Mac LnF (which explains why the same code works fine on Windows). The bug occurs when typing the "s" character in the use case mentioned in this defect. Here is what happens: 1) the FilterList is told to filter using the String "as" which filters away all items (since "abc", "bcd", "cde" do not contain the filter term "as") 2) a ListDataEvent is broadcast from the AutoCompleteComboBoxModel 3) the apple.laf.CUIAquaComboBoxPopup is notified that the AutoCompleteComboBoxModel is empty and it fires an event to PopupSizer.popupMenuWillBecomeInvisible 4) PopupSizer.popupMenuWillBecomeInvisible responds by trying to unfilter the AutoCompleteComboBoxModel. We do this because the idea is that all items should be present in the AutoCompleteComboBoxModel if the popup is not trying to show those elements. This preserves programmatic access to the model's elements for our API users. So, in simpler terms, step 4) in the above chain is really a ListEvent that is triggering the start of ANOTHER ListEvent on the same pipeline before the FIRST ListEvent is completely fired. That's not a good thing. In fact, that's a pretty bad thing. Old GL code in ListEventAssembler used to just ignore the attempt to begin a new ListEvent but we have checked in a fast-fail check now that will throw an Exception if you attempt to build a new ListEvent while you are currently firing an existing ListEvent in the same pipeline. We've decided that we probably won't include whatever fix we design for this problem in the 1.8 release because the possbility of destabilizing the rest of the implementation is moderately high. We know, fully, that this leaves AutoCompleteSupport broken on the Mac for the time being, and we'll do our best to try to get a fix into a nightly build shortly after 1.8 is released.

          People

          • Assignee:
            jessewilson
            Reporter:
            niklass
          • Votes:
            2 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: