SlideShare a Scribd company logo
1 of 130
Download to read offline
Gerrit Grunwald | Developer Advocate | Azul
ABOUT ME...
diabetes
sucks
monitoring


24/7
MONITORING 24/7
DESKTOP APP
The Swift
SWIFT DESKTOP APP
MacOS APP
Show value and history


Last 30 days average


Pattern of last week


Time in range


Settings


Has system tray icon
THE
QUESTION
JAVA FX...?
Can I create that same app in
WINDOWS
Native looking
NATIVE LOOKING WINDOWS
Properties
Title


Buttons for minimize, maximize, close


Resizeable


Draggable


Rounded corners on Macos


Support dark and light themes !


Have toolbuttons, text
fi
elds etc. on Macos !!!
NATIVE LOOKING WINDOWS
Rounded corners
Close, Minimize, Maximize buttons Title
NATIVE LOOKING WINDOWS
Text
fi
eld
Buttons
Greater height
CSS
So let's try to create such a window using
NATIVE LOOKING WINDOWS IN CSS
BorderPane
BorderPane
LAYOUT...
AnchorPane (top)
BorderPane
AnchorPane (top)
LAYOUT...
AnchorPane (top)
HBox
BorderPane
AnchorPane (top)
HBox
LAYOUT...
AnchorPane (top)
BorderPane
AnchorPane (top)
Circle
Circle
Circle
HBox
LAYOUT...
AnchorPane (top)
BorderPane
Region (center)
Region (center)
AnchorPane (top)
Circle
Circle
Circle
HBox
LAYOUT...
Height: 52.5px
Corner radius: 10px rgb(2, 2, 2)
rgb(117, 115, 116)
rgb(133, 131, 132)
rgb(47, 46, 47)
DropShadow
DESIGN HEADER...
tip...
screenshot
Tool
colorpicker
Tool
.header {
-fx-min-height : 52.5;
-fx-max-height : 52.5;
-fx-pref-height : 52.5;
-fx-background-insets: 0, 0.5 0.5 0 0.5, 1 1 0 1, 1.5 1 0 1;
-fx-background-radius: 10 10 0 0, 9.5 9.5 0 0, 9.5 9.5 0 0, 8.5 8.5 0 0;
-fx-background-color : rgb(2, 2, 2),
linear-gradient(to bottom, rgb(117, 115, 115) 0%,
rgb(99, 98, 98) 20%,
rgb(99, 98, 98) 100%),
rgb(133, 131, 132),
rgb(47, 46, 47);
-fx-effect : dropshadow(gaussian, rgba(0, 0, 0, 0.35),
1, 0, 0, 1.5)
}
CSS HEADER...
(Zoomed)
CSS styled AnchorPane .header
public class SimpleHeaderDemo extends Application {




private static final String STYLE = "simple-styles.css";


private AnchorPane header;


@Override public void init() {


header = new AnchorPane();


header.getStyleClass().add("header");


}


@Override public void start(final Stage stage) {


BorderPane pane = new BorderPane();


pane.setPrefSize(600, 200);


pane.setPadding(new Insets(20));


pane.setTop(header);


Scene scene = new Scene(pane);


scene.getStylesheets()


.add(SimpleHeaderDemo.class.getResource(STYLE)


.toExternalForm());


stage.setTitle("Header Demo");


stage.setScene(scene);


stage.show();


stage.centerOnScreen();


}


}


CODE HEADER...
Corner radius: 10px
rgb(2, 2, 2)
rgb(84, 82, 81)
rgb(32, 34, 34)
DESIGN BODY...
.body {
-fx-background-insets: 0, 0 0.5 0.5 0.5, 0 1 1 1;
-fx-background-radius: 0 0 10 10, 0 0 9.5 9.5, 0 0 9.5 9.5;
-fx-background-color : rgb(2, 2, 2),
rgb(84, 82, 81),
rgb(32, 28, 28);
}
CSS BODY...
CSS styled Region .body
(Zoomed)
public class SimpleHeaderDemo extends Application {




private static final String STYLE = "simple-styles.css";


private AnchorPane header;


private Region body;


@Override public void init() {


header = new AnchorPane();


header.getStyleClass().add("header");


body = new Region();


body.getStyleClass().add("body");


}


@Override public void start(final Stage stage) {


BorderPane pane = new BorderPane();


pane.setPrefSize(400, 400);


pane.setPadding(new Insets(20));


pane.setTop(header);


pane.setCenter(body);


Scene scene = new Scene(pane);


scene.getStylesheets()


.add(SimpleHeaderDemo.class.getResource(STYLE)


.toExternalForm());


stage.setTitle("Header Demo");


stage.setScene(scene);


stage.show();


stage.centerOnScreen();


}


}


CODE
.header {
-fx-min-height : 52.5;
-fx-max-height : 52.5;
-fx-pref-height : 52.5;
-fx-background-insets: 0, 0.5 0.5 0 0.5, 1 1 0 1, 1.5 1 0 1;
-fx-background-radius: 10 10 0 0, 9.5 9.5 0 0, 9.5 9.5 0 0, 8.5 8.5 0 0;
-fx-background-color : rgb(2, 2, 2),
rgb(133, 131, 132),
linear-gradient(to bottom, rgb(117, 115, 115) 0%,
rgb(99, 98, 98) 20%,
rgb(99, 98, 98) 100%),
rgb(47, 46, 47);
-fx-effect : dropshadow(gaussian, rgba(0, 0, 0, 0.35),
1, 0, 0, 1.5)
}
.body {
-fx-background-insets: 0, 0 0.5 0.5 0.5, 0 1 1 1;
-fx-background-radius: 0 0 10 10, 0 0 9.5 9.5, 0 0 9.5 9.5;
-fx-background-color : rgb(2, 2, 2),
rgb(84, 82, 81),
rgb(32, 28, 28);
}
CSS
THE RESUL
T
Distance: 8px
Radius: 6px
rgb(236, 107, 95)
rgb(244, 190, 79)
rgb(91, 87, 87) rgb(38, 193, 56)
Distance: 22px
DESIGN BUTTONS...
public class CircleButton extends Circle {




public enum Type {


CLOSE("close"),


MINIMIZE("minimize"),


MAXIMIZE("maximize");


public final String style;


Type(final String style) {


this.style = style;


}


}


public CircleButton(final Type type) {


super(6);


getStyleClass().add(type.style);


}


}


