Shikhar13 / codenameone

Automatically exported from code.google.com/p/codenameone
0 stars 0 forks source link

CellRenderer returning variable sized components are not correctly displayed for ContainerList #317

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
On simulator. 

In the below example, select the line with "test1", then push [Show]. This will 
make the CellRenderer return a container with two lines for the focused list 
element ("test1"). The two lines are displayed correctly immediately after 
pushing [Show]. 

However, if you then select the other element "test2" in the list, the size of 
the displayed elements are not correctly displayed: an empty line is shown 
after "test1" and the "optional line" is *not* shown for "test2". 

I haven't been able to debug the example to find the cause, but as discussed in 
the forum in the thread "ContainerList seems to alter the layout and style of 
rendered components", it should work. 

It seems that somehow the size of the resized entry is not correctly 
re-calculated, although setShouldCalcPreferredSize(true) is called. 

What steps will reproduce the problem?
1. Compile and run below example, select the line "test1"
2. Press command [Show]. Now "optional line" is shown after "test1"
3. Select "test2"

What is the expected output? What do you see instead?
After "test2" the "optional line" should be displayed. Instead an empty line is 
shown after "test1" and nothing is displayed after "test2". 

What version of the product are you using? On what operating system?

Please provide any additional information below.

//bug with CellRenderer not rendering two line items
final Container variabelSizeContainer = new Container(new 
BoxLayout(BoxLayout.Y_AXIS));
final Label fixedLabel = new Label();
final Label optionalLabel = new Label("optional line");
variabelSizeContainer.addComponent(fixedLabel);
final ContainerList containList = new ContainerList(new DefaultListModel(new 
String[]{"test1", "test2"}));
CellRenderer cellRenderer = new CellRenderer() {
    public Component getCellRendererComponent(Component list, Object model, Object value, int index, boolean isSelected) {
        ContainerList containList = (ContainerList) list;
        fixedLabel.setText((String) value);
        variabelSizeContainer.setFocus(isSelected);
        if (isSelected) {
            if (showLine) {
                if (!variabelSizeContainer.contains(optionalLabel)) {
                    variabelSizeContainer.addComponent(optionalLabel); //add the second optional line to the container returned by the renderer
                    containList.getComponentAt(index).setShouldCalcPreferredSize(true); //this sets shouldCalc... for the Entry in the ContainerList, which should retrigger a layout - but doesn't
                }
            }
        } else {
            if (variabelSizeContainer.contains(optionalLabel)) {
                variabelSizeContainer.removeComponent(optionalLabel); //remove the second optional line from the container returned by the renderer
                    containList.getComponentAt(index).setShouldCalcPreferredSize(true); //this sets shouldCalc... for the Entry in the ContainerList, which should retrigger a layout - but doesn't
            }
        }
        return variabelSizeContainer;
    }

    public Component getFocusComponent(Component list) {
        Label label = new Label();
        label.getStyle().setFgColor(0x333333);
        return label;
    }
};
containList.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
containList.setRenderer(cellRenderer);
Command show2LinesForSelectedEntry = new Command("Show") {
    public void actionPerformed(ActionEvent evt) {
        super.actionPerformed(evt);
        showLine = !showLine; //turn showing two lines on and off
    }
};
Dialog dialog = new Dialog("test");
dialog.setAutoDispose(false);
dialog.addComponent(containList);
dialog.addCommand(new Command("OK"));
dialog.addCommand(show2LinesForSelectedEntry);
dialog.show();

Original issue reported on code.google.com by ch.hj...@gmail.com on 5 Sep 2012 at 8:24

GoogleCodeExporter commented 9 years ago
If you resize the elements in runtime you need to revalidate or animate we 
don't retest size changes due to the major performance overhead of seamlessly 
reflowing the UI.

Original comment by shai.almog on 6 Sep 2012 at 4:43

GoogleCodeExporter commented 9 years ago
But isn't the purpose of setShouldCalcPreferredSize(true) exactly to signal 
that the size of an element has changed and its size should be recalculated? 

The documentation for setShouldCalcPreferredSize says "Indicates the values 
within the component have changed and preferred size should be recalculated", 
and that's also what I understood from your answer on the forum thread 
mentioned above.

Original comment by ch.hj...@gmail.com on 6 Sep 2012 at 5:39

GoogleCodeExporter commented 9 years ago
It signals that but it doesn't trigger the actual layout. E.g. 20 components 
changed in different layouts. setShouldCalcPreferredSize would be invoked for 
all of them but validate() can be invoked only once.

Original comment by shai.almog on 6 Sep 2012 at 7:15

GoogleCodeExporter commented 9 years ago
OK, I think I've spend far too much time trying to figure this out myself. 
Basically, what I'm trying to achieve is the List fisheye effect, but with 
variable size list elements as ContainerList allows. Something I believe iOS 
and Android supports. I'll ask the question in the forum. 

Original comment by ch.hj...@gmail.com on 7 Sep 2012 at 5:10

GoogleCodeExporter commented 9 years ago
We explicitly supported fisheye for list but never tested it in ContainerList, 
I think it needs explicit support. I'll convert this to an RFE and assign it to 
Chen who might have some input here since he worked allot with the fisheye in 
the list class.

Original comment by shai.almog on 7 Sep 2012 at 5:20