Recently I wanted to have a clickable button in a table. Searching on Google for JButton in JTable I found a couple of suggestions, most notably this DevX article and this Esus article. There was also a StackOverflow question that just referenced other solutions. None really satisfied me. So borrowing their ideas I created my own solution.
Fundamentally, there are two problems with having a JButton in a JTable. Firstly, by default a JTable will display cell values as a String, so JButtons appear as “javax.swing.JButton”. Secondly, a JTable does not pass clicks through to the cells.
To display the buttons correctly a custom cell renderer needs to be applied to any columns displaying JButtons. This can be done with the code table.getColumn(“Button1”).setCellRenderer(new JTableButtonRenderer()) (this assumes that there is a column in the table labelled “Button1”. The button renderer is below. The default renderer always returns a JLabel, but this one returns a JButton after colouring it in an appropriate manner. Note, this renderer assumes the contents of column will always be a JButton and will throw an exception if this is not the case. If the table column may not contain JButtons, just extend DefaultTableCellRenderer, detect if the value is a JButton (or even a Swing component) with instanceof, otherwise call super. This Sun article may help with this.
To get the table to pass clicks through to the button, add a mouse listener to the table with table.addMouseListener(new JTableButtonMouseListener(table)). This mouse listener (example below) will have to take the click, work out in which cell it occurred and if that cell contains a JButton, click it.
And with that, the buttons in your table should start to work. All you need to do is return the buttons (which perform the required actions) when requested from your model, using getValueAt(). A complete working example is below.