CODE BUTTON...
.close {
-fx-fill : rgb(236, 107, 95); /* RED */
-fx-stroke: derive(rgb(236, 107, 95), -10%);
}
.minimize {
-fx-fill : rgb(244, 190, 79); / * YELLOW */
-fx-stroke: derive(rgb(244, 190, 79), -10%);
}
.maximize {
-fx-fill : rgb(38, 193, 56); /* GREEN */
-fx-stroke: derive(rgb(38, 193, 56), -10%);
}
.close:disabled,
.minimize:disabled,
.maximize:disabled {
-fx-fill : rgb(91, 87, 87); /* GRAY */
-fx-stroke: derive(rgb(91, 87, 87), -10%);
}
CSS BUTTON...
public class SimpleHeaderDemo extends Application {




private static final String STYLE = "simple-styles.css";


private HBox buttonBox;


private AnchorPane header;


private Region body;


@Override public void init() {


CircleButton close = new CircleButton(Type.CLOSE);


CircleButton minimize = new CircleButton(Type.MINIMIZE);


CircleButton maximize = new CircleButton(Type.MAXIMIZE);


buttonBox = new HBox(8, close, minimise, maximize);


buttonBox.setAlignment(Pos.CENTER);


AnchorPane.setTopAnchor(buttonBox, 0d);


AnchorPane.setBottomAnchor(buttonBox, 0d);


AnchorPane.setLeftAnchor(buttonBox, 22d);


header = new AnchorPane(buttonBox);


header.getStyleClass().add("header");


body = new Region();


body.getStyleClass().add("body");


}


@Override public void start(final Stage stage) {...}


}


CODE...
ORIGINAL JAVA FX
ORIGINAL JAVA FX
stage.initStyle(StageStyle.TRANSPARENT)
You need to take care of Resizing + Dragging !!!
SHADOWS


Some tips related to
LAYOUTS...
Dropshadows within
AnchorPane (top)
Region (center)
DropShadow
SHADOWS
"Same" code no shadow...
Left side shows no shadow


Right side shows shadow
why...?
WRONG ORDER...
BorderPane borderPane = new BorderPane();


borderPane.setTop(header);


borderPane.setCenter(content);
AnchorPane anchorPane = new AnchorPane(header, content);


AnchorPane.setTopAnchor(lowerLeftHeader, 0d);


AnchorPane.setRightAnchor(lowerLeftHeader, 0d);


AnchorPane.setLeftAnchor(lowerLeftHeader, 0d);


AnchorPane.setTopAnchor(lowerLeftContent, 50d);


AnchorPane.setRightAnchor(lowerLeftContent, 0d);


AnchorPane.setLeftAnchor(lowerLeftContent, 0d);


2nd
1st
2nd
1st
RIGHT ORDER...
BorderPane borderPane = new BorderPane();


borderPane.setCenter(content);


borderPane.setTop(header);
AnchorPane anchorPane = new AnchorPane(content, header);


AnchorPane.setTopAnchor(lowerLeftHeader, 0d);


AnchorPane.setRightAnchor(lowerLeftHeader, 0d);


AnchorPane.setLeftAnchor(lowerLeftHeader, 0d);


AnchorPane.setTopAnchor(lowerLeftContent, 50d);


AnchorPane.setRightAnchor(lowerLeftContent, 0d);


AnchorPane.setLeftAnchor(lowerLeftContent, 0d);


1st
2nd
1st
2nd
WINDOWS...
Dropshadows for custom
BorderPane


setE
ff
ect(new DropShadow())
DropShadow
Stage
SHADOWS...
Custom windows
Add the shadow the BorderPane


No shadow will show


There is no space to draw the
shadow
SHADOWS...
Custom windows
Add another Region


Keep the Region transparent


Add padding to left, right, bottom


Add the BorderPane to the
Region


Apply the shadow to the
BorderPane
BorderPane


setE
ff
ect(new DropShadow())
DropShadow
Stage
Transparent Region
back to the
buttons...
HOVERED
NORMAL
svg
public class CircleButton extends Circle {




public enum Type {


CLOSE("close"),


MINIMIZE("minimize"),


MAXIMIZE("maximize");


public final String style;


Type(final String style) {


this.style = style;


}


}


public CircleButton(final Type type) {


super(6);


getStyleClass().add(type.style);


}


}
CODE BUTTON...
extends Circle
public class CircleButton extends StackPane {




public enum Type {


CLOSE("close"),


MINIMIZE("minimize"),


MAXIMIZE("maximize");


public final String style;


Type(final String style) {


this.style = style;


}


}


private final Region icon;


public CircleButton(final Type type) {


super();


icon.getStyleClass().add("icon")


getChildren().setAll(icon);


getStyleClass().add(type.style);


}


}
CODE BUTTON...
extends StackPane
Region icon
.close:hover .icon {
-fx-scale-shape : false;
-fx-shape : "M 2,2.5 l 2,0 l 0,2.5 l 2.5,0 l 0,2
l -2.5,0 l 0,2.5 l -2,0 l 0,-2.5
l -2.5,0 l 0,-2 l 2.5,0 l 0,-2.5 z";
}
CSS BUTTON...
adding points to the SVG shape...
.close:hover .icon {
-fx-background-color: rgb(55, 52, 52);
-fx-scale-shape : false;
-fx-shape : "M 2,2.5 l 2,0 l 0,2.5 l 2.5,0 l 0,2
l -2.5,0 l 0,2.5 l -2,0 l 0,-2.5
l -2.5,0 l 0,-2 l 2.5,0 l 0,-2.5 z";
}
CSS BUTTON...
set the
fi
ll color
.close:hover .icon {
-fx-rotate : 45;
-fx-background-color: rgb(55, 52, 52);
-fx-scale-shape : false;
-fx-shape : "M 2,2.5 l 2,0 l 0,2.5 l 2.5,0 l 0,2
l -2.5,0 l 0,2.5 l -2,0 l 0,-2.5
l -2.5,0 l 0,-2 l 2.5,0 l 0,-2.5 z";
}
CSS BUTTON...
rotate the shape by 45°
USE VECTOR DRAWING PROGRAM...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/
svg11.dtd">
<svg width="12px" height="12px" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://
www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-
miterlimit:2;">
<path d="M5,2.5l2,0l0,2.5l2.5,0l0,2l-2.5,0l0,2.5l-2,0l0,-2.5l-2.5,0l0,-2l2.5,0l0,-2.5z"
style="fill:#090909;"/>
</svg>
DEMO BUTTON HOVER...
another
example...
MACOS DROPDOWN...
MacOS
JavaFX
MACOS DROPDOWN...
CODE MACOS DROPDOWN...
public class Demo extends Application {


private Region arrows;


private StackPane arrowButton;


private Label label;


private HBox dropdownBox;


@Override public void init() {


arrows = new Region();


arrows.getStyleClass().add("arrows");


arrowButton = new StackPane(arrows);


arrowButton.getStyleClass().add("arrow-button");


HBox.setHgrow(arrowButton, Priority.NEVER);


HBox.setMargin(arrowButton, new Insets(0, 2, 0, 0));


label = new Label("JavaFX");


label.getStyleClass().add("box-label");


label.setAlignment(Pos.CENTER_LEFT);


HBox.setHgrow(label, Priority.ALWAYS);


dropdownBox = new HBox(5, label, arrowButton);


dropdownBox.getStyleClass().add("dropdown-box");


dropdownBox.setAlignment(Pos.CENTER_RIGHT);


}


@Override public void start(final Stage stage) {


StackPane pane = new StackPane(dropdownBox);


...
.arrow-button StackPane


with .arrows Region childnode
CSS MACOS DROPDOWN...
.root * {


BUTTON-COLOR : rgb(51, 101, 207);


SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%);


}


.arrow-button {


-fx-min-width : 16px;


-fx-min-height : 16px;


-fx-max-width : 16px;


-fx-max-height : 16px;


-fx-pref-width : 16px;


-fx-pref-height : 16px;


-fx-background-insets: 0px;


-fx-background-radius: 3.25px;


}


3.25px
16px
16px
Set the dimensions and radius for


the .arrow-button StackPane
(StackPane)
CSS MACOS DROPDOWN...
.root * {


BUTTON-COLOR : rgb(51, 101, 207);


SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%);


}


