4

我正在尝试创建一个动态表,该表从数据库中获取数据并将这些数据添加到单独的行中。我想为每一行(动态)添加一个额外的单元格,其中包含两个按钮……并在单击这些按钮时发生一些事件应该只发生在相应的行上..
(PS:我已经设法从数据库中获取数据并将其添加到表中..)

这是一个例子:

_____________________________________________________________
ID  | Name | Application for leave | Accept/Reject           |
--------------------------------------------------------------
1   |AD    | xxxxxxxxxxxxxxxxxx    |AcceptButton RejectButton| 
2   |SD    | xxxxxxxxxxxxxxxxxx    |AcceptButton RejectButton|
3   |PD    | xxxxxxxxxxxxxxxxxx    |AcceptButton RejectButton|
4   |DD    | xxxxxxxxxxxxxxxxxx    |AcceptButton RejectButton|
5   |MD    | xxxxxxxxxxxxxxxxxx    |AcceptButton RejectButton|
--------------------------------------------------------------

AcceptButton 和 RejectButton 应该在运行时与每一行一起动态添加。如果我按下 AcceptButton 或 RejectButton 该行应该自动被删除,并且数据库中具有相应 ID 的行应该得到更新。

4

3 回答 3

9

你需要做一些事情才能让它工作。

  • 可以支持所需功能的表模型,即删除行
  • 能够在单个单元格中渲染按钮的单元格渲染器
  • 能够提供编辑功能的单元格编辑器,因此您可以确定单击了哪个按钮并采取适当的操作

首先查看如何使用表格了解更多详细信息

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;

public class MultiButtonTable {

    public static void main(String[] args) {
        new MultiButtonTable();
    }

    public MultiButtonTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                MyTableModel model = new MyTableModel();
                model.add(new Data(1, "AD", "Blah 1"));
                model.add(new Data(2, "SD", "Blah 2"));
                model.add(new Data(3, "PD", "Blah 3"));
                model.add(new Data(4, "DD", "Blah 4"));
                model.add(new Data(5, "MD", "Blah 5"));

                JTable table = new JTable(model);
                AcceptRejectRenderer renderer = new AcceptRejectRenderer();
                table.getColumnModel().getColumn(3).setCellRenderer(renderer);
                table.getColumnModel().getColumn(3).setCellEditor(new AcceptRejectEditor());
                table.setRowHeight(renderer.getTableCellRendererComponent(table, null, true, true, 0, 0).getPreferredSize().height);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Data {

        private int id;
        private String name;
        private String application;

        public Data(int id, String name, String application) {
            this.id = id;
            this.name = name;
            this.application = application;
        }

        public int getID() {
            return id;
        }

        public void setID(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getApplication() {
            return application;
        }

        public void setApplication(String application) {
            this.application = application;
        }
    }

    public class MyTableModel extends AbstractTableModel {

        private List<Data> data;

        public MyTableModel() {
            data = new ArrayList<>(25);
        }

        @Override
        public String getColumnName(int column) {
            String value = null;
            switch (column) {
                case 0:
                    value = "ID";
                    break;
                case 1:
                    value = "Name";
                    break;
                case 2:
                    value = "Application for leave";
                    break;
                case 3:
                    value = "Accept/Reject";
                    break;
            }
            return value;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            Class value = Object.class;
            switch (columnIndex) {
                case 0:
                    value = Integer.class;
                    break;
                case 1:
                    value = String.class;
                    break;
                case 2:
                    value = String.class;
                    break;
            }
            return value;
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public int getColumnCount() {
            return 4;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Data obj = data.get(rowIndex);
            Object value = null;
            switch (columnIndex) {
                case 0:
                    value = obj.getID();
                    break;
                case 1:
                    value = obj.getName();
                    break;
                case 2:
                    value = obj.getApplication();
                    break;
                case 3:
                    break;
            }
            return value;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            if (columnIndex == 3) {

                System.out.println(aValue);

                Data value = data.get(rowIndex);
                if ("accept".equals(aValue)) {
                    System.out.println("Accepted");
                } else {
                    System.out.println("Rejected");
                }
                fireTableCellUpdated(rowIndex, columnIndex);
                remove(value);

            }
        }

        public void add(Data value) {
            int startIndex = getRowCount();
            data.add(value);
            fireTableRowsInserted(startIndex, getRowCount() - 1);
        }

        public void remove(Data value) {
            int startIndex = data.indexOf(value);
            System.out.println("startIndex = " + startIndex);
            data.remove(value);
            fireTableRowsInserted(startIndex, startIndex);
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 3;
        }
    }

    public class AcceptRejectPane extends JPanel {

        private JButton accept;
        private JButton reject;
        private String state;

        public AcceptRejectPane() {
            setLayout(new GridBagLayout());
            accept = new JButton("Accept");
            accept.setActionCommand("accept");
            reject = new JButton("Reject");
            reject.setActionCommand("reject");

            add(accept);
            add(reject);

            ActionListener listener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    state = e.getActionCommand();
                    System.out.println("State = " + state);
                }
            };

            accept.addActionListener(listener);
            reject.addActionListener(listener);
        }

        public void addActionListener(ActionListener listener) {
            accept.addActionListener(listener);
            reject.addActionListener(listener);
        }

        public String getState() {
            return state;
        }
    }

