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

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

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

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

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

Q&A

解決済

1回答

3525閲覧

javaFXのListViewにおけるセルのインデックスの取得方法

ta_ko

総合スコア13

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

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

0グッド

0クリップ

投稿2016/07/01 09:29

編集2016/07/01 12:53

###前提・実現したいこと
javaFXのListViewで、カーソルを合わせたセルのインデックスを取得する。
###発生している問題
listview.getFocusModel().getFocusedIndex()を用いてセルのインデックスを取得したいのですが、
一度セルのpaneをクリックすればインデックスを取得できるのですが、
paneに設置してあるbuttonが一度セルをクリックせずに押すときちんと動作しません
(セルのインデックスを用いて動作するため)。
なのでセルの上をホバーしたときにインデックスを取得できるようにしたいです。
このような方法はあるのでしょうか。
私の考えている方法で実装できなくても他の方法で
セルのpaneをクリックすることなくインデックスを取得できる方法があるようでしたら
教えてくださるとうれしいです。

~~追記~~
スクリーンショットを載せます。セルの内容は青い四角で隠しています。
カーソルをセルの上でホバーすると出力に
listview.getFocusModel().getFocusedIndex()
が表示されるようにしています。
セルが黒くなっているのがカーソルが合わさっているセルで、
セルが青くなっているのがクリックして選択したセルです。

イメージ説明
↑今一番上のセルにマウスを合わせていて、右の出力では‐1になっておりセルの選択ができていません。

イメージ説明
↑この画像では一番上のセルをクリックして選択しています。
右の出力が0になっているため、一番上のセルの情報は取得できているのですが
他のセルにカーソルを合わせても0が出力されてしまいます。(他のセルをクリックしてインデックスを取得できていないため)

~~追記~~
ボタン周りのコードです。

lang