.arrow-button {


-fx-min-width : 16px;


-fx-min-height : 16px;


-fx-max-width : 16px;


-fx-max-height : 16px;


-fx-pref-width : 16px;


-fx-pref-height : 16px;


-fx-background-insets: 0px;


-fx-background-radius: 3.25px;


-fx-background-color : linear-gradient(to bottom,


derive(BUTTON-COLOR, 20%) 0%,


BUTTON-COLOR 20%,


BUTTON-COLOR 100%)


}


Set the
fi
ll for


the .arrow-button StackPane
(StackPane)
Linear Gradient
CSS MACOS DROPDOWN...
.root * {


BUTTON-COLOR : rgb(51, 101, 207);


SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%);


}


.arrow-button {


-fx-min-width : 16px;


-fx-min-height : 16px;


-fx-max-width : 16px;


-fx-max-height : 16px;


-fx-pref-width : 16px;


-fx-pref-height : 16px;


-fx-background-insets: 0px, 0.5px;


-fx-background-radius: 3.25px, 2.85px;


-fx-background-color : linear-gradient(to bottom,


derive(BUTTON-COLOR, 20%) 0%,


BUTTON-COLOR 20%,


BUTTON-COLOR 100%),


white;


}


2.85px
Added second layer with
fi
ll color white
(StackPane)
0.5px
CSS MACOS DROPDOWN...
.root * {


BUTTON-COLOR : rgb(51, 101, 207);


SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%);


}


.arrow-button {


-fx-min-width : 16px;


-fx-min-height : 16px;


-fx-max-width : 16px;


-fx-max-height : 16px;


-fx-pref-width : 16px;


-fx-pref-height : 16px;


-fx-background-insets: 0px, 0.5px;


-fx-background-radius: 3.25px, 2.85px;


-fx-background-color : linear-gradient(to bottom,


derive(BUTTON-COLOR, 20%) 0%,


BUTTON-COLOR 20%,


BUTTON-COLOR 100%),


BUTTON-COLOR;


}


Outer layer
fi
lled with gradient,


inner layer
fi
lled with solid color
Highlight
(StackPane)
CSS MACOS DROPDOWN...
.root * {


BUTTON-COLOR : rgb(51, 101, 207);


SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%);


}


.arrow-button {


-fx-min-width : 16px;


-fx-min-height : 16px;


-fx-max-width : 16px;


-fx-max-height : 16px;


-fx-pref-width : 16px;


-fx-pref-height : 16px;


-fx-background-insets: 0px, 0.5px;


-fx-background-radius: 3.25px, 2.85px;


-fx-background-color : linear-gradient(to bottom,


derive(BUTTON-COLOR, 20%) 0%,


BUTTON-COLOR 20%,


BUTTON-COLOR 100%),


BUTTON-COLOR;


-fx-effect : dropshadow(two-pass-box, rgba(0, 0, 0, 0.65),


1, 0.0, 0, 0.5);


}


Drop Shadow
Adding a dropshadow
(StackPane)
CSS MACOS DROPDOWN...
.root * {


BUTTON-COLOR : rgb(51, 101, 207);


SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%);


}


.arrow-button {


-fx-min-width : 16px;


-fx-min-height : 16px;


-fx-max-width : 16px;


-fx-max-height : 16px;


-fx-pref-width : 16px;


-fx-pref-height : 16px;


-fx-padding : 2.5px 4.5px 2.5px 4.5px;


-fx-background-insets: 0px, 0.5px;


-fx-background-radius: 3.25px, 2.85px;


-fx-background-color : linear-gradient(to bottom,


derive(BUTTON-COLOR, 20%) 0%,


BUTTON-COLOR 20%,


BUTTON-COLOR 100%),


BUTTON-COLOR;


-fx-effect : dropshadow(two-pass-box, rgba(0, 0, 0, 0.65),


1, 0.0, 0, 0.5);


}


.arrow-button > .arrows {


-fx-background-insets: 0;


-fx-background-color : white;


-fx-position-shape : true;


-fx-scale-shape : false;


-fx-shape : "M8.047, ... 8.002,2.525Z";


}


4.5px 4.5px
2.5px
2.5px
Adding a SVG shape


to .arrows Region
(StackPane)
(Region)
MACOS DROPDOWN...
MacOS
JavaFX styled
WHEN TO USE CSS...?
Use CSS when...
...you use standard controls


