JavaFX Custom Control – Nest Thermostat Part 2

I’ts been a while since I started to create the Nest thermostat FX custom control ! So last time, as suggested by Gerrit Grunwald I took some time to reproduce the Nest thermostat design with inkscape, as a first step to build a JavaFX version of it.

Today I’d like to share with you the mistakes I made when trying to create it in JavaFX, and also the final result.

First of all, I started to use the css file in order to make the background, that is composed in my inkscape version of three circle with three linear gradients andtwoa strokes. As suggested by Gerrit I made it by using only one Region and style it using CSS.

.nest{}

.nest .frame {
  -fx-background-radius		: 1024px;
  -fx-background-insets		: 1, 4, 20;
  -fx-background-color 		: linear-gradient(from 27.1% 6.5% to 77.35% 91%,  
                                      	#e8e8e8 0%, 
                                      	#c6c6c6 50%, 
                                      	#a6a6a6 100%),
                                  linear-gradient(from 27.1% 6.5% to 77.35% 91%, 
                                      	#fdfdfd 0%,
  					#ededed 3.552646%,
  					#d7d7d7 7.277831%,
  					#d2d2d2 11.973317%,
  					#c7c7c7 18.269639%,
  					#c1c1c1 25.449407%,
  					#b0b0b0 32.21809%,
  					#999999 37.210315%,
  					#868686 43.145844%,
  					#747474 49.577036%,
  					#5c5c5c 55.667913%,
  					#5a5a5a 61.299348%,
  					#5e5e5e 68.340749%,
  					#676767 76.115692%,
  					#706e6f 82.365692%,
  					#838383 88.148153%,
  					#959595 93.637025%,
  					#a8a8a8 100%),
  				linear-gradient(from 27.1% 6.5% to 77.35% 91%, 
                                      	#1c1715 0%, 
                                       	#181818 50%, 
                                       	#3a3a3a 100%); 
  -fx-border-radius		: 1024px;
  -fx-border-insets		: 0, 5, 20;
  -fx-border-width		: 0, 2, 1;
  -fx-border-color	 	: transparent, 
  				  linear-gradient(from 27.1% 6.5% to 77.35% 91%, 
                                    	#d5d5d5 0%, 
                                     	#747474 50%, 
                                     	#8f8f8f 100%), 
                                  #212121;
}

The final result was good, but when I resized my control I had bad result since the -fx-background-insets and -fx-border-width are absolute pixel values. You can see my problem below.

Nest-Mistake1
It took some time to me to figure out how to correct this. At the end the only idea I had was to make three different regions and use the svg path values. It would correct the -fx-background-insets pixel values, but not the stroke ones.

.nest{}

.nest .frame {
  -fx-shape			: "m 519.18435,179.4957 a 266.9594,266.9594 0 1 1 -0.72682,-2.0685";
  -fx-background-insets	        : 1;
  -fx-background-color 	        : linear-gradient(from 27.1% 6.5% to 77.35% 91%,  
                                     	#e8e8e8 0%, 
                                      	#c6c6c6 50%, 
                                       	#a6a6a6 100%);
}

.nest .frame1 {
  -fx-shape			: "m 514.32688,181.18013 a 261.81818,261.81818 0 1 1 -0.71283,-2.02866";
  -fx-background-color 	        : linear-gradient(from 27.1% 6.5% to 77.35% 91%, 
                                    	#fdfdfd 0%,
					#ededed 3.552646%,
					#d7d7d7 7.277831%,
					#d2d2d2 11.973317%,
					#c7c7c7 18.269639%,
					#c1c1c1 25.449407%,
					#b0b0b0 32.21809%,
					#999999 37.210315%,
					#868686 43.145844%,
					#747474 49.577036%,
					#5c5c5c 55.667913%,
					#5a5a5a 61.299348%,
					#5e5e5e 68.340749%,
					#676767 76.115692%,
					#706e6f 82.365692%,
					#838383 88.148153%,
					#959595 93.637025%,
					#a8a8a8 100%);      						
  -fx-border-width		: 2;
  -fx-border-color	 	: linear-gradient(from 27.1% 6.5% to 77.35% 91%, 
                                      	#d5d5d5 0%, 
                                      	#747474 50%, 
                                       	#8f8f8f 100%);
}

.nest .frame2 {
  -fx-shape			: "m 497.45305,187.03163 a 243.95858,243.95858 0 1 1 -0.66421,-1.89028";
  -fx-background-color 	        : linear-gradient(from 27.1% 6.5% to 77.35% 91%, 
                                     	#1c1715 0%, 
                                      	#181818 50%, 
                                      	#3a3a3a 100%); 
  -fx-border-width		: 1;
  -fx-border-color	 	: #212121;
}

nestmistake2.1

Anyway when I tried it, here is the result I had.

??? What is this ??? why am I only seeing one circle here… Well I have to say I took me some time to understand it was the fx-scale-shape and fx-position-shape attributes whose default value is true. Here it the definition of this two css attributes

-fx-position-shape<boolean>trueIf true means the shape centered within the region’s width and height, otherwise the shape is positioned at its source position. Has no effect if a shape string is not specified.
-fx-scale-shape<boolean>trueIf true means the shape is scaled to fit the size of the region, otherwise the shape is at its source size, and its position depends on the value of the position-shape property. Has no effect if a shape string is not specified.

So I only have to set the scale value to false then…  But when I did this, the shape into the region did not resized correctly when changing my control size… Argh!!!

nestmistake2.2

Well, eventually I tried scaling the region and setting its prefSize when the control was resized. So I used the code snippet below :

private void resize() {
   size = getWidth() < getHeight() ? getWidth() : getHeight();
   final double scaleRatio = size / initialSize;
   frame.setPrefSize(size, size);
   frame.setScaleX(scaleRatio);
   frame.setScaleY(scaleRatio);

   frame1.setPrefSize(size, size);
   frame1.setScaleX(scaleRatio);
   frame1.setScaleY(scaleRatio);

   frame2.setPrefSize(size, size);
   frame2.setScaleX(scaleRatio);
   frame2.setScaleY(scaleRatio);
}

Nst-Mistake3

It worked !!!

Well, I do not know if this is the right way to do it, but it is the only one I found so far… Anyone using other tricks to solve the problems I identified in this post, share it loud on the comment section !!

The ticks and currentCursor and targetCursor are done using my RadialMenuItem from RadialFX. For now It did not allow me to customize it though css, but now that I start to understand how it works, next step is to enhance the RadialFx RadialMenuItem with css attributes.

To conclude here is a little video of the result I have today.

  • Code will soon be available on JFXtras too !

 

Reference: JavaFX Custom Control – Nest Thermostat Part 2 from our JCG partner Laurent Nicolas at the Mr LoNee blog.
Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Leave a Reply


4 − = zero



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books