ひらおかゆみのなげやりブログ

もう、なげやりです…

JavaFXのHTMLEditorはどこまで使えるか?

このエントリは、JavaFX Advent Calendar 2017 の 16 日目です。昨日は平田あづみ(@planet_az / id:planet-az)でした。明日は@opengl_8080さんです。

JavaFXにはHTMLEditorというそのものずばりなコントロールが付属しています。HTMLの編集と入出力、印刷ができるようです。これがあればホームページビルダーみたいなソフトを簡単に自作できるのでは?ということでちょっと試してみました。

とりあえず作ってみたのがこれです。Scene Builderの最新版にメニュー付き画面のテンプレートが用意されているので、それを使ってみました。

f:id:yumix_h:20171213003612p:plain

見た目だけなら割と本格派です。実際にワードパット並みの編集機能は持っています。何となくですが使えそうな気にはさせてくれます。

ただ、このHTMLEditorには1つ問題があって、カット・コピー&ペーストやらフォントやら段落書式やら編集操作はいろいろできるのですが、それらをプログラムから制御することができません。例えば、メニューからカット・コピー&ペーストを行おうにも、メニューから呼び出すためのインタフェースがHTMLEditorには備わっていません。

悔しいので深く追っていくと、HTMLEditorは処理のほとんどをHTMLEditorSkinというクラスに委ねていることがわかります。いわゆるhas-Aの関係です。さらにHTMLEditorSkinを見ていくと、内部でWebViewクラスとWebPageクラスを使っていることがわかります。WebPageはWebView内部から呼び出されるクラスで、HTMLEditorSkinからも直接呼び出されます。どうやらHTMLEditorはHTMLの編集にWebViewの内部機能(たぶんWebKit)を用いているようです。HTMLEditorが生成するHTMLはこんな感じになります。

f:id:yumix_h:20171213005838p:plain

見づらい…でも、自動生成したHTMLにインデントや改行を求めてはいけませんよね…

HTMLEditorの様々なボタンは、HTMLEditorSkinがprivateフィールドで保持しているようです。リフレクションを使ってprivateフィールドに強引にアクセスするのはSIer辞めてPayaraに移った例の人が大好きな手法ですが(あの人確か4~5年くらいリフレクションのユーティリティをスクラップ&ビルドしてたはず)、わたしは今のところやるつもりはないです。

HTMLEditorはJava 9からjavafx.webモジュールに含まれているのですが、なぜjavafx.webに分類されたのか、今回の結果でわかったような気がします。

今回作成した(正確には作成途中というべきか?)アプリケーションは、GitHubにアップロードしています。

github.com

OpenJFXのWikiからJavaFX 9の新機能を俯瞰する

このエントリは、JavaFX Advent Calendar 2017 の 14 日目です。昨日は高橋 @boochnich さんの「JavaFXアプリケーションのファイル構成(FXML, CSS, properties)」でした。明日は平田あづみ id:planet-az / @planet_az です。

ここ数年、JavaFXのアドベントカレンダーは櫻庭 @skrb さんが立てていらして、わたしも毎年それに便乗させていただいていたのですが、今年はそれがなかった。それもそのはず、今年の櫻庭さんはなんと一人アドベントカレンダーに挑戦中!

adventar.org

例えば、12/12は本わらび餅など和菓子特集…ああ、食べたくなってきた。

sunnypartlysweets.hatenadiary.jp

毎年JavaFX Advent Calendarを支えてきた偉大なるトライアングル(櫻庭さん、青江さん、高橋さん)の一角が今年は不在とあっては、さすがに力不足だったのかな?わたしの力ではお三方に遠く及ばないのはわかっているのですが。

今日は、本当は@khasunuma(@btnrouge)に頼もうと思っていたのですが、あいにく風邪で寝込んでいて書けないらしい(でもJava EE Advent Calendar 2017用の記事は数日分のストックがあるから大丈夫だとか)ので、自分で書くことにしました。

さて、ここからが本題です。

JavaFXは現在OpenJFXというプロジェクトでオープンソース・ソフトウェアとして開発が行われています。その中のWikiで、OpenJFX 9の新機能について触れられています。以下、そのリストを全文引用します。

Milestones

TBD

JEPs

  • 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
  •  8043352: JEP 257: Update JavaFX/Media to Newer Version of GStreamer

Minor enhancements:

  • Public API to replace heavily-used internal API no longer accessible with Jigsaw
  • Better Hi-DPI support (with API control) on Mac, Windows, Linux

  • Update WebKit to newer version

これだけです。少ないですね。少ないので全部順にみてゆきましょう。

