Hey,
I've got a problem with a JTable I'm implementing. The MouseListener just isn't registering any clicks. The constructor is being called fine but clicking on a row doesn't do anything.
Here's the code for the MouseListener.
public class TableListener implements MouseListener {
private JTable table;
// Column from the data model to process mouse events on
private int column;
// The table row when the mouse was pressed
private int row;
// The table column when the mouse was pressed
private int tableColumn;
// Repaint the button on mouse released event
private boolean paintOnRelease;
public TableListener ( JTable table, int column ) {
this.table = table;
this.column = column;
}
/*
* Repaint button to show pressed state
*/
public void mousePressed ( MouseEvent e ) {
// Make sure the MouseEvent was on the button column
if ( !buttonColumn(e) ) return;
// Repaint the button for the current row/column
Point point = e.getPoint();
row = table.rowAtPoint( point );
tableColumn = table.columnAtPoint( point );
if ( row == -1 ) {
return;
}
Object o = table.getValueAt(row, tableColumn);
if ( o instanceof JButton ) {
paintButton( true );
paintOnRelease = true ;
}
}
/*
* Do table processing on this event
*/
public void mouseClicked ( MouseEvent e ) {
System.out.println("Test");
if ( e.getClickCount() == 2 && !buttonColumn(e)) {
JTable target = (JTable)e.getSource();
int row = target.getSelectedRow();
int column = target.getSelectedColumn();
// do some action
}
// Make sure the MouseEvent was on the button column
if ( !buttonColumn(e) ) return;
// Only process a single click
if ( e.getClickCount() > 1 ) return;
// Row has been deleted, nothing to repaint
paintOnRelease = false;
}
public void mouseEntered ( MouseEvent e ) {
return;
}
public void mouseExited ( MouseEvent e ) {
return;
}
/*
* Repaint button to show normal state
*/
public void mouseReleased ( MouseEvent e ) {
if ( paintOnRelease ) {
paintButton( false );
}
paintOnRelease = false;
}
private boolean buttonColumn ( MouseEvent e ) {
// In case columns have been reordered, we must map the
// table column to the data model column
int tableColumn = table.columnAtPoint( e.getPoint() );
int modelColumn = table.convertColumnIndexToModel(tableColumn);
return modelColumn == column;
}
private void paintButton ( boolean pressed ) {
// Make sure we have a JButton before repainting
Object o = table.getValueAt(row, tableColumn);
if ( o instanceof JButton ) {
JButton button = (JButton)o;
button.getModel().setPressed( pressed );
button.getModel().setArmed( pressed );
table.setValueAt(button, row, tableColumn);
}
}
}
This is the code for the actual Table
public class Table extends JTable {
private Set<Row> rows = new TreeSet<Row>(new RowComparator());
private Color AlternateColor = new Color(237, 243, 254);
private Color MarkedColor = UIManager.getColor("Table.selectionBackground");
public Table ( Object[][] data, Object[] columnNames ){
super(data, columnNames);
}
/*
* Paints empty rows too, after letting the UI delegate do its painting.
*/
public void paint ( Graphics g ) {
super.paint(g);
paintEmptyRows(g);
}
/*
* Paints the backgrounds of the implied empty rows when the table model is
* insufficient to fill all the visible area available to us. We don't involve
* cell renderers, because we have no data.
*/
protected void paintEmptyRows ( Graphics g ) {
final int rowCount = getRowCount();
final Rectangle clip = g.getClipBounds();
double height = clip.y + clip.height;
if ( rowCount * rowHeight < height ) {
for ( int i = rowCount; i <= height / rowHeight; ++i ) {
g.setColor(colorForRow(i));
g.fillRect(clip.x, i * rowHeight, clip.width, rowHeight);
}
}
}
/*
* Returns the appropriate background color for the given row.
*/
protected Color colorForRow ( int row ) {
return (row % 2 == 0) ? AlternateColor : getBackground();
}
/*
* Shades alternate rows in different colors.
*/
public Component prepareRenderer ( TableCellRenderer renderer, int row, int column ) {
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent) c;
if ( !c.getBackground().equals(MarkedColor) ) {
if ( isCellSelected(row, column) == false ) {
c.setBackground(colorForRow(row));
c.setForeground(UIManager.getColor("Table.foreground"));
} else {
c.setBackground(UIManager.getColor("Table.selectionBackground"));
c.setForeground(UIManager.getColor("Table.selectionForeground"));
}
}
return c;
}
public Color getAlternateColor() {
return AlternateColor;
}
public Color getMarkedColor() {
return MarkedColor;
}
public boolean isCellEditable ( int row, int column ) {
return false;
}
public TableCellRenderer getCellRenderer ( int row, int column ) {
TableColumn tableColumn = getColumnModel().getColumn(column);
TableCellRenderer renderer = tableColumn.getCellRenderer();
if ( renderer == null ) {
Class c = getColumnClass(column);
if ( c.equals(Object.class) ) {
Object o = getValueAt(row,column);
if ( o != null )
c = getValueAt(row,column).getClass();
}
renderer = getDefaultRenderer(c);
}
return renderer;
}
public TableCellEditor getCellEditor (int row, int column) {
TableColumn tableColumn = getColumnModel().getColumn(column);
TableCellEditor editor = tableColumn.getCellEditor();
if ( editor == null ) {
Class c = getColumnClass(column);
if ( c.equals(Object.class) ) {
Object o = getValueAt(row,column);
if ( o != null )
c = getValueAt(row,column).getClass();
}
editor = getDefaultEditor(c);
}
return editor;
}
}
And this is the code that actually creates the table (the data gets added later):
Table resultsTable = new Table(results, resultsHeader);
resultsTable.setDefaultRenderer( JComponent.class, new TableRenderer() );
resultsTable.setDefaultEditor( JComponent.class, new TableEditor() );
resultsTable.addMouseListener( new TableListener(resultsTable, 4) );
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(resultsTable.getModel());
resultsTable.setRowSorter(sorter);