编程语言
首页 > 编程语言> > java-是否可以在JTable中的指定列上侦听数据更改?

java-是否可以在JTable中的指定列上侦听数据更改?

作者:互联网

我正在用一种类似于excel的公式进行JTable,因为某些单元格是自动计算的.

我正在使用TableModelListener侦听数据更改,并在那里调用一个函数以遍历所有数据并计算每一行的值,如下所示.

我正在计算列号3“ uds”,它包含由colum件给出的整数.例如,如果件的值为“ 3”,则uds应该为“ 1”,或者如果件的值为“ 3-5”,uds应该为“ 2”

private void maths() {
        //    0        1       2     3      4
        // Descrip - Pieces - PVP - Uds - Total - Done
        //                          Col 4 is Nº of "-"  (col2 * col3)
        int colDescrip = 0; int colPieces = 1; int colPvp = 2;  int colUds = 3; int colTotal = 4; //Columnas

        for(int row = 0; row < getTable().getRowCount(); row++) {

            String pieces = getTable().getModel().getValueAt(row, colPiezas).toString();

            if(pieces != "") {
                Integer n = nOfHyphens(getTable().getModel().getValueAt(row, colPieces).toString());
                System.out.println(n);
                getTable().getModel().setValueAt(n, row, colUds); //Error here
            }


            System.out.println("Col 0: " + getTable().getModel().getValueAt(row, 0) + "." + getTable().getModel().getValueAt(row, 0).getClass());
            System.out.println("Col 1: " + getTable().getModel().getValueAt(row, 1) + "." + getTable().getModel().getValueAt(row, 1).getClass());
            System.out.println("Col 2: " + getTable().getModel().getValueAt(row, 2) + "." + getTable().getModel().getValueAt(row, 2).getClass());
            System.out.println("Col 3: " + getTable().getModel().getValueAt(row, 3) + "." + getTable().getModel().getValueAt(row, 3).getClass());
            System.out.println("Col 4: " + getTable().getModel().getValueAt(row, 4) + "." + getTable().getModel().getValueAt(row, 4).getClass());
            System.out.println("#################");
        }

    }

    private int nOfHyphens(String s) {
        int t = 1;
        char c = '-';
        for(int i = 0; i < s.length(); i++) 
            if(s.charAt(i) == c) 
                t++;

        return t;
    }

此maths()函数在public void tableChanged(TableModelEvent arg0)内部调用,而我的问题是,每次它计算每一行的总数时,数据都会发生变化,当然,该事件一次又一次地调用,直到得到StackOverflowError,如何我可以预防吗?用数据制作一个JTable,用结果制作另一个JTable?还是只有在指定的列更改时才可以调用此事件?

谢谢.

编辑:添加完整代码

public class PresupuestoFrameNuevo extends JFrame{

    private JPanel tableHolder;
    private JPanel btnHolder;
    private JPanel btnleft;
    private JPanel btnright;

    private JScrollPane jsp;
    private JTable table;

    private JButton addrow;
    private JButton delrow;
    private JButton save;
    private JButton cancel;

    private ButtonListener BL;
    private TableListener TL;

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

    public PresupuestoFrameNuevo() {
        setSize(1000,600);
        setTitle("Presupuesto nuevo");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());

        initComps();
        drawComps();