...your control inherits a standard control


...it has an impact on many controls


...the environment is already using CSS


...creating a library and want total control


...the customer should be able to customize the app
back to the
idea...
desktop


app...
gluCOSTATUSFX
Re-styled ToggleButton


using CSS
Icons implemented
using SVGPath
Chart implemented
using Canvas
SWIFT JAVA FX
ToggleButton
HBox ToggleButton ToggleButton
SWIFT JAVA FX
Custom Switch control
SWIFT JAVA FX
SWIFT JAVA FX
SWIFT JAVA FX
SWIFT JAVA FX
TRAYICON
The
Makes use of AWT (EDT* + FXAT**) !!!


Only supports images !!!


Sizes di
ff
er on operating systems


Macos, Windows, Linux***
FXTRAYICON
FXTrayIcon library
*** not all all distributions
** FX Application Thread
* Event Dispatch Thread
Onl
y
images!!!
public BufferedImage createTextTrayIcon(String text, Color color) {
final int width = 64;
final int height = 18;
final double fontSize = 14;
final double x = 32;
final double y = 14;
Canvas canvas = new Canvas(width, height);
GraphicsContext ctx = canvas.getGraphicsContext2D();
ctx.setFont(Fonts.sfProRoundedRegular(fontSize));
ctx.setTextAlign(TextAlignment.CENTER);
ctx.setFill(color);
ctx.fillText(text, x, y);
final WritableImage img = new WritableImage(width, height);
final SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
canvas.snapshot(parameters, img);
return SwingFXUtils.fromFXImage(img, null);
}
FXTRAYICON
FXTrayIcon library
Draw text in Canvas node


Take a snapshot of the node


Create a Bu
ff
eredImage


Display the image as tray icon


Sync EDT and FXAT !!!
JAVA FX...?
Can I create that same app in
Yes...!
web...?
jpro
Demo...
DESKTOP JPRO
DESKTOP JPRO
Full size pane instead
of dialog
DESKTOP JPRO
DESKTOP JPRO
DESKTOP JPRO
JPRO APP
Advantages of using JPro
Large parts of the code can be re-used


Performance is good


Easy to start with for Java developers


Runs on every HTML5 capable browser


Is very close to the desktop version


Can run in docker container


Dark/light mode support
JPRO APP
Disadvantages of using JPro
Need a server/cloud infrastructure to run on


Multiuser setup is tricky running on one instance


Dialogs are di
ff
erent from Desktop


No accent color support
Mobile...?
gluon
Demo...
SWIFT JAVA FX
Desktop style buttons
SWIFT JAVA FX
Full size pane instead
of dialog
Desktop style buttons
SWIFT JAVA FX
SWIFT JAVA FX
SWIFT JAVA FX
Desktop style Sliders
GLUON APP
Advantages of using Gluon
Large parts of the code can be re-used


Performance is NOT the problem


Easy to start with for Java developers


Runs on iOS and Android


Can be adjusted for each platform


Can be published on app stores
GLUON APP
Disadvantages of using Gluon
No real native UI out of the box (better on Android)


Problem with 24/7 apps (no native background tasks)


No support for iOS widgets and watch faces


Sound is handled di
ff
erently than on desktop


No accent color support


No dark/light mode support


No automatic locale detection
tip...
Separate
branches
for web +
Mobile
AppleFX
APPLE FX...
Native looking UI's on Macos
APPLE FX...
Native looking UI's on Macos
Demo...
NATIVE UI...
CANVAS
Let's take a look at
CANVAS NODE
Advantages of using Canvas
Just one node


You have "full" control


Fast


Flexible


99% compatible with HTML5 canvas
CANVAS NODE...
Disadvantages of using Canvas
No direct interaction with shapes


Layout is your job (no layout container)


Cleanup and redraw is your job


Not testable


Content is not styleable using CSS*
* partly possible using StyleableProperties
when to
use it...?
CANVAS NODE...
When to use it...
Complex graphics needed


Pixel based graphics needed


Performance needed


No interaction needed


Full control needed


Games


On graphical restricted devices (e.g. Raspberry Pi)
CANVAS NODE...
Examples
Complex Controls
Shape E
ff
ects
CANVAS NODE...
Examples
Pixel based charts
CANVAS NODE...
Examples
Complex Charts
CANVAS NODE...
Examples
Games
CANVAS NODE...
Examples
EXAMPLE
Number of nodes
Label
28 Nodes
TextField
CheckBox
RadioButton
2 Nodes
3 Nodes
3 Nodes
5 Nodes
ComboBox
Button 2 Nodes
NUMBER OF NODES...
NUMBER OF NODES...
Analyse...
Matrix


GridPane


Simple labels


Styled with CSS
NUMBER OF NODES...
NUMBER OF NODES...
saves 86
nodes in 1
control
PERFORMANCE
Some tips about
PERFORMANCE...
Avoid deeply nested layout structures


Reduce number of nodes


Avoid using e
ff
ects


Apply e
ff
ects to groups instead of single nodes


Keep track of dirty state when override layoutChildren()


Use Canvas if needed


Cache nodes before doing animations
Things to keep in mind
PERFORMANCE...
Be aware of FXApplicationThread


Avoid inlining CSS


Know your target platform


Avoid using transparent stages if possible


Disable layout of unused nodes (setManaged(true/false))
Things to keep in mind
MayTheForceBeWithYou II.pdf
MayTheForceBeWithYou II.pdf

More Related Content

Similar to MayTheForceBeWithYou II.pdf

Flash Camp - Degrafa & FXG
Flash Camp - Degrafa & FXGFlash Camp - Degrafa & FXG
Flash Camp - Degrafa & FXGjmwhittaker
 
Introduction to Coding
Introduction to CodingIntroduction to Coding
Introduction to CodingFabio506452
 
Patrick Kettner - Creating magic with houdini
Patrick Kettner - Creating magic with houdiniPatrick Kettner - Creating magic with houdini
Patrick Kettner - Creating magic with houdiniOdessaJS Conf
 
Start your app the better way with Styled System
Start your app the better way with Styled SystemStart your app the better way with Styled System
Start your app the better way with Styled SystemHsin-Hao Tang
 
Responsive Design for Data Visualization
Responsive Design for Data VisualizationResponsive Design for Data Visualization
Responsive Design for Data VisualizationMika Aldaba
 
