watermint.org - Takayuki Okazaki's note

Akka + JavaFX Proof of Concept

Since GUI framework like JavaFX requires always run on main thread for handle events/manipurating UI properties. This usually cause unexpected behaviors. Fextile trying to separate layout specific codes, handling events, manipurating UI properties, and business logic on top of Akka async messaging framework.

Defining layout is very similar to JavaFX/ScalaFX applications.

object MyApp extends FextileApp {
  // Do layout just like JavaFX/ScalaFX application
  stage = new PrimaryStage {
    title = "My Application"
    width = 800
    height = 600
    scene = new Scene {
      fill = Color.BLUE
    }
  }

  override def props: Option[Props] = Some(Props[MyApp])
}

For all events from scene graph are transfered to actors on Akka.

class MyApp extends Actor {
  override def receive: Receive = {
    case (s: Scene, e: MouseClicked) =>
      s.fill = Color.RED

    case (_, _: WindowHidden) =>
      Fextile.shutdown()
  }
}

code on github: semester/semester-foundation-fextile

Product/Service GA/EOL/EOSL dates

Glossary

  • GA … General Availability
  • EOL … End of Life. End of support for enhancement and/or bug fix.
  • EOSL … End of Service Life. End of support for both bug fix and security fix.
  • TBD … To be determined.

Programming Languages

Ruby (MRI)

Version GA EOL EOSL
1.9.3 2011-10-31 2014-02-23 2015-02-25
2.0.0 2013-02-24 TBD (2015-02?) TBD (2016-02?)
2.1 2013-12-25 TBD (2015-12?) TBD (2016-12?)
2.2 2014-12-25 TBD (2016-12?) TBD (2017-12?)

PHP

Version GA EOL EOSL
5.4 2012-03-01 2014-09-14 2015-09-14
5.5 2013-06-20 2015-06-20 2016-06-20
5.6 2014-08-28 2016-08-28 2017-08-28

Java SE

Version GA Public EOL
5.0 2004-05 2009-10
6 2006-12 2013-02
7 2011-06 2015-04
8 2014-04 TBD

Database

MySQL

Version GA Public EOL
5.0 2005-10-15 2012-01-09
5.1 2008-11-27 2013-12-31
5.5 2010-12-03  
5.6 2013-02-05  

KVS

Redis

Version GA EOL/EOSL
2.4 2011-10-18 2012-11-29(?)
2.6 2012-10-24 2013-12-11(?)
2.8 2013-11-22  
3.0 TBD  

Server OS

Reference

Debian (Server)

Version GA EOL/EOSL
6.0 (Squeeze) LTS 2011-02-06 2016-02-06
7.0 (Wheezy) 2013-05-04 TBD

Ubuntu (Server)

Version GA EOL/EOSL
10.04 LTS 2010-04-29 2015-04
12.04 LTS (Precise) 2012-04-26 2017-04
14.04 LTS (Trusty) 2014-04-17 2019-04

CentOS

Version GA EOL EOSL
3 2004-03-19 2006-06-20 2010-10-31
4 2005-03-09 2009-03-31 2012-02-29
5 2007-04-12 2014-Q1 2017-03-31
6 2011-07-11 2017-Q2 2020-11-30
7 2014-07-07 2020-Q4 2024-06-30

Mobile OS

Reference

iOS

Version GA EOL/EOSL
6 2012-09-19 2013-02-21(?)
7 2013-09-18 2014-06-30(?)
8 2014-09-17 TBD
  • No explicit EOL/EOSL policy found. Guessing EOL/EOSL dates from latest update of each version.
  • iOS 6.x latest update: iOS 6.1.6
  • iOS 7.x latest update: iOS 7.1.2

Android

Version GA EOL/EOSL
3.2 (API level 13) 2011-06-15 2012-02(?)
4.0 (API level 14/15) 2011-10-18 2012-03-29(?)
4.1 (API level 16) 2012-07-09 2012-10-09(?)
4.2 (API level 17) 2012-11-13 2013-02-11(?)
4.3 (API level 19) 2013-07-24 2013-10-03(?)
4.4 (API level 20) 2013-10-31 2014-06-19(?)
5.0 (API level 21) 2014-11-12 TBD

Using ELK(ElasticSearch 1.4.2 + Logstash 1.4.2 + Kibana 4 Beta3)

Demonstration on ELK on Mac OS X (Yosemite)

Download

  • http://www.elasticsearch.org/overview/elkdownloads/

Setup - ElasticSearch

$ unzip elasticsearch-1.4.2.zip

Configure

Configure elasticsearch to allow connection from Kibana4. Add following two lines into $ELASTICSEARCH_HOME/conf/elasticsearch.yml

