JTable 仅在我调用 GUI() 的新实例时刷新;

JTable refreshes only when i call new instance of GUI();

我有一个简单的 JTable 应用程序,仅当我在我的 buttonListener 方法中使用 'new GUI()' 时才添加数据。否则不起作用。我已经尝试在这段代码的每个地方使用每个 FireTable... 方法。还尝试了 mainFrame/mainPanel.repaint(); table.revalidate();

主要class

public class AddressBook {

public static void main(String[] args) {
    try 
    { 
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");  
        new GUI();
    }   
    catch(Exception e){ 
        System.out.println("GUI loading error..");
    }
}
}

GUI() class

    public GUI() {

    /** Main Frame, Panels, Borders */
    mainFrame = new JFrame("Address Book");
    mainPanel = new JPanel(new GridBagLayout());
    mainPanel.setBorder(BorderFactory.createEmptyBorder(borderOffset, borderOffset, borderOffset, borderOffset));   // up, left, down, right
    GridBagConstraints c = new GridBagConstraints();

    tablePanel = new JPanel();
    tablePanel.setLayout((new BoxLayout(tablePanel,BoxLayout.PAGE_AXIS)));

    buttonsPanel = new JPanel();
    buttonsPanel.setLayout((new BoxLayout(buttonsPanel,BoxLayout.PAGE_AXIS)));

    /** Head of table */
    model = new MyTableModel();
    table = new JTable(model);
    table.setPreferredScrollableViewportSize(new Dimension(500, 50));

    /** Heart of table */
    scrollPane = new JScrollPane(table);

    /** Title of app */
    titleLabel = new JLabel("Address Book");
    titleLabel.setFont(new Font(null, Font.PLAIN, 15));
    titleLabel.setForeground(Color.GRAY);

    /** Buttons */
    final int BUTTONS_WIDTH = 130;
    final int BUTTONS_HEIGHT = 40;
    addButton = new JButton("Add new person");
    addButton.setPreferredSize(new Dimension(BUTTONS_WIDTH, BUTTONS_HEIGHT));
    addButton.addActionListener(new addButtonListener());
    editButton = new JButton("Edit person");
    editButton.setPreferredSize(new Dimension(BUTTONS_WIDTH, BUTTONS_HEIGHT));
    editButton.addActionListener(new editButtonListener());
    deleteButton = new JButton("Delete person");
    deleteButton.setPreferredSize(new Dimension(BUTTONS_WIDTH, BUTTONS_HEIGHT));

    /** Separator */
    separatorH = new JSeparator(JSeparator.HORIZONTAL);
    separatorH.setPreferredSize(new Dimension(2,2));

    tablePanel.add(table.getTableHeader());
    tablePanel.add(scrollPane);

    buttonsPanel.add(addButton);
    buttonsPanel.add(Box.createRigidArea(new Dimension(0, 3)));
    buttonsPanel.add(editButton);
    buttonsPanel.add(Box.createRigidArea(new Dimension(0, 3)));
    buttonsPanel.add(deleteButton);

    /** Relocate compoments */
    c.gridx = 0;
    c.gridy = 0;
    c.insets = new Insets(0,2,2,0);
    c.anchor = GridBagConstraints.FIRST_LINE_START;
    mainPanel.add(titleLabel, c);

    c.gridx = 0;
    c.gridy = 1;
    c.insets = new Insets(0,0,0,0);
    c.fill = GridBagConstraints.HORIZONTAL;
    mainPanel.add(separatorH, c);

    c.gridx = 0;
    c.gridy = 2;
    c.insets = new Insets(10,0,0,0);
    mainPanel.add(tablePanel, c);

    c.gridx = 1;
    c.gridy = 2;
    c.insets = new Insets(9,10,0,0);
    mainPanel.add(buttonsPanel, c);

    /** Activate Main Frame and its properties */
    mainFrame.add(mainPanel);
    mainFrame.setBounds(200, 100, 0, 0);
    mainFrame.setResizable(true);
    mainFrame.pack();
    mainFrame.setVisible(true);
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public class addButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent a) {
        ((MyTableModel)model).setValueAt("cos", "test", "email", 123124);
        new GUI();
    }
}
}

MyTableModel class

class MyTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;

static private ArrayList<Person> personList = new ArrayList<Person>();
Object[][] persons = new Object[personList.size()][4];

int row;
int col;
static String name;
static String surname;
String email;
static int telephone;
private String[] columnNames = {"First Name",
                                "Last Name",
                                "E-mail",
                                "Telephone"};

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

