27

I have made one swing GUI which have JTable with some rows and Columns.How should I add a button to row in a JTable ?

kleopatra
  • 51,061
  • 28
  • 99
  • 211
om.
  • 4,159
  • 11
  • 37
  • 36

3 Answers3

37

You don't add it to a row - you add it to the cell. This tutorial describes what you need.

Nightfirecat
  • 11,432
  • 6
  • 35
  • 51
Bostone
  • 36,858
  • 39
  • 167
  • 227
  • 2
    waw! I just opened that example and realized that the source code added a "new JCheckbox" to the CellEditor. But actually it rendered as JButton. Anyway, my question is, why should we put JCheckBox into it? :( – gumuruh Jan 10 '12 at 09:48
  • 2
    @Bostone - How can I send the data in a different cell as parameter to the a function triggered by the button? --- The example only shows the cell's own data being used, so I'm kinda lost. – CosmicGiant Jan 23 '13 at 20:24
  • 1
    This doesn't seem to display the button click animation for me. – Thomas Ahle Aug 19 '14 at 15:19
  • @ThomasAhle i'm also facing the some problem. got any solution? – Hritik R Apr 15 '21 at 07:13
21

You can add Component as a table cell.

First of all, you should implement a class that has JButton as its parent class and two interfaces: TableCellRenderer and TableCellEditor.

The reason that it should implement TableCellEditor is for receiving button's ActionEvent.

    public class TableButton extends JButton implements TableCellRenderer, TableCellEditor {
      private int selectedRow;
      private int selectedColumn;
      Vector<TableButtonListener> listener;
    
      public TableButton(String text) {
        super(text); 
        listener = new Vector<TableButtonListener>();
        addActionListener(new ActionListener() { 
          public void actionPerformed( ActionEvent e ) { 
            for(TableButtonListener l : listener) { 
              l.tableButtonClicked(selectedRow, selectedColumn);
            }
          }
        });
      }
     
      public void addTableButtonListener( TableButtonListener l ) {
        listener.add(l);
      }
    
      public void removeTableButtonListener( TableButtonListener l ) { 
        listener.remove(l);
      }
    
      @Override 
      public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row, int col) {
        return this;
      }
    
      @Override
      public Component getTableCellEditorComponent(JTable table,
          Object value, boolean isSelected, int row, int col) {
        selectedRow = row;
        selectedColumn = col;
        return this;
      } 
    
      @Override
      public void addCellEditorListener(CellEditorListener arg0) {      
      } 
    
      @Override
      public void cancelCellEditing() {
      } 
    
      @Override
      public Object getCellEditorValue() {
        return "";
      }
    
      @Override
      public boolean isCellEditable(EventObject arg0) {
        return true;
      }
    
      @Override
      public void removeCellEditorListener(CellEditorListener arg0) {
      }
    
      @Override
      public boolean shouldSelectCell(EventObject arg0) {
        return true;
      }
    
      @Override
      public boolean stopCellEditing() {
        return true;
      }
    }

Then I added an EventListener named TableButtonListener` for handling button event as follows.

    public interface TableButtonListener extends EventListener {
      public void tableButtonClicked( int row, int col );
    }

And use above Renderer/Editor.

    TableButton buttonEditor = new TableButton("Button");
    buttonEditor.addButtonListener(new TableButtonListener() {
      @Override
      public void tableButtonClicked(int row, int col) {
        // do something 
      }     
    }); 
     
    TableColumn col = new TableColumn(1, 80);
    col.setCellRenderer(buttonEditor);
    col.setCellEditor(buttonEditor);

    cols.addColumn(colPattern);

If you want to display different buttons label for each row, you should insert a code block into the getTableCellRendererComponent and getTableCellEditorComponent methods to modify button's label.

DaveyDaveDave
  • 9,821
  • 11
  • 64
  • 77
xrath
  • 834
  • 6
  • 14
  • 4
    -1 this is an illegal implementation of CellEditor: by contract, it _must_ notify registered CellEditorListeners. Which it trivially cant with empty implementation of the addEditorListener ;-) Super contracts _must_ be served by implementations, no way around. – kleopatra Oct 05 '11 at 09:51
  • 1
    If you have multiple buttons in the same table, (as you will if you set this as the renderer for a column) this will have rendering issues since all the buttons are the same instance. It does weird things like fail to draw part of the button, just draw a white background, or draw several buttons as being highlighted instead of just one. I fixed the problem by separating to two separate classes TableButton and TableButtonEditor. I track multiple buttons in a hashmap based on the row and column index. – Ted Aug 23 '19 at 18:32
  • just wanna say I love you. working perfectly! – HNL Jul 02 '21 at 21:48
0

Check out Table Button Column.

It demonstrates how to use a JButton as a custom renderer and editor that you can click an easily invoke an Action.

camickr
  • 321,443
  • 19
  • 166
  • 288