复制行时出现Java JTable错误

复制行时出现Java JTable错误,java,swing,jtable,Java,Swing,Jtable,你好! 下载的程序有问题。您可以通过单击鼠标右键复制一行,但在这之后,当您更改一个单元格中的数据时,列中每个单元格中的数据都将更改。请帮我理解,我错过了什么 import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; i

你好! 下载的程序有问题。您可以通过单击鼠标右键复制一行,但在这之后,当您更改一个单元格中的数据时,列中每个单元格中的数据都将更改。请帮我理解,我错过了什么

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

        }
}
导入java.awt.Container;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.util.ArrayList;
导入java.awt.BorderLayout;
导入javax.swing.JFrame;
导入javax.swing.JMenuItem;
导入javax.swing.JOptionPane;
导入javax.swing.jpopmenu;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.SwingUtilities;
导入javax.swing.table.AbstractTableModel;
公共类主框架{
项目obrc;
JTable表;
数据模型tm;
JScrollPane滚动表;
Main(){
超级(“示例JTable”);
容器c=getContentPane();
ArrayList columnNames=新的ArrayList();
columnNames.add(“Type”);columnNames.add(“Sort”);columnNames.add(“Thickness”);columnNames.add(“Width”);
tm=新数据模型(列名称);
表=新JTable(tm);
c、 添加(新的JScrollPane(表),BorderLayout.CENTER);
设置大小(400300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(真);
table.getColumnModel().getColumn(0).setPreferredWidth(40);
table.getColumnModel().getColumn(1).setPreferredWidth(40);
表.addMouseListener(新的MouseAdapter(){
公共void mouseClicked(MouseEvent事件){
if(SwingUtilities.isRightMouseButton(事件)){
JPopupMenu obrcd=新的JPopupMenu();
obrc=新项目(“副本”);
addActionListener(新的MenuListener());
obrcd.add(obrc);
show(c,event.getX(),event.getY());
}
}
});
}
公共类MenuListener实现ActionListener{
已执行的公共无效操作(操作事件e){
int[]nums=table.getSelectedRows();
如果(nums.length!=0){
如果(例如getSource()==obrc){
ArrayList list=tm.getRows(nums);
tm.addRows(列表);
}
else JOptionPane.showMessageDialog(空,
“选择至少一行”,“警告”,JOptionPane.错误消息);
}
}
}   
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
新的Main();
}
});
}
类DataModel扩展了AbstractTableModel{
ArrayList数据=新的ArrayList();
ArrayList columnNames=新的ArrayList();
公共数据模型(ArrayList cNames){
超级();
columnNames=cNames;
Object[]dat=新对象[4];
dat[0]=“板”;
dat[1]=“1”;
dat[2]=“25”;
dat[3]=“150”;
添加数据(dat);
}
公共布尔值isCellEditable(int-rowIndex、int-columnIndex)
{
返回true;
}
公共对象getValueAt(int-rowIndex,int-columnIndex){
对象[]行=data.get(行索引);
返回行[列索引];
};
public void setValueAt(对象newValue、int行索引、int列索引){
data.get(rowIndex)[columnIndex]=newValue;
fireTableDataChanged();
}
public int getRowCount()
{
返回data.size();
};
public int getColumnCount()
{
返回columnNames.size();
};
公共字符串getColumnName(int列)
{
返回columnNames.get(column);
}
公共ArrayList getRows(int[]nums){
ArrayList newdata=新ArrayList();
对于(int i=0;i
添加新行时出现问题

    public void addRows (ArrayList<Object[]> rows) {
        for (int i = 0; i < rows.size(); i++) data.add(rows.get(i));
        fireTableDataChanged();
    }
public void addRows(ArrayList行){
对于(inti=0;i
复制的行将指向与选定行相同的对象。您需要克隆到新对象:

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