SlideShare une entreprise Scribd logo
1  sur  52
Télécharger pour lire hors ligne
GroovyFX	-	Groove	JavaFX_
Alexander	Klein
 
1
About	me
Alexander	Klein
Branchmanager
codecentric	AG
Curiestr.	2
70563	Stuttgart,	Germany
	+49	(0)	172	529	40	20
	alexander.klein@codecentric.de
	www.codecentric.de
	blog.codecentric.de
	@saschaklein
 
2
What	is	GroovyFX
 
3
GroovyFX
library	for	JavaFX	using	Groovy
Groovy	Builder	Pattern
DSL	on	top	of	JavaFX
declarative
simpler	to	write
easier	to	read
more	natural
http://groovyfx.org
https://github.com/groovyfx-project/groovyfx
http://groovy.jmiguel.eu/groovy.codehaus.org/GroovyFX.html
 
4
Example
groovyx.javafx.GroovyFX.start	{
				stage(title:	'Hello	GroovyFX',	visible:	true)	{
								scene(fill:	DARKSLATEGREY,	width:	860,	height:	430)	{
												borderPane	{
																top	{
																				hbox(padding:	[20,	60,	20,	60])	{
																								text(text:	'Hello	',	font:	'80pt	sanserif')	{
																												fill	linearGradient(endX:	0,	stops:	[PALEGREEN,	SEAGREEN])
																								}
																								text(text:	'GroovyFX',	font:	'80pt	sanserif')	{
																												fill	linearGradient(endX:	0,	stops:	[CYAN,	DODGERBLUE])
																												effect	dropShadow(color:	DODGERBLUE,	radius:	25,	spread:	0.25)
																								}
																				}
																}
																group(id:	'logo',	scaleX:	2,	scaleY:	2)	{
																				transitions	=	parallelTransition()
																				star	delegate,	12,	[LIGHTGREEN,	GREEN]*.brighter()
																				star	delegate,	6,	[LIGHTBLUE,	BLUE]*.brighter()
																				star	delegate,	0,	[YELLOW,	ORANGE]
																				fxLabel	delegate
																				onMouseClicked	{	transitions.playFromStart()	}
																}
				}			}			}
				transitions.delay	=	Duration.seconds(1)
				transitions.playFromStart()
				transitions.delay	=	Duration.seconds(0)
}
 
5
Example
 
6
Simple	Scene
	
General	contract
import	static	groovyx.javafx.GroovyFX.start
start	{
				stage(title:	'Hello	GroovyFX',	visible:	true)	{
								scene	{
												stylesheets('groovyfx.css')
												label('Hello	GroovyFX',	styleClass:	'big')
								}
				}
}
[container	name](value?,	attributes*)	{
				[subcontainer	name](value?,	attributes*)	{
								[node	name](value?,	attributes*)
				}
}
 
7
Simple	Scene
 
8
Forms	and	components
 
9
Simple	Form
import	static	groovyx.javafx.GroovyFX.start
start	{
				stage(title:	'Simple	form',	visible:	true)	{
								scene	{
												stylesheets('groovyfx.css')
												vbox	{
																label('Name')
																textField(onAction:	{	evt	->	result.text	=	evt.source.text	})
																label(id:	'result')
												}
								}
				}
}
 
10
Simple	Form
 
11
Binding
import	static	groovyx.javafx.GroovyFX.start
start	{
				stage(title:	'Simple	form	binding',	visible:	true)	{
								scene	{
												stylesheets('groovyfx.css')
												vbox	{
																label('Name')
																def	textField	=	textField()
																label	text:	bind(textField.textProperty())
																label	text:	bind(textField.text())
																label	text:	bind{textField.text}
																label	text:	bind(textField,	'text')
																label	text:	bind(textField,	'text').using{	"Text:	$it"	}
																label	id:	'lastLabel'
																bind	lastLabel.text()	to	textField.text()
												}
								}
				}
}
 
12
Binding
 
13
Bean	Binding
import	java.time.LocalDate
import	groovyx.javafx.beans.FXBindable
@FXBindable
class	Person	{
				String	name
				LocalDate	birth
}
def	person	=	new	Person(name:	'Sascha',	birth:	new	LocalDate(1975,	4,	1))
groovyx.javafx.GroovyFX.start	{
				stage(title:	'Bean	binding',	visible:	true)	{
								scene	{
												stylesheets('groovyfx.css')
												vbox	{
																label	'Name'
																textField(text:	bind(person,	'name'))
																label	'Birthday'
																datePicker(value:	bind(person.birth()))
																label	text:	bind	{	person.birth	&&	person.name	}.using	{
																				"$person.name	is	${LocalDate.now().year	-	person.birth.year}	years	old"
}			}			}			}			}
 
14
Bean	Binding
 
15
Layouting
import	static	groovyx.javafx.GroovyFX.start
start	{
				stage(title:	'Border	Pane	Demo',	visible:	true)	{
								scene	{
												stylesheets('groovyfx.css')
												borderPane	{
																top	{
																				label('Header')
																}
//														center	{
																				textField(id:	'tf')
//														}
																bottom	{
																				label	text:	bind(tf.textProperty())
																}
																right	{
																				imageView('GroovyFX_logo.png')
																}
												}
								}
				}
}
 
16
Layouting
 
17
GridLayout
groovyx.javafx.GroovyFX.start	{
				stage(title:	'GridLayout	form',	visible:	true)	{
								scene	{
												stylesheets('groovyfx.css')
												gridPane(hgap:	5,	vgap:	10,	padding:	25,	alignment:	TOP_CENTER)	{
																columnConstraints(minWidth:	50,	halignment:	RIGHT)
																columnConstraints(prefWidth:	250,	hgrow:	'always')
																label("Please	send	us	your	feedback",	style:	"-fx-font-size:	18px;",
																								row:	0,	columnSpan:	2,	halignment:	"center",	margin:	[0,	0,	10])	{
																				onMouseEntered	{	e	->	e.source.parent.gridLinesVisible	=	true	}
																				onMouseExited	{	e	->	e.source.parent.gridLinesVisible	=	false	}
																}
																label("Name",	hgrow:	"never",	row:	1,	column:	0)
																textField(promptText:	"Your	name",	row:	1,	column:	1	)
																label("Email",	row:	2,	column:	0)
																textField(promptText:	"Your	email	address",	row:	2,	column:	1)
																label("Message",	row:	3,	column:	0,	valignment:	"baseline")
																textArea(prefRowCount:	8,	row:	3,	column:	1,	vgrow:	'always')
																button("Send	Message",	row:	4,	column:	1,	halignment:	"right")
}			}			}			}
 
18
GridLayout
 
19
Lists
@FXBindable
class	SelectionHolder	{
				def	selected
}
def	selectionHolder	=	new	SelectionHolder()
def	colors	=	['blue',	'green',	'red']
start	{	primaryStage	->
				stage(title:	"GroovyFX	List	Demo",	width:	400,	height:	200,	visible:	true)	{
								scene(fill:	WHITE)	{
												vbox(padding:	10,	spacing:	5)	{
																choiceBox(value:	bind(selectionHolder.selected()),	items:	colors)
																listView(id:	'myList',	items:	colors)	{
																				onSelect	{	control,	item	->
																								selectionHolder.selected	=	item
																				}
																}
																selectionHolder.selected().onChange	{	source,	oldValue,	newValue	->
																				myList.selectionModel.select(newValue)
																}
																label(text:	bind(selectionHolder.selected()))
}			}			}			}
 
20
Lists
 
21
Colors
start	{	primaryStage	->
				def	colors	=	[
												BLUE,
												GREEN,
												RED,
												hsb(67,	0.8,	0.91),
												rgb(39,	209,	100),
												rgba(20,	100,	150,	0.60),
												delegate."#AA4411"
				]
				stage(title:	"GroovyFX	Table	Demo",	visible:	true)	{
								scene(fill:	WHITE)	{
												vbox(padding:	9,	spacing:	5)	{
//...
 
22
Tables
				tableView(selectionMode:	"single",	cellSelectionEnabled:	true,	items:	colors)	{
								tableColumn	text:	"Color",	prefWidth:	50,
																cellValueFactory:	{	new	ReadOnlyObjectWrapper(it.value)	},
																cellFactory:	{	column	->
																				Rectangle	rect	=	rectangle(width:	40,	height:	20)
																				new	TableCell<Color,	Color>()	{
																								void	updateItem(Color	color,	boolean	empty)	{
																												rect.fill	=	empty	?	Color.TRANSPARENT	:	color
																												setGraphic(rect)
																}			}			}
								tableColumn	text:	"Web",	prefWidth:	80,
																cellValueFactory:	{
																				Color	color	=	it.value
																				int	r	=	Math.round(color.red	*	255.0)
																				int	g	=	Math.round(color.green	*	255.0)
																				int	b	=	Math.round(color.blue	*	255.0)
																				new	ReadOnlyObjectWrapper(String.format("#%02X%02X%02X",	r,	g,	b))
																}
								tableColumn(property:	"opacity",	text:	"Opacity",	prefWidth:	70,
																converter:	{	from	->	"${Math.round(from	*	100)}%"	})
								tableColumn(property:	"hue",	text:	"Hue",	prefWidth:	120)
								tableColumn(property:	"brightness",	text:	"Brightness",	prefWidth:	120)
								tableColumn(property:	"saturation",	text:	"Saturation",	prefWidth:	120)
				}			}			}			}			}
 
23
Tables
 
