JavaFX Tip 4: Have the Final Word

When developing custom controls for JavaFX I would highly recommend to follow in the footsteps of  the core JavaFX controls and to make the API of your controls as final as possible and to put the “final” keyword in front of all your method declarations.

Example

In FlexGanttFX I have a lot of code that looks like this:

public final Activity getActivityAt(double x, double y) { ... }
public final Row getRowAt(double y) { ... }
public final void setShowLinks(boolean show) { ... }

 

Why?

When you design a control you have a specific behaviour of the control in mind. This behaviour can be protected by using “final”. If you do not use it then other developers will subclass the control, they will override its methods, they will run into problems, and they will submit a defect ticket to your issue management tool. In the end you will waste your time on chasing their bugs. Bugs that only exist because your control was used in a way that you couldn’t possibly foresee.

Where?

Protection is especially needed for the public API of the control class, which is managing the “state” of the control. It is the contract between you and the user of your control. It is less true for the skin of the control, because skins are “implementation detail” and people modifying skins know that they are interfering with the inner workings of the control. You still want to make it easy for other developers to modify the “appearance” of the control.

New Concept?

Protecting your controls this way is not a new concept but it wasn’t used very much in Swing. The case for using “final” is stronger now because JavaFX controls are much more observable than Swing controls. They are exposing their state via properties and observable collections. This way applications can react to state changes by “listening” to the control instead of plugging themself into the control by overriding its methods. Another reason is the clean separation into “control” and “skin” in JavaFX. Swing components often had “skin” aspects right in the component itself and not in the UI delegate (e.g. paintComponent()).

About these ads

8 thoughts on “JavaFX Tip 4: Have the Final Word

  1. Pingback: JavaFX links of the week, July 13 // JavaFX News, Demos and Insight // FX Experience

  2. Pingback: Java desktop links of the week, July 13 « Jonathan Giles

  3. Please don’t. The idea of making api methods final is understandable from the developer’s point of view for the reasons given above. For users, it will quite often situations where they cannot use a given module or control due to oversights in the original design.

    When publishing an API you should never assume that your code is working perfectly or even remotely complete in a sense that you have covered all valid use cases. JavaFX itself is especially problematic as the developers knowingly left out concepts existing in swing because ‘you will never need them’.

    Furthermore, when building a complex API I will often run into a case where I simply don’t understand why a control will render itself the way it does. Maybe there’s a misunderstanding, there might be a threading issue, a bug in the API or most likely I make a simple mistake but am too blind to see. Having the chance of overwriting methods is a simple way to hooking into the flow without resorting to crutches like aspects, as has helped me on countless occasions.

    Building user interfaces is trivial when everything works as it should, but may likely become one of the most frustrating and time consuming things when the API does not work out.

    Finally, there’s that situation where you’ve build this massive analytics application and the product owner says ‘Hey, that’s a great tool, but I really need errors bars for that chart’. And to which you’re left to respond: ‘Yeah, no, sorry, the API developer thought errors bars are useless and did not allow me to hook into his rendering routine…’

  4. Obviously I am looking at this from a framework developer’s point of view. However, I do understand that the framework user would like to have the ability to override methods, either to modify the control’s behavior or to understand its inner workings. But I also believe that in the end this will only lead to greater confusion and dirty work-arounds. If something does’t work or is missing, then please talk to the framework developer, so that the feature is either fixed or added. Not being able to modify the control yourself might in the end be the more productive solution, maybe not for the individual, but for the entire group of framework users. It will lead to a better product because if forces you to talk to the framework developer and this ongoing discussion leads to better code.

  5. I see your point, but honestly think it is a bit idealistic.

    As far as I can tell, if a developer is missing a feature he will go through significant lengths to get it. If you make it harder for someone to implement, he will come up with a more complex and overall worse implementation, but rarely if ever talk to the developer.

    Even if he does, and I for one do try to give the devs feedback, unless you’re talking about a truely unique project, it will not help him. Take a look at how often existing frameworks are being updated. Take a look at JavaFX, which still can be considered to be new and growing, and at the time between releases. Look at JFreeChart (which, incidentally, gives the user a lot of freedom), or really any other framework in the java world. If I need a solution for a commerical project, the one thing I cannot do is wait for 6 months to maybe receive an update.

    Which leads directly to the many, many abandoned frameworks where the devs started with great ideas and simply ran out of time.

    Finally, and I do agree that this is subjective, when I write code I want others to use, e.g. UI controls, I want them to get the best usability out of it. If a developer is inexperienced and still decides to overwrite methods that are not explicitly meant to be overwritten, chances are he won’t be producing great code anyway. If he is convinced that he knows what he is doing, I prefer to give him the opportunity at his own risk.

  6. Pingback: Pixel Perfect | JavaFX Tip 8: Beauty is Skin Deep

  7. Remember what the guru said: “Classes should be open
    for extension, but closed for
    modification.”

  8. Pingback: e(fx)clipse 1.0 – New Features – Generate JavaFX Properties accessors | Tomsondev Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s