JEP 253というのは、具体的にはJavaFX 9で追加されたjavafx.scene.control.skinパッケージのことを指します。このパッケージには主要なコントロールのSkinが定義されていて、コントロールの見た目を細かくカスタマイズできるようになります。詳細はこちら。実は昨年のJavaFX Advent Calendarのエントリです。

nodamushi.hatenablog.com

JEP 257は、javafx.mediaモジュール(javafx.scene.mediaパッケージ)が内部で利用しているGStreamerというライブラリが新しくなっているのでアップデートしようというものです。それまではかなり古いバージョンのGStreamerを使用しており、バージョンアップに際して相応の修正が要求されたようです。

JEP 253/257 とも今年の3月には既に完成していて(開発自体は2015~2016年にかけて実施)、Java 9がリリースされるまで半年くらい温存されていたことになります。

続いて小さな変更です。

Public API to replace heavily-used internal API no longer accessible with Jigsaw は、Jigsawに備えて今まで多用されてきた内部API(内部APIが多用される時点であまりよろしくない気もしますが…)を公開APIで置き換えようというもの。これはJavaFX 9というよりJava 9全体で行われたことですね。

Better Hi-DPI support (with API control) on Mac, Windows, Linux はHiDPI対応が一通り完了したことを意味します。Macはかなり早い時期にHiDPI対応(Retina対応)が行われ、WindowsでもJava 8のUpdate 80以降でJavaFXのHiDPIがなされています。Java 9ではLinuxのGUIでもHiDPI対応となりました。同時期にJEP 263としてAWT & SwingのHiDPI対応もなされています。

最後の Update WebKit to newer version ですがWebViewが使用しているレンダリングエンジンWebKitのバージョンアップです。@khasunumaによると、実はJava 8の最新版(Update 152)と全く同じらしいですが。JEP 239としてJava 8 Update 60でのWebKitバージョンアップが行われていますが、さらに新しいバージョンアップか、それともJEP 239のことかは不明です。

WebKitとGStreamのバージョンアップについては一昨年のAdvent Calendarで青江 id:aoe-tk / @aoetk さんが言及されています。

aoe-tk.hatenablog.com

JavaFX 9の話題は昨年一昨年のAdvent Calendar でも見かけましたし、公式のWikiで変更点を見てもそれほどの量ではなく、Advent Calendarで紹介されたものの結局入らなかった機能がいくつもあります。JavaFX 9の新機能についてはもう語りつくされたと考えると、現時点ではブログに書くほどの話題はないのかもしれません。

こうした現状の中、ブログを書いてくださっている皆様、本当にありがとうございます。

まだブログを書いていらっしゃらない皆様、新機能でなくても、周りがあっと驚くものでなくても、JavaFXのコードを書かなかったとしても、JavaFXの話題であれば何でも構いませんので、ぜひご参加ください。

明日は平田あづみが再びミュージックプレーヤーの作成に挑むそうです。明後日はHTMLEditorコントロールについて私が書きます。

Java 8で作成したJavaFXアプリケーションをJava 9で動かす

このエントリは、JavaFX Advent Calendar 2017 の 4 日目です。昨日は @boochnich さんの「JavaFXとHiDPI」、明日は今のところ未定です。

昨年はわたしの誕生日枠で JavaFX の 3D 機能を使って小惑星のビューワを作成しました。

 

blog.yumix.net

 

今回はこのビューワをJava 9に対応させる方法について調べてみました。

方法1: Java 8 で作成したアプリケーションをそのまま動かす

javacの -source と -target がともに 1.8 (または 8) の場合、特に変更することはありません。互換性は維持されていますのでご安心を。JDK 9の新機能を利用できないデメリットはありますが、とりあえず何もしなくても動作するのはお手軽です。なお、JDK 8は -source / -target に 1.8 と 8 のどちらかでも指定できるようになっていますが、JDK 9 では 1.9 は指定できず 9 のみ使用できます。

方法2: Java 9 のモジュール機能を使用してプロジェクトを修正する

本来はこちらの方法が推奨なのでしょう。まずは、ソースファイルのレイアウトからご覧ください。

f:id:yumix_h:20171203025621p:plain

Java 8 までとの相違点は以下の通りです。

  • src ディレクトリ以下にパッケージをまとめるディレクトリ(この例ではasteroid)を作成する。Eclipseではパッケージ扱いされるのでなんかキモい。
  • 上記のフォルダにJavaのソースファイル等とmodule-info.javaファイルを格納する。

Eclipse Oxygen 1a組み込みのMavenはバージョンが古いのか、挙動不審な点が多々見られました。最新版のMavenをセットアップして、そちらを使うように設定したほうがよさそうです。

