Solved

JTable row colors

Posted on 2002-04-25
16
716 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
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
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 

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 100 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

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
How to get all the API from website? 11 92
how do i compare an object based on two fields 6 54
Oracle SQL syntax check  without executing 6 57
servlet example 17 33
For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This video teaches viewers about errors in exception handling.

832 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