简体   繁体   中英

Java JTable object with multiple fields

I have an object that has X number of fields. Each row in my JTable corresponds to one item. Each column in the row represents a field for that item. I also need to maintain a reference to the item (the item has a unique ID field as well) so I can determine the item in the selected cell.

Would the preferred approach to this be putting the actual object in each cell in the table and using various renderers to display the item or to simply put the field values in each of the cells and have a hidden column that has the item ID that I can reference when I need to know the item ID?

thanks, Jeff

I'd write a custom table model (as opposed to trying to shoehorn your design into the default table model implementation). This model then holds your actual objects, and in its method implementations (such as getValueAt ), it'd consider each of the fields as a column.


Simple example (not tested, but should illustrate the idea nicely):

import java.util.List;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;

/**
 * Simple table model for displaying properties common to all objects.
 * Note that all methods must run inside the event dispatch thread.
 */
public class ObjectPropertyTableModel extends AbstractTableModel {
    private final List<Object> objects = new ArrayList<Object>();

    public void addObject(Object obj) {
        addObject(obj, objects.size());
    }

    public void addObject(Object obj, int index) {
        objects.add(index, obj);
        fireTableRowsInserted(index, index);
    }

    public void removeObject(Object obj) {
        int index = objects.indexOf(obj);
        objects.remove(index);
        fireTableRowsDeleted(index, index);
    }

    public Object getObject(int rowIndex) {
        return objects.get(rowIndex);
    }

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

    @Override
    public int getColumnCount() {
        return 3;
    }

    @Override
    public String getColumnName(int columnIndex) {
        switch (columnIndex) {
        case 0: return "toString";
        case 1: return "hashCode";
        case 2: return "class";
        default: throw new IndexOutOfBoundsException();
        }
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
        case 0: return String.class;
        case 1: return Integer.class;
        case 2: return Class.class;
        default: throw new IndexOutOfBoundsException();
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Object obj = objects.get(rowIndex);
        switch (columnIndex) {
        case 0: return obj.toString();
        case 1: return obj.hashCode();
        case 2: return obj.getClass();
        default: throw new IndexOutOfBoundsException();
        }
    }
}

You might be able to use the Bean Table Model . If not, then the JButtonTableModel examples shows how you might implement the getValueAt/setValueAt() methods and take advantage of the functionality provided by the RowTableModel so you don't need to create the TableModel from scratch.

My preferred approach is to have a table model which returns a value from the field for each column. To be able to get a reference to the object, I add a method to the model which could be called getObjectFromRow and as its name suggests, it returns the object corresponding to the row index. This way you can have the actual displayed data in the cell and you don't need a hidden column to get a reference to the row object. Of course this requires a custom table model but I think it's well worth the trouble.
Of course using renderers for displaying data from the correct field is also possible, but in my experience this has several problems, including the trouble of writing all the renderers for different data types and also the fact that copy & paste from the table does not work properly out of the box.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM