Open Source & Free  

Bottom Align

Bottom Align

Header Image

Box layout Y is one of the most used layouts in Codename One. It’s a wonderful, easy to use layout that makes vertical scrollable layout trivial. I love its simplicity, but sometimes that simplicity goes too far. A good example of that is the a common layout where we have a button at the bottom of the screen.

Historically we solved this by nesting box into a border layout:

Form f = new Form("Border Layout", new BorderLayout()); (1)

Container box = new Container(BoxLayout.y());
box.setScrollableY(true); (2)

Button b = new Button("Add New Button");

b.addActionListener(e -> {
    MultiButton mb = new MultiButton("Added Button");
    box.addComponent(0, mb);
    mb.setWidth(f.getWidth());
    mb.setY(f.getHeight());
    box.animateLayout(150);
});

f.add(SOUTH, b);
f.add(CENTER, box);

f.show();
1 Border layout implicitly disables the default scrolling of the Form
2 Because of that we need to scroll the box layout

When launched the UI looks like this:

Newly launched UI
Figure 1. Newly launched UI
After adding a couple of elements it looks like this
Figure 2. After adding a couple of elements it looks like this
After adding a lot of elements it looks like this
Figure 3. After adding a lot of elements it looks like this

Now this might be what you want. The add button is always clearly visible and easily accessible. However, in some cases this doesn’t work.

Lets say you want this exact behavior like we see in the first two images. But once we reach the edge of the form you want the button to act as if this was a regular box layout. Effectively the button would either align to the bottom of the form or the edge of the layout.

To accomplish this we are adding a new yLast mode in the BoxLayout which can be created using BoxLayout.yLast() or new BoxLayout(BoxLayout.Y_AXIS_BOTTOM_LAST). E.g the code below will produce the exact same result for the first two images:

Form f = new Form("Border Layout", BoxLayout.yLast()); (1)
Button b = new Button("Add New Button");
b.addActionListener(e -> {
    MultiButton mb = new MultiButton("Added Button");
    f.addComponent(0, mb);
    mb.setWidth(f.getWidth());
    mb.setY(f.getHeight());
    f.getContentPane().animateLayout(150);
});

f.add(b);

f.show();
1 Box layout doesn’t disable the default scrollability of form

When it’s completely filled the button is pushed down out of the view area:

The button scrolls down when there is no more space
Figure 4. The button scrolls down when there is no more space

I like this approach as it reduces clutter for the UI and leaves more space available. It doesn’t fit for all cases but it’s a valuable addition to the API. These changes will be available with the update we’ll release this Friday.

6 Comments

  • Francesco Galgani says:

    Why did you use f.addComponent(0, mb);?

  • Shai Almog says:

    This adds the component to the first index in the component list. When I call add(Component) or addComponent(Component) it adds the component at the last offset which in this case will replace the existing “last component”. Here I added it to the top so a new entry will always appear first.

  • Francesco Galgani says:

    So in your example all the MultiButtons are disposed in inverted order of insertion, right? And if we want that every new MultiButton is added as penultimate?

  • Shai Almog says:

    No buttons are disposed but the new button is added to the top of the list instead of the bottom. That way the last button is always the add button.

  • Francesco Galgani says:

    Thank you for the quick reply. I’m sorry, my mistake: “disposed” is a false friend in my language, I wrote a thing thinking another. I understood your first reply. My question, in your example, is how to place the new added multibuttons to the bottom of list instead to the top. I mean if it’s possible something like: addComponent(n-2), where n is the number of added components to the container (plus the one we are going to add), n-1 is the Button always in the bottom, n-2 is the place to add a new multibutton. I guess that it’s not possible in this way.

  • Shai Almog says:

    It’s possible to call it that way. I just wanted to keep the code a bit simpler without a “weird” – offset calculation. I think it would be “cmpCount -1” but it might be “cmpCount -2” I don’t recall.

Leave a Reply