bizarre result with tablelayout

33 views
Skip to first unread message

howud...@gmail.com

unread,
Jul 24, 2016, 7:49:56 PM7/24/16
to CodenameOne Discussions
I'm not sure why but verticalSpan isn't quite being respected.  Here is a simple test case:
     this.setLayout(new BorderLayout());
  
    TableLayout layout = new TableLayout(5,3);

    Container cnt2 = new Container();
    cnt2.getStyle().setBgColor(0xd3d3d3);
    cnt2.getStyle().setBgTransparency(255);
    cnt2.add(new Label("Activity:"));

        Container cnt1 = new Container(layout);
        cnt1.add(layout.createConstraint().widthPercentage(20), new Label());
        cnt1.add(layout.createConstraint().widthPercentage(40), new Label());
        cnt1.add(layout.createConstraint().widthPercentage(40), new Label());
    cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Last:"));
    cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());
    cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());

    cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("First:"));
    cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());
    cnt1.add(layout.createConstraint().horizontalSpan(1).verticalSpan(4), cnt2);

    cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Age:"));
    cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());

    cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Height:"));
    cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());

    cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Weight:"));
    cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());
    cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());   <-----NOTE: this empty field had to be added to align

    cnt1.add(layout.createConstraint().horizontalSpan(3), new Label("Some Really Long Text that represents a button panel that should span"));
this.add(BorderLayout.CENTER, cnt1);


I had to intersperse the controls with empty labels in order for the alignment to work.  In this test case, I used a TextField instead.  In the screenshot you can see the last label "Some really long text..." is actually showing up in the last row right column, instead of showing up in the next row, as it does in the 2nd screenshot when I add an empty label (or TextField).   The panel labelled "Activity" has a verticalSpan of 4, and you can see the grey color respecting that, but the label (or textfield) is not.   

howud...@gmail.com

unread,
Jul 24, 2016, 7:52:35 PM7/24/16
to CodenameOne Discussions, howud...@gmail.com
oops forgot to add the screenshot


Shai Almog

unread,
Jul 25, 2016, 12:00:06 AM7/25/16
to CodenameOne Discussions, howud...@gmail.com

This is what I got when I ran something similar:

The sample is overly complex so it's kind of hard to see what goes wrong or if something goes wrong and it seems to be working fine. I suggest reducing this to as small a test case as possible and using something I can just paste into a standard barebones hello world.

        TableLayout layout = new TableLayout(5,3);

       
Form f = new Form("Table", layout);  

        f
.add(layout.createConstraint().widthPercentage(20), new Label());
        f
.add(layout.createConstraint().widthPercentage(40), new Label());
        f
.add(layout.createConstraint().widthPercentage(40), new Label());
        f
.add(layout.createConstraint().horizontalSpan(1), new Label("Last:"));
        f
.add(layout.createConstraint().horizontalSpan(1), new TextField());
        f
.add(layout.createConstraint().horizontalSpan(1), new TextField());

        f
.add(layout.createConstraint().horizontalSpan(1), new Label("First:"));
        f
.add(layout.createConstraint().horizontalSpan(1), new TextField());
        f
.add(layout.createConstraint().horizontalSpan(1).verticalSpan(4),new SpanLabel("Long text\nThat should\nBreak lines\nIn spanning..."));

        f
.add(layout.createConstraint().horizontalSpan(1), new Label("Age:"));
        f
.add(layout.createConstraint().horizontalSpan(1), new TextField());

        f
.add(layout.createConstraint().horizontalSpan(1), new Label("Height:"));
        f
.add(layout.createConstraint().horizontalSpan(1), new TextField());

        f
.add(layout.createConstraint().horizontalSpan(1), new Label("Weight:"));
        f
.add(layout.createConstraint().horizontalSpan(1), new TextField());
        f
.add(layout.createConstraint().horizontalSpan(1), new TextField());

        f
.add(layout.createConstraint().horizontalSpan(3), new Label("Some Really Long Text that represents a button panel that should span"));

        f
.show();                        



howud...@gmail.com

unread,
Jul 25, 2016, 12:33:35 AM7/25/16
to CodenameOne Discussions, howud...@gmail.com
comment out the adding of the last text field.  The the container should span 4 rows, and the text field should NOT be overlayed on top of the container that spans 4 rows.  The sample really isn't that complex.

howud...@gmail.com

unread,
Jul 25, 2016, 11:16:08 AM7/25/16
to CodenameOne Discussions, howud...@gmail.com
You can see the problem in your sample, why is there  a textfield laying on top of your vertically spanned container?


