Search code examples
javaswingjtabletablecellrenderer

How Can I hide same value in the JTable by using DefaultTableCellRenderer


I make a timetable with Java, but I cannot solve one problem.

I want to change the foreground color as same as background color or Hiding a value, when some cells have a same value at first detected cell.

Like this...

Here's what I made...

(Sorry about Korean words...)

So, I want to use a DefaultTableCellRenderer, but I can't find a good example about this.

And, I don't know how DefaultTableCellRenderer works. Can't find any explains about that...

So, I want to ask a favor about that problem.

Here's my code:

public class subject_table_renderer extends DefaultTableCellRenderer
{ 
private Object subject_name = "";
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean   isSelected, boolean hasFocus, int row, int column) 
{ 
    Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
    if (! isSelected) 
    {
        if(value.equals("")){
                cell.setBackground(Color.WHITE);
        }
        else{
            String[] temp = MainFrame.find_list((String)value, MainFrame.subject);
            //take a subject_list for decide background color

            if(!value.equals(subject_name)){
                subject_name = value;
                cell.setBackground(get_rand_color(cell, Integer.parseInt(temp[6])));
            }
            else{   
                cell.setBackground(get_rand_color(cell, Integer.parseInt(temp[6])));
                cell.setForeground(get_rand_color(cell, Integer.parseInt(temp[6])));
            }
        }
    }
    return cell;
} 

Solution

  • And, I don't know how DefaultTableCellRenderer works. Can't find any explains about that...

    Maybe start with the Swing tutorial on Concepts: Editors and Renderers.

    You can't use an instance variable to track the previous value because you can't be guaranteed that the rows will always be rendered in sequential order. For example if row 1 is selected and then you click on row 10, only rows 1 and 10 will be repainted.

    So the solution is to compare the previous value in the render with code something like:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.text.*;
    import javax.swing.table.*;
    
    public class SSCCE extends JPanel
    {
        public SSCCE()
        {
            setLayout( new BorderLayout() );
    
            JTable table = new JTable(10, 1);
            table.setValueAt("one", 0, 0);
            table.setValueAt("one", 1, 0);
            table.setValueAt("two", 2, 0);
            table.setValueAt("two", 3, 0);
            table.setValueAt("two", 4, 0);
            table.setValueAt("three", 5, 0);
            add( new JScrollPane( table ) );
    
            table.getColumnModel().getColumn(0).setCellRenderer( new DuplicateRenderer() );
        }
    
        /*
        **  Color the focused cell
        */
        class DuplicateRenderer extends DefaultTableCellRenderer
        {
            @Override
            public Component getTableCellRendererComponent(
                JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
            {
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    
                if (row > 0 && value != null)
                {
                    Object previous = table.getValueAt(row - 1, column);
    
                    if (value.equals(previous))
                    {
                        setText("");
                    }
                }
    
                return this;
            }
        }
    
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new SSCCE());
            frame.setLocationByPlatform( true );
            frame.pack();
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater( () -> createAndShowGUI() );
    /*
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowGUI();
                }
            });
    */
        }
    }