24
Actions
start	{
				actions	{
								fxaction(id:	'saveAction',
																name:	'Save',
																description:	'This	saves	something',
																accelerator:	'Ctrl+S',
																enabled:	false,
																onAction:	{	println	"Save"	})
								fxaction(id:	'exitAction',
																name:	'Exit',
																onAction:	{	primaryStage.close()	})
								fxaction(id:	'copyAction',
																name:	'Copy',	icon:	'icons/copy.png',
																onAction:	{	println	"Copy"	}
								)
								fxaction(id:	'pasteAction',
																name:	'Paste',	icon:	'icons/paste.png',
																onAction:	{	println	"Paste"	}
								)
								fxaction(id:	'checkAction',
																name:	'Check',
																selected:	true,
																onAction:	{	println	"Check"	}
								)
				}
//	...
 
25
Actions
				stage(title:	"GroovyFX	Menu	Demo",	width:	650,	height:	450,	visible:	true)	{
								scene(fill:	WHITE)	{
												borderPane	{
																top	{
																				menuBar	{
																								menu("File")	{
																												menuItem("Open",	onAction:	{	println	"Open"	})	{
																																rectangle(width:	16,	height:	16,	fill:	RED)
																												}
																												menuItem(saveAction)	{
																																graphic(circle(radius:	8,	fill:	BLUE))
																												}
																												separatorMenuItem()
																												menuItem(exitAction)
																								}
																								menu(text:	"Edit")	{
																												menuItem(text:	"Cut",	onAction:	{	println	"Cut"	})	{
																																imageView('/icons/cut.png')
																												}
																												menuItem(copyAction)
																												menuItem(pasteAction)
																												separatorMenuItem()
																												checkMenuItem(checkAction)
																												def	toggleGroup	=	new	ToggleGroup()
																												radioMenuItem("Radio1",	toggleGroup:	toggleGroup,	selected:	true)
																												radioMenuItem("Radio2",	toggleGroup:	toggleGroup)
																												menu("Foo")	{
																																menuItem("Bar")
																																menuItem("FooBar")
																}			}			}			}
//	...
 
26
Actions
																center	{
																				vbox(spacing:	20,	padding:	10)	{
																								checkBox("Enable	'Save'	menu",	id:	'cb')
																								bean(saveAction,	enabled:	bind(cb.selectedProperty()))
																				}
																}
																bottom	{
																				toolBar	{
																								button(onAction:	{	println	"Cut"	})	{
																												graphic	imageView('/icons/cut.png')
																								}
																								button(copyAction,	skipName:	true)
																								button(pasteAction,	skipName:	true)
																				}
																}
												}
								}
				}
}
 
27
Actions
 
28
Charts
def	pieData	=	FXCollections.observableArrayList([
								new	PieChart.Data("Yours",	42),
								new	PieChart.Data("Mine",	58)
])
start	{
				Map	data	=	[first:	0.25f,	second:	0.25f,	third:	0.25f]
				stage(title:	'Chart	Demo',	visible:	true,	width:	1024,	height:	960)	{
								scene	{
												stylesheets('groovyfx.css')
												stackPane	{
																scrollPane	{
																				tilePane(padding:	10,	prefTileWidth:	480,	prefColumns:	2)	{
																								pieChart(data:	[first:	0.25f,	second:	0.25f,	third:	0.25f])
																								stackPane(alignment:	TOP_RIGHT)	{
																												pieChart(data:	pieData,	animated:	true)
																												button('Add	Slice')	{
																																onAction	{
																																				pieData.add(new	PieChart.Data('Other',	25))
																																}
																												}
																								}
//	...
 
29
Charts
				lineChart(data:	[First:	[0,0.25,0.5,1.5,2,1],	Second:	[0.25,0,0.5,0.5,1.5,0.75]])
				final	yAxis	=	numberAxis(label:	"Y	Axis",	lowerBound:	-1.2,	upperBound:	1.2,
												tickUnit:	0.2,	autoRanging:	false)
				lineChart(xAxis:	categoryAxis(label:	"X	Axis"),	yAxis:	yAxis)	{
								series(name:	'First	Series',	data:	["A",	0,	"B",	1,	"C",	-1])
								series(name:	'Second	Series',	data:	[["A",	0],	["B",	-1],	["C",	1],	["D",	0]])
				}
				areaChart	{
								series(name:	'First	Series',	data:	[0,	0,	0.5,	0.2,	1.5,	0.6,	2,	0.8])
								series(name:	'Second	Series',	data:	[0,	0,	0.25,	0.2,	0.5,	0.6,	2.25,	0.4])
				}
				bubbleChart	{
								series(name:	'First	Series',	data:	[[0,0.2,0.1],	[0.5,0.2,0.25],	[1.5,0.1,0.5]])
								series(name:	'Second	Series',	data:	[[0,	0.1,	0.25],	[0.2,	0.5,	0.2]])
				}
				scatterChart	{
								series(name:	'First	Series',	data:	[0,	0,	0.5,	0.2,	1.5,	0.6,	2,	0.8])
								series(name:	'Second	Series',	data:	[0,	0,	0.25,	0.2,	0.5,	0.6,	2.25,	0.4])
				}
				barChart(barGap:	0,	categoryGap:	0)	{
								series(name:	'2010',	data:	['Q1',	1534,	'Q2',	2698,	'Q3',	1945,	'Q4',	3156])
								series(name:	'2012',	data:	['Q1',	2200,	'Q2',	2750,	'Q3',	2125,	'Q4',	3100])
}			}			}			}			}			}		}
 
