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

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

ただいまの
回答率

88.10%

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,571

score 13

前提・実現したいこと

javaFXのListViewで、カーソルを合わせたセルのインデックスを取得する。

発生している問題

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

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

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

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

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

@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();
}
}
});
}
<?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>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • masaya_ohashi

    2016/07/01 18:34

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

    キャンセル

  • masaya_ohashi

    2016/07/01 18:50

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

    キャンセル

  • masaya_ohashi

    2016/07/01 18:52

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

    キャンセル

  • ta_ko

    2016/07/01 18:55

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

    キャンセル

回答 1

checkベストアンサー

0

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

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) {
            // 見つかった場合、
            ListCell cell = (ListCell) n;
            System.out.println(cell.getIndex());// ListCell#getIndexで番号が取れる
        }
    }
});

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/01 22:07

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

    キャンセル

  • 2016/07/01 22:15

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

    キャンセル

  • 2016/07/02 00: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なのです。

    キャンセル

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

  • ただいまの回答率 88.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る