2011-12-24 18 views
1

私は、特定のjtableが起動時に作成され、決して再構築されない大きなプロジェクトを持っています。表モデルはリフレッシュされ、さまざまなユーザーの操作に基づいて表が再描画されます。jtableからAbstractActionを削除します。

私は、カスタムのTableCellListenerクラスを追加して、AbstractActionとともにセルの変更に対応しました。テーブルにデータが最初に読み込まれるときに実行されるコードを次に示します。 ( 'firstLoad'チェックなしでは、テーブルが再描画されるたびに複数のアクションがアタッチされていました)。

if(firstLoad) { 
    AbstractAction action = new AbstractAction() 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      TableCellListener tcl = (TableCellListener)e.getSource(); 


        sayIt("Row:" + tcl.getRow()+" Column:" + tcl.getColumn()+ 
         " Old:" + tcl.getOldValue()+" New:" + tcl.getNewValue()); 

     } 
    }; 

    firstLoad = false; 
    TableCellListener tcl = new TableCellListener(table2, action); 
} 

TableCellListenerはロブCamickでhereを掲載するカスタムリスナーであると「sayIt」ビットは自分自身のデバッグのコードです。

これはすべて機能しますが、テーブルが再構築されるたびにリスナーを完全に削除して、最後に選択したセルの値を「覚えています」データは新しいものです。

私はかなり 'removePropertyChangeListener()'型の呼び出しがそれを行うだろうが、それはリスナーを引数として期待しており、それを見つける方法がわかりません。

+0

@camickrはすでに述べています:あなたが表示していないコードに何か間違っています。時間は1時間です – kleopatra

+0

はい。私は今問題を抱えている。また、選択リスナーを使用してセルの内容を編集用に自動的に選択します(ユーザはダブルクリックを継続しないようにします)、Camickrのテストコードが期待通りに機能するため、問題になる可能性があります。 – jeff

答えて

4

それはテーブルのデータが新しいですので、今は有効ではありません最後に選択したセルから値を「思い出す」されているため。

編集を開始して編集を開始するときに、現在の値を保存する必要があります。 TableModelを変更するときは、セルを編集しないでください。したがって、次のイベントを生成するときは、別のセルを選択して編集を開始したことを意味します。その場合は、新しいモデルの現在の値が必要です。私のためにうまくいく:

import java.awt.*; 
import java.awt.event.*; 
import java.util.Random; 
import java.io.*; 
import java.net.*; 
import javax.swing.*; 
import javax.swing.table.*; 

public class TableCellListenerTest2 
{ 
    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 

    public static void createAndShowGUI() 
    { 
     final JTable table = new JTable(TableCellListenerTest2.createModel()); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     JScrollPane scrollPane = new JScrollPane(table); 

     Action action = new AbstractAction() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       TableCellListener tcl = (TableCellListener)e.getSource(); 
       System.out.println(tcl.getOldValue() + " : " + tcl.getNewValue()); 
      } 
     }; 

     TableCellListener tcl = new TableCellListener(table, action); 

     JButton button = new JButton("Reset Model"); 
     button.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       table.setModel(TableCellListenerTest2.createModel()); 
      } 
     }); 

     JFrame.setDefaultLookAndFeelDecorated(true); 
     JFrame frame = new JFrame("Table Cell Listener"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(scrollPane); 
     frame.add(button, BorderLayout.SOUTH); 
     frame.setSize(400, 160); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static TableModel createModel() 
    { 
     Random random = new Random(); 

     DefaultTableModel model = new DefaultTableModel(10, 2); 

     for (int i = 0; i < model.getRowCount(); i++) 
      model.setValueAt("" + random.nextInt(100), i, 0); 

     return model; 
    } 
} 

あなたがもっと助けが必要ならあなたのSSCCEを投稿してください。

+0

SSCCEの内容が不明です。私は少し初心者のために謝ります。しかし、はい、あなたのコードは期待どおりに動作します。 「TableModelを変更すると、セルを編集してはいけません。 ...これは私が思う問題かもしれません。私は選択リスナを使用します(前述のように)ので、テーブルが再構築される前に行/列の選択を解除する必要がありますが、これまでのところ、 'table2.getSelectionModel()。clearSelection()'はコンパイルされますが、引き続きトラブルシューティングを行います。チップとテストコードをありがとう。 – jeff

+0

私はSSCCEを掲示しました。ウェブを検索して詳細を調べることができます。私はなぜSelectionLIstenerが問題を引き起こすのか分かりません。あなたの理論をテストするには、コードを変更してSelectionListenerを追加するだけです。 – camickr

+0

選択モデルと列モデルにリスナーがあったようです。列モデルのリスナーを削除してから、テーブルを再作成する直前に編集を取り消して、clearSelection()を実行してみてください。助けてくれてありがとう、正しい方向へ私を向ける。 (そしてSSCCEのヒント)。 – jeff

1

単純にTableCellListener、tcl、クラスフィールドを作成し、モデルが再構築されている場合はそれを削除してから、リスナーを再構築して再追加してください。

+0

ホバークラフト:速い返事をいただきありがとうございます。私はこれについて少し初心者ですので、少し実験して、それがどうなるか見てみましょう。ありがとう。 – jeff

0

ちょうどインスタンス変数にTableCellListenerインスタンスを覚えている:

// side effect: the tcl is added as PropertyChangeListener to the table 
// (bad design, IMHO) 
this.tcl = new TableCellListener(table2, action); 

// when the table data changes: 
if (this.tcl != null) { 
    table2.removePropertyChangeListener(this.tcl); 
} 
this.tcl = new TableCellListener(table2, action); 
+0

JBに感謝します。試してみましたが、「this.tcl」が好きではありません。 tclはどこかで最初に宣言する必要がありますか?私は何が分かるかを見ていきます。 – jeff

+0

this.tclの場合、これは実際にはtclがインスタンス変数であることを意味します。これはインスタンスで宣言する必要があります。 http://docs.oracle.com/javase/tutorial/java/javaOO/variables.html –

+0

-1リスナーを削除する必要はありません。OPが表示されていないコードで何か問題があります(@camickrとして既に編集の前に値を自動的に追跡するヘルパークラス_is_の全体的なポイント(これは...よく表の編集状態の変更を聞くことを意味する) – kleopatra

関連する問題