简体   繁体   中英

JTable & custom TableModel not acting as expected

So I have been reading through Java's "How to use Tables" as I am trying to implement a JTable into my program. What I want is to take a list of String values from a database and then sort them by column and row names. Now I know there isn't a default row Header like there is for column's so I have been sidestepping this by making my first column a "row header". So then I decided to create a custom Table Model for my Jtable in order to sort the data correctly (the data is stored in a Vector of Vectors of Strings & column/row names as a Vector of Strings separately) but all I have been running into is problems. At first I was receiving a whole bunch of array out of index errors, so I added in code that showed me where data from the table model was being put in the Jtable. So here is the code from my Jpanel that initializes my Jtable

    //other GUI stuff above: buttons, labels, etc.
    Vector<String> tableColNames = new Vector<String>(1);
    Vector<String> tableRowNames = new Vector<String>(1); 
    Vector<Vector<String>> tableData = new Vector<Vector<String>>(1,1); //<row, col>

    for(int i = 0; i <50; i++){
        tableData.insertElementAt(new Vector<String>(), i);
        for(int b = 0; b<5; b++){
            tableData.elementAt(i).insertElementAt("TestData", b);
        }
        tableRowNames.insertElementAt("TestRowNames", i);
    }

    for(int a = 0; a<5; a++){
        tableColNames.insertElementAt("TestColNames", a);
    }

    System.out.println(tableData.toString());


    table = new JTable(new SemesterTableModel(tableColNames, tableRowNames, tableData));
    table.getColumnModel().getColumn(0).setCellRenderer(new JRowHeader());//Makeshift "rowHeader"
    table.setRowHeight(30);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    table.setBackground(Color.LIGHT_GRAY);



    JScrollPane scrollPane = new JScrollPane(table);
    //scrollPane.setBackground(Color.BLUE);
    springLayout.putConstraint(SpringLayout.WEST, scrollPane, 180, SpringLayout.WEST, this);
    springLayout.putConstraint(SpringLayout.NORTH, lblCumGPA, 30, SpringLayout.NORTH, scrollPane);
    springLayout.putConstraint(SpringLayout.EAST, comboBoxSemester, -15, SpringLayout.WEST, scrollPane);
    springLayout.putConstraint(SpringLayout.EAST, lblCumGPA, -15, SpringLayout.WEST, scrollPane);
    springLayout.putConstraint(SpringLayout.EAST, lblSemGPA, -15, SpringLayout.WEST, scrollPane);
    springLayout.putConstraint(SpringLayout.SOUTH, btnRemoveSemester, 0, SpringLayout.SOUTH, scrollPane);
    springLayout.putConstraint(SpringLayout.EAST, scrollPane, -15, SpringLayout.EAST, this);
    springLayout.putConstraint(SpringLayout.NORTH, scrollPane, 15, SpringLayout.NORTH, this);
    springLayout.putConstraint(SpringLayout.SOUTH, scrollPane, -15, SpringLayout.SOUTH, this);

    add(scrollPane);

    table.setFillsViewportHeight(true);

So here you see I initialize my Jtable with my SemesterTableModel and pass my 3 vectors as the parameters for my SemesterTableModel. That then passes in the below:

public class SemesterTableModel extends AbstractTableModel {

private Vector<String> colNames, rowNames;
private Vector<Vector<String>> data;

public SemesterTableModel() {
    colNames = new Vector<String>(1);
    rowNames = new Vector<String>(1);
    data = new Vector<Vector<String>>(1,1);
}

public SemesterTableModel(Vector<String> colNames, Vector<String> rowNames, Vector<Vector<String>> data){
    this.colNames = colNames;
    this.rowNames = rowNames;
    this.data = data;
}

@Override
public int getColumnCount() {
    return colNames.size();
}

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

@Override
public Object getValueAt(int col, int row) {
    if(col == 0)
        return rowNames.elementAt(row);
    else if(col >=5 || row >=5) //This is the code I added to figure out where my data was going, before I added this else if statement I was getting the array-index out of bounds errors
        return "Out of Bounds";
    else
        return data.elementAt(row).elementAt(col);
}

@Override
public boolean isCellEditable(int row, int col){
    if(col == 0 || row < 5){ //5 is an arbitrary number, I really want this to be an arbitrary variable that will be dependent on another class I haven't finished yet.
        return false;
    }
    return true;
}

}

So right now when I run my program my table looks like this.

在此处输入图片说明

Naturally I want "TestData" to fall inbetween the "row Headers" and the column Headers, "TestRowNames"to be in the first Column only, and then I also have "TestColNames" that don't even show up (though if I remember correctly I would need change the Column Header via the Jtable itself and not the TableModel).

Obviously I am not understanding something here and I have been banging my head against the keyboard for a while now trying to figure this out. If you guys know what's up or have any suggestions I am all ears.

TableModel#getValueAt should be int row, int col not int col, int row ...

public Object getValueAt(int row, int col) {

You'll have to remove the "out of bounds" check to make it work fully...because there are more then 5 rows

Take a closer look at How to Use Scroll Panes to see how you might be able to implement your own row header without needing to fake it...

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