Java CellEditorListener不会检测单元格何时被编辑

Java CellEditorListener不会检测单元格何时被编辑,java,swing,jtable,Java,Swing,Jtable,我正在进行我的“顶点”项目,准备在本学期毕业,在我正在进行的项目中遇到了一些问题。代码是为“意外发现”书商计划编写的。我将为一家虚拟书店设计一个销售点系统 目前,当用户编辑给定行的“数量”单元格时,我一直在尝试更新“总计”列(第5列)。“数量”字段还需要验证其单元格中的值是否不大于库存数量(第1列) 我还阅读了Java教程,昨晚在Google上搜索了几个小时,试图找到一些关于如何让CellEditorListener工作的有用代码 我以前也尝试过让CashierPanel类实现CellEdito

我正在进行我的“顶点”项目,准备在本学期毕业,在我正在进行的项目中遇到了一些问题。代码是为“意外发现”书商计划编写的。我将为一家虚拟书店设计一个销售点系统

目前,当用户编辑给定行的“数量”单元格时,我一直在尝试更新“总计”列(第5列)。“数量”字段还需要验证其单元格中的值是否不大于库存数量(第1列)

我还阅读了Java教程,昨晚在Google上搜索了几个小时,试图找到一些关于如何让CellEditorListener工作的有用代码

我以前也尝试过让CashierPanel类实现CellEditorListener,并通过以下方式进行注册:

CellEditorListener listener = null;
table.getDefaultEditor(String.class).addCellEditorListener(listener);
这种方法也不起作用

下面是我现在拥有的代码(217行):

/*导入的依赖项*/
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyAdapter;
导入java.awt.event.KeyEvent;
导入java.math.BigDecimal;
导入java.math.RoundingMode;
导入java.util.ArrayList;
导入javax.swing.DefaultCellEditor;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.JTextField;
导入javax.swing.event.CellEditorListener;
导入javax.swing.event.ChangeEvent;
导入javax.swing.table.AbstractTableModel;
导入javax.swing.table.DefaultTableCellRenderer;
导入javax.swing.table.TableColumn;
导入net.miginfocom.swing.MigLayout;
公共类出纳面板扩展JFrame{
/**
*串行版本
*/
私有静态最终长serialVersionUID=6922826100788686147L;
/*私人领域*/
私人JPanel搜索小组;
私人JLabel isbn_lbl;
私人JLabel所有权_lbl;
私人JTextField isbn_tf;
私人JTextField title_tf;
私有JTextField-currentCell;
私人藏书;
私有出纳表模型表数据;
私有CellEditorListener侦听器;
/**
*建造师
*/
公共出纳小组(){
//设置窗口属性
setTitle(“测试此表”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
设置大小(585300);
setLayout(新的BorderLayout());
tableData=新出纳TableModel();
最终JTable表=新JTable(tableData);
表2.设置行高(25);
table.getTableHeader().setReorderingAllowed(false);
table.setCellSelectionEnabled(真);
table.putClientProperty(“terminateEditOnFocusLost”,Boolean.TRUE);
添加(新的JScrollPane(表),BorderLayout.CENTER);
//定义单元渲染器以将文本渲染到单元的中心
DefaultTableCellRenderer centerRenderer=新的DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
//设置列属性
int[]大小=新的int[]{50,50,87,275,50,50};
字符串[]columnNames=新字符串[]{“数量”、“库存”、“ISBN”、“标题”,
“价格”、“总额”};
TableColumn[]column=新的TableColumn[columnNames.length];
for(字节i=0;i/* Imported Dependencies */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;

import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

import net.miginfocom.swing.MigLayout;

public class CashierPanel extends JFrame {

    /**
    * Serial Version UID
    */
    private static final long serialVersionUID = 6922826100788686147L;

    /* Private Fields */
    private JPanel searchPanel;
    private JLabel isbn_lbl;
    private JLabel title_lbl;
    private JTextField isbn_tf;
    private JTextField title_tf;
    private JTextField currentCell;
    private BookCollection myCollection;
    private CashierTableModel tableData;

    private CellEditorListener listener;

    /**
    * Constructor
    */
    public CashierPanel() {

        // Set window properties
        setTitle("Testing this table");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(585, 300);
        setLayout(new BorderLayout());

        tableData = new CashierTableModel();
        final JTable table = new JTable(tableData);
        table.setRowHeight(25);
        table.getTableHeader().setReorderingAllowed(false);
        table.setCellSelectionEnabled(true);
        table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
        add(new JScrollPane(table), BorderLayout.CENTER);

        // Define a cell renderer to render text to center of cell
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment(JLabel.CENTER);

        // Set column properties
        int[] sizes = new int[] { 50, 50, 87, 275, 50, 50 };
        String[] columnNames = new String[] { "Qty", "Stock", "ISBN", "Title",
                "Price", "Total" };
        TableColumn[] column = new TableColumn[columnNames.length];
        for (byte i = 0; i < columnNames.length; i++) {
            column[i] = table.getColumnModel().getColumn(i);
            column[i].setMinWidth(sizes[i]);
            column[i].setHeaderValue(columnNames[i]);
            if (i != 3) {
                column[i].setMaxWidth(sizes[i]);
                column[i].setCellRenderer(centerRenderer);
            }
        }

        /* Make the quantity field only display digits */
        currentCell = new JTextField();
        column[0].setCellEditor(new DefaultCellEditor(currentCell));
        // Add a key listener to the current cell
        currentCell.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                // if the key typed is not a digit or backspace
                if (!Character.isDigit(e.getKeyChar())
                        && e.getKeyChar() != KeyEvent.VK_BACK_SPACE) {
                    currentCell.setEditable(false);
                    currentCell.setBackground(Color.WHITE);
                } else {
                    currentCell.setEditable(true);
                }
            }
        });

        /* Search panel */
        searchPanel = new JPanel();
        myCollection = new BookCollection();

        isbn_lbl = new JLabel("Search by ISBN:");
        isbn_tf = new JTextField();
        isbn_tf.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                ArrayList<BookData> data = myCollection.select(isbn_tf.getText(), BookCollection.FIELD_ISBN);
                tableData.addNewRow();
                table.setValueAt((new BigDecimal("1").toString()), tableData.getRowCount() - 1, 0);
                table.setValueAt(Integer.toString(data.get(0).getQtyOnHand()), tableData.getRowCount() - 1, 1);
                table.setValueAt(data.get(0).getIsbn(),tableData.getRowCount() - 1, 2);
                table.setValueAt(data.get(0).getTitle(),tableData.getRowCount() - 1, 3);
                table.setValueAt(data.get(0).getRetail().setScale(2, RoundingMode.HALF_UP).toString(), tableData.getRowCount() - 1, 4);
                table.setValueAt(table.getValueAt(tableData.getRowCount() - 1, 4), tableData.getRowCount() - 1, 5);
                isbn_tf.setText("");
            }
        });

        title_lbl = new JLabel("Search by Title:");
        title_tf = new JTextField();
        title_tf.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                ArrayList<BookData> data = myCollection.select(title_tf.getText(), BookCollection.FIELD_TITLE);
                tableData.addNewRow();
                table.setValueAt((new BigDecimal("1").toString()), tableData.getRowCount(), 0);
                table.setValueAt(Integer.toString(data.get(0).getQtyOnHand()), tableData.getRowCount() - 1, 1);
                table.setValueAt(data.get(0).getIsbn(), tableData.getRowCount(), 2);
                table.setValueAt(data.get(0).getTitle(), tableData.getRowCount(), 3);
                table.setValueAt(data.get(0).getRetail().setScale(2, RoundingMode.HALF_UP).toString(), tableData.getRowCount(), 4);
                table.setValueAt(data.get(0).getRetail().setScale(2, RoundingMode.HALF_UP).toString(), tableData.getRowCount(), 5);
                title_tf.setText("");
            }
        });

        searchPanel.setLayout(new MigLayout("", "[78px][202px,grow]", "[24px][29px]"));
        searchPanel.add(isbn_lbl, "cell 0 0, alignx left, aligny center");
        searchPanel.add(isbn_tf, "cell 1 0,growx, aligny center");
        searchPanel.add(title_lbl, "cell 0 1, alignx left, aligny center");
        searchPanel.add(title_tf, "cell 1 1, growx, aligny center");

        add(searchPanel, BorderLayout.SOUTH);

    };

    public static void main(String[] args) {
        CashierPanel myCashierPanel = new CashierPanel();
        myCashierPanel.setVisible(true);
    }
}

