Open Source & Free ❤️

Static Global Context

Static Global Context

Header Image

A developer recently asked me why Display is called Display when it has such a broad purpose?
The reason is historic with roots in Codename One’s origin back in 2007, when we formed the company Chen advocated for a rename of that class and I disagreed. In retrospect I was wrong, the name doesn’t work.

This isn’t something we can easily fix but it’s something we can replace and improve…​

Static Context

When we released Codename One’s first beta almost everything was different but two huge differences matter for this post:

  • We only supported JDK 1.3 era CLDC subset

  • We used XMLVM which didn’t implement static methods very efficiently

Both of these are no longer correct. Under ParparVM static methods perform better than instance methods (as they should) and we always use Java 8 syntax. This means that classes like Display which works as a singleton are at a disadvantage when compared to a class where all the methods are static. In such a class the performance will be faster:

  • We remove the getInstance() call

  • A single static call is faster than an instance method call

But there is another advantage of shorter syntax, e.g. instead of doing something like:

int width = Display.getInstance().getDisplayWidth();

We could (theoretically) do:

int width = Display.getDisplayWidth();

But that’s not all, static methods have the advantage of newer Java static import syntax which allows us to add one import statement:

import static com.codename1.ui.Display.*;

Then write something like:

int width = getDisplayWidth();

Why do it in Display?

Adding something like this into Display doesn’t make sense…​ It would make that class huge and just persist a design mistake from years ago. It’s better to start with a new global context class that will provide us static methods for all the common things we need where it’s common constants or NetworkManager methods etc.

This doesn’t deprecate Display (yet), it provides a better approach for doing the things we do today in Display with the new CN class. It also adds common methods & constants from several other classes so Codename One code will feel more terse e.g. once we do:

import static com.codename1.ui.CN.*;
That’s optional, if you don’t like static imports you can just write CN. for every element

From that point on you can write code that looks like this:

callSerially(() -> runThisOnTheEDT());

Instead of:

Display.getInstance().callSerially(() -> runThisOnTheEDT());

The same applies for most network manager calls e.g.:

addToQueue(myConnectionRequest);

Some things were changed so we won’t have too many conflicts e.g. Log.p or Log.e would have been problematic so we now have:

log("my log message");
log(myException);

Instead of Display.getInstance().getCurrent() we now have getCurrentForm() since getCurrent() is too generic. But for most methods you should just be able to remove the NetworkManager or Display access and it should “just work”.

I ported the Kitchen Sink to use this new convention, to see a sample of how this can cut down on code clutter check of this diff of my commit.

The motivation for this change is three fold:

  • Terse code

  • Small performance gain

  • Cleaner API without some of the baggage in Display or NetworkManager

Both of these classes will probably be around and won’t be deprecated any time soon.

2 Comments

  • Diamond says:

    Great improvement! How about changing CN to CN1 to actually read more like the platform name?…since this is a major class most CN1 developers will be calling to perform some generic tasks.

  • Shai Almog says:

    I actually started with CN1 as I had a similar thought process. After wrestling with it a bit I eventually settled on CN. My reasoning for this is 4 fold:

    1. Not a fan of numbers in class names.
    2. It’s slightly shorter which isn’t much but still…
    3. It’s not about the brand name it’s just a class name and calling it CN keeps it simple
    4. We might change our name under a future rebrand. E.g. on iOS NSString is cemented because of NextStep. I don’t mind having a CN class to mark the history but a CN1 class might be too much.

Leave a Reply