        setVisible(true);
    }

    private void initComps() {

        setTable(new JTable(new PresupuestoModel()));
        setJsp(new JScrollPane(getTable()));

        getTable().getTableHeader().setReorderingAllowed(false);
        getTable().getTableHeader().setResizingAllowed(false);
        getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        getTable().setCellSelectionEnabled(true);   

        setTL(new TableListener());

        getTable().getModel().addTableModelListener(getTL());

        //Table width
        getTable().getColumnModel().getColumn(0).setPreferredWidth(300); //Descrip
        getTable().getColumnModel().getColumn(2).setMaxWidth(80);//pvp unidad
        getTable().getColumnModel().getColumn(3).setMaxWidth(70);//unidades
        getTable().getColumnModel().getColumn(4).setMaxWidth(80);//total
        getTable().getColumnModel().getColumn(5).setMaxWidth(60);//hecho

        setTableHolder(new JPanel());
        setBtnHolder(new JPanel());
        setBtnleft(new JPanel());
        setBtnright(new JPanel());

        getTableHolder().setLayout(new GridLayout(1,1));
        getBtnHolder().setLayout(new GridLayout(1,2));

        setBL(new ButtonListener());

        setAddrow(new JButton("Add row"));
        setDelrow(new JButton("Delete row")); //TODO
        setSave(new JButton("Save"));         //TODO
        setCancel(new JButton("Cancel"));     //TODO

        getAddrow().addActionListener(getBL());
        getDelrow().addActionListener(getBL());
        getSave().addActionListener(getBL());
        getCancel().addActionListener(getBL());

    }

    private void drawComps() {

        getBtnleft().add(getAddrow());
        getBtnleft().add(getDelrow());
        getBtnright().add(getSave());
        getBtnright().add(getCancel());

        getBtnleft().setBorder(BorderFactory.createTitledBorder("Tools"));
        getBtnright().setBorder(BorderFactory.createTitledBorder("Options"));
        getTableHolder().add(getJsp());
        getBtnHolder().add(getBtnleft());
        getBtnHolder().add(getBtnright());

        add(getBtnHolder(), BorderLayout.SOUTH);
        add(getTableHolder(), BorderLayout.CENTER);
    }

    private class ButtonListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent ae) {
            if(ae.getSource() == addrow) {
                ((PresupuestoModel) getTable().getModel()).addRow();
            }
            else if(ae.getSource() == delrow) {

            }
            else if(ae.getSource() == save) {

            }
            else if(ae.getSource() == cancel) {

            }

        }

    }

    private class TableListener implements TableModelListener{

        @Override
        public void tableChanged(TableModelEvent e) {
            System.out.println(e.getSource());
            System.out.println(e.getSource().getClass());
            System.out.println(e.getColumn());

            /*if(e.getColumn() == 3) {
                return;
            }
            else {

                //maths();  
            }*/


        }

        private void maths() {
            //    0        1          2           3         4
            // Descrip - Piezas - PVP Unidad - Unidades - Total - Hecho
            //                                  Nº of "-"  2*3
            int colDescrip = 0; int colPieces = 1; int colPvp = 2;  int colUds = 3; int colTotal = 4; //Columnas

            for(int row = 0; row < getTable().getRowCount(); row++) {

                String pie = getTable().getModel().getValueAt(row, colPieces).toString();

                if(pie != "") {
                    Integer n = nOfHyphens(getTable().getModel().getValueAt(row, colPieces).toString());
                    System.out.println(n);
                    getTable().getModel().setValueAt(n, row, colUds);
                }


                System.out.println("Col 0: " + getTable().getModel().getValueAt(row, 0) + "." + getTable().getModel().getValueAt(row, 0).getClass());
                System.out.println("Col 1: " + getTable().getModel().getValueAt(row, 1) + "." + getTable().getModel().getValueAt(row, 1).getClass());
                System.out.println("Col 2: " + getTable().getModel().getValueAt(row, 2) + "." + getTable().getModel().getValueAt(row, 2).getClass());
                System.out.println("Col 3: " + getTable().getModel().getValueAt(row, 3) + "." + getTable().getModel().getValueAt(row, 3).getClass());
                System.out.println("Col 4: " + getTable().getModel().getValueAt(row, 4) + "." + getTable().getModel().getValueAt(row, 4).getClass());
                System.out.println("#################");
            }

        }

        private int nOfHyphens(String s) {
            int t = 1;
            char c = '-';
            for(int i = 0; i < s.length(); i++) 
                if(s.charAt(i) == c) 
                    t++;

            return t;
        }

    }

    public JPanel getTableHolder() {
        return tableHolder;
    }

    public void setTableHolder(JPanel tableHolder) {
        this.tableHolder = tableHolder;
    }

    public JPanel getBtnHolder() {
        return btnHolder;
    }

    public void setBtnHolder(JPanel btnHolder) {
        this.btnHolder = btnHolder;
    }

    public JPanel getBtnleft() {
        return btnleft;
    }

    public void setBtnleft(JPanel btnleft) {
        this.btnleft = btnleft;
    }

    public JPanel getBtnright() {
        return btnright;
    }

    public void setBtnright(JPanel btnright) {
        this.btnright = btnright;
    }

    public JScrollPane getJsp() {
        return jsp;
    }

    public void setJsp(JScrollPane jsp) {
        this.jsp = jsp;
    }

    public JTable getTable() {
        return table;
    }

    public void setTable(JTable table) {
        this.table = table;
    }

    public JButton getAddrow() {
        return addrow;
    }

    public void setAddrow(JButton addrow) {
        this.addrow = addrow;
    }

    public JButton getDelrow() {
        return delrow;
    }

    public void setDelrow(JButton delrow) {
        this.delrow = delrow;
    }

    public JButton getSave() {
        return save;
    }

    public void setSave(JButton save) {
        this.save = save;
    }

    public JButton getCancel() {
        return cancel;
    }

    public void setCancel(JButton cancel) {
        this.cancel = cancel;
    }

    public ButtonListener getBL() {
        return BL;
    }

    public void setBL(ButtonListener bL) {
        BL = bL;
    }

    public TableListener getTL() {
        return TL;
    }

    public void setTL(TableListener tL) {
        TL = tL;
    }



}