class CashierTableModel extends AbstractTableModel implements CellEditorListener{

    /**
     * 
     */
    private static final long serialVersionUID = -1500952132717353189L;
    private ArrayList<Object[]> data = new ArrayList<Object[]>();

    public void addNewRow() {
        data.add(new String[] { null, null, null, null, null, null });
        fireTableDataChanged();
    }

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

    public int getColumnCount() {
        return 6;
    }

    public Object getValueAt(int row, int col) {
        return data.get(row)[col];
    }

    public void setValueAt(Object value, int row, int col) {
        data.get(row)[col] = value;
        fireTableCellUpdated(row, col);
    }

    public boolean isCellEditable(int row, int col) {
        if (col > 0) {
            return false;
        } else {
            return true;
        }
    }

    public void editingCanceled(ChangeEvent e) {
        for (int i = 0; i <= getRowCount() - 1; i++) {
            BigDecimal[] data = new BigDecimal[3];
            data[0] = data[0].add((BigDecimal) getValueAt(i, 1));
            data[1] = data[1].add((BigDecimal) getValueAt(i, 4));
            data[2] = data[2].add(calculateTotal(data[0], data[1]));
            setValueAt(data[2], i, 5);
        }
    }

    public void editingStopped(ChangeEvent e) {
        for (int i = 0; i <= getRowCount() - 1; i++) {
            BigDecimal[] data = new BigDecimal[3];
            data[0] = data[0].add((BigDecimal) getValueAt(i, 1));
            data[1] = data[1].add((BigDecimal) getValueAt(i, 4));
            data[2] = data[2].add(calculateTotal(data[0], data[1]));
            setValueAt(data[2], i, 5);
        }
    }

    public BigDecimal calculateTotal(BigDecimal qty, BigDecimal retail) {
        BigDecimal total = new BigDecimal("0.00");
        total = total.add(qty.multiply(retail));
        return total;
    }
}