SlideShare a Scribd company logo
JAVAFX 2.0
Practical Experience Building Rich Clients
Richard Bair & Jasper Potts
General
Binding
Controls
& Charts
AnimationThreading
CSS
Tips
 
 Tricks
General
Binding
Controls
 Charts
AnimationThreading
CSS
Node subnode = parentNode.lookup(“......”);
where .... is a CSS selector
Lets you quickly and easily get any descendent node.
Useful Selectors:
“#NodeID” find descendent node with id “NodeID”
“.StyleClass”
“ClassName”
LOOKUP
public class Lookup extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
final SplitPane splitPane = new SplitPane();
splitPane.getItems().addAll(
RegionBuilder.create().style(
-fx-background-color: red;).build(),
RegionBuilder.create().style(
-fx-background-color: dodgerblue;).build()
);
Scene scene = new Scene(splitPane, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
}
public class Lookup extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
final SplitPane splitPane = new SplitPane();
splitPane.getItems().addAll(
RegionBuilder.create().style(-fx-background-color: red;).build(),
RegionBuilder.create().style(-fx-background-color: dodgerblue;).build()
);
Scene scene = new Scene(splitPane, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
Pane gripper = (Pane)splitPane.lookup(.horizontal-grabber);
gripper.getChildren().add(
VBoxBuilder.create().spacing(5).children(
ButtonBuilder.create().text()
.onAction(new EventHandlerActionEvent() {
public void handle(ActionEvent t) {
splitPane.setDividerPosition(0, 0);
}
}).build(),
// .... a second button here for 
).build()
);
splitPane.lookup(.split-pane-divider).setStyle(-fx-padding: 8px;);
}
}
General
Binding
Controls
 Charts
AnimationThreading
CSS
CSS COLORING CONTROLS
CSS COLORING CONTROLS
+
CSS COLORING CONTROLS
-fx-base: red;
+
CSS COLORING CONTROLS
-fx-base: red;
+
=
CSS COLORING CONTROLS
-fx-base: red;
+
=
public ToolBar createToolBar(String id) {
return ToolBarBuilder.create()
.id(id)
.items(
new Button(Button 1),
new Button(Button 2),
new Slider(),
new ChoiceBox(
FXCollections.observableArrayList(Font.getFamilies())),
new Button(Button 3)
).build();
}
CSS COLORING CONTROLS
Method for creating example ToolBar
public class DarkToolbar extends Application {
public static void main(String[] args) {
Application.launch(args);
}
public ToolBar createToolBar(String id) {.....}
@Override public void start(Stage primaryStage) {
primaryStage.setTitle(Colored Toolbars);
ToolBar standardToolbar = createToolBar(standard);
ToolBar darkToolbar = createToolBar(dark);
ToolBar blueToolbar = createToolBar(blue);
Scene scene = new Scene(
VBoxBuilder.create()
.spacing(10)
.padding(new Insets(10))
.children(standardToolbar, darkToolbar, blueToolbar)
.build()
);
scene.getStylesheets().add(
DarkToolbar.class.getResource(DarkToolbar.css).toString());
primaryStage.setScene(scene);
primaryStage.show();
}
}
#dark {
-fx-base: #333333;
}
#blue {
-fx-base: dodgerblue;
}
CSS COLORING CONTROLS
#dark {
-fx-base: #333333;
}
#blue {
-fx-base: dodgerblue;
}
CSS COLORING CONTROLS
Say you have some rounded content in a SplitPane like:
CSS HIDDEN SPLITTERS
And you want to make the split panes not draw a bar like:
public class HidingSplitPane extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
primaryStage.setTitle(Hidden Splitter);
final SplitPane splitPane = SplitPaneBuilder.create()
.id(hiddenSplitter)
.items(
RegionBuilder.create().styleClass(rounded).build(),
RegionBuilder.create().styleClass(rounded).build(),
RegionBuilder.create().styleClass(rounded).build()
).dividerPositions(new double[]{0.33,0.66})
.build();
Scene scene = new Scene(splitPane, 300, 100);
scene.getStylesheets().add(HidingSplitPane.class
.getResource(HidingSplitPane.css).toString());
primaryStage.setScene(scene);
primaryStage.show();
}
}
.rounded {
-fx-border-color: dodgerblue;
-fx-border-width: 2px;
-fx-border-radius: 15px;
-fx-padding: 20px;
}
#hiddenSplitter {
-fx-background-color: null;
-fx-padding: 10px;
}
#hiddenSplitter *.split-pane-divider,
#hiddenSplitter *.vertical-grabber,
#hiddenSplitter *.horizontal-grabber {
-fx-background-color: null;
-fx-border-color: null;
-fx-padding: 5px;
}
CSS HIDDEN SPLITTERS
Scene scene = new Scene(
VBoxBuilder.create()
.spacing(10)
.padding(new Insets(10))
.children(
ButtonBuilder.create()
.text(Inset Text Button)
.id(button1).build(),
LabelBuilder.create()
.text(Label styled as bar)
.id(label1).build()
)
.build()
);
CSS INSET TEXT
Apple style inset text, eg:
#button1 Text, #label1 Text{
-fx-effect: dropshadow(
one-pass-box , white, 0, 0 , 0, 1);
}
CSS INSET TEXT
Add some simple CSS:
General
Binding
Controls
 Charts
