Solved

How to change single row color on JTable

Posted on 2004-07-30
9
26,269 Views
Last Modified: 2013-11-23
i am using JTable in my program.during the running time i like to change single row color.how to change..can u give some ideas immediately..bz it's very urgent.
Thankingyou  
0
Comment
Question by:pml_siva
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 11675953
Use a custom cell renderer
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11675956
0
 
LVL 37

Expert Comment

by:zzynx
ID: 11676010
Use your own TableCellRenderer (extending the DefaultTableCellRenderer):

public class MyColorCellRenderer extends DefaultTableCellRenderer {

    private int rowToColor = -1;

    public MyColorCellRenderer() {
    }

    public void setRowToColor(int row) {
        rowToColor = row;
    }

    Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

         if (rowToColor!=-1 && row==rowToColor)
            setForeground(Color.RED);
         return super.getTableCellRenderer(table, value, isSelected, hasFocus, row, column);          
    }
}

MyColorCellRenderer myRenderer = new MyColorCellRenderer();
yourTable.setCellRenderer( myRenderer );

To change a row's color:

myRenderer.setRowToColor(5);  // for the 6th row
0
 
LVL 37

Expert Comment

by:zzynx
ID: 11676031
Typo:

Change

           setForeground(Color.RED);

into

          setBackground(Color.RED);
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 92

Expert Comment

by:objects
ID: 11681843
0
 
LVL 1

Accepted Solution

by:
lowenbrausat earned 500 total points
ID: 11685023
Hi pml_siva,
The solution posted by zzynx is heading you in the right way, however you’ll face a few problems if you use it just like it is…!
Tables usually need to render different data types so you’ll need different cell renderers.
You’ll probably need a checkbox cell render to show Boolean or Bit data, ComboBox cell render to show a list of fixed possibilities, etc.

Each cell renderer type will need to know when to paint a color – background or foreground – and where to do it.

So, the best way to achieve this is to let the JTable object remember de rows you – the user – would like to paint using different colors.

The most common cell renderer extends JLabel – it’s the default cell renderer – so I’ll work here with a Custom Cell Renderer that extends JLabel.

First, the JTable implementation needed to remember the rows to paint:

import javax.swing.JTable;                    import javax.swing.table.*;
import java.util.Hashtable;
import java.awt.Color;

public class MyJTable extends JTable
{
  Hashtable rowsToPaint = new Hashtable(1);

  /**
   * Default Constructor
   */
  public MyJTable()
  {
    super();
  }

  /**
   * Set the TableModel and then render each column with a custom cell renderer
   * @param tm TableModel
   */
  public void setModel(TableModel tm)
  {
    super.setModel(tm);
    renderColumns(new JLabelRenderer(this));
  }

  /**
   * Add a new entry indicating:
   * @param row the row to paint - the first row = 0;
   * @param bgColor background color
   */
  public void addRowToPaint(int row, Color bgColor)
  {
    rowsToPaint.put(new Integer(row), bgColor);
    this.repaint();// you need to repaint the table for each you put in the hashtable.
  }

  /**
   * Returns the user selected BG Color or default BG Color.
   * @param row the row to paint
   * @return Color BG Color selected by the user for the row
   */
  public Color getRowToPaint(int row)
  {
    Color bgColor = (Color)rowsToPaint.get(new Integer(row));
    return (bgColor != null)?bgColor:getBackground();
  }

  /**
   * Render all columns with the specified cell renderer
   * @param cellRender TableCellRenderer
   */
  public  void renderColumns(TableCellRenderer cellRender)
  {
    for(int i=0; i<this.getModel().getColumnCount(); i++)
    {
      renderColumn(this.getColumnModel().getColumn(i), cellRender);
    }
  }

  /**
   * Render a TableColumn with the sepecified Cell Renderer
   * @param col TableColumn
   * @param cellRender TableCellRenderer
   */
  public void renderColumn(TableColumn col, TableCellRenderer cellRender)
  {
    try{
          col.setCellRenderer(cellRender);
        }catch(Exception e){System.err.println("Error rendering column: [HeaderValue]: "+col.getHeaderValue().toString()+" [Identifier]: "+col.getIdentifier().toString());}
  }
}


Now, the Custom Cell Renderer:



import javax.swing.*;                           import java.awt.Component;
import javax.swing.table.*;

public class JLabelRenderer extends JLabel implements TableCellRenderer
{
  private MyJTable myTable;
  /**
   * Creates a Custom JLabel Cell Renderer
   * @param t your JTable implmentation that holds the Hashtable to inquire for
   * rows and colors to paint.
   */
  public JLabelRenderer(MyJTable t)
  {
    this.myTable = t;
  }

  /**
   * Returns the component used for drawing the cell.  This method is
   * used to configure the renderer appropriately before drawing.
   * see TableCellRenderer.getTableCellRendererComponent(...); for more comments on the method
   */
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
  {
    setOpaque(true); //JLabel isn't opaque by default
    setText(value.toString());
    setFont(myTable.getFont());

    //Colors

    if(!isSelected)//if the row is not selected then use the custom color
    setBackground(myTable.getRowToPaint(row));
    else //if the row is selected use the default selection color
    setBackground(myTable.getSelectionBackground());

    //Foreground could be changed using another Hashtable...
    setForeground(myTable.getForeground());

    // Since the renderer is a component, return itself
    return this;
  }