Learn to Love CSS3 [English]
Learn to Love CSS3 [English]Learn to Love CSS3 [English]
Learn to Love CSS3 [English]ThemePartner
 
I Can't Believe It's Not Flash
I Can't Believe It's Not FlashI Can't Believe It's Not Flash
I Can't Believe It's Not FlashThomas Fuchs
 
Creating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfCreating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfShaiAlmog1
 
Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017
Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017
Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017Codemotion
 
Learn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing LanguageLearn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing Languageshelfrog
 
Learn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing LanguageLearn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing LanguageW M Harris
 
Learn to love CSS3 | Joomla! Day Deutschland
Learn to love CSS3 | Joomla! Day DeutschlandLearn to love CSS3 | Joomla! Day Deutschland
Learn to love CSS3 | Joomla! Day DeutschlandThemePartner
 
Componentization css angular
Componentization css angularComponentization css angular
Componentization css angularDavid Amend
 
Powerpointpresentation.c
Powerpointpresentation.cPowerpointpresentation.c
Powerpointpresentation.cMaqbool Ur Khan
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonAlex Payne
 

Similar to MayTheForceBeWithYou II.pdf (20)

Flash Camp - Degrafa & FXG
Flash Camp - Degrafa & FXGFlash Camp - Degrafa & FXG
Flash Camp - Degrafa & FXG
 
ES6, WTF?
ES6, WTF?ES6, WTF?
ES6, WTF?
 
Introduction to Coding
Introduction to CodingIntroduction to Coding
Introduction to Coding
 
Accelerated Stylesheets
Accelerated StylesheetsAccelerated Stylesheets
Accelerated Stylesheets
 
Patrick Kettner - Creating magic with houdini
Patrick Kettner - Creating magic with houdiniPatrick Kettner - Creating magic with houdini
Patrick Kettner - Creating magic with houdini
 
Start your app the better way with Styled System
Start your app the better way with Styled SystemStart your app the better way with Styled System
Start your app the better way with Styled System
 
Anthony Starks - deck
Anthony Starks - deckAnthony Starks - deck
Anthony Starks - deck
 
Responsive Design for Data Visualization
Responsive Design for Data VisualizationResponsive Design for Data Visualization
Responsive Design for Data Visualization
 
Learn to Love CSS3 [English]
Learn to Love CSS3 [English]Learn to Love CSS3 [English]
Learn to Love CSS3 [English]
 
I Can't Believe It's Not Flash
I Can't Believe It's Not FlashI Can't Believe It's Not Flash
I Can't Believe It's Not Flash
 
CSS3 ...in 3D!
CSS3 ...in 3D!CSS3 ...in 3D!
CSS3 ...in 3D!
 
Creating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfCreating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdf
 
Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017
Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017
Building a theming system with React - Matteo Ronchi - Codemotion Amsterdam 2017
 
Learn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing LanguageLearn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing Language
 
Learn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing LanguageLearn Creative Coding: Begin Programming with the Processing Language
Learn Creative Coding: Begin Programming with the Processing Language
 
CSS3 pronti all'uso
CSS3 pronti all'usoCSS3 pronti all'uso
CSS3 pronti all'uso
 
Learn to love CSS3 | Joomla! Day Deutschland
Learn to love CSS3 | Joomla! Day DeutschlandLearn to love CSS3 | Joomla! Day Deutschland
Learn to love CSS3 | Joomla! Day Deutschland
 
Componentization css angular
Componentization css angularComponentization css angular
Componentization css angular
 
Powerpointpresentation.c
Powerpointpresentation.cPowerpointpresentation.c
Powerpointpresentation.c
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 

Recently uploaded

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 

Recently uploaded (20)

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 

