title: Blackberry scrolling doesn't redraw fields
body: <p>I have a very strange problem at the moment.</p>
  
  <p>Basically when I scroll in a screen, the fields don't get redrawn completely or consistently.</p>
  
  <p>I have a Screen (NO_VERTICAL_SCROLL), with a manager as a titlebar. Below that I have a vertical field manager (VERTICAL_SCROLL) with labelfields. When I scroll the vfm one or two lines of the labelfields, which were already visible, get redrawn. The section I'm scrolling down to has absolutely nothing drawn.</p>
  
  <p>I tried invalidate(), and calling doPaint in a scrollchangelistener, but its actually much worse. It results in the titlebar only being  partially redrawn.</p>
  
  <p>In the code below I used a custom <code>FontManager</code>, <code>DimenManager</code>, and <code>ImageResourceManager</code> to return values dependent on screen size. I used a custom <code>BitmapButtonField</code> and <code>ClickableLabel</code> in order to change the state of a field when a click is being held in.</p>
  
  <pre><code>public class BaseScreen extends MainScreen implements StringsResource
  {
      protected ResourceBundle resources;
  
      public BaseScreen(long style)
      {
          super(style);
  
          StandardTitleBar titlebar = new StandardTitleBar();
          titlebar.addSignalIndicator();
          titlebar.addClock();
          titlebar.addNotifications();
  
          setTitle(titlebar);
  
          resources = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);
      }
  }
  
  public class TandCScreen extends BaseScreen
  {
      final String copy_text1 = "long text here";
      final String copy_text2 = "even longer text here";
  
      ColoredLabelField label_title;
      ColoredLabelField label_subtitle;
      ColoredLabelField label1;
      ColoredLabelField label2;
      ClickableLabel label3;
  
      public TandCScreen()
      {
          super(NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR);
          label_title = new ColoredLabelField(resources.getString(STRING_APP_NAME), Color.WHITE, DrawStyle.HCENTER | USE_ALL_WIDTH);
          label_title.setBackground(BackgroundFactory.createSolidBackground(0x60223b));
          label_subtitle = new ColoredLabelField(resources.getString(STRING_TANDC_TITLE), 0x58585b, DrawStyle.HCENTER | USE_ALL_WIDTH);
  
          label1 = new ColoredLabelField(copy_text1, 0x58585b, USE_ALL_WIDTH);
          label2 = new ColoredLabelField("", 0xa7a9ab, USE_ALL_WIDTH);
  
          label3 = new ClickableLabel("Read more...")
          {
              protected void unclick()
              {
                  super.unclick();
                  UiApplication.getUiApplication().invokeLater(new Runnable()
                  {
                      public void run()
                      {
                          ColoredLabelField label = new ColoredLabelField(copy_text2, 0xa7a9ab, 0);
                          label.setFont(FontManager.body());
                          label.setMargin(0, 0, DimenManager.interField(), 0);
                          label2.getManager().replace(label2, label);
                          label3.getManager().delete(label3);
                      }
                  });
              }
          };
  
          label_title.setFont(FontManager.subtitle());
          label_subtitle.setFont(FontManager.subtitle());
          label1.setFont(FontManager.body());
          label2.setFont(FontManager.body());
          label3.setFont(FontManager.body());
  
          BitmapButtonField button_accept = new BitmapButtonField(ImageResourceManager.buttonAccept(), ImageResourceManager.buttonAcceptHover(), FIELD_HCENTER)
          {
              protected void click()
              {
                  super.click();
                  setImage(ImageResourceManager.buttonAcceptSelected());
                  setFocusImage(ImageResourceManager.buttonAcceptSelected());
              }
  
              protected void unclick()
              {
                  super.unclick();
                  PersistentStoreManager.setTandCAccepted(true);
                  UiApplication.getUiApplication().pushScreen(new LoginScreen());
                  close();
              }
          };
  
          BitmapButtonField button_decline = new BitmapButtonField(ImageResourceManager.buttonDecline(), ImageResourceManager.buttonDeclineHover(), FIELD_HCENTER)
          {
              protected void click()
              {
                  super.click();
                  setImage(ImageResourceManager.buttonDeclineSelected());
                  setFocusImage(ImageResourceManager.buttonDeclineSelected());
              }
  
              protected void unclick()
              {
                  super.unclick();
                  close();
              }
          };
  
          int margin = (VariableManager.DISPLAY_WIDTH - button_accept.getPreferredWidth()) / 2;
          // calculate where to put ellipsis
          Font font = label2.getFont();
          int max_length = (VariableManager.DISPLAY_WIDTH - margin * 2) * 2;
          int i = copy_text2.length() - 1;
          while (font.getAdvance(copy_text2.substring(0, i)) + font.getAdvance("...") &gt;= max_length)
              i--;
  
          label2.setText(copy_text2.substring(0, i).trim() + "...");
  
          VerticalFieldManager vfm = new VerticalFieldManager(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
          vfm.add(new NullField());
          vfm.add(label_subtitle);
          vfm.add(new Seperator());
          vfm.add(label1);
          vfm.add(label2);
          vfm.add(label3);
          vfm.add(button_accept);
          vfm.add(button_decline);
  
          vfm.setMargin(0, margin, 0, margin);
  
          // paddings
          int padding = (DimenManager.header() - label_title.getPreferredHeight()) / 2;
          label_title.setPadding(padding, 0, padding, 0);
          label_subtitle.setPadding(DimenManager.interField(), 0, DimenManager.interField(), 0);
          label1.setMargin(DimenManager.interField(), 0, DimenManager.interField(), 0);
          label3.setMargin(DimenManager.interField(), 0, DimenManager.interField(), button_accept.getPreferredWidth() - label3.getPreferredWidth());
          button_decline.setMargin(DimenManager.interField(), 0, DimenManager.interButton(), 0);
  
          add(label_title);
          add(vfm);
      }
  
      protected boolean onSavePrompt()
      {
          return false;
      }
  
      protected void makeMenu(Menu menu, int instance)
      {
          if (instance == Menu.INSTANCE_CONTEXT)
          {
              ContextMenu contextMenu = ContextMenu.getInstance();
              contextMenu.setTarget(this);
              contextMenu.clear();
              this.makeContextMenu(contextMenu);
              menu.deleteAll();
              menu.add(contextMenu);
          }
          else
          {
              super.makeMenu(menu, instance);
          }
      }
      protected void makeContextMenu(ContextMenu contextMenu)
      {
      }
  
      /**
       * Clickable labelfield which changes color on down press, and fires action
       * on release. Action is canceled if touch moves outside field bounds.
       * 
       * @author kevin
       * 
       */
      private class ClickableLabel extends LabelField
      {
          private boolean canceled = true;
          private boolean consumed = false;
          protected boolean pressed = false;
  
          public ClickableLabel(String label)
          {
              super(label, LabelField.FOCUSABLE | USE_ALL_WIDTH);
              setFont(FontManager.body());
          }
  
          protected void paint(Graphics g)
          {
              // background
              if (pressed)
              {
                  g.setColor(0x2C1721);
              }
              else if (isFocus())
              {
                  g.setColor(0x993C6B);
              }
              else
              {
                  g.setColor(0x60223B);
              }
  
              int padding_y = (getPreferredHeight() - getFont().getHeight()) / 2;
              int padding_x = getPaddingLeft();
              g.drawText(getText(), padding_x, padding_y);
          }
  
          public int getPreferredHeight()
          {
              return ImageResourceManager.highlight().getHeight();
          }
  
          protected void layout(int width, int height)
          {
              height = getPreferredHeight();
              super.layout(width, height);
              setExtent(width, height);
          }
  
          // --------- Highlight selected row ---------
          protected void onFocus(int direction)
          {
              super.onFocus(direction);
              invalidate();
          }
  
          protected void onUnfocus()
          {
              super.onUnfocus();
              invalidate();
          }
          // --------------------------------------------
  
          protected void drawFocus(Graphics graphics, boolean on)
          {
          }
  
          /**
           * Called when trackpad pressed, or touchscreen touched
           */
          protected void click()
          {
              pressed = true;
              invalidate();
          }
  
          /**
           * Called when trackpad released, or touchscreen released
           */
          protected void unclick()
          {
              cancel();
          }
  
          protected void cancel()
          {
              pressed = false;
              invalidate();
          }
  
          protected boolean navigationClick(int status, int time)
          {
              if (status != 0)
              {
                  if (consumed)
                  {
                      consumed = false;
                  }
                  else
                  {
                      click();
                  }
              }
              return true;
          }
  
          protected boolean navigationUnclick(int status, int time)
          {
              if (status != 0)
              {
                  if (consumed)
                      consumed = false;
                  else
                      unclick();
              }
              return true;
          }
  
          protected boolean touchEvent(TouchEvent message)
          {
              int x = message.getX(1);
              int y = message.getY(1);
              if (x &lt; 0 || y &lt; 0 || x &gt; getExtent().width || y &gt; getExtent().height)
              {
                  // Outside the field
                  if (!canceled)
                  {
                      cancel();
                  }
                  canceled = true;
                  return false;
              }
  
              if (message.getEvent() == TouchEvent.UP)
              {
  
                  if (canceled)
                      cancel();
                  else
                      unclick();
                  consumed = true;
  
                  return true;
              }
              if (message.getEvent() == TouchEvent.DOWN)
              {
                  click();
                  consumed = true;
                  canceled = false;
  
                  return true;
              }
  
              return super.touchEvent(message);
          }
      }
  
      private class Seperator extends SeparatorField
      {
          protected void paint(Graphics graphics)
          {
              graphics.setColor(0xa7a9ab);
              super.paint(graphics);
          }
      }
  }
  </code></pre>
  
  <p>Thanks in advance for any suggestions</p>