訂正:Eclipse 4.7.1aでは、Maven形式のプロジェクトではJava 9のJigsawは使えないようです。EclipseのJavaプロジェクトで作成して正常に動いたプログラムをMaven形式に変換した途端にjava.lang.module.FindExceptionで動作しなくなったので、原因はMavenにあるとみて間違いなさそうです。MavenというツールそのものがJava 9のJigsawに対応できていないのか、それともEclipseのMaven周りの問題なのかは、今のところ不明です。

さて、問題なのは module-info.java をどう書けばよいかです。Jigsawのメリットとして使わないモジュールを除外できるというのがあります(特にjavapackagerでネイティブ版を作成したときは効果大です)。でも、JDK 9のドキュメントにはモジュール間の依存関係は書いてあるのですが、JDK 8までのように「とりあえず全部」が難しくなっています。

JDK 9では何もしないとjava.baseというモジュールが使えます。残念ながらその中にJavaFXのモジュールは含まれていません。そこで、module-info.javaにJavaFXのモジュールを取り込むように設定する必要があります(そのため、JDK 9ではファイルのレイアウトが変わります)。

JavaFXのモジュール依存関係を見てみると、javafx.baseを起点としていくつかのスーパーセットが定義されています。そして一番広範囲に API をカバーしているモジュールは、javafx.fxml、javafx.media、javafx.web、javafx.swingの4種類です。つまりこの4モジュールを取り込めば、JDK 8とほぼ同じ範囲の API が使えるようになります。

とりあえず動けばいいや、と思う方は以下のように module-info.java を記述すればたぶん大丈夫です。

module asteroid {
    requires javafx.web;
requires javafx.fxml;
requires javafx.media;
requires javafx.swing;

モジュール名は、モジュールをまとめるディレクトリ名(今回の例ではasteroid)と一致するようにすればOK。 

モジュールについて感覚がつかめてきたら、取り込むモジュールをもっと範囲の狭いもの(javafx.controlsなど)に絞り、使わないものは除外すると、特にjavapackagerでJDKと一緒にパッケージしたときサイズが小さくなります。

結論: Eclipseの場合、普通のJavaプロジェクト(Maven形式でない)に限り、Java 9で動作させることができるようです。

JavaFX Advent Calendar 2017、もうすぐ始まります

わたしが毎年参加させていただいていた "JavaFX Advent Calendar"、今年はどなたも主宰される様子がなかったので、僭越ながらわたしが主催します。今までの感謝の気持ちが先走って、肝心のネタがまだ見つかっていないのですが。

皆さんぜひ、参加してみてください。

qiita.com

※ただし、平田あづみ(id:planet-az)は義務なのでよろしく。

※あと、@btnrouge (a.k.a. @khasunuma) はさっさと参加表明しなさい。

2017年8月の部分月食

こんばんは。

 

8月8日の午前2時過ぎから4時過ぎにかけて、全国的に部分月食が見られるようです。当日は曇りの予報(東京)で天気がちょっと心配ですが、コンディションが良ければ南西の空で徐々にかけてゆく月の姿が見られるでしょう。

www.nao.ac.jp

 

今月は流星群(ペルセウス座流星群)も見られます。夜空を見上げるのが楽しみになりますね。

 

Surface Pro 3、再び

こんばんは。

 

わたしの手元に、再びSurface Pro 3がやってきました。

頂き物です。というか、補償です。

中古で、電源コネクタのところにやっちゃった感丸出しの大きな傷はありますが、今のところ問題なく動いています。

 

最初に電源入れたとき、Windows 8.1の懐かしい画面が出てきたので、Microsoftアカウントの設定だけ済ませてすぐにWindows 10へとアップグレードしたのですが、どこかでライセンス認証すると言われるかと思いきや、最後まで何も言われなかったです。前の持ち主が一度アップグレードしたか、もしくはわたしが以前のSurface Pro 3でWindows 10へアップグレードした記録がMicrosoftアカウントに存在したのか、定かではありませんが、結果オーライということで。

 

 

実はOfficeがついていないのですが、ブラウザのOffice OnlineやGoogle Docsで事足りそうだし、Windows Inkとかで十分遊べそうだから、しばらくはこのままでいいかなとも思っています。

 

ではまた。

Google Domains

お久しぶりです。

 

唐突ですけど、Googleがドメインの取り扱いまで始めたようです。

domains.google.com

 

何だか面白そうなので、"yumix.net"を移管させて…いる途中です。

ここには10~20分で終わると書いてあったのに、もう30分以上待たされています。

お名前.comから応答がないっぽい。お名前.comの移管状況確認見ても何にも載っていないし、ちゃんと移管できるの? →1時間くらい経ったら移管始まった。よかった