2009-06-25 34 views
0

我的程序使用Swing的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完成之前看到UI,所以我把它放在「SwingWorker」類中,讓它在應用程序UI窗口打開後執行init;這樣我就可以在UI中看到進度,而不用等待第一個窗口打開。在我看來,這是個人電腦緩慢的問題,搞亂了UI更新過程;如果我稍後轉向更快的機器,Swing應該將此解決,否則我是否正確?

我試圖使用「(包裹在一個Runnable的變化和調用SwingUtilities.invokeLater)」的方法,但它沒有按預期工作。它等待所有的列表填入,然後打開第一個窗口;這意味着我必須在第一個UI出現之前查看空屏幕一分鐘。

隨着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的代碼嗎? – 2009-06-25 19:36:35

+0

千萬不要忽略Java引發的錯誤(或任何編程語言)。你可能沒有注意到任何錯誤,但通常這樣的錯誤是令人擔憂的,並且可能會影響到你。現在只要在腦海中保持新鮮感,並且在這之前沒有寫很多代碼就更好了。 – AlbertoPL 2009-06-25 19:41:39

+0

您正在使用哪個版本的java? – akf 2009-06-25 19:49:15

回答

1

我猜也是異常是因爲某些swing對象數組的併發修改。

SwingWorker可以選擇「進行中的事件」。您需要覆蓋process(List<V> chunks)受保護的方法,並使用void publish(V... chunks)方法向UI發送狀態更新。在你的處理情況下,這意味着定期提交你的部分結果,這樣用戶不會感到無聊。

0

你如何建立你的數據模型? UI組件被告知dataModel中至少有4個項目,但該模型沒有那麼多。

2

這裏值得關注的明顯原因是您在不同的線程中修改模型,而不是在Swing事件隊列中。如果是這樣的話,你的代碼應該有一個問題需要解決(將更改包裝在一個Runnable中,如果沒有其他的話,調用SwingUtilities.invokeLater)。

如果不是這樣,我肯定會遇到這樣的情況,您只會看到一個擺動錯誤,並且不值得讓應用程序崩潰。但考慮到這種堆棧跟蹤的性質,我認爲這不太可能,更可能的原因是線程和事件隊列)。

3

我認爲易is是對的。我有一個類似的行爲,並將其包裝... 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(); 
     } 
    }); 
0

我有這個問題,只是想通了:

  • ,如果你有一個JList對象
  • 當你撥打:listModel.removeAllElements()
  • ,然後添加元素到listModel

它?有時候?執行valueChanged事件。

這可能會出現隨機。我的代碼在SwingWorker中執行。 解決方案不是調用removeAllElements,而是創建一個新的ListModel。

不這樣做:

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

這樣做:

DefaultListModel的ListModel =新DefaultListModel(); myJList.setModel(listModel);

This code?sometimes?執行valueChanged方法:

listModel.addElement(symbol);

相關問題