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

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

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

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

Q&A

解決済

1回答

2118閲覧

JavaFXのチャートのデータにクリックイベントを追加したい

oscikonome

総合スコア16

JavaFX

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

0グッド

0クリップ

投稿2017/01/27 15:18

###前提・実現したいこと
JavaFXでチャートを描画しています。
チャート・・・例えばScatterChartに描画したデータ点に何らかの形でクリックイベントを追加したいです。

###発生している問題・エラーメッセージ
ToolTipを表示する例があったので、ContextMenuも同様に表示できるかと思ったのですがうまくいっていません。

###該当のソースコード
今手元にソースがないですが、ToolTipを表示する例は以下で見つけました。
http://bitwalk.blogspot.jp/2015/06/javafx-scatterchart.html

###試したこと
ContextMenuで似たようなことができないか試しましたが、不慣れなためうまく書けていません。

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

guest

回答1

0

ベストアンサー

ScatterChart上でプロットされるデータの点はXYChart.Dataクラスで表されますが、XYChar.Dataクラスには画面上へその点を表現するためのnodeプロパティーが用意されています。これはNodeクラスの派生クラスなのでsetOnMouseClickedでマウスクリックイベントを設定できます。

たとえばチャートに表示するデータ列(XYChar.Series)を生成するときに次のようにするとマウスクリックイベントを設定できると思います。

ポイントはXYChar.Dataを作ったばかりのときはまだ画面表示用のnodeプロパティーが未設定という点です。自分でチャートの表現をカスタマイズする際には自前のNodeを生成してXYChar.Dataのnodeプロパティーへ設定してやればいいので、その際にNode#setOnMouseClickedを使ってハンドラーを登録すればいいのですが、JavaFXが自動で設定してくれるデフォルトのXYChar.Data用のNodeを使いたい場合は最初からマウスイベントのハンドラーを設定できません(いつそのNodeが追加されるかわからないので)。
そうした場合にはnodeプロパティーのChangeListenerを使って「nodeプロパティーへ実際のNodeが設定されたときにハンドラーを登録する」という戦略を用いるとよいと思います。

java

1class Foo ... { 2 ... 3 XYChart.Series<Double, Double> createSeries() { 4 Series<Double, Double> series = new Series<>(); 5 series.setName("series 1"); 6 7 for (int i = 0; i < 50; i++) { 8 XYChart.Data<Double, Double> p = new XYChart.Data(X座標, Y座標); 9 p.nodeProperty().addListener((ob, oldNode, newNode) -> { 10 if (newNode != null) { 11 newNode.setOnMouseClicked(this::onChartDataClicked); 12 } 13 }); 14 series.getData().add(p); 15 } 16 return series; 17 } 18 19 void onChartDataClicked(MouseEvent ev) { 20 ... 21 } 22}

訂正:
上の回答に「いつそのNodeが追加されるかわからないので」と書きましたが、ご質問にあるページのサンプルを見るとstartメソッドでnodeプロパティーにtooltipをインストールするコードが書いてありますね・・・
実際にやってみるとチャートへデータ系列をsetDataするときにNodeが追加されるみたいです。自分の回答の方法でも動きはしますが、わざわざChangeListenerを使わなくてもよさそうです。
チャートへデータ列を設定した後でデータ列を走査してハンドラーを登録すればいいんですね。以下はサンプルコードの抜粋ですがtooptipのかわりにマウスクリックイベントのハンドラーを登録する例です。

//質問にあるページのサンプルコードの抜粋 scatterData.stream().forEach((series) -> { series.getData().stream().forEach(point -> { point.getNode().setOnClicked(this::onChartDataClicked); }); });

投稿2017/01/28 02:17

編集2017/01/28 03:20
KSwordOfHaste

総合スコア18394

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

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

oscikonome

2017/01/28 10:52

scatterData.stream().forEach((series) -> { series.getData().stream().forEach(point -> { point.getNode().setOnMouseClicked((MouseEvent)->{ onChartDataClicked(); }); }); }); こんな感じですかね。思うとおりに実現できました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問