JTables + Multiple Arrays
This has really been bugging me for the last couple of days. I'm trying to develop an application where the user will be able to choose from a dropdown menu (a JMenuBar I guess) from a set of different data. Whatever the user selects, the JTable is populated with the needed data. IE: they click on "fruits" and they get a table of fruits and info; if they click on "cars", they get a listing of cars.
Currently, I have it set up so that one applet contains one set of data in an array and everything, and to view another set of data they need to load another applet... kinda unuseful I think. Basically, all of the values in my arrays are constants... and I have no idea how to load another array to populate the JTable. I've tried everything I can think of but it just doesn't work. :/ Thanks for any help or pointers you guys can give! :)
How are you loading your "constants" into the arrays at the moment?It would be useful if you could post your code (in [ code ] ) tags to indicate what you've tried.
Step 1. Create your own table model, based on [url=http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/table/AbstractTableModel.html]AbstractTableModel[/url]. This takes care of implementing the majority of methods of the [url=http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/table/TableModel.html]TableModel interface[/url] that you don't care about. If you need to, you can override them. That will leave you with only 3 methods to implement:int getRowCount()
int getColumnCount()
Object getValueAt(int rowIndex, int columnIndex)
you do not have to overridevoid setValueAt(Object aValue, int rowIndex, int columnIndex)
Step 2. Add to your model the ability to determine which of the two arrays you want to represent; I would simply have an underlyingData array variable that is settable from outside the model. Then you could switch back and forth between any number of array data sources without copying any data at all (except the array references themselves)
Step 3. Implement the three methods I showed you to return data from and information about your underlyingData array in whatever format is appropriate for the array and table. The possibilities are limitless. You could, for example return "Bogus Data" for any row in column 4 (even if your array doesn't have a column 4). Then column 4 in your table would have a bunch of cells saying "Bogus Data". You could return for any row in column 5 the sum of the data in the same row for columns 3 and 4. The data doesn't actually have to "exist". What is important is that you are "representing" the data with your model.
Step 4. Use [url=http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#setModel(javax.swing.table.TableModel)]setModel(yourTableModel)[/url] in your table to set the table model to your model.
And that's all there is to it.
One additional thing; whenever you do your switch, you should notify the hosting table by doing the following:fireTableDataChanged();
fireTableStructureChanged();
Message was edited by:
CliffsNotes
Message was edited by:
CliffsNotes
*forgot semicolons...*
Basically, this is what I have to initialize the arrays:
//column names for the jtable
private String[] columnNames = {"Number", "Item", "Price", "Other"};
//array to populate jtable
private Object[][] objectsArray = {
{new Integer(1),"First Thing", new Double(10), ""},
{new Integer(2), "Second Thing",new Double(25.50), ""},
{new Integer(3), "Third thing", new Double(17), ""}
};
Of course, this is just a test array I made up to get this thing working.
@Cliffs: what do you mean by an underlyingData array? I currently have a custom table model and custom cell renderer set up for displaying the table how I need to (of course, without the multiple array thing), but you lost me on that part. :P Thanks for the help!
Message was edited by:
mistah-java
Message was edited by:
mistah-java
> @Cliffs: what do you mean by an underlyingData array?
I mean have a variable in your model (or maybe two, one for the column headings and one two-dimensional for the data) referring to the data represented and settable from outside the model so your applet can set and reset it (them) when a different item is selected in the dropdown. In your example, if columnNames and objectsArray were passed to the model, he could use them as the underlying data for the table.
> I currently have a custom table model and custom cell renderer set up for displaying the table how I need to (of course, without the multiple array thing), but you lost me on that part. :P Thanks for the help!
Perhaps you could show me your model code and I could give you more specific answers.
I think I understand what you're saying, but I'm not sure how to go about doing it. Here's my table model:
public class MyTableModel extends AbstractTableModel{
public final Object[] longValues = {new Integer(1), "Long Text",
new Double(100.00), "10000"};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return objectsArray.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
public void setValueAt(Object value, int row, int col) {
objectsArray[row][col] = value;
fireTableDataChanged();
fireTableCellUpdated(row, col);
}
public void tableChanged(TableModelEvent e) {
fireTableChanged(e);
}
public Object getValueAt(int row, int col) {
return objectsArray[row][col];
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
Would I have all of my arrays (both table headings and to populate the JTable) already initialized as class variables?
Message was edited by:
mistah-java : missed "/" in code tag
You have everthing you need; just add these things to your model:// Internal references for data
Object[] columnNames;
Object[][] objectsArray;
// Whoever manages the table should call this method
// whenever the underlying data array is to be replaced with a different array
public void setUnderlyingData(Object[] newColumnNames, Object[][]newObjectsArray)
{
columnNames = newColumnNames;
objectsArray = newObjectsArray;
fireTableStructureChanged(); // Notify table that the data may have changed radically
fireTableDataChanged(); // Notify table that the structure may have changed radically
}
For convenience, you might wish to add a constructor with similar parameters.
Note: It is not necesary to call fireTableDataChanged() in your setValueAt() method since you are already notifying the table of the specific change using fireTableCellUpdated() and your table has no dependent rows or columns (I say this because your getValueAt() method simply returns the array value at row/col).
That worked, thanks! It seems so simple now that I look at what you posted, I feel stupid for not figuring that out before. :P Thanks again!