user1618533
user1618533

Reputation: 76

Strange things happen when set margin to VerticalFieldManager

I'd like to generate a VerticalFieldManager that has a none-zero margin, so I create a VerticalFieldManager, and then use vfm.setMargin(10, 10, 10, 10); after that, put some fields(buttonField, ObjectChoiceField) in it.

It seems too simple, right? but strange thing happens. When I focus to the last ObjectChoiceField and press space to toggle choice of it, the ObjectChoiceField disappeared.

How can that be? here is the demo code, anyone kindly find the bug?

final class HelloWorldScreen extends MainScreen{
  HelloWorldScreen() {
    // just a demo to show the strange thing
    String [] arr = {"a","b"};
    for(int i = 0; i < 10; i++){

        VerticalFieldManager vfm = new VerticalFieldManager(); // Field.USE_ALL_WIDTH
        vfm.setMargin(10, 10, 10, 10);
        ButtonField btn = new ButtonField(String.valueOf(i));
        ObjectChoiceField ch = new ObjectChoiceField(String.valueOf(i), arr);

        vfm.add(btn);
        vfm.add(ch);

        add(vfm);
    }
  }
}

Edit: screenshot of desired UI margins:

enter image description here

Upvotes: 2

Views: 199

Answers (1)

Nate
Nate

Reputation: 31045

That is strange.

For the benefit of those who don't run your code, what's happening is that when you click on the object choice fields, the whole screen is scrolling a little bit vertically. After each vertical scroll, the screen loses the ability to scroll all the way down to the bottom. After many such operations, eventually much of the lower part of this screen is no longer accessible.

I don't know why this is happening. (looks like a BlackBerry bug to me)

What I observed is that if you take out the call to

    vfm.setMargin(10, 10, 10, 10);

the problem goes away.

May I suggest a workaround where you use

    vfm.setPadding(10, 10, 10, 10);

instead?

I know that margin and padding are not the same thing. However, depending on what your full UI design is (which I cannot see), in this case, setting a 10 pixel padding may be sufficient to do what you were trying to do.


Update: based on the screenshot of your desired UI, I was able to produce that with this workaround. Again, it shouldn't be this much work, but this additional code worked for me:

public class BugScreen extends MainScreen {

   private static final int BG_COLOR = Color.LIGHTGRAY;
   private static final int FG_COLOR = Color.WHITE;
   private static final int BORDER_LINE_COLOR = Color.GRAY;
   private static final int PAD = 10;

   public BugScreen() {
      super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);

      getMainManager().setBackground(BackgroundFactory.createSolidBackground(BG_COLOR));
      // this additional call ensures that when scrolling bounces, the area "behind"
      // the normal visible area is ALSO of BG_COLOR
      setBackground(BackgroundFactory.createSolidBackground(BG_COLOR));

      // this will establish a thin gray padding on the screen's left/right sides
      // NOTE: I seem to get drawing artifacts if I try to use this for ALL sides!
      getMainManager().setPadding(0, PAD, 0, PAD);

      String [] arr = {"a","b"};
      for(int i = 0; i < 10; i++){

         VerticalFieldManager vfm = new VerticalFieldManager(Field.USE_ALL_WIDTH) {
            public int getPreferredWidth() {
               return Display.getWidth() - 2 * PAD;
            }
            public void paint(Graphics graphics) {
               int oldColor = graphics.getColor();
               super.paint(graphics);
               graphics.setColor(BORDER_LINE_COLOR);
               // draw the (1-pixel wide) border size you would like.
               graphics.drawRect(0, 0, getPreferredWidth(), getHeight());
               graphics.setColor(oldColor);
            }
         };

         vfm.setBackground(BackgroundFactory.createSolidBackground(FG_COLOR));
         ButtonField btn = new ButtonField(String.valueOf(i));
         ObjectChoiceField ch = new ObjectChoiceField(String.valueOf(i), arr);

         vfm.add(btn);
         vfm.add(ch);

         // add a separator field to get thin gray margin between (vfm) fields         
         add(new MarginField());

         add(vfm);
      }

      // add one last margin field at the bottom
      add(new MarginField());
   }

   private class MarginField extends Field {
      public MarginField() {
         super(Field.USE_ALL_WIDTH);
      }
      public int getPreferredHeight() { return PAD; }
      protected void paint(Graphics g) {
         int oldColor = g.getColor();
         g.setColor(BG_COLOR);
         g.fillRect(0, 0, getWidth(), getPreferredHeight());
         g.setColor(oldColor);
      }
      protected void layout(int width, int height) {
         setExtent(width, getPreferredHeight());               
      }     
   }
}

Upvotes: 1

Related Questions