• 締切済み

TableModelListener 通知出し方

他の質問の補足に書いたものを質問にしました JButtonなどのイベントは,addActionListenerしたコンポーネントがアクションを起こした時に、ActionListenerをimplementsしたクラスのActionPerformedメソッドが呼び出されるのはわかるんですが。 TableModelListenerがわからなくて、 ~JTableのインスタンスを生成したクラス~ table.getModel().addTableModelListener(); ~別のクラス~ public class TableModel extends AbstractTableModel implements TableModelListener{ //いろいろ @Override public void tableChanged(TableModelEvent e) { //ここに書いた処理が更新時に行われる } } (ここまでがあってるのかわかりませんが)ここまでは来るのですが、更新のGOサインをだれが出すのかがよくわかんなくて、今作っているプログラムではドラッグされた時に更新したいんです。 ただfireTableChangedをドラッグの処理のところに貼るんじゃもちろんダメなんでしょうけど(TдT)

  • Java
  • 回答数6
  • ありがとう数7

みんなの回答

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.6

#5の段階で、何が問題になっているのか、ちょっとわかりにくいのですが、 とりあえず、先にもいった通り、問題点は順に分けて解決してください。 一緒にしてしまうと、何が悪いのかわかりにくくなります。 ですので、JTableの話はこれだけで完結するように考えましょう。 テストするのも、ドロップと組み合わせるのではなく、独立して動くようにしてテストするのが望ましいです。 ただし、ドロップの処理がきちんとテスト済みで、動作が保証されているのならこの限りではありません。 で、今の問題点はなんでしょうか? すみませんが、もう一度お願いします。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.5

fireDataChangedなら全部を再表示すると思いますので、 まあ、無難かもしれません。 ただ、必要以上の再表示は、画面がちらついたりしますので、 できるなら適切なものを選ぶべきです。

domybestatall
質問者

お礼

ListPane.table.getModel()).fireTableDataChanged(); と入力したら~にキャストみたいなクイックフィックスが出て ((AbstractTableModel) ListPane.table.getModel()).fireTableDataChanged(); になって ListPane.table.revalidate(); ListPane.table.repaint(); をtableChangedに入れたらちゃんと動作するようになりました!!!!!!!!! そりゃただfireTableDataChanged();って入力しただけじゃエラーになるわけですね(笑)

domybestatall
質問者

補足

そこでなんですが、呆れられるかもしれないのですが、fireTableDataChanged()の書き方がわからないんです Transferhandlerをextendsしてあるクラスの中で(関係ないかもしれませんが)、ドロップされたファイルの情報をArrayListに入れた後に fireTableDataChanged(e); と書き込んでもeのところに新しいeというフィールドやらローカル変数やらを作成するというクイックフィックスが出てしまうんです。 何がどう間違ってそうなってしまっているのか、どうすればいいのか教えていただけないでしょうか 付け焼き刃でこんな複雑なことをやろうとしている自分が悪いのは重々承知していますが、ぜひよろしくお願いします。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.4

入れ違いで#2に補足が入ったようですが、#3が回答になると思います。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.3

ここまでが理解できたと仮定します。 さて、やりたいことは、ドロップして追加されたファイルの情報を テーブルに追加表示する、ということでだったかと思います。 おわかりだとは思いますが、こういった処理を一気に考えたり作ったりしてはいけません。 必ず手順を分けて考えて作ります。 今回だと、 ・ファイルのドロップを受け取る ・ファイルの情報を取得する ・テーブルに表示する(TableModelに追加する) という処理を別に考える必要があります。 とりあえず、テーブルの更新の話を続けます。 既にfire~の原理はわかったと思います。 ではどのメソッドを使うのかということですが、 なにをしたいかによって変わってきます。 例えば、追加されたものだけをテーブルの末尾の行に追加するだけ、 ということであれば、fireTableRowsInsertedで最終行を指定すればいいでしょう。 そうではなく、ドロップされたのをきっかけにして、表示されている内容を再度チェックし、 再表示するというのであれば、既に表示済みのデータが更新せれたことを通知する必要がありますので、fireTableRowsInsertedでは足りません。 この場合はfireTableDataChanged()あたりが適切かもしれません。 fireTableStructureChanged() を使うと、ユーザーが変えた列幅等がリセットされますので 注意が必要です。 とりあえず、ここまでで、反応を待ちたいと思います。

