More Struggling with JavaFX

September 9th, 2009 by Martin Leave a reply »

In my first blog on JavaFX I mentioned polishing the details takes a lot of time and I thought it is due to the lack of experience. As I am spending more time trying to develop a real-life desktop application, I am becoming more doubtful about this. Too often I have to spend too much time trying to make the UI behave the way I want and sometimes I just have to give up and change my mind about the desired design to avoid wasting even more time. It is hard to provide concrete examples and ask for help as my application’s UI is quite complex. But recently I could isolate a simple case that I can use to demonstrate what I am talking about.
Look at the following simple code:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;

var rec1: Rectangle;
var stage: Stage = Stage {
    title: "Rectangles"
    width: 200
    height: 200
    scene: Scene {
        content: [
            VBox {
                spacing: 0
                content: [
                    rec1 = Rectangle {
                        fill: Color.BLACK
                        width: bind stage.scene.width
                        height: 50
                    }
                    Rectangle {
                        fill: Color.GRAY
                        width: bind stage.scene.width
                        height: bind stage.scene.height - rec1.height
                    }
                ]
            }
        ]
    }
}

It creates a window containing two rectangles that fully cover the scene:
Rectangles screenshot
All works great at this point.
Now, let’s see what happens when I set the stroke to Color.BLACK:

                    Rectangle {
                        fill: Color.GRAY
                        stroke: Color.BLACK
                        width: bind stage.scene.width
                        height: bind stage.scene.height - rec1.height
                    }

Running this I am getting the following result:
Rectangles screenshot
As you can see, besides the fact that the rectangle now has the black border, it also jumped both horizontally and vertically and uncovered a strip of white background color. Going back and forth trying to find a workaround can be time consuming – I did not find a good way of debugging this kind of issues. Now imagine the same thing happens when the UI contains many more nested components. Trying to figure out which one causes the problem and how to tweak things to get the desired result may be endless.
Anyway, I am still not giving up! Has anyone found an efficient way of debugging and resolving this type of issues quickly?

4 comments

  1. andy xie says:

    var rec1: Rectangle;
    var tmp1 = Rectangle { stroke: Color.BLACK };
    var tmp2 = Rectangle { };
    var gap = tmp1.layoutBounds.width-tmp2.layoutBounds.width;

    var stage: Stage = Stage {
    title: “Rectangles”
    width: 200
    height: 200
    scene: Scene {
    content: [
    VBox {
    spacing: 0
    content: [
    rec1 = Rectangle {
    fill: Color.BLACK
    width: bind stage.scene.width
    height: 50
    }
    Rectangle {
    fill: Color.GRAY
    width: bind stage.scene.width – gap
    height: bind stage.scene.height – rec1.layoutBounds.height – gap
    stroke: Color.BLACK
    }
    ]
    }
    ]
    }
    }

  2. Martin says:

    Thanks Andy, good try! :) It still does not solve the issue though – the white strip is still there (not sure if it is platform specific – I am using MacOS). Anyway, my main point was – it feels something is not right when seemingly simple things take a lot of effort. When problems such as this one appear it is quite time consuming to debug and resolve. Maybe there are some tricks for how to identify and fix this type of problems efficiently? The NetBeans debugger currently does not seem to be usable for JavaFX, so right now I am debugging by printing out layoutBounds or pref. height/width etc. of objects in a response to certain events to see what’s going on, then doing trial-error approach trying to fix it. Originally I was hoping I can be more productive with JavaFX than with plain Java when it comes to building UI.

  3. Jasper Potts says:

    It looks like a rectangle with stroke is reporting the wrong bounds which VBox is using. I will see if we can fix it. Here is a simple fix for now. Because strokes are centered on the shape they add 1px to the overall size so the -1s are needed to make the stroke inside the given size.

    var rec1: Rectangle;
    var stage: Stage = Stage {
    title: “Rectangles”
    width: 200
    height: 200
    scene: Scene {
    content: [
    rec1 = Rectangle {
    fill: Color.BLACK
    width: bind stage.scene.width
    height: 50
    }
    Rectangle {
    fill: Color.GRAY
    stroke: Color.BLACK
    y: bind rec1.height
    width: bind stage.scene.width – 1
    height: bind stage.scene.height – rec1.height -1
    }
    ]
    }
    }

    It is also recommended to move the width: 200 height:200 into the scene rather than stage as that will make the content area (Scene) 200×200 and make the stage 200×200 + any platform decorations, like the titlebar.

Leave a Reply