30
Charts
DEMO
 
31
Graphics	and	animations
 
32
Paths
start	{
				stage(title:	"GroovyFX	Path	Demo",	visible:	true)	{
								scene(fill:	BLACK)	{
												path(translateX:	0,	translateY:	493.672	+	10,	fill:	WHITE,	stroke:	GREY,
																				strokeWidth:	1,
																				strokeLineCap:	StrokeLineCap.BUTT,
																				strokeLineJoin:	StrokeLineJoin.MITER,
																				strokeMiterLimit:	4.00000000)	{
																moveTo(x:	105.367,	y:	-493.672)
																cubicCurveTo(
																								controlX1:	128.507,	controlY1:	-478.22,
																								controlX2:	151.465,	controlY2:	-462.40,
																								x:	173.917,	y:	-446.100
																)
																cubicCurveTo(
																								controlX1:	128.862,	controlY1:	-466.995,
																								controlX2:	79.407,	controlY2:	-482.018,
																								x:	24.547,	y:	-490.346
																)
//	...
 
33
Paths
				cubicCurveTo(controlX1:	71.244,	controlY1:	-463.626,	controlX2:	116.143,	controlY2:	-434.766,
												x:	160.252,	y:	-404.822)
				cubicCurveTo(controlX1:	123.049,	controlY1:	-422.855,	controlX2:	82.772,	controlY2:	-437.042,
												x:	38.650,	y:	-446.192)
				cubicCurveTo(controlX1:	96.868,	controlY1:	-411.870,	controlX2:	148.018,	controlY2:	-373.727,
												x:	193.360,	y:	-331.986)
				cubicCurveTo(controlX1:	136.020,	controlY1:	-284.773,	controlX2:	86.295,	controlY2:	-227.283,
												x:	45.790,	y:	-157.820)
				cubicCurveTo(controlX1:	72.900,	controlY1:	-182.110,	controlX2:	100.700,	controlY2:	-205.365,
												x:	128.658,	y:	-228.500)
				cubicCurveTo(controlX1:	81.942,	controlY1:	-172.640,	controlX2:	45.050,	controlY2:	-106.990,
												x:	20.200,	y:	-29.865)
				cubicCurveTo(controlX1:	40.560,	controlY1:	-54.485,	controlX2:	61.188,	controlY2:	-78.068,
												x:	82.105,	y:	-100.682)
				cubicCurveTo(controlX1:	126.805,	controlY1:	-168.167,	controlX2:	171.672,	controlY2:	-247.792,
												x:	230.961,	y:	-271.100)
				cubicCurveTo(controlX1:	201.351,	controlY1:	-240.392,	controlX2:	167.601,	controlY2:	-195.936,
												x:	132.711,	y:	-152.955)
				cubicCurveTo(controlX1:	173.701,	controlY1:	-193.392,	controlX2:	215.801,	controlY2:	-230.415,
												x:	259.126,	y:	-264.467)
				cubicCurveTo(controlX1:	320.724,	controlY1:	-193.977,	controlX2:	369.883,	controlY2:	-115.087,
												x:	411.271,	y:	-28.594)
				cubicCurveTo(controlX1:	404.533,	controlY1:	-73.388,	controlX2:	394.475,	controlY2:	-115.978,
												x:	381.241,	y:	-156.260)
				lineTo(x:	427.685,	y:	-90.730)
//	...
 
34
Paths
				cubicCurveTo(controlX1:	427.685,	controlY1:	-90.730,	controlX2:	401.648,	controlY2:	-163.420,
												x:	384.025,	y:	-192.717)
				cubicCurveTo(controlX1:	424.785,	controlY1:	-136.807,	controlX2:	462.233,	controlY2:	-78.289,
												x:	496.353,	y:	-17.512)
				cubicCurveTo(controlX1:	477.679,	controlY1:	-106.966,	controlX2:	445.841,	controlY2:	-187.284,
												x:	397.460,	y:	-255.736)
				cubicCurveTo(controlX1:	432.366,	controlY1:	-221.046,	controlX2:	466.097,	controlY2:	-184.636,
												x:	498.390,	y:	-146.691)
				cubicCurveTo(controlX1:	465.048,	controlY1:	-223.173,	controlX2:	423.580,	controlY2:	-290.180,
												x:	372.214,	y:	-345.000)
				cubicCurveTo(controlX1:	412.438,	controlY1:	-370.887,	controlX2:	453.694,	controlY2:	-394.730,
												x:	496.077,	y:	-416.783)
				cubicCurveTo(controlX1:	464.052,	controlY1:	-411.223,	controlX2:	433.587,	controlY2:	-403.863,
												x:	404.071,	y:	-394.849)
				cubicCurveTo(controlX1:	425.907,	controlY1:	-411.022,	controlX2:	448.481,	controlY2:	-426.973,
												x:	471.095,	y:	-442.372)
				cubicCurveTo(controlX1:	433.108,	controlY1:	-430.462,	controlX2:	396.462,	controlY2:	-416.597,
												x:	362.028,	y:	-400.939)
				cubicCurveTo(controlX1:	404.696,	controlY1:	-428.612,	controlX2:	448.348,	controlY2:	-454.607,
												x:	493.032,	y:	-479.541)
				lineTo(x:	493.029,	y:	-479.541)
				cubicCurveTo(controlX1:	425.559,	controlY1:	-461.486,	controlX2:	362.199,	controlY2:	-437.351,
												x:	304.031,	y:	-405.993)
				cubicCurveTo(controlX1:	247.737,	controlY1:	-447.783,	controlX2:	182.021,	controlY2:	-477.780,
												x:	105.368,	y:	-493.673)
				lineTo(x:	105.367,	y:	-493.672)
				closePath()
}			}			}			}
 