domybestatall
質問者

補足

ファイルの情報を取得してArrayListに入れるまでは書いてあって、後は更新するだけなんです。 ファイルの数に応じて行数も増減したいのですがそれもfireDataChanged()できるなら、中身が増えたり減ったりする予定なのでfireTableDataChanged()だと思います。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

>JButtonが押されると、押されたよーって通知が勝手に出るのを >JTableではfire~で通知を出すっていうことでいいでしょうか たぶん理解されたんだと思います。 一応、JButtonと比較しておくと、 ・JButtonの場合  クリックする  JButton →通知(actionPerformed)→リスナー という感じ。 一方 ・JTableの場合  TableModelに変更があったため、fire~を発行  AbstractTableModel→通知(tableChanged)→リスナー(JTable) とこんな感じです。 なお、前回もいいましたが、これはあくまでも「イメージ」であり、 「流れ」というか「仕組み」の概略的なものです。 実際のソースをみても全く同じにはなっていないはずです。 (例えばJTable自体にはTableModelListenertは実装されていないはずです。  恐らく、インナークラスか何かで受けているでことでしょう)

domybestatall
質問者

補足

fire~の発行の仕方がわかんないんです。。。 ただfireTableChanged(e);と書いても「eはなんですか?」ってなってしまって

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.1

