【问题标题】:Add Jbutton to each row of a Jtable将 Jbutton 添加到 Jtable 的每一行
【发布时间】:2014-09-24 02:00:14
【问题描述】:

我需要你的帮助,我想在 Jtable 的每一行中添加一个 Jbutton(删除按钮)。到目前为止,我将按钮添加到每一行,但我的操作有问题。我试过这个,但它不工作。当我单击按钮时,没有任何反应。谁能帮帮我,我真的很累。 这是我的代码:

`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);
  }
}`

【问题讨论】:

  • 请发帖MCVE。另请参阅@camickr 的Table Button Column
  • 您需要同时定义单元格渲染器和单元格编辑器。
  • 感谢您回答 Aqua。你能告诉我怎么做吗,我真的卡住了
  • @user3862042 您当前的方法不正确。您不应将组件存储在模型中。该模型仅用于数据。渲染器用于渲染数据。您还需要添加一个编辑器的实现。编辑器组件允许您进行更改。渲染器只绘制单元格。
  • -1 10 天前提出的问题,OP 仍未发布正确的 SSCCE:stackoverflow.com/questions/24873671/delete-button-in-a-jtable/…

标签: java swing jtable jbutton


【解决方案1】:

JTable 的列中添加一个按钮来执行某项操作是……个人而言……限制性,而且有点像 80 年代的网络……

考虑一种不同的方法来解决这个问题,而不是在列中放置按钮,这会占用屏幕空间,如果配置正确,这些按钮可能会出现在屏幕之外,并在处理多个操作时限制用户执行单个、重复的操作行(即,他们想一次性删除多行),您可以使用JToolBar 和/或JMenu 提供对删除功能的访问,这将允许用户选择一行或多行并删除它们只需单击一下...

另外考虑一下,您提供了一个动作,可以通过键盘上的 Delete 键触发以执行相同的动作,从而使用户不必从键盘上抬起手...

您甚至可以将JPopupMenu 附加到表格...

实际上,这是一个非常常见的用例,如果设计得当,可重复使用...

例如...

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);
                }
            }
        }

    }

}

看看:

了解更多详情。

如果你还是确定要在表格列中放置一个按钮,那就看看Table Button Column

【讨论】:

  • +1 很棒的图片,比文字更有价值 :)
  • @Aqua 是的,如果我有更多时间,我也会在其中添加 JMenuJPopupMenu,但我想我的意思是 ;)
  • 非常感谢@MadProgrammer 的帮助
  • 既然视图索引映射到模型索引,那么是的
  • @Viraj 这个问题很困难,因为一旦你删除了一行,你就改变了视图/模型索引。您可以从表的末尾向后走到开头,直接按索引删除行
猜你喜欢
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
相关资源
最近更新 更多