35
Paths
 
36
Shapes
start	{
				stage(title:	"GroovyFX	Shape	Demo",	width:	400,	height:	400,	visible:	true)	{
								scene(fill:	BLACK)	{
												group(id:	'group')	{
																rectangle	x:	25,	y:	25,
																								width:	150,	height:	75,
																								arcWidth:	20,	arcHeight:	20,
																								fill:	GROOVYBLUE,	stroke:	ORANGE,	strokeWidth:	2
																circle	centerX:	150,	centerY:	100,
																								radius:	20,	fill:	RED
																svgPath	content:	"""
												M248.91	50c11.882-.006	23.875	1.018	35.857	3.13
												85.207	15.025	152.077	81.895	167.102	167.102	15.023	85.208-24.944
												170.917-99.874	214.178-32.782	18.927-69.254	27.996-105.463
												27.553-46.555-.57-92.675-16.865-129.957-48.15l30.855-36.768c50.95
												42.75	122.968	49.05	180.566	15.797	57.597-33.254	88.152-98.777
												76.603-164.274-11.55-65.497-62.672-116.62-128.17-128.168-51.656-9.108-103.323
												7.98-139.17	43.862L185	192H57V64l46.34	46.342C141.758	71.962	194.17
												50.03	248.91	50z""",
																								translateX:	-130,	translateY:	-200,
																								scaleX:	0.1,	scaleY:	0.1,
																								fill:	WHITE,	stroke:	WHITE,	strokeWidth:	2
//	...
 
37
Shapes	and	Animations
polygon(id:	'triangle',
				points:	[0,	-10,	10,	10,	-10,	10,	0,	-10],
				translateX:	70,	translateY:	60,
				scaleX:	2.0,	scaleY:	2.0,	fill:	BLUE,
				onMousePressed:	{
								if	(rotation.status	==	Animation.Status.RUNNING)
												rotation.pause()
								else
												rotation.play()
				})	{
								rotation	=	rotateTransition	2.s,	tween:	LINEAR,	to:	-360,	cycleCount:	INDEFINITE
				}
parallelTransition(onFinished:	{	println	"parallel	done"	})	{
				translateTransition	3.s,	tween:	EASE_OUT,	to:	100,
												onFinished:	{	println	"translate	done"	}
				scaleTransition	3.s,	interpolator:	EASE_IN,	to:	2.0,
												onFinished:	{	println	"scale	done"	}
}.playFromStart()
}			}			}			}
 
38
Shapes
 
