Now we shall discuss how to include a JButton in a table cell.
ButtonJTable.java
/*
* ButtonJTable.java
*
* Created on Aug 3, 2013, 02:57:58 PM
*/
package me.dhanoop.forblog;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
/**
*
* @author dhanoopbhaskar
*/
public class ButtonJTable extends javax.swing.JFrame {
private JButton tableData = null;
/** Creates new form ButtonJTable */
public ButtonJTable() {
initComponents();
customizeTable();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
//
private void initComponents() {
dbScrollPane = new javax.swing.JScrollPane();
dbTable = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
dbTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Title 1"
}
));
dbScrollPane.setViewportView(dbTable);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(dbScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
);
pack();
}//
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ButtonJTable().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JScrollPane dbScrollPane;
private javax.swing.JTable dbTable;
// End of variables declaration
private void customizeTable() {
Object[] columnNames = new Object[1];
columnNames[0] = "Button";
String buttonString = "Click Me";
Object[][] rowData = new Object[1][1];
rowData[0][0] = buttonString;
DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
dbTable.setModel(tableModel);
tableData = new JButton(buttonString);
tableData.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(new JFrame(), "I'm clicked!", "ButtonJTable", JOptionPane.INFORMATION_MESSAGE);
}
});
dbTable.getColumnModel().getColumn(0).setCellEditor(new ButtonCellEditor(new JCheckBox()));
dbTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(UIManager.getColor("Button.background"));
}
tableData.setText((value == null) ? "" : value.toString());
return tableData;
}
});
dbTable.updateUI();
}
}
DBTableModel.java
package me.dhanoop.forblog;
import javax.swing.table.DefaultTableModel;
/**
*
* @author dhanoopbhaskar
*/
public class DBTableModel extends DefaultTableModel {
public DBTableModel(Object[] columns) {
super(columns, 0);
}
public DBTableModel(Object[][] data, Object[] columns) {
super(data, columns);
}
@Override
public boolean isCellEditable(int row, int column) {
return true;
}
}
The following is the key snippet in the program.
Here we do mainly two things:
-
Changing the
CellEditor
of the ColumnModel of the column at position 0 (zero) of the table. -
Changing the
CellRenderer
of the ColumnModel of the column at position 0 (zero) of the table.
Unlike JComboBox and JCheckBox, for JButton we don’t have a suitable constructor.
public javax.swing.DefaultCellEditor(javax.swing.JTextField);
public javax.swing.DefaultCellEditor(javax.swing.JCheckBox);
public javax.swing.DefaultCellEditor(javax.swing.JComboBox);
The above are the ONLY available constructors for DefaultCellEditor. Hence we have to create fully customized DefaultCellEditor
for JButton.
private void customizeTable() {
Object[] columnNames = new Object[1];
columnNames[0] = "Button";
String buttonString = "Click Me";
Object[][] rowData = new Object[1][1];
rowData[0][0] = buttonString;
DefaultTableModel tableModel = new DBTableModel(rowData, columnNames);
dbTable.setModel(tableModel);
tableData = new JButton(buttonString);
tableData.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(new JFrame(), "I'm clicked!", "ButtonJTable", JOptionPane.INFORMATION_MESSAGE);
}
});
dbTable.getColumnModel().getColumn(0).setCellEditor(new ButtonCellEditor(new JCheckBox()));
dbTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(UIManager.getColor("Button.background"));
}
tableData.setText((value == null) ? "" : value.toString());
return tableData;
}
});
dbTable.updateUI();
}
Please find below an example of such a customized DefaultCellEditor
ButtonCellEditor.java
package me.dhanoop.forblog;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JTable;
/**
*
* @author dhanoopbhaskar
*/
public class ButtonCellEditor extends DefaultCellEditor {
private JButton button = null;
private String buttonText = null;
private boolean isClicked;
public ButtonCellEditor(JCheckBox checkBox) {
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (isSelected) {
button.setForeground(table.getSelectionForeground());
button.setBackground(table.getSelectionBackground());
} else {
button.setForeground(table.getForeground());
button.setBackground(table.getBackground());
}
buttonText = (value == null) ? "" : value.toString();
button.setText(buttonText);
isClicked = true;
return button;
}
@Override
public Object getCellEditorValue() {
if (isClicked) {
JOptionPane.showMessageDialog(button, "I'm clicked!", "ButtonJTable", JOptionPane.INFORMATION_MESSAGE);
}
isClicked = false;
return buttonText;
}
@Override
public boolean stopCellEditing() {
isClicked = false;
return super.stopCellEditing();
}
@Override
protected void fireEditingStopped() {
super.fireEditingStopped();
}
}