2009-06-25 6 views
0

Mon programme utilise swing JPanel, JList, JScrollPane ...Java Swing BasicUI erreur de mise à jour, que puis-je faire?

Il fonctionne très bien, mais a généré le message d'erreur suivant, et encore dans le message qu'il n'a pas dit quelle ligne de mon programme a causé l'erreur, ce qui peut Je fais ?

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

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) 

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

J'ai plusieurs instructions .validate() et .repaint() dans mon programme pour m'assurer qu'il s'exécute correctement. Parce que mon programme semble bien, est-ce que cela signifie que je peux ignorer l'erreur? Tout ce que je peux faire pour éviter le message d'erreur?

============================================== ======================================= Voici plus de détails:
< 1> Java Version jdk1.6.0_11
< 2> Comment j'initialiser le liste:

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 est juste, puisque mon programme doit initialiser une très longue liste, ce qui nécessite environ une minute. J'ai hâte de voir l'IU avant la fin de l'init, donc je l'ai mis dans une classe "SwingWorker" et je l'ai laissé faire l'init après l'ouverture de la fenêtre de l'interface utilisateur de l'application; De cette façon, je peux voir les progrès à partir de l'interface utilisateur plutôt que d'attendre que la première fenêtre s'ouvre. Il me semble que c'est la lenteur du PC qui gâche le processus de mise à jour de l'interface utilisateur; si plus tard je passe à une machine plus rapide, Swing devrait redresser cela, ou ai-je raison à ce sujet?

J'ai essayé d'utiliser l'approche "(encapsuler la modification dans un Runnable et appeler SwingUtilities.invokeLater)", mais cela n'a pas fonctionné comme prévu. Il attend que toute la liste soit remplie, puis ouvre la première fenêtre; cela signifie que je dois regarder l'écran vide pendant une minute avant que la première interface utilisateur se présente. Avec SwingWorker, il affiche maintenant le message d'erreur de manière aléatoire - parfois ici, parfois là, parfois pas du tout.

Mon SwingWorker ressemble à ceci:

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

Pouvez-vous poster le code qui crée/initialise votre JList? –

+0

Ne jamais ignorer les erreurs que Java lance sur vous (ou n'importe quel langage de programmation d'ailleurs). Vous ne remarquerez peut-être rien de mal, mais une erreur comme celle-ci est habituellement une source de préoccupation et peut vous affecter plus tard. Il est préférable de prendre soin de lui maintenant, alors qu'il est frais dans votre tête et vous n'avez pas écrit beaucoup de code en plus de cela. – AlbertoPL

+0

quelle version de Java utilisez-vous? – akf

Répondre

1

Je suppose aussi que l'exception est due à la modification simultanée d'un tableau d'objets swing.

SwingWorker a l'option pour les 'événements en cours'.Vous devez remplacer la méthode protégée process(List<V> chunks) et utiliser la méthode void publish(V... chunks) pour envoyer la mise à jour du statut à l'interface utilisateur. Dans votre cas de traitement, cela signifie soumettre vos résultats partiels périodiquement afin que l'utilisateur ne s'ennuie pas.

+0

Oui, vous avez raison, même si j'ai utilisé SwingWorker, je n'ai jamais utilisé les méthodes publish() et process(), c'est la première fois que j'apprends à l'utiliser. – Frank

0

Comment êtes-vous mise en place de votre modèle de données? Le composant UI est dit que vous avez au moins 4 éléments dans le dataModel, mais le modèle n'en a pas autant.

2

La cause évidente d'inquiétude ici est que vous modifiez votre modèle dans un thread différent, et non dans la file d'attente d'événements Swing. Si tel est le cas, vous avez un problème avec votre code que vous devriez adresser (enveloppez la modification dans un Runnable et appelez SwingUtilities.invokeLater si rien d'autre). Si ce n'est pas le cas, j'ai certainement vu des cas où vous voyez juste un bug swing et ça ne vaut pas la peine d'écraser votre application. Mais étant donné la nature de cette trace de pile, je dirais que ce n'est pas probable, la cause la plus probable est le threading et la file d'attente des événements).

3

Je pense que Yishai a raison. J'ai eu un comportement similaire et l'enveloppant dans ... EventQueue.invokeLater ... résolu mon problème.

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' devrait également fonctionner – Tombart

0

J'ai eu ce problème et juste compris que:

  • si vous avez un objet JList
  • lorsque vous appelez: listModel.removeAllElements()
  • puis ajouter des éléments à la listeModèle

il? parfois? exécute l'événement valueChanged.

Cela peut sembler aléatoire. Mon code a été exécuté dans SwingWorker. La solution est de ne pas appeler removeAllElements mais de créer un nouveau ListModel.

Ne faites ceci:

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

Pour ce faire:

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

Ce code? Parfois? exécute la méthode valueChanged:

listModel.addElement (symbole);

Questions connexes