Remove column from a JTable

12,495

Solution 1

An adjacency matrix may be more easily manipulated in an AbstractTableModel, where you can explicitly manipulate the rows to elide one column. In outline,

class MatrixModel extends AbstractTableModel {

    private int rows;
    private int cols;
    private Boolean[][] matrix;

    MatrixModel(int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
        matrix = new Boolean[rows][cols];
    }

    public void deleteColumn(int col) {
        for (Boolean[] row : matrix) {
            Boolean[] newRow = new Boolean[row.length - 1];
            // TODO: copy remaining values
            row = newRow;
        }
        this.fireTableStructureChanged();
    }
    ...
}

Solution 2

for example

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumn;

public class MyDialog extends JDialog {

    private static final long serialVersionUID = 1L;
    private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
    private Stack<TableColumn> colDeleted = new Stack<TableColumn>();

    public MyDialog() {
        Object[][] data = {{"Mary", "Campione", "Snowboarding", new Integer(5), false},
            {"Alison", "Huml", "Rowing", new Integer(3), true},
            {"Kathy", "Walrath", "Knitting", new Integer(2), false},
            {"Sharon", "Zakhour", "Speed reading", new Integer(20), true},
            {"Philip", "Milne", "Pool", new Integer(10), false}};
        final JTable table = new javax.swing.JTable(data, columnNames);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        add(new JScrollPane(table));
        final JButton button1 = new JButton("Add Col");
        final JButton button = new JButton("Remove Last Col");
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                if (table.getColumnCount() > 0) {
                    TableColumn colToDelete = table.getColumnModel().getColumn(table.getColumnCount() - 1);
                    table.removeColumn(colToDelete);
                    table.validate();
                    colDeleted.push(colToDelete);
                    button1.setEnabled(true);
                } else {
                    button.setEnabled(false);
                }
            }
        });
        button1.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                if (colDeleted.size() > 0) {
                    table.addColumn(colDeleted.pop());
                    table.validate();
                    button.setEnabled(true);
                } else {
                    button1.setEnabled(false);
                }
            }
        });
        JPanel southPanel = new JPanel();
        southPanel.add(button);
        southPanel.add(button1);
        add(southPanel, BorderLayout.SOUTH);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        pack();
        setLocation(150, 150);
        setVisible(true);
    }

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

            @Override
            public void run() {
                MyDialog myDialog = new MyDialog();
            }
        });
    }
}
Share:
12,495
Kenny D.
Author by

Kenny D.

Big Data Engineer @ Microsoft Android Fan Coding Fan Geek at Heart. http://mx.linkedin.com/in/kennyeni

Updated on November 22, 2022

Comments

  • Kenny D.
    Kenny D. over 1 year

    I'm making a graph-related program so I need to dynamically create/remove columns from a JTable to simulate the adjacency table. I already can create columns when desired but I cannot remove them, because if I remove a column and then I create another column the previous data (from the deleted column) is shown in the newest column.

    I have read this is because the column data is not removed from the tablemodel. I have seen examples to hide or show columns but I need really to remove them so then when I get the 2-dimensional matrix of data I don't have crossed references nor bad data.

    First correction:

    private DefaultTableModel removeCol(int id){
            DefaultTableModel tmp = new DefaultTableModel();
            int columnas = modelo.getColumnCount();
            for(int i=0;i<columnas;i++){
                if(i!=id)
                    tmp.addColumn(modelo.getColumnName(i));
            }
            int rows = modelo.getRowCount();
            String datos[] = new String[columnas-1];
            for(int row=0;row<rows;row++){
                for(int col=0,sel=0;col<columnas;col++,sel++){
                    if(col!=id)
                        datos[sel] = (String) modelo.getValueAt(row, col);
                    else
                        sel--;
                }
                tmp.addRow(datos);
            }
            return tmp;
    
        }
    

    When invoking:

       DefaultTableModel mo = removeCol(i);
        tblTrans = new JTable(mo);
    
    • Andrew Thompson
      Andrew Thompson almost 12 years
      One way is to provide a new TableModel with the same data except one less column. Perhaps a better way is to create a custom table model that allows you to configure the visibility of columns and adjusts the columnCount and related columns at run-time.
    • Kenny D.
      Kenny D. almost 12 years
      I tried to do the first option, but after getting a corrected TableModel (checked with debugger so data, columns and all are correct within) I can't get the JTable to show the new model, it shows the old model :S (Details in my post)
    • Andrew Thompson
      Andrew Thompson almost 12 years
      For better help sooner, post an SSCCE.
  • Nathan Tuggy
    Nathan Tuggy about 9 years
    Please do not simply post the same answer to multiple questions without at least adapting to explain its applicability to each one.