3

データを更新するサンプルを見つけましたが、DefaultTableModel を使用しています。独自の TableModel と独自のデータ クラスを作成したときに、データを JTable に追加しても更新されません。

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

編集2

ここで 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で正しいデータを更新するために、このメソッドをどこに置く必要がありますか?

4

1 に答える 1

4

あなたは非常に危険な2つのことをしています:

  • オーバーライドfireTableDataChanged()して空のメソッド本体を与えているため、スーパーのメソッドに含まれるすべての魔法がバイパスされ、本質的に価値のないメソッドになっています。
  • fireXXXChanged()モデルのデータを変更した後、どのメソッドも呼び出していません。

正反対のことをお勧めします。

  • オーバーライドしない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 にリスナーを追加する理由は何ですか?

編集2
あなたは次のように述べています:

firexxx メソッドの 1 つを実装する必要があると思いました。

クラスが TableModel インターフェイスを実装するのではなく、AbstractTableModel クラスを拡張する理由は、fireXXX(...)メソッドを含め、AbstractTableModel クラスが提供するすべての機能を取得するためです。それらは、データが変更されたことをモデルを使用するすべての JTables に通知するように既に配線されています。それらをオーバーライドする場合、特にそれらをオーバーライドしてスーパー メソッドをまったく呼び出さない場合は、この便利なコードが壊れてしまい、機能しなくなります。

LinkedList については、別のコレクション (すべてのサンプルのような配列ではありません) を使用してみました。

通常、ランダムな方法でデータにアクセスしたいので、ArrayList からより多くのお金を得ることができると思います。それにもかかわらず、コレクション変数は、必要に応じてコレクション オブジェクトのデータ型を変更できるように、おそらく List インターフェイス型である必要があります。

あなたの実装を使用すると機能しない理由がわかりません。

何かが「機能しない」と言い、それがどのように、またはなぜ機能しないのか、どのようなエラーが表示されるのかを説明せず、コードの実装を示さない場合、あなたは私たちの手を縛り、私たちがあなたを助けることができないようにします.効果的に。私たちの助けが必要な場合は、問題を理解できるように十分な情報を提供することを検討してください。これには、コードへの変更の表示、コンパイル エラーまたは例外メッセージの表示、問題の詳細の詳細な説明が含まれます。

編集 3
あなたの最新のコード反復では、あなたの addElement メソッドはすべてを行いますが、要素を追加します!

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

上記の方法では、LinkedList に何も追加しません。

于 2013-04-23T20:41:43.727 に答える