0

I have a JTable that contains 4 columns and for example 10 rows. I want to add a new column and put the maximum value for each row in that.

Here is the function that I use to compute the maximum and put them into the new column:

private void jFindmaximumActionPerformed(java.awt.event.ActionEvent evt) {                                             
        DefaultTableModel model = (DefaultTableModel)jMYtable.getModel();
        TableColumn col = new TableColumn(model.getColumnCount());
        String headerLabel = "Maximum";
        col.setHeaderValue(headerLabel);
        jMYtable.addColumn(col);

        model.addColumn(headerLabel.toString(), new Object [0]);  
        double[] MAX = new double[ndata[0].length];
        for(int i = 0; i < ndata[0].length; i++){
            MAX[i] = ndata[i][0];
            for(int j = 0 ; j < ndata.length; j ++){
                if(ndata[j][i] > MAX[i]){
                    MAX[i] = ndata[j][i];
                }
            }
            model.setValueAt(MAX[i],i,4);
        }
        jMYtable.revalidate();
 } 

If my table does not have any row when I call this method the new column is added and shows up on the interface. However, when I populate my table with 10 rows and call this action, table is not acting properly:

  1. There is a gui redraw problem where the new column will show only after mouse goes on the jtable; and
  2. The new column does not have any data.

Please help.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Morteza
  • 13
  • 7
  • I find out that new column does not have any rows, this make problem in rendering of jtable, but how can I add rows for only this column or I need to remove all rows and again insert them into the jtable? – Morteza Jul 27 '13 at 19:11
  • code should be works, jMYtable.revalidate(); is about relayout, quite useless and very hard event called ndata[0].length times – mKorbel Jul 27 '13 at 21:20
  • How can I insert rows for new column? – Morteza Jul 27 '13 at 21:24
  • new row is automatically added with a new column, sure valid for cells in new column – mKorbel Jul 27 '13 at 21:26
  • I recive this error from netbeans Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 4 and its about the public Class getColumnClass(int columnIndex) { return types [columnIndex]; } – Morteza Jul 27 '13 at 21:30
  • I know it related to rows I remove the row from my table and could insert new column without any problem and it work correctly. but when i have a row or more I got error on it...!!! I'm really confused. fully searched internet and try some example in my fuction but nothing change... – Morteza Jul 27 '13 at 21:36
  • I'm really appreciate for your answer dear Korbel... – Morteza Jul 27 '13 at 21:37
  • 2
    1) `// TODO add your handling code here:` The idea is to **remove** those comments once some actual code is added. 2) Please add an upper case letter at the start of sentences. Also use a capital for the word I, and abbreviations and acronyms like JEE or WAR. This makes it easier for people to understand and help. 3) *"Please help."* Please ask a specific question. 4) For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jul 28 '13 at 05:41
  • why would you add arbitrary columns? It's data, so should be the tableModel's task to manage a that column – kleopatra Jul 29 '13 at 12:27

1 Answers1

1

I tested your code and while I didn't get the exact same error, there's a couple of weird things:

First, you are calling both jMyTable.addColumn(...) and model.addColumn(...). Which is a mistake. You only need to call the model's addColumn. Adding also a column with the JTable method will create inconsistencies, because the TableModel and the TableColumnModel are not synchronized.

Your code to add a new column into the model, and the calculation of the maximums is wrong. i should move through rows, and j should move through columns, and then check if we should do the MAX[i] = ndata[i][j]; assignment. And while passing new Object[0] doesn't appear to cause any issues (because that constructor with a null value is valid) it doesn't make any sense.

It should be something like this:

private void jFindmaximumActionPerformed(java.awt.event.ActionEvent evt) {  
    DefaultTableModel model = (DefaultTableModel)jMYtable.getModel();
    String headerLabel = "Maximum";

    Object[] MAX = new Object[ndata.length];

    for(int i = 0; i < ndata.length; i++){
         MAX[i] = ndata[i][0];
          for(int j = 0 ; j < ndata[0].length; j ++){
                  if(ndata[i][j] > MAX[i]){
                        MAX[i] = ndata[i][j];
                  }
             }
    }
    model.addColumn(headerLabel, MAX);  
}

On a side note, if you ever were to implement your own TableModel, extending AbstractTableModel, when the memory structure (created and handled by yourself) that contains the table data changes, you have to update the table with the new values or new column/rows changes using an assortment of methods in the AbstractTableModel class to notify the JTable: fireTableDataChanged(), fireRowsInserted(), fireTableStructureChanged()...

UPDATE:

Here's a simple test code that adds columns to a JTable.

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;

public class SimpleColumnAdderFrame
{
    private DefaultTableModel _model;

    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new SimpleColumnAdderFrame().initUI();
            }
        });
    }

    public void initUI()
    {
        JFrame frame = new JFrame();        
        Object[][] data = {
                {1,2,3},
                {10,20,30}
        };
        String[] columnNames = {"Column 1", "Column 2", "Column 3"};        
        _model = new DefaultTableModel(data, columnNames);
        JTable table = new JTable(_model);

        JButton addColumnButton = new JButton("Add column");
        addColumnButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                int columns = _model.getColumnCount();
                int rows = _model.getRowCount();
                Object[] columnData = new Object[rows];
                for (int i = 0; i < rows; ++i)
                {
                    columnData[i] = (int) ((columns + 1)*(Math.pow(10, i))); // <- Unnecessarily complicated cell value 
                }
                _model.addColumn("New Column " + (columns + 1), columnData);
            }   
        });

        JButton addRowButton = new JButton("Add row");
        addRowButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                int columns = _model.getColumnCount();
                int rows = _model.getRowCount();
                Object[] rowData = new Object[columns];
                for (int i = 0; i < columns; ++i)
                {
                    rowData[i] = (int) ((i+1)*(Math.pow(10, rows))); // <- Unnecessarily complicated cell value 
                }
                _model.addRow(rowData);
            }
        });

        JPanel buttonPanel = new JPanel(new GridLayout(1,2,2,2));
        buttonPanel.add(addColumnButton);
        buttonPanel.add(addRowButton);

        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.add(buttonPanel, BorderLayout.PAGE_END);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

}
DSquare
  • 2,458
  • 17
  • 19
  • thanks dear DSquare for you help. I change my function and follow yours but my problem still remain. It really questionable... may be Netbeans IDE need to be more than these to do such thing... – Morteza Jul 28 '13 at 17:54
  • Adding the column shouldn't be that hard. You can do a simple frame with a table and a button and it works well. The problem must be somewhere else. – DSquare Jul 28 '13 at 20:58
  • Thanks dear DSquare. It was nice. right know I try to find the main reason of problem... – Morteza Jul 30 '13 at 09:41