AnimationThreading
CSS
ANIMATION CACHING
When animating objects with complex graphics such as large
screens of controls like a data form can be jerky. So what
you need to do is cache them while animating.
public void handle(ActionEvent t) {
ANIMATION CACHING
SequentialTransitionBuilder.create()
.node(tilePane)
.children(.......)
.build().play();
}
public void handle(ActionEvent t) {
ANIMATION CACHING
SequentialTransitionBuilder.create()
.node(tilePane)
.children(.......)
.onFinished(new EventHandlerActionEvent() {
public void handle(ActionEvent t) {
tilePane.setCache(false);
}
})
tilePane.setCache(true);
tilePane.setCacheHint(CacheHint.SPEED);
.build().play();
}
General
Binding
Controls
 Charts
AnimationThreading
CSS
BINDING
Using the low level binding API, you can do arbitrarily
interesting binding, such as creating complex messages
THE SETUP
StringBinding
• Listens to the TextField
• Computes the String to be
displayed in the Label
• Uses a SimpleDateFormat and
some Calendar’s to do the job
TextField
• Enter the text here
Label
• Just binds to a custom binding
General
Binding
Controls
 Charts
AnimationThreading
CSS
TASKS
Using aTask, ProgressIndicator, and Region you can
implement background tasks which block the UI, simply
SERVICE
Using a Service instead of aTask, you can easily create a
reusable Service for doing background work
General
Binding
Controls
 Charts
