Don't updating JTable

て烟熏妆下的殇ゞ 提交于 2019-12-21 05:36:16

问题


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.

How do I add a listener to my TableModel?

Here is my code:

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

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);
    }
 }

There is my table model:

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);
    }
}

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


回答1:


You're doing two things that are very dangerous:

  • 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:

  • Don't override fireTableDataChanged()
  • Call the fireXXX() methods when you change data.

For example:

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

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

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

Edit 2
You state:

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

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.

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

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.

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);
}

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



来源:https://stackoverflow.com/questions/16178747/dont-updating-jtable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!