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

查看:69
本文介绍了不要更新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()方法.
  • Don't override fireTableDataChanged()
  • Call the fireXXX() methods when you change data.

例如:

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
您声明:

Edit 2
You state:

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

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

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

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中获得更多收益.无论如何,collection变量可能应该是List接口类型,以便您可以根据需要更改collection对象的数据类型.

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
在最近的代码迭代中,除了添加元素

Edit 3
In your most recent code iteration, your addElement method does everything but add an element!

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天全站免登陆