AnimationThreading
CSS
VALIDATORS
Using the scene graph and some CSS you can wrap any
control in order to handle custom validation
Has-a
THE SETUP
TextInputValidatorPane
• A layout container which wraps its content
• Listens to changes in the TextField and
handles validation
• Sets the style class to “.validation-error” or
“.validation-warning” when there are
validation problems
Validator
• Interface which takes a control and
produces aValidationResult
ValidationResult
• Has a message  validation result
type (Error,Warning, Normal)
CSS
• Styles make the background of the
text field change
TextField
• Just lives its life normal, doesn’t
have to do anything special
Styles
Creates
TABLE PLACE HOLDER
You can place any node in as a place holder on aTableView
and it will be shown when there is no data.
final TableView tableView = new TableView();
TABLE PLACE HOLDER
tableView.getColumns().addAll(
TableColumnBuilder.create()
.text(First)
.cellValueFactory(new PropertyValueFactory(firstName))
.build(),
TableColumnBuilder.create()
.text(Last)
.cellValueFactory(new PropertyValueFactory(lastName))
.build(),
TableColumnBuilder.create()
.text(Email)
.prefWidth(220)
.cellValueFactory(new PropertyValueFactory(email))
.build()
);
final TableView tableView = new TableView();
TABLE PLACE HOLDER
tableView.getColumns().addAll(
TableColumnBuilder.create()
.text(First)
.cellValueFactory(new PropertyValueFactory(firstName))
.build(),
TableColumnBuilder.create()
.text(Last)
.cellValueFactory(new PropertyValueFactory(lastName))
.build(),
TableColumnBuilder.create()
.text(Email)
.prefWidth(220)
.cellValueFactory(new PropertyValueFactory(email))
.build()
);
tableView.setPlaceholder(
ProgressIndicatorBuilder.create()
.maxWidth(100)
.maxHeight(100)
.build());
TABLE PLACE HOLDER
PauseTransitionBuilder.create()
.duration(Duration.seconds(5))
.onFinished(new EventHandlerActionEvent() {
public void handle(ActionEvent t) {
tableView.setItems(FXCollections.observableArrayList(
new Person(Jacob, Smith,
jacob.smith@example.com ),
new Person(Isabella, Johnson,
isabella.johnson@example.com ),
new Person(Ethan, Williams,
ethan.williams@example.com ),
new Person(Emma, Jones,
emma.jones@example.com ),
new Person(Michael, Brown,
michael.brown@example.com )
));
}
})
.build().play();
SUBMIT PROGRESS
It is nice to give the user some feedback while we are
responding to their action.A quick neat way to do this for
a form submission is to add a ProgressIndicator to the
submit button.
SUBMIT PROGRESS
public class SaveButtonProgressIndicator extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
primaryStage.setTitle(Save Button ProgressIndicator);
try {
Parent root =
FXMLLoader.load(getClass().getResource(SalesForm.fxml));
primaryStage.setScene(new Scene(root));
primaryStage.show();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
SUBMIT PROGRESS
GridPane xmlns:fx=http://javafx.com/fxml
fx:controller=tipsandtricks.SalesForm fx:id=salesForm
hgap=15 vgap=12
paddingInsets top=10 right=10 bottom=10 left=10//padding
children
Label text=Quantity: GridPane.columnIndex=1 GridPane.rowIndex=1/
TextField fx:id=quanityTextField text=1 GridPane.columnIndex=2
GridPane.rowIndex=1/
HBox spacing=10 alignment=center_right GridPane.columnIndex=1
GridPane.rowIndex=2 GridPane.columnSpan=3
children
Button text=Cancel onAction=#cancelAction cancelButton=true
style=-fx-base: #AAAAAA;/
Button text=Save onAction=#saveAction defaultButton=true
style=-fx-base: #333333;/
/children
/HBox
/children
/GridPane
SUBMIT PROGRESS
public class SalesForm {
@FXML private void cancelAction(final ActionEvent event) {}
@FXML private void saveAction(final ActionEvent event) {
// put progress indicator in save button to show user
// something is happening
Button saveButton = (Button)event.getSource();
ProgressIndicator pi = new ProgressIndicator();
pi.setPrefSize(14,14);
saveButton.setGraphic(pi);
}
}
IMAGE BARCHART
You can customize the look of JavaFX charts with CSS
such as styling the bars of a BarChart with images.
IMAGE BARCHART
You can customize the look of JavaFX charts with CSS
such as styling the bars of a BarChart with images.
IMAGE BARCHART
public class ImageBarChart extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
primaryStage.setTitle(Image BarChart);
BarChart barChart = new BarChart(new CategoryAxis(), new NumberAxis());
barChart.setLegendVisible(false);
barChart.getData().add(
new XYChart.SeriesString,Integer(Sales Per Product,
FXCollections.observableArrayList(
new XYChart.DataString, Integer(SUV,120),
new XYChart.DataString, Integer(Sedan,50),
new XYChart.DataString, Integer(Truck,180),
new XYChart.DataString, Integer(Van,20)
)
)
);
Scene scene = new Scene(barChart, 350, 300);
scene.getStylesheets().add(InsetText.class
.getResource(ImageBarChart.css).toString());
primaryStage.setScene(scene);
primaryStage.show();
}
}
IMAGE BARCHART
.chart {
-fx-background-color: -fx-box-border, #f5f5f5;
-fx-background-insets: 0, 1;
-fx-font-size: 0.9em;
}
.chart-bar {
-fx-background-color: rgba(0,168,355,0.05);
-fx-border-color: rgba(0,168,355,0.3) rgba(0,168,355,0.3)
transparent rgba(0,168,355,0.3);
-fx-background-radius: 0;
-fx-background-position: center bottom;
-fx-background-repeat: no-repeat space;
-fx-background-image: url(van-s.png);
}
.data0.chart-bar { -fx-background-image: url(suv-s.png); }
.data1.chart-bar { -fx-background-image: url(sedan-s.png); }
.data2.chart-bar { -fx-background-image: url(truck-s.png); }
.data3.chart-bar { -fx-background-image: url(van-2.png); }
DRILL DOWN CHART
You can attach mouse handling to items in a chart so you
can do drill down or other actions.
DRILL DOWN CHART
public class DrilldownChart extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
primaryStage.setTitle(Drilldown Chart);
PieChart.Data A,B,C,D;
final PieChart pie = new PieChart(
FXCollections.observableArrayList(
A = new PieChart.Data(A, 20),
B = new PieChart.Data(B, 30),
C = new PieChart.Data(C, 10),
D = new PieChart.Data(D, 40)
)
);
Scene scene = new Scene(pie, 350, 300);
scene.getStylesheets().add(InsetText.class
.getResource(DrilldownChart.css).toString());
primaryStage.setScene(scene);
primaryStage.show();
}
}
DRILL DOWN CHART
public class DrilldownChart extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
primaryStage.setTitle(Drilldown Chart);
PieChart.Data A,B,C,D;
final PieChart pie = new PieChart(
FXCollections.observableArrayList(
A = new PieChart.Data(A, 20),
B = new PieChart.Data(B, 30),
C = new PieChart.Data(C, 10),
D = new PieChart.Data(D, 40)
)
);
A.getNode().setOnMouseClicked(new EventHandlerMouseEvent() {
public void handle(MouseEvent t) {
pie.setData(FXCollections.observableArrayList(
new PieChart.Data(a1, 7),
new PieChart.Data(a2, 2),
new PieChart.Data(a3, 5),
new PieChart.Data(a4, 3),
new PieChart.Data(a5, 2)
));
}
});
Scene scene = new Scene(pie, 350, 300);
scene.getStylesheets().add(InsetText.class
.getResource(DrilldownChart.css).toString());
primaryStage.setScene(scene);
primaryStage.show();
}
}
DRILL DOWN CHART
.chart-pie:hover {
-fx-border-color: red;
-fx-border-width: 2px;
}
SEARCH BOX
You can combine standard controls + some CSS and
create new controls such as a search box.
SEARCH BOX
public class SearchBoxApp extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override public void start(Stage primaryStage) {
primaryStage.setTitle(SearchBox);
VBox root = new VBox();
root.getChildren().addAll(new SearchBox());
Scene scene = new Scene(root);
scene.getStylesheets().add(InsetText.class
.getResource(SearchBox.css).toString());
primaryStage.setScene(scene);
primaryStage.show();
}
}
SEARCH BOX
public class SearchBox extends Region {
private TextField textBox;
private Button clearButton;
public SearchBox() {
setId(SearchBox);
getStyleClass().add(search-box);
setMinHeight(24);
setPrefSize(150, 24);
setMaxHeight(24);
textBox = new TextField();
textBox.setPromptText(Search);
clearButton = new Button();
clearButton.setVisible(false);
getChildren().addAll(textBox, clearButton);
......
}
@Override protected void layoutChildren() {
textBox.resize(getWidth(),getHeight());
clearButton.resizeRelocate(getWidth()-18,6,12,13);
}
}
SEARCH BOX
public class SearchBox extends Region {
private TextField textBox;
private Button clearButton;
public SearchBox() {
setId(SearchBox);
getStyleClass().add(search-box);
setMinHeight(24);
setPrefSize(150, 24);
setMaxHeight(24);
textBox = new TextField();
textBox.setPromptText(Search);
clearButton = new Button();
clearButton.setVisible(false);
getChildren().addAll(textBox, clearButton);
clearButton.setOnAction(new EventHandlerActionEvent() {
@Override public void handle(ActionEvent actionEvent) {
textBox.setText();
textBox.requestFocus();
}
});
textBox.textProperty().addListener(new ChangeListenerString() {
@Override public void changed(ObservableValue? extends String
observable, String oldValue, String newValue) {
clearButton.setVisible(textBox.getText().length() != 0);
}
});
}
@Override protected void layoutChildren() {
textBox.resize(getWidth(),getHeight());
clearButton.resizeRelocate(getWidth()-18,6,12,13);
}
}
SEARCH BOX
.root {
-fx-padding: 10px;
-fx-background-image: url(images/top-bar.png);
-fx-background-size: cover;
-fx-background-position: left top;
-fx-background-repeat: no-repeat;
}
.search-box .text-field {
-fx-background-color: white;
-fx-background-insets: 1;
-fx-background-radius: 15;
-fx-padding: -9 5 -11 0;
-fx-border-image-source: url(images/search-box.png);
-fx-border-image-slice: 12 12 12 22 fill;
-fx-border-image-width: 12 12 12 22;
-fx-border-image-repeat: stretch;
-fx-font-size: 13px;
-fx-prompt-text-fill: grey;
}
.search-box .text-field:focused {
-fx-background-color: -fx-focus-color, white;
-fx-background-insets: -1.4, 1;
-fx-background-radius: 14.4;
}
SEARCH BOX
SEARCH BOX
.search-box .button {
-fx-background-color: null;
-fx-background-image: url(images/search-clear.png);
}
.search-box .button:hover {
-fx-background-image: url(images/search-clear-over.png);
}