@Override
public String getColumnName(int col) {
    return columnNames[col];
}

@Override
public int getRowCount() {
    return persons.length;
}

@Override
public Object getValueAt(int row, int col) {
    for(int i=0; i<personList.size(); i++) {
        persons [i][0] = personList.get(i).name.toString(); 
        persons [i][1] = personList.get(i).surname.toString(); 
        persons [i][2] = personList.get(i).mail.toString();
        persons [i][3] = personList.get(i).telephone; 
    }
    return persons[row][col];
}

public void fire(Object value, int row, int col) {
    persons[row][col] = value;
}

public void setValueAt(String n, String s, String e, int t){
    name = n;
    surname = s;
    email = e;
    telephone = t;
    Person person = new Person(n, s, e, t);
    personList.add(person);
    }
}

人class

public class Person {
String name;
String surname;
String mail;
int telephone;

public Person(String n, String s, String m, int t){
    name = n;
    surname = s;
    mail = m;
    telephone = t;
}
}

您的 table 模型已损坏:

  • ArrayList 和 2D 数组都有奇怪的数据重复。完全摆脱 2D 对象数组,只使用 ArrayList,一个应该 而不是 静态的字段。
  • 你需要给这个class一个addRow(Person p)方法,在那个方法中添加另一个Person到ArrayList,然后调用fireTableRowsInserted(...)方法,传入正确的数据。这是应该从您的添加 ActionListener 中调用的方法。
  • 或者让自己更轻松,根本不使用 ArrayList,而是扩展 DefaultTableModel,并使用它的方法。这会更简单、更容易,这就是我要做的。

例如:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.table.*;

public class TableFun extends JPanel {
    public static final String[] COL_NAMES = { "First Name", "Last Name", "E-mail", "Telephone" };
    private MyTableModel2 model = new MyTableModel2(COL_NAMES);
    private JTable myTable = new JTable(model);

    public TableFun() {
        JButton addPersonBtn = new JButton(new AddPersonAction("Add Person"));
        JPanel btnPanel = new JPanel();
        btnPanel.add(addPersonBtn);

        setLayout(new BorderLayout());
        add(new JScrollPane(myTable));
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private class AddPersonAction extends AbstractAction {
        public AddPersonAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String name = "John";
            String surname = "Smith";
            String address = "Foo Street";
            String telephone = "222-222-5555";
            model.addRow(new Person(name, surname, address, telephone));
        }
    }

    private static void createAndShowGui() {
        TableFun mainPanel = new TableFun();

        JFrame frame = new JFrame("Table Fun");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private class MyTableModel2 extends DefaultTableModel {
        public MyTableModel2(String[] columnNames) {
            super(columnNames, 0);
        }

        public void addRow(Person person) {
            Object[] rowData = new Object[4];
            rowData[0] = person.getName();
            rowData[1] = person.getSurname();
            rowData[2] = person.getMail();
            rowData[3] = person.getTelephone();            
            super.addRow(rowData);
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            if (getRowCount() > 0) {
                Object value = getValueAt(0, columnIndex);
                if (value != null) {
                    return value.getClass(); 
                }
            }
            return super.getColumnClass(columnIndex);
        }
    }
}

class Person {
    private String name;
    private String surname;
    private String mail;
    private String telephone;

    public Person(String n, String s, String m, String t) {
        name = n;
        surname = s;
        mail = m;
        telephone = t;
    }

    public String getName() {
        return name;
    }

    public String getSurname() {
        return surname;
    }

    public String getMail() {
        return mail;
    }

    public String getTelephone() {
        return telephone;
    }


}

请注意,如果您按照建议整理代码,您自己的代码也可以正常工作:

class MyTableModel extends AbstractTableModel {
    private static final long serialVersionUID = 1L;
    private ArrayList<Person1> personList = new ArrayList<Person1>();
    private String[] columnNames = { "First Name", "Last Name", "E-mail", "Telephone" };

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

    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }

    @Override
    public int getRowCount() {
        return personList.size(); //!! 
    }

    @Override
    public Object getValueAt(int row, int col) {
        Person1 person = personList.get(row);
        switch (col) {
        case 0:
            return person.name;
        case 1:
            return person.surname;
        case 2:
            return person.mail;
        case 3: 
            return person.telephone;
        }
        return "";
    }

    public void setValueAt(String n, String s, String e, int t) {
        Person1 person = new Person1(n, s, e, t);
        personList.add(person);
        int firstRow = personList.size() - 1;
        int lastRow = firstRow;
        fireTableRowsInserted(firstRow, lastRow);
    }
}