I am trying to delete a row from a JTable whenever the button on the last column is pressed. I know to do this, I can use the removeRow(int) method of the tableModel. But the odd thing is when I try to get a handle to the TableModel from the JTable to use that function, i.e. table.getModel().removeRow(int) it doesn't work. But if I explicitly pass in the tableModel into my class it does work. Here's the code below:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.UIManager;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.AbstractCellEditor;
import javax.swing.table.DefaultTableModel;
public class tester4 extends JFrame
{
protected final int BUTTON_COL = 2;
private TableCellRenderer defaultRenderer;
private TableCellEditor defaultEditor;
private JTable workingTable;
private String[] transactionCols = {"Qty", "Product", "Cancel"};
private Object[][] data = {{5, "prod1", "Cancel"},
{6, "prod2", "Cancel"},
{7, "prod3", "Cancel"}};
public tester4()
{
workingTable = new JTable(tableModel);
workingTable.setName("Working Table");
defaultRenderer = workingTable.getDefaultRenderer(JButton.class);
defaultEditor = workingTable.getDefaultEditor(Object.class);
StatusTableRenderer testRenderer = new StatusTableRenderer(defaultRenderer, defaultEditor, workingTable, tableModel);
workingTable.setDefaultRenderer(Object.class, testRenderer);
workingTable.setDefaultEditor(Object.class, testRenderer);
JScrollPane scrollPane = new JScrollPane( workingTable );
getContentPane().add( scrollPane );
}
private DefaultTableModel tableModel = new DefaultTableModel(data, transactionCols){
// Only allow button column to be editable, if there is an actual
// button in that row
public boolean isCellEditable(int row, int col){
return (col == BUTTON_COL && data[row][col] != "") ? true : false;
}
// Overriden getColumnClass method that will return the object
// class type of the first instance of the data type otherwise
// returns the Object.class
public Class getColumnClass(int column){
for (int row = 0; row < getRowCount(); row++){
Object o = getValueAt(row, column);
if (o != null){ return o.getClass(); }
}
return Object.class;
}
};
public static void main(String[] args)
{
tester4 frame = new tester4();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
}
public class StatusTableRenderer extends AbstractCellEditor
implements TableCellRenderer,
TableCellEditor,
ActionListener{
private TableCellRenderer defaultRenderer;
private TableCellEditor defaultEditor;
private JButton cancelButton;
private JButton editButton;
private String text;
private int buttonColumn;
private int selectedRow;
private JTable table;
private DefaultTableModel tableModel;
public StatusTableRenderer(TableCellRenderer renderer,
TableCellEditor editor,
JTable table,
DefaultTableModel tableModel){
defaultRenderer = renderer;
defaultEditor = editor;
this.table = table;
this.tableModel = tableModel;
buttonColumn = table.getColumnCount() - 1;
cancelButton = new JButton();
editButton = new JButton();
editButton.setFocusPainted(true);
editButton.addActionListener(this);
}
public StatusTableRenderer(TableCellRenderer renderer,
TableCellEditor editor,
JTable table,
DefaultTableModel tableModel,
int _buttonColumn){
this(renderer, editor, table, tableModel);
buttonColumn = _buttonColumn;
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (column == buttonColumn){
if (hasFocus){
cancelButton.setForeground(table.getForeground());
cancelButton.setBackground(UIManager.getColor("Button.background"));
}
else if (isSelected){
cancelButton.setForeground(table.getSelectionForeground());
cancelButton.setBackground(table.getSelectionBackground());
}
else{
cancelButton.setForeground(table.getForeground());
cancelButton.setBackground(UIManager.getColor("Button.background"));
}
cancelButton.setText( (value == null) ? "" : value.toString() );
return cancelButton;
}
return defaultRenderer.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column){
if (column == buttonColumn){
text = ((value == null) ? "": value.toString());
editButton.setText(text);
selectedRow = row;
return editButton;
}
return defaultEditor.getTableCellEditorComponent(
table, value, isSelected, row, column);
}
public Object getCellEditorValue()
{
return text;
}
public void actionPerformed(ActionEvent e)
{
fireEditingStopped();
// This works
tableModel.removeRow(selectedRow);
// This does not work
// table.getModel().removeRow(selectedRow);
}
}
}
Take a look at the actionPerfformed method. One way of doing it works, one doesn't. Just trying to understand why me getting a handle to the tableModel through the table doesn't work.
Message was edited by:
deadseasquirrels