0

私のプログラムは、Swing JPanel、JList、JScrollPane を使用しています...

正常に実行されますが、次のエラー メッセージが生成されましたが、エラーの原因となったプログラムの行がメッセージに表示されませんでした。

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

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

私のプログラムは非常に長いリストを初期化する必要があり、これには約 1 分かかります。初期化が完了する前に UI を見るのが待ちきれないので、「SwingWorker」クラスに入れて、アプリの UI ウィンドウが開いた後に初期化を実行させます。そうすれば、最初のウィンドウが開くのを待つのではなく、UI 内から進行状況を確認できます。PC の遅さが UI 更新プロセスを混乱させているように思えます。後でより高速なマシンに移行した場合、Swing はこれを解決する必要がありますか、それともこれで正しいでしょうか?

「(Runnable で変更をラップし、SwingUtilities.invokeLater を呼び出す)」アプローチを使用しようとしましたが、期待どおりに機能しませんでした。すべてのリストが入力されるまで待機し、最初のウィンドウを開きます。つまり、最初の UI が表示される前に、空の画面を 1 分間見なければなりません。

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

5 に答える 5

4

私はイーシャイが正しいと思います。同様の動作があり、それを ...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();
        }
    });
于 2014-02-15T08:54:00.233 に答える
3

ここで懸念される明らかな原因は、Swingイベントキューではなく、別のスレッドでモデルを変更することです。その場合は、対処する必要のあるコードに問題があります(変更をRunnableでラップし、他に何もない場合はSwingUtilities.invokeLaterを呼び出します)。

そうでない場合は、スイングのバグが表示され、アプリケーションをクラッシュさせる価値がない場合を確かに見ました。しかし、このスタックトレースの性質を考えると、そうは思われませんが、より可能性の高い原因はスレッド化とイベントキューです)。

于 2009-06-25T19:52:29.713 に答える
2

私も例外は、いくつかのスイングオブジェクト配列の同時変更によるものだと思います。

SwingWorker には、「進行中のイベント」のオプションがあります。process(List<V> chunks)保護されたメソッドをオーバーライドし、void publish(V... chunks)メソッドを使用してステータスの更新を UI に送信する必要があります。処理の場合、これはユーザーが飽きないように部分的な結果を定期的に送信することを意味します。

于 2009-06-26T15:16:55.337 に答える
0

私はこの問題を抱えていて、それを理解しました:

  • JList オブジェクトがある場合
  • 呼び出すとき: listModel.removeAllElements()
  • 次に、要素を listModel に追加します

それ?時々?valueChanged イベントを実行します。

これはランダムに表示される場合があります。私のコードは SwingWorker 内で実行されました。解決策は、removeAllElements を呼び出すのではなく、新しい ListModel を作成することです。

これをしないでください:

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

これを行う:

DefaultListModel listModel = new DefaultListModel(); myJList.setModel(listModel);

このコードは?valueChanged メソッドを実行します。

listModel.addElement(シンボル);

于 2016-11-04T01:38:00.267 に答える
0

データモデルをどのように設定していますか? UI コンポーネントには、dataModel に少なくとも 4 つのアイテムがあることが通知されていますが、モデルにはそれほど多くはありません。

于 2009-06-25T19:45:39.260 に答える