On Sunday, July 24, 2016 at 9:00:06 PM UTC-7, Shai Almog wrote:

howud...@gmail.com

unread,
Jul 25, 2016, 11:20:07 AM7/25/16
to CodenameOne Discussions, howud...@gmail.com
And the problems keep getting weirder.  Now the 4th column is disappearing.  Here is a complete test app you can copy / paste.  Click on test1 and you see all 4 columns, click on test2 and the 4th column disappears.  The difference is a textfield is in test2
public class FrmMain extends Form {
    public FrmMain() {
        initManualComponents();
    }
    
    protected void initManualComponents() {
    this.setLayout(new BorderLayout());
    Button btn = new Button("Test");
    btn.addActionListener(evt -> onClick());
    this.add(BorderLayout.NORTH, btn);

    Button btn2 = new Button("Test2");
    btn2.addActionListener(evt -> onClick2());
    this.add(BorderLayout.SOUTH, btn2);

    }
    
    protected void onClick() {
    new MyDlg().show();
    }
    protected void onClick2() {
    new MyDlg2().show();
    }
    class MyDlg extends Dialog {
    protected Button btnClose = new Button(FontImage.createMaterial(FontImage.MATERIAL_CLEAR, UIManager.getInstance().getComponentStyle("TitleCommand")));
    public MyDlg() {
            initManualComponents();
        }
        
        protected void initManualComponents() {
        this.setLayout(new BorderLayout());
        this.getDialogStyle().setBgColor(0xFF0000);
        this.getStyle().setBgColor(0xFF0000);
        this.getContentPane().getStyle().setBgColor(0xFF0000);
        btnClose.addActionListener(evt -> dispose());

        TableLayout layout = new TableLayout(10,4);
            Container cnt1 = new Container(layout);
            cnt1.add(layout.createConstraint().horizontalSpan(4).horizontalAlign(Component.RIGHT), btnClose);
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("A"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("B"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("C"));
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("D"));

            cnt1. add(layout.createConstraint().horizontalSpan(2), new Label("Span 2"));
            cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("A"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));

        cnt1.add(layout.createConstraint().horizontalSpan(3), new Label("Span 3"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));
       
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label(""));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Span 1"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Span 1"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));

    this.add(BorderLayout.CENTER, cnt1);
        }
    }
    class MyDlg2 extends Dialog {
    protected Button btnClose = new Button(FontImage.createMaterial(FontImage.MATERIAL_CLEAR, UIManager.getInstance().getComponentStyle("TitleCommand")));
    public MyDlg2() {
            initManualComponents();
        }
        
        protected void initManualComponents() {
        this.setLayout(new BorderLayout());
        this.getDialogStyle().setBgColor(0xFF0000);
        this.getStyle().setBgColor(0xFF0000);
        this.getContentPane().getStyle().setBgColor(0xFF0000);
        btnClose.addActionListener(evt -> dispose());

        TableLayout layout = new TableLayout(10,4);
            Container cnt1 = new Container(layout);
            cnt1.add(layout.createConstraint().horizontalSpan(4).horizontalAlign(Component.RIGHT), btnClose);
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("A"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("B"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("C"));
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("D"));

            cnt1. add(layout.createConstraint().horizontalSpan(2), new Label("Span 2"));
            cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("A"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));

        cnt1.add(layout.createConstraint().horizontalSpan(3), new Label("Span 3"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));
       
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label(""));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Span 1"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Span 1"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));

        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label(""));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Span 1"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));
    this.add(BorderLayout.CENTER, cnt1);
        }
    }
}

And the results of clicking test1 and test2:


Shai Almog

unread,
Jul 26, 2016, 12:02:44 AM7/26/16
to CodenameOne Discussions, howud...@gmail.com
This is a complex problem to debug and the code requires an understanding of what you are trying to achieve. Try reproducing it with the smallest possible table and just buttons then file an issue with something like that.

We are entering the 3.5 codefreeze and have a lot of issues after that so I'm not sure when I'll be able to dig into that more closely.

howud...@gmail.com

unread,
Jul 26, 2016, 1:33:52 AM7/26/16
to CodenameOne Discussions, howud...@gmail.com
here is the smallest possible I could get to reproduce the problem.  There is only a one line difference between the two dialogs.  It is that one line that causes MyDlg2 to break.
test1 (MyDlg) the X is chopped off on the right
test2 (MyDlg2) the 4th column is completely gone.