表格模型

public class PresupuestoModel extends AbstractTableModel {

    private String[] cols = { "Description", "Pieces", "PVP U", "Uds", "Total", "Done" };
    private Vector<Object[]> data;

    public PresupuestoModel() {
        setData(new Vector<Object[]>());
    }

    public void addRow() {
        Object[] s = new Object[getCols().length];

        for (int i = 0; i < getCols().length; i++) {
            if (i != getCols().length - 1)
                s[i] = "";
            else
                s[i] = new Boolean(false);
        }

        getData().add(s);
        fireTableRowsInserted(getRowCount() - 1, getColumnCount());
    }

    public void deleteRow(int index) {
        getData().remove(index);
        fireTableRowsDeleted(index, index);
    }

    public String getColumnName(int n) {
        return getCols()[n];
    }

    public boolean isCellEditable(int row, int col) {
        if ((col == 3) || (col == 4)) 
            return false;
        else 
            return true;
    }

    public Class<?> getColumnClass(int c) {
        if (c == getCols().length - 1) {
            return Boolean.class;
        }
        else if((c == 2) || (c == 3)) {
            return Integer.class;
        }
        else { 
            return String.class;
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return (getData().get(rowIndex))[columnIndex];
    }

    public void setValueAt(Object value, int row, int col) {
        System.out.println("Object: " + value + "." + value.getClass()+ "[" + row + "," + col + "]");
        if(col == getCols().length - 1) {
            (getData().get(row))[col] = value;
        }
        else if((col > 1) || (col < 5))  {
            (getData().get(row))[col] = value;
        }
        else {
            (getData().get(row))[col] = value.toString();
        }
        fireTableDataChanged();
    }

    @Override
    public int getColumnCount() {
        return getCols().length;
    }

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

    public String[] getCols() {
        return cols;
    }

    public void setCols(String[] cols) {
        this.cols = cols;
    }

    public Vector<Object[]> getData() {
        return data;
    }

    public void setData(Vector<Object[]> data) {
        this.data = data;
    }

}

解决方法:

TableModelEvent参数具有getColumn()方法,该方法将告诉您正在更改并导致事件的列.您可以使用if块,检查此方法返回的int值,如果忽略了列,则只需调用return即可;

public void tableChanged(TableModelEvent event) {
    if (event.getColumn() == COLUMN_TO_IGNORE) {
        return;
    } else {
        maths();
    }
}

标签:stack-overflow,listener,swing,jtable,java
来源: https://codeday.me/bug/20191027/1945077.html