Unable to get column index with table.getColumn method using custom table Model

16,721

Solution 1

In order to retrieve columns by identifier, you have to set one using TableColumn.setIdentifier().

EDIT:

Note that according to specs of TableColumn.getIdentifier():

If the identifier is null, getIdentifier() returns getHeaderValue as a default.

That is how it works in the linked example.

EDIT:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.GridLayout;

public class TableDemo extends JPanel {
    public TableDemo() {
        super(new GridLayout(1,0));

        JTable table = new JTable(new MyTableModel());

        JScrollPane scrollPane = new JScrollPane(table);

        add(scrollPane);

        table.getColumn("Column1").setCellRenderer(new TestCellRenderer());
        table.getColumn("Column2").setCellRenderer(new TestCellRenderer());
    }

    class TestCellRenderer extends DefaultTableCellRenderer{ }

    class MyTableModel extends AbstractTableModel {
        private String[] columnNames = { "Column1", "Column2" };
        private Object[][] data = { { "1", "1" }, { "2", "2" } };

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return data.length;
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("TableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        TableDemo newContentPane = new TableDemo();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

Solution 2

1.use Table Button Column by @camickr

2.JButton in JTable represents String value stored in XxxTableModel, then have to override the ColumnClass

     public Class getColumnClass(int column) {
        switch (column) {
            case 0:
                return Date.class;
            case 1:
                return Integer.class;
            case 2:
                return Long.class;
            case 3:
                return Double.class;
            case 4:
                return Boolean.class;
            case 5:
                return Icon.class;
            default:
                return String.class;
        }
    }

Cells in the Column should be editable

    public boolean isCellEditable(int row, int col) {
        switch (col) {
            case 0:
                return false;
            case 1:
                return false;
            default:
                return true;
        }
    }

3.everything is about your AbstractTableModel, maybe there no reason use that, use DefaultTableModel before, in the case that you understand How XxxTableModel works, then you can to override methods for JTable with AbstractTableModel

Share:
16,721
Amarnath
Author by

Amarnath

Full Stack Developer (Java + Angular 2) at Pramati Technologies, Hyderabad. Currently working on Health Domain MicroServices application. Recently participating in Open Source contribution. Github Interested in Java, J2EE, JavaScript, AngularJS, NodeJS, Web Technologies. Zealous to learn new technologies.

Updated on June 05, 2022

Comments

  • Amarnath
    Amarnath almost 2 years

    I have created a custom TableModel using AbstractTableModel. I am able to populate my JTable. But my JTable has a button column say "Button1". So I am using CellRenderer method to add buttons to column and CellEditor to add actions, but I am getting exception at LINE:3.

    CustomModelForTable customTableModel = new CustomModelForTable(colNames, data);
    tableA = new JTable(customTableModel);
    
    **LINE:3** 
    tableA.getColumn("Button1").setCellRenderer(new JButtonRendererClass());
    tableA.getColumn("Button1").setCellEditor(new ButtonEditor(new JCheckBox()));
    

    I am getting the following error.

    java.lang.IllegalArgumentException: Identifier not found
    at javax.swing.table.DefaultTableColumnModel.getColumnIndex(DefaultTableColumnModel.java:265)
    

    I am getting this error because I am not able to get the Column from my custom Table. But can some one help me out with this issue.

    I am using the following source to perform this task. In this source they are using DefaultTableModel where as in my case I am using AbstractTableModel.

  • tenorsax
    tenorsax over 11 years
    @Che What is the header value for that column? See my last edit.
  • Amarnath
    Amarnath over 11 years
    Column header value is Button1 which is of type JButton class
  • tenorsax
    tenorsax over 11 years
    @Che Make sure you implement getColumnName() in your model. See my last edit for a simple example of a model.
  • Amarnath
    Amarnath over 11 years
    Awesome. Works like a champ. Thank you. But just one explanation regarding this. How getColumnName(int col) method helped to achieve this?
  • tenorsax
    tenorsax over 11 years
    @Che When new column is created in JTable, column's name is used to set column's header name (unless this column already has a header value). Then during lookup by identifier, the column's header name is used in case its identifier is null (part of getIdentifier() method).
  • Amarnath
    Amarnath over 11 years
  • tenorsax
    tenorsax over 11 years
    @Che ditto, it turned to be an challenging question.