More Related Content

What's hot

Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsIntroduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsJason Myers
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsMichael Miles
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEMJan Wloka
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212Mahmoud Samir Fayed
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at ScaleJan Wloka
 
supporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered tablesupporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered tableMahabubur Rahaman
 
Apache Solr Search Mastery
Apache Solr Search MasteryApache Solr Search Mastery
Apache Solr Search MasteryAcquia
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascriptAlmog Baku
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial추근 문
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Rabble .
 
Postgres rules
Postgres rulesPostgres rules
Postgres rulesgisborne
 
The Ring programming language version 1.5.4 book - Part 44 of 185
The Ring programming language version 1.5.4 book - Part 44 of 185The Ring programming language version 1.5.4 book - Part 44 of 185
The Ring programming language version 1.5.4 book - Part 44 of 185Mahmoud Samir Fayed
 
Pier - no kernel left behind
Pier - no kernel left behindPier - no kernel left behind
Pier - no kernel left behindNick Ager
 
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드영욱 김
 
Xamarin: Introduction to iOS 8
Xamarin: Introduction to iOS 8Xamarin: Introduction to iOS 8
Xamarin: Introduction to iOS 8Xamarin
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shintutorialsruby
 
Swift Tableview iOS App Development
Swift Tableview iOS App DevelopmentSwift Tableview iOS App Development
Swift Tableview iOS App DevelopmentKetan Raval
 

What's hot (20)

Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsIntroduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback Commands
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEM
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at Scale
 
Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto
 
supporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered tablesupporting t-sql scripts for Heap vs clustered table
supporting t-sql scripts for Heap vs clustered table
 
Apache Solr Search Mastery
Apache Solr Search MasteryApache Solr Search Mastery
Apache Solr Search Mastery
 
Drupal & javascript
Drupal & javascriptDrupal & javascript
Drupal & javascript
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
 
Postgres rules
Postgres rulesPostgres rules
Postgres rules
 
I os 04
I os 04I os 04
I os 04
 
The Ring programming language version 1.5.4 book - Part 44 of 185
The Ring programming language version 1.5.4 book - Part 44 of 185The Ring programming language version 1.5.4 book - Part 44 of 185
The Ring programming language version 1.5.4 book - Part 44 of 185
 
Pier - no kernel left behind
Pier - no kernel left behindPier - no kernel left behind
Pier - no kernel left behind
 
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
 
Xamarin: Introduction to iOS 8
Xamarin: Introduction to iOS 8Xamarin: Introduction to iOS 8
Xamarin: Introduction to iOS 8
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shin
 
Swift Tableview iOS App Development
Swift Tableview iOS App DevelopmentSwift Tableview iOS App Development
Swift Tableview iOS App Development
 

Viewers also liked

Java Rich Clients with JavaFX 2.0
Java Rich Clients with JavaFX 2.0Java Rich Clients with JavaFX 2.0
Java Rich Clients with JavaFX 2.0Richard Bair
 
Building Amazing Applications with JavaFX
Building Amazing Applications with JavaFXBuilding Amazing Applications with JavaFX
Building Amazing Applications with JavaFXRichard Bair
 
