Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In JavaFX, should I use CSS or setter methods to change properties on my UI Nodes? [closed]

Tags:

java

javafx-2

There are two ways to set properties on my UI nodes (labels, buttons, etc.)

I could use something like this:

Button b = new Button("Sample");
b.setTextFill( Paint.valueOf("red") );
b.setTextAlignment( TextAlignment.CENTER );

Or I could do something equivalent:

Button b = new Button("Sample");
b.setStyle("-fx-text-alignment: center; -fx-text-fill: red");

What I'm wondering is, is one of these methods preferable for any reason (other than personal taste)?

like image 228
Xanatos Avatar asked Feb 07 '13 18:02

Xanatos


2 Answers

The answer to this does come down to personal taste a little bit, but there are some general rules of thumb things which I think are useful.

The four options for styling in JavaFX are:

  1. css stylesheets.
  2. css setStyle command issued from code.
  3. java code for styling.
  4. fxml attributes for styling.

My advice is:

  1. Use css stylesheets for almost all of your styling.
  2. Use Java API calls where you have thousands of Nodes or where you personally prefer the type safety and easy debugging capabilities the API offers.
  3. Use setStyle only when you need to dynamically change a style which can only be set using CSS and cannot be set using an API or a stylesheet.
  4. Don't apply styling via fxml.

The advantages of using css stylesheets for styling are:

  1. You can separate style from code.
  2. You can easily define multiple stylesheets and change them in and out at runtime to get different looks to your application.
  3. You are making use of a language specifically designed for styling.
  4. You can apply the stylesheets in a design tool like SceneBuilder.

Really, the last point is critical if you are using a visual design tool - you really need to use css stylesheets to get the most out of it. If you apply styles in code rather than in css stylesheets, then you won't really be able to visualize what the application looks like when you are trying to design it in the visual design tool. If you apply style through fxml attributes, then your fxml becomes unwieldy as it is then defining both the structure and layout of your application as well as it's style - and generally it is best to seperate those concerns.

I do use setStyle calls in my code sometimes, but mostly that is just because of laziness rather than because it is a recommended way to do it.

The need to dynamically change styles using setStyle should be very limited case. For example, in JavaFX 2.2 you cannot set the background color of a region via API. You can set it using a styleclass. But if you wanted to dynamically set the background color to a user selected color, then you might use a setStyle method like this button.setStyle("-fx-text-fill: " + userColor.toString() + ";");. So, really pretty specialized.

Also note that in JavaFX 8, some of the things which can only be done in JavaFX 2.2 by css (such as setting a region background) will be able to be done in code via Java API. For the example given above of setting a user fill color for a Region background, using the Java API for this would be the preferred method if JavaFX 8 is being used.

In terms of performance impact of the various usage cases. My understanding (from comments by the JavaFX css implementation maintainer in forums) in most cases is that the performance order from most performant to least performant would be something like below:

  1. Direct API call.
  2. Style via FXML.
  3. Style applied via styleclass.
  4. setStyle call.

Note that css application in JavaFX is designed to be quite efficient, so in many cases performance isn't a major consideration. My guess is that it is only when you have thousands of nodes being styled that there would be a major performance impact of using css, though I have no hard data to back that guess up.

In the past I have seen some comments by JavaFX programmers that they would like not use css and prefer to use a JavaFX API for styling their application. Reasons given are for things like easier debugging, everything in a single language, better integration with IDEs for assistance on method names, edit and compile time static type checking, etc. And if it is your preference to style using a Java API rather than css for these reasons in your own code, this is fine as far as it goes. But you simply won't be able to accomplish all of the styling you need using only the Java API.

Use of css and knowledge of how to use it in JavaFX is critical to being proficient with JavaFX technology. The main reason for this is that all core controls in JavaFX are styled by css. Even the most trivial JavaFX application usually makes use of these controls and if you want to be able to customize their look, you are going to need to understand css (even if it's just to read the standard JavaFX css stylesheet so that you know how the standard controls are styled). And when it comes to customizing the standard controls, it's generally going to be easier to apply a css custom stylesheet.

like image 142
jewelsea Avatar answered Oct 20 '22 06:10

jewelsea


I guess this can be debated, but in my opinion is to go back and see what you are hoping to accomplish. If you are planning on changing your style, it would be very clean when defined in an external CSS file. Then if you change your style down the road (or allow users to change their style) it would be changed at one place.

Button b = new Button("Sample");
b.setStyleClass("myClass");

JavaFX works great with an MVC approach. Styling would definetly fall into the view. Keep everything in one place. Why not keep it there?

Also, what makes your code look cleaner? Easier to read? How easy will this be to maintain, by you or someone else down the road?

like image 30
blo0p3r Avatar answered Oct 20 '22 05:10

blo0p3r