電子にノーと言う! 高速JavaFXデスクトップアプリケーションの作成

最近、プログラマーフォーラム(例えば、 こちらこちらこちら今日の こちらをご覧ください)で、Electronとそのデスクトップアプリケーションの開発への影響について、少なからず議論が始まっています。

Electronがわからない場合、これは本質的にWebブラウザ( Chromium )であり、Webアプリケーションのみが動作します...実際のデスクトッププログラムのように(いいえ、これは冗談ではありません)...これにより、Webスタックを使用してクロスプラットフォームデスクトップを開発できますアプリケーション。

最近の最新の流行に敏感なデスクトップアプリは、 SlackVS CodeAtom、 GitHub Desktopなど、Electronで作成されています 。 並外れた成功。

私たちは何十年もデスクトッププログラムを書いてきました。 一方、ウェブは20年足らず前に開発され始めたばかりで、ほとんどの時間、ドキュメントとアニメーションGIFを配信するだけでした。 誰もそれを使って本格的なアプリケーションを作成したわけではありません。

10年前は、Webアプリケーションのスタックを使用してデスクトップアプリケーションを作成できると想像することはできませんでした。 しかし、2017年が到来し、多くの賢い人々がElectronは素晴らしいアイデアだと信じています!

これは、アプリケーションを作成するためのWebスタックの優位性の結果ではありません(そのような優位性からはほど遠いため、 Webが混乱であると主張することはほとんどありません)が、デスクトップでUIを開発するための既存のフレームワークの失敗です。 開発のためにJavaScript(sarcasm)などの優れたツールを使用するためだけにWebブラウザー全体をプログラムとともに出荷することを好む場合、何かが完全に間違っていました。

それでは、Webスタックとの競争に負けたこれらの恐ろしい選択肢は何でしょうか?

私はこれらのテクノロジーの1つで実際のアプリケーションを調べて作成することにしました。

Electronの代替


複数の開発チームが異なるOS向けに異なるバージョンのアプリケーションを作成することを気にしない場合、オプションは次のようになります。AppKitfor MacOS、 WPF for Windows(私は特定のプラットフォームの開発のスペシャリストではないので、どのオプションを教えてください最近はもっと人気があります)。

ただし、Electronの本当の競争相手はマルチプラットフォームフレームワークです。 それらの中で、今日最も人気があるのはGTK +Qt 、およびJavaFXです。

GTK +


GTK +はCで記述されていますが、 他の多くの言語に関連付けられています 。 このフレームワークは、美しいGNOME-3プラットフォームの開発に使用されました。

Qt


