Link to home
Start Free TrialLog in
Avatar of MarkLoveExEx
MarkLoveExEx

asked on

JList custom Cell Renderer refresh

I have a JList with a custom cell renderer (the background color changes).  How do you refresh a JList, applying this renderer automatically?  I have the JList on a tab in a JFrame.  If I select another tab, and come back to the tab the JList is on, it refreshes.  But I need to have the JList's background color refresh without having me change tabs.  (Or, at least have it refresh every 5 seconds or so).  I need this to happen without strange GUI glitches (which would probably happen if I have to clear/repopulate the JList)  Thanks.
Avatar of MarkLoveExEx
MarkLoveExEx

ASKER

I added a ListDataListener, but I still need to "click" the List for it to update.  Still looking for a solution to have it update with no user interaction.
Would the solution involve a swing worker?
SOLUTION
Avatar of zzynx
zzynx
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you for the input. I will be back working on this problem on Monday, where I will try your suggestions. I will see what I can do about posting some code. My programs average 6000 lines and 30 classes which all interact, so sometimes it is difficult to know exactly what to post.  For this particular problem, I don't think I'm doing anything strange. It is just a basic JList with its model. You're right, the data is changing, and the custom cell renderer accesses that data, but the background color of the JList just won't change unless I have some GUI interaction, such as a change of tab or simply clicking on the JList. Again, thank you for your suggestions so far, but I have to put this on hold until Monday.
You're right, the data is changing, and the custom cell renderer accesses that data, but the background color of the JList just won't change unless I have some GUI interaction
Try what I posted.

Again, thank you for your suggestions so far,  
You're welcome
but I have to put this on hold until Monday.
No problem. Keep us up to date whenever you have new information.
Here's a bit more code you can try for size :

import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.io.*;
import javax.swing.event.*;
import java.awt.event.*;


class Cellular extends JFrame {

static JList<?> jlist;
static JTabbedPane tabs;
static Cellular cell;
static Exception exx;
static String[] sA={"A","B","C","D","E","Z"};
static ListDataEvent lde;

public static void main(String[] args) {

try{
	
	jlist = new JList<String>(sA);
	cell = new Cellular();
	tabs = new JTabbedPane();
         
        tabs.addTab("Main",new JLabel("Main"));
        tabs.addTab("Advanced",new JLabel());
        tabs.addTab("Privacy",new JLabel());
        tabs.addTab("eMail",new JLabel());
        tabs.addTab("Security",new JLabel());
        tabs.setSize(300, 100);
        tabs.setVisible(true);
	
	tabs.add(new JLabel("1"));
	tabs.add("JList",jlist);
	
	jlist.setBackground(java.awt.Color.WHITE);
	jlist.setVisible(true);
	
	cell.add(tabs);
	cell.setSize(new Dimension(450,255));
	cell.setVisible(true);
	
	int delay = 1000;
	
	ActionListener listUpdater = new ActionListener() {
	
      public void actionPerformed(ActionEvent evt) {
		
					try{
					if(!cell.isVisible()){throw new Exception(exx);}
					lde = new ListDataEvent(jlist,0,0,0);				
									
					if(jlist.getBackground()==java.awt.Color.WHITE){jlist.setForeground(new java.awt.Color(100,100,100));}
					else{jlist.setForeground(new java.awt.Color(255,255,255));}
								
					String st = (String)jlist.getModel().getElementAt(0);
					System.out.println(st);
					if(sA[0].equals("K")){sA[0]="A";}
					else{sA[0]="K";}
					if (lde.getSource()==jlist){
					jlist.setBackground(new java.awt.Color((int)(Math.random()*100),(int)(Math.random()*100),(int)(Math.random()*100)));}jlist.updateUI();
					}
					catch(Exception exx){System.exit(1);}
	  }
  };
	
	tabs.setSelectedComponent(jlist);
	new javax.swing.Timer(delay, listUpdater).start();
	
}catch(Exception t){System.exit(1);}

}

}

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I finally found a solution that works.  I added a timer that adds an element to the JList, and then removes that element right away.  There is probably a better way, but this seems to work.  Thank you all for your input. I am not sure how to assign points, as I did not actually end up using any suggestions.  What is the protocol for this?
If this is real data you are dealing with then I would say that it is not really good practice to artificially insert some simply in order to fire an event. It is more than a notional compromise of integrity. But if this was an experimental / recreational / learning exercise then I guess it's fine. Did you run my last piece of code?
Generally speaking (i think you know the quality of the workaround you just described, so i shan't comment on it) there is seldom much need to mutate a JList. What can happen is that a different model needs to be set on it, in which case, if the renderer is OK, then everything should work fine. When the new model is set, the renderer will carry on as before
I added a timer that adds an element to the JList, and then removes that element right away.
Really? That's quite a dirty workaround...
Really? That's quite a dirty workaround...

I know right?  But it works surprisingly well.
krakatoa -- I will try your latest code, maybe tomorrow.
No big deal. All I was really referring to is the point that CEHJ made, that the threading would affect performance, and my second piece of code has a better approach to that.