Jtable Renderer dilemma when there is no data intially

So I have a dilemma, I would like to create set a TableCellRender for a JTable that I have so that it renders a button component on the last column. I have a functional product already, when there is data, but when there isn't data in the table by default then it won't render. I have included a small self-contained code snippet below. To make it disfunctional, uncomment the TableModel that I have commented out, so that instead of the tableModel constructor DefaultTableModel(Object[][] data, Object[] columnNames), it uses constructor DefaultTableModel(Vector columnNames, int rowCount)

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.*;

import javax.swing.table.*;

publicclass TableButton3extends JFrame

{

private String[] transactionCols ={"Qty","Product","Cancel"};

private Object[][] data ={{5,"prod1",new JButton("Cancel")},

{6,"prod2",new JButton("Cancel")},

{7,"prod3",new JButton("Cancel")}};

public TableButton3()

{

TableCellRenderer defaultRenderer;

JTable table =new JTable(tableModel);

defaultRenderer = table.getDefaultRenderer(JButton.class);

table.setDefaultRenderer(JButton.class,

new StatusTableRenderer(defaultRenderer));

JScrollPane scrollPane =new JScrollPane( table );

getContentPane().add( scrollPane );

}

// comment the next lines out to make it dysfunctional

private DefaultTableModel tableModel =new DefaultTableModel(data, transactionCols){

// and uncomment next lines to make it dysfunctional

//private DefaultTableModel tableModel = new //DefaultTableModel(transactionCols, 10)

publicboolean isCellEditable(int row,int col){returnfalse;}

public Class getColumnClass(int column)

{

return getValueAt(0, column).getClass();

}

};

publicstaticvoid main(String[] args)

{

TableButton3 frame =new TableButton3();

frame.setDefaultCloseOperation( EXIT_ON_CLOSE );

frame.pack();

frame.setVisible(true);

}

publicclass StatusTableRendererimplements TableCellRenderer{

private TableCellRenderer defaultRenderer;

public StatusTableRenderer(TableCellRenderer renderer){

defaultRenderer = renderer;

}

public Component getTableCellRendererComponent(JTable table, Object value,

boolean isSelected,boolean hasFocus,int row,int column){

if (valueinstanceof Component){

return (Component)value;

}

return defaultRenderer.getTableCellRendererComponent(

table, value, isSelected, hasFocus, row, column);

}

}

}

As you can see it'll die now in the getColumnClass area because getValueAt(0, column) = null, but how do I avoid this? I want a blank table with 10 rows by default, but I thought there should be a way to get a handle to the TableColumn and setDefaultRenderer or something. I know the third column is going to have JButtons, but it doesn't at this point.

[5723 byte] By [deadseasquirrelsa] at [2007-10-3 10:12:54]
# 1
Use DefaultTableModel with a dummy initialization data.
hiwaa at 2007-7-15 5:33:10 > top of Java-index,Desktop,Core GUI APIs...
# 2

a) hardcode the values:

switch (column)

{

case 2: return JButton.class;

default: return Object.class;

}

b) write smarter code (the first non-null value will determine the class of the column):

for (int row = 0; row < getRowCount(); row++)

{

Object o = getValueAt(row, column);

if (o != null)

{

return o.getClass();

}

}

return Object.class;

camickra at 2007-7-15 5:33:10 > top of Java-index,Desktop,Core GUI APIs...
# 3
ok, thanks. I'm starting to understand a little more, it seems like when you create you own renderers and/or editors and/or tableModels you really have to handhold the object. I guess I'm just not use to that much control.
deadseasquirrelsa at 2007-7-15 5:33:10 > top of Java-index,Desktop,Core GUI APIs...
# 4

Actually the default implementation of getColumnClass just return Object.class for all columns. Instead of overriding the getColumnClass method you can just assign a renderer for a specific column using:

table.getColumnModel().getColumn(2).setCellRenderer( ? );

My answer 'b' was taken from code that loads data from a database into a table. Using that code the renderers will dynamically be assigned based on the data retrieved from the database.

If you want to hardcode a renderer to a column then the solution I just gave you is probably easier.

camickra at 2007-7-15 5:33:10 > top of Java-index,Desktop,Core GUI APIs...
# 5
Thanks for the tip, I was tring to set a renderer specifically for a column but was using table.getColumn() which doesn't allow for a column index parameter. I guess I should have been looking at the tableModel's getColumn.
deadseasquirrelsa at 2007-7-15 5:33:10 > top of Java-index,Desktop,Core GUI APIs...