Slide 1

Slide 1 text

JRubyFX For Web Developers

Slide 2

Slide 2 text

When I was a little boy I wanted to build cool apps

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

A programmer’s best friend

Slide 9

Slide 9 text

The minimum standard is that the software has to work for me

Slide 10

Slide 10 text

JavaFX

Slide 11

Slide 11 text

Why not shoes? or GTK? Or X?

Slide 12

Slide 12 text

1.0 1.1 1.2 1.3 1.3.1 2.0-2.2 8

Slide 13

Slide 13 text

What’s cool

Slide 14

Slide 14 text

SceneBuilder

Slide 15

Slide 15 text

CSS .default-color0.chart-series-line { -fx-stroke: #CC0000; } .default-color1.chart-series-line { -fx-stroke: #FF6600; } .default-color2.chart-series-line { -fx-stroke: #FFCC00; } .default-color0.chart-line-symbol { -fx-background-color: #CC0000, white; } .default-color1.chart-line-symbol { -fx-background-color: #FF6600, white; } .default-color2.chart-line-symbol { -fx-background-color: #FFCC00, white; }

Slide 16

Slide 16 text

ScenicView

Slide 17

Slide 17 text

ControlsFX

Slide 18

Slide 18 text

java 8u40 / OpenJFX dialogs

Slide 19

Slide 19 text

AquaFX for that native look and feel

Slide 20

Slide 20 text

Automaton require_relative '../lib/brakeman_pro' require 'lib/automaton.jar' java_import 'com.athaydes.automaton.FXer' java_import 'com.athaydes.automaton.FXApp' FXApp.start_app( BrakemanPro::Main.new ); fxer = FXer.get_user_with( FXApp.scene.root ) fxer.click_on("text:Add Group").wait_for_fx_events fxer.type("Yo mama").click_on("text:Save")

Slide 21

Slide 21 text

Polish You can distribute apps as a jar or as a native application with various installers ● deb/rpm ● OSX Applications (bundles) / dmg / pkg ● exe / msi for windows The JVM is included in the package.

Slide 22

Slide 22 text

JRubyFX

Slide 23

Slide 23 text

For web developers

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

DAFUQ

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Using the DSL

Slide 31

Slide 31 text

Using FXML

Slide 32

Slide 32 text

Contols Buttons Labels VBox HBox SplitPane BorderPane AnchorPane ListView TableView TreeView TreeTableView

Slide 33

Slide 33 text

Property binding

Slide 34

Slide 34 text

The not so ideal way

Slide 35

Slide 35 text

The more better way

Slide 36

Slide 36 text

Binding to events

Slide 37

Slide 37 text

def handle_click event # do stuff # event.target == @b end

Slide 38

Slide 38 text

@b.set_on_action do |event| # do stuff end

Slide 39

Slide 39 text

But inline event handlers are bad Prefer binding in controller code over on* attributes in fxml unless your component is tiny

Slide 40

Slide 40 text

The selection model API is much more powerful

Slide 41

Slide 41 text

don’t bind to “click” events, bind to the selected_item property

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

Custom Elements module BrakemanPro module Controls class CodeViewer < Java::javafx::scene::control::VBox include JRubyFX::Controller fxml "result_category_pane.fxml" … def update_code code @webview.get_engine.load_content(content, "text/html") end

Slide 44

Slide 44 text

Controller class MainWindow include JRubyFX::Controller fxml "main.fxml" def some_function @main_pane.center = CodeViewer.new @split_pane.items.add(@code_viewer) @code_viewer.update_code(warning.location) end end

Slide 45

Slide 45 text

Starting the app class Main < JRubyFX::Application def start(stage) title = "Brakeman Pro" with(stage, title: title, resizable: true) do fxml MainWindow show end end end

Slide 46

Slide 46 text

Design Tip (follow at your own risk) ● Make components as small as possible ● Have each component belong to an object, or prefer composition over inheritance. depends. ● If the object won’t change, bind properties ● If the object will change, use a “repaint” strategy

Slide 47

Slide 47 text

Performance Tips ● Store “pages” in memory ● Track “dirty regions” ● Update on change (or bind) ● The fewer elements, the faster the process ● Perform (most) code in event handlers in a run_later

Slide 48

Slide 48 text

Threads Possibly the best part of JRuby

Slide 49

Slide 49 text

Don’t block the main thread

Slide 50

Slide 50 text

run_later { update_ui }

Slide 51

Slide 51 text

A simple, performant pattern

Slide 52

Slide 52 text

FXCollections and Java 8

Slide 53

Slide 53 text

(filtering demo)

Slide 54

Slide 54 text

What isn’t cool Exception in thread "JavaFX Application Thread" org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `int' for RubyWrapperBeanAdapter:Class at RUBY.getConstantValue(.../jrubyfx-fxmlloader-0.4-java/lib/fxmlloader/rrba.rb:607) at RUBY.constructValue(.../jrubyfx-fxmlloader-0.4-java/lib/fxmlloader/real_elts.rb:85) at RUBY.processStartElement(.../jrubyfx-fxmlloader-0.4-java/lib/fxmlloader/value_elts.rb:62) at FxmlLoader.processStartElement(.../jrubyfx-fxmlloader-0.4-java/lib/jrubyfx-fxmlloader.rb:440) at RUBY.load(.../jrubyfx-fxmlloader-0.4-java/lib/jrubyfx-fxmlloader.rb:351) at RUBY.load_fxml(.../jrubyfx-1.1.1-java/lib/jrubyfx/controller.rb:266) at RUBY.initialize_controller(.../jrubyfx-1.1.1-java/lib/jrubyfx/controller.rb:248) at RUBY.new(.../jrubyfx-1.1.1-java/lib/jrubyfx/controller.rb:157) at RUBY.initialize(...brakeman-pro/lib/brakeman_pro/controller/details_controller.rb:12)

Slide 55

Slide 55 text

What isn’t cool I’ve yet to be able to use a release, always pointing to master Project activity is… bursty Java

Slide 56

Slide 56 text

Where I’ve been wrong Composition vs Inheritance

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

Resources http://code.makery.ch/java/javafx-8-tutorial-intro www.GuiGarage.com Mastering javafx 8 controls