私の目を引いた議論で、QtはElectronの最も人気のある選択肢のようです...これはC ++ライブラリですが、 他の言語にも関連しています (ただし、商業ベースでサポートされているものはないようです。 Qtは組み込みシステムの一般的な選択肢のようです。

Javafx


ただし、この記事では、JavaFXとJVMはデスクトッププログラムに適していると考えているため、JavaFXを使用したデスクトップアプリケーションの開発に専念します。

JVMについてどう考えても、他のプラットフォームはありません(おそらく、Electron自体以外に)。これは、クロスプラットフォーム開発にとって非常に簡単です。 jarを任意のプラットフォームで作成したら、すべてのOSのユーザーに配布できます-それは機能します。

JVMで現在サポートされている多種多様な言語では、言語の選択も問題になりません:間違いなくあなたが好きなものがあります(それを拒否できない場合はJavaScriptを含みます )、そして任意のJVM言語でJavaFXを使用できます問題なく。 この記事では、Javaのほかに、 Kotlinにいくつかのコードを示します。

UI自体は、コード( IntelliJEclipse、またはNetBeansから素晴らしいIDEサポートがある場合のみ)で作成されます。これらはすべて、競合他社よりも優れた優れた無料のIDEであり、ちなみにJavaのデスクトップアプリケーションの最良の例ですUIコンストラクター: SceneBuilder (IntelliJに統合可能)またはNetBeans Visual Debugger

JavaFXの歴史

JavaFXは新しいテクノロジーではありません。 彼女は2008年12月に登場し、今日見られるものとは非常に異なっていました。 アイデアは、90年代後半から公式のJVMフレームワークであった時代遅れのSwingフレームワークを置き換えるために、最新のUIフレームワークを作成することでした。

Oracleは最初からすべてをほぼ台無しにし、UIアプリケーションの作成に使用されるはずの特別な宣言型言語の作成を開始しました。 これはJava開発者にはあまり受け入れられず、その取り組みはJavaFXをほぼ台無しにしました。

この問題に気づいたOracleは、独自の特別な言語を使用せずに2011年にJavaFX 2をリリースし、代わりにFXMLを純粋なJavaコードのオプションとして使用することにしました(後で説明します)。

2012年頃、JavaFXはある程度の人気を獲得し、オラクルはこのプラットフォームの改善と普及に多大な努力をしました。 バージョン2.2以降、JavaFXフレームワークはかなり堅固なフレームワークになりましたが、標準のJavaランタイムには含まれていませんでした(常にJDKに付属していました)。

JavaFX 8(Java 8に合わせてバージョンが変更された)でのみ、標準Javaランタイムの一部になりました。

現在、JavaFXフレームワークはUIの世界では主要なプレーヤーではないかもしれませんが、多くの実際のアプリケーションを作成し接続されたライブラリがかなりあり、モバイルプラットフォームに移植されています

JavaFXアプリケーションの作成


LogFXログを表示するためのアプリケーションでは、Java(基本的にかなり低レベルのコードがあるため、速度と小さなパケットサイズに集中したかったため)とIntelliJをIDEとして使用することにしました。 私はほとんどKotlinで書くことにしましたが、IntelliJでのJavaサポートは非​​常に優れていることが判明したので、Javaで書く(より正確には、IntelliJに任せることは真実に近い)ことは、余分な0.9 MB配布キット。

プログラムのインターフェースが非常に単純であるため、FXML(JavaFX用のXMLベースのGUI)またはビジュアルUIコンストラクターを使用しないことにしました。

だから、いくつかのコードを見てください!

Java Hello World


JavaFX — , javafx.application.Application JavaFX Stage.

Hello World JavaFX:

 public class JavaFxExample extends Application {

     @Override
     public void start(Stage primaryStage) throws Exception {
         Text helloWorld = new Text("Hello world");
         StackPane root = new StackPane(helloWorld);
         primaryStage.setScene(new Scene(root, 300, 120));
         primaryStage.centerOnScreen();
         primaryStage.show();
     }

     public static void main(String[] args) {
         launch(JavaFxExample.class, args);
     }
 }
src/main/java/main/JavaFxExample.java

«» :



FXML+Java Hello World


UI , FXML:

 <?xml version="1.0" encoding="UTF-8"?>

 <?import javafx.scene.layout.StackPane?>
 <?import javafx.scene.Scene?>
 <?import javafx.scene.text.Text?>
 <Scene xmlns="http://javafx.com/javafx"
        width="300.0" height="120.0">
     <StackPane>
         <Text>Hello world</Text>
     </StackPane>
 </Scene>
src/main/resources/main/Example.fxml

 public class JavaFxExample extends Application {

     @Override
     public void start(Stage primaryStage) throws Exception {
         Scene scene = FXMLLoader.load(getClass().getResource("Example.fxml"));
         primaryStage.setScene(scene);
         primaryStage.centerOnScreen();
         primaryStage.show();
     }

     public static void main(String[] args) {
         launch(JavaFxExample.class, args);
     }
 }
src/main/java/main/JavaFxExample.java

, IntelliJ FXML Java , , , , , … , FXML, UI … FXML. , FXML.

Hello World Kotlin+TornadoFX


, , Kotlin JavaFX, TornadoFX:

 class Main : App() {
     override val primaryView = HelloWorld::class
 }

 class HelloWorld : View() {
     override val root = stackpane {
         prefWidth = 300.0
         prefHeight = 120.0
         text("Hello world")
     }
 }
src/main/kotlin/main/app.kt

Kotlin JavaFX, ( TornadoFX « ») 5  .

( ), Kotlin JavaFX.

JavaFX


, JavaFX, , JavaFX.

, JavaFX.

, , :




(, ) — :

 root.setBackground(new Background(new BackgroundFill(
         Color.DARKSLATEGRAY, CornerRadii.EMPTY, Insets.EMPTY)));

 helloWorld.setStroke(Color.WHITE);

— CSS:

 root.setStyle("-fx-background-color: darkslategray");
 helloWorld.setStyle("-fx-stroke: white");

, IntelliJ .

FXML:

 <StackPane style="-fx-background-color: darkslategray">
     <Text style="-fx-stroke: white">Hello world</Text>
 </StackPane>




, JavaFX ! , .

:

 .root {
     -fx-base: darkslategray;
 }

 Text {
     -fx-stroke: white;
 }
src/main/resources/css/hello.css

Scene:

 primaryStage.getScene().getStylesheets().add("css/hello.css");

.

, StackPane darkslategray, .

, «» , . , . , , .

, , «» , :

 -fx-stroke: ladder(-fx-base, white 49%, black 50%);

JavaFX , . CSS Reference Guide.

, . , , :


: JavaFX. : ,

, , , .

LogFX :



, FontAwesome. CSS. , :

 Font.loadFont( LogFX.class.getResource( "/fonts/fontawesome-webfont.ttf" ).toExternalForm(), 12 );

. , Linux Mint:



, JavaFX. , .

, JavaFX… , .

JavaFX . ( GroovyFX):



:

 Text {
     -fx-fill: white;
 }

 #logfx-text-log {
     -fx-font-family: sans-serif;
     -fx-font-weight: 700;
     -fx-font-size: 70;
     -fx-fill: linear-gradient(to top, cyan, dodgerblue);
 }

 #logfx-text-fx {
     -fx-font-family: sans-serif;
     -fx-font-weight: 700;
     -fx-font-size: 86;
     -fx-fill: linear-gradient(to top, cyan, dodgerblue);
     -fx-effect: dropshadow(gaussian, dodgerblue, 15, 0.25, 5, 5);
 }

