I
IchBin
To use the TableSorter class from Sun, referenced in the JTable tutorial
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html. I
have to create a MyTableModel that houses and manipulates the Table
data. The code they have can not really work in a real world
application. That is, hard coded model data and columns. This is not
practical. What I have done, is working as designed. (Attached below)
The pattern that Sun uses for the TableSorter and MyTableModel classes
is the decorator pattern. I have to fold MyTableModel into the
TableSorter class and then set the TableSorter as the JTable model. Code
wise it is done this this way:
TableSorter sorter = new TableSorter(new MyTableModel());
JTable table = new JTable(sorter);
sorter.setTableHeader(table.getTableHeader());
So in TableSorter there is a constructor defined to house the passed
MyTableModel:
public TableSorter(TableModel tableModel) {
this();
setTableModel(tableModel);
}
OK, MyTableModel works as designed. I have no problem at all with
loading data, Sorting..etc. All works the way it should. The problem I
am having is that when I have to reference the MyTableModel thru the
JTable owner I am not seeing it. Say I have to get the
table.getRowCount(), table.getColumnModel(), table.getColumnCount() or
attached any renders. And if I do table.getModel() I am not getting the
MyTableModel that has the data. The TableSorter HAS the reference to
MyTableModel else no sorting would work but it does.
Hope my question is understandable. It's like I can not reference the
MyTableModel that is in TableSorter set as the model for the JTable
owner.. MyTableModel and TableSorter both extend AbstractTableModel.
public class MyTableModel extends AbstractTableModel
{
/**
* Debugging switch for problem determination
*/
private boolean DEBUG = false;
/**
* Define as string Object and not Vector to maintain Columns
*/
private String[] columnNames;
// private String[] columnNames = {"Index","Entry
Name","URL","Results","Coment"};
/**
* Define as new with one element to eliminate error
* on intial reference from TableSorter
*/
private Object[][] data = new Object[0][0];
/**
* Default Class constructor on intial refference from TableSorter
*/
public JBookMarksTableModel() {
}
/**
* Added a constructor to load in data column names.
*
* @param data row data to add to row model
* @param columnNames columms with colummns names to add to model
*/
protected JBookMarksTableModel(Object[][] data, String[] columnNames) {
//
// Copy all Columns data to instance Columns
addColumn(columnNames);
//
// Redefine the instance row size
this.data = new Object[data.length][data[0].length];
//
// Copy all row data to instance row data
copyObjects(data, this.data);
}
/**
* Added a constructor to load in data column names.
*
* @param data row data to add to row model
* @param columnNames columms with colummns names to add to model
*/
protected void addDataObject(Object[][] data) {
//
// Redefine the instance row size
this.data = new Object[data.length][data[0].length];
//
// Copy all row data to instance row data
copyObjects(data, this.data);
}
/**
* Delete all data.
*/
protected void deleteDataObject() {
//
// Redefine the instance row size to zero
this.data = new Object[0][0];
}
/**
* Non-Standard Added this method to return the all the Models data
* @return data[][]
*/
protected Object[][] getTableData(){
return data;
}
/**
* @see javax.swing.table.TableModel#getColumnCount()
*/
public int getColumnCount() {
return columnNames.length;
}
/**
* @see javax.swing.table.TableModel#getRowCount()
*/
public int getRowCount() {
return data.length;
}
/**
* Added Method to add Columns[]. There is no equivwent method
* in Sun's table models.
* It overrides addColumn(String columnName)
* (Mine only works for seq column adds)
*
* @param columnNames All Table Column names
*/
protected void addColumn(String[] columnNames) {
//
// Copy all Columns data to instance Columns
this.columnNames = new String[columnNames.length];
this.columnNames = columnNames;
}
/**
* I added Method to add Columns
* DefaultTableModel uses a addColumn(int column, String[] column)
* (Mine only works for seq column adds)
*
* @param columnName Column name
*/
protected void addColumn(String columnName) {
if (columnNames == null) {
//
// First time
this.columnNames = new String[1];
this.columnNames[0] = columnName;
} else {
// Create temp Object to hold current columns data plus one new
// empty element
Object temp[] = new Object[columnNames.length + 1];
//
// Copy all current Column data to temp
System.arraycopy(columnNames, 0, temp, 0, columnNames.length);
//
// Added the new column name to the temp Object
temp[temp.length - 1] = columnName;
//
// Rebuild the Instance Column object with all of the new data
this.columnNames = new String[temp.length];
System.arraycopy(temp, 0, columnNames, 0, columnNames.length);
}
}
/**
* Overrides javax.swing.table.AbstractTableModel.getColumnName(int)
* @see javax.swing.table.AbstractTableModel#getColumnName(int)
*/
public String getColumnName(int col) {
return columnNames[col];
}
/**
* @see javax.swing.table.TableModel#getValueAt(int, int)
*/
public Object getValueAt(int row, int col) {
return data[row][col];
}
/**
* JTable uses this method to determine the default renderer/
editor for
* each cell. If we didn't implement this method, then the last
column would
* contain text ("true"/"false"), rather than a check box.
*
* @see javax.swing.table.AbstractTableModel#getColumnClass(int)
*/
public Class getColumnClass(int c) {
Class value = null;
try {
value = getValueAt(0, c).getClass();
} catch (Exception e) {
// TODO: handle exception
}
return value;
}
/**
* Don't need to implement this method unless your table's editable.
*
* @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
*/
public boolean isCellEditable(int row, int col) {
// Note that the data/cell address is constant,
// no matter where the cell appears onscreen.
if (col < 2) {
return false;
}
return true;
}
/**
* Don't need to implement this method unless your table's data can
change.
* Overrides javax.swing.table.AbstractTableModel.setValueAt(Object
value, int row, int col)
* @see
javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object, int, int)
*/
public void setValueAt(Object value, int row, int col) {
if (DEBUG){
out.println("Setting value at " + row + "," + col + " to "
+ value + " (an instance of " + value.getClass() +
")");
}
data[row][col] = value;
fireTableCellUpdated(row, col);
if (DEBUG) printDebugData(this.data);
}
/**
* I added Methods to add row data conforms to DefaultTableModel.
* DefaultTableModel uses a addRow(int row, Object[] data)
* (I only append the row data)
*
* @param data a one dimension row element
*/
protected void addRow(Object[] data) {
if (this.data == null) {
this.data = new Object[1][data.length];
//
// loop and add the new first data row elements
for (int j = 0; j < data.length; j++) {
this.data[0][j] = data[j];
}
} else {
//
// Create temp Object to hold current columns data plus one new
// empty element
Object temp[][] = new Object[this.data.length +
1][data.length];
//
// Copy all current Column data to temp
copyObjects(this.data, temp);
//
// Add the new column data elements
for (int outer = 0; outer < data.length; outer++){
temp[temp.length - 1][outer] = data[outer];
}
//
// Rebuild the Instance data object with all of the new data
this.data = new Object[temp.length][data.length];
copyObjects(temp, this.data);
//
// Display the data if un debug mode
if (DEBUG) printDebugData(this.data);
//
// Update the JTable display with new data
fireTableDataChanged();
}
}
/**
* I added this Method as a helper to manage the data[][] expansion
*
* @param fromdata the data[]][] object to copy from
* @param todata the data[]][] object build target
*
* @return Object[][] return the build data[][] object
*/
protected Object[][] copyObjects(Object[][] fromdata, Object[][]
todata) {
for (int outer = 0; outer < fromdata.length; outer++) {
for (int inner = 0; inner < fromdata[outer].length; inner++){
todata[outer][inner] = fromdata[outer][inner];
}
}
return todata;
}
private void printDebugData(Object[][] data) {
int numRows = data.length;
int numCols = data[0].length;
out.println();
for (int i = 0; i < numRows; i++) {
out.print(" row " + i + ":");
for (int j = 0; j < numCols; j++) {
out.print(" " + data[j]);
}
out.println();
}
}
}
--
Thanks in Advance...
IchBin, Pocono Lake, Pa, USA
http://weconsultants.servebeer.com/JHackerAppManager
__________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"'
-William E. Taylor, Regular Guy (1952-)
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html. I
have to create a MyTableModel that houses and manipulates the Table
data. The code they have can not really work in a real world
application. That is, hard coded model data and columns. This is not
practical. What I have done, is working as designed. (Attached below)
The pattern that Sun uses for the TableSorter and MyTableModel classes
is the decorator pattern. I have to fold MyTableModel into the
TableSorter class and then set the TableSorter as the JTable model. Code
wise it is done this this way:
TableSorter sorter = new TableSorter(new MyTableModel());
JTable table = new JTable(sorter);
sorter.setTableHeader(table.getTableHeader());
So in TableSorter there is a constructor defined to house the passed
MyTableModel:
public TableSorter(TableModel tableModel) {
this();
setTableModel(tableModel);
}
OK, MyTableModel works as designed. I have no problem at all with
loading data, Sorting..etc. All works the way it should. The problem I
am having is that when I have to reference the MyTableModel thru the
JTable owner I am not seeing it. Say I have to get the
table.getRowCount(), table.getColumnModel(), table.getColumnCount() or
attached any renders. And if I do table.getModel() I am not getting the
MyTableModel that has the data. The TableSorter HAS the reference to
MyTableModel else no sorting would work but it does.
Hope my question is understandable. It's like I can not reference the
MyTableModel that is in TableSorter set as the model for the JTable
owner.. MyTableModel and TableSorter both extend AbstractTableModel.
public class MyTableModel extends AbstractTableModel
{
/**
* Debugging switch for problem determination
*/
private boolean DEBUG = false;
/**
* Define as string Object and not Vector to maintain Columns
*/
private String[] columnNames;
// private String[] columnNames = {"Index","Entry
Name","URL","Results","Coment"};
/**
* Define as new with one element to eliminate error
* on intial reference from TableSorter
*/
private Object[][] data = new Object[0][0];
/**
* Default Class constructor on intial refference from TableSorter
*/
public JBookMarksTableModel() {
}
/**
* Added a constructor to load in data column names.
*
* @param data row data to add to row model
* @param columnNames columms with colummns names to add to model
*/
protected JBookMarksTableModel(Object[][] data, String[] columnNames) {
//
// Copy all Columns data to instance Columns
addColumn(columnNames);
//
// Redefine the instance row size
this.data = new Object[data.length][data[0].length];
//
// Copy all row data to instance row data
copyObjects(data, this.data);
}
/**
* Added a constructor to load in data column names.
*
* @param data row data to add to row model
* @param columnNames columms with colummns names to add to model
*/
protected void addDataObject(Object[][] data) {
//
// Redefine the instance row size
this.data = new Object[data.length][data[0].length];
//
// Copy all row data to instance row data
copyObjects(data, this.data);
}
/**
* Delete all data.
*/
protected void deleteDataObject() {
//
// Redefine the instance row size to zero
this.data = new Object[0][0];
}
/**
* Non-Standard Added this method to return the all the Models data
* @return data[][]
*/
protected Object[][] getTableData(){
return data;
}
/**
* @see javax.swing.table.TableModel#getColumnCount()
*/
public int getColumnCount() {
return columnNames.length;
}
/**
* @see javax.swing.table.TableModel#getRowCount()
*/
public int getRowCount() {
return data.length;
}
/**
* Added Method to add Columns[]. There is no equivwent method
* in Sun's table models.
* It overrides addColumn(String columnName)
* (Mine only works for seq column adds)
*
* @param columnNames All Table Column names
*/
protected void addColumn(String[] columnNames) {
//
// Copy all Columns data to instance Columns
this.columnNames = new String[columnNames.length];
this.columnNames = columnNames;
}
/**
* I added Method to add Columns
* DefaultTableModel uses a addColumn(int column, String[] column)
* (Mine only works for seq column adds)
*
* @param columnName Column name
*/
protected void addColumn(String columnName) {
if (columnNames == null) {
//
// First time
this.columnNames = new String[1];
this.columnNames[0] = columnName;
} else {
// Create temp Object to hold current columns data plus one new
// empty element
Object temp[] = new Object[columnNames.length + 1];
//
// Copy all current Column data to temp
System.arraycopy(columnNames, 0, temp, 0, columnNames.length);
//
// Added the new column name to the temp Object
temp[temp.length - 1] = columnName;
//
// Rebuild the Instance Column object with all of the new data
this.columnNames = new String[temp.length];
System.arraycopy(temp, 0, columnNames, 0, columnNames.length);
}
}
/**
* Overrides javax.swing.table.AbstractTableModel.getColumnName(int)
* @see javax.swing.table.AbstractTableModel#getColumnName(int)
*/
public String getColumnName(int col) {
return columnNames[col];
}
/**
* @see javax.swing.table.TableModel#getValueAt(int, int)
*/
public Object getValueAt(int row, int col) {
return data[row][col];
}
/**
* JTable uses this method to determine the default renderer/
editor for
* each cell. If we didn't implement this method, then the last
column would
* contain text ("true"/"false"), rather than a check box.
*
* @see javax.swing.table.AbstractTableModel#getColumnClass(int)
*/
public Class getColumnClass(int c) {
Class value = null;
try {
value = getValueAt(0, c).getClass();
} catch (Exception e) {
// TODO: handle exception
}
return value;
}
/**
* Don't need to implement this method unless your table's editable.
*
* @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
*/
public boolean isCellEditable(int row, int col) {
// Note that the data/cell address is constant,
// no matter where the cell appears onscreen.
if (col < 2) {
return false;
}
return true;
}
/**
* Don't need to implement this method unless your table's data can
change.
* Overrides javax.swing.table.AbstractTableModel.setValueAt(Object
value, int row, int col)
* @see
javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object, int, int)
*/
public void setValueAt(Object value, int row, int col) {
if (DEBUG){
out.println("Setting value at " + row + "," + col + " to "
+ value + " (an instance of " + value.getClass() +
")");
}
data[row][col] = value;
fireTableCellUpdated(row, col);
if (DEBUG) printDebugData(this.data);
}
/**
* I added Methods to add row data conforms to DefaultTableModel.
* DefaultTableModel uses a addRow(int row, Object[] data)
* (I only append the row data)
*
* @param data a one dimension row element
*/
protected void addRow(Object[] data) {
if (this.data == null) {
this.data = new Object[1][data.length];
//
// loop and add the new first data row elements
for (int j = 0; j < data.length; j++) {
this.data[0][j] = data[j];
}
} else {
//
// Create temp Object to hold current columns data plus one new
// empty element
Object temp[][] = new Object[this.data.length +
1][data.length];
//
// Copy all current Column data to temp
copyObjects(this.data, temp);
//
// Add the new column data elements
for (int outer = 0; outer < data.length; outer++){
temp[temp.length - 1][outer] = data[outer];
}
//
// Rebuild the Instance data object with all of the new data
this.data = new Object[temp.length][data.length];
copyObjects(temp, this.data);
//
// Display the data if un debug mode
if (DEBUG) printDebugData(this.data);
//
// Update the JTable display with new data
fireTableDataChanged();
}
}
/**
* I added this Method as a helper to manage the data[][] expansion
*
* @param fromdata the data[]][] object to copy from
* @param todata the data[]][] object build target
*
* @return Object[][] return the build data[][] object
*/
protected Object[][] copyObjects(Object[][] fromdata, Object[][]
todata) {
for (int outer = 0; outer < fromdata.length; outer++) {
for (int inner = 0; inner < fromdata[outer].length; inner++){
todata[outer][inner] = fromdata[outer][inner];
}
}
return todata;
}
private void printDebugData(Object[][] data) {
int numRows = data.length;
int numCols = data[0].length;
out.println();
for (int i = 0; i < numRows; i++) {
out.print(" row " + i + ":");
for (int j = 0; j < numCols; j++) {
out.print(" " + data[j]);
}
out.println();
}
}
}
--
Thanks in Advance...
IchBin, Pocono Lake, Pa, USA
http://weconsultants.servebeer.com/JHackerAppManager
__________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"'
-William E. Taylor, Regular Guy (1952-)