jtable仅使用链表中的值填充一行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jtable仅使用链表中的值填充一行相关的知识,希望对你有一定的参考价值。

所以我有这个班级,里面有员工的姓名,地址和城市。之后,类被存储在链表中,当用户在文本字段中输入名称,地址和城市时,值将被插入到链表中,然后填充到jtable上。到目前为止,我已经能够获取用户详细信息并将其添加到likeslist中,但是当我单击添加按钮时,它只向表中添加一行,如果我在文本字段中插入一些其他值并单击addbutton再次,它只是删除以前添加的行并添加新的仍然只显示一行,我希望jtable显示所有值。这是我的代码。

public class EmployeeDetails extends javax.swing.JFrame {
String [] str = {"NAME", "ADDRESS", "CITY", "ZICODE"};
LinkedList<EmployeeDetails> linkedlist;
String name;
String address;
String city;
String zipcode;


public EmployeeDetails(String name, String address, String city, String zipcode) {
   this.name = name;
   this.address = address;
   this.city = city;
   this.zipcode = zipcode;
}

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

public String getName() {
    return name;
}

public void setAddres(String address) {
    this.address = address;
}

public String getAddress() {
    return address;
}

public void setCity(String city) {
    this.city = city;
}

public String getCity() {
    return city;
}

public void setZip(String zipcode) {
    this.zipcode = zipcode;
}

public String getZip() {
    return zipcode;
}

public String toString() {
    return name + " " + address + " " + city + " " + zipcode;
}

public EmployeeDetails() {
    initComponents();
}

//this is the method that does the adding
public void add() {
    name = nametxt.getText().trim();
    address = addresstxt.getText().trim();
    city = citytxt.getText().trim();
    zipcode = zipcodetxt.getText().trim();

    linkedlist = new LinkedList<>();
    linkedlist.add(new EmployeeDetails(name, address, city, zipcode));
    DefaultTableModel model = new DefaultTableModel(str, linkedlist.size());

    for(EmployeeDetails details : linkedlist) {
        System.out.println(details);
        model.addRow(new Object[]{details.getName()details.getAddress(), details.getCity(), details.getZip()});
    }

    employeeTable.setModel(model);
}
}
答案

看看你的add方法。它创建了一个新的LinkedList添加单个EmployeeDetails(从JFrame延伸!!这不会很好地结束),创建一个新的TableModel并添加(单个)EmployeeDetails到它然后将其应用到employeeTable ...为什么你有意外吗?

EmployeeDetails没有理由从基于UI的组件扩展,它为您提供零利益。 EmployeeDetails类也不负责以任何形式或形式管理UI。

面向对象开发的一个关键方面是责任分离。 EmployeeDetails应该管理员工的详细信息,没有别的...

public class EmployeeDetails {

    String name;
    String address;
    String city;
    String zipcode;

    public EmployeeDetails(String name, String address, String city, String zipcode) {
        this.name = name;
        this.address = address;
        this.city = city;
        this.zipcode = zipcode;
    }

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

    public String getName() {
        return name;
    }

    public void setAddres(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCity() {
        return city;
    }

    public void setZip(String zipcode) {
        this.zipcode = zipcode;
    }

    public String getZip() {
        return zipcode;
    }

    public String toString() {
        return name + " " + address + " " + city + " " + zipcode;
    }

}

虽然DefaultTableModel是一个强大而灵活的模型,但它也有点基础。对我来说,我更喜欢可以管理它所显示的对象的东西,并且可以更好地决定它们应该如何显示。对于模型可变状态(应该允许添加,删除甚至编辑各行?),这甚至更为关键?

在您的情况下,您希望能够至少添加新的EmployeeDetails对象...

public static class EmployeeTableModel extends AbstractTableModel {

    protected static String [] COLUMN_NAMES = {"NAME", "ADDRESS", "CITY", "ZICODE"};

    private List<EmployeeDetails> rows = new ArrayList<>(25);

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

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

