2017-05-29 10 views
2

私はこれに関するさまざまな質問と回答を調査しましたが、うまくいくとは思われません。Java:子jDialogのデータ更新後にjTableをリフレッシュする

私はJavaを使い慣れていませんが、さまざまな言語での経験があり、これまでのところ(私が実験していることとの関連で)、アクションを構築しなければならないという点を除けばVBAのようです/あなたはすでにそこにあるはずだと感じている機能。これは、私自身が経験していないことだけではないかと期待しています。

私はNetbeans IDE 8.2とJava Runtime 1.80を使用しています。

jTableを含むjFrameを作成しました。 JTableのはそうのようなデータで構築されています:

public void showTasks(Boolean removeID) { 
    ArrayList<Tasks> list = tasksList("SELECT * FROM tasks"); 
    JTable table = jTable1; 
    DefaultTableModel model = (DefaultTableModel) jTable1.getModel(); 
    Object[] row = new Object[4]; 
    for(int i=0;i<list.size();i++) { 
     row[0]=list.get(i).getId(); 
     row[1]=list.get(i).getName(); 
     row[2]=list.get(i).getDesc(); 
     row[3]=list.get(i).getDate(); 
     model.addRow(row); 
    } 
    // Remove the 'id' column from the table view 
    if(removeID) { table.removeColumn(table.getColumnModel().getColumn(0)); } 
} 

この背後にある背景にはあまり関係ですが、基本的にtasksListは、ArrayListのを返す、SQL文にクエリを適用する機能です。私は4列の行を構築し、最初の列を削除して 'ID'が利用可能だが可視ではないようにする(この最終アクションはテスト/実験によって分離されている)。

MySQL DBを更新する行がクリックされたときにjDialogを開く別のコード領域があります。

問題

のJDialogを閉じたときに、私はテーブルデータ「リフレッシュ」するように関数呼び出しでスローするようにしようとしています。私はこの機能をテスト/デバッグするためにjFrame(jTableが存在する)にボタンを一時的に追加しました。

私はこれを動作させるようには思えません。私が達成した最も近いのは、showTasks(false)を再呼び出しすることですが、この明白な点は、データセットを置き換えるのではなく、更新されたデータを行に追加するだけです。私は100%確信していないすべての行を削除する場合は、それらを構築する 'ベストプラクティス'です。

私はJavaを使い慣れていて、欠陥のある考え方から見ているかもしれませんが、他の例を自分自身のものに適用することは困難です。私はまた、fireTableDataChanged()を実装する方法を見つけることができないようです。

確かにこれは私が過度に考えている単純な概念ですか?

編集 - 答え

の下に基づいてすべての行を削除して再度追加することが大丈夫であれば、このようなものは、正しくないと考えられる理由はありますか?

public void refreshTasks() { 
    DefaultTableModel model = (DefaultTableModel) jTable1.getModel(); 
    int row_total = model.getRowCount(); 
    for(int i= row_total -1;i>=0;i--) { 
     model.removeRow(i); 
    } 
showTasks(false); 
} 

編集:ボタンは、次のと今(ない不適切な場合は)正しく動作データ更新

を起動します

private DefaultTableModel parentTable;  // To store the parent 'Task' table model 

public void setStart(int user,DefaultTableModel table) { 

    this.txt_taskID.setText(Integer.toString(user)); // Converts the ID to a string 
    addData(user);   // Populates the fields 
    parentTable = table; // Sets parent TableModel to a variable 

} 

上記のコードは、親のJFrameから呼び出されたときダイアログが開き、テーブルモデルと編集したい行の「ID」が渡されます。テーブルモデルはparentTableに格納されています。

「保存」ボタンと「キャンセル」ボタンもあります。私はまだこれらを分離していますが、現在は '保存'だけでそれができます(SQLの更新など)。私はあなたがそれをやりたいかどうかはわかりませんが、私はつもり削除してリフレッシュするためのあなたに簡単な例を与える

