Fork us on GitHub

Static Global Context

Changing one of the most central parts of Codename One!
Static Global Context

Static Global Context

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.

Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.