简体   繁体   English

Java JTable错误复制行

[英]Java JTable mistake in copying rows

Good day! 美好的一天! There is a problem in downloaded program. 下载的程序有问题。 You can copy a row by clicking on it by right mouse button, but after that when you change data in one cell data will be changed in every cell in column. 您可以通过单击鼠标右键来复制一行,但是此后在一个单元格中更改数据时,列中每个单元格中的数据都会更改。 Please, help me to understand, what I've missed. 拜托,帮助我理解我错过的一切。

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.awt.BorderLayout;


import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;


public class Main extends JFrame{

    JMenuItem obrc;
    JTable table;
    DataModel tm;
    JScrollPane scrollTable;

    Main() {
         super("Example JTable");
         Container c = getContentPane();
         ArrayList<String> columnNames = new ArrayList<String>();
         columnNames.add("Type"); columnNames.add("Sort"); columnNames.add("Thickness"); columnNames.add("Width"); 
         tm = new DataModel(columnNames);
         table = new JTable(tm);
         c.add(new JScrollPane(table), BorderLayout.CENTER);
         setSize(400, 300);
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         setVisible(true);


        table.getColumnModel().getColumn(0).setPreferredWidth(40);
        table.getColumnModel().getColumn(1).setPreferredWidth(40);
        table.addMouseListener(new MouseAdapter(){
            public void mouseClicked(MouseEvent event) {
                if (SwingUtilities.isRightMouseButton(event)) {
                    JPopupMenu obrcd = new JPopupMenu();
                    obrc = new JMenuItem("Copy");
                    obrc.addActionListener(new MenuListener());
                    obrcd.add(obrc); 
                    obrcd.show(c, event.getX(), event.getY()); 
                }
            }
        });
    }

    public class MenuListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            int[] nums = table.getSelectedRows();
            if (nums.length != 0) {
                if (e.getSource() == obrc) {
                ArrayList<Object[]> list = tm.getRows(nums);
                tm.addRows(list);
                }

                else JOptionPane.showMessageDialog(null, 
                    "Select at least one row", "Warning", JOptionPane.ERROR_MESSAGE);
            }
        }
    }   


        public static void main(String[] args) {
            // TODO Auto-generated method stub
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new Main();

                }

            });
        }

        class DataModel extends AbstractTableModel{
              ArrayList<Object[]> data = new ArrayList<Object[]>();
              ArrayList<String> columnNames = new ArrayList<String>();

            public DataModel(ArrayList<String> cNames){
                super();
                columnNames = cNames;
                Object[] dat = new Object[4];
                dat[0] = "board";
                dat[1] = "1";
                dat[2] = "25";
                dat[3] = "150";
                data.add(dat);
            }

            public boolean isCellEditable(int rowIndex, int columnIndex)
            {
              return true;
            }

            public Object getValueAt(int rowIndex, int columnIndex){ 
                Object[] row = data.get(rowIndex);

                return row[columnIndex];
            };

            public void setValueAt(Object newValue, int rowIndex, int columnIndex){
                data.get(rowIndex)[columnIndex] = newValue;
                fireTableDataChanged();

            }

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

            public int getColumnCount()
            {
                return columnNames.size();
            };
            public String getColumnName(int column)
            {
                    return columnNames.get(column);
            }

            public ArrayList<Object[]> getRows(int[] nums) {
                ArrayList<Object[]> newdata = new ArrayList<Object[]>();
                for (int i = 0; i < nums.length; i++) {
                    newdata.add(data.get(nums[i]));
                }
                return newdata;
            }

            public void addRows (ArrayList<Object[]> rows) {
                for (int i = 0; i < rows.size(); i++) data.add(rows.get(i));
                fireTableDataChanged();
            }

        }
}

Problem when you are adding new rows 添加新行时出现问题

    public void addRows (ArrayList<Object[]> rows) {
        for (int i = 0; i < rows.size(); i++) data.add(rows.get(i));
        fireTableDataChanged();
    }

Your copied row(s) will point to same object(s) with selected row(s). 您复制的行将指向与选定行相同的对象。 You need clone to new object: 您需要克隆到新对象:

public void addRows (ArrayList<Object[]> rows) {
    for (int i = 0; i < rows.size(); i++) {
        Object[] clone = rows.get(i).clone();
        data.add(clone);
    }
    fireTableDataChanged();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM