2009-06-25 1 views
0

Моя программа использует Свинг JPanel, JList, JScrollPane ...Ошибка Java Swing BasicUI, что я могу сделать?

Он работает нормально, но генерируется следующее сообщение об ошибке, и все же в сообщении не сказано, какая линия моей программы вызвала ошибку, что может Я делаю ?

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

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) 

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

У меня есть разные инструкции .validate() и .repaint() в моей программе, чтобы убедиться, что она работает правильно. Поскольку моя программа выглядит нормально, значит ли это, что я могу игнорировать ошибку? Что-нибудь, что я могу сделать, чтобы избежать сообщения об ошибке?

==================================================================================================================== ======================================= здесь более подробно:
< 1> Java версия jdk1.6.0_11
< 2> Как инициализировать список:

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)); 

Ишай является правильным, так как моя программа должна инициализировать очень длинный список, который требует около минуты. Я не могу дождаться, когда увижу пользовательский интерфейс перед завершением init, поэтому я помещаю его в класс SwingWorker и позволяю ему делать init после открытия окна пользовательского интерфейса приложения; таким образом, я вижу прогресс в пользовательском интерфейсе, а затем жду, пока откроется первое окно. Мне кажется, что это медленность ПК, которая испортила процесс обновления пользовательского интерфейса; если я позже перейду на более быструю машину, Swing должен это исправить, или я прав?

Я попытался использовать «(обернуть изменение в Runnable и вызвать SwingUtilities.invokeLater)», но он не работал, как я ожидал. Он ждет, пока весь список не будет заполнен, затем откроется первое окно; это означает, что я должен смотреть на пустой экран за одну минуту до появления первого пользовательского интерфейса.

С SwingWorker он теперь показывает сообщение об ошибке случайным образом - иногда здесь, иногда там, иногда нет вовсе.

Мой SwingWorker выглядит следующим образом:

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); } 
} 
+0

Можете ли вы опубликовать код, который создает/инициализирует ваш JList? –

+0

Никогда не игнорируйте ошибки, которые Java бросает вам (или любой язык программирования, если на то пошло). Вы можете не заметить ничего плохого, но обычно такая ошибка вызывает беспокойство и может повлиять на вас в будущем. Лучше просто позаботиться об этом сейчас, пока он свежий в вашей голове, и вы не написали много кода поверх этого. – AlbertoPL

+0

, какую версию java вы используете? – akf

ответ

1

Я полагаю, что исключение - это то, что одновременная модификация какого-либо массива объектов поворота.

SwingWorker имеет возможность для «текущих событий».Вам необходимо переопределить защищенный метод process(List<V> chunks) и использовать метод void publish(V... chunks) для отправки обновления статуса в пользовательский интерфейс. В вашем случае обработки это означает периодическое предоставление частичных результатов, чтобы пользователь не скучал.

+0

Да, вы совершенно правы, хотя я использую SwingWorker, я никогда не использовал методы publish() и process(), это первый раз, когда вы узнаете, как его использовать. – Frank

0

Как вы настройки модели данных? Компоненту пользовательского интерфейса говорят, что у вас есть как минимум 4 элемента в dataModel, но у модели их нет.

2

Очевидной причиной для беспокойства является то, что вы изменяете свою модель в другом потоке, а не в очереди событий Swing. Если это так, у вас есть проблема с кодом, который вы должны адресовать (оберните изменение в Runnable и вызовите SwingUtilities.invokeLater, если ничего другого).

Если нет, я, конечно же, видел случаи, когда вы просто видите ошибку качания, и это не стоит сбивать ваше приложение. Но учитывая природу этой трассировки стека, я бы сказал, что это маловероятно, тем более вероятной причиной является потоки и очередь событий).

3

Я думаю, что Ишай прав. У меня было подобное поведение и его упаковка в ... EventQueue.invokeLater ... решила мою проблему.

java.awt.EventQueue.invokeLater(new Runnable() { 
    @Override 
     public void run() { 
      listModel.addElement(book); 
      jListBooks = new JList(listModel); 
      jListBooks.setCellRenderer(new RobotBookListRenderer()); 
      jScrollPane1.setViewportView(jListBooks); 
      jListBooks.updateUI(); 
     } 
    }); 
+1

'SwingUtilities.invokeLater' должен работать также – Tombart

0

Я имел эту проблему и просто понял, что:

  • , если у вас есть объект JList
  • при вызове: listModel.removeAllElements()
  • , а затем добавлять элементы в listModel

это? иногда? выполняет событие valueChanged.

Это может показаться случайным. Мой код был выполнен внутри SwingWorker. Решение не для вызова removeAllElements, а для создания нового ListModel.

не делают этого:

DefaultListModel ListModel = (DefaultListModel) myJList.getModel(); listModel.removeAllElements();

ли это:

DefaultListModel ListModel = новый DefaultListModel(); myJList.setModel (listModel);

Этот код? выполняет метод valueChanged:

listModel.addElement (символ);