2

I need help at adding a empty row to my JTable. I use a AbstractTableModel for my JTable! I have here a small executable program for you so it is easier to help me.

Main Class - TestClass.java

package testproject;

import java.awt.event.ActionEvent;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JTable;

public class TestClass {

    String[] header = {"Name", "Quantity"};
    ArrayList<Object[]> data = new ArrayList<Object[]>();

    public TestClass() {
        data.add(new Object[]{"Apple", "234"});
        data.add(new Object[]{"Banana", "123"});
        data.add(new Object[]{"Cranberry", "346"});

        JFrame frame = new JFrame();
        JTable table = new JTable(new Model(data, header));
        JMenuBar menubar = new JMenuBar();
        JMenu editmenu = new JMenu("Edit");

        Action addrowaction = new AbstractAction("Add Row") {
            private static final long serialVersionUID = 1433684360133156145L;

            @Override
            public void actionPerformed(ActionEvent e) {
                data.add(new Object[9]);
            }
        };

        frame.add(table);

        frame.setJMenuBar(menubar);
        menubar.add(editmenu);
        editmenu.add(addrowaction);

        frame.setLocationByPlatform(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.pack();
    }

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

Table Model - Model.java

package testproject;

import java.util.ArrayList;

import javax.swing.table.AbstractTableModel;

public class Model extends AbstractTableModel{
    private static final long serialVersionUID = 6889542282067432083L;

    private String[] header;
    private ArrayList<Object[]> data;

    public Model(ArrayList<Object[]> data, String[] header) {
        this.header = header;
        this.data = data;
    }

    @Override
    public int getColumnCount() {
        return header.length;
    }

    @Override
    public String getColumnName(int column) {
        return header[column];
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public Object getValueAt(int row, int column) {
        return data.get(row)[column];
    }

    @Override
    public void setValueAt(Object value, int row, int column) {
        data.get(row)[column] = value;
        fireTableCellUpdated(row, column);
    }
}

Basically I want to use a Action in the edit menu to add a empty row. Please do not answer with other links! I searched for it but don't understand it or it isnt suitable for my program!

EDIT: Updated the source as suggested by MadProgrammer! There is only one problem left. How I update the JTable so the new Row is displayed at the moment I have to resize the Window and the Table is updating!

  • Thank you for help
Community
  • 1
  • 1
Gerret
  • 2,948
  • 4
  • 18
  • 28
  • 2
    1- Change your data model, arrays are not suited to this task. 2- Add a method that will create a new row "object" in your table model – MadProgrammer Aug 19 '13 at 09:24
  • @MadProgrammer I cant change the array I need it my whole program is based on it. What you mean with new row object? – Gerret Aug 19 '13 at 09:25
  • A row is typically represented by a Object of some kind, in your case, this is a 2D array. Arrays are not suited for what you trying to achieve. They are difficult to increase in size dynamically and have a high overhead when doing. It would be better to store the data in an `ArrayList`, you could use `ArrayList`, where each item in the `ArrayList` represents a row, and the `Object[]` represents the column values... – MadProgrammer Aug 19 '13 at 09:29
  • @MadProgrammer Well yes your right and you are sure this is the only why I mean I could change the Array to an ArrayList but it would cost me a lot of work. This is only with a ArrayList possible? – Gerret Aug 19 '13 at 09:33
  • To be honest. It is significantly easier to use something like `ArrayList` as it does what you want as is optimised to do the job... – MadProgrammer Aug 19 '13 at 10:07
  • not don't to bother with AbstractTableModel, its methods, notifiers etc., use DefautTableModel without any of a.m. issue, btw with Vector as underlaying array is everything possible, inc zero effort for ColumnModel – mKorbel Aug 19 '13 at 10:12
  • @MadProgrammer ATmKorbel ATtrashgod give me some time ill fix that and ive no problem with the arraylist ive a problem to change my whole program ;) – Gerret Aug 19 '13 at 10:31
  • You may not need to change you're entire program. The `TableModel` should be capable of wrapping your data – MadProgrammer Aug 19 '13 at 10:37
  • Yes but I use a database to and I fill that into the array also for clear it to change data to use checkboxes everything is dont with the Object[][] – Gerret Aug 19 '13 at 10:39
  • @MadProgrammer could you have a look at my edit! I used you suggestion now but ive a problem with the update! – Gerret Aug 19 '13 at 11:46
  • 2
    Do not access `data` directly in your `ActionListener`. Add a method to the model to do that which will then call a `fireTableRowsInserted` method. Make any changes to your data through your model. That is what a model is about :) – c.s. Aug 19 '13 at 12:10
  • Yea your right first I made a mistake with table.getModel() I got it now I used Model model = table.getModel(); and model.fireTableStructureChanged(); Thank you anyway for you help :) – Gerret Aug 19 '13 at 12:22

1 Answers1

3

As @MadProgrammer comments, arrays are conceptually easy to understand but hard to expand & contract. Instead, use a Collection. In this example, MyModel manages a List<Row> that is implemented as an ArrayList<Row>. Each Row is a Plain Old Java Object (POJO) having an attribute for each column. Try adding a method to insert new rows using the constructor as an example, then try adding a column to Row. The example uses a static nested class to avoid clutter.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • @mKorbel cites a compelling example; note that I made the same [mistake](http://stackoverflow.com/posts/12352838/revisions). :-) – trashgod Aug 19 '13 at 10:27
  • @trashgod Could you have a look at my edit pls :) I ve just one problem left! – Gerret Aug 19 '13 at 11:04
  • @Gerret: Kudos for `Action`, but have it invoke a model method that calls an appropriate `fireXxx()`, as c.s. suggests. – trashgod Aug 19 '13 at 14:46