any recommendations?

Discussion in 'Java' started by Brandon McCombs, Feb 5, 2007.

  1. Hello,

    Somewhere in my code I have a bug that I can't reliably reproduce. It
    occurs randomly when I'm deleting entries from a JList (I retrieve
    certain pieces of info from the entry before deleting it, then I delete
    it and the JList contents are then refreshed so remaining items are
    re-added to the JList). The only output I get when the exception occurs
    is the following:

    Exception in thread "AWT-EventQueue-0"
    java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    at java.util.Vector.elementAt(Unknown Source)
    at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
    at javax.swing.plaf.ComponentUI.update(Unknown Source)
    at javax.swing.JComponent.paintComponent(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintWithOffscreenBuffer(Unknown Source)
    at javax.swing.JComponent.paintDoubleBuffered(Unknown Source)
    at javax.swing.JComponent._paintImmediately(Unknown Source)
    at javax.swing.JComponent.paintImmediately(Unknown Source)
    at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    at
    javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown
    Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)


    The "1" as the index value differs between exception printouts. I don't
    know where that index value is originating from or what Vector is really
    having its elements retrieved. The index value doesn't correspond to
    the index of the Object that I'm selecting for deletion. I've placed
    try/catches throughout the places where I thought was causing the
    exception to print out a stacktrace that I hoped would include a line
    number but I'm not getting any extra output. I also would put in a print
    statement so I knew which try/catch was being executed but I don't see
    that outputted either.

    When the JList is refreshed it is done so through a thread. I've tried
    to use run() to make the thread do its work but not in a thread and I
    don't get the exception but since I can't reproduce it reliably I don't
    know if it's really a threading problem or not. Using Eclipse's
    debugger also doesn't help so far because I can't get the error to occur
    during the debugging, at least not yet.

    Is there anything else I can try that can give me more information as to
    what line in my code this is occurring on so I can begin to fix it?

    thanks
    Brandon McCombs, Feb 5, 2007
    #1
    1. Advertising

  2. Brandon McCombs wrote:
    > Hello,
    >
    > Somewhere in my code I have a bug that I can't reliably reproduce. It
    > occurs randomly when I'm deleting entries from a JList (I retrieve
    > certain pieces of info from the entry before deleting it, then I delete
    > it and the JList contents are then refreshed so remaining items are
    > re-added to the JList). The only output I get when the exception occurs
    > is the following:
    >
    > Exception in thread "AWT-EventQueue-0"
    > java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    > at java.util.Vector.elementAt(Unknown Source)
    > at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    > at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    > at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
    > at javax.swing.plaf.ComponentUI.update(Unknown Source)
    > at javax.swing.JComponent.paintComponent(Unknown Source)
    > at javax.swing.JComponent.paint(Unknown Source)
    > at javax.swing.JComponent.paintWithOffscreenBuffer(Unknown Source)
    > at javax.swing.JComponent.paintDoubleBuffered(Unknown Source)
    > at javax.swing.JComponent._paintImmediately(Unknown Source)
    > at javax.swing.JComponent.paintImmediately(Unknown Source)
    > at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    > at
    > javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown
    > Source)
    > at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    > at java.awt.EventQueue.dispatchEvent(Unknown Source)
    > at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown
    > Source)
    > at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    > at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    > at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    > at java.awt.EventDispatchThread.run(Unknown Source)
    >
    >
    > The "1" as the index value differs between exception printouts. I don't
    > know where that index value is originating from or what Vector is really
    > having its elements retrieved. The index value doesn't correspond to
    > the index of the Object that I'm selecting for deletion. I've placed
    > try/catches throughout the places where I thought was causing the
    > exception to print out a stacktrace that I hoped would include a line
    > number but I'm not getting any extra output. I also would put in a print
    > statement so I knew which try/catch was being executed but I don't see
    > that outputted either.
    >
    > When the JList is refreshed it is done so through a thread. I've tried
    > to use run() to make the thread do its work but not in a thread and I
    > don't get the exception but since I can't reproduce it reliably I don't
    > know if it's really a threading problem or not. Using Eclipse's
    > debugger also doesn't help so far because I can't get the error to occur
    > during the debugging, at least not yet.
    >
    > Is there anything else I can try that can give me more information as to
    > what line in my code this is occurring on so I can begin to fix it?
    >
    > thanks


    Are you modifying the JList on the EDT? Are you modifying the Vector
    after creating your JList? Can you make a simple test program that
    demonstrates the problem?

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 5, 2007
    #2
    1. Advertising

  3. Knute Johnson wrote:
    > Brandon McCombs wrote:
    >> Hello,
    >>
    >> Somewhere in my code I have a bug that I can't reliably reproduce. It
    >> occurs randomly when I'm deleting entries from a JList (I retrieve
    >> certain pieces of info from the entry before deleting it, then I
    >> delete it and the JList contents are then refreshed so remaining items
    >> are re-added to the JList). The only output I get when the exception
    >> occurs is the following:
    >>
    >> Exception in thread "AWT-EventQueue-0"
    >> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >> at java.util.Vector.elementAt(Unknown Source)
    >> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)

    [snip]
    >>
    >>
    >> The "1" as the index value differs between exception printouts. I
    >> don't know where that index value is originating from or what Vector
    >> is really having its elements retrieved. The index value doesn't
    >> correspond to the index of the Object that I'm selecting for deletion.
    >> I've placed try/catches throughout the places where I thought was
    >> causing the exception to print out a stacktrace that I hoped would
    >> include a line number but I'm not getting any extra output. I also
    >> would put in a print statement so I knew which try/catch was being
    >> executed but I don't see that outputted either.
    >>
    >> When the JList is refreshed it is done so through a thread. I've tried
    >> to use run() to make the thread do its work but not in a thread and I
    >> don't get the exception but since I can't reproduce it reliably I
    >> don't know if it's really a threading problem or not. Using Eclipse's
    >> debugger also doesn't help so far because I can't get the error to
    >> occur during the debugging, at least not yet.
    >>
    >> Is there anything else I can try that can give me more information as
    >> to what line in my code this is occurring on so I can begin to fix it?
    >>
    >> thanks

    >
    > Are you modifying the JList on the EDT? Are you modifying the Vector
    > after creating your JList? Can you make a simple test program that
    > demonstrates the problem?
    >


    The code that the Thread class uses to tell the JList when to update is
    this:

    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    component.updateGUI(results);
    component.resetGUI(results);
    }
    });

    Component is the class that contains my GUI which is a JTree and JList
    in a JSplitPane; component is passed into the Thread's constructor.

    Results is a Vector that contains the results of a LDAP search which
    will be put into the JList.

    Yes I'm modifying the Vector. Since the JList can have entries
    added/modified/removed the Vector will obviously be changed accordingly
    (as I state in the original mesg). I can't make a simple test program
    because I don't know where the problem is. If I did I wouldn't have
    posted this because I'd be working on figuring out a way to fix it. The
    problem could be in a lot of places and ripping out stuff to duplicate
    the problem would be a waste of time I believe since I can't reproduce
    it not to mention the code involved is spread across multiple classes.
    To test it I'm having to create temporary entries in my LDAP server and
    then delete them one by one to see if the error occurs. Sometimes I
    delete 50 before it crops up, other times I delete 1 and the index value
    mentioned in the exception never corresponds with the deleted entry.

    I'm mainly asking if there is a way to glean more info from the
    exception information. I can't believe it isn't giving me a line number
    to review. Is the printout I originally posted the only stack trace
    information available from the JVM? I've put whole method bodies in a
    try/catch and I don't get any more information so either I won't get
    more information or I'm putting try/catches in the wrong place. Can the
    JVM be launched with options that will help?

    Brandon
    Brandon McCombs, Feb 5, 2007
    #3
  4. Brandon McCombs wrote:
    > Knute Johnson wrote:
    >> Brandon McCombs wrote:
    >>> Hello,
    >>>
    >>> Somewhere in my code I have a bug that I can't reliably reproduce. It
    >>> occurs randomly when I'm deleting entries from a JList (I retrieve
    >>> certain pieces of info from the entry before deleting it, then I
    >>> delete it and the JList contents are then refreshed so remaining
    >>> items are re-added to the JList). The only output I get when the
    >>> exception occurs is the following:
    >>>
    >>> Exception in thread "AWT-EventQueue-0"
    >>> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >>> at java.util.Vector.elementAt(Unknown Source)
    >>> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >>> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >>> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)

    > [snip]
    >>>
    >>>
    >>> The "1" as the index value differs between exception printouts. I
    >>> don't know where that index value is originating from or what Vector
    >>> is really having its elements retrieved. The index value doesn't
    >>> correspond to the index of the Object that I'm selecting for
    >>> deletion. I've placed try/catches throughout the places where I
    >>> thought was causing the exception to print out a stacktrace that I
    >>> hoped would include a line number but I'm not getting any extra
    >>> output. I also would put in a print statement so I knew which
    >>> try/catch was being executed but I don't see that outputted either.
    >>>
    >>> When the JList is refreshed it is done so through a thread. I've
    >>> tried to use run() to make the thread do its work but not in a thread
    >>> and I don't get the exception but since I can't reproduce it reliably
    >>> I don't know if it's really a threading problem or not. Using
    >>> Eclipse's debugger also doesn't help so far because I can't get the
    >>> error to occur during the debugging, at least not yet.
    >>>
    >>> Is there anything else I can try that can give me more information as
    >>> to what line in my code this is occurring on so I can begin to fix it?
    >>>
    >>> thanks

    >>
    >> Are you modifying the JList on the EDT? Are you modifying the Vector
    >> after creating your JList? Can you make a simple test program that
    >> demonstrates the problem?
    >>

    >
    > The code that the Thread class uses to tell the JList when to update is
    > this:
    >
    > SwingUtilities.invokeLater(new Runnable() {
    > public void run() {
    > component.updateGUI(results);
    > component.resetGUI(results);
    > }
    > });
    >
    > Component is the class that contains my GUI which is a JTree and JList
    > in a JSplitPane; component is passed into the Thread's constructor.
    >
    > Results is a Vector that contains the results of a LDAP search which
    > will be put into the JList.
    >
    > Yes I'm modifying the Vector. Since the JList can have entries
    > added/modified/removed the Vector will obviously be changed accordingly
    > (as I state in the original mesg). I can't make a simple test program
    > because I don't know where the problem is. If I did I wouldn't have
    > posted this because I'd be working on figuring out a way to fix it. The
    > problem could be in a lot of places and ripping out stuff to duplicate
    > the problem would be a waste of time I believe since I can't reproduce
    > it not to mention the code involved is spread across multiple classes.
    > To test it I'm having to create temporary entries in my LDAP server and
    > then delete them one by one to see if the error occurs. Sometimes I
    > delete 50 before it crops up, other times I delete 1 and the index value
    > mentioned in the exception never corresponds with the deleted entry.
    >
    > I'm mainly asking if there is a way to glean more info from the
    > exception information. I can't believe it isn't giving me a line number
    > to review. Is the printout I originally posted the only stack trace
    > information available from the JVM? I've put whole method bodies in a
    > try/catch and I don't get any more information so either I won't get
    > more information or I'm putting try/catches in the wrong place. Can the
    > JVM be launched with options that will help?
    >
    > Brandon


    Brandon:

    I think you are attempting to access a non-existing element or you've
    been modifying the Vector itself which is not good either. If you want
    to add and remove elements from a JList you need to use a ListModel that
    is read/write. So since you can't make a test program, shows us
    snippets of the critical code where you create the JList and modify it.

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 5, 2007
    #4
  5. Knute Johnson wrote:
    > Brandon McCombs wrote:
    >> Knute Johnson wrote:
    >>> Brandon McCombs wrote:
    >>>> Hello,
    >>>>
    >>>> Somewhere in my code I have a bug that I can't reliably reproduce.
    >>>> It occurs randomly when I'm deleting entries from a JList (I
    >>>> retrieve certain pieces of info from the entry before deleting it,
    >>>> then I delete it and the JList contents are then refreshed so
    >>>> remaining items are re-added to the JList). The only output I get
    >>>> when the exception occurs is the following:
    >>>>
    >>>> Exception in thread "AWT-EventQueue-0"
    >>>> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >>>> at java.util.Vector.elementAt(Unknown Source)
    >>>> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >>>> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >>>> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)

    >> [snip]
    >>>>
    >>>>
    >>>> The "1" as the index value differs between exception printouts. I
    >>>> don't know where that index value is originating from or what Vector
    >>>> is really having its elements retrieved. The index value doesn't
    >>>> correspond to the index of the Object that I'm selecting for
    >>>> deletion. I've placed try/catches throughout the places where I
    >>>> thought was causing the exception to print out a stacktrace that I
    >>>> hoped would include a line number but I'm not getting any extra
    >>>> output. I also would put in a print statement so I knew which
    >>>> try/catch was being executed but I don't see that outputted either.
    >>>>
    >>>> When the JList is refreshed it is done so through a thread. I've
    >>>> tried to use run() to make the thread do its work but not in a
    >>>> thread and I don't get the exception but since I can't reproduce it
    >>>> reliably I don't know if it's really a threading problem or not.
    >>>> Using Eclipse's debugger also doesn't help so far because I can't
    >>>> get the error to occur during the debugging, at least not yet.
    >>>>
    >>>> Is there anything else I can try that can give me more information
    >>>> as to what line in my code this is occurring on so I can begin to
    >>>> fix it?
    >>>>
    >>>> thanks
    >>>
    >>> Are you modifying the JList on the EDT? Are you modifying the Vector
    >>> after creating your JList? Can you make a simple test program that
    >>> demonstrates the problem?
    >>>

    >>
    >> The code that the Thread class uses to tell the JList when to update
    >> is this:
    >>
    >> SwingUtilities.invokeLater(new Runnable() {
    >> public void run() {
    >> component.updateGUI(results);
    >> component.resetGUI(results);
    >> }
    >> });
    >>
    >> Component is the class that contains my GUI which is a JTree and JList
    >> in a JSplitPane; component is passed into the Thread's constructor.
    >>
    >> Results is a Vector that contains the results of a LDAP search which
    >> will be put into the JList.
    >>
    >> Yes I'm modifying the Vector. Since the JList can have entries
    >> added/modified/removed the Vector will obviously be changed
    >> accordingly (as I state in the original mesg). I can't make a simple
    >> test program because I don't know where the problem is. If I did I
    >> wouldn't have posted this because I'd be working on figuring out a way
    >> to fix it. The problem could be in a lot of places and ripping out
    >> stuff to duplicate the problem would be a waste of time I believe
    >> since I can't reproduce it not to mention the code involved is spread
    >> across multiple classes. To test it I'm having to create temporary
    >> entries in my LDAP server and then delete them one by one to see if
    >> the error occurs. Sometimes I delete 50 before it crops up, other
    >> times I delete 1 and the index value mentioned in the exception never
    >> corresponds with the deleted entry.
    >>
    >> I'm mainly asking if there is a way to glean more info from the
    >> exception information. I can't believe it isn't giving me a line
    >> number to review. Is the printout I originally posted the only stack
    >> trace information available from the JVM? I've put whole method bodies
    >> in a try/catch and I don't get any more information so either I won't
    >> get more information or I'm putting try/catches in the wrong place.
    >> Can the JVM be launched with options that will help?
    >>
    >> Brandon

    >
    > Brandon:
    >
    > I think you are attempting to access a non-existing element or you've
    > been modifying the Vector itself which is not good either. If you want
    > to add and remove elements from a JList you need to use a ListModel that
    > is read/write. So since you can't make a test program, shows us
    > snippets of the critical code where you create the JList and modify it.
    >


    Well the deletion still works when I get the exception. I am doing the
    deletion by going through the ListModel for the JList which I thought
    was correct. I never knew you could create a read-only ListModel.

    I use the following as the constructor to my BrowserModel class which
    contains 2 models for my Browser (JTree and JList I mentioned before):

    public BrowserModel(Node root) {
    this.root = (Node)root.getChildAt(0);
    tree = new DefaultTreeModel(root);
    list = new DefaultListModel();
    }

    The method I call for deleting a selected item from the JList is the
    following (model is the instance of BrowserModel):

    private void list_deleteObj() {
    int idx = dirList.getSelectedIndex();
    String dn = LDAPMgr.ldapUtility.getDN(
    model.getListModel().getElementAt(idx) );
    int ans = JOptionPane.showConfirmDialog(this,
    "Confirm delete for:\n" + dn + "\n",
    "Delete Object", JOptionPane.YES_NO_OPTION,
    JOptionPane.PLAIN_MESSAGE);
    if (ans == 1)
    return;
    String msg = null;
    msg = LDAPMgr.ldapUtility.deleteEntry(
    model.getListModel().getElementAt(idx));
    /* if successful */
    if (msg == null) {
    model.getListModel().remove(idx);
    /* reload the subtree and list to show deletion */
    refresh();
    }
    }

    The idx in the code above rarely matches (if ever) the index value
    listed in the generated exception and again, the deletion above still
    works when the exception is generated. Refresh() essentially determines
    which node in the JTree needs refreshing and then calls expand(node,
    node.getDN()). Expand() removes all the node's current children and
    spawns the thread to retrieve the current children. The items in the
    JList are the children of the selected Node in the JTree.

    The thread is spawned with this:

    selectedNode = node;
    searchBase = dn;
    if (asyncSearch != null)
    asyncSearch.stopSearch(); //allow 1 search at a time
    asyncSearch = new AsyncSearch(this);
    asyncSearch.setSearchBase(searchBase);
    asyncSearch.setFilter("(objectClass=*)");
    asyncSearch.setReturnedAttributes("*");
    asyncSearch.setScope(1);
    asyncSearch.start();

    That calls a method that executes a LDAP search and passes the results
    back to the Browser class by calling updateGUI() from the Browser.
    Within updateGUI() the Browser populates the selected node's children in
    the JTree as well as the JList (which is just another view of the node's
    children). If I do this whole process enough times I get the
    aforementioned exception.

    I hope that description is helpful and understandable.
    If you can figure this one out I'd appreciate it because I don't even
    know where to look since nothing is making sense (index values not
    matching up, deletion still works).


    thanks for the help
    Brandon McCombs, Feb 5, 2007
    #5
  6. Brandon McCombs wrote:
    > Knute Johnson wrote:
    >> Brandon McCombs wrote:
    >>> Knute Johnson wrote:
    >>>> Brandon McCombs wrote:
    >>>>> Hello,
    >>>>>
    >>>>> Somewhere in my code I have a bug that I can't reliably reproduce.
    >>>>> It occurs randomly when I'm deleting entries from a JList (I
    >>>>> retrieve certain pieces of info from the entry before deleting it,
    >>>>> then I delete it and the JList contents are then refreshed so
    >>>>> remaining items are re-added to the JList). The only output I get
    >>>>> when the exception occurs is the following:
    >>>>>
    >>>>> Exception in thread "AWT-EventQueue-0"
    >>>>> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >>>>> at java.util.Vector.elementAt(Unknown Source)
    >>>>> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >>>>> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >>>>> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
    >>> [snip]
    >>>>>
    >>>>>
    >>>>> The "1" as the index value differs between exception printouts. I
    >>>>> don't know where that index value is originating from or what
    >>>>> Vector is really having its elements retrieved. The index value
    >>>>> doesn't correspond to the index of the Object that I'm selecting
    >>>>> for deletion. I've placed try/catches throughout the places where I
    >>>>> thought was causing the exception to print out a stacktrace that I
    >>>>> hoped would include a line number but I'm not getting any extra
    >>>>> output. I also would put in a print statement so I knew which
    >>>>> try/catch was being executed but I don't see that outputted either.
    >>>>>
    >>>>> When the JList is refreshed it is done so through a thread. I've
    >>>>> tried to use run() to make the thread do its work but not in a
    >>>>> thread and I don't get the exception but since I can't reproduce it
    >>>>> reliably I don't know if it's really a threading problem or not.
    >>>>> Using Eclipse's debugger also doesn't help so far because I can't
    >>>>> get the error to occur during the debugging, at least not yet.
    >>>>>
    >>>>> Is there anything else I can try that can give me more information
    >>>>> as to what line in my code this is occurring on so I can begin to
    >>>>> fix it?
    >>>>>
    >>>>> thanks
    >>>>
    >>>> Are you modifying the JList on the EDT? Are you modifying the
    >>>> Vector after creating your JList? Can you make a simple test
    >>>> program that demonstrates the problem?
    >>>>
    >>>
    >>> The code that the Thread class uses to tell the JList when to update
    >>> is this:
    >>>
    >>> SwingUtilities.invokeLater(new Runnable() {
    >>> public void run() {
    >>> component.updateGUI(results);
    >>> component.resetGUI(results);
    >>> }
    >>> });
    >>>
    >>> Component is the class that contains my GUI which is a JTree and
    >>> JList in a JSplitPane; component is passed into the Thread's
    >>> constructor.
    >>>
    >>> Results is a Vector that contains the results of a LDAP search which
    >>> will be put into the JList.
    >>>
    >>> Yes I'm modifying the Vector. Since the JList can have entries
    >>> added/modified/removed the Vector will obviously be changed
    >>> accordingly (as I state in the original mesg). I can't make a simple
    >>> test program because I don't know where the problem is. If I did I
    >>> wouldn't have posted this because I'd be working on figuring out a
    >>> way to fix it. The problem could be in a lot of places and ripping
    >>> out stuff to duplicate the problem would be a waste of time I believe
    >>> since I can't reproduce it not to mention the code involved is spread
    >>> across multiple classes. To test it I'm having to create temporary
    >>> entries in my LDAP server and then delete them one by one to see if
    >>> the error occurs. Sometimes I delete 50 before it crops up, other
    >>> times I delete 1 and the index value mentioned in the exception never
    >>> corresponds with the deleted entry.
    >>>
    >>> I'm mainly asking if there is a way to glean more info from the
    >>> exception information. I can't believe it isn't giving me a line
    >>> number to review. Is the printout I originally posted the only stack
    >>> trace information available from the JVM? I've put whole method
    >>> bodies in a try/catch and I don't get any more information so either
    >>> I won't get more information or I'm putting try/catches in the wrong
    >>> place. Can the JVM be launched with options that will help?
    >>>
    >>> Brandon

    >>
    >> Brandon:
    >>
    >> I think you are attempting to access a non-existing element or you've
    >> been modifying the Vector itself which is not good either. If you
    >> want to add and remove elements from a JList you need to use a
    >> ListModel that is read/write. So since you can't make a test program,
    >> shows us snippets of the critical code where you create the JList and
    >> modify it.
    >>

    >
    > Well the deletion still works when I get the exception. I am doing the
    > deletion by going through the ListModel for the JList which I thought
    > was correct. I never knew you could create a read-only ListModel.
    >
    > I use the following as the constructor to my BrowserModel class which
    > contains 2 models for my Browser (JTree and JList I mentioned before):
    >
    > public BrowserModel(Node root) {
    > this.root = (Node)root.getChildAt(0);
    > tree = new DefaultTreeModel(root);
    > list = new DefaultListModel();
    > }
    >
    > The method I call for deleting a selected item from the JList is the
    > following (model is the instance of BrowserModel):
    >
    > private void list_deleteObj() {
    > int idx = dirList.getSelectedIndex();
    > String dn = LDAPMgr.ldapUtility.getDN(
    > model.getListModel().getElementAt(idx) );
    > int ans = JOptionPane.showConfirmDialog(this,
    > "Confirm delete for:\n" + dn + "\n",
    > "Delete Object",
    > JOptionPane.YES_NO_OPTION,
    > JOptionPane.PLAIN_MESSAGE);
    > if (ans == 1)
    > return;
    > String msg = null;
    > msg = LDAPMgr.ldapUtility.deleteEntry(
    > model.getListModel().getElementAt(idx));
    > /* if successful */
    > if (msg == null) {
    > model.getListModel().remove(idx);
    > /* reload the subtree and list to show deletion */
    > refresh();
    > }
    > }
    >
    > The idx in the code above rarely matches (if ever) the index value
    > listed in the generated exception and again, the deletion above still
    > works when the exception is generated. Refresh() essentially determines
    > which node in the JTree needs refreshing and then calls expand(node,
    > node.getDN()). Expand() removes all the node's current children and
    > spawns the thread to retrieve the current children. The items in the
    > JList are the children of the selected Node in the JTree.
    >
    > The thread is spawned with this:
    >
    > selectedNode = node;
    > searchBase = dn;
    > if (asyncSearch != null)
    > asyncSearch.stopSearch(); //allow 1 search at a time
    > asyncSearch = new AsyncSearch(this);
    > asyncSearch.setSearchBase(searchBase);
    > asyncSearch.setFilter("(objectClass=*)");
    > asyncSearch.setReturnedAttributes("*");
    > asyncSearch.setScope(1);
    > asyncSearch.start();
    >
    > That calls a method that executes a LDAP search and passes the results
    > back to the Browser class by calling updateGUI() from the Browser.
    > Within updateGUI() the Browser populates the selected node's children in
    > the JTree as well as the JList (which is just another view of the node's
    > children). If I do this whole process enough times I get the
    > aforementioned exception.
    >
    > I hope that description is helpful and understandable.
    > If you can figure this one out I'd appreciate it because I don't even
    > know where to look since nothing is making sense (index values not
    > matching up, deletion still works).
    >
    >
    > thanks for the help


    Brandon:

    I don't see anything there, nothing looks out of the ordinary. Any
    chance that you've got a concurrency problem? Or maybe you are setting
    the size of the ListModel before trying to remove the element?

    I think this is going to be hard to find without a simpler test program.
    I had a problem like that once though that I couldn't duplicate. I
    ended up solving it by synchronizing access to the method where I
    thought the problem was occurring. That was kind of a shotgun approach.

    Sorry I can't be more help.

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 5, 2007
    #6
  7. Brandon McCombs wrote:
    >>>>>
    >>>>> Exception in thread "AWT-EventQueue-0"
    >>>>> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >>>>> at java.util.Vector.elementAt(Unknown Source)
    >>>>> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >>>>> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >>>>> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
    >>> [snip]

    > Well the deletion still works when I get the exception. I am doing the
    > deletion by going through the ListModel for the JList which I thought
    > was correct. I never knew you could create a read-only ListModel.


    NB: a ListModel *is* read-only by default.

    >
    > The method I call for deleting a selected item from the JList is the
    > following (model is the instance of BrowserModel):
    >
    > private void list_deleteObj() {


    Is this method called from the EDT?

    >
    > The idx in the code above rarely matches (if ever) the index value
    > listed in the generated exception and again, the deletion above still
    > works when the exception is generated. Refresh() essentially determines


    Sure, the exception originates from the UI-Delegate's paint method. Why
    would you expect the deletion not to work?

    The reason for the exception is usually a simple one: you're modifying
    the underlying ListModel in one thread while the EDT repaints the list.

    Imagine the following pseudo code as part of the painting procedure:

    int n = model.getSize();
    for ( int i = 0; i < n; i++ ) {
    // ...
    Object value = model.getElementAt(i);
    // ...
    }

    Let's consider a ListModel that contains 5 elements. The code above runs
    on the EDT, so it starts with n = 5 and enters the loop. Now, in another
    thread you delete one element from the ListModel so that
    model.getSize()==4. The loop continues until i=4, then an
    ArrayIndexOutOfBoundsException will be thrown, e.g.: 4 >= 4. If the
    second thread would have removed all elements from the ListModel, the
    exception is thrown immediately at the next model.getElementAt method
    call, e. g. 2 >= 0.

    >
    > The thread is spawned with this:
    >

    ....
    > asyncSearch = new AsyncSearch(this);

    ....
    > asyncSearch.start();


    Does AsynchSearch modify the ListModel? And if, how?

    Bye
    Michael
    Michael Rauscher, Feb 5, 2007
    #7
  8. Brandon McCombs

    Nigel Wade Guest

    Brandon McCombs wrote:


    > The method I call for deleting a selected item from the JList is the
    > following (model is the instance of BrowserModel):
    >
    > private void list_deleteObj() {
    > int idx = dirList.getSelectedIndex();
    > String dn = LDAPMgr.ldapUtility.getDN(
    > model.getListModel().getElementAt(idx) );
    > int ans = JOptionPane.showConfirmDialog(this,
    > "Confirm delete for:\n" + dn + "\n",
    > "Delete Object", JOptionPane.YES_NO_OPTION,
    > JOptionPane.PLAIN_MESSAGE);
    > if (ans == 1)
    > return;
    > String msg = null;
    > msg = LDAPMgr.ldapUtility.deleteEntry(
    > model.getListModel().getElementAt(idx));
    > /* if successful */
    > if (msg == null) {
    > model.getListModel().remove(idx);
    > /* reload the subtree and list to show deletion */
    > refresh();
    > }
    > }
    >


    What thread is the above method being executed on? If it's not the EDT you have
    a problem there, you are modifying the JList in a thread other than the EDT.

    The error is telling you that when the EDT came to draw a JList it tried to
    access element 1 and that element didn't exist in the the DefaultListModel's
    Vector at the time. That would imply a synchronization error, the Vector is in
    the process of being modified whilst it's being drawn (the JList and
    DefaultTreeModel have a different idea of how many elements there are), and I
    don't see how that can happen unless it's being modified from another thread -
    even the EDT can only do one thing at a time...

    --
    Nigel Wade, System Administrator, Space Plasma Physics Group,
    University of Leicester, Leicester, LE1 7RH, UK
    E-mail :
    Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
    Nigel Wade, Feb 5, 2007
    #8
  9. Michael Rauscher wrote:
    > Brandon McCombs wrote:
    >>>>>>
    >>>>>> Exception in thread "AWT-EventQueue-0"
    >>>>>> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >>>>>> at java.util.Vector.elementAt(Unknown Source)
    >>>>>> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >>>>>> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >>>>>> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
    >>>> [snip]

    >> Well the deletion still works when I get the exception. I am doing the
    >> deletion by going through the ListModel for the JList which I thought
    >> was correct. I never knew you could create a read-only ListModel.

    >
    > NB: a ListModel *is* read-only by default.
    >
    >>
    >> The method I call for deleting a selected item from the JList is the
    >> following (model is the instance of BrowserModel):
    >>
    >> private void list_deleteObj() {

    >
    > Is this method called from the EDT?


    currently it is not.
    >
    >>
    >> The idx in the code above rarely matches (if ever) the index value
    >> listed in the generated exception and again, the deletion above still
    >> works when the exception is generated. Refresh() essentially determines

    >
    > Sure, the exception originates from the UI-Delegate's paint method. Why
    > would you expect the deletion not to work?


    I never said I didn't expect it to work. I was notifying you guys that
    it still was in case you didn't know and needed to know.

    >
    > The reason for the exception is usually a simple one: you're modifying
    > the underlying ListModel in one thread while the EDT repaints the list.
    >
    > Imagine the following pseudo code as part of the painting procedure:
    >
    > int n = model.getSize();
    > for ( int i = 0; i < n; i++ ) {
    > // ...
    > Object value = model.getElementAt(i);
    > // ...
    > }
    >
    > Let's consider a ListModel that contains 5 elements. The code above runs
    > on the EDT, so it starts with n = 5 and enters the loop. Now, in another
    > thread you delete one element from the ListModel so that
    > model.getSize()==4. The loop continues until i=4, then an
    > ArrayIndexOutOfBoundsException will be thrown, e.g.: 4 >= 4. If the
    > second thread would have removed all elements from the ListModel, the
    > exception is thrown immediately at the next model.getElementAt method
    > call, e. g. 2 >= 0.


    ok that makes sense.

    >
    >>
    >> The thread is spawned with this:
    >>

    > ...
    >> asyncSearch = new AsyncSearch(this);

    > ...
    >> asyncSearch.start();

    >
    > Does AsynchSearch modify the ListModel? And if, how?


    no. It calls updateGUI() from the component that spawned the thread.
    Component is a constructor to that thread class and updateGUI() is an
    interface method of an interface I created for that purpose of letting
    the components (I got 3 of them) update themselves in their own ways.
    Only one of them is involved with this problem though. I'll work on
    making the delete method spawn from the EDT.

    I don't suppose you guys know of a way I can test this to know for sure
    it works?

    >
    > Bye
    > Michael
    Brandon McCombs, Feb 5, 2007
    #9
  10. Knute Johnson wrote:
    > Brandon McCombs wrote:
    >> Knute Johnson wrote:
    >>> Brandon McCombs wrote:
    >>>> Knute Johnson wrote:
    >>>>> Brandon McCombs wrote:
    >>>>>> Hello,
    >>>>>>
    >>>>>> Somewhere in my code I have a bug that I can't reliably reproduce.
    >>>>>> It occurs randomly when I'm deleting entries from a JList (I
    >>>>>> retrieve certain pieces of info from the entry before deleting it,
    >>>>>> then I delete it and the JList contents are then refreshed so
    >>>>>> remaining items are re-added to the JList). The only output I get
    >>>>>> when the exception occurs is the following:
    >>>>>>
    >>>>>> Exception in thread "AWT-EventQueue-0"
    >>>>>> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >>>>>> at java.util.Vector.elementAt(Unknown Source)
    >>>>>> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >>>>>> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >>>>>> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
    >>>> [snip]
    >>>>>>
    >>>>>>
    >>>>>> The "1" as the index value differs between exception printouts. I
    >>>>>> don't know where that index value is originating from or what
    >>>>>> Vector is really having its elements retrieved. The index value
    >>>>>> doesn't correspond to the index of the Object that I'm selecting
    >>>>>> for deletion. I've placed try/catches throughout the places where
    >>>>>> I thought was causing the exception to print out a stacktrace that
    >>>>>> I hoped would include a line number but I'm not getting any extra
    >>>>>> output. I also would put in a print statement so I knew which
    >>>>>> try/catch was being executed but I don't see that outputted either.
    >>>>>>
    >>>>>> When the JList is refreshed it is done so through a thread. I've
    >>>>>> tried to use run() to make the thread do its work but not in a
    >>>>>> thread and I don't get the exception but since I can't reproduce
    >>>>>> it reliably I don't know if it's really a threading problem or
    >>>>>> not. Using Eclipse's debugger also doesn't help so far because I
    >>>>>> can't get the error to occur during the debugging, at least not yet.
    >>>>>>
    >>>>>> Is there anything else I can try that can give me more information
    >>>>>> as to what line in my code this is occurring on so I can begin to
    >>>>>> fix it?
    >>>>>>
    >>>>>> thanks
    >>>>>
    >>>>> Are you modifying the JList on the EDT? Are you modifying the
    >>>>> Vector after creating your JList? Can you make a simple test
    >>>>> program that demonstrates the problem?
    >>>>>
    >>>>
    >>>> The code that the Thread class uses to tell the JList when to update
    >>>> is this:
    >>>>
    >>>> SwingUtilities.invokeLater(new Runnable() {
    >>>> public void run() {
    >>>> component.updateGUI(results);
    >>>> component.resetGUI(results);
    >>>> }
    >>>> });
    >>>>
    >>>> Component is the class that contains my GUI which is a JTree and
    >>>> JList in a JSplitPane; component is passed into the Thread's
    >>>> constructor.
    >>>>
    >>>> Results is a Vector that contains the results of a LDAP search which
    >>>> will be put into the JList.
    >>>>
    >>>> Yes I'm modifying the Vector. Since the JList can have entries
    >>>> added/modified/removed the Vector will obviously be changed
    >>>> accordingly (as I state in the original mesg). I can't make a simple
    >>>> test program because I don't know where the problem is. If I did I
    >>>> wouldn't have posted this because I'd be working on figuring out a
    >>>> way to fix it. The problem could be in a lot of places and ripping
    >>>> out stuff to duplicate the problem would be a waste of time I
    >>>> believe since I can't reproduce it not to mention the code involved
    >>>> is spread across multiple classes. To test it I'm having to create
    >>>> temporary entries in my LDAP server and then delete them one by one
    >>>> to see if the error occurs. Sometimes I delete 50 before it crops
    >>>> up, other times I delete 1 and the index value mentioned in the
    >>>> exception never corresponds with the deleted entry.
    >>>>
    >>>> I'm mainly asking if there is a way to glean more info from the
    >>>> exception information. I can't believe it isn't giving me a line
    >>>> number to review. Is the printout I originally posted the only stack
    >>>> trace information available from the JVM? I've put whole method
    >>>> bodies in a try/catch and I don't get any more information so either
    >>>> I won't get more information or I'm putting try/catches in the wrong
    >>>> place. Can the JVM be launched with options that will help?
    >>>>
    >>>> Brandon
    >>>
    >>> Brandon:
    >>>
    >>> I think you are attempting to access a non-existing element or you've
    >>> been modifying the Vector itself which is not good either. If you
    >>> want to add and remove elements from a JList you need to use a
    >>> ListModel that is read/write. So since you can't make a test
    >>> program, shows us snippets of the critical code where you create the
    >>> JList and modify it.
    >>>

    >>
    >> Well the deletion still works when I get the exception. I am doing the
    >> deletion by going through the ListModel for the JList which I thought
    >> was correct. I never knew you could create a read-only ListModel.
    >>
    >> I use the following as the constructor to my BrowserModel class which
    >> contains 2 models for my Browser (JTree and JList I mentioned before):
    >>
    >> public BrowserModel(Node root) {
    >> this.root = (Node)root.getChildAt(0);
    >> tree = new DefaultTreeModel(root);
    >> list = new DefaultListModel();
    >> }
    >>
    >> The method I call for deleting a selected item from the JList is the
    >> following (model is the instance of BrowserModel):
    >>
    >> private void list_deleteObj() {
    >> int idx = dirList.getSelectedIndex();
    >> String dn = LDAPMgr.ldapUtility.getDN(
    >> model.getListModel().getElementAt(idx) );
    >> int ans = JOptionPane.showConfirmDialog(this,
    >> "Confirm delete for:\n" + dn + "\n",
    >> "Delete Object",
    >> JOptionPane.YES_NO_OPTION,
    >> JOptionPane.PLAIN_MESSAGE);
    >> if (ans == 1)
    >> return;
    >> String msg = null;
    >> msg = LDAPMgr.ldapUtility.deleteEntry(
    >> model.getListModel().getElementAt(idx));
    >> /* if successful */
    >> if (msg == null) {
    >> model.getListModel().remove(idx);
    >> /* reload the subtree and list to show deletion */
    >> refresh();
    >> }
    >> }
    >>
    >> The idx in the code above rarely matches (if ever) the index value
    >> listed in the generated exception and again, the deletion above still
    >> works when the exception is generated. Refresh() essentially
    >> determines which node in the JTree needs refreshing and then calls
    >> expand(node, node.getDN()). Expand() removes all the node's current
    >> children and spawns the thread to retrieve the current children. The
    >> items in the JList are the children of the selected Node in the JTree.
    >>
    >> The thread is spawned with this:
    >>
    >> selectedNode = node;
    >> searchBase = dn;
    >> if (asyncSearch != null)
    >> asyncSearch.stopSearch(); //allow 1 search at a time
    >> asyncSearch = new AsyncSearch(this);
    >> asyncSearch.setSearchBase(searchBase);
    >> asyncSearch.setFilter("(objectClass=*)");
    >> asyncSearch.setReturnedAttributes("*");
    >> asyncSearch.setScope(1);
    >> asyncSearch.start();
    >> That calls a method that executes a LDAP search and passes the
    >> results back to the Browser class by calling updateGUI() from the
    >> Browser. Within updateGUI() the Browser populates the selected node's
    >> children in the JTree as well as the JList (which is just another view
    >> of the node's children). If I do this whole process enough times I get
    >> the aforementioned exception.
    >>
    >> I hope that description is helpful and understandable.
    >> If you can figure this one out I'd appreciate it because I don't even
    >> know where to look since nothing is making sense (index values not
    >> matching up, deletion still works).
    >>
    >>
    >> thanks for the help

    >
    > Brandon:
    >
    > I don't see anything there, nothing looks out of the ordinary. Any
    > chance that you've got a concurrency problem? Or maybe you are setting
    > the size of the ListModel before trying to remove the element?


    It's possible b/c like I said, I can't get it to work in Eclipse's
    debugger and maybe the breakpoints I sort of straightening everything
    out while being debugged. Well I don't specifically set it. To remove
    the current items before I retrieve the most current children for the
    selected tree node I call model.getListModel().removeAllElements(). Then
    the search is executed and the newest data is put back into the list one
    by one by looping through the Vector of results returned from the search.

    >
    > I think this is going to be hard to find without a simpler test program.
    > I had a problem like that once though that I couldn't duplicate. I
    > ended up solving it by synchronizing access to the method where I
    > thought the problem was occurring. That was kind of a shotgun approach.


    I've been setting synchronized keyword on some methods. I'll need to
    keep doing that in case it helps but without a sure fire way of testing
    this I may never really know if it's fixed.

    >
    > Sorry I can't be more help.
    >
    Brandon McCombs, Feb 5, 2007
    #10
  11. Brandon McCombs

    Chris Uppal Guest

    Brandon McCombs wrote:

    > Is there anything else I can try that can give me more information as to
    > what line in my code this is occurring on so I can begin to fix it?


    People downthread are already speculating that the problem is caused by
    modifying the model from outside the EDT; I suspect that they are correct.

    I just wanted to add (for general info) that the version of rt.jar which comes
    with the JRE is (at least in 1.5 and 1.6 on my machine) compiled without line
    numbers -- whence the less informative stack trace. The equivalent rt.jar
    which is part of the JRE which is inside the JDK /does/ have that information
    (again, as far as I can tell from what's on my machine). So if you can use
    that JRE to execute your program, instead of the "standard" one, then you may
    get more information.

    -- chris
    Chris Uppal, Feb 5, 2007
    #11
  12. Chris Uppal wrote:
    > Brandon McCombs wrote:
    >
    >> Is there anything else I can try that can give me more information as to
    >> what line in my code this is occurring on so I can begin to fix it?

    >
    > People downthread are already speculating that the problem is caused by
    > modifying the model from outside the EDT; I suspect that they are correct.
    >
    > I just wanted to add (for general info) that the version of rt.jar which comes
    > with the JRE is (at least in 1.5 and 1.6 on my machine) compiled without line
    > numbers -- whence the less informative stack trace. The equivalent rt.jar
    > which is part of the JRE which is inside the JDK /does/ have that information
    > (again, as far as I can tell from what's on my machine). So if you can use
    > that JRE to execute your program, instead of the "standard" one, then you may
    > get more information.
    >
    > -- chris
    >
    >


    Well I've gotten line numbers printed before but for some reason in this
    case (when I really need it) the line number doesn't get printed. I've
    been using the JRE included with Eclipse 3.1.2 but I just tried using
    JDK 1.5 and it didn't help make line numbers visible (running it outside
    of Eclipse as a regular JAR).
    Brandon McCombs, Feb 6, 2007
    #12
  13. Nigel Wade wrote:
    > Brandon McCombs wrote:
    >
    >
    >> The method I call for deleting a selected item from the JList is the
    >> following (model is the instance of BrowserModel):
    >>
    >> private void list_deleteObj() {
    >> int idx = dirList.getSelectedIndex();
    >> String dn = LDAPMgr.ldapUtility.getDN(
    >> model.getListModel().getElementAt(idx) );
    >> int ans = JOptionPane.showConfirmDialog(this,
    >> "Confirm delete for:\n" + dn + "\n",
    >> "Delete Object",JOptionPane.YES_NO_OPTION,
    >> JOptionPane.PLAIN_MESSAGE);
    >> if (ans == 1)
    >> return;
    >> String msg = null;
    >> msg = LDAPMgr.ldapUtility.deleteEntry(
    >> model.getListModel().getElementAt(idx));
    >> /* if successful */
    >> if (msg == null) {
    >> model.getListModel().remove(idx);
    >> /* reload the subtree and list to show deletion */
    >> refresh();
    >> }
    >> }
    >>

    >
    > What thread is the above method being executed on? If it's not the EDT you have
    > a problem there, you are modifying the JList in a thread other than the EDT.
    >
    > The error is telling you that when the EDT came to draw a JList it tried to
    > access element 1 and that element didn't exist in the the DefaultListModel's
    > Vector at the time. That would imply a synchronization error, the Vector is in
    > the process of being modified whilst it's being drawn (the JList and
    > DefaultTreeModel have a different idea of how many elements there are), and I
    > don't see how that can happen unless it's being modified from another thread -
    > even the EDT can only do one thing at a time...
    >


    Maybe I did this wrong but in the place in my code where I call the
    method above I put the following:

    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    list_deleteObj(); }
    });

    And I still get the exception generated so what am I missing?
    Brandon McCombs, Feb 6, 2007
    #13
  14. Michael Rauscher wrote:
    > Brandon McCombs wrote:
    >>>>>>
    >>>>>> Exception in thread "AWT-EventQueue-0"
    >>>>>> java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
    >>>>>> at java.util.Vector.elementAt(Unknown Source)
    >>>>>> at javax.swing.DefaultListModel.getElementAt(Unknown Source)
    >>>>>> at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
    >>>>>> at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
    >>>> [snip]

    >> Well the deletion still works when I get the exception. I am doing the
    >> deletion by going through the ListModel for the JList which I thought
    >> was correct. I never knew you could create a read-only ListModel.

    >
    > NB: a ListModel *is* read-only by default.
    >
    >>
    >> The method I call for deleting a selected item from the JList is the
    >> following (model is the instance of BrowserModel):
    >>
    >> private void list_deleteObj() {

    >
    > Is this method called from the EDT?
    >
    >>
    >> The idx in the code above rarely matches (if ever) the index value
    >> listed in the generated exception and again, the deletion above still
    >> works when the exception is generated. Refresh() essentially determines

    >
    > Sure, the exception originates from the UI-Delegate's paint method. Why
    > would you expect the deletion not to work?
    >
    > The reason for the exception is usually a simple one: you're modifying
    > the underlying ListModel in one thread while the EDT repaints the list.
    >
    > Imagine the following pseudo code as part of the painting procedure:
    >
    > int n = model.getSize();
    > for ( int i = 0; i < n; i++ ) {
    > // ...
    > Object value = model.getElementAt(i);
    > // ...
    > }
    >
    > Let's consider a ListModel that contains 5 elements. The code above runs
    > on the EDT, so it starts with n = 5 and enters the loop. Now, in another
    > thread you delete one element from the ListModel so that
    > model.getSize()==4. The loop continues until i=4, then an
    > ArrayIndexOutOfBoundsException will be thrown, e.g.: 4 >= 4. If the
    > second thread would have removed all elements from the ListModel, the
    > exception is thrown immediately at the next model.getElementAt method
    > call, e. g. 2 >= 0.



    Although what you say makes sense, I wonder if it's my problem because
    I'm modifying the model outside of the EDT (whatever that situation is
    properly termed) and after a few other method calls is when the model is
    updated with new nodes. I don't know when the exception actually occurs
    (painting when the item is deleted or painting when i refresh the list
    to get the current contents from the server) so maybe your theory is
    still accurate.

    private void list_deleteObj() {
    int idx = dirList.getSelectedIndex();
    String dn = LDAPMgr.ldapUtility.getDN(
    model.getListModel().getElementAt(idx) );
    int ans = JOptionPane.showConfirmDialog(this,
    "Confirm delete for:\n" + dn + "\n",
    "Delete Object",
    JOptionPane.YES_NO_OPTION,
    JOptionPane.PLAIN_MESSAGE);
    if (ans == 1)
    return;
    String msg = null;
    msg = LDAPMgr.ldapUtility.deleteEntry(
    model.getListModel().getElementAt(idx));
    /* if successful */
    if (msg == null) {
    model.getListModel().remove(idx);
    /* reload the subtree and list to show deletion */
    refresh();
    }
    }

    As you can see the removal from the list occurs before refresh(). In
    refresh() I call expand(). In expand() I spawn the thread to refresh the
    list model. If the repaint from the model.getListModel().remove(idx);
    doesn't occur until my thread is spawned then maybe that creates the
    exception. In another posting a few minutes before this one I tell
    Nigel that I put the call to the method above on the EDT and it didn't
    help; after enough deletions the exception crops up again.
    Brandon McCombs, Feb 6, 2007
    #14
  15. Brandon McCombs schrieb:
    > Although what you say makes sense, I wonder if it's my problem because
    > I'm modifying the model outside of the EDT (whatever that situation is
    > properly termed) and after a few other method calls is when the model is
    > updated with new nodes.


    If you modfy the model outside of the EDT, then it's the problem. It's
    easy. Really. Don't modify UI-state outside of the EDT and you don't get
    strange Exceptions :)

    I'll explain it in more detail, e. g. have a look at

    > model.getListModel().remove(idx);
    > /* reload the subtree and list to show deletion */
    > refresh();


    Since you're using DefaultListModel, the element at index idx gets
    removed from DefaultListModel's data Vector. Then, the model's listeners
    (to which the JList belongs, too) get notified. The JList repaints itself.

    You call refresh afterwards. I expect, you set a new Vector on the
    DefaultListModel. I expect that this occurs outside of the EDT, too.


    Now, I can imagine two situations:
    1) remove was called while repaint was active
    2) refresh() modified the ListModel while repaint was active.
    E. g. refresh could call DefaultListModel#removeAll.

    >
    > As you can see the removal from the list occurs before refresh().


    Doesn't matter. The point is, that you modify UI-state outside of the
    EDT. There are only a few methods in Swing (e. g. repaint()) that may be
    used outside the EDT.

    Bye
    Michael
    Michael Rauscher, Feb 6, 2007
    #15
  16. Brandon McCombs schrieb:
    > Nigel Wade wrote:
    >> Brandon McCombs wrote:
    >>
    >>
    >>> The method I call for deleting a selected item from the JList is the
    >>> following (model is the instance of BrowserModel):
    >>>
    >>> private void list_deleteObj() {
    >>> int idx = dirList.getSelectedIndex();
    >>> String dn = LDAPMgr.ldapUtility.getDN(
    >>> model.getListModel().getElementAt(idx) );
    >>> int ans = JOptionPane.showConfirmDialog(this,
    >>> "Confirm delete for:\n" + dn + "\n",
    >>> "Delete Object",JOptionPane.YES_NO_OPTION,
    >>> JOptionPane.PLAIN_MESSAGE);
    >>> if (ans == 1)
    >>> return;
    >>> String msg = null;
    >>> msg = LDAPMgr.ldapUtility.deleteEntry(
    >>> model.getListModel().getElementAt(idx));
    >>> /* if successful */
    >>> if (msg == null) {
    >>> model.getListModel().remove(idx);
    >>> /* reload the subtree and list to show deletion */
    >>> refresh();
    >>> }
    >>> }
    >>>

    >>
    >> What thread is the above method being executed on? If it's not the EDT
    >> you have
    >> a problem there, you are modifying the JList in a thread other than
    >> the EDT.
    >>
    >> The error is telling you that when the EDT came to draw a JList it
    >> tried to
    >> access element 1 and that element didn't exist in the the
    >> DefaultListModel's
    >> Vector at the time. That would imply a synchronization error, the
    >> Vector is in
    >> the process of being modified whilst it's being drawn (the JList and
    >> DefaultTreeModel have a different idea of how many elements there
    >> are), and I
    >> don't see how that can happen unless it's being modified from another
    >> thread -
    >> even the EDT can only do one thing at a time...
    >>

    >
    > Maybe I did this wrong but in the place in my code where I call the
    > method above I put the following:
    >
    > SwingUtilities.invokeLater(new Runnable() {
    > public void run() {
    > list_deleteObj(); }
    > });
    >
    > And I still get the exception generated so what am I missing?


    Look out for other threads. What does e. g. AsynchSearch do?

    Bye
    Michael
    Michael Rauscher, Feb 6, 2007
    #16
  17. Michael Rauscher wrote:
    > Brandon McCombs schrieb:
    >> Nigel Wade wrote:
    >>> Brandon McCombs wrote:
    >>>
    >>>
    >>>> The method I call for deleting a selected item from the JList is the
    >>>> following (model is the instance of BrowserModel):
    >>>>
    >>>> private void list_deleteObj() {
    >>>> int idx = dirList.getSelectedIndex();
    >>>> String dn = LDAPMgr.ldapUtility.getDN(
    >>>> model.getListModel().getElementAt(idx) );
    >>>> int ans = JOptionPane.showConfirmDialog(this,
    >>>> "Confirm delete for:\n" + dn + "\n",
    >>>> "Delete Object",JOptionPane.YES_NO_OPTION,
    >>>> JOptionPane.PLAIN_MESSAGE);
    >>>> if (ans == 1)
    >>>> return;
    >>>> String msg = null;
    >>>> msg = LDAPMgr.ldapUtility.deleteEntry(
    >>>> model.getListModel().getElementAt(idx));
    >>>> /* if successful */
    >>>> if (msg == null) {
    >>>> model.getListModel().remove(idx);
    >>>> /* reload the subtree and list to show deletion */
    >>>> refresh();
    >>>> }
    >>>> }
    >>>>
    >>>
    >>> What thread is the above method being executed on? If it's not the
    >>> EDT you have
    >>> a problem there, you are modifying the JList in a thread other than
    >>> the EDT.
    >>>
    >>> The error is telling you that when the EDT came to draw a JList it
    >>> tried to
    >>> access element 1 and that element didn't exist in the the
    >>> DefaultListModel's
    >>> Vector at the time. That would imply a synchronization error, the
    >>> Vector is in
    >>> the process of being modified whilst it's being drawn (the JList and
    >>> DefaultTreeModel have a different idea of how many elements there
    >>> are), and I
    >>> don't see how that can happen unless it's being modified from another
    >>> thread -
    >>> even the EDT can only do one thing at a time...
    >>>

    >>
    >> Maybe I did this wrong but in the place in my code where I call the
    >> method above I put the following:
    >>
    >> SwingUtilities.invokeLater(new Runnable() {
    >> public void run() {
    >> list_deleteObj(); }
    >> });
    >>
    >> And I still get the exception generated so what am I missing?

    >
    > Look out for other threads. What does e. g. AsynchSearch do?
    >


    It retrieves the current state of what the list should contain by
    contacting an LDAP server. It then alerts the GUI the results are ready
    by calling the GUI's updateGUI() method by I do that on the EDT like
    above so it should be okay.

    What I ended up doing that seems to work so far is I put the body of the
    method prepareGUI() inside of the SwingUtilities.invokeLater() call.
    The prepareGUI() is called by asyncSearch to prepare the GUI before the
    newest results are loaded. prepareGUI() is actually what deletes the
    rest of the items in the listmodel so that I don't get duplicate entries
    when it is updated. I've been testing that and haven't received the
    exception, yet.
    Brandon McCombs, Feb 6, 2007
    #17
  18. Brandon McCombs wrote:
    >>> And I still get the exception generated so what am I missing?

    >>
    >> Look out for other threads. What does e. g. AsynchSearch do?
    >>

    >
    > It retrieves the current state of what the list should contain by
    > contacting an LDAP server. It then alerts the GUI the results are ready
    > by calling the GUI's updateGUI() method by I do that on the EDT like
    > above so it should be okay.
    >
    > What I ended up doing that seems to work so far is I put the body of the
    > method prepareGUI() inside of the SwingUtilities.invokeLater() call.
    > The prepareGUI() is called by asyncSearch to prepare the GUI before the
    > newest results are loaded. prepareGUI() is actually what deletes the
    > rest of the items in the listmodel so that I don't get duplicate entries
    > when it is updated. I've been testing that and haven't received the
    > exception, yet.


    Sounds good. Next time don't follow the trial and error method: just
    ensure that any code that modifies the GUI runs on the EDT.

    Bye
    Michael
    Michael Rauscher, Feb 6, 2007
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Sisson
    Replies:
    4
    Views:
    2,325
    Lothar Werzinger
    Sep 15, 2004
  2. Steven T. Hatton
    Replies:
    14
    Views:
    3,854
    Ron Natalie
    Oct 20, 2004
  3. Mark Space
    Replies:
    3
    Views:
    396
    Mark Space
    Oct 27, 2007
  4. Jonathan Wood

    Any CMS Recommendations?

    Jonathan Wood, Jul 19, 2009, in forum: ASP .Net
    Replies:
    1
    Views:
    352
    nitin
    Jul 21, 2009
  5. Replies:
    3
    Views:
    104
    Daniel M. Hendricks
    Jan 13, 2005
Loading...

Share This Page