Tiny BrowserComponents in layout with BorderLayout.NORTH, WEST, EAST (CENTER inside)

38 views
Skip to first unread message

P5music

unread,
Aug 18, 2020, 3:31:15 AM8/18/20
to CodenameOne Discussions
In my app I have a screen with instructions. It has a special purpose so it has a suitable layout.
There are three text areas, that I can render with SpanLabels or BrowserComponents because I need that the text overflows with scrollbars horizontally.
First I wonder if it is possible with SpanLabels.

Now I have two versions. The one with SpanLabels has the right layout and shows the text correctly but has not horizontal scroll. 

The one with BrowserComponents has three tiny BCs.
I mean, I created a layout this way: mainForm has a BL inside. The BL has three BLs inside NORTH, WEST, EAST. Each of these BLs has a BrowserCommponent inside CENTER with a HTML page inside.
As said I just get tiny BCs, and, in fact, at start I see a different layout, while after I touch it, it shows the three areas, but tiny and ony scrollbars are visible, except for a line of text.
I think it is not just matter of BorderLayout.CENTER, BC has some issues. However maybe I have to change something, because in other part of the app I succeeded in having a full size BC.
Thanks in advance

Shai Almog

unread,
Aug 19, 2020, 2:12:35 AM8/19/20
to CodenameOne Discussions
That won't work since browser component layout is non-deterministic. Only the center will work correctly.
You need to know the approximate size of the layout in advance with browser component. It's an "all or nothing" approach. You can use table layout with height/width constraints for the browser component cells.

P5music

unread,
Aug 19, 2020, 5:10:00 AM8/19/20
to CodenameOne Discussions
Here is what I tried:
main form is BoxLayout.y()
I add a SpanLabel, and it works, the area on top shows the text.
I add a BorderLayout Container to the mainForm, inside this Container I  put a TableLayout Container CENTER, the TL has two BorderLayout containers inside.
In each of these two container I put the BrowserComponents CENTER with constraint 100 height percentage, 50 width, and the TL has this constraint too:
tl.createConstraint().setVerticalSpan(2000);

So, to recap, the BC are CENTER in two BL containers. That are in a TL with those constraints. The TL is CENTER inside a BL. That is added to the mainForm (BL y) after a SpanLabel.
Result: the SpanLabel is displayed entirely, while the two BC are just one line tall.
Thanks in advance

Shai Almog

unread,
Aug 19, 2020, 9:44:47 PM8/19/20
to CodenameOne Discussions
Don't use center constraint in the table layout. It will break everything. Leave it as the default.
Height should never be 100 as all the heights together should come up to 100 (it's in percent).
Don't use span, it makes column calculation hard and spanning 2000 columns is probably not what you're trying to do.

Also make sure you invoked form.setScrollable(false).

P5music

unread,
Aug 20, 2020, 5:07:48 AM8/20/20
to CodenameOne Discussions
You have to see the attached image, that corresponds to the code below: you can see an inverted layout, indeed the instructions text is at the bottom, while it is added NORTH to the form. And what you see at the top is added CENTER. I was trying some changes and stumbled into this. Am I wrong? Is this an issue?

As to my real code, I am not using CENTER constraint in the TL. Just each cell is a BL container with the BC inside, I used this scheme for another layout and it worked.
If you mean that the TL should not be CENTER in a BL, also if I put it in a BoxLayout.y the layout does not work.
100% height is not harmful I think because there is just one row, however I removed it.
the form was set not scrollable.
But still the BC do not take the space.

Here's the code that I talked about. If I am not wrong this could be an issue.
Anyway can you suggest some tweaks using it as a starting point, said that the intended layout is that the two BCs are at the bottom and they are expanded to show full text?
Thanks in advance

private void createForm()
    {
        Command backCommand=new Command("Back") {
            @Override
            public void actionPerformed(ActionEvent evt) {
                parentForm.showBack();
            }
        };

        this.setScrollable(false);
        getToolbar().setBackCommand(backCommand);

        setTitle(formTitle);
        Container mainContainer=new Container();
        
        mainContainer.setLayout(BoxLayout.y());
       
        TableLayout tl=new TableLayout(1,2);
Container tableContainer=new Container();
tableContainer.setLayout(tl);


        Container centerContainerLeft=new Container(new BorderLayout());
        Container centerContainerRight=new Container(new BorderLayout());

        SpanLabel textArea=new SpanLabel();
       
        textArea.setText("Multiline text\nMultiline text\nMultiline text\nMultiline text\n");
add(BorderLayout.NORTH,textArea);


        BrowserComponent textAreaLeft=new BrowserComponent();
       
        textAreaLeft.setPage("<HTML><BODY><DIV style='overflow-x:scroll;'>"+"Multiline Text</BR>Multiline Text</BR>Multiline Text</BR>Multiline Text</BR></DIV><BODY></HTML>","");
centerContainerLeft.add(BorderLayout.CENTER,textAreaLeft);

        BrowserComponent textAreaRight=new BrowserComponent();
       
        textAreaRight.setPage("<HTML><BODY><DIV style='overflow-x:scroll;'>"+"Multiline Text</BR>Multiline Text</BR>Multiline Text</BR>Multiline Text</BR></DIV><BODY></HTML>","");
       
        centerContainerRight.add(BorderLayout.CENTER,textAreaRight);

tableContainer.add(tl.createConstraint().widthPercentage(50),centerContainerLeft).
        add(tl.createConstraint().widthPercentage(50),centerContainerRight);
mainContainer.add(tableContainer);
add(BorderLayout.CENTER,mainContainer); //same if I add tl directly
    }
2020-08-20 10-46-52.png

Shai Almog

unread,
Aug 21, 2020, 12:44:38 AM8/21/20
to CodenameOne Discussions
You can nest a border layout in a table cell although I'm not sure what the benefit would be but this is OK.

You lost me a bit with all the level of nesting all over the place, reading the code I have no idea how it should look by now and since everything is conveniently named "Multiline text" my brain is stack overflowing..

I suggest opening this in Component Inspector and looking at the sizes of each component in the hierarchy. Where they were placed and why.

P5music

unread,
Aug 21, 2020, 4:23:10 AM8/21/20
to CodenameOne Discussions
I use BL surrounding a BC because I think I have understood that it "encourages" the BC to spread. And other BLs are surrounding. 
It is a trial/error method but now I am stuck. 
I wanted to show you a possible issue: indeed the layout is inverted, what is CENTER is at the top and what is NORTH is at the bottom. This could be of interest in general if a bug is discovered.
Back to my layout, text is not important, the BC do not spread, this is the problem. If you will test the code, you can also remove something redundant, or tweak it, so I have the solution, otherwise it is a bug, this is of interest for you anyway, I think, solving this would shed light on the subject..
Thanks in advance

Shai Almog

unread,
Aug 22, 2020, 1:16:42 AM8/22/20
to CodenameOne Discussions
You don't need the border layout. This is only a tip for the simple usage in a form.
Using the same strings make it hard for me to read the code and screenshot without trying it.

If you think there's a bug you can file an issue. Unfortunately you probably understand we have a deep issue pipeline and it takes us a long while to evaluate everything.

P5music

unread,
Aug 22, 2020, 4:10:27 AM8/22/20
to CodenameOne Discussions
If the BrowserComponent itself (rendering, updating, Javascript) would not have issues on the real iOS app (native build) like they exist on the simulator, I wonder whether also these layout  issues are automatically happening on the real iOS app.
Unfortunately iOS builds are "costly" in terms of credits, I cannot use them to test the layout and the BrowserComponent. Furthermore Chrome mirroring for debugging does not work, I see a blank screen.

Shai Almog

unread,
Aug 22, 2020, 10:54:01 PM8/22/20
to CodenameOne Discussions
You can't rely on that. The layout code is very cross platform since it's 100% Java. The things that behave differently are native e.g. the browser.
In this case I'm pretty sure the layout will misbehave. You need to create 100% deterministic layout with no scrolling for the browser component. That means the layout manager will know the size and won't need the value of getPreferredSize().

P5music

unread,
Aug 23, 2020, 6:27:04 AM8/23/20
to CodenameOne Discussions
I realized that the default form layout is FlowLayout and not BorderLayout (I do not where I read that) so it is not a bug, although I would expect an error or warning when using BorderLayout constraints in the add() call. 
Said that it is not possible to use a TableLayout to split the screen 50/50 with two BrowserComponents, whatever I try. I do not know if that's a bug.
I only succeded in creating a similar layout just adding the BC CENTER and WEST, but they are not 50/50, one is smaller. 
Take into account that in the two BCs there is multiline text with overflow:scroll and white-spaces:nowrap so you just imagine that scrollbars allow to see what's not visible horizontally for example, so,the BCs have taken all available space and share it with some ratio like 70/30.
Is there any constraint to correct this?

Shai Almog

unread,
Aug 23, 2020, 9:53:38 PM8/23/20
to CodenameOne Discussions
You need to use Component inspector to look at hierarchies, it shows the layout and would have made this easier to spot.
You shouldn't use non-center border layout for browser component.

If you place TableLayout on the form itself. Disable scrolling and add both rows with height set to 50 (and no other constraints) you'd get a perfectly split 50/50 layout.

P5music

unread,
Aug 24, 2020, 5:54:50 AM8/24/20
to CodenameOne Discussions
I will have a look at the Component Inspector.
But you seem very confident about the TL-BC behaviour, so I think it's me that cannot guess the right constraint to the TL.
Please give me two lines of code where you create a working 50/50 TL layour with two BCs that expand vertically.
1 row and 2 columns, each BC has to take all the available vertical space.
Thanks in advance

Shai Almog

unread,
Aug 24, 2020, 11:46:53 PM8/24/20
to CodenameOne Discussions
TableLayout tl = TableLayout(2, 1);
myForm.setLayout(tl);
myForm.setScrollable(false);
myForm.add(tl.cc().hp(50), bc1);
myForm.add(tl.cc().hp(50), bc2);

P5music

unread,
Aug 25, 2020, 4:51:55 AM8/25/20
to CodenameOne Discussions
As I said, my layout needs a TableLayout with 1 row and 2 columns (not 2 rows and 1 column), so I changed your code:
 BrowserComponent textAreaLeft=new BrowserComponent();
       textAreaLeft.setPage("<HTML><BODY><DIV style='overflow:scroll;white-space:nowrap;'>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR></DIV><BODY></HTML>","");

        BrowserComponent textAreaRight=new BrowserComponent();
        textAreaRight.setPage("<HTML><BODY><DIV style='overflow:scroll;white-space:nowrap;'>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR>MULTILINE TEXT</BR></DIV><BODY></HTML>","");


        TableLayout tl = new TableLayout(1, 2);
        setLayout(tl);
        setScrollable(false);
        add(tl.cc().hp(50), textAreaLeft);
        add(tl.cc().hp(50), textAreaRight);

and you can see the result in the attached image, where two vertical BCs are one beside the other horizontally, but they are both in the left area of the screen, while I want that they occupy half screen each horizontally. Note that they are vertically spread as I need.
Clearly hp(50) has to be changed to wp(50), so I try it:

        TableLayout tl = new TableLayout(1, 2);
        setLayout(tl);
        setScrollable(false);
        add(tl.cc().wp(50), textAreaLeft);
        add(tl.cc().wp(50), textAreaRight);

and the result is what you can see in the other image, where two BCs share 50/50 the screen horizontally but they are not spread vertically.
So the problem is that the BC do not spread vertically when in a TL with 1 row and 2 columns and wp=50
Thanks
2020-08-25 10-44-18.png
2020-08-25 10-41-02.png

Shai Almog

unread,
Aug 26, 2020, 2:54:39 AM8/26/20
to CodenameOne Discussions
Is this a subclass of form?
Actually my code was wrong. You should do:


add(tl.cc().hp(100).wp(50), textAreaLeft);
 add(tl.cc().hp(100).wp(50), textAreaRight);

P5music

unread,
Aug 26, 2020, 5:00:10 AM8/26/20
to CodenameOne Discussions
Yes it is a separate class that extends Form.
Now I see that your code works, but only when a TL is added to the form. Indeed I cannot have a text area at the top, and then the TL. This is somewhat acceptable for my app, or I can use the 70/30 layout with BL. I have to present the instructions elsewhere.

So I think TL does not work with Containers, it just works with Forms. I do not know if it is by design.
I tried also to add a Form to the Form, so the TL is in a Form that is in a Form, but the result is the same of BC not spread vertically.
I do not know if this trick could work with different constraints that you can devise and provide a workaround.
Thanks

Shai Almog

unread,
Aug 26, 2020, 10:23:57 PM8/26/20
to CodenameOne Discussions
It works fine with containers.
It doesn't work this way for non-deterministic hierarchy.

So if you place the table layout in the CENTER of a border layout and place a simple label in the north of the border layout it will work too.

Where it will fail is if you will place a scrollable in the hierarchy or a container that isn't deterministic and grabs the view. It will fail if you don't give it width/height constraints.

P5music

unread,
Aug 27, 2020, 4:47:13 AM8/27/20
to CodenameOne Discussions
As I said using the BorderLayout CENTER does not work in any combination with the TL and BCs.
Please if you know the solution, please give me the constraints so to have a Label at the top and then the TL with BCs  below (50/50 horizontally, spread vertically).
Thanks in advance

Shai Almog

unread,
Aug 28, 2020, 12:54:56 AM8/28/20
to CodenameOne Discussions
It does work 100% sure. I don't even need setScrollable(false) for this case:

Form myForm = new Form("Title", new BorderLayout());

TableLayout tl = TableLayout(2, 1);
Container table = new Containter(tl);
myForm.add(CENTER, table);
myForm.add(NORTH, new Label("My Label"));
add(tl.cc().hp(100).wp(50), textAreaLeft);
 add(tl.cc().hp(100).wp(50), textAreaRight);

P5music

unread,
Aug 28, 2020, 4:28:15 AM8/28/20
to CodenameOne Discussions
I guessed that the last two instructions are indeed:
table.add(tl.cc().hp(100).wp(50), textAreaLeft);
table. add(tl.cc().hp(100).wp(50), textAreaRight);
and that myForm is my Form.
It works now. Thank you,
Regards

Reply all
Reply to author
Forward
0 new messages