    @Override
    public String getColumnName(int column) {
        return COLUMN_NAMES[column];
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        EmployeeDetails ed = rows.get(rowIndex);
        switch (columnIndex) {
            case 0: return ed.getName();
            case 1: return ed.getAddress();
            case 2: return ed.getCity();
            case 3: return ed.getZip();
        }
        return null;
    }

    public void add(EmployeeDetails ed) {
        rows.add(ed);
        int row = rows.size() - 1;
        fireTableRowsInserted(row, row);
    }

    public void remove(EmployeeDetails ed) {
        int row = rows.indexOf(ed);
        if (row < 0) {
            return;
        }
    }

    public void remove(int row) {
        if (row < 0 || row > rows.size()) {
            return;
        }
        rows.remove(row);
        fireTableRowsInserted(row, row);
    }
}

除了管理模型的状态之外,模型不做任何其他事情。我更复杂的解决方案可能有一个额外的模型/控制器来管理如何创建新对象以及更新或删除现有对象,但我会将其留给您添加。

最后,我们可以将它们拼接在一起......

public class TestPane extends JPanel {

    private EmployeeTableModel model = new EmployeeTableModel();

    public TestPane() {
        setLayout(new BorderLayout());
        add(new JScrollPane(new JTable(model)));

        JButton add = new JButton("Add");
        add.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int row = model.getRowCount();
                EmployeeDetails ed = new EmployeeDetails("Employee " + row, "@ " + row, "Metro" + row, Integer.toString(row));
                model.add(ed);
            }
        });
        add(add, BorderLayout.SOUTH);
    }

}

一个带按钮和桌子的简单面板,现在您可以混合添加按钮并观察您的员工名单增长...希望您有充足的资金;)

请确保您花时间阅读How to Use Tables,其中包含许多重要且相关的信息以及您可以使用的可运行示例

Runnable example...

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private EmployeeTableModel model = new EmployeeTableModel();

        public TestPane() {
            setLayout(new BorderLayout());
            add(new JScrollPane(new JTable(model)));

            JButton add = new JButton("Add");
            add.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int row = model.getRowCount();
                    EmployeeDetails ed = new EmployeeDetails("Employee " + row, "@ " + row, "Metro" + row, Integer.toString(row));
                    model.add(ed);
                }
            });
            add(add, BorderLayout.SOUTH);
        }

    }

    public static class EmployeeTableModel extends AbstractTableModel {

        protected static String [] COLUMN_NAMES = {"NAME", "ADDRESS", "CITY", "ZICODE"};

        private List<EmployeeDetails> rows = new ArrayList<>(25);

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

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

        @Override
        public String getColumnName(int column) {
            return COLUMN_NAMES[column];
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            EmployeeDetails ed = rows.get(rowIndex);
            switch (columnIndex) {
                case 0: return ed.getName();
                case 1: return ed.getAddress();
                case 2: return ed.getCity();
                case 3: return ed.getZip();
            }
            return null;
        }

        public void add(EmployeeDetails ed) {
            rows.add(ed);
            int row = rows.size() - 1;
            fireTableRowsInserted(row, row);
        }

        public void remove(EmployeeDetails ed) {
            int row = rows.indexOf(ed);
            if (row < 0) {
                return;
            }
        }

        public void remove(int row) {
            if (row < 0 || row > rows.size()) {
                return;
            }
            rows.remove(row);
            fireTableRowsInserted(row, row);
        }
    }

    public class EmployeeDetails {

        String name;
        String address;
        String city;
        String zipcode;

        public EmployeeDetails(String name, String address, String city, String zipcode) {
            this.name = name;
            this.address = address;
            this.city = city;
            this.zipcode = zipcode;
        }

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

        public String getName() {
            return name;
        }

        public void setAddres(String address) {
            this.address = address;
        }

        public String getAddress() {
            return address;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getCity() {
            return 

以上是关于jtable仅使用链表中的值填充一行的主要内容,如果未能解决你的问题,请参考以下文章

单击以打开 JComboBox 时,JTable 单元格失去价值

从数据库表中添加 JTable 中的值

在 jTable 中选择一行会产生错误

JTable中的换行,右对齐,自动调整行高

从 Postgres 数据库填充 jTable

使用从 VBA 代码派生的值填充表中的字段