質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

1回答

3757閲覧

Java Swing getSelectedRowメソッドの「-1」を返す条件

Akihito_Jv

総合スコア64

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2017/07/05 06:30

###前提・実現したいこと
商品管理システムでMysqlとJTableを使用して、システムを作成しております。
その中で、商品の情報を修正や、削除を行い、
JTableを更新(再度情報取得後、Modelに格納、ModelをJTableにセット)を行った後、
getSelectedRowが「-1」を返す。
そのため、JTableを更新((再度情報取得後、Modelに格納、ModelをJTableにセット)した後でも、getSelectedRowがちゃんと選択した行の値を返すように修正したい。

###発生している問題・エラーメッセージ

java.lang.ArrayIndexOutOfBoundsException: -1

###該当のソースコード

諸事情により、割愛させていただきます。

###試したこと
エラーに記載されているのは、配列が不正なインデックスを使用して、
エラーが表示されておりますが、
デバッグで確認したところ、getSelectedRowで-1が返されており、
それが原因で発生していることがわかりました。
getSelectedRowで-1が返されている時は、行を選択していない時と
のみリファレンスで記載されておりますが、
それ以外は記載されていませんでした。
また、再描画イベントを実施後、本エラーが発生するので、
原因は再描画ととらえております。

###補足情報(言語/FW/ツール等のバージョンなど)
Java
Eclipse 4.6NEON

要点としまして、
1.Tableを更新(SetModel等)を行った後、getSelectedRowは判定されないのでしょうか。
2.判定されない場合、対処法としてどのような処理が考えられるでしょうか。
3.このような症状の場合の対応としては、どのように対処していくのか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Model全体を置き換えるのではなくModelの変更(追加・削除など)であれば、元の選択行を削除しない限り、「選択していた行がModelの変更前後でかわらないように自動的に選択位置が補正される」というのがJTable(あるいはJTableのListSelectionModel)の振舞いと思います。一方Model全体を設定しなおした場合、それ以前に選択していた行は無効になると思います。「以前に選択していた行」と「新たに設定されたモデルの中の同じインデックスのレコード」には何の関係もないと解釈するからだと思います。またその解釈は自分には自然に思えます。

もしModel全体を置き換え、かつユーザー操作なしに最初から特定の行を選択状態にしたいなら、アプリケーション固有の判断に従って「新たに設定したModelのどの行を選択状態にしたいのか」をJTableへ教えてやる必要があると思います。具体的にはModelを設定した直後にJTableのListSelectionModelオブジェクトに対してsetSelectionIntervalメソッドなどを用いればよいでしょう。


訂正:上記回答は質問者さんの問題とはずれた内容だったようです。追加された情報に基づき改めてコメントします。

javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:648)

at パッケージ名.クラス名.mouseClicked(クラス名.java:496)

「行が選択された際の振る舞い」をMouseListener(MouseClicked)で行おうとしているように見えます。何に対してのMouseClickedなのか、そのハンドラーで「選択状態でないにもかかわらずなぜTableModel#getValueAtを呼び出そうとしているのか」コードがないので不明ですが、やはりそのあたりに問題があるように思えます。

ところで、選択状態の変化を捉える目的ならMouseClickedではなくListSelectionListenerを使うべきと思います。

投稿2017/07/05 07:10

編集2017/07/06 02:03
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Akihito_Jv

2017/07/05 07:58

>KSwordOfHaste様 いつもお世話になっております。 Modelの振る舞いについて、ご教示頂きありがとうございます。 わたくしの考えも同様の認識で御座います。 ですが、Modelを置き換えたのち、ユーザからTableを選択してもらい、 対象の商品への「アクション」を起こしてもらいたいため、 最初から特定の行を選択するのではなく、 再度、addMounseListenerを走らせたいです。 その中で、getSelectedRowメソッドを動かし、行の取得ひいては その商品の情報を配列へ格納したいと存じます。
KSwordOfHaste

2017/07/05 08:39 編集