JavaFX In Practice
JavaFX In PracticeJavaFX In Practice
JavaFX In PracticeRichard Bair
 
From Shabby to Chic
From Shabby to ChicFrom Shabby to Chic
From Shabby to ChicRichard Bair
 
Enterprising JavaFX
Enterprising JavaFXEnterprising JavaFX
Enterprising JavaFXRichard Bair
 

Viewers also liked (8)

Java Rich Clients with JavaFX 2.0
Java Rich Clients with JavaFX 2.0Java Rich Clients with JavaFX 2.0
Java Rich Clients with JavaFX 2.0
 
Gaming JavaFX
Gaming JavaFXGaming JavaFX
Gaming JavaFX
 
JavaFX Deployment
JavaFX DeploymentJavaFX Deployment
JavaFX Deployment
 
Building Amazing Applications with JavaFX
Building Amazing Applications with JavaFXBuilding Amazing Applications with JavaFX
Building Amazing Applications with JavaFX
 
JavaFX In Practice
JavaFX In PracticeJavaFX In Practice
JavaFX In Practice
 
JavaFX 101
JavaFX 101JavaFX 101
JavaFX 101
 
From Shabby to Chic
From Shabby to ChicFrom Shabby to Chic
From Shabby to Chic
 
Enterprising JavaFX
Enterprising JavaFXEnterprising JavaFX
Enterprising JavaFX
 

Similar to Practical Experience Building JavaFX Rich Clients

JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)Stephen Chin
 
Building mobile web apps with Mobello
Building mobile web apps with MobelloBuilding mobile web apps with Mobello
Building mobile web apps with MobelloJeong-Geun Kim
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components EverywhereIlia Idakiev
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web appsIvano Malavolta
 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189Mahmoud Samir Fayed
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in CassandraJairam Chandar
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql JOYITAKUNDU1
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chinjaxconf
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...Dan Wahlin
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the CloudStephen Chin
 
20140821 delapsley-cloudopen-public
20140821 delapsley-cloudopen-public20140821 delapsley-cloudopen-public
20140821 delapsley-cloudopen-publicDavid Lapsley
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularIlia Idakiev
 
Single page webapps & javascript-testing
Single page webapps & javascript-testingSingle page webapps & javascript-testing
Single page webapps & javascript-testingsmontanari
 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196Mahmoud Samir Fayed
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Tsuyoshi Yamamoto
 

Similar to Practical Experience Building JavaFX Rich Clients (20)

#JavaFX.forReal()
#JavaFX.forReal()#JavaFX.forReal()
#JavaFX.forReal()
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
 
Building mobile web apps with Mobello
Building mobile web apps with MobelloBuilding mobile web apps with Mobello
Building mobile web apps with Mobello
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web apps
 
The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189The Ring programming language version 1.6 book - Part 46 of 189
The Ring programming language version 1.6 book - Part 46 of 189
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in Cassandra
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
Building the an End-to-End ASP.NET MVC 4, Entity Framework, HTML5, jQuery app...
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the Cloud
 
20140821 delapsley-cloudopen-public
20140821 delapsley-cloudopen-public20140821 delapsley-cloudopen-public
20140821 delapsley-cloudopen-public
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With Angular
 
Single page webapps & javascript-testing
Single page webapps & javascript-testingSingle page webapps & javascript-testing
Single page webapps & javascript-testing
 
The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196The Ring programming language version 1.7 book - Part 48 of 196
The Ring programming language version 1.7 book - Part 48 of 196
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 

Recently uploaded

Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationZilliz
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCzechDreamin
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor TurskyiFwdays
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlPeter Udo Diehl
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...Product School
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...Product School
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Product School
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...CzechDreamin
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backElena Simperl
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsPaul Groth
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...Elena Simperl
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...CzechDreamin
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesBhaskar Mitra
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...Product School
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeCzechDreamin
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Julian Hyde
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
 

Recently uploaded (20)

Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG Evaluation
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 