http.cors.enabled: true
http.cors.allow-origin: /.*/

Startup

$ ./bin/elasticsearch

Test

$ curl localhost:9200

Logstash 1.4.2

$ unzip logstash-1.4.2.zip

You have to replace elasticsearch libraries inside logstash.

  • https://github.com/elasticsearch/kibana/issues/1629#issuecomment-64172892
  • logstash contains old version of elasticsearch (1.1.1).
  • Kibana4 requires elasticsearch 1.4.0 or higher.
$ cd logstash-1.4.2/vendor/jar
$ rm -fr elasticsearch-1.1.1
$ unzip $YOUR_DOWNLOAD_DIR/elasticsearch-1.4.2.zip

Test configuration

Save file like below as test-logstash.conf

input {
  file {
    type => "apache"
    path => "/var/log/apache2/access_log"
  }
}

output {
  elasticsearch {
    host => localhost
  }
}

Startup

$ ./bin/logstash -f test-logstash.conf

Test

$ sudo apachectl start
$ curl localhost

Kibana 4 Beta 3

$ unzip kibana-4.0.0-beta3.zip

Startup

$ ./bin/kibana

Test

Open http://localhost:5601 with your browser. Configure index pattern with time-based events.

  • Check “Index contains time-based events”
  • Index name or pattern: logstash-*
  • Choose Time-field name: @timestamp

Kibana4.png

Twitter Bootstrap like UI framework for JavaFX/ScalaFX

Feeling of Applications

Applications which running on iOS, Android, Windows, and OS X have nearly identical user experience. There are guidelines of fonts, color, margins, etc for labels, buttons, etc including effects or animation for action. User experience guidelines are publicly available for developers like below.

Application developers and designers refer these guidelines, then design UI/UX for their applications. For iOS and Windows Phones have official review for publishing on application store. Applications may reject when their applications are not compatible with design guidelines.

Twitter Bootstrap

However, there are no reviews for cross platform applications like web applications. Web applications may have different feeling compared to their native applications. Of course, we could find guidelines or best practices for web application UI/UX design. For example, Bootstrap is well known UI framework for designing web applications. Bootstrap is collection of CSS/JavaScript to define UI component and their categories. Defined UI components are like

  • Red button for destructive operation like delete file, delete repository, etc.
  • Yellow text region for attention to the user to describe warnings.

Bootstrap UI components

Bootstrap also have customization feature, called theme, to define own color scheme, fonts, sizes, etc.

JavaFX and UI framework

JavaFX is a new UI framework running on Java. JavaFX have varieties of UI components, like buttons, tab pane, tables, lists, sliders etc.

JavaFX UI components

However, at least I know, there is no UI framework like Twitter Bootstrap. There are no definitions like button for destructive operation, warning text, approval operation, etc. That’s why I started development of UI framework for JavaFX/ScalaFX.

Fextile; UI framework for JavaFX/ScalaFX

Fextile is my project name which coined from JavaFX and textile. On the begining of the project, I just thought it’s easy to port Bootstrap’s CSS into JavaFX because JavaFX has similar feature called JavaFX CSS. But there are no compatibility except syntax. So I needed to create both JavaFX CSS and class libraries.

Current implementation of Fextile built based upon ScalaFX. ScalaFX is a DSL/wrapper of JavaFX on Scala.

Sample 1

package fextile.sample

import fextile._
import scalafx.application.JFXApp
import scalafx.scene.control.Label

object Sample1 extends JFXApp {
  lazy val sample = new VContainer {
    content = Seq(
      new H1 {
        text = "Fextile Sample"
      },
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
      },
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
        styleClass = Seq("text-primary")
      }
    )
  }

  stage = new JFXApp.PrimaryStage {
    title = "Fextile"
    width = 800
    height = 600

    // use fextile.Scene instead of scalafx.scene.Scene
    scene = new Scene {
      root = sample
    }
  }
}

Sample1; simple header and labels. First label uses default fonts, size and color. Second label uses “text-primary” class on Bootstrap. Fextile also defines “text-muted”, “text-warning”, etc.

Sample 2 - Wider screen

Sample 2; responsive layout. This sample is responsive to screen width. On wider screen, texts are aligned as two columns.

Sample 2 - Narrow screen

package fextile.sample

import fextile._
import scalafx.scene.control.Label
import scalafx.application.JFXApp

object Sample2 extends JFXApp {
  lazy val sample2 = new GridRow {
    add(
      new H1 {
        text = "Responsive"
      },
      xs12, sm12, md12, lg12
    )
    add(
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
      },
      xs12, sm6, md6, lg6
    )
    add(
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
        styleClass = Seq("text-primary")
      },
      xs12, sm6, md6, lg6
    )
  }

  stage = new JFXApp.PrimaryStage {
    title = "Fextile"
    width = 800
    height = 600

    // use fextile.Scene instead of scalafx.scene.Scene
    scene = new Scene {
      root = sample2
    }
  }
}

