torutkのブログスマートフォン用の表示で見るtorutkのブログソフトウェア・エンジニアのブログ2019-07-15JavaFXのグラフの凡例部分を操作可能にするはじめに先週書いた次のブログの続編です。torutk.hatenablog.jp一つのグラフ表示領域に、複数のグラフ(Series)を重畳表示した際に、簡単な操作でそれぞれのグラフを非表示にしたり表示したりとできると使い勝手が向上します。グラフに凡例を表示した場合、それぞれの凡例をクリックするとその凡例に対応するグラフを表示する、非表示すると切り替えられるようにします。凡例全体のNodeは、Legendクラス(com.sun.javafx.chart.Legend)で実装されています。このcom.sun.javafx.chartパッケージは、アプリケーション側のモジュールには公開されていません。9以降では使えません(--add-exportsオプション指定でコンパイルすれば可能)。JavaFXのAPIには、セレクタを指定してNodeを取得する機能(lookupおよびlookupAll)が提供されているので、これを使って凡例のNodeを取得します。spectrumChart.lookupAll(".chart-legend-item");それぞれの凡例にマウスハンドラーを設定するには例えば次のようにします。clicked")));各凡例をクリックしたら対応するグラフを表示/非表示するクリックされた凡例のNodeにマウスハンドラーを設定することはできましたが、次はそこから対応するグラフを取得して、その表示を切り替える方法を考えなくてはなりません。それぞれの凡例はLabelクラスのインスタンスで、ラベルに表示されるテキストはグラフ(Series)のnameプロパティとなっています。そこで、取得したそれぞれの凡例をLabel型にキャストしてラベルに表示されるテキストを取得し(getTextメソッド)、次にそのテキストを名前として持つSeriesをLineChartから探して取得します。}}));Label型へのキャストが可能な場合に、Labelへキャストし、getTextメソッドでラベルに表示されるテキストを取得します。}}));chartのdataプロパティには表示するグラフ(Series)がリストで登録されています。これを順次アクセスしSeriesのnameプロパティが凡例ラベルのテキストと一致するものを取り出します。}}));取り出したグラフ(Series)のgetNodeメソッドで画面に表示されるグラフのNodeを取得し、その表示状態をisVisibleで取得します。その真偽を反転させてsetVisibleに指定し、表示/非表示を反転させます。グラフが非表示のときは凡例の表示を薄くしたい実現方法を悩みましたが、CSSの疑似クラスを使って非表示の際に薄く(透過度を変えて)表示させることにしました。0.2;}次に、凡例ラベルのマウスハンドラー内でグラフ(Series)の表示/非表示切り替えに合わせて疑似クラスの有効・無効を凡例ラベルに設定します。00:04JavaFXのグラフの凡例部分を操作可能にするTweet広告を非表示にするもっと読むコメントを書く2019-07-07JavaFXで折れ線グラフを出そうとしてみたはじめに(お題)電気信号を時間領域から周波数領域に変換し、周波数に対するエネルギー量を解析できる測定器にスペクトラム・アナライザがあります。今回、このスペクトラム・アナライザで解析した結果をファイルに保存し、別な場所にあるPC上でその結果を表示、分析したいとします。計測器にCSVファイルで結果を保存する機能があればこれをExcelで読み込ませてグラフ化することは容易ですが、今回の計測器はバイナリデータのファイルに保存するものでした。そこで、JavaFXで保存したバイナリデータのファイルを読み込み折れ線グラフ(LineChart)で表示するプログラムを作成してみます。Builderで作成しました。ファイル構成は次です。BuilderでLineChartを画面にポトペタすると次の表示となります。縦軸は数値メモリとなっていますが、横軸は表示されていません。Builderの左下ペインを見ると、LineChartの子ノードとしてNumberAxisとCategoryAxisが1つずつ置かれています。縦軸がNumberAxisで、横軸がCategoryAxisです。NumberAxisは名前の通り数値の軸を表し、CategoryAxisは何らかの分類(県名、年別、チーム別、など)の軸を表します。Builder上では、LineChartの子ノードの軸を変更する方法が見つからなかったので、FXMLファイルを直接エディタで開き修正しました。</LineChart>横軸がNumberAxisに変更されました。}}JavaFXの典型的なApplication派生クラスの実装です。mainメソッドでプロセスのエントリを用意し、startメソッドでFXMLファイルを読み込みシーングラフを作成、Stageを表示させています。Builderでポトペタ作成したFXMLファイルで、ビュー(画面)を定義しています。コントローラークラスを指定しているので、このFXMLがロードされると自動でコントローラークラスのインスタンスが生成されます。}}FXMLに対応するコントローラークラスです。コントローラーから操作するビュー部品(コントロール)は、@FXMLアノテーションを指定し、FXML側で指定したfx:idの識別子と同じ名前の変数名とすることで、FXMLロード時にインスタンスがインジェクションされます。データについては、今回はデータファイルの読み込み部分が未実装なので、ランダムな値を表示するモデルを使います。}JavaFXではモデルクラスについては特にフレームワークが用意されていませんが、コントローラーを軽くするために、ちょっとしたロジックであってもモデルクラスを設けるようにしています。表示確認のために、データファイルを読み込む前にランダムなスペクトルを表示するモデルを作りました。JavaFXの折れ線グラフ(LineChart)に表示する1本の連続する線は、データ系列(XYChart.Series)で定義し、複数のデータ系列を表示することができます。データ系列は、複数の点データ(XYChart.Data)のリストとして作られています。今回は、1つのデータ系列を用意しています。用意するデータは、周波数軸(X軸)の950~1450までの間を1刻みで作成し、縦軸の電力は正規分布乱数で平均-60.0、分散5.0としています。表示プログラムを実行すると、次の画面が表示されました。改善したい点があります。Builderで、軸のLabelプロパティに文字列を設定すれば表示できます。縦軸は、-30.0~-80.0の範囲を表示し、横軸は950~1450の範囲を表示します。表示すべきデータを読み込んだ際にデータに応じた値を設定するので、コードで制御します。前回からのコード変更部分を次に記載します。}NumberAxisには、表示する軸の値の上限値・下限値を指定するlowerBound、upperBoundがあります。ここに表示する軸の数値範囲を指定します。この上下限値設定は、LineChartにデータ(XYChart.Series)を登録する前に実行する必要があります。あとから実行したら表示には反映されません。これだけでは意図したとおりの動作をしません。NumberAxisのAutoRangingプロパティが有効だと、登録したデータの値に応じた軸の数値範囲に自動調整が働いてしまいます。Builder上でAutoRangingプロパティを無効にします(次の図参照)。プログラムを実行すると、次の様に意図した数値範囲でグラフが表示されました。グラフの罫線間隔については、NumberAxisのTickUnitプロパティで制御可能です。〇の表示(シンボル)をなくすデフォルトでは、折れ線グラフの点データに丸いシンボルが表示されます。データ数が少ないときは、データとデータを補完する線とを明確に表現するこの表示が適していますが、データ数が多いときは上図のようにシンボルだらけで肝心の折れ線が見えなくなってしまいます。シンボルをなくすのであれば、LineChartのCreateSymbolプロパティを無効にします(次の図参照)。プログラムを実行すると、次のとおり丸いシンボルが表示されなくなりました。シンボルを消すのではなく、シンボルの形状を変更したいときは、CSSでセレクターに.chart-line-symbolを指定し見栄えを記述します。折れ線を細くデフォルトでは、折れ線の幅がちょっと太いので、これを細くします。形状の変更はCSSで記述します。セレクターに.chart-series-lineを指定し見栄えを記述します。0.75px;}CSSファイルは、アプリケーション派生クラスでSceneに設定するか、FXMLで最上位要素に指定するかの方法があります。Builder)上で最上位要素のBorderPaneにCSSファイルを設定します。CSSファイルはFXMLファイルと同じ場所に置き、BorderPaneのStylesheetsプロパティに指定します(次の図参照)。プログラムを実行すると、次のとおり折れ線が細くなりました。凡例の記号を四角ではなく線にするCSSファイルで凡例の記号を定義している@.chart-legend-item-symbol@の定義を変更します。CHART_COLOR_8;}デフォルトの凡例シンボルは枠が系列色、中が白色塗りつぶしの円です。@-fx-background-radius@と@-fx-background-insets@はデフォルトの定義を無効化するのに指定する模様です(細部よくわからない)グラフはデフォルトで8つまで色分けできるようにCHART_COLOR_1からCHART_COLOR_8まで色が定義されています。svg-pathで定義した枠の中をグラフの対応する色で塗りつぶすために、@.default-colorX.chart-legend-item-symbol@を定義しています。11:03JavaFXで折れ線グラフを出そうとしてみたTweet広告を非表示にするもっと読むコメントを書く2019-06-30インターネットとつながらないソフトウェア開発環境で使うツール前提ソフトウェア開発環境がインターネットと隔離されていることは、昨今のセキュリティ事情からよくあることと思います*1。ソフトウェアエンジニアの場合、事務作業で使うPC環境とは別にソフトウェア開発用のPC環境があり、それは事務作業で使うネットワーク環境とは異なるソフトウェア開発のネットワーク環境につながっており、インターネットとはつながらない(あるいは強度な制約のもとインターネットにつながる)環境となります。事務作業用のPCと開発用のPCが物理的に分かれていて、それぞれ別々なネットワークに接続されていることや、事務作業用PCの利用は仮想マシンを通して行い、開発用PCと仮想マシン間のデータ交換は不可となっていることなどです。開発したソフトウェアを組み込む製品と開発環境をつないで、ソフトウェアのインストール・更新、ログの取得、デバッグ、各種設定をする際は、製品が開発用ネットワークとはつながっていないため、開発用PCを開発用ネットワークから切り離して使うこともあります。場合によっては開発用ネットワークなしに単独で最初から最後まで開発を行うこともあります。このように開発環境がインターネットとは接続されていない場合は、開発に使うツールの選定時点からそのことを考慮に入れておくことが不可欠です。開発環境で使うツールの準備インターネットと隔離されているので、開発環境で使うツールは開発環境用のネットワークの中で展開できるようにする必要があります。ここで困るのが、Webインストーラーのみ提供され、インターネットとつながっていないとインストールができないツールです*2。開発用PCをインターネットにつないでインストールしてから開発環境用ネットワークに持ち込めばいいのでは?との声があるかもしれませんが、開発データを抱えたPCをインターネットに接続することは原則不可でしょう。インストールはできるもののライセンス認証にインターネット接続が必須となるツールも使うことができません。ツール本体はオフラインでインストールできても、プラグインの追加がインターネット接続必須となると困ります。インストールができたとしても、実行時に問題があるというケースも困ります*3。IDEAは、いずれもインストールイメージをオフラインで展開して使用できます。ビルドツールmaven、gradleはJavaのビルドツールとして非常に流行っておりますが、インターネットに接続していることをほぼ前提としているツールなので、インターネットと隔離した開発環境での使用には不適です。mavenは、自身の実行にもインターネットからモジュールのダウンロードが発生します。オフラインオプションもありますが、一度オンラインでダウンロードしたキャッシュを使うものなので、ゼロから使うには、mavenセントラルリポジトリのクローンをNexusやArtifactoryなどで開発ネットワーク内に構築し、各開発PCからはそのクローンを参照する必要があります*4。開発環境から切り離しての作業には制限があります*5。gradleは、mavenに比べるとオフライン使用がまだ容易ですが、オフラインで使用できるようにするための手間はやはり発生します。Studioで開発した際は、SDKのインストール場所、ライブラリの配置などを調整する必要がありました。その時の取り組みは次のブログに記載しています。torutkのブログ現時点では、引き続きAntを使うのがインターネット隔離環境では適すると言えます。mavenセントラルリポジトリのライブラリ利用におけるセキュリティリスクmavenリポジトリを利用する場合、利用するライブラリが依存するライブラリ群を逐一把握して揃えなくてもビルド時に自動で取得してくれる利便性があります。これは逆に意図しないライブラリが入り込むことになります。意図しないものに、知財的な問題からバックドア等のセキュリティ脆弱性問題までいろいろな問題が含まれます。開発者が使用するPC個別に直接mavenリポジトリへアクセスしライブラリをダウンロードしてくるので、マルウェア等が入り込み別サイトに誘導されダウンロードしてしまうということも考えられます。バージョン管理ツール開発用PCが開発ネットワークに接続して使用、あるいは切り離して使用するので、リポジトリサーバーへの常時接続がなくても管理できる分散リポジトリ方式のGitやMercurialがよいでしょう。製品組み込み後にその場で修正をした場合は、開発ネットワークから切り離されている間にリポジトリへのコミットを重ねておき、もどってから中央リポジトリに反映することができるのは大きな利点です。CIツール計画的な(デイリーの)ビルド・成果物作成はJenkinsなどのサーバーを使いますが、製品と隣り合わせでビルド・インストールを繰り返すときには持ち出しできる(開発PCに一緒に乗せて使える)CIツールがあるといいですね。これは今後調査していきたいと思っています。ソフトウェア開発メンバーだけでなく、組織の管理者層や品質保証部門からも参照したい情報です。ソフトウェア開発環境の中に閉じたツールを立てると、開発メンバーしか共有できません。隔離したネットワークの双方から参照したい場合の実現方法は今後調査していきたいと思っています。コミュニケーションツール開発環境とは別に、事務作業用の環境で使うか、開発環境の中に独自にツールを用意するかの選択(あるいは併用)となります。ビルド結果の通知、プロジェクト管理ツールからの通知などをコミュニケーションツールで受けるので開発環境の中に置きたいところですが、開発以外のメンバーとのコミュニケーションには事務作業用の環境で使えるツールが必要です。インターネット接続環境ではチャットツールの活用でコミュニケーションが良好になっています。隔離したネットワーク内およびその外側とでコミュニケーションをとる方法を今後調査したいところです。前提で書いた開発環境は、かなり制約がつよい(利便性が犠牲になっている)環境となっています。プログラマー視点で普段目にする技術情報では、便利な技術の紹介がほとんどで、インターネット上のサービスをガンガン使うものばかりですが、所属する会社組織において要求されるセキュリティレベルによってはそうした便利技術が使えないということが私の経験では多いです。前提のような環境を強いられなくてもセキュリティが保てるような開発環境をどうしたら構築できるかについて、少しずつ検討していきたいと考えています。インターネット接続できない場所が意外と先日出張の際、建物の中のある会議室では携帯キャリアによってつながる/つながらないが分かれました。出張の合間に車で移動する際、キャリアすべてがつながらない場所が少なからずありました。*1:開発用PCがインターネットとつながってメールやWebができると、開発環境にある情報が漏洩するリスクがあり、入口対策でファイアウォールやウィルス対策をしていても、標的型攻撃や開発ツール・ライブラリ等に仕込まれたサプライチェーン攻撃等による漏洩は防げません。開発環境に攻撃が及んでも社外に漏洩しないよう隔離をして対策を取るケースです。2017以降はISOイメージが提供されなくなり、オフラインインストールが困難になりました。インターネットに接続したPCでいったんWebインストーラーを動かしオフラインイメージをダウンロード、それを検疫等必要な処置をして開発環境へ持ち込み、開発PCへインストールする手順は用意されていますが、コード署名の証明書が追加で必要なるとか、ダウンロードしたPCと構成が違うときにエラーになるといったトラブルが生じることがあります。インターネットに接続するPCでWebインストーラーを実行できるかは組織のセキュリティポリシーにより許されないこともあります。*3:過去にあったのが、アセンブリ(DLLファイル)にコード署名が施されており、ツールを起動するたびにコード署名の検証をするがその際インターネット接続を試み、タイムアウトが発生してから起動するというもの。ツールの起動に数分待たされてしまいました。18:11インターネットとつながらないソフトウェア開発環境で使うツールTweet広告を非表示にするもっと読むコメントを書く2019-06-28JavaFXアプリケーションでユーザーが編集可能なCSSファイルを置くには問題JavaFXアプリケーションを作成する際に、画面のレイアウトをFXMLで記述、色やフォントなどの見栄えをCSSファイルに記述し、FXMLのルートノードにCSSファイルを指定しました。模式的なソースファイル構成は次のようになります。MyApp.cssMyApp.javaの中でFXMLファイルを読み込みます。中でCSSファイルを指定します。xmlns=...>このアプリケーションをビルドすると、CSSファイルは他のクラスファイル等と一緒にJARファイルまたはjlinkでモジュールファイルに含まれます。このアプリケーションを実行するマシンに配布したあとに、画面の見栄えをカスタマイズしようとCSSファイルを取り出して編集、再組み込みすることは簡単ではありません。JARファイルならzipアーカイブツールでCSSファイルを取り出し編集後再度JARファイルに戻すことは可能です(かなり面倒です)。jlinkのモジュールファイルの場合、zipではないので取り出し編集は困難です。そこで、ビルド時にJARファイルまたはモジュールファイルに組み込まれるデフォルトの設定を記述したCSSファイルとは別に、独立したCSSファイルをアプリケーション実行時に読み込み反映する方法を探ってみました。sceneに別CSSファイルを設定するも反映されずカレントディレクトリにMyCustom.cssファイルが存在すればそれをSceneのスタイルシートとして設定するコードを追加しました。scene.getStylesheets().add(path.toUri().toString());}しかし、これではMyCustom.cssに記述したカスタム設定が反映されませんでした。このコードでは、SceneとそのrootノードのHBoxにそれぞれ別のスタイルシートが設定されます。Guide」に次の記述を見つけました。sheets.つまり、Sceneのスタイルシートよりもその子ノード(rootノード)のスタイルシートの方が優先されてしまいますsceneのrootノードにスタイルシートを設定するそこで、Sceneのrootノードに対してスタイルシートを設定するようにしました。scene.getRoot().getStylesheets().add(path.toUri().toString());}これで、アプリケーションを実行するときのカレントディレクトリにMyCustom.cssファイルが存在すれば、その内容が反映されるという仕組みができました。07:55JavaFXアプリケーションでユーザーが編集可能なCSSファイルを置くにはTweet広告を非表示にするもっと読むコメントを書く2019-06-24gitのリリースタグをアプリケーションのバージョン表記に使うはじめにJavaとJavaFXで小さなスタンドアロン・アプリケーション(ユーティリティ)を作成、使用するマシンに配置し、使い勝手を見ながら改善しています。System)として作成し、jlinkコマンドで実行イメージを作成してJavaのランタイム込みで配布しています。アプリケーションの利用者から今使っているバージョンを認識し、フィードバックを得るようにするため、バージョン番号表記をどのように組み込もうかと試行錯誤してみました。世の中よく見かけるバージョン表記は、アプリケーションのメニューバーに「ヘルプ」を置き、メニュー項目に「このアプリケーションについて」等を入れ、それをクリックするとアプリケーションの名前、バージョン、その他情報をポップアップ表示するといったものです。小さなプログラムでメニューバーを設けていない場合は別な手段が必要になります。今回は、ウィンドウのタイトルバーにバージョンを表記することとしました。バージョン管理ツールとバージョンgitを使ってソースコードのバージョン管理をしています。リリースの際にはタグでリリースバージョンを設けます。v1.3.2このタグをバージョン表記に使用することとし、ソースコードのリポジトリにはバージョン番号を記載したファイルは設けないようにします。ビルド時に、次のコマンドでバージョンを取得します。abbrev=0v1.3.2abbrev=0を付与しない場合、タグをつけたコミットからタグをつけないコミットを行った際、次の様にタグをつけてからのコミット数とハッシュが追加されて表示されます。--tagv1.3.2-2-g595ad04gitのタグの種類gitには、軽量タグ、注釈タグ、署名タグとタグの種類がいくつか存在します。describeでは--tagオプションを指定する必要があります。注釈タグは、タグを付与するときにコミットログを記述します。describeでは--tagオプションがなくても最新のタグを取り出すことができます。バージョン番号の埋め込み方法JavaFXでは、ウィンドウのタイトルへ表示する文字は次のようにStageクラスのsetTitleメソッドを呼んで設定します。}ビルド時にgitのタグからバージョン番号を取り出してウィンドウタイトルに表示させるため、ここではリソースバンドルにバージョンをビルド時に埋め込むようにします。:Windowsバッチファイルで置換する場合リソースバンドルには、ビルド時に文字列置換できるように置換キーワードを記述した状態でコミットしておきます。#VERSION_TO_BE_REPLACED#そして、ビルド時に置換キーワードをgitのタグ情報に置き換えます。Features」を読む会(第1回)を開催しました。あいにくの雨模様でしたが、10名を超える参加者が集まりました。SE9からの技術を解説した日本語の書籍が皆無で、洋書の選択となりました。Java読書会BOFが開催する読書会では、書籍を本文、脚注、ソースコードとすべてを朗読して進めています。今回は洋書なので、どう進めようか?と思いましたが、英語のままで朗読して進めてみることとしました。書籍の入手に関してAmazonのサイトには、紙の書籍とKindle電子書籍版があり、紙版も2日程度で入手可能となっています。Publishingのサイトには、ePubおよびPDFの電子書籍版があります。Kindle版は2840円ですが、ePubおよびPDF版は10ドル(約1100円)と半額以下です。英語の朗読について英語の朗読なので、英語の得意な人は問題なく把握できますが、そうでないと分からない単語が多く読み取ることがなかなかむずかしいというところがありました。今回の本は割とやさしい英文でしたが、それでもちょっと苦労はあったようです。時間がかかりますが、段落ごとに内容を日本語で簡単にまとめるといったフェーズをおくのがよかったかもしれません。10で導入された型推論(var)について、3時間はじっくりとかけて読みました。括弧とは一緒に定義できないという制約があります。varは予約語(キーワード)ではないので、メソッド名やインスタンス変数、static変数の識別子にvarの名前を使用可能です。議論はありましたが、ローカル変数の宣言行でvarによる型推論を使うことでその宣言行を読んだだけでは型が分からない場合(例を次に示す)はvarによる型推論を使わない、というのが必須と思います。getData();これは、getDataのメソッド名の宣言行(シグニチャ)を調べないと、ローカル変数iの型が分かりません。varを導入したことによりコードの読み手に対する情報が欠落してしまっています。左辺の変数名、あるいは右辺のメソッド名から型が容易に推測できる場合はvarによる型推論を使ってもよいという意見もあります。個人的には、ローカル変数の宣言行で、型名を2回記述しなければならないときに型指定をvarとしてもよい、それ以外の場合は、型を書くというのをベストプラクティスにしたいです。搭載されていた機能でしたが、まったく気にしたことがなく、使い方の記述を日本語では殆ど見かけたことがありませんでした。今回読書会では、JDKの標準クラスが格納されたclasses.jsaと、アプリケーションの起動時に必要なクラスをシェアリング用ファイルとして生成し使用するAppCDSとについて、じっくり読んで知識を得られました。なしとなっていました。classes.jsaがない場合は、次のコマンドで生成することができます。デフォルトとなりました。11以降を使う場合は明示的に指定しなくてもCDSが有効となります。一度実行しておくとよいでしょう。AppCDS(アプリケーション・クラス・データ・シェアリング)CDSがJavaの標準クラスをシェアする機構に対して、AppCDSはアプリケーションのクラスを含んだクラスをシェアする機構です。10とで変わるので少々混乱してしまいます。11以降では廃止となって指定する必要はありません。11以降では、次のステップでAppCDSのシェアドアーカイブファイルを適用します。-XX:SharedArchiveFile=<シェアドアーカイブファイル名>以後、アプリケーションを実行するときは次のJVMオプションを指定-XX:SharedArchiveFile=<シェアドアーカイブファイル名>最初のステップで-Xshare:offを指定するのは、リストを作成するときに標準CDSのアーカイブファイルから読み込むことを抑制するためと思われます。次回の範囲は次回は、次の項目を読み進める予定です。Features」(洋書)を読む会を開催してTweet広告を非表示にするもっと読むコメントを書く2019-06-03JavaFXの入力部品でエラー時に色を変えるGUIでユーザーが入力した値が範囲外などのエラー時に、エラーとなった箇所が分かるよう色を変える方法を模索しました。今回はTextFieldを題材とします。CSSの疑似クラスでエラーを定義JavaFXで、CSSファイルを使って見栄えを定義している場合、CSSファイルにTextFieldの疑似クラスerrorを次のように定義します。}疑似クラスの名前でPseudoClassインスタンスを取得し、対象となるTextFieldインスタンスのpseudoClassStateChangedメソッドで引数に疑似クラスのインスタンスと有効・無効のフラグを指定すると見栄えを変更することができます。この実装では、submitボタンが押された段階でTextFieldの内容をチェックし疑似クラスerrorの適不適を切り替えています。本格的に、TextFieldに文字を入力する度にチェックし色を変えることもできますが、本日は割愛します。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。