public class FrmMain extends com.codename1.ui.Form {
    public FrmMain() {
        this(com.codename1.ui.util.Resources.getGlobalResources());
    }
    
    public FrmMain(com.codename1.ui.util.Resources resourceObjectInstance) {
        initManualComponents();
    }
    protected void initManualComponents() {
    this.setLayout(new BorderLayout());
    Button btn = new Button("Test");
    btn.addActionListener(evt -> onClick());
    this.add(BorderLayout.NORTH, btn);

    Button btn2 = new Button("Test2");
    btn2.addActionListener(evt -> onClick2());
    this.add(BorderLayout.SOUTH, btn2);
    }
    
    protected void onClick() {
    new MyDlg().show();
    }
    protected void onClick2() {
    new MyDlg2().show();
    }
    class MyDlg extends Dialog {
    protected Button btnClose = new Button(FontImage.createMaterial(FontImage.MATERIAL_CLEAR, UIManager.getInstance().getComponentStyle("TitleCommand")));
    public MyDlg() {
            initManualComponents();
        }
        
        protected void initManualComponents() {
        this.setLayout(new BorderLayout());
        btnClose.addActionListener(evt -> dispose());

        TableLayout layout = new TableLayout(10,4);
            Container cnt1 = new Container(layout);
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("A"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("B"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("C"));
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("D"));
            cnt1.add(layout.createConstraint().horizontalSpan(4).horizontalAlign(Component.RIGHT), btnClose);

            cnt1.add(layout.createConstraint().horizontalSpan(1), new Label(""));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Span 1"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Textfield"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));

    this.add(BorderLayout.CENTER, cnt1);
        }
    }
    class MyDlg2 extends Dialog {
    protected Button btnClose = new Button(FontImage.createMaterial(FontImage.MATERIAL_CLEAR, UIManager.getInstance().getComponentStyle("TitleCommand")));
    public MyDlg2() {
            initManualComponents();
        }
        
        protected void initManualComponents() {
        this.setLayout(new BorderLayout());
        btnClose.addActionListener(evt -> dispose());

        TableLayout layout = new TableLayout(10,4);
            Container cnt1 = new Container(layout);
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("A"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("B"));
            cnt1.add(layout.createConstraint().widthPercentage(35), new Label("C"));
            cnt1.add(layout.createConstraint().widthPercentage(15), new Label("D"));
            cnt1.add(layout.createConstraint().horizontalSpan(4).horizontalAlign(Component.RIGHT), btnClose);

        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label(""));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("Span 1"));
        cnt1.add(layout.createConstraint().horizontalSpan(1), new TextField());
        cnt1.add(layout.createConstraint().horizontalSpan(1), new Label("X"));
    this.add(BorderLayout.CENTER, cnt1);
        }
    }
}



Peter

howud...@gmail.com

unread,
Jul 26, 2016, 9:44:58 AM7/26/16
to CodenameOne Discussions, howud...@gmail.com
some further troubleshooting shows that the problem is the size of the textfield.  it is so big that it is squeezing the other columns out.  The dialog width calculations are not correct.  I have manually set the width of the columns and at least now the 4th column shows by calling:
d.show(0, 0, Display.getInstance().getDisplayWidth()/2, 0);



On Monday, July 25, 2016 at 9:02:44 PM UTC-7, Shai Almog wrote:

Shai Almog

unread,
Jul 26, 2016, 11:59:56 PM7/26/16
to CodenameOne Discussions, howud...@gmail.com
So the problem is with the layout or the transparency?
I don't understand.

Either way I suggest not using complex dialogs like that. This is a recipe for disaster as Dialogs have very elaborate behaviors and don't handle "growing" and other complexities very well.

howud...@gmail.com

unread,
Jul 27, 2016, 12:35:09 AM7/27/16
to CodenameOne Discussions, howud...@gmail.com
hmmm...I dont think I asked anything about transparency (that's another thread).  The problem is simple.  the textfield default width is so large that it squeezes out the 4th column in the table.
As to the complexity...the dialog is a way to input several parameters that become a filter for a query that then populates a list.  If there is a better way to do it than a dialog, please tell me.

Peter

Shai Almog

unread,
Jul 28, 2016, 12:47:53 AM7/28/16
to CodenameOne Discussions, howud...@gmail.com
I would suggest using Forms.
Dialogs determine their size based on preferred size and have a hard time growing. You can force a dialog to grow after it is shown but it's not as convenient as just using a form.
Reply all
Reply to author
Forward
0 new messages