Permanent SideMenu, getAllStyles, Scrollbar & more

Permanent SideMenu, getAllStyles, Scrollbar & more

Header Image

We’ve been so busy recently that changes and features keep piling up with no end…

Permanent Sidemenu

It was always possible to create a permanent side menu but up until now it wasn’t trivial. For Tablets/Desktops
the side menu UI is perfect, but the folding aspect of it isn’t as great. We have more space so we’d like to keep
it open all the time.
Unfortunately, the side menu implementation wasn’t very suited for such usage. With the Toolbar this became
much easier to implement in a generic way. Right now we hardcoded the side menu to the left, fixing it to work
for all sides would requite some effort. But its still pretty neat, just do something like this in your init(Object)
method and your code will implicitly adapt to tablets/desktops if you used the Toolbar API.

// will return true for desktops as well...
if(Display.getInstance().isTablet()) {
    Toolbar.setPermanentSideMenu(true);
}

All Styles

We recommend using the designer and UIID’s for styles but sometimes its just inconvenient or wrong. That’s why
we allow things such as:

myCmp.getUnselectedStyle().setFgColor(0xffffff);

A lot of people misuse getStyle() for this case which returns the current style based on state. Also
with focusable or pressable components (e.g. Button) this becomes a HUGE chore. If I want to disable a border
for a button in all of its states I need to do this:

myButton.getUnselectedStyle().setBorder(null);
myButton.getSelectedStyle().setBorder(null);
myButton.getPressedStyle().setBorder(null);
myButton.getDisabledStyle().setBorder(null);

If I need to set more than one property this becomes a huge pain and I’d want to refactor this into a method that
accepts a Style object etc… Painful!
So to simplify this common use case we finally came up with something simple: getAllStyles().
This new method returns a special “fake” style object that will implicitly call all the above setters in a single go.
Important: the getters for this style return meaningless values and should never be used,
we would have added an exception for them but this would create a performance penalty.
To use this new style for the above use case just do:

myButton.getAllStyles().setBorder(null);

Minor Updates

  • Chen added support for customizing the audio when a push arrives in Android, he posted the details to the
    relevant issue in git.
  • We added a setter to the Picker allowing you to specify a SimpleDateFormat to properly format the displayed date.
  • We added a new utility method to Container that makes the common process of wrapping a Component in a
    Container trivial. E.g.
    Container enclosed = Container.encloseIn(new BorderLayout(), new Button("Up North"), BorderLayout.NORTH);

Creating A Scrollbar in Codename One

Codename One has always been “mobile first” and while we do have a desktop/web port it still feels like
a mobile app even there which is normally fine by us.
In the past some guys asked for scrollbar functionality and we thought it would be a bit tough, but recently
a discussion in the forums
made my aging brain cogs spin a bit and I came up with a really simple way to implement a scrollbar in
Codename One with almost no code!
We might build something like this into Codename One proper if there is demand for it although right now I think
this should be enough for most cases:

private Container makeScrollable(final Component scrollable, Image thumb) {
    scrollable.setScrollVisible(false);
    final Slider scroll = new Slider();
    scroll.setThumbImage(thumb);
    Container sc = new Container(new BorderLayout());
    sc.addComponent(BorderLayout.CENTER, scrollable);
    sc.addComponent(BorderLayout.EAST, scroll);
    scroll.setVertical(true);
    scroll.setMinValue(0);
    scroll.setEditable(true);
    scroll.setMaxValue(scrollable.getScrollDimension().getHeight());
    scroll.setProgress(scroll.getMaxValue());
    final boolean[] lock = new boolean[1];
    scroll.addDataChangedListener(new DataChangedListener() {
        public void dataChanged(int type, int index) {
            if(!lock[0]) {
                lock[0] = true;
                scrollable.scrollRectToVisible(0, scroll.getMaxValue() - index, 5, scrollable.getHeight(), scrollable);
                lock[0] = false;
            }
        }
    });
    scrollable.addScrollListener(new ScrollListener() {
        public void scrollChanged(int scrollX, int scrollY, int oldscrollX, int oldscrollY) {
            if(!lock[0]) {
                lock[0] = true;
                scroll.setProgress(scroll.getMaxValue() - scrollY);
                lock[0] = false;
            }
        }
    });        
    return sc;
}

Coming Soon

I have the last part of the chat app tutorial practically ready. It was delayed waiting for the new push stuff to
come out and then got delayed because of some bugs related to specific usage of the certificate wizard.
I’ll try to get this out next week or the week after that time permitting.

I’ve been working on some apps recently, most specifically I was building an app in my free time for my spouses
Yoga Studio and I’ve been playing with the excellent
Parse cn1lib from Chidiebere Okwudire.
I was pleasantly surprised by how mature and solid it felt!
This has been something I procrastinated on for more than 4 years and I got the whole thing done in 4 days!
The Parse/server storage logic took me less than 24 hours and worked on the first try which is something that
took me by surprise…

We have some other apps mostly built as PoC’s and demos, we are thinking of a way to expose them to
a wider audience probably as a bundle.
At the top of the post you can see some screenshots of a couple of those apps. Ideally we’ll pair this with
a course that would hopefully refresh the now ageing
CodenameOne 101
with something more similar to the
Learn mobile programming by example with Codename One
course.

Update: Since writing this we’ve launched the Codename One Academy. Check it out…

SUBSCRIBE TO OUR MONTHLY NEWSLETTER

TWITTER

OTHER RESOURCES