• Home
  • Events
  • About
  • JavaFX recipes "CSS vs. Code"

    In JavaFX you could style controls by using different ways, two possible solutions are

    • cascading stylesheets (CSS)
    • code (like you know it from Java Swing

    This blogpost is no advice on what is the better approach but only shows a little example of things I came across when using both approaches.

    So let’s take a look at those approaches and compare them on an example image.

    As an example I will take the following image that I have created in Adobe Fireworks

    120710 0004

    As you could see we have a circle with a linear gradient from top to bottom, the circle seems to be raised and has a drop shadow. The raised effect comes from adding two inner shadows to the circle, one with a black color and one with a white color. That means we have to apply one gradient and three different effects to the shape. So let’s check if this is possible…

     

    Using CSS:

    Using CSS is the preferred solution to style controls if you ask Oracle. And I have to agree that it has it’s advantages. Each control has either it’s own our one shared css file where all the style definitions are stored. In this case I have created a little control that only contains the circle and this is the css file for this control…

        .drop {

            -fx-skin: “DropSkin”;

        }


        .drop .circle {

            -fx-fill  : linear-gradient(from 50% 0% to 50% 100%,

                                        rgb(207, 0, 58) 0%,

                                        rgb(129, 0, 33) 100%);

            -fx-stroke: transparent;

            -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.65), 10, 0.5, 0.0, 0.0);

            -fx-effect: innershadow(gaussian, rgba(1, 1, 1, 0.65), 10, 0.5, 0.0, 5.0);

            -fx-effect: innershadow(gaussian, rgba(0, 0, 0, 0.65), 10, 0.5, 0.0, -5.0);

        }

    The -fx-skin variable defines the location of the Skin class that will be used to visualize the control. The variables in the .drop .circle class are defining the linear gradient of the circle and the effects. The java code that is needed to create the result is the following…

        final Circle circle = new Circle(64, 64, 48);

        circle.getStyleClass().add(“circle”);

    As you could see that’s only 2 lines of code which is really nice. Well at the moment it is not possible to chain effects in CSS which means we only could apply one of the needed effects which would lead to the following result for the code above…

    120710 0006

    One of the big advantages when using css (for me) is that you don’t have to take care about the start and stop positions of gradients.

    You just could type

        from 0%  0% to 0% 100%

    and that’s it, which is really nice. Another advantage is that you could apply a complete style by just writing

        shape.getStyleClass().add(“circle”);

    That’s really cool because it makes to change the style of a shape in your code. It’s also neat that you are able to define your own css stylesheet and apply it to your control. This makes it possible to change the complete styling of a control with one line of code. The JavaFX team added a lot of css features that you could use to style your shapes, for more information you should take a look at the official documentation that you could find here.

    But there are also drawbacks, Strings as method parameters could always lead to errors that you won’t see at compile time but only at runtime. The same is true for the style class defintion in the css file itself, where also a typo is enough to give you a runtime error.

    The other main problem is that it’s just not everything possible in css that is possible in code. Of course you could mix both approaches but to be honest this is also not very good to support afterwards.

    So let’s take a look at the code approach…

     

    Using Code:

    Using code offers you all possibilities, even if it feels a bit like Java Swing programming. The code to produce the expected image looks like follows…

        Circle circle = new Circle(64, 64, 48);    

        Paint fill = new LinearGradient(0, 18, 0, 110, 

                                        false, CycleMethod.NO_CYCLE,

                                        new Stop(0.0, Color.rgb(207, 0, 58)),

                                        new Stop(1.0, Color.rgb(129, 0, 33)));

        circle.setFill(fill);

        circle.setStroke(null);


        // Create the dark inner shadow on the bottom

        InnerShadow innerShadow = InnerShadowBuilder.create()

                                                    .offsetY(5)

                                                    .radius(5)

                                                    .color(Color.color(0, 0, 0, 0.65))

                                                    .blurType(BlurType.GAUSSIAN)

                                                    .build();


         // Create the bright inner glow on the top

        InnerShadow innerGlow = InnerShadowBuilder.create()

                                                  .offsetY(5)

                                                  .radius(5)

                                                  .color(Color.color(1, 1, 1, 0.65))

                                                  .blurType(BlurType.GAUSSIAN)

                                                  .input(innerShadow)

                                                  .build();


        // Create the drop shadow on the outside

        DropShadow dropShadow = DropShadowBuilder.create()

                                                 .radius(5)

                                                 .color(Color.color(0, 0, 0, 0.65))

                                                 .blurType(BlurType.GAUSSIAN)

                                                 .input(innerGlow)

                                                 .build();


        // Apply the chained effects to the shape

        circle.setEffect(dropShadow);

    The main difference between the code and the css approach is the possibility to chain effects in code and of course the amount of code you have to write. This means you could define an effect and use this effect as an input to another effect. With this solution we are able to add two inner shadows and a dropshadow to one shape. The result of this codes looks like this…

    120710 0005

    As you could see the result is very close to the source image. 

     

    Conclusion:

    There is no simple answer to the question which way you should choose because it really depends on the usecase. For standard styling where you only use a single effect or no effect at all the CSS approach absolutely makes sense but for more complex graphics with multiple effects it might be easier to choose the code approach. At the moment it’s also faster if you apply colors and gradients by using the code approach instead of the CSS approach but this might change in the future.

    I personally like the code approach more because of the “compile time safety” and the total control but I have to admit that the CSS approach is also really nice and I use both.

    So as always it’s up to you…so keep coding…

     

    Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • email
    • Print
    • Twitter
    • LinkedIn
    • XING
    • Facebook
    • Google Bookmarks

    Leave a Comment

    Time limit is exhausted. Please reload the CAPTCHA.

    css.php