不要更新 JTable [英] Don't updating JTable

查看:14
本文介绍了不要更新 JTable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了更新数据的示例,但它使用的是 DefaultTableModel.当我创建我自己的 TableModel 和我自己的数据类时,当我将数据添加到 JTable 时,它​​不会更新.

I found sample with updating data, but it uses DefaultTableModel. When I created my own TableModel and my own data class, when I add data into JTable it doesn't update.

如何向 TableModel 添加侦听器?

How do I add a listener to my TableModel?

这是我的代码:

package by;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.LinkedList;

import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
public class DialogEg {
   private static void createAndShowGui() {
      MainWin mainPanel = new MainWin();
      JFrame frame = new JFrame("DialogEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
class MainWin extends JPanel {
   private String[] COL_NAMES = { "Last Name", "First Name" };
   //private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);
   private MyTableModel model = new MyTableModel();
   private JTextField lastNameField = new JTextField(15);
   private JTextField firstNameField = new JTextField(15);

   public MainWin() {
      final JPanel dataPanel = new JPanel();
      dataPanel.add(new JLabel("Last Name:"));
      dataPanel.add(lastNameField);
      dataPanel.add(Box.createHorizontalStrut(15));
      dataPanel.add(new JLabel("First Name:"));
      dataPanel.add(firstNameField);
      JPanel btnPanel = new JPanel();
      btnPanel.add(new JButton(new AbstractAction("Add Name") {
         @Override
         public void actionPerformed(ActionEvent arg0) {
            lastNameField.setText("");
            firstNameField.setText("");
            int result = JOptionPane.showConfirmDialog(MainWin.this, dataPanel,
                  "Enter Name", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if (result == JOptionPane.OK_OPTION) {
               String lastName = lastNameField.getText();
               String firstName = firstNameField.getText();
               Object[] dataRow = new String[] { lastName, firstName };
               //model.addRow(dataRow);
               Person person = new Person();
               person.setFirstName(firstName);
               person.setLastName(lastName);
               model.addElement(person);
               model.fireTableDataChanged();
            }
         }
      }));
      setLayout(new BorderLayout());
      JTable jtable = new JTable(model);
      //new JTable(model)
      jtable.setModel(model);
      add(new JScrollPane(jtable), BorderLayout.CENTER);
      add(btnPanel, BorderLayout.SOUTH);
   }
}
class MyTableModel extends AbstractTableModel {
    private String[] columnNames = {
            "Last name",
            "First name"
    };
    //private LinkedList<Person> data = new LinkedList<Person>();
    private LinkedList<Person> data = new LinkedList<Person>();
    public int getColumnCount() {
        return columnNames.length;
    }
    public int getRowCount() {
        return data.size();
    }
    public String getColumnName(int col) {
        return columnNames[col];
    }
    public Object getValueAt(int row,int col) {
        switch(col) {
        case 0: {
            return data.get(col).getLastName();
        }
        case 1: {
            return data.get(col).getFirstName();
        }
        default:
            return "";
        }
    }
    public void addElement(Person person) {
        data.add(person);
    }
    public void fireTableDataChanged() {

    }
}
class Person {
    String last_name;
    String first_name;
    public Person() {
    }
    public void setLastName(String l_name) {
        last_name = l_name;
    }
    public void setFirstName(String f_name) {
        first_name = f_name;
    }
    public String getLastName() {
        return last_name;
    }
    public String getFirstName() {
        return first_name;
    }
}

Edit2

这里我使用 addElement 方法:

Here i use method addElement:

 public void actionPerformed(ActionEvent arg0) {
    lastNameField.setText("");
    firstNameField.setText("");
    int result = JOptionPane.showConfirmDialog(MainWin.this, dataPanel,
          "Enter Name", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
    if (result == JOptionPane.OK_OPTION) {
       String lastName = lastNameField.getText();
       String firstName = firstNameField.getText();

       Person person = new Person();
       person.setFirstName(firstName);
       person.setLastName(lastName);
       //here i use add element 
       model.addElement(person);
    }
 }

这是我的表模型:

class MyTableModel extends AbstractTableModel {
    private String[] columnNames = {
            "Last name",
            "First name"
    };
    //private LinkedList<Person> data = new LinkedList<Person>();
    private LinkedList<Person> data = new LinkedList<Person>();
    public int getColumnCount() {
        return columnNames.length;
    }
    public int getRowCount() {
        return data.size();
    }
    public String getColumnName(int col) {
        return columnNames[col];
    }
    public Object getValueAt(int row,int col) {
        switch(col) {
        case 0: {
            return data.get(col).getLastName();
        }
        case 1: {
            return data.get(col).getFirstName();
        }
        default:
            return "";
        }
    }

    public void addElement(Person person) {
        int firstRow = data.size() - 1;
        int lastRow = firstRow;
        fireTableRowsInserted(firstRow, lastRow);
    }
}

当我添加任何信息时,但它没有更新.我必须把这个方法放在 jtable 中的哪个位置以进行正确的数据更新?

When i added any information, but it doesn't updated. Where i have to put this method for right data updating in jtable?

推荐答案

你正在做两件非常危险的事情:

You're doing two things that are very dangerous:

  • 您覆盖了 fireTableDataChanged() 并为其提供了一个空方法体,从而绕过了 super 方法包​​含的所有魔法,使其本质上成为一个毫无价值的方法,
  • 并且您在更改模型数据后没有调用任何 fireXXXChanged() 方法.
  • You're overriding fireTableDataChanged() and giving it an empty method body thereby bypassing all the magic that the super's method contains and making it essentially a worthless method,
  • and you're not calling any of the fireXXXChanged() methods after changing the model's data.

我建议你做完全相反的事情:

I recommend that you do the exact opposite:

  • 不要覆盖fireTableDataChanged()
  • 在更改数据时调用 fireXXX() 方法.

例如:

public void addElement(Person person) {
   data.add(person);
   int firstRow = data.size() - 1;
   int lastRow = firstRow;
   fireTableRowsInserted(firstRow, lastRow);
}

// public void fireTableDataChanged() {
//
// }

顺便说一句:为什么要向 JTable 或其 TableModel 添加侦听器?

As an aside: why do you want to add a listener to the JTable or its TableModel?

编辑 2
你说:

我认为我必须实现 firexxx 方法之一.

I thought that i have to implement one of the firexxx method.

您的类扩展 AbstractTableModel 类而不是实现 TableModel 接口的原因是为了获得 AbstractTableModel 类必须提供的所有优点,包括它的 fireXXX(...) 方法.它们已经连接到通知任何使用该模型的 JTables 数据已更改.如果您覆盖它们,特别是如果您覆盖它们并且不调用任何超级方法,那么您已经破坏了这段有用的代码,它将不再起作用.

The reason that your class extends the AbstractTableModel class rather than implementing the TableModel interface is to get all the goodies that the AbstractTableModel class has to offer, including its fireXXX(...) methods. They're already wired to notify any JTables that use the model that the data has changed. If you override them, and especially if you override them and don't call any of the super methods, you've broken this helpful code and it will no longer work.

至于 LinkedList,我想尝试使用另一个集合(所有样本中都没有数组).

As for LinkedList, i wanted to try use another collection(no array like in all samples).

由于您通常希望以随机方式访问数据,我认为您会从 ArrayList 中获得更多收益.无论如何,集合变量应该是 List 接口类型,以便您可以根据需要更改集合对象的数据类型.

Since you will usually want to access the data in a random way, I think you'd get more money out of an ArrayList. Regardless, the collection variable should probably be of List interface type so you can change the data type of the collection object as needed.

我不明白为什么当我使用你的实现时它不起作用.

I don't understand why when i use your implementation it doesn't work.

如果你说一些不起作用"并且你没有解释它是如何或为什么不起作用,你可能会看到什么错误,并且没有展示你的代码实现,你就束缚了我们的手,阻止我们能够以有效地帮助您.如果您需要我们的帮助,请考虑向我们提供足够的信息,以便我们了解您的问题.这将包括向我们展示对您的代码所做的任何更改、展示任何编译错误或异常消息,以及详细描述您的问题的细节.

If you say something "doesn't work" and you don't explain how or why it's not working, what errors you may be seeing, and without showing your code implementation, you tie our hands and prevent us from being able to help you effectively. If you need our help, consider giving us enough information to allow us to understand your problem. This will include showing us any changes to your code, showing any compilation errors or exception messages, and describing in detail the specifics of your problems.

编辑 3
在您最近的代码迭代中,您的 addElement 方法除了添加一个元素

public void addElement(Person person) {
    int firstRow = data.size() - 1;
    int lastRow = firstRow;
    fireTableRowsInserted(firstRow, lastRow);
}

你没有在上面的方法中向 LinkedList 添加任何东西!

You don't add anything to the LinkedList in the method above!

这篇关于不要更新 JTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