    public class AcceptRejectRenderer extends DefaultTableCellRenderer {

        private AcceptRejectPane acceptRejectPane;

        public AcceptRejectRenderer() {
            acceptRejectPane = new AcceptRejectPane();
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                acceptRejectPane.setBackground(table.getSelectionBackground());
            } else {
                acceptRejectPane.setBackground(table.getBackground());
            }
            return acceptRejectPane;
        }
    }

    public class AcceptRejectEditor extends AbstractCellEditor implements TableCellEditor {

        private AcceptRejectPane acceptRejectPane;

        public AcceptRejectEditor() {
            acceptRejectPane = new AcceptRejectPane();
            acceptRejectPane.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            stopCellEditing();
                        }
                    });
                }
            });
        }

        @Override
        public Object getCellEditorValue() {
            return acceptRejectPane.getState();
        }

        @Override
        public boolean isCellEditable(EventObject e) {
            return true;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            if (isSelected) {
                acceptRejectPane.setBackground(table.getSelectionBackground());
            } else {
                acceptRejectPane.setBackground(table.getBackground());
            }
            return acceptRejectPane;
        }
    }
}

需要注意的关键领域是构造函数中的AcceptRejectRendererand AcceptRejectEditor, the setValueAt, remove, isCellEditableof theMyTableModel和 the setCellRendererandsetCellEditor方法....

于 2013-07-10T08:30:09.587 回答
4
  • 单元格不能嵌套两个JComponents,因为默认JComponent/ JLabel(返回 by Renderer)没有LayoutManager在 API 中实现任何(与JFrame/JDialog...or相比JPanel),必须设置正确的LayoutManager( Grid/BoxLayout) 并且重要的是覆盖PrederredSize,不要这样做,麻烦

  • 有三种方式

    1. 添加JPanel两个JButtonsasRendererEditortoo(在此处搜索作为渲染器组件的RollOver效果)JButtons Component

    2. 使用JCheckBox(内置Boolean支持RendererEditor太)

    3. JRadioButtons使用两个ButtonGroup

      • JRadioButtonas Rendererand Editortoo

      • (更好,更好,更容易)JRadioButtons使用ButtonGroupasRendererJComboBoxasEditor

于 2013-07-10T08:11:49.430 回答
1

使用 CellRenderer 呈现列上的两个按钮。

被覆盖的方法可能看起来像这样:

@Override
public Component getTableCellRendererComponent(JTable table, Object value,
                       boolean isSelected, boolean hasFocus, int row, int column)
{
    component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);


     JPanel buttonPanel = new JPanel();

    //create buttons and add to JPanel. 

    //add an action listener to each of the buttons

    //Return this JPanel at the end of the method.

    return buttonPanel;

}

在删除按钮的actionPerformed()方法中,找到要删除的行。你有表格对象。然后,您可以从表对象中获取模型对象。在您的模型对象中,您应该有一个类似getRowForRowNumber(..)的方法,您可以在其中传递行参数。

现在,一旦您在单击按钮后引用了您的行,您只需要转到后端,更新您的删除操作,将其从模型中删除,然后执行fireTableDataChanged()

于 2013-07-10T08:21:17.883 回答