private void btn_CancelActionPerformed(java.awt.event.ActionEvent evt) { 

    this.setVisible(false);   // Hide the dialog 
    Menu menu = new Menu();   // for accessing the tasksList function 

    parentTable.setRowCount(0);  // Clears the jTable data 

    // jTable data is then 'rebuilt' using the new data 

    ArrayList<Tasks> list = menu.tasksList("SELECT * FROM tasks"); 
    Object[] row = new Object[4]; 
    for(int i=0;i<list.size();i++) { 
     row[0]=list.get(i).getId(); 
     row[1]=list.get(i).getName(); 
     row[2]=list.get(i).getDesc(); 
     row[3]=list.get(i).getDate(); 
     parentTable.addRow(row); 
    } 
} 

答えて

2

を、私は100%ではありませんよすべての行を削除してからそれらを再構築するのが「ベストプラクティス」であることは確かです。

はい、おそらくベストプラクティスです。

完全に新しいTableModelを作成し、それをsetModel()メソッドを使用してテーブルに追加する以外の方法はありません。この方法の問題は、テーブルに設定したカスタムレンダラ/エディタをリセットすることです。あなたのコメントのための

model.setRowCount(0); 
+0

ありがとう - 間違いなく、現在の行を削除するより効率的な方法です。 何らかの理由で、私はまだjDialogから関数 'refreshTasks'を呼び出すことができません。printlnをデバッグメソッドとして使用することで、呼び出しが正しいことがわかります。テーブルモデルを修正する。 'refreshTasks'関数は、フォーム上のボタンを使用して意図したとおりに動作しますが、jDialogから離れているわけではありません。 –

+1

@ChrisJ、ダイアログを作成するときにTableModelへの参照を渡します。ユーザーが「保存」ボタンをクリックすると、TableModel内のデータが更新されます。テーブル自体が再描画されます。 – camickr

+0

ありがとうございました - 希望通りに動作するように管理し、あなたの提案を使用してコードを更新しました! –

-1

:私のボタンは、ダイアログを閉じ、以下の機能ごとに、JTableのをリフレッシュする[キャンセル] JTable多分それはあなたを助ける。

この次btnDeleteのJButtonは、テーブルから行を削除するためのJFrameに追加:原始的な方法で

btnDelete.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      int rowIndex = table.getSelectedRow(); 
      if(rowIndex > -1) { 
       int x = (Integer) table.getModel().getValueAt(rowIndex, 0); 
       if (conn.removeContact(x) == true) { //here add your own code like removeID 

        model.removeRow(rowIndex); 
        lblInfo.setText("Contact deleted successfully."); 
        model.fireTableDataChanged(); 
       } else { 
        lblInfo.setText("Cannot remove at this time!"); 
       } 
      }else { 
       lblInfo.setText("At first you need select a row with single click!"); 
       return; 
      } 
     } 
    }); 

とさわやかなテーブルのためにこれらの次のコードを:

btnRefresh.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      int rowCount = model.getRowCount(); 
      for (int i = rowCount - 1; i >= 0; i--) {//remove all rows 

       model.removeRow(i); 
      } 
      lblInfo.setText("Table datas updated successfully."); 

      for (Person p : conn.readAllContacts()) {//add all row from scratch 
       model.addRow(new Object[] { p.getId(), p.getName(), p.getLastName(), p.getPhone(), p.getEmail() }); 
      } 

     } 
    }); 
+0

感謝を:

のDefaultTableModelからすべての行を削除する最も簡単な方法は、単に使用することです。 データを削除して再構築することが効果的/許容可能な方法である場合、このようなより簡潔な人に欠陥がある/間違っている理由はありますか? (編集された質問を参照) –

+0

@ChrisJいいえ間違っているのではなく、最善の方法ではありません。 –

+0

このリンクを調べる場合は、次のURLを参照してください。http://docs.oracle.com/javase/7/docs/api/javax/swing/table/AbstractTableModel.html#fireTableDataChanged%28%29 –

関連する問題