Appropriate collection for model of JTable used for selection

307 views Asked by At

What is best collection for storing data in JTable's model (extending AbstractTableModel) if table contains check box for selection in first column and object's attributes in other columns (so boolean attribute is not part of domain object in row)? This is what i have now, but i suppose that some Map or List would serve better?

EDITED: I need some mutable collection to hold on a pair of boolean/Person, from which i can easily retrieve all Persons with boolean set to true.

public class TableModelPerson extends AbstractTableModel {

    private String columnName[] = {"Yes/No", "First name", "Last name"};
    private Object data[][] = {
        {true, new Person("Katy", "Brown")},
        {false, new Person("Sam", "Brown")},
        {true, new Person("Peter", "Brown")}
    };

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

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

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
         Person person = (Person) data[rowIndex][1];
         switch (columnIndex) {
            case 0:
               return data[rowIndex][0];
            case 1:
               return person.getFirstName();
            case 2:
               return person.getLastName();
         }
      return "error";
   }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
       data[rowIndex][columnIndex] = aValue;
       fireTableDataChanged();
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
       return getValueAt(0, columnIndex).getClass();
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
      if (columnIndex == 0) {
        return true;
      }
      return false;
    }

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

    public List<Person> getAllSelectedPersons() {
      List<Person> lista = new ArrayList<>(1);
        for (int i = 0; i < data.length; i++) {
           if (data[i][0] == true) {
            lista.add(new Person((String) data[i][1], (String) data[i][2]));
           }
        }
        return lista;
    }

    public void addPerson(Person person){
        // code for adding a person
    }

    public void removePerson(Person person){
        //code for removing person
    }

  }

EDITED: I maybe found a solution:

    private List<Map.Entry<Boolean, Person>> boolPerson = new ArrayList<>();

    public List<Person> getPersonsSelected(){
       List<Person> personList = new ArrayList<>();
       for(Map.Entry<Boolean, Person> entry : boolPerson){
          if(entry.getKey()){
              personList.add(entry.getValue());
          }
       }
       return personList;
    }

But, i'm still wondering is there a better one?

I intended to post a photo of table but i can't because it is my first question, so please be gentle :)

1

There are 1 answers

1
camickr On

Take a look at Row Table Model. Only the first part relates to this question. It shows how to create a custom PersonTableModel.

In the example the Person is stored in a List and depending on the column parameter the appropriate getter method from the Person class is used to get the data. In your case you want the Boolean value separated from the Person, so you will also need to have separate storage for all the Boolean values.

Then you need to customize all the method to take into account the extra Boolean column. For example you might customize the getColumnClass() method as follows:

@Override
public Class getColumnClass(int column)
{
    switch (column)
    {
        case 0: return Boolean.class; // added
        case 3: return Date.class; // changed
        default: return String.class;
    }
}

So I suggest you first get your code working for a simple Person class using the code from the blog to understand the basics of creating a custom TableModel. Then do further customization to add a Boolean column at the beginning.