For narrow screen, text are aligned as one column.

Sample3

Sample 3; screen to screen navigation. This sample uses screen to screen navigation component like UINavigationController in iOS. Screen scroll left on “Next” button pressed.

Fextile is on early starge of development. If you’d like to have more components. Please send me pull-requests on github. Thanks.

JavaFXアプリケーションの手触り感をととのえる、Fextile

この記事はJavaFX Advent Calendar 2013の13日目、昨日はorekyuuさんのJavaFXでTwitterクライアント作ってみた。でした。

手触り感

iOSや、Android、Windows、OS Xのアプリケーションは、アプリケーションの製作者が違っていてもだいたい同じような手触り感があります。これはラベルの配置や色、スペースの取り方、フォントのような見栄えはもちろんのこと、ボタンをおしたときのフィードバック、画面遷移の時のエフェクトなどさまざまな振る舞いがOSやUIフレームワークによってルールが規定されているためです。規定はたとえば次のようにガイドラインとして公開されています。

アプリケーション開発者はこれを参照し、アプリケーションに必要なUI/UXを作り上げていきます。iOSやWindows Phoneアプリケーションのように、アプリケーション公開までに審査があるようなケースではガイドラインに沿っていないアプリケーションは排除されるなどOSやデバイス全体のエコシステムとして手触り感の統一をしています。

クロスプラットホームの場合<

ではWebアプリケーションの場合はどうでしょうか。WebアプリケーションはデバイスやOS、Webブラウザの種別やプラグインなどによって左右されることもありますが、モダンなデバイス/OSからであればたいていの環境で同じように動作します。この場合、iOSならではの手触り感、Androidならではの手触り感といったOSごとの手触り感とは違う別の手触り感が表現されることになります。Webアプリケーションでもいくつかルールやマナーはありますが、審査等はありませんので厳格かつ広く守られているガイドラインのようなモノは存在しません。

自由にデザインできるという反面、自由度が高すぎて制作コストが高くなったり、制作期間が長引いてしまうというデメリットもあります。このような課題に対して、近年ではTwitter BootstrapのようにWebのデザインルールを決めたCSSやJavaScriptライブラリを使い、アプリケーションのテイストに合わせてテーマなどをカスタマイズする手法がとられることが多くなりました。

Bootstrap UI components

ヘッダやボタン、ラベルがある程度のカテゴリにわけられているため、Webアプリケーション開発者・デザイナーはこれらのカテゴリを利用してデザインを決定します。カテゴリと色やサイズなどはCSSとして分離されているため、プロトタイプ開発時にはデフォルトのデザインで作成しておき、リリース時には適切なブランドカラーを配置するなどデザイン作業に余裕が生まれます。

JavaFX

クロスプラットホームのUIを作る手段としてJavaはすでによく用いられています。一昔前はJavaアプレットがあまりにも重いという印象で敬遠されることもありましたが、近年では高速化も進み、10年ほど前のユーザエクスペリエンスが低い状態ではなくなりました。ただJavaのUIフレームワークはAWTとSwingという10年ほど前の状態からあまり進歩していませんでした。その間にはMicrosoftのSilverlightやAdobe AirなどデスクトップアプリケーションのためのUIライブラリが続々と登場し差は広がる一方でした。

2008年にはJavaFX Scriptとして、新しく既存のAWT・Swingに変わるUIフレームワークが発表されました。当初、JavaFX ScriptとしてJava言語とは別の新しいプログラミング言語を使ってUIを構成するようにプロジェクトは進んでいましたが、紆余曲折の末、AWTやSwingと同様にJava言語から利用できるUIフレームワークと位置づけられてJavaFX 2がリリースされました。JavaFX 2ではWebKitエンジンを組み込んだモダンなWebView等を始めとして強力なコンポーネントが追加されました。クロスプラットホームで利用可能なUIフレームワークとして新たな選択肢が登場したといえます。

JavaFXと手触り感

JavaFXには、ボタン、タブ、リストやテーブルなど多くのコントロールが提供されています。これらのデザインはプログラムから変更したり、JavaFX CSSをつかって外部ファイルにて定義することができます。

JavaFX UIのコントロール

JavaFXのコントロールは、一定のデザインテイストで制作されているためボタンやタブ、スクロールバーなどの手触り感は共通しています。ただ、ファイル削除など「破壊的な操作をするためのボタン」とか、決済をするための「同意をするためのボタン」といったユーザに対する意図を伝えるためのカテゴリ分けまでは定義されていません。このため開発者はそれぞれアプリケーションの都合に合わせて色やサイズを変えることになるのですが、自由度が高すぎて制作コストが高くなったりします。