Practical Experience Building JavaFX Rich Clients

  • 1. JAVAFX 2.0 Practical Experience Building Rich Clients Richard Bair & Jasper Potts
  • 3.  
  • 6. Node subnode = parentNode.lookup(“......”); where .... is a CSS selector Lets you quickly and easily get any descendent node. Useful Selectors: “#NodeID” find descendent node with id “NodeID” “.StyleClass” “ClassName” LOOKUP
  • 7. public class Lookup extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { final SplitPane splitPane = new SplitPane(); splitPane.getItems().addAll( RegionBuilder.create().style( -fx-background-color: red;).build(), RegionBuilder.create().style( -fx-background-color: dodgerblue;).build() ); Scene scene = new Scene(splitPane, 300, 250); primaryStage.setScene(scene); primaryStage.show(); } }
  • 8. public class Lookup extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { final SplitPane splitPane = new SplitPane(); splitPane.getItems().addAll( RegionBuilder.create().style(-fx-background-color: red;).build(), RegionBuilder.create().style(-fx-background-color: dodgerblue;).build() ); Scene scene = new Scene(splitPane, 300, 250); primaryStage.setScene(scene); primaryStage.show(); Pane gripper = (Pane)splitPane.lookup(.horizontal-grabber); gripper.getChildren().add( VBoxBuilder.create().spacing(5).children( ButtonBuilder.create().text() .onAction(new EventHandlerActionEvent() { public void handle(ActionEvent t) { splitPane.setDividerPosition(0, 0); } }).build(), // .... a second button here for ).build() ); splitPane.lookup(.split-pane-divider).setStyle(-fx-padding: 8px;); } }
  • 9.
  • 16. public ToolBar createToolBar(String id) { return ToolBarBuilder.create() .id(id) .items( new Button(Button 1), new Button(Button 2), new Slider(), new ChoiceBox( FXCollections.observableArrayList(Font.getFamilies())), new Button(Button 3) ).build(); } CSS COLORING CONTROLS Method for creating example ToolBar
  • 17. public class DarkToolbar extends Application { public static void main(String[] args) { Application.launch(args); } public ToolBar createToolBar(String id) {.....} @Override public void start(Stage primaryStage) { primaryStage.setTitle(Colored Toolbars); ToolBar standardToolbar = createToolBar(standard); ToolBar darkToolbar = createToolBar(dark); ToolBar blueToolbar = createToolBar(blue); Scene scene = new Scene( VBoxBuilder.create() .spacing(10) .padding(new Insets(10)) .children(standardToolbar, darkToolbar, blueToolbar) .build() ); scene.getStylesheets().add( DarkToolbar.class.getResource(DarkToolbar.css).toString()); primaryStage.setScene(scene); primaryStage.show(); } }
  • 18. #dark { -fx-base: #333333; } #blue { -fx-base: dodgerblue; } CSS COLORING CONTROLS
  • 19. #dark { -fx-base: #333333; } #blue { -fx-base: dodgerblue; } CSS COLORING CONTROLS
  • 20. Say you have some rounded content in a SplitPane like: CSS HIDDEN SPLITTERS And you want to make the split panes not draw a bar like:
  • 21. public class HidingSplitPane extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle(Hidden Splitter); final SplitPane splitPane = SplitPaneBuilder.create() .id(hiddenSplitter) .items( RegionBuilder.create().styleClass(rounded).build(), RegionBuilder.create().styleClass(rounded).build(), RegionBuilder.create().styleClass(rounded).build() ).dividerPositions(new double[]{0.33,0.66}) .build(); Scene scene = new Scene(splitPane, 300, 100); scene.getStylesheets().add(HidingSplitPane.class .getResource(HidingSplitPane.css).toString()); primaryStage.setScene(scene); primaryStage.show(); } }
  • 22. .rounded { -fx-border-color: dodgerblue; -fx-border-width: 2px; -fx-border-radius: 15px; -fx-padding: 20px; } #hiddenSplitter { -fx-background-color: null; -fx-padding: 10px; } #hiddenSplitter *.split-pane-divider, #hiddenSplitter *.vertical-grabber, #hiddenSplitter *.horizontal-grabber { -fx-background-color: null; -fx-border-color: null; -fx-padding: 5px; } CSS HIDDEN SPLITTERS
  • 23. Scene scene = new Scene( VBoxBuilder.create() .spacing(10) .padding(new Insets(10)) .children( ButtonBuilder.create() .text(Inset Text Button) .id(button1).build(), LabelBuilder.create() .text(Label styled as bar) .id(label1).build() ) .build() ); CSS INSET TEXT Apple style inset text, eg:
  • 24. #button1 Text, #label1 Text{ -fx-effect: dropshadow( one-pass-box , white, 0, 0 , 0, 1); } CSS INSET TEXT Add some simple CSS:
  • 26. ANIMATION CACHING When animating objects with complex graphics such as large screens of controls like a data form can be jerky. So what you need to do is cache them while animating.
  • 27.
  • 28. public void handle(ActionEvent t) { ANIMATION CACHING SequentialTransitionBuilder.create() .node(tilePane) .children(.......) .build().play(); }
  • 29. public void handle(ActionEvent t) { ANIMATION CACHING SequentialTransitionBuilder.create() .node(tilePane) .children(.......) .onFinished(new EventHandlerActionEvent() { public void handle(ActionEvent t) { tilePane.setCache(false); } }) tilePane.setCache(true); tilePane.setCacheHint(CacheHint.SPEED); .build().play(); }
  • 31. BINDING Using the low level binding API, you can do arbitrarily interesting binding, such as creating complex messages
  • 32. THE SETUP StringBinding • Listens to the TextField • Computes the String to be displayed in the Label • Uses a SimpleDateFormat and some Calendar’s to do the job TextField • Enter the text here Label • Just binds to a custom binding
  • 33.
  • 35. TASKS Using aTask, ProgressIndicator, and Region you can implement background tasks which block the UI, simply
  • 36.
  • 37. SERVICE Using a Service instead of aTask, you can easily create a reusable Service for doing background work
  • 38.
  • 40. VALIDATORS Using the scene graph and some CSS you can wrap any control in order to handle custom validation
  • 41. Has-a THE SETUP TextInputValidatorPane • A layout container which wraps its content • Listens to changes in the TextField and handles validation • Sets the style class to “.validation-error” or “.validation-warning” when there are validation problems Validator • Interface which takes a control and produces aValidationResult ValidationResult • Has a message validation result type (Error,Warning, Normal) CSS • Styles make the background of the text field change TextField • Just lives its life normal, doesn’t have to do anything special Styles Creates
  • 42.
  • 43. TABLE PLACE HOLDER You can place any node in as a place holder on aTableView and it will be shown when there is no data.
  • 44.
  • 45. final TableView tableView = new TableView(); TABLE PLACE HOLDER tableView.getColumns().addAll( TableColumnBuilder.create() .text(First) .cellValueFactory(new PropertyValueFactory(firstName)) .build(), TableColumnBuilder.create() .text(Last) .cellValueFactory(new PropertyValueFactory(lastName)) .build(), TableColumnBuilder.create() .text(Email) .prefWidth(220) .cellValueFactory(new PropertyValueFactory(email)) .build() );
  • 46. final TableView tableView = new TableView(); TABLE PLACE HOLDER tableView.getColumns().addAll( TableColumnBuilder.create() .text(First) .cellValueFactory(new PropertyValueFactory(firstName)) .build(), TableColumnBuilder.create() .text(Last) .cellValueFactory(new PropertyValueFactory(lastName)) .build(), TableColumnBuilder.create() .text(Email) .prefWidth(220) .cellValueFactory(new PropertyValueFactory(email)) .build() ); tableView.setPlaceholder( ProgressIndicatorBuilder.create() .maxWidth(100) .maxHeight(100) .build());
  • 47. TABLE PLACE HOLDER PauseTransitionBuilder.create() .duration(Duration.seconds(5)) .onFinished(new EventHandlerActionEvent() { public void handle(ActionEvent t) { tableView.setItems(FXCollections.observableArrayList( new Person(Jacob, Smith, jacob.smith@example.com ), new Person(Isabella, Johnson, isabella.johnson@example.com ), new Person(Ethan, Williams, ethan.williams@example.com ), new Person(Emma, Jones, emma.jones@example.com ), new Person(Michael, Brown, michael.brown@example.com ) )); } }) .build().play();
  • 48. SUBMIT PROGRESS It is nice to give the user some feedback while we are responding to their action.A quick neat way to do this for a form submission is to add a ProgressIndicator to the submit button.
  • 49.
  • 50. SUBMIT PROGRESS public class SaveButtonProgressIndicator extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle(Save Button ProgressIndicator); try { Parent root = FXMLLoader.load(getClass().getResource(SalesForm.fxml)); primaryStage.setScene(new Scene(root)); primaryStage.show(); } catch (IOException ex) { ex.printStackTrace(); } } }
  • 51. SUBMIT PROGRESS GridPane xmlns:fx=http://javafx.com/fxml fx:controller=tipsandtricks.SalesForm fx:id=salesForm hgap=15 vgap=12 paddingInsets top=10 right=10 bottom=10 left=10//padding children Label text=Quantity: GridPane.columnIndex=1 GridPane.rowIndex=1/ TextField fx:id=quanityTextField text=1 GridPane.columnIndex=2 GridPane.rowIndex=1/ HBox spacing=10 alignment=center_right GridPane.columnIndex=1 GridPane.rowIndex=2 GridPane.columnSpan=3 children Button text=Cancel onAction=#cancelAction cancelButton=true style=-fx-base: #AAAAAA;/ Button text=Save onAction=#saveAction defaultButton=true style=-fx-base: #333333;/ /children /HBox /children /GridPane
  • 52. SUBMIT PROGRESS public class SalesForm { @FXML private void cancelAction(final ActionEvent event) {} @FXML private void saveAction(final ActionEvent event) { // put progress indicator in save button to show user // something is happening Button saveButton = (Button)event.getSource(); ProgressIndicator pi = new ProgressIndicator(); pi.setPrefSize(14,14); saveButton.setGraphic(pi); } }
  • 53. IMAGE BARCHART You can customize the look of JavaFX charts with CSS such as styling the bars of a BarChart with images.
  • 54. IMAGE BARCHART You can customize the look of JavaFX charts with CSS such as styling the bars of a BarChart with images.
  • 55.
  • 56. IMAGE BARCHART public class ImageBarChart extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle(Image BarChart); BarChart barChart = new BarChart(new CategoryAxis(), new NumberAxis()); barChart.setLegendVisible(false); barChart.getData().add( new XYChart.SeriesString,Integer(Sales Per Product, FXCollections.observableArrayList( new XYChart.DataString, Integer(SUV,120), new XYChart.DataString, Integer(Sedan,50), new XYChart.DataString, Integer(Truck,180), new XYChart.DataString, Integer(Van,20) ) ) ); Scene scene = new Scene(barChart, 350, 300); scene.getStylesheets().add(InsetText.class .getResource(ImageBarChart.css).toString()); primaryStage.setScene(scene); primaryStage.show(); } }
  • 57. IMAGE BARCHART .chart { -fx-background-color: -fx-box-border, #f5f5f5; -fx-background-insets: 0, 1; -fx-font-size: 0.9em; } .chart-bar { -fx-background-color: rgba(0,168,355,0.05); -fx-border-color: rgba(0,168,355,0.3) rgba(0,168,355,0.3) transparent rgba(0,168,355,0.3); -fx-background-radius: 0; -fx-background-position: center bottom; -fx-background-repeat: no-repeat space; -fx-background-image: url(van-s.png); } .data0.chart-bar { -fx-background-image: url(suv-s.png); } .data1.chart-bar { -fx-background-image: url(sedan-s.png); } .data2.chart-bar { -fx-background-image: url(truck-s.png); } .data3.chart-bar { -fx-background-image: url(van-2.png); }
  • 58. DRILL DOWN CHART You can attach mouse handling to items in a chart so you can do drill down or other actions.
  • 59.
  • 60. DRILL DOWN CHART public class DrilldownChart extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle(Drilldown Chart); PieChart.Data A,B,C,D; final PieChart pie = new PieChart( FXCollections.observableArrayList( A = new PieChart.Data(A, 20), B = new PieChart.Data(B, 30), C = new PieChart.Data(C, 10), D = new PieChart.Data(D, 40) ) ); Scene scene = new Scene(pie, 350, 300); scene.getStylesheets().add(InsetText.class .getResource(DrilldownChart.css).toString()); primaryStage.setScene(scene); primaryStage.show(); } }
  • 61. DRILL DOWN CHART public class DrilldownChart extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle(Drilldown Chart); PieChart.Data A,B,C,D; final PieChart pie = new PieChart( FXCollections.observableArrayList( A = new PieChart.Data(A, 20), B = new PieChart.Data(B, 30), C = new PieChart.Data(C, 10), D = new PieChart.Data(D, 40) ) ); A.getNode().setOnMouseClicked(new EventHandlerMouseEvent() { public void handle(MouseEvent t) { pie.setData(FXCollections.observableArrayList( new PieChart.Data(a1, 7), new PieChart.Data(a2, 2), new PieChart.Data(a3, 5), new PieChart.Data(a4, 3), new PieChart.Data(a5, 2) )); } }); Scene scene = new Scene(pie, 350, 300); scene.getStylesheets().add(InsetText.class .getResource(DrilldownChart.css).toString()); primaryStage.setScene(scene); primaryStage.show(); } }
  • 62. DRILL DOWN CHART .chart-pie:hover { -fx-border-color: red; -fx-border-width: 2px; }
  • 63. SEARCH BOX You can combine standard controls + some CSS and create new controls such as a search box.
  • 64.
  • 65. SEARCH BOX public class SearchBoxApp extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle(SearchBox); VBox root = new VBox(); root.getChildren().addAll(new SearchBox()); Scene scene = new Scene(root); scene.getStylesheets().add(InsetText.class .getResource(SearchBox.css).toString()); primaryStage.setScene(scene); primaryStage.show(); } }
  • 66. SEARCH BOX public class SearchBox extends Region { private TextField textBox; private Button clearButton; public SearchBox() { setId(SearchBox); getStyleClass().add(search-box); setMinHeight(24); setPrefSize(150, 24); setMaxHeight(24); textBox = new TextField(); textBox.setPromptText(Search); clearButton = new Button(); clearButton.setVisible(false); getChildren().addAll(textBox, clearButton); ...... } @Override protected void layoutChildren() { textBox.resize(getWidth(),getHeight()); clearButton.resizeRelocate(getWidth()-18,6,12,13); } }
  • 67. SEARCH BOX public class SearchBox extends Region { private TextField textBox; private Button clearButton; public SearchBox() { setId(SearchBox); getStyleClass().add(search-box); setMinHeight(24); setPrefSize(150, 24); setMaxHeight(24); textBox = new TextField(); textBox.setPromptText(Search); clearButton = new Button(); clearButton.setVisible(false); getChildren().addAll(textBox, clearButton); clearButton.setOnAction(new EventHandlerActionEvent() { @Override public void handle(ActionEvent actionEvent) { textBox.setText(); textBox.requestFocus(); } }); textBox.textProperty().addListener(new ChangeListenerString() { @Override public void changed(ObservableValue? extends String observable, String oldValue, String newValue) { clearButton.setVisible(textBox.getText().length() != 0); } }); } @Override protected void layoutChildren() { textBox.resize(getWidth(),getHeight()); clearButton.resizeRelocate(getWidth()-18,6,12,13); } }
  • 68. SEARCH BOX .root { -fx-padding: 10px; -fx-background-image: url(images/top-bar.png); -fx-background-size: cover; -fx-background-position: left top; -fx-background-repeat: no-repeat; }
  • 69. .search-box .text-field { -fx-background-color: white; -fx-background-insets: 1; -fx-background-radius: 15; -fx-padding: -9 5 -11 0; -fx-border-image-source: url(images/search-box.png); -fx-border-image-slice: 12 12 12 22 fill; -fx-border-image-width: 12 12 12 22; -fx-border-image-repeat: stretch; -fx-font-size: 13px; -fx-prompt-text-fill: grey; } .search-box .text-field:focused { -fx-background-color: -fx-focus-color, white; -fx-background-insets: -1.4, 1; -fx-background-radius: 14.4; } SEARCH BOX
  • 70. SEARCH BOX .search-box .button { -fx-background-color: null; -fx-background-image: url(images/search-clear.png); } .search-box .button:hover { -fx-background-image: url(images/search-clear-over.png); }
  • 71.
  • 72. The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions.The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.