Profilo di 亮Omnia Vincit AmorFotoBlogElenchi Strumenti Guida

Blog


26/03/2009

JavaFX Tips: Getting Screen Dimension before Stage Initialization

To make adaptive UI, UI components' position and size should be calculated according to screen size instead of being hard-coded. JavaME developers usually make different builds for different devices(i.e. screen dimension are set as constants and hard-coded to different phone device) or using Displayable.getWidth()/getHeight() when canvas is created. JavaFX desktop developers, however would use Stage.width/height. This also has defects. Considering the following code snippets which intends to place a red rectangle that is half size of the screen.:

   1: var cs : Stage;
   2: var rec : Rectangle = Rectangle{
   3:     width: cs.width
   4:     height: cs.height / 2
   5:     fill: Color.RED
   6: }
   7: function run() {
   8:     stage = Stage {
   9:         scene: Scene {
  10:             content: rec
  11:         }
  12:     }
  13: }

 

When rec is created, stage is not initialized. So rec.width and rec.height would be 0 and you get a blank screen. So we would change this using bind keyword, and when stage.width is initialized, rec.width would get correct value too.

   1: var cs : Stage;
   2: var rec : Rectangle = Rectangle{
   3:     width: bind cs.width
   4:     height: bind cs.height / 2
   5:     fill: Color.RED
   6: }
   7: function run() {
   8:     stage = Stage {
   9:         scene: Scene {
  10:             content: rec
  11:         }
  12:     }
  13: }

We got the expected rectangle but for JavaFX mobile we have a better solution. JavaFX has an javafx.lang.FX class that is similar to java.lang.System class which provides  some static utility methods. We could use javafx.lang.FXgetProperty() to get screen dimension before stage variable is initialized. Let's see the final code for FX mobile.

   1: var cs : Stage;
   2: var rec : Rectangle = Rectangle{
   3:     width: Integer.parseInt(FX.getProperty("javafx.screen.width"))
   4:     height: Integer.parseInt(FX.getProperty("javafx.screen.height")) / 2
   5:     fill: Color.RED
   6: }
   7: function run() {
   8:     stage = Stage {
   9:         scene: Scene {
  10:             content: rec
  11:         }
  12:     }
  13: }


For mobile devices, the Stage width and height is fixed and won't change. So bind is not needed. We know that bind feature is exciting but it has performance costs. So removing bind will also improve the application's performance.