1

Let's say I have a List of Items(my own class that I created that have 5 fields). I want to somehow inject these items into the JTable.
And in the JTable I want to have some kind of method like public String determineColumnText(Object o, int col) where I can convert the received Object into Item and then based on the col take out a specific value from the Item and return it so that it will be shown.

I have tried searching and saw numerous answers saying create AbstractTableModel however all the tutorials I looked at do not provide anything that I desired. Closest I saw was public Object getValueAt(int rowIndex, int columnIndex) however that would mean that I would have to store all the objects I want to display inside the AbstractTableModel. But what if I want to make it so that the Object is not stored inside AbstractTableModel but at the same time can be send into the AbstractTableModel.

Any suggestion as to how to go about doing this?

jzd
  • 23,473
  • 9
  • 54
  • 76
Quillion
  • 6,346
  • 11
  • 60
  • 97

3 Answers3

3

But what if I want to make it so that the Object is not stored inside AbstractTableModel

The Object should always be stored inside the TableModel. You can create the Object externally but then you need to add the Object to the TableModel. Once the Object is part of the model you should only manipulate it through the TableModel methods.

See the Row Table Model for a TableModel that will allow you to store Objects in the model but allow you to retrieve the data as a complete Object if you desire.

You will need to extend the class to implement your own getValueAt() and setValueAt() methods. These methods will access individual properties of your Object. The JButtonTableModel.java example shows how you can do this.

camickr
  • 321,443
  • 19
  • 166
  • 288
1

Option 1:

  • Loop through your list of items.
  • Build arrays of the data for all cells
  • Pass that array to a DefaultTableModel's constructor, which you will use in a JTable

Option 2:

  • Extend DefaultTableModel and override getValueAt(), like you describe
  • Store a reference to the list in your table model

Option 1 can be simple if the data is not changing. Option 2 is the most flexible but you seem to have an object to it that isn't explained.

jzd
  • 23,473
  • 9
  • 54
  • 76
  • 1
    Neither option is very good. You should not be keeping two references to the data. – camickr Oct 31 '13 at 15:17
  • Sorry I was going to pick your answer as the correct one. But cmickr gave me a solution that I didn't like, but it does work and does seem to be used in other places. I really want to go about storing a reference, but I think it will be shot down during code review. Thank you very much for your answer however, I really like it and wish I could do Option 2 way you described. – Quillion Oct 31 '13 at 15:32
  • 1
    @Quillion, `I really like it and wish I could do Option 2 way you described.` - why would you want to do something that is wrong? Should you not spend your time learning better design principles? Yes, my solution is a little more complex because it has full functionality and is easily reusable (that was a design goal). If you don't need all the functionality then you should use Pentarex's approach since it shows an easy way to create a custom model. – camickr Oct 31 '13 at 16:23
  • @camickr the functionality provided by you is exactly what I was searching for. And yes I agree that it is the best solution. I am very new at this, and sometimes I feel inclined to fall back into my student principles where garbage felt better. It is a nasty habit that is difficult to throw away. Sorry I meant no offense, and I really loved your answer. – Quillion Oct 31 '13 at 16:29
0

I will paste you how I've used AbstractTableModel to populate table.

public class InventoryModel extends AbstractTableModel {

private static final String[] columnNames = { "Owner", "Location", "Sample Name", "Form Factor" };
private List<Samples> samplesList;

public InventoryModel(){
    samplesList = SampleQueries.getAvailableSamples();

}

@Override
public int getColumnCount() {
    // TODO Auto-generated method stub
    return columnNames.length;
}

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

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

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    switch (columnIndex) {
    case 0:
        return samplesList.get(rowIndex).getCurrentOwner();
    case 1:
        return samplesList.get(rowIndex).getSampleLocation();
    case 2:
        return samplesList.get(rowIndex).getSampleName();
    case 3:
        return samplesList.get(rowIndex).getFormFactor();
    }
    return null;
}   

And this is how I call it from the Panel.

    table = new JTable();
    model = new InventoryModel();
    model.fireTableDataChanged();
    panel.setLayout(new BorderLayout(0, 0));
    table.setModel(model);

    JScrollPane scroll = new JScrollPane(table);
    panel.add(scroll);

Hope it will work for you

Pentarex
  • 130
  • 1
  • 9
  • 1
    -1 the fireXXX methods should only be invoked from within the TableModel. And there is certainly no reason to invoke that method just because you create the model. The model hasn't even been added to the table yet. However, you model implementation is a good example of how to access data from a List. – camickr Oct 31 '13 at 15:16