This week's book giveaway is in the Jython/Python forum.
We're giving away four copies of Murach's Python Programming and have Michael Urban and Joel Murach on-line!
See this thread for details.
Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

item does not repaint within a list  RSS feed

 
Kelly Dolan
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Overall, my problem is that I have a list of items and when the information for ONLY ONE of those items changes behind the scenes, the item is not repainted.

More specifically, I have a JList that contains items of type MyJPanel (which extends JPanel). I provide a simple ListCellRenderer that identifies the MyJPanel object as the rendered of the cell and I have implemented the paintComponent() method in the MyJPanel class.

The MyJPanel class is also an observer to a data model and implements the update() method. When notified that a change has occurred, the MyJPanel.update() method performs the necessary steps and then calls MyJPanel.revalidate() and MyJPanel.repaint() as I thought it should. However, I noticed that the calls to revalidate() and repaint() do absolutely nothing (i.e., it does not trigger a call to the paintComponent() method)! I even tried calling MyJPanel.updateUI() and that did not work.

To get my display to update, it required a call to revalidate() and repaint() on the JList. This however, triggers a call to the paintComponent() method on every MyJPanel item in the list.

My question is...is this how it is supposed to work? Is there any way to invalidate a single item in the list thus triggering a repaint of that one item only? It seems a shame to have to invalidate the entire list (and repaint all items) when only one item has changed and needs to be repainted.
 
Scott Delap
author
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kelly,

First a little JList 101. The items in your model that extend JPanel are not actually in the list. The list contains no really objects. What happens is for each item in the model it looks up the renderer, generates a rendered image of the item, and puts that image in the appropriate area of the JList. Therefore you can update your renderer all day and nothing will happen because it isn't directly associated with the JList.

You should notice that your ListModel has add and remove ListDataListener methods. What you need to do when your model changes is iterator through these listeners and fire either an intervalAdded(), intervalRemoved(), or contentsChanged() event. The JList is a listener to the model so it will receive this event. Depending how you specify it, the JList will determine that it needs to re-render an item. At this point it will get the appropriate renderer and repaint that specific area. The reason why you revalidate() on the JList works is that it triggers a repaint of all the items in the JList.

As an aside, I would recommend structuring your data and renderers a little differently. Normally, the data items in your model aren't GUI components. You also usually only need one renderer class. This class will take the data for each item and determine how to display it properly.

Scott Delap
ClientJava.com
Desktop Java Live
 
Kelly Dolan
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Scott,

Hey thanks! Your lesson means alot to me. I think I understand most of what you described but I need to take what you said, digest it and try a few things.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!