private boolean add(IFormField field, GridData data) {
   MatrixIndex currentIndex = m_cursor.currentIndex();
   if (data.w > 1) {
     // try to reorganize fields above
     int x = currentIndex.x;
     int y = currentIndex.y;
     // try to move left if the right border of the field is outside the column range
     while (x + data.w > m_cursor.startX + m_cursor.columnCount) {
       // shift left and bottom
       x--;
       y = m_cursor.rowCount - 1;
     }
     reorganizeGridAbove(x, y, data.w);
   }
   if (!nextFree(data.w, data.h)) {
     return false;
   }
   currentIndex = m_cursor.currentIndex();
   data.x = currentIndex.x;
   data.y = currentIndex.y;
   // add field
   for (int xx = currentIndex.x; xx < currentIndex.x + data.w; xx++) {
     for (int yy = currentIndex.y; yy < currentIndex.y + data.h; yy++) {
       m_cells.put(new MatrixIndex(xx, yy), new Cell(field, data));
     }
   }
   return true;
 }
 @Override
 public void setScrollable(boolean scrollable) {
   if (m_scrollable != scrollable) {
     m_scrollable = scrollable;
     if (m_scrollable) {
       // force weighty to be > 0
       GridData gd = getGridDataHints();
       if (gd.weightY <= 0) {
         gd.weightY = 1;
         setGridDataHints(gd);
       }
     }
   }
 }
 private void layoutStatic() {
   int x = 0;
   for (int i = 0; i < m_fields.length; i++) {
     GridData data = GridDataBuilder.createFromHints(m_fields[i], 1);
     data.x = x;
     data.y = 0;
     if (data.weightX < 0) {
       data.weightX = data.w;
     }
     m_fields[i].setGridDataInternal(data);
     x = x + data.w;
     m_gridRows = Math.max(m_gridRows, data.h);
   }
   m_gridColumns = x;
 }