Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

JTable row colors

Posted on 2002-04-25
16
Medium Priority
?
724 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
[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
  • 5
  • 5
16 Comments
 
LVL 15

Expert Comment

by:ozymandias
ID: 6969525
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
ID: 6970778
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
ID: 6971833
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:afterburner
ID: 6971854
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
ID: 6972144
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
ID: 6972163
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
ID: 6972174
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
ID: 6972219
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
 
LVL 15

Expert Comment

by:ozymandias
ID: 6972221
Sorry, that should read ListSelectionModel, not ListSelectionListener.
0
 
LVL 3

Expert Comment

by:randyd
ID: 6972229
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
ID: 6972234
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
ID: 7004625
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
ID: 7202870
I plan to get back to this question as soon as I have sorted out a related issue.
0
 

Author Comment

by:afterburner
ID: 7258828
> 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 400 total points
ID: 7259194
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
ID: 7261021
I havent tried it yet, but it sounds good.

aftrbrnr
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

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

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
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…
Suggested Courses

604 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