  // The following methods override the defaults for performance reasons
  public void validate() {}
  public void revalidate() {}
  protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
  public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
}

Finaly, a Test Frame to see the results:

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

public class TestFrame extends JFrame
{
  MyJTable myTable = new MyJTable();

  public TestFrame()
  {
    try {  jbInit(); } catch(Exception e) {  e.printStackTrace(); }
    setSize(400, 400);
    show();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    add some data to the table here
    ...

    //set a new bg color on first row
    myTable.addRowToPaint(0, Color.red);

    //set a new bg color on third row
    myTable.addRowToPaint(2, Color.gray);
  }

  public static void main(String[] args)
  {
    TestFrame testFrame = new TestFrame();
  }

  private void jbInit() throws Exception
  {
    this.getContentPane().add(myTable, BorderLayout.NORTH);
  }
}


Why do I use a different Cell Renderer for each column on the table?
Because, each column could have different data types.
i.e. Column 0 has plain text; Column 1 has Boolean data, Column 2, fixed data (you can use a ComboBox to show the fixed data with a CellEditor), etc.

 The method renderColumn(TableColumn col, TableCellRenderer cellRender) in class MyJTable lets you set a custom renderer on each column.

Hope this let you understand a little bit more the rendering process. Tables, List and ComboBoxes can be rendered this way.
Just let me know if you need further explanation.
cya!
0
 
LVL 1

Expert Comment

by:lowenbrausat
ID: 11687447
Just a few more lines....
I've done this method and classes to let the user select a BG color from a JColorChooser. Add all this methods and inner clases to the original MyJTable class posted before. Add them at the end of the class, but before the closing '}'.

  private JPopupMenu createPopupMenu()
  {
    String menuName = (getSelectedRows().length == 1)?"Paint Row "+(getSelectedRow()+1):"Paint Selected Rows";
    JMenuItem newBGColorItem = createMenuItem(menuName, new ShowColorChooserAL(this));
    JPopupMenu popup = new JPopupMenu();
    popup.add(newBGColorItem);
    return popup;
  }

  private JMenuItem createMenuItem(String menuName, java.awt.event.ActionListener listener)
  {
    JMenuItem jm = new JMenuItem(menuName);
    jm.addActionListener(listener);
    return jm;
  }

/////INNER CLASSES TO MAMAGE EVENTS/////

  class MyJTableMouseListener extends MouseAdapter
  {
    public void mouseClicked(MouseEvent e)
    {
      if(e.getButton() == MouseEvent.BUTTON3)//right button
      {
          createPopupMenu().show((MyJTable)e.getSource(), e.getX(), e.getY());
      }
    }
  }


  class ShowColorChooserAL implements ActionListener
  {
    private MyJTable parentComp;

    public ShowColorChooserAL(MyJTable c)
    {
      parentComp = c;
    }

    public void actionPerformed(ActionEvent e)
    {
      JColorChooser jcc = new JColorChooser();
      Color selColor = jcc.showDialog(parentComp, "Choose BG Color", Color.white);
      if(selColor != null)
      {
        int[] selectedRows = parentComp.getSelectedRows();
        for(int i=0; i<selectedRows.length; i++)
        {
          parentComp.addRowToPaint(selectedRows[i], selColor);
        }
      }
    }
  }


Finaly, add this line in the constructor of MyJTable class:    this.addMouseListener(new MyJTableMouseListener());

By the way, you'll need to modify the "imports" to compile the class with this modifications.
You'll need javax.swing.JPopupMenu; javax.swing.JMenuItem; javax.swing.JColorChooser; java.awt.event.*;


At Run-Time, select one or more rows and press the right mouse button. You'll see a popup menu with one menu item.
This menu item will open a JColorChooser. Select a color, OK button and thats it!! The selected rows will have a new BG Color.
Hope this is what you are looking for...!
cya!


0
 
LVL 37

Expert Comment

by:zzynx
ID: 11687664
>>The solution posted by zzynx is heading you in the right way, however you’ll face a few problems if you use it just like it is…!
>>Tables usually need to render different data types so you’ll need different cell renderers.
>>You’ll probably need a checkbox cell render to show Boolean or Bit data,
The default renderer IS a check box in case of a boolean

>>ComboBox cell render to show a list of fixed possibilities, etc.

1) If the author doesn't need special renderers my solution will work OK.

2) If he uses special renderers for specific columns then it's easy to adapt them:

           private int rowToColor = -1;

           public void setRowToColor(int row) {
               rowToColor = row;
           }

           if (rowToColor!=-1 && row==rowToColor)
               setBackground(Color.RED);

3) In this case - of using special renderers - I like the idea of remembering the row to color centralized.
    But I wouldn't do that in your own extension of the JTable, but in my own extension of TableModel.

    Then the above becomes:
           int rowToColor = ( (MyOwnTableModel) table.getModel() ).getRowToColor();
           if (rowToColor!=-1 && row==rowToColor)
               setBackground(Color.RED);
0
 

Expert Comment

by:tienthinh
ID: 26105285
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int col)
{

    String s = table.getModel().getValueAt(row,col).toString();

    if(s.equalsIgnoreCase("Fail")) {
         setForeground(Color.red);
    }else {
         setForeground(null);
    }
   
    return super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, col);

}
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

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…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

758 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

27 Experts available now in Live!

Get 1:1 Help Now