Add Jbutton to each row of a Jtable
I need ur help, I want to add a Jbutton ( delete button) to each row of a Jtable. Till now, I added the button to each row, but I've a problem with the action. I tried this, but it's not working. When I click the button nothing happens. Can anyone help me please, i'm really stack. This is my code :
`public class Fenetre extends JFrame {
Statement stmt;
Map<Integer,Integer> row_table = new HashMap<Integer,Integer>();
JButton addUser;
public Fenetre(){
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("JTable");
this.setSize(600, 140);
String requeteListeUser=" SELECT * FROM COMPTE_UTILISATEUR";
try{
stmt= (Statement) new Connexion().getConnection().createStatement();
ResultSet resultat= stmt.executeQuery(requeteListeUser);
resultat.last();
String title[] = {"Nom","Prenom","Matricule","Action"};
int rowCount = resultat.getRow();
Object[][] data = new Object[rowCount][4];
final JTable tableau = new JTable(data,title);
JButton jButton2= new JButton("Supprimer");
// this.tableau = new JTable(model);
tableau.getColumn("Action").setCellRenderer(new ButtonRenderer());
this.getContentPane().add(new JScrollPane(tableau), BorderLayout.CENTER);
int i=0;
resultat.beforeFirst(); // on repositionne le curseur avant la première ligne
while(resultat.next()) //tant qu'on a quelque chose à lire
{
//Remplire le tableau à deux dimensions Data[][]
for(int j=1;j<=4;j++)
{
if(j != 4)data[i][j-1]=resultat.getObject(j)+"";
else { data[i][j-1] = jButton2;
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
((DefaultTableModel)tableau.getModel()).removeRow(tableau.getSelectedRow());
}
});
}
}
i++;
row_table.put(i, resultat.getInt("id_utilisateur"));
}
}
catch(SQLException ex){
System.out.println(ex);
}
addUser = new JButton("Ajouter un utilisateur");
addUser.setPreferredSize(new Dimension(60,30));
addUser.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
new AjouterUtilisateur().setVisible(true);
}
});
this.getContentPane().add(addUser,BorderLayout.SOUTH);
}
//Classe modèle personnalisée
class ZModel extends AbstractTableModel{
private Object[][] data;
private String[] title;
//Constructeur
public ZModel(Object[][] data, String[] title){
this.data = data;
this.title = title;
}
//Retourne le nombre de colonnes
public int getColumnCount() {
return this.title.length;
}
//Retourne le nombre de lignes
public int getRowCount() {
return this.data.length;
}
//Retourne la valeur à l'emplacement spécifié
public Object getValueAt(int row, int col) {
return this.data[row][col];
}
}
public class ButtonRenderer extends JButton implements TableCellRenderer{
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean isFocus, int row, int col) {
//On écrit dans le bouton ce que contient la cellule
setText("Suuprimer");
//On retourne notre bouton
return this;
}
}
public static void main(String[] args){
//Fenetre fen = new Fenetre();
new Menu().setVisible(true);
}
}`
Solution 1:
Adding a button to a JTable
's column to perform an action is...personally...restrictive and a little, well, 80's web...
Consider a different approach to the problem, instead of placing buttons in the columns, which take up screen real estate, which, if configured correctly could appear off screen and limit the user to a single, repetitive, action when dealing with multiple rows (ie, they want to delete multiple rows in one go), you could use a JToolBar
and/or JMenu
to provide access to the delete function, which would allow the user to select one or more rows and delete them in a single click...
Consider also, you provide a action which can be triggered by the Delete key on the keyboard to perform the same action, freeing the user from having to lift their hands from the keyboard...
You could even attach a JPopupMenu
to the table as well...
This is, actually, a very common use case, and if designed properly, very re-usable...
For example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class EditRows {
public static void main(String[] args) {
new EditRows();
}
public EditRows() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
DefaultTableModel model = new DefaultTableModel();
for (int index = 0; index < 13; index++) {
model.addColumn(Character.toString((char) (index + 65)));
}
for (int row = 0; row < 100; row++) {
Vector<String> rowData = new Vector<>(13);
for (int col = 0; col < 13; col++) {
rowData.add(row + "x" + col);
}
model.addRow(rowData);
}
JTable table = new JTable(model);
DeleteRowFromTableAction deleteAction = new DeleteRowFromTableAction(table, model);
JToolBar tb = new JToolBar();
tb.add(deleteAction);
InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
ActionMap am = table.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "deleteRow");
am.put("deleteRow", deleteAction);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(tb, BorderLayout.NORTH);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public abstract class AbstractTableAction<T extends JTable, M extends TableModel> extends AbstractAction {
private T table;
private M model;
public AbstractTableAction(T table, M model) {
this.table = table;
this.model = model;
}
public T getTable() {
return table;
}
public M getModel() {
return model;
}
}
public class DeleteRowFromTableAction extends AbstractTableAction<JTable, DefaultTableModel> {
public DeleteRowFromTableAction(JTable table, DefaultTableModel model) {
super(table, model);
putValue(NAME, "Delete selected rows");
putValue(SHORT_DESCRIPTION, "Delete selected rows");
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
setEnabled(getTable().getSelectedRowCount() > 0);
}
});
setEnabled(getTable().getSelectedRowCount() > 0);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("...");
JTable table = getTable();
if (table.getSelectedRowCount() > 0) {
List<Vector> selectedRows = new ArrayList<>(25);
DefaultTableModel model = getModel();
Vector rowData = model.getDataVector();
for (int row : table.getSelectedRows()) {
int modelRow = table.convertRowIndexToModel(row);
Vector rowValue = (Vector) rowData.get(modelRow);
selectedRows.add(rowValue);
}
for (Vector rowValue : selectedRows) {
int rowIndex = rowData.indexOf(rowValue);
model.removeRow(rowIndex);
}
}
}
}
}
Take a look at:
- How to Use Actions
- How to Use Key Bindings
- How to Use Tool Bars
- How to Use Menus
For more details.
If you're still determined to place a button in the table column, then take a look at Table Button Column