MayTheForceBeWithYou II.pdf

  • 1.
  • 2. Gerrit Grunwald | Developer Advocate | Azul ABOUT ME...
  • 7. SWIFT DESKTOP APP MacOS APP Show value and history Last 30 days average Pattern of last week Time in range Settings Has system tray icon
  • 9. JAVA FX...? Can I create that same app in
  • 11. NATIVE LOOKING WINDOWS Properties Title Buttons for minimize, maximize, close Resizeable Draggable Rounded corners on Macos Support dark and light themes ! Have toolbuttons, text fi elds etc. on Macos !!!
  • 12. NATIVE LOOKING WINDOWS Rounded corners Close, Minimize, Maximize buttons Title
  • 14. CSS So let's try to create such a window using
  • 20. AnchorPane (top) BorderPane Region (center) Region (center) AnchorPane (top) Circle Circle Circle HBox LAYOUT...
  • 21. Height: 52.5px Corner radius: 10px rgb(2, 2, 2) rgb(117, 115, 116) rgb(133, 131, 132) rgb(47, 46, 47) DropShadow DESIGN HEADER...
  • 25. .header { -fx-min-height : 52.5; -fx-max-height : 52.5; -fx-pref-height : 52.5; -fx-background-insets: 0, 0.5 0.5 0 0.5, 1 1 0 1, 1.5 1 0 1; -fx-background-radius: 10 10 0 0, 9.5 9.5 0 0, 9.5 9.5 0 0, 8.5 8.5 0 0; -fx-background-color : rgb(2, 2, 2), linear-gradient(to bottom, rgb(117, 115, 115) 0%, rgb(99, 98, 98) 20%, rgb(99, 98, 98) 100%), rgb(133, 131, 132), rgb(47, 46, 47); -fx-effect : dropshadow(gaussian, rgba(0, 0, 0, 0.35), 1, 0, 0, 1.5) } CSS HEADER... (Zoomed) CSS styled AnchorPane .header
  • 26. public class SimpleHeaderDemo extends Application { private static final String STYLE = "simple-styles.css"; private AnchorPane header; @Override public void init() { header = new AnchorPane(); header.getStyleClass().add("header"); } @Override public void start(final Stage stage) { BorderPane pane = new BorderPane(); pane.setPrefSize(600, 200); pane.setPadding(new Insets(20)); pane.setTop(header); Scene scene = new Scene(pane); scene.getStylesheets() .add(SimpleHeaderDemo.class.getResource(STYLE) .toExternalForm()); stage.setTitle("Header Demo"); stage.setScene(scene); stage.show(); stage.centerOnScreen(); } } CODE HEADER...
  • 27. Corner radius: 10px rgb(2, 2, 2) rgb(84, 82, 81) rgb(32, 34, 34) DESIGN BODY...
  • 28. .body { -fx-background-insets: 0, 0 0.5 0.5 0.5, 0 1 1 1; -fx-background-radius: 0 0 10 10, 0 0 9.5 9.5, 0 0 9.5 9.5; -fx-background-color : rgb(2, 2, 2), rgb(84, 82, 81), rgb(32, 28, 28); } CSS BODY... CSS styled Region .body (Zoomed)
  • 29. public class SimpleHeaderDemo extends Application { private static final String STYLE = "simple-styles.css"; private AnchorPane header; private Region body; @Override public void init() { header = new AnchorPane(); header.getStyleClass().add("header"); body = new Region(); body.getStyleClass().add("body"); } @Override public void start(final Stage stage) { BorderPane pane = new BorderPane(); pane.setPrefSize(400, 400); pane.setPadding(new Insets(20)); pane.setTop(header); pane.setCenter(body); Scene scene = new Scene(pane); scene.getStylesheets() .add(SimpleHeaderDemo.class.getResource(STYLE) .toExternalForm()); stage.setTitle("Header Demo"); stage.setScene(scene); stage.show(); stage.centerOnScreen(); } } CODE .header { -fx-min-height : 52.5; -fx-max-height : 52.5; -fx-pref-height : 52.5; -fx-background-insets: 0, 0.5 0.5 0 0.5, 1 1 0 1, 1.5 1 0 1; -fx-background-radius: 10 10 0 0, 9.5 9.5 0 0, 9.5 9.5 0 0, 8.5 8.5 0 0; -fx-background-color : rgb(2, 2, 2), rgb(133, 131, 132), linear-gradient(to bottom, rgb(117, 115, 115) 0%, rgb(99, 98, 98) 20%, rgb(99, 98, 98) 100%), rgb(47, 46, 47); -fx-effect : dropshadow(gaussian, rgba(0, 0, 0, 0.35), 1, 0, 0, 1.5) } .body { -fx-background-insets: 0, 0 0.5 0.5 0.5, 0 1 1 1; -fx-background-radius: 0 0 10 10, 0 0 9.5 9.5, 0 0 9.5 9.5; -fx-background-color : rgb(2, 2, 2), rgb(84, 82, 81), rgb(32, 28, 28); } CSS
  • 31. Distance: 8px Radius: 6px rgb(236, 107, 95) rgb(244, 190, 79) rgb(91, 87, 87) rgb(38, 193, 56) Distance: 22px DESIGN BUTTONS...
  • 32. public class CircleButton extends Circle { public enum Type { CLOSE("close"), MINIMIZE("minimize"), MAXIMIZE("maximize"); public final String style; Type(final String style) { this.style = style; } } public CircleButton(final Type type) { super(6); getStyleClass().add(type.style); } } CODE BUTTON... .close { -fx-fill : rgb(236, 107, 95); /* RED */ -fx-stroke: derive(rgb(236, 107, 95), -10%); } .minimize { -fx-fill : rgb(244, 190, 79); / * YELLOW */ -fx-stroke: derive(rgb(244, 190, 79), -10%); } .maximize { -fx-fill : rgb(38, 193, 56); /* GREEN */ -fx-stroke: derive(rgb(38, 193, 56), -10%); } .close:disabled, .minimize:disabled, .maximize:disabled { -fx-fill : rgb(91, 87, 87); /* GRAY */ -fx-stroke: derive(rgb(91, 87, 87), -10%); } CSS BUTTON...
  • 33. public class SimpleHeaderDemo extends Application { private static final String STYLE = "simple-styles.css"; private HBox buttonBox; private AnchorPane header; private Region body; @Override public void init() { CircleButton close = new CircleButton(Type.CLOSE); CircleButton minimize = new CircleButton(Type.MINIMIZE); CircleButton maximize = new CircleButton(Type.MAXIMIZE); buttonBox = new HBox(8, close, minimise, maximize); buttonBox.setAlignment(Pos.CENTER); AnchorPane.setTopAnchor(buttonBox, 0d); AnchorPane.setBottomAnchor(buttonBox, 0d); AnchorPane.setLeftAnchor(buttonBox, 22d); header = new AnchorPane(buttonBox); header.getStyleClass().add("header"); body = new Region(); body.getStyleClass().add("body"); } @Override public void start(final Stage stage) {...} } CODE...
  • 35. ORIGINAL JAVA FX stage.initStyle(StageStyle.TRANSPARENT) You need to take care of Resizing + Dragging !!!
  • 39. SHADOWS "Same" code no shadow... Left side shows no shadow Right side shows shadow
  • 41. WRONG ORDER... BorderPane borderPane = new BorderPane(); borderPane.setTop(header); borderPane.setCenter(content); AnchorPane anchorPane = new AnchorPane(header, content); AnchorPane.setTopAnchor(lowerLeftHeader, 0d); AnchorPane.setRightAnchor(lowerLeftHeader, 0d); AnchorPane.setLeftAnchor(lowerLeftHeader, 0d); AnchorPane.setTopAnchor(lowerLeftContent, 50d); AnchorPane.setRightAnchor(lowerLeftContent, 0d); AnchorPane.setLeftAnchor(lowerLeftContent, 0d); 2nd 1st 2nd 1st
  • 42. RIGHT ORDER... BorderPane borderPane = new BorderPane(); borderPane.setCenter(content); borderPane.setTop(header); AnchorPane anchorPane = new AnchorPane(content, header); AnchorPane.setTopAnchor(lowerLeftHeader, 0d); AnchorPane.setRightAnchor(lowerLeftHeader, 0d); AnchorPane.setLeftAnchor(lowerLeftHeader, 0d); AnchorPane.setTopAnchor(lowerLeftContent, 50d); AnchorPane.setRightAnchor(lowerLeftContent, 0d); AnchorPane.setLeftAnchor(lowerLeftContent, 0d); 1st 2nd 1st 2nd
  • 44. BorderPane setE ff ect(new DropShadow()) DropShadow Stage SHADOWS... Custom windows Add the shadow the BorderPane No shadow will show There is no space to draw the shadow
  • 45. SHADOWS... Custom windows Add another Region Keep the Region transparent Add padding to left, right, bottom Add the BorderPane to the Region Apply the shadow to the BorderPane BorderPane setE ff ect(new DropShadow()) DropShadow Stage Transparent Region
  • 48. svg
  • 49. public class CircleButton extends Circle { public enum Type { CLOSE("close"), MINIMIZE("minimize"), MAXIMIZE("maximize"); public final String style; Type(final String style) { this.style = style; } } public CircleButton(final Type type) { super(6); getStyleClass().add(type.style); } } CODE BUTTON... extends Circle
  • 50. public class CircleButton extends StackPane { public enum Type { CLOSE("close"), MINIMIZE("minimize"), MAXIMIZE("maximize"); public final String style; Type(final String style) { this.style = style; } } private final Region icon; public CircleButton(final Type type) { super(); icon.getStyleClass().add("icon") getChildren().setAll(icon); getStyleClass().add(type.style); } } CODE BUTTON... extends StackPane Region icon
  • 51. .close:hover .icon { -fx-scale-shape : false; -fx-shape : "M 2,2.5 l 2,0 l 0,2.5 l 2.5,0 l 0,2 l -2.5,0 l 0,2.5 l -2,0 l 0,-2.5 l -2.5,0 l 0,-2 l 2.5,0 l 0,-2.5 z"; } CSS BUTTON... adding points to the SVG shape...
  • 52. .close:hover .icon { -fx-background-color: rgb(55, 52, 52); -fx-scale-shape : false; -fx-shape : "M 2,2.5 l 2,0 l 0,2.5 l 2.5,0 l 0,2 l -2.5,0 l 0,2.5 l -2,0 l 0,-2.5 l -2.5,0 l 0,-2 l 2.5,0 l 0,-2.5 z"; } CSS BUTTON... set the fi ll color
  • 53. .close:hover .icon { -fx-rotate : 45; -fx-background-color: rgb(55, 52, 52); -fx-scale-shape : false; -fx-shape : "M 2,2.5 l 2,0 l 0,2.5 l 2.5,0 l 0,2 l -2.5,0 l 0,2.5 l -2,0 l 0,-2.5 l -2.5,0 l 0,-2 l 2.5,0 l 0,-2.5 z"; } CSS BUTTON... rotate the shape by 45°
  • 54. USE VECTOR DRAWING PROGRAM... <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/ svg11.dtd"> <svg width="12px" height="12px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http:// www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke- miterlimit:2;"> <path d="M5,2.5l2,0l0,2.5l2.5,0l0,2l-2.5,0l0,2.5l-2,0l0,-2.5l-2.5,0l0,-2l2.5,0l0,-2.5z" style="fill:#090909;"/> </svg>
  • 59. CODE MACOS DROPDOWN... public class Demo extends Application { private Region arrows; private StackPane arrowButton; private Label label; private HBox dropdownBox; @Override public void init() { arrows = new Region(); arrows.getStyleClass().add("arrows"); arrowButton = new StackPane(arrows); arrowButton.getStyleClass().add("arrow-button"); HBox.setHgrow(arrowButton, Priority.NEVER); HBox.setMargin(arrowButton, new Insets(0, 2, 0, 0)); label = new Label("JavaFX"); label.getStyleClass().add("box-label"); label.setAlignment(Pos.CENTER_LEFT); HBox.setHgrow(label, Priority.ALWAYS); dropdownBox = new HBox(5, label, arrowButton); dropdownBox.getStyleClass().add("dropdown-box"); dropdownBox.setAlignment(Pos.CENTER_RIGHT); } @Override public void start(final Stage stage) { StackPane pane = new StackPane(dropdownBox); ... .arrow-button StackPane with .arrows Region childnode
  • 60. CSS MACOS DROPDOWN... .root * { BUTTON-COLOR : rgb(51, 101, 207); SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%); } .arrow-button { -fx-min-width : 16px; -fx-min-height : 16px; -fx-max-width : 16px; -fx-max-height : 16px; -fx-pref-width : 16px; -fx-pref-height : 16px; -fx-background-insets: 0px; -fx-background-radius: 3.25px; } 3.25px 16px 16px Set the dimensions and radius for the .arrow-button StackPane (StackPane)
  • 61. CSS MACOS DROPDOWN... .root * { BUTTON-COLOR : rgb(51, 101, 207); SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%); } .arrow-button { -fx-min-width : 16px; -fx-min-height : 16px; -fx-max-width : 16px; -fx-max-height : 16px; -fx-pref-width : 16px; -fx-pref-height : 16px; -fx-background-insets: 0px; -fx-background-radius: 3.25px; -fx-background-color : linear-gradient(to bottom, derive(BUTTON-COLOR, 20%) 0%, BUTTON-COLOR 20%, BUTTON-COLOR 100%) } Set the fi ll for the .arrow-button StackPane (StackPane) Linear Gradient
  • 62. CSS MACOS DROPDOWN... .root * { BUTTON-COLOR : rgb(51, 101, 207); SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%); } .arrow-button { -fx-min-width : 16px; -fx-min-height : 16px; -fx-max-width : 16px; -fx-max-height : 16px; -fx-pref-width : 16px; -fx-pref-height : 16px; -fx-background-insets: 0px, 0.5px; -fx-background-radius: 3.25px, 2.85px; -fx-background-color : linear-gradient(to bottom, derive(BUTTON-COLOR, 20%) 0%, BUTTON-COLOR 20%, BUTTON-COLOR 100%), white; } 2.85px Added second layer with fi ll color white (StackPane) 0.5px
  • 63. CSS MACOS DROPDOWN... .root * { BUTTON-COLOR : rgb(51, 101, 207); SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%); } .arrow-button { -fx-min-width : 16px; -fx-min-height : 16px; -fx-max-width : 16px; -fx-max-height : 16px; -fx-pref-width : 16px; -fx-pref-height : 16px; -fx-background-insets: 0px, 0.5px; -fx-background-radius: 3.25px, 2.85px; -fx-background-color : linear-gradient(to bottom, derive(BUTTON-COLOR, 20%) 0%, BUTTON-COLOR 20%, BUTTON-COLOR 100%), BUTTON-COLOR; } Outer layer fi lled with gradient, inner layer fi lled with solid color Highlight (StackPane)
  • 64. CSS MACOS DROPDOWN... .root * { BUTTON-COLOR : rgb(51, 101, 207); SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%); } .arrow-button { -fx-min-width : 16px; -fx-min-height : 16px; -fx-max-width : 16px; -fx-max-height : 16px; -fx-pref-width : 16px; -fx-pref-height : 16px; -fx-background-insets: 0px, 0.5px; -fx-background-radius: 3.25px, 2.85px; -fx-background-color : linear-gradient(to bottom, derive(BUTTON-COLOR, 20%) 0%, BUTTON-COLOR 20%, BUTTON-COLOR 100%), BUTTON-COLOR; -fx-effect : dropshadow(two-pass-box, rgba(0, 0, 0, 0.65), 1, 0.0, 0, 0.5); } Drop Shadow Adding a dropshadow (StackPane)
  • 65. CSS MACOS DROPDOWN... .root * { BUTTON-COLOR : rgb(51, 101, 207); SELECTED-BUTTON-COLOR: derive(BUTTON-COLOR, 10%); } .arrow-button { -fx-min-width : 16px; -fx-min-height : 16px; -fx-max-width : 16px; -fx-max-height : 16px; -fx-pref-width : 16px; -fx-pref-height : 16px; -fx-padding : 2.5px 4.5px 2.5px 4.5px; -fx-background-insets: 0px, 0.5px; -fx-background-radius: 3.25px, 2.85px; -fx-background-color : linear-gradient(to bottom, derive(BUTTON-COLOR, 20%) 0%, BUTTON-COLOR 20%, BUTTON-COLOR 100%), BUTTON-COLOR; -fx-effect : dropshadow(two-pass-box, rgba(0, 0, 0, 0.65), 1, 0.0, 0, 0.5); } .arrow-button > .arrows { -fx-background-insets: 0; -fx-background-color : white; -fx-position-shape : true; -fx-scale-shape : false; -fx-shape : "M8.047, ... 8.002,2.525Z"; } 4.5px 4.5px 2.5px 2.5px Adding a SVG shape to .arrows Region (StackPane) (Region)
  • 67. WHEN TO USE CSS...? Use CSS when... ...you use standard controls ...your control inherits a standard control ...it has an impact on many controls ...the environment is already using CSS ...creating a library and want total control ...the customer should be able to customize the app
  • 71. Re-styled ToggleButton using CSS Icons implemented using SVGPath Chart implemented using Canvas SWIFT JAVA FX ToggleButton HBox ToggleButton ToggleButton
  • 72. SWIFT JAVA FX Custom Switch control
  • 78. Makes use of AWT (EDT* + FXAT**) !!! Only supports images !!! Sizes di ff er on operating systems Macos, Windows, Linux*** FXTRAYICON FXTrayIcon library *** not all all distributions ** FX Application Thread * Event Dispatch Thread
  • 80. public BufferedImage createTextTrayIcon(String text, Color color) { final int width = 64; final int height = 18; final double fontSize = 14; final double x = 32; final double y = 14; Canvas canvas = new Canvas(width, height); GraphicsContext ctx = canvas.getGraphicsContext2D(); ctx.setFont(Fonts.sfProRoundedRegular(fontSize)); ctx.setTextAlign(TextAlignment.CENTER); ctx.setFill(color); ctx.fillText(text, x, y); final WritableImage img = new WritableImage(width, height); final SnapshotParameters parameters = new SnapshotParameters(); parameters.setFill(Color.TRANSPARENT); canvas.snapshot(parameters, img); return SwingFXUtils.fromFXImage(img, null); } FXTRAYICON FXTrayIcon library Draw text in Canvas node Take a snapshot of the node Create a Bu ff eredImage Display the image as tray icon Sync EDT and FXAT !!!
  • 81. JAVA FX...? Can I create that same app in
  • 84. jpro
  • 87. DESKTOP JPRO Full size pane instead of dialog
  • 91. JPRO APP Advantages of using JPro Large parts of the code can be re-used Performance is good Easy to start with for Java developers Runs on every HTML5 capable browser Is very close to the desktop version Can run in docker container Dark/light mode support
  • 92. JPRO APP Disadvantages of using JPro Need a server/cloud infrastructure to run on Multiuser setup is tricky running on one instance Dialogs are di ff erent from Desktop No accent color support
  • 94. gluon
  • 96. SWIFT JAVA FX Desktop style buttons
  • 97. SWIFT JAVA FX Full size pane instead of dialog Desktop style buttons
  • 100. SWIFT JAVA FX Desktop style Sliders
  • 101. GLUON APP Advantages of using Gluon Large parts of the code can be re-used Performance is NOT the problem Easy to start with for Java developers Runs on iOS and Android Can be adjusted for each platform Can be published on app stores
  • 102. GLUON APP Disadvantages of using Gluon No real native UI out of the box (better on Android) Problem with 24/7 apps (no native background tasks) No support for iOS widgets and watch faces Sound is handled di ff erently than on desktop No accent color support No dark/light mode support No automatic locale detection
  • 103. tip...
  • 106. APPLE FX... Native looking UI's on Macos
  • 107. APPLE FX... Native looking UI's on Macos
  • 111. CANVAS NODE Advantages of using Canvas Just one node You have "full" control Fast Flexible 99% compatible with HTML5 canvas
  • 112. CANVAS NODE... Disadvantages of using Canvas No direct interaction with shapes Layout is your job (no layout container) Cleanup and redraw is your job Not testable Content is not styleable using CSS* * partly possible using StyleableProperties
  • 114. CANVAS NODE... When to use it... Complex graphics needed Pixel based graphics needed Performance needed No interaction needed Full control needed Games On graphical restricted devices (e.g. Raspberry Pi)
  • 117. Pixel based charts CANVAS NODE... Examples
  • 121. Label 28 Nodes TextField CheckBox RadioButton 2 Nodes 3 Nodes 3 Nodes 5 Nodes ComboBox Button 2 Nodes NUMBER OF NODES...
  • 125. saves 86 nodes in 1 control
  • 127. PERFORMANCE... Avoid deeply nested layout structures Reduce number of nodes Avoid using e ff ects Apply e ff ects to groups instead of single nodes Keep track of dirty state when override layoutChildren() Use Canvas if needed Cache nodes before doing animations Things to keep in mind
  • 128. PERFORMANCE... Be aware of FXApplicationThread Avoid inlining CSS Know your target platform Avoid using transparent stages if possible Disable layout of unused nodes (setManaged(true/false)) Things to keep in mind