Solved

JList custom Cell Renderer refresh

Posted on 2016-11-17
15
39 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
  • 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 125 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
 
LVL 16

Accepted Solution

by:
krakatoa earned 250 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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 125 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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will learn how to implement Singleton Design Pattern in Java.

708 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now