Solved

JTable row colors

Posted on 2002-04-25
16
714 Views
Last Modified: 2007-11-27
Hi again;

I have one more question just now relating to JTables; I want to be able to toggle the back color of a row on and off when it is clicked, and for the background color to be retained when I go to click on another row. I am having a bit of trouble figuring our where and how a table can retain these values.
0
Comment
Question by:afterburner
  • 6
  • 5
  • 5
16 Comments
 
LVL 15

Expert Comment

by:ozymandias
Comment Utility
This can be set as default behaviour for the ListSelectionModel of the table.

By default a selected row will change its background color.

Additional rows can be added to this selection either contiguously (by holding down shift) or individually (by holding down ctrl).

To enable this behavious use :

table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

where table is the name of your JTable.

Cheers.
0
 

Author Comment

by:afterburner
Comment Utility
I had already tried shift and control-clicking, but I am looking for a way to toggle the row color one at a time using single clicks. Do your think your suggestion would still enable this. or is something more exotic called for like the celleditors and renderers that I see mentioned?
0
 
LVL 15

Expert Comment

by:ozymandias
Comment Utility
Using the example above and holding down control will "toggle the row color one at a time using single clicks".

I don;t think cell renderers and editors are the answer.
If you cannot adapt the ListSelectionModel to you needs you may have to write your own ListSelectionModel by extending it and overriding some of the methods.

This is basically where the information about which rows in the table are selected is stored and it therefore informs decisions about which rows to show as selected (i.e.coloured).

The JTable itself implements the ListSelectionListener interface and it passes information about changes in the selection to its ListSelectionModel. Based on the mode of the ListSelectionModel it will add and remove rows from the selection in response to the row selection events.
0
 

Author Comment

by:afterburner
Comment Utility
ok, I will have a look into this class, as I am not familiar with it, and see what results I can get (if any).

Thanks for now
0
 
LVL 3

Expert Comment

by:randyd
Comment Utility
you will need a table cell renderer:

see this example. (you can change it for your behavior)..

import javax.swing.JTable;

import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

import java.awt.Component;
import java.awt.Color;

public class StripedTableCellRenderer implements TableCellRenderer
{
   protected TableCellRenderer targetRenderer;
   protected Color evenBack;
   protected Color evenFore;
   protected Color oddBack;
   protected Color oddFore;

   public StripedTableCellRenderer(TableCellRenderer targetRenderer,
                                   Color evenBack,
                                   Color evenFore,
                                   Color oddBack,
                                   Color oddFore)
   {
      this.targetRenderer = targetRenderer;
      this.evenBack = evenBack;
      this.evenFore = evenFore;
      this.oddBack  = oddBack;
      this.oddFore  = oddFore;
   }

   // Implementation of TableCellRenderer interface
   public Component getTableCellRendererComponent(JTable table,
                                                  Object value,
                                                  boolean isSelected,
                                                  boolean hasFocus,
                                                  int row,
                                                  int column)
   {
      TableCellRenderer renderer = targetRenderer;
      if (renderer == null)
      {
         // Get default renderer from the table
         renderer = table.getDefaultRenderer(table.getColumnClass(column));
      }

      // Let the real renderer create the component
      Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

      // Now apply the stripe effect
      if (isSelected == false && hasFocus == false)
      {
         if ((row & 1) == 0)
         {
            comp.setBackground(evenBack != null ? evenBack : table.getBackground());
            comp.setForeground(evenFore != null ? evenFore : table.getForeground());
         }
         else
         {
            comp.setBackground(oddBack != null ? oddBack : table.getBackground());
            comp.setForeground(oddFore != null ? oddFore : table.getForeground());
         }
      }

      return comp;
   }

