Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

JList custom Cell Renderer refresh

Posted on 2016-11-17
15
Medium Priority
?
86 Views
Last Modified: 2016-11-23
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.
0
Comment
Question by:MarkLoveExEx
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 3
  • +1
15 Comments
 

Author Comment

by:MarkLoveExEx
ID: 41892012
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.
0
 

Author Comment

by:MarkLoveExEx
ID: 41892164
Would the solution involve a swing worker?
0
 
LVL 37

Assisted Solution

by:zzynx
zzynx earned 500 total points
ID: 41892593
But I need to have the JList's background color refresh without having me change tabs.
I assume that the background color is determined somehow by the data.
So, there's no need to refresh eg. every 5 seconds (if the data isn't changed)
You only need to refresh when the data has changed. In that light, adding a ListDataListener was defintely a good step.

...but I still need to "click" the List for it to update.
How do you mean?

You know, helping you without having a single piece of code is nearly impossible. Could you please post your code?

Did you already try something like this:

in your ListDataListener's method

void contentsChanged(ListDataEvent e) {
     JList theList = (JList)e.getSource();
     theList.invalidate();
     theList.doLayout();
}

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 16

Accepted Solution

by:
krakatoa earned 1000 total points
ID: 41892795
This is an appalling hack, and requires not only considerable questioning, but more oop-ness all 'round. Nevertheless, it may help point you in some direction you are seeking, given that, as zzynx says, we don't really know the full context of what you are doing, nor why.

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


class Cellular extends JFrame{

static JList jlist;
static DefaultListCellRenderer dlcr;
static JTabbedPane tabs;
static Cellular cell;

public static void main(String[] args){

	jlist = new JList();
		
	cell = new Cellular();
	
	//.......
	tabs = new JTabbedPane();
         
        tabs.addTab("Main",new JLabel());
        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);

	
	//.......
	
	dlcr = (DefaultListCellRenderer)jlist.getCellRenderer();
	
	
	tabs.add(new JLabel("1"));
	tabs.add(jlist);
	jlist.setVisible(true);
	
	cell.add(tabs);
	cell.setSize(new Dimension(400,175));
	cell.setVisible(true);
	new Thread(new Timing()).start();

}

  static class Timing extends TimerTask{

		public Timing(){
			
			java.util.Timer t = new java.util.Timer();
            t.scheduleAtFixedRate(this, 10, 5000);
			tabs.setSelectedComponent(jlist);
		}
			
   public void run(){
   
	 
					jlist.setBackground(new java.awt.Color((int)(Math.random()*100),(int)(Math.random()*100),(int)(Math.random()*100)));
					
					if(!cell.isVisible()){System.exit(0);}
					dlcr.update(jlist.getGraphics());
					
			     
	}

  }

}

Open in new window

0
 

Author Comment

by:MarkLoveExEx
ID: 41892872
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.
0
 
LVL 37

Expert Comment

by:zzynx
ID: 41893071
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.
0
 
LVL 16

Expert Comment

by:krakatoa
ID: 41895193
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

0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 500 total points
ID: 41896040
You only need to refresh when the data has changed. In that light, adding a ListDataListener was defintely a good step.
The 'inner wiring' of the JList should cause its rendering to be done correctly as soon as its data is mutated with no need for extra listeners.
 The fact that it's not doing so is probably caused by some blocking of the EDT caused by incorrect thread handling
0
 

Author Closing Comment

by:MarkLoveExEx
ID: 41896316
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?
0
 
LVL 16

Expert Comment

by:krakatoa
ID: 41896337
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?
1
 
LVL 86

Expert Comment

by:CEHJ
ID: 41896356
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
0
 
LVL 37

Expert Comment

by:zzynx
ID: 41897074
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...
0
 

Author Comment

by:MarkLoveExEx
ID: 41898449
Really? That's quite a dirty workaround...

I know right?  But it works surprisingly well.
0
 

Author Comment

by:MarkLoveExEx
ID: 41898452
krakatoa -- I will try your latest code, maybe tomorrow.
0
 
LVL 16

Expert Comment

by:krakatoa
ID: 41898740
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.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question