views:

68

answers:

3

For the sake of this question, let us suppose that I want a row of buttons. I want to put as many buttons in that row as I can fit on the screen, but no more. In other words, as long as a prospective button will not be cut off or have its text shortened, add it.

It seems that I should be able to do something like:

HorizontalFieldManager hfm = new HorizontalFieldManager();

int remainingWidth = Display.getWidth();

int i =0;
while(true) {
    ButtonField bf = new ButtonField("B " + i);
    remainingWidth -= bf.getWidth();
    if(remainingWidth<0)
        break;
    hfm.add(bf);
    i++;
}

add(hfm);

But this doesn't work. bf.getWidth() is always 0. I suspect that this is because the button has not yet been laid out when I query for the width.

So, perhaps I could just make sure the buttons are always the same size. But this won't work for a few reasons:

  1. Different BB platforms have different looks for buttons and text that will fit on a button on a Curve won't fit on a button on a Storm.
  2. 3rd party themes may change the look of buttons, so I can't even count on buttons being a certain size on a certain platform.

Is there no way for me to actually check the remaining space before adding a button? It feels like a fairly useful feature; am I just missing something?

A: 

Try to draw the Manager before adding component to it.

You should probably add the padding too, if the button has one.

public class Main extends UiApplication{

    public static void main(String[] args) {
        Main main = new Main();
        main.enterEventDispatcher();
    }

    public Main() {
        Screen main = new Screen();
        this.pushScreen(main);
        main.init();
    }
}

public class Screen extends MainScreen    {
HorizontalFieldManager hfm;
public Screen() {
    hfm = new HorizontalFieldManager();
    this.add(hfm);
}

public void init() {
    int remainingWidth = Display.getWidth();
    int i = 0;
    while(true) {
        ButtonField bf = new ButtonField("B " + i);
        hfm.add(bf);
        remainingWidth -= bf.getWidth();
        System.out.println(remainingWidth);
        if(remainingWidth <= 0) {
            hfm.delete(bf);
            break;
        }
        i++;
    }
}
Michael B.
@Eric I edited my answer to reflect your correction.
Michael B.
+1  A: 

You're correct that getWidth() returns the width of the field after it's been laid out (that's why it's 0), but getPreferredWidth() will return the value that's given to the Layout Manager, and is probably what you want.

The other problem you have is that you're comparing remainingWidth to 0. If a button's preferred width is, say, 36 pixels, and the remaining width is 20 pixels, you'll draw a button in a spot where you don't have enough room to display it.

Try something like this:

HorizontalFieldManager hfm = new HorizontalFieldManager();
int remainingWidth = Display.getWidth();
for (int i; true; i++ ) {
  ButtonField bf = new ButtonField("B " + i);
  int preferredWidth = bf.getPreferredWidth();
  if ( remainingWidth < preferredWidth )
    break;
  remainingWidth -= preferredWidth;
  hfm.add(bf);
}
add(hfm);
Skrud
getPreferredWidth() seems to return what getContentWidth() would in the ideal case. However, both values are smaller than the space actually consumed by the button. Like getContentWidth(), I think getPreferredWidth() returns the space consumed by the text but not all the padding (and such) of the button.
Eric
You could always extend the button field and override getPreferredWidth(). Then you would have complete control of how the width is declared.
Fostah
A: 
Alex