   // Convenience method to apply this renderer to single column
   public static void installInColumn(JTable table,
                                      int columnIndex,
                                      Color evenBack,
                                      Color evenFore,
                                      Color oddBack,
                                      Color oddFore)
   {
      TableColumn tc = table.getColumnModel().getColumn(columnIndex);

      // Get the cell renderer for this column, if any
      TableCellRenderer targetRenderer = tc.getCellRenderer();

      // Create a new StripedTableCellRenderer and install it
      tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore));
   }

   // Convenience method to apply this renderer to an entire table
   public static void installInTable(JTable table,
                                     Color evenBack,
                                     Color evenFore,
                                     Color oddBack,
                                     Color oddFore)
   {
      StripedTableCellRenderer sharedInstance = null;
      int columns = table.getColumnCount();
      for (int i = 0 ; i < columns; i++)
      {
         TableColumn tc = table.getColumnModel().getColumn(i);
         TableCellRenderer targetRenderer = tc.getCellRenderer();
         if (targetRenderer != null)
         {
            // This column has a specific renderer
            tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore));
         }
         else
         {
            // This column uses a class renderer - use a shared renderer
            if (sharedInstance == null)
            {
               sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore);
            }
            tc.setCellRenderer(sharedInstance);
         }
      }
   }
}


randy
0
 
LVL 15

Expert Comment

by:ozymandias
Comment Utility
randyd, I can see how that would help stripe the rows of a table, but how does it help with afterburner's actual question which is how to change the color of rows when they are selected and have them retain that coloring when the selection changes (i.e. toggling them on and off) ?
0
 
LVL 3

Expert Comment

by:randyd
Comment Utility
i assumed that he was tracking the state somewhere (in a database or at least a vector or hashmap) then the renderer could use that data to decide what color to actually render the cell in question. i.e.  if i find myself in the hashmap paint myself green etc...

randy
0
 
LVL 15

Expert Comment

by:ozymandias
Comment Utility
I see your point and I think that that is actually the crux of the issue rather than how do I make table rows dufferent colors. The default behaviour for a selected table row is to change its background color. It is the management of the selection that is being explored. As far as I can see this is much better done in the ListSelectionListener since it alreday deos exactly that, i.e. keep track of which rows are selected and which are not (probably, as you said, in a hashmap or similar structure). Afterburner is saying that he/she wants to change the way the selection responds to selection events.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 15

Expert Comment

by:ozymandias
Comment Utility
Sorry, that should read ListSelectionModel, not ListSelectionListener.
0
 
LVL 3

Expert Comment

by:randyd
Comment Utility
you are exactly correct.

the 'natural' place to store the state is already available in the ListSelectionModel.

randy
0
 
LVL 3

Expert Comment

by:randyd
Comment Utility
reading further... it appears maybe Afterburner wants the behavior modified so that multi-selection does not require the control key...

the rest of the comments still apply.

randy
0
 

Author Comment

by:afterburner
Comment Utility
Hi;

I think I may have caused some confusion, so maybe I can rephrase what I asked:

I want to click a row in the Jtable and have it turn, say red. If another row is selected (clicked) then I want that to turn red too, and the first row to stay red, so now we have two red rows on screen - or however many the user clicks ONE AT A TIME. If any red row is clicked on again, then I want it to turn back to the default color.

I can write : JTable.setSelectionBackGround(red) and thats OK. If selection mode is SINGLE_SELECTION then any single row I select turns red, and Java takes care of resetting the no-loner-selected row to its default. But how do I tell the table to retain the color until it is explicitly toggled off by the next click on that row?

Maybe if I can find a how to get hold of the index for the row selected, I can store this somehow - but I cant seem to find a method to let me acscertain the row!
0
 

Author Comment

by:afterburner
Comment Utility
I plan to get back to this question as soon as I have sorted out a related issue.
0
 

Author Comment

by:afterburner
Comment Utility
> reading further... it appears maybe Afterburner wants the behavior modified so that multi-selection does not require the control key...

Yes, that's what I want to do, and I would like to progress the matter if poss now.

So, again, click a row, color changes; click it again, color changes back. Click the first row, then click another (or more) row(s) _individually_ and they all retain a new non-default color, until individually clicked again. Whew.
0
 
LVL 3

Accepted Solution

by:
randyd earned 100 total points
Comment Utility
ok.

so create a listener, when the listener is envoked (an event happened in the list i.e. something was clicked). then do some logic on a HashMap.

if the HashMap contains the clicked row, remove the row from the HashMap, repaint the list.

if the HashMap does not contain the clicked row, add the row to the HashMap, repaint the list.

use a similar cell renderer as posted above, and determine the color to use based on HashMap entries.

randy
0
 

Author Comment

by:afterburner
Comment Utility
I havent tried it yet, but it sounds good.

aftrbrnr
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

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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 …
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This video teaches viewers about errors in exception handling.

771 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

10 Experts available now in Live!

Get 1:1 Help Now