> わたくしの考えも同様の認識 えーと・・・?問題を勘違いしていたようです。自分でgetSelectedRow()を呼び出しているのではなく、swingのruntime内部でgetSelectedRow()が呼び出されていてそれが-1となったときにエラーを起こしてしまうということでしょうか? 問題がどこにあるかつかみかねています。コードの提示が無理でも例外発生時のスタックトレースを明記していただけると状況がつかみやすくなるかも知れません。
Akihito_Jv

2017/07/05 08:56

>> わたくしの考えも同様の認識 >えーと・・・?問題を勘違いしていたようです。自分でgetSelectedRow()を呼び出しているのではなく、 >swingのruntime内部でgetSelectedRow()が呼び出されていてそれが-1となったときにエラーを起こして >しまうということでしょうか? ご認識の通りで御座います。 説明不足お詫びいたします。 処理フローとスタックトレースを記載させていただきます。 テーブル表示⇒ユーザがテーブルを選択⇒ 他画面のTextFieldの初期値として、選択した商品の情報を設定 ⇒情報修正、削除等の処理をユーザ選択し、実行ボタンを押下 ⇒(ActionListener)DBへ登録、DBから情報を取得、Modelへ情報格納、TableにModelをset ⇒テーブル表示(削除操作の場合、DELETE_FLGが1となりはじかれるため、表示されない、情報変更は情報取得により、変更されております。) ⇒ユーザが商品を選択⇒エラー スタックトレース(一部クラス名称を変更しております。) java.lang.ArrayIndexOutOfBoundsException: -1 at java.util.Vector.elementData(Vector.java:734) at java.util.Vector.elementAt(Vector.java:477) at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:648) at パッケージ名.クラス名.mouseClicked(クラス名.java:496) at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:270) at java.awt.Component.processMouseEvent(Component.java:6536) at javax.swing.JComponent.processMouseEvent(JComponent.java:3324) at java.awt.Component.processEvent(Component.java:6298) at java.awt.Container.processEvent(Container.java:2236) at java.awt.Component.dispatchEventImpl(Component.java:4889) at java.awt.Container.dispatchEventImpl(Container.java:2294) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4534) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466) at java.awt.Container.dispatchEventImpl(Container.java:2280) at java.awt.Window.dispatchEventImpl(Window.java:2746) at java.awt.Component.dispatchEvent(Component.java:4711) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) at java.awt.EventQueue.access$500(EventQueue.java:97) at java.awt.EventQueue$3.run(EventQueue.java:709) at java.awt.EventQueue$3.run(EventQueue.java:703) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.awt.EventQueue$4.run(EventQueue.java:731) at java.awt.EventQueue$4.run(EventQueue.java:729) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:728) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 情報少ない中、ご検討感謝致します。 なにとぞよろしくお願いいたします。
Akihito_Jv

2017/07/06 02:07

KSwordOfHastesama様 お世話になっております。 昨日ご質問させていただきました件、解決致しましたので、ご報告させていただきます。 本問題の背景として、 再描画の処理に問題が御座いました。 その再描画時に新しくTableを作成していたことが本事象を発生させる原因で御座いました。 そのため、newする処理を抜き、再度試したところ 「getSelectedRow」メソッドで問題なく行が取得されることを確認いたしました。 >ところで、選択状態の変化を捉える目的ならMouseClickedではなく >ListSelectionListenerを使うべきと思います。 こちらで御座いますが、 ListselectionListenerのリファレンスを確認いたしましたが、 「選択範囲内の値が変更されたときに呼び出されます。」 との記載があり、 MouseClickedは 「コンポーネント上でマウスボタンをクリック (押してから離す) したときに呼び出されます。」 との記載で、本システムでは、こちらを採用した背景があります。 テーブル上は表示のみを行っており、直接入力して変更するものではないためで御座います。 もしかすると、KSwordOfHastesama様のお話を考えますと それを差し引いても、ListselectionListenerで実装しても同様の結果が得られるのかもしれません。 今後も、本システムはUpdate予定となっておりますので、 リファクタリングの機会があれば、一度試させていただきます。 本当に、どうしょうもない状態だったので、ご相談に乗っていただきありがとうございました。 またご縁が御座いましたら、なにとぞよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問