. . .

, (), (hot reload) .

,


. UI «» UI.

JavaFX ( JVM) .

SceneBuilder


SceneBuilder, UI, FXML, UI.



Java IDE, ().

SceneBuilder , - -, .

, SceneBuilder, - , SceneBuilder — .

ScenicView


, ScenicView .

.



ScenicView jar -javaagent:/path-to/scenicView.jar JVM.

ScenicView , Javadocs .

JVM


, UI, Java . Oracle JVM HotSpot. , OpenJDK JVM.

: .

HotSpot VM DCEVM (Dynamic Code Evolution VM) : / , / , . JVM.

LogFX — . , , , - Stage… , UI, ScenicView ScenicBuilder .

DCEVM JVM. — IDE .

IntelliJ (Cmd+F9 «»):




JavaFX . LogFX , — .

LogFX — , FileChangeWatcher, .

, ( jar).

, .

, . , ( , ).

( jar), , Unix/Mac Windows. , :

 private static String toAbsoluteFileUri( File file ) {
     String absolutePath = file.getAbsolutePath();
     if ( File.separatorChar == '\\' ) {
         // windows stuff
         return "file:///" + absolutePath.replace( "\\", "/" );
     } else {
         return "file:" + absolutePath;
     }
 }

Mac, Windows Linux Mint. , ( — , Mac, ). JavaFX .

, , , :

 Runnable resetStylesheet = () -> Platform.runLater( () -> {
     scene.getStylesheets().clear();
     scene.getStylesheets().add( stylesheet );
 } );

. , ScenicView ( jar), TornadoFX , .


JavaFX . JavaFX- ( JavaFX , ), … - , - - JVM.

LogFX, , , , . , :

curl -sSfL https://jcenter.bintray.com/com/athaydes/logfx/logfx/0.7.0/logfx-0.7.0-all.jar -o logfx.jar

, jar 303 . 0,3 , TTF, HTML CSS, Java!

, JVM, JVM ! Java 9 , JVM, jar, , ( JVM 35  21  ).

LogFX 50  RAM ( , JavaFX). , :

java -Xmx50m -jar logfx.jar

Electron, 200  .

JavaFX , . — . , JNLP Java WebStart, , , Getdown FxLauncher, , Install4J (, Install4J open source).

JavaFX, , , , , :

Source: https://habr.com/ru/post/J339382/


All Articles