39
Effects
start	{
				stage(title:	'Animation	Demo',	visible:	true)	{
								scene	{
												rectangle(width:	800,	height:	600,
																				effect:	blend(mode:	"screen")	{
																								topInput	{
																												imageInput(source:	"background-ripples.png",	x:	0,	y:	0)
																								}
																								bottomInput	{
																												color	=	colorInput(
																																				paint:	radialGradient(
																																												center:	[0.7,	0.05],
																																												radius:	0.6,
																																												stops:	["#767A7B",	"#222222"]
																																				).build(),
																																				x:	0,	y:	0,
																																				width:	800,	height:	600
																												)
																								}
																				}
												)
//	...
 
40
Animated	Objects
												circle	id:	'circle',	radius:	60,
																				fill:	radialGradient(
																												center:	[0.5,	0.5],
																												radius:	0.7,
																												stops:	[ORANGE,	DARKORANGE]
																				),
																				effect:	glow(level:	0.5)
												noparent	{
																path(id:	'thePath',	translateX:	50,	translateY:	5)	{
																				moveTo(x:	100,	y:	100)
																				arcTo(x:	300,	y:	100,	radiusX:	5,	radiusY:	10)
																				lineTo(x:	600,	y:	200)
																				lineTo(x:	300,	y:	500)
																				arcTo(x:	150,	y:	200,	radiusX:	50,	radiusY:	100)
																				closePath()
				}			}			}			}
				pathTransition(10.s,
												delay:	100.ms,
												node:	circle,
												path:	thePath,
												orientation:	PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT
				).play()
//	...
 
41
Animated	Background
				timeline(cycleCount:	-1,	autoReverse:	true)	{
								at(4.s)	{
												change(color,	"paint")	to(x:	0.3,	y:	0.95)	tween	new	CenterInterpolator()
												onFinished	{	println	"4	seconds	elapsed"	}
								}
				}.play()
}
class	CenterInterpolator	extends	Interpolator	{
				@Override
				Object	interpolate(Object	startValue,	Object	endValue,	double	fraction)	{
								RadialGradient	s	=	startValue
								return	new	RadialGradient(
																s.focusAngle,
																s.focusDistance,
																EASE_BOTH.interpolate(s.centerX,	endValue.x,	fraction),
																EASE_BOTH.interpolate(s.centerY,	endValue.y,	fraction),
																s.radius,
																s.proportional,
																s.cycleMethod,
																s.stops)
				}
				@Override	protected	double	curve(double	t)	{	return	0	}
}
 
42
Animations
 
43
Animations
DEMO
 
44
Enhancing	GroovyFX
 
45
Using	custom	components
start	{
				def	colors	=	[BLUE,	GREEN,	RED,	hsb(67,	0.8,	0.91),
																		rgb(39,	209,	100),	rgba(20,	100,	150,	0.60),
																		delegate."#AA4411"]	as	ObservableList
				stage(title:	'Custom	Components	Demo',	visible:	true)	{
								scene()	{
												borderPane	{
																treeView(id:	'tree',	showRoot:	false,	prefHeight:	300)	{
																				treeItem(expanded:	true,	value:	"Root")	{
																								treeItem(value:	"one")	{
																												treeItem(value:	"one.one")
																												treeItem(value:	"one.two")
																												treeItem(value:	"one.three")
																												graphic	{	rectangle(width:	20,	height:	20,	fill:	RED)	}
																								}
																								treeItem(value:	"two")	{
																												treeItem(value:	"two.one")
																												treeItem(value:	"two.two")
																												treeItem(value:	"two.three")
																												graphic	{	rectangle(width:	20,	height:	20,	fill:	GREEN)	}
																}			}			}
//	...
 
46
Using	custom	components
																tree.selectionModel.selectionMode	=	SelectionMode.SINGLE
																top	{
																				node	new	BreadCrumbBar(tree.root),
																												selectedCrumb:	bind(tree.selectionModel,	'selectedItem'),
																												prefHeight:	30
																}
																bottom	{
																				container	new	MigPane("wrap	2",	"20[]5[fill,	grow]20",	""),	{
																								4.times	{
																												button("Button	$it")
																								}
																				}
																}
												}
								}
				}
}
 
47
Using	custom	components
 
48
Own	Factories
import	groovyfx.javafx.factory.MessageFactory
import	org.controlsfx.control.GridView
import	org.controlsfx.control.cell.ColorGridCell
groovyx.javafx.GroovyFX.start	{
				delegate.registerBeanFactory('gridView',	GridView)
				delegate.registerFactory('message',	new	MessageFactory())
				stage(title:	'Custom	Factory	Demo',	visible:	true)	{
								scene	{
												stylesheets('groovyfx.css')
												vbox	{
																label('Hello	GroovyFX',	styleClass:	'big')
																gridView(items:	[RED,	GREEN,	YELLOW,	SLATEGREY],
																								prefHeight:	200,
																								cellFactory:	{	new	ColorGridCell()	}
																)
																message(message:	'This	is	a	message')
												}
								}
				}
}
 
49
Own	Factories
 
50
Think	Big
Application	Framework
Java,	Groovy	and	Kotlin
JavaFX,	Swing,	Pivot,	Lanterna
MVC,	MVVC,	PresentationModel
a	lot	of	usefull	stuff
http://griffon-framework.org
 
51
Questions?
Alexander	Klein
Branchmanager
codecentric	AG
Curiestr.	2
70563	Stuttgart,	Germany
	+49	(0)	172	529	40	20
	alexander.klein@codecentric.de
	www.codecentric.de
	blog.codecentric.de
	@saschaklein
 
52

Contenu connexe

