删除一行后JTable没有重新绘制

时间:2013-10-16 07:33:46

标签: java swing jtable

AdminFrame.java

package com.sorcerok;

import java.awt.Color;

import java.awt.Font;
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.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;

public class AdminFrame extends JFrame {

    private JFrame frame;
    private JPanel panel;
    private JButton delete, change;
    private JTable usersTable;
    private static final int WIDTH = 510;
    private static final int HEIGHT = 300;
    private List<User> list;
    private MyTableModel model;

    public AdminFrame(JFrame frame) {
        super("Просмотр пользователей");
        setResizable(false);
        this.frame = frame;
        frame.setVisible(false);


        panel = new JPanel();
        frame.setResizable(false);
        panel.setLayout(null);

        delete = new JButton("Удалить");
        delete.setBounds(310, 230, 121, 30);
        change = new JButton("Изменить");
        change.setBounds(50, 230, 121, 30);


        list = new ArrayList<>(Authorisation.userMap.values());

        model = new MyTableModel(list);

        usersTable = new JTable(model);
        JTableHeader header = usersTable.getTableHeader();
        header.setForeground(Color.black);
        header.setFont(new Font("Times New Roman", Font.BOLD, 20));
        JScrollPane sp = new JScrollPane(usersTable);

        sp.setBounds(0, 0, 500, 90);

        panel.add(delete);
        panel.add(change);
        panel.add(sp);

        add(panel);
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void dispose() {
        frame.setVisible(true);
        super.dispose();
    }

    public void deleteFromTable() {

        delete.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int row = usersTable.getSelectedRow();
                if (getSelectedUser(row) != null) {
                    Authorisation.userMap.remove(getSelectedUser(row).getName());
                    list.remove(getSelectedUser(row));
                    System.out.println(list);
                    Registration.writeToFile();

                    model.removeRow(row);
                }
            }
        });

    }

    public User getSelectedUser(int index) {
        index = usersTable.getSelectedRow();
        if (isSelectedUser(index)) {
            String name = (String) usersTable.getValueAt(index, 1);
            return getUser(name);
        } else {
            return null;
        }
    }

    public boolean isSelectedUser(int index) {
        if (index < 0) {
            return false;
        } else {
            return true;
        }
    }

    public User getUser(String name) {
        for (User u : list) {
            if (name.equals(u.getName())) {
                return u;
            }
        }
        return null;
    }

    public class MyTableModel extends AbstractTableModel {

        private List<User> list;

        private MyTableModel(List<User> list) {
            this.list = list;
        }

        public void addTableModelListener(TableModelListener listener) {
        }

        public Class<?> getColumnClass(int columnIndex) {
            return String.class;
        }

        public int getColumnCount() {
            return 3;
        }

        public String getColumnName(int columnIndex) {

            switch (columnIndex) {
                case 0:
                    return "№";
                case 1:
                    return "Логин";
                case 2:
                    return "Пароль";
            }
            return "";
        }

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

        public Object getValueAt(int rowIndex, int columnIndex) {
            User user = list.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    return ++rowIndex;
                case 1:
                    return user.getName();
                case 2:
                    return user.getPassword();

            }
            return "";
        }

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

        public void removeTableModelListener(TableModelListener listener) {
        }

        public void setValueAt(Object value, int rowIndex, int columnIndex) {
        }

        public void removeRow(int row) {

            fireTableRowsDeleted(row, row);
            fireTableStructureChanged();
            System.out.println("Deleted by AbstractTableModel Table Model");

        }
    }
}

在其他类中调用方法

AdminFrame af = new AdminFrame(frame);
af.deleteFromTable();

当表中有很多元素并且有滚动时,即按下删除一行,该行立即从Arralist中删除但未从表中删除,如果您使用滚动,则记录会立即消失。没有这个方法model.removeRow(row)的相同函数;什么是争吵?

1 个答案:

答案 0 :(得分:2)

您的表格型号不支持TableModelListeners ,这就是为什么表格无法观察模型的变化。

您的 TableModel 应该通知 TableModelListeners 更改时(添加,删除或刷新行时)。
在表格上设置模型时,表格会将TableModelListener添加到观察模型。模型更改后,会触发TableModelEvent(通过在所有侦听器上调用tableChanged(TableModelEvent))。然后,JTable会收到此通知并重新验证并重新绘制表格内容以适应更改。

在您的具体案例中: 您已覆盖add|removeTableModelListener()方法,因此无法注册任何侦听器。只需在模型上删除这两个方法,然后让这些方法的DefaultTableModel实现处理它。