1@FXML 2Button button; 3 4@FXML 5static ListCell cell; 6 7@FXML public void sampleButton(ActionEvent e){ 8button.setOnAction(new EventHandler<ActionEvent>() { 9@Override public void handle(ActionEvent e) { 10// getParentを使い、このボタンが含まれるListCellを遡って探す 11Node n = (Node)(e.getSource()); 12while(n != null && !(n instanceof ListCell)) { 13n = n.getParent(); 14} 15if(n != null) { 16// 見つかった場合、 17cell = (ListCell) n; 18System.out.println(cell.getIndex());// ListCell#getIndexで番号が取れる 19num = cell.getIndex(); 20} 21} 22}); 23}

lang

1<?xml version="1.0" encoding="UTF-8"?> 2 3<AnchorPane id="AnchorPane" fx:id="cell" maxHeight="-1.0" 4maxWidth="-1.0" minHeight="-1.0" minWidth="-1.0" prefHeight="90.0" 5prefWidth="500.0" styleClass="cell" xmlns:fx="http://javafx.com/fxml/1" 6xmlns="http://javafx.com/javafx/2.2" fx:controller="application.CellController"> 7<children> 8<Button fx:id="button" layoutX="5.0" layoutY="57.0" maxHeight="25.0" 9maxWidth="25.0" minHeight="20.0" minWidth="20.0" mnemonicParsing="false" 10onAction="#sampleButton" prefHeight="25.0" prefWidth="25.0" 11styleClass="circle-buttonfavo" text="" /> 12</children> 13</AnchorPane> 14

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

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

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

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

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

masaya_ohashi

2016/07/01 09:34

いまいち状況が読めないのですが、できればレイアウトのスクリーンショットを添付していただけますか?
masaya_ohashi

2016/07/01 09:50

リストの中かつ青い隠された部分以外をクリックすると、そのセルがフォーカスされ、青い隠された部分の中にあるボタンを押した時はフォーカスが移らない、という状態ですか?
masaya_ohashi

2016/07/01 09:52

あと、通常「ホバー」とはマウスカーソルがその要素の上を通過するだけのことを指しますが、認識はあっていますか?
ta_ko

2016/07/01 09:55

そういうことです、ボタンを押してもそのセルが選択されたことにならずにセルのインデックスが取得できていないためエラーが生じます。 そういう認識です、ただボタンを押したときにインデックスを取得できるように出来るのでしたらそのようなやり方でもぜんぜんかまわないです。
guest

回答1

0

ベストアンサー

動作は確認していませんが、このような方法は使えないでしょうか。
ボタンのgetParentを使いListCellが見つかるまで遡ってindexを取ります。

Java

1button.setOnAction(new EventHandler<ActionEvent>() { 2 @Override public void handle(ActionEvent e) { 3 // getParentを使い、このボタンが含まれるListCellを遡って探す 4 Node n = (Node)(e.getSource()); 5 while(n != null && !(n instanceof ListCell)) { 6 n = n.getParent(); 7 } 8 if(n != null) { 9 // 見つかった場合、 10 ListCell cell = (ListCell) n; 11 System.out.println(cell.getIndex());// ListCell#getIndexで番号が取れる 12 } 13 } 14});

投稿2016/07/01 10:09

masaya_ohashi

総合スコア9206

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

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

ta_ko

2016/07/01 10:38

いろいろこちらのソースと比較して要所要所変更したのですが buttonやcellの部分でNullPointerExceptionを吐いてしまいます。 当方がFXMLでGUIのボタン設定や配置を作成しているため、 FXMLとコード内のbuttonやcellとの紐づけがきちんと行われていないためでしょうか…。 java自体初心者なので、エラーの原因やFXMLの使い方があまり理解できず申し訳ないです。
masaya_ohashi

2016/07/01 10:42

さすがに私もそこからどこを直せばいいかはエスパーではないので無理です...質問文にクリックした時の処理前後のコードを追記していただければ指摘できるかと思います。伏せたいところは伏せて構いません。
ta_ko

2016/07/01 11:53

```lang-Java @FXML Button button; @FXML static ListCell cell; @FXML public void sampleButton(ActionEvent e){ button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { // getParentを使い、このボタンが含まれるListCellを遡って探す Node n = (Node)(e.getSource()); while(n != null && !(n instanceof ListCell)) { n = n.getParent(); } if(n != null) { // 見つかった場合、 cell = (ListCell) n; System.out.println(cell.getIndex());// ListCell#getIndexで番号が取れる num = cell.getIndex(); } } }); } ``` javaのコードはこんな感じです。 このコードはセルのコントローラに記述してあります。 ListCellのstaticはstaticをいれずに実行したところListViewにセルが出てこなかったため つけています。 ```lang-FXML <?xml version="1.0" encoding="UTF-8"?> <AnchorPane id="AnchorPane" fx:id="cell" maxHeight="-1.0" maxWidth="-1.0" minHeight="-1.0" minWidth="-1.0" prefHeight="90.0" prefWidth="500.0" styleClass="cell" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="application.CellController"> <children> <Button fx:id="button" layoutX="5.0" layoutY="57.0" maxHeight="25.0" maxWidth="25.0" minHeight="20.0" minWidth="20.0" mnemonicParsing="false" onAction="#sampleButton" prefHeight="25.0" prefWidth="25.0" styleClass="circle-buttonfavo" text="" /> </children> </AnchorPane> ``` 一応、これがセルのFXMLです。 FXMLのfx:idでcellとbuttonを記述してあります。 教えていただいたコードの ListCell cell = (ListCell) n; の箇所の記述方法がFXMLだとどのように紐づけするのかわからず AnchorPaneのfx:idにcellと書いています。 これで伝わりますでしょうか…
masaya_ohashi

2016/07/01 12:14

コメントだとコードが見づらいので、質問文の方に移していただけますか?
masaya_ohashi

2016/07/01 13:07

私のコードでいうhandleメソッドの部分が、そちらのコードのsampleButtonメソッドの部分にあたります。 handleの中身のコードだけをsampleButtonの中にコピーしてみてください。
ta_ko

2016/07/01 13:15

実装できました!ありがとうございます。 なぜこれでうまく実装できるのか、ちゃんとコード見て考えてみます。 instanceofとかNodeなど今まで触れていなかった箇所があるので…
masaya_ohashi

2016/07/01 15:41

NodeというのはJavaFXのUIのパーツすべての基底クラスになっています。ButtonだろうとListCellだろうとListViewだろうとAnchorPaneだろうと、super classを辿ればNodeに行き着きます。上で挙げたクラスのAPIリファレンスを見てみてください。上のへんにjava.lang.Objectから始まるクラスの継承階層がありますよね?その継承階層の中に必ずNodeが含まれいてるはずです。 getParentは自分の親要素をParentというクラスの形で受け取れます。Parentのsuper classはNodeなので、Node型変数nで受け取ることができます。そして、例えParentという型であっても、その正体はListCellだったり、ListViewだったり、AnchorPaneだったりします。その正体を見破るための技がinstanceofなのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問