Tendances

Tendances (20)

WebRTC と Native とそれから、それから。
WebRTC と Native とそれから、それから。 WebRTC と Native とそれから、それから。
WebRTC と Native とそれから、それから。
 
Web of Technologies
Web of TechnologiesWeb of Technologies
Web of Technologies
 
Require js + backbone, bower and grunt
Require js + backbone, bower and gruntRequire js + backbone, bower and grunt
Require js + backbone, bower and grunt
 
DDEV - Extended
DDEV - ExtendedDDEV - Extended
DDEV - Extended
 
Node js实践
Node js实践Node js实践
Node js实践
 
Groovy a Scripting Language for Java
Groovy a Scripting Language for JavaGroovy a Scripting Language for Java
Groovy a Scripting Language for Java
 
Compressed js with NodeJS & GruntJS
Compressed js with NodeJS & GruntJSCompressed js with NodeJS & GruntJS
Compressed js with NodeJS & GruntJS
 
Node.js and Ruby
Node.js and RubyNode.js and Ruby
Node.js and Ruby
 
Security of go modules and vulnerability scanning in GoCenter
Security of go modules and vulnerability scanning in GoCenterSecurity of go modules and vulnerability scanning in GoCenter
Security of go modules and vulnerability scanning in GoCenter
 
Building a REST API with Node.js and MongoDB
Building a REST API with Node.js and MongoDBBuilding a REST API with Node.js and MongoDB
Building a REST API with Node.js and MongoDB
 
Nodejs presentation
Nodejs presentationNodejs presentation
Nodejs presentation
 
Anwendungsfälle für Elasticsearch JavaLand 2015
Anwendungsfälle für Elasticsearch JavaLand 2015Anwendungsfälle für Elasticsearch JavaLand 2015
Anwendungsfälle für Elasticsearch JavaLand 2015
 
Lets crash-applications
Lets crash-applicationsLets crash-applications
Lets crash-applications
 
NodeJS
NodeJSNodeJS
NodeJS
 
NodeJS
NodeJSNodeJS
NodeJS
 
Jedi knight
Jedi knightJedi knight
Jedi knight
 
Fake it 'til you make it
Fake it 'til you make itFake it 'til you make it
Fake it 'til you make it
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
 
PFIセミナー資料 H27.10.22
PFIセミナー資料 H27.10.22PFIセミナー資料 H27.10.22
PFIセミナー資料 H27.10.22
 
TDD with Spock @xpdays_ua
TDD with Spock @xpdays_uaTDD with Spock @xpdays_ua
TDD with Spock @xpdays_ua
 

En vedette

En vedette (20)

マイクロソフトが創る未来 医療編 20170401
マイクロソフトが創る未来 医療編 20170401マイクロソフトが創る未来 医療編 20170401
マイクロソフトが創る未来 医療編 20170401
 
Elixir-Conf-Japan-2017-session-ohr486
Elixir-Conf-Japan-2017-session-ohr486Elixir-Conf-Japan-2017-session-ohr486
Elixir-Conf-Japan-2017-session-ohr486
 
ARM Compute Library
ARM Compute LibraryARM Compute Library
ARM Compute Library
 
Biases in military history
Biases in military historyBiases in military history
Biases in military history
 
In the DOM, no one will hear you scream
In the DOM, no one will hear you screamIn the DOM, no one will hear you scream
In the DOM, no one will hear you scream
 
Waarom is Jong VLD lid van 11.11.11?
Waarom is Jong VLD lid van 11.11.11?Waarom is Jong VLD lid van 11.11.11?
Waarom is Jong VLD lid van 11.11.11?
 
Pubic mental health: time to translate evidence into policy and practice
Pubic mental health: time to translate evidence into policy and practicePubic mental health: time to translate evidence into policy and practice
Pubic mental health: time to translate evidence into policy and practice
 
グローバル理工人材のための今日から使える検索テクニック ―もう日本語でググるのはやめよう
グローバル理工人材のための今日から使える検索テクニック ―もう日本語でググるのはやめようグローバル理工人材のための今日から使える検索テクニック ―もう日本語でググるのはやめよう
グローバル理工人材のための今日から使える検索テクニック ―もう日本語でググるのはやめよう
 
Delfina Gómez, la candidata desconocida
Delfina Gómez, la candidata desconocidaDelfina Gómez, la candidata desconocida
Delfina Gómez, la candidata desconocida
 
Top 10 Digital Workplace Patterns #spscalgary
Top 10 Digital Workplace Patterns #spscalgaryTop 10 Digital Workplace Patterns #spscalgary
Top 10 Digital Workplace Patterns #spscalgary
 
Alejandro Fernandez vs Luis Miguel
Alejandro Fernandez vs Luis MiguelAlejandro Fernandez vs Luis Miguel
Alejandro Fernandez vs Luis Miguel
 