さて、この話何か見覚えがあります。これを解決するためには、Twitter BootstrapのようなUIフレームワークがJavaFX向けにあればいいのではないか。早速、そういったライブラリがないか探してみました。ただ、ある程度探してみた限りでは求めているようなUIフレームワークは見当たりませんでした。無ければ作るしかありません。

JavaFX向けのTwitter Bootstrapを作る

さて、JavaFXには前述の通りJavaFX CSSというCSSライクな機能が提供されています。ではTwitter BootstrapのCSSをそのまま移植すればよいのではないかというのが最初の考えでした。ただ、残念ながらJavaFX CSSとCSSは直接的な互換性はなく、またJavaFX CSSからは指定できない項目があるなど簡単な移植ではすまないということが分かり、JavaFX CSSと合わせてクラスライブラリも作成することにしました。

Java言語で作ってもよかったのですが、今回は最近勉強中のScala言語を使って実装することにしました。ScalaにはScalaFXというScalaからJavaFXを利用するためのライブラリがありますので、ScalaFXをベースに作ることにしました。

Fextile<

ライブラリの名前はFextileにしました。テキスタイル(Textile; 織物、布地)とJavaFXを何となく合わせた造語です。まずはデザインテイストを全体的にTwitter Bootstrapに合わせてデザインし、実際のアプリケーションをデザインしながら優先度の高いコンポーネントを製作しました。でき上がったのが次のサンプルのようなコンポーネントです。

Sample 1

package fextile.sample

import fextile._
import scalafx.application.JFXApp
import scalafx.scene.control.Label

object Sample1 extends JFXApp {
  lazy val sample = new VContainer {
    content = Seq(
      new H1 {
        text = "Fextile Sample"
      },
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
      },
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
        styleClass = Seq("text-primary")
      }
    )
  }

  stage = new JFXApp.PrimaryStage {
    title = "Fextile"
    width = 800
    height = 600

    // use fextile.Scene instead of scalafx.scene.Scene
    scene = new Scene {
      root = sample
    }
  }
}

ヘッダとテキスト。サンプルではテキストの色はデフォルトのものと、Twitter Bootstrapでのtext-primary相当のものを使っています。JavaFX CSS側にはtext-muted、text-warningなど他のクラスを定義されていますので、利用シーンごとに指定を変えて使います。

次のサンプルではデバイスや画面の広さによってコンポーネントの配置が適切に変更されるような、いわゆるレスポンシブデザインをサポートしたコンポーネントを利用しています。

Sample 2 - 画面が広い場合

画面が狭くなると、2列に表示されていたコンポーネントは1列に整列し直されます。

Sample 2 - 画面が狭い場合

package fextile.sample

import fextile._
import scalafx.scene.control.Label
import scalafx.application.JFXApp

object Sample2 extends JFXApp {
  lazy val sample2 = new GridRow {
    add(
      new H1 {
        text = "Responsive"
      },
      xs12, sm12, md12, lg12
    )
    add(
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
      },
      xs12, sm6, md6, lg6
    )
    add(
      new Label {
        text = "Lorem ipsum dolor sit amet, ex sit tempor ceteros interesset. Per ei epicuri complectitur, has quodsi accumsan consetetur eu. Vis at meis quando, ne nec ullum instructior. Vel dolore alienum explicari et, hinc inermis corpora vel an, nominati inciderint eam ad. Cum ex dolor malorum vituperata, cu possit equidem accusata cum."
        wrapText = true
        styleClass = Seq("text-primary")
      },
      xs12, sm6, md6, lg6
    )
  }

  stage = new JFXApp.PrimaryStage {
    title = "Fextile"
    width = 800
    height = 600

    // use fextile.Scene instead of scalafx.scene.Scene
    scene = new Scene {
      root = sample2
    }
  }
}

次のサンプルではiOSのUINavigationControllerのように、1つの画面から左から右へとより詳細な情報を表示するためのコンポーネントを使っています。ボタンを押すと、画面全体が左へスライドし新しい画面が表示されます。

Sample3

いまのところこれだけですが、比較的実用的になってきました。これから実際のアプリケーションを実装する過程では、まだ多くのリファクタリングやコンポーネント追加が必要になりますが、簡単なユースケース向けにはひとまず形としてでき上がったかなと思っています。

FextileはMITライセンスにてオープンソースとして公開しておりますので、同じような問題で悩まれている方はぜひお使いいただき、新しい提案もいただければ幸いです。