views:

386

answers:

3

My program uses Swing JPanel, JList, JScrollPane ...

It runs fine, but generated the following error message, and yet in the message it didn't say which line of my program caused the error, what can I do ?

=========================================================================

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 3

        at javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1356)
        at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1299)
        at javax.swing.plaf.basic.BasicListUI.getPreferredSize(BasicListUI.java:566)
        at javax.swing.JComponent.getPreferredSize(JComponent.java:1632)
        at javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:769)
        at java.awt.Container.layout(Container.java:1398)
        at java.awt.Container.doLayout(Container.java:1387)
        at java.awt.Container.validateTree(Container.java:1485)
        at java.awt.Container.validate(Container.java:1457)
        at javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:670)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:127)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

=====================================================================================

I do have various .validate() and .repaint() statements in my program to make sure it runs correctly. Because my program looks fine, does that mean I can ignore the error ? Anything I can do to avoid the error message ?

===================================================================================== Here is more details:
<1> Java version jdk1.6.0_11
<2> How I init the list:

for (int Selector_Id=0;Selector_Id<6;Selector_Id++)
{
  Stock_Symbol_Data[Selector_Id]=new DefaultListModel();
  Stock_Symbol_List[Selector_Id]=new JList(Stock_Symbol_Data[Selector_Id]);
  Stock_Symbol_ScrollPane[Selector_Id]=new JScrollPane(Stock_Symbol_List[Selector_Id]);
}
...
Stock_Symbol_Data[A_Selector_Id].clear();

if (Selected_Symbols_Vector.size()>0)
  for (int i=0;i<Selected_Symbols_Vector.size();i++)
    Stock_Symbol_Data[A_Selector_Id].addElement(Selected_Symbols_Vector.elementAt(i));

Yishai is right, since my program needs to init a very long list, which requires about a minute. I can't wait to see the UI before the init is finished, so I put it in a "SwingWorker" class and let it do the init after the app UI window opens; that way I can see the progress from within the UI rather then wait for the first window to open. It seems to me it's the PC's slowness that's messing up the UI update process; if I later on move to a faster machine, Swing should straighten this out, or am I right about this?

I tried to use the "(wrap the change in a Runnable and call SwingUtilities.invokeLater)" approach, but it didn't work as I expected. It waits till all the list is filled in, then opens the first window; that means I have to look at empty screen for one minute before the first UI shows up.

With SwingWorker, it now shows the error message randomly--sometimes here, sometimes there, other times not at all.

My SwingWorker looks like this :

class Update_Selection_Worker extends SwingWorker<Integer,Integer>             // Look into SwingWorkerDemo in Fit for details
{
  int Selector_Id;
  boolean Update_Only_This_Selector;
  Stock_Image_Scanner Stock_image_scanner;

  public Update_Selection_Worker(int Selector_Id,boolean Update_Only_This_Selector,Stock_Image_Scanner Stock_image_scanner)
  {
    this.Selector_Id=Selector_Id;
    this.Update_Only_This_Selector=Update_Only_This_Selector;
    this.Stock_image_scanner=Stock_image_scanner;
  }

  @Override
  protected Integer doInBackground() throws Exception
  {
//    Out("  In Update_Selection_Worker  Selector_Id="+Selector_Id);

    if (Update_Only_This_Selector)          // Only need to update from Rules_Panel_Id, eariler ones haven't changed
    {
      Stock_image_scanner.Update_Selector_List(Selector_Id);
      Thread.sleep(5);
      publish(Selector_Id);
    }
    else for (int i=Selector_Id;i<Stock_image_scanner.Rules_Panel_Count;i++)
    {
      Stock_image_scanner.Update_Selector_List(i);
      Thread.sleep(5);
      publish(i);
    }

    return 1;
  }

  @Override
  protected void process(java.util.List<Integer> chunks)                       // As the worker thread executes, it can publish results of V type. Override the process method to work with intermediate results.
  {
    for (final int i : chunks)
    {
      SwingUtilities.invokeLater(new Runnable()
      {
        public void run()
        {

          Stock_image_scanner.Selector_Total_Label[i].setText(Stock_image_scanner.Stock_Symbol_Data[i].getSize()+"");
          Stock_image_scanner.Stock_Symbol_List[i].revalidate();
          Stock_image_scanner.Stock_Symbol_List[i].repaint();
          Stock_image_scanner.Stock_Symbol_ScrollPane[i].revalidate();
          Stock_image_scanner.Stock_Symbol_ScrollPane[i].repaint();
          Stock_image_scanner.Selector_Panel[i].revalidate();
          Stock_image_scanner.Selector_Panel[i].repaint();

        }
      });
    }
  }

  @Override
  protected void done()
  {
  }

  public static void out(String message) { System.out.print(message); }
  public static void Out(String message) { System.out.println(message); }
}
A: 

How are you setting up your data model? The UI component is being told that you have at least 4 items in the dataModel, but the model doesnt have that many.

akf
A: 

The obvious cause for concern here is that you modifying your Model in a different thread, and not in the Swing event queue. If that is the case, you do have a problem with your code that you should address (wrap the change in a Runnable and call SwingUtilities.invokeLater if nothing else).

If not, I have certainly seen cases where you just see a swing bug and it is not worth crashing your application over. But given the nature of this stack trace, I would say that is not likely, the more likely cause is threading and the event queue).

Yishai
+1  A: 

I guess too the exception is because the concurrent modification of some swing object array.

SwingWorker has the option for 'in progress events'. You need to override process(List<V> chunks) protected method and use the void publish(V... chunks) method to send status update to the UI. In your processing case this means submit your partial results periodically so the user doesn't get bored.

kd304
Yes, you are exactly right, although I've been using SwingWorker, I've never used the publish() and process() methods, this is the first time to learn how to use it.
Frank