Green Behavior
Green BehaviorGreen Behavior
Green Behavior
 
Playful Neurons
Playful NeuronsPlayful Neurons
Playful Neurons
 
Top Artificial Intelligence (AI) Startups Disrupting Retail
Top Artificial Intelligence (AI) Startups Disrupting RetailTop Artificial Intelligence (AI) Startups Disrupting Retail
Top Artificial Intelligence (AI) Startups Disrupting Retail
 
#MobileRevolution - How Mobile Is Changing You
#MobileRevolution - How Mobile Is Changing You#MobileRevolution - How Mobile Is Changing You
#MobileRevolution - How Mobile Is Changing You
 
あなたの業務に機械学習を活用する5つのポイント
あなたの業務に機械学習を活用する5つのポイントあなたの業務に機械学習を活用する5つのポイント
あなたの業務に機械学習を活用する5つのポイント
 
10 Things You Didn’t Know About Mobile Email from Litmus & HubSpot
 10 Things You Didn’t Know About Mobile Email from Litmus & HubSpot 10 Things You Didn’t Know About Mobile Email from Litmus & HubSpot
10 Things You Didn’t Know About Mobile Email from Litmus & HubSpot
 
How to Earn the Attention of Today's Buyer
How to Earn the Attention of Today's BuyerHow to Earn the Attention of Today's Buyer
How to Earn the Attention of Today's Buyer
 
25 Discovery Call Questions
25 Discovery Call Questions25 Discovery Call Questions
25 Discovery Call Questions
 
Modern Prospecting Techniques for Connecting with Prospects (from Sales Hacke...
Modern Prospecting Techniques for Connecting with Prospects (from Sales Hacke...Modern Prospecting Techniques for Connecting with Prospects (from Sales Hacke...
Modern Prospecting Techniques for Connecting with Prospects (from Sales Hacke...
 

Similaire à GroovyFX - Groove JavaFX

GTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyGTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with Groovy
Andres Almiray
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with Groovy
James Williams
 

Similaire à GroovyFX - Groove JavaFX (20)

Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGroovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
 
Javaone2008 Bof 5102 Groovybuilders
Javaone2008 Bof 5102 GroovybuildersJavaone2008 Bof 5102 Groovybuilders
Javaone2008 Bof 5102 Groovybuilders
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
LISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial HandoutsLISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial Handouts
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
 
Grooscript gr8conf 2015
Grooscript gr8conf 2015Grooscript gr8conf 2015
Grooscript gr8conf 2015
 
Grooscript greach 2015
Grooscript greach 2015Grooscript greach 2015
Grooscript greach 2015
 
Groovy on Android
Groovy on AndroidGroovy on Android
Groovy on Android
 
KSDG-iSlide App 開發心得分享
KSDG-iSlide App 開發心得分享KSDG-iSlide App 開發心得分享
KSDG-iSlide App 開發心得分享
 
Svcc Groovy Testing
Svcc Groovy TestingSvcc Groovy Testing
Svcc Groovy Testing
 
WebGL Awesomeness
WebGL AwesomenessWebGL Awesomeness
WebGL Awesomeness
 
Griffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java TechnologyGriffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java Technology
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
GTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyGTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with Groovy
 
Groovy & Grails
Groovy & GrailsGroovy & Grails
Groovy & Grails
 
Gradle in a Polyglot World
Gradle in a Polyglot WorldGradle in a Polyglot World
Gradle in a Polyglot World
 
Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with Groovy
 
Javaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 Groovytesting
 

Plus de sascha_klein

Plus de sascha_klein (9)

DSL101
DSL101DSL101
DSL101
 
Groovy on the shell
Groovy on the shellGroovy on the shell
Groovy on the shell
 
Bob the Builder - Gr8Conf EU 2017
Bob the Builder - Gr8Conf EU 2017Bob the Builder - Gr8Conf EU 2017
Bob the Builder - Gr8Conf EU 2017
 
Using Groovy with Jenkins
Using Groovy with JenkinsUsing Groovy with Jenkins
Using Groovy with Jenkins
 
Introduction to Graphics- and UI-Design
Introduction to Graphics- and UI-DesignIntroduction to Graphics- and UI-Design
Introduction to Graphics- and UI-Design
 
Android on Groovy
Android on GroovyAndroid on Groovy
Android on Groovy
 
Groovy on the shell
Groovy on the shellGroovy on the shell
Groovy on the shell
 
Groovy on the Shell
Groovy on the ShellGroovy on the Shell
Groovy on the Shell
 
Vert.x using Groovy - Simplifying non-blocking code
Vert.x using Groovy - Simplifying non-blocking codeVert.x using Groovy - Simplifying non-blocking code
Vert.x using Groovy - Simplifying non-blocking code
 

Dernier

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Dernier (20)

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
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
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
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
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

GroovyFX - Groove JavaFX