2

I have a JTable with my own Model (extends AbstractTableModel), and I'd like to add a row to it when I Click a JButton.

I don't really know how to hadd the row to the Model.

here is my model:

public class MembersModel extends AbstractTableModel {
  String[] columnNames = {
    "Name",
    "Money Spent",
    "Percent",
    "Current Deck"
  };

  Object[][] data = {
  {"Cajo", new Integer(150), new Integer(0), "Event Deck"},
  {"Sekiam", new Integer(200), new Integer(0), "Jeskay"},
  {"Nuvas", new Integer(100), new Integer(0), "Big Shit"},
  {"Dos", new Integer(100), new Integer(0), "Crap Deck"},
  {"Atoj", new Integer(100), new Integer(0), "IDK"}
  };

  public MembersModel(){
      super();
      calcAllPercent();
  }

  public void calcAllPercent(){
      for(int i = 0; i < data.length; ++i){
        data[i][2] = calcPercetage((Integer) data[i][1]);
      }
  }

  private int calcPercetage(int money){
      return (money*100)/teamMoneySpent();
  }

  private int teamMoneySpent(){
      int money = 0;
      for(int i = 0; i < data.length; ++i){
        money += (Integer) data[i][1];
      }
      return money;
   }

    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];
    }

    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    public boolean isCellEditable(int row, int col) {
       return false;
    } 

    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        calcAllPercent();
        fireTableRowsUpdated(0, 4);
    }
}

Should i create my table aswell or add the method to the Model?

2 Answers 2

4

The key will be the data nucleus that you're using for your model, which here is your 2-D array, Object[][] data. The question then boils down to this: how do you add another row to the array and then notify the model's listener of the addition. While this can be done by creating a new data array with another row, copying all the data from this array, and adding the new data to the newly added row, why bother? For my money I'd

  • create a class to hold the data of a single table row, here I'll call it MyType, but you'll give it a better name, and it will have String, int, int, and String fields to correspond to the columns of your table.
  • Give this class some of the methods you have in your model above, such as doing row-specific calculations, calcPercentage(..), teamMoneySpent(...), and then the model can call the row object's method when this information is needed.
  • use an ArrayList<MyType> as my table model data nucleus, not a 2-dimensional hard-coded array.
  • give my model class an addRow(MyType myObj) method
  • in the method add to the ArrayList
  • and then call the appropriate model notification method, which here would be fireTableRowsInserted(...).

Note, I'm not sure what you mean by,

Should i create my table aswell or add the method to the Model?

Sign up to request clarification or add additional context in comments.

2 Comments

by Should i create my table aswell or add the method to the Model? Should i create my table aswell or add the method to the Model? I meant create a type that extends JTable. I got your process, thanks for the help
@CarlosMorgado: you may need to extend JTable for other reasons, but it has nothing to do with the crux of your current question.
3

Some problems with your current model:

  1. The setValueAt() method is wrong. You should invoking tableCellUpdated(...). You don't want to repaint the data in the entire table when you update a single cell. Actually you don't even need to implement the setValueAt(...) method because your table is not editable.

  2. You didn't override the getColumnClass(...) method. This method is required so the table can use the proper renderer to display the data.

Instead of creating a completely new TableModel, you could extend the DefaultTableModel. It already supports an addRow(...) method.

However, as hovercraft has already pointed out a better design is create a custom Object to store all the data of a single row. For a solution that uses this approach check out Row Table Model for a solution. The base TableModel is more complicated, but it makes it easier to create custom TableModels in the future since all the common code is in one class.

I would implement hovercraft's suggestion first so you better understand the concepts of creating a TableModel with a custom Object. I include this link as a suggestion for the future.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.