2

I am creating JTable with custom table cell renderer by extending DefaultTableCellRenderer where I would like to use some image along with the text.

enter image description here

As you can see above, even though I have selected the particular row, it is not highlighting in the Testcases column. I have tried some existing SO questions (Q1, Q2) solutions, but still it is not working. Where I am making the mistake ?

JTableTest.java

import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class JTableTest extends JFrame {

    public DefaultTableModel testcaseModel;
    public JTable testcasesTable;
    Object[] testcaseTableColumns = {"S.No", "Testcases"};
    public static final int TESTCASE_SNO_COLUMN = 0;
    public static final int TESTCASE_NAME_COLUMN = 1;

    public JTableTest() {
        initComponents();
    }

    private void initComponents() {
        if (testcaseModel == null) {
            testcaseModel = new DefaultTableModel(null, testcaseTableColumns){

                @Override
                public Class<?> getColumnClass(int columnIndex) {
//                    if (columnIndex == -1) {
//                        return Integer.class;
//                    } else if(columnIndex==1){
//                        return JLabel.class;
//                    }
                    return Object.class;
                }

            };
        }
        if (testcasesTable == null) {
            testcasesTable = new JTable(testcaseModel) {
                @Override
                public boolean isCellEditable(int row, int column) {
                    return false;
                }
            };
        }
        testcasesTable.setCellSelectionEnabled(true);
        testcasesTable.getColumnModel().getColumn(TESTCASE_NAME_COLUMN).setCellRenderer(new LabelRenderer());
        for (int i = 0; i < 10; i++) {
            testcaseModel.addRow(new Object[]{i, (i * 100)});
        }
    }

    public static void main(String[] args) {
        JTableTest jTableTest = new JTableTest();
        jTableTest.setSize(300, 300);
        jTableTest.setTitle("TableIcon");
        jTableTest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel pnlMain = new JPanel(new BorderLayout(10, 10));
        JScrollPane scrollPane = new JScrollPane(jTableTest.testcasesTable);
        pnlMain.add(scrollPane);
        jTableTest.getContentPane().add(pnlMain);
        jTableTest.setVisible(true);

    }

}

LabelRenderer.java

import java.awt.Component;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.table.DefaultTableCellRenderer;


public class LabelRenderer extends DefaultTableCellRenderer {

    public static final Border focusedCellBorder = UIManager.getBorder("Table.focusCellHighlightBorder");

    public static final Border unfocusedCellBorder = createEmptyBorder();

    private static Border createEmptyBorder() {
        Insets i = focusedCellBorder.getBorderInsets(new JLabel());
        return BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        String text = value.toString();
        JLabel label = new JLabel(text);

        try {
            label.setIcon(new ImageIcon(getClass().getResource("ok_16px.png")));
            // This below code setting the border to be highlighted, but not whole              
            label.setBorder(hasFocus ? focusedCellBorder : unfocusedCellBorder);

        } catch (Exception ex) {
            System.out.println(ex);
        }
       // This also not working.....    
        if (isSelected) {
            label.setBackground(table.getSelectionBackground());
            label.setForeground(table.getSelectionForeground());
        } else {
            label.setBackground(table.getBackground());
            label.setForeground(table.getForeground());
        }
        return label;
    }
}
Community
  • 1
  • 1
Dinesh
  • 16,014
  • 23
  • 80
  • 122
  • 1
    1. label.setIcon(new ImageIcon(getClass().getResource("ok_16px.png"))); isn't good idea load images to the local variable(s), 2. public static final should be public final, 3, isSelected and hasFocus, 4, to cast (J)Component to the JLabel, there isn't reaqson to create an local variable for, 5. many times here, incl. workaround for Nimbus L&F – mKorbel Sep 29 '15 at 07:03
  • @mKorbel : Poor Me!!! Thank you for the tips for my learnings. Will follow Sir. – Dinesh Sep 29 '15 at 07:27
  • plus one for an SSCCE / MCVE – mKorbel Sep 29 '15 at 08:20

1 Answers1

3

Don't create another JLabel in the TableCellEditor, DefaultTableCellEditor extends from JLabel already, you just to apply the settings you need, leave the DefaultTableCellRenderer to take care of the rest

Selected

public class LabelRenderer extends DefaultTableCellRenderer {

    public static final Border focusedCellBorder = UIManager.getBorder("Table.focusCellHighlightBorder");

    public static final Border unfocusedCellBorder = createEmptyBorder();

    private static Border createEmptyBorder() {
        Insets i = focusedCellBorder.getBorderInsets(new JLabel());
        return BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        String text = value.toString();

        try {
            setIcon(new ImageIcon(getClass().getResource("ok_16px.png")));
            // This below code setting the border to be highlighted, but not whole              

        } catch (Exception ex) {
            System.out.println(ex);
        }
        setBorder(hasFocus ? focusedCellBorder : unfocusedCellBorder);

        return this;
    }
}

Also, note, that with cellSelection enabled, you will need to click a cell in the second column to see the highlighting. Turn it off to allow for full row selection

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • @ MadProgrammer : It seems like `setBorder()` itself not required. Using the `setIcon()` alone does the required magic!!!. – Dinesh Sep 29 '15 at 07:29