0

When adding a component to a form, I want the form to scroll down to make that newly added component visible.

I assumed that .scrollComponentToVisible() was used for this, but I does not work for me.

If you run the sample code I provided bellow, you will notice that the component is added correctly and gets focus. However, it is still outside of the visible area of the screen.

Pay attention to the row:

form.scrollComponentToVisible(cont4);

I guess this line is wrong? What should I use instead?

import javax.microedition.midlet.*;

import com.sun.lwuit.*;
import com.sun.lwuit.events.*;

public class ScrollTest extends MIDlet {

public void startApp() {

    Display.init(this);

    final Form form = new Form();
    form.getStyle().setBgColor(0xff0000);

    String text = "aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa" +
                "aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa";

    Container cont = new Container();
    cont.setFocusable(true);
    cont.getUnselectedStyle().setBgTransparency(0);
    cont.getSelectedStyle().setBgTransparency(100);
    TextArea area = new TextArea(text);
    area.setEditable(false);
    area.setFocusable(false);
    area.getUnselectedStyle().setBgTransparency(0);
    cont.addComponent(area);
    form.addComponent(cont);

    Container cont2 = new Container();
    cont2.setFocusable(true);
    cont2.getUnselectedStyle().setBgTransparency(0);
    cont2.getSelectedStyle().setBgTransparency(100);
    TextArea area2 = new TextArea(text);
    area2.setEditable(false);
    area2.setFocusable(false);
    area2.getUnselectedStyle().setBgTransparency(0);
    cont2.addComponent(area2);
    form.addComponent(cont2);

    Container cont3 = new Container();
    cont3.setFocusable(true);
    cont3.getUnselectedStyle().setBgTransparency(0);
    cont3.getSelectedStyle().setBgTransparency(100);
    TextArea area3 = new TextArea(text);
    area3.setEditable(false);
    area3.setFocusable(false);
    area3.getUnselectedStyle().setBgTransparency(0);
    cont3.addComponent(area3);
    form.addComponent(cont3);

    Command add = new Command("Add");
    form.addCommand(add);

    form.addCommandListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            Container cont4 = new Container();
            cont4.setFocusable(true);
            cont4.getSelectedStyle().setBgColor(0xff0000);
            TextArea area4 = new TextArea("This should get focus and be visible when added");
            area4.setEditable(false);
            area4.setFocusable(false);
            cont4.getUnselectedStyle().setBgTransparency(0);
            cont4.getSelectedStyle().setBgTransparency(100);
            cont4.addComponent(area4);
            form.addComponent(cont4);
            form.repaint();

            cont4.requestFocus();
            form.scrollComponentToVisible(cont4);

        }
    });

    form.show();
}

public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void actionPerformed(ActionEvent ae) {
    notifyDestroyed();
}
}
Harshal Patil
  • 6,659
  • 8
  • 41
  • 57
Daniele Testa
  • 1,538
  • 3
  • 16
  • 34

1 Answers1

0

if the container you want to add on every click is same, you could use a List and custom list cell renderer like in the below sample code.

list's setScrollToSelected can be used for focus and scrolling to last added item.

public class ScrollTest extends MIDlet {

private List myList;
private ListModel mListModel;
private int i = 0;

public void startApp() {
    Display.init(this);

    Form form = new Form();
    form.setLayout(new BorderLayout());
    form.setScrollableY(false);
    form.getStyle().setBgColor(0xff0000);

    myList = new List();
    CustomListRenderer mRenderer = new CustomListRenderer();
    myList.setListCellRenderer(mRenderer);
    mListModel = new DefaultListModel();
    myList.setModel(mListModel);
    myList.setFixedSelection(List.FIXED_NONE_ONE_ELEMENT_MARGIN_FROM_EDGE);
    myList.setSmoothScrolling(true);
    myList.setScrollToSelected(true);
    form.addComponent(BorderLayout.CENTER, myList);

    Command add = new Command("Add");
    form.addCommand(add);

    form.addCommandListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            mListModel.addItem(" Item #" + (i++));
            myList.setSelectedIndex(mListModel.getSize() - 1);
            myList.setScrollToSelected(true);
        }
    });

    form.show();
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

private class CustomListRenderer extends Container implements
        ListCellRenderer {
    TextArea area;
    Label focus = new Label();

    public CustomListRenderer() {
        this.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
        area = new TextArea();
        area.setEditable(false);
        area.setFocusable(false);
        this.addComponent(area);
        this.getStyle().setBgColor(0xff0000);
        this.getSelectedStyle().setBgColor(0xff6600);
    }

    public Component getListCellRendererComponent(List list, Object value,
            int index, boolean isSelected) {
        area.setText(value.toString());
        return this;
    }

    public Component getListFocusComponent(List arg0) {
        focus.getStyle().setBgColor(0xff6600);
        return focus;
    }
}
}
SKK
  • 5,261
  • 3
  • 27
  • 39
  • I can't use a list as the components I am adding demands variable heights. Also, ContainerList does not support "setScrollToSelected". However, I solved it by putting the "repaint" and "requestFocus" in "invoideAndWait". That solved the issue. I guess the component had to be printed to the screen before "requestFocus" can be applied to it. – Daniele Testa May 02 '14 at 19:38