別の質問にしなくてもよかったのですが。。。 だいぶ、こんがらがっているようですね(^^; まずリスナーの登録ですが、JTableが勝手にやるので、 あなたが特に行う必要はありません。 イメージとしては、次のようになっています。 class JTable implements TableModelListener { public void setModel(TableModel model){ this.mode = model; mode.addTableModelListener(this); } public void tableChanged(TableModelEvent e) { //テーブルの表示 } } class AbstractTableModel { TableModelListener lis; public void addTableModelListener(TableModelListenet lis){ this.lis = lis; } protected void fireTableCellUpdated(int row, int column){ lis.tableChanged(new TableModelEvent(this, row,row, column)); } } ※あくまでもイメージで、実際にはこれと同じ構造にはなっていません ここまではよろしいでしょうか? 次に、「なぜfire~を行う必要があるか」を再度確認のため説明しておきます。 データ(TableModel)に変化があったとき、なぜJTableが変化を反映して表示できるかということですが、 JTableはTableModelを常に監視しているわけではありません。 それは、javaの作りからいって非常に難しいです。 ではどうするかというと、データに変化があったときに、データ側(TableModel)から表示(JTable)に 変化があった旨を通知します。 表示側は、この通知をきっかけにして、データを再表示し変更を反映します。 したがって、この通知を行わないと、データと表示との間で不整合がおこります。 この通知をするのがAbstractTableModelの「fire~」メソッドです。 まずは、ここまでを整理してください。

domybestatall
質問者

補足

JTableには元からaddTableModelListenerされてるんですね( ゜д゜)ハッ! JButtonが押されると、押されたよーって通知が勝手に出るのを JTableではfire~で通知を出すっていうことでいいでしょうか

関連するQ&A

  • ActionListener について

    JFrame の上に JPanel があり、JPanel の上に JButton があるとします。 JButton が押されたことを JFrame に知らせるにはどうしたらいいでしょうか。 わかるところまで書いてみました。 class MyFrame extends JFrame implements ActionListener { MyPanel myPanel = new MyPanel(); MyFrame() { myPanel.addActionListener(this); add(myPanel); } public void actionPerformed(ActionEvent e) { System.out.println("The button on the MyPanel was pressed!"); } public static void main(String[] args) { new MyFrame(); } } class MyPanel extends JPanel implements ActionListener { JButton button1 = new JButton(); MyPanel() { button1.addActionListener(this); add(button1); } public void actionPerformed(ActionEvent e) { } }

    • ベストアンサー
    • Java
  • javaで起こったバグ?!

    私が普段プログラムを書いてコンパイルすると、ほぼ確実といってもいいくらいにおかしなことが起きます。 ボタンを配置して、処理を書きます(ここではJTableが現れるという処理にします)、そしてコンパイルします、コンパイルは通ります、ウィンドウが現れます、ボタンを押したら処理が起きてJTableが現れるはずなのですが、ボタンを押すとコマンドプロンプトでわけわからん英語や数字が現れます(出力される)。 自分の書いたプログラムをeclipseでコピペしても、問題はありませんでした。 コマンドプロンプトを一度消して、直ったプログラムもあります。また、その逆に何度やっても直らないものもあります。 ↓私の書いたプログラムです。おかしいところ等がありましたらご指摘下さい。また解答者様のPCでコピペして、試してみて下さい。 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Sukejuru extends JFrame implements ActionListener { JPanel p; public static void main(String args[]) { Sukejuru ske = new Sukejuru(); ske.setBounds(200,200,600,300); //大きさ&ウィンドウの位置 ske.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//クローズ ske.setVisible(true); } Sukejuru() { super("Myスケジュール"); JPanel p = new JPanel(); p.setBackground(Color.green); add(p); JButton b1 = new JButton("一月"); b1.addActionListener(this); b1.setActionCommand("b1"); p.add(b1); JButton b2 = new JButton("二月"); b2.addActionListener(this); b2.setActionCommand("b2"); p.add(b2); JButton b3 = new JButton("三月"); b3.addActionListener(this); b3.setActionCommand("b3"); p.add(b3); } public void actionPerformed(ActionEvent e) { JTable table = new JTable(5,5); JScrollPane sp = new JScrollPane(table); p.add(sp); } }

    • ベストアンサー
    • Java
  • actionListenerについて

    ど素人です 改行の関係でimportは省略してます labelにActionListenerが登録できないのですが、なぜでしょうか class test extends JFrame{ test() { getContentPane().setLayout(new FlowLayout()); JLabel label = new JLabel("てすと"); JButton b1 = new JButton("OK"); b1.addActionListener(label); getContentPane().add(b1); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("JButtonTest"); setSize(200, 100); setVisible(true); } public static void main(String[] args) { new test(); } } class LetLabel extends JLabel implements ActionListener{ public void LetLabe(){ } public void actionPerformed(ActionEvent ae){ } }

    • ベストアンサー
    • Java
  • JTableのイベント取得方法

    お世話になります JTableにDBからの検索結果を表示させて、そのセルを編集したときに編集したセルに対してアップデート等の処理を行いたいのですが、セルが編集されたときのイベントを取得したいのですがうまくいきません。 具体的なソース等のアドバイスよろしくお願いします。 ---ソース--- TableEditListener lisner = new TableEditListener() tableModel = new AbstractTableModel(vecResult,clmName); tableModel.addTableModelListener(lisner); table = new JTable(tableModel); 内部クラス class TableEditListener implements javax.swing.event.TableModelListener{  public TableEditListener(){ } public void tableChanged(TableModelEvent e){ System.out.println("セルの編集をしました。"); } } 現在以上のようなソースになっています。 よろしくお願いします。

    • ベストアンサー
    • Java
  • ボタンの複数割り当てについて

    public class TestButton extends Applet implements ActionListener {      Button bt1,bt2,bt3;      public void init()      {           bt1 = new Button("red");           add(bt1);           bt2 = new Button("blue");           add(bt2);           bt3 = new Button("yellow");           add(bt3);           bt1.addActionListener(this);       } java初心者です。アプレットで上のようにボタンを作ります。それぞれが押された時に、red,blue,yellowが表示されるようにしたいのです。ActionListenerをインプリメントしているので、      public void actionPerformed(ActionEvent ae) をオーバーライドする必要がありますが、そこで質問です。 ボタンを3種類別々に関連づけるには、actionPerformed内をどのように記述したらよいでしょうか?また、init内はこれだけでいいんでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • javaGUIインスタント変数とローカル変数

    過去質問で、「javaで起こったバグ?!」という質問をした者です。 親切な回答者の方々のおかげで、理解することが出来ました。 あのとき質問に答えてくださった回答者の方々本当にありがとうございます。 本題に戻ります。 この↓プログラムなんですが、インスタント変数pとJPanel p;で定義した、ローカル変数(おそらく。別の変数だよ、という意見がありましたら、ご指摘ください)は別物で、デバッグを行ったらローカルのp の中身は、null(何も入ってない)といわれてしまいました。 プログラム↓ import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Sukejuru extends JFrame implements ActionListener { JPanel p; public static void main(String args[]) { Sukejuru ske = new Sukejuru(); ske.setBounds(200,200,600,300);//大きさ&ウィンドウの位置 ske.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//クローズ ske.setVisible(true); } Sukejuru() { super("Myスケジュール"); JPanel p = new JPanel(); p.setBackground(Color.green); add(p); JButton b1 = new JButton("一月"); b1.addActionListener(this); b1.setActionCommand("b1"); p.add(b1); JButton b2 = new JButton("二月"); b2.addActionListener(this); b2.setActionCommand("b2"); p.add(b2); JButton b3 = new JButton("三月"); b3.addActionListener(this); b3.setActionCommand("b3"); p.add(b3); } public void actionPerformed(ActionEvent e) { JTable table = new JTable(5,5); JScrollPane sp = new JScrollPane(table); p.add(sp); } } ボタンを押してもJTableは、現れません。押すとコマンドプロンプトでは次のようなエラー?が出ます。↓ Exception in thread"AWT-EventQueue-0"java.langNullPointerException JPanel p(インスタント変数p)にコンポーネント(ローカル変数p)を貼り付けるには、どう記述すればいいのでしょうか?

    • ベストアンサー
    • Java
  • JPanelからJFrameへの変数にアクセス

    JFrameは2つのJPanelを持つ場合JPanelでボタンが押された場合もう1つのJPanelへ影響を及ぼす場合どうしたらいいですか? class FrameTest extends JFrame {   PanelTest1 pt1 = new PanelTest1();   PanelTest2 pt2 = new PanelTest2();   pt1.setBoudns(...);   pt2.setBoudns(...);   add(pt1);   add(pt2); } class PanelTest1 extends JPanel implements ActionListener {   JButton btn = new JButton("Panel2のaを変える");   //ソース省略します。   //この辺りでbtnをsetBoundsしてpanelに乗せてaction...   public void actionPerformed(ActionEvent e)   {     //★質問はどうやってここでPanelTest2の変数を変えるか?   } } class PanelTest2 extends JPanel {   public int a; }

    • ベストアンサー
    • Java
  • Javaのメモリ・リークについて

    Javaのメモリ・リークについて 以下のコードはスレッド内で、無限ループをしています。 コンストラクタで呼び出し、ずっとこのままにしておいてもフリーズするか否かが知りたいです。 (jconsole.jarというツールがありますが、まだ理解に至っておりません。) ご存知の方がおられましたら教えてください。 よろしくお願いいたします。 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class ActioneventRoopTest extends JFrame implements Runnable, ActionListener { JButton start = new JButton(); JButton change = new JButton("切り替え"); Boolean flag = true; public static void main(String[] args) { new ActioneventRoopTest(); } public ActioneventRoopTest() { change.addActionListener(this); start.addActionListener(this); this.add(change); this.pack(); this.setVisible(true); Thread thread = new Thread(this); thread.start(); } public void actionPerformed(ActionEvent e) { if (e.getSource() == change) { if (flag) { flag = false; } else if (!flag) { flag = true; } } } public void run() { while (true) { while (flag) { System.out.println("リンゴ"); } while (!flag) { System.out.println("ミカン"); } } } }

    • ベストアンサー
    • Java
  • Buttonを配列とすることができるでしょうか

    swingをつかってJFrameに多数のJButtonをつくりました。どのボタンがクリックされたかを知りたいのです。 そのためにJButtonを配列として、宣言したところ、コンパイルは通るようですが、実行時にエラーとなります。 JButton[] button; と宣言してリスナーを次のように登録し、使いたいのです。 int i; for(i=0;i<80;i++){ button[i].addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ loc=i; } } } このようにすれば、クリックされたときに、iの値をしらべれば、どのボタンがクリックされたかわかるとかんがえたのですが。実行時にエラーとなってしまいます。なにか良い方法はありませんか。

  • イベントの宣言について

    public class J_applet extends Applet implements ActionListener ,ItemListener { と宣言したところ、 J_applet は abstract でなく、java.awt.event.ActionListener 内の abstract メソッド actionPerformed(java.awt.event.ActionEvent) をオーバーライ ドしません。 とエラーがでました。 インポート宣言はきちんとしました。 上記のような書き方はもしかして出来ないんでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう