private void updateCharacterBufferFromModel() {
    charBuffer.clear();

    charBuffer.setBackgroundColor(java.awt.Color.LIGHT_GRAY.brighter());
    currentFirstRow = verticalScrollbar.getValue();
    currentFirstCharColumn = horizontalScrollbar.getValue();

    // Draw the header, if requested.
    int totalCopiedLines = 0;
    if (codeModel.hasHeaderRow()) {
      totalCopiedLines = 1;
      int currentColumnIndex = 0;
      for (int fieldIndex = 0;
          fieldIndex < codeModel.getNumberOfColumns();
          currentColumnIndex += codeModel.getColumnWidthInCharacters(fieldIndex), fieldIndex++) {
        charBuffer.copyInto(0, currentColumnIndex, codeModel.getHeader(fieldIndex));
      }
    }

    // Iterates over the rows. Since each row has a height of at least one line,
    // the for() loop iterates over more than what is strictly required and
    // aborts early.
    for (int rowIndex = currentFirstRow;
        rowIndex < Math.min(currentFirstRow + currentlyVisibleLines, codeModel.getNumberOfRows());
        rowIndex++) {
      for (int lineIndex = (rowIndex == currentFirstRow) ? currentFirstLine : 0;
          lineIndex < codeModel.getMaximumLinesForRow(rowIndex);
          lineIndex++) {
        // Iterate over all the columns that need to be drawn.
        int currentColumnIndex = 0;
        for (int fieldIndex = 0;
            fieldIndex < codeModel.getNumberOfColumns();
            currentColumnIndex += codeModel.getColumnWidthInCharacters(fieldIndex), fieldIndex++) {
          // Update the current X/Y position of the caret in terms of this buffer.
          if ((caretPosition.getRow() == rowIndex)
              && (caretPosition.getLine() == lineIndex)
              && (caretPosition.getColumn() == fieldIndex)) {
            caretX = currentColumnIndex + caretPosition.getFieldIndex();
            caretY = totalCopiedLines;
          }

          FormattedCharacterBuffer line =
              codeModel.getLineFormatted(rowIndex, fieldIndex, lineIndex);

          if (line != null) {
            charBuffer.copyInto(totalCopiedLines, currentColumnIndex, line);
          }

          // Update the map that allows quick mapping of pixel positions to rows
          // and lines within rows.
          int linestart = totalCopiedLines * fontLineHeight + (fontLineHeight / 2);
          if (!yCoordinateToRowAndLine.containsKey(linestart)) {
            yCoordinateToRowAndLine.put(
                linestart, new CodeDisplayCoordinate(rowIndex, lineIndex, 0, 0));
          } else {
            CodeDisplayCoordinate coordinate = yCoordinateToRowAndLine.get(linestart);
            coordinate.setRow(rowIndex);
            coordinate.setLine(lineIndex);
          }
        }
        totalCopiedLines++;
      }
    }
    setScrollBarMaximum();
  }
Updates/rewrites the internal representation of the character buffer (that will be drawn) from
the data model. Updating the character buffer from the data model requires a bit of care: The
model provides a sequence of rows, each divided into a fixed number of columns, and each cell
(identified by a row/column combination) can have multiple lines of text. To properly copy this
into a FormattedCharacterBuffer, the code iterates over all rows first. For each row, it
determines what the maximum number of text lines is (over all columns) - this is needed to
determine the overall height of the row. The individual cells are then filled into the right
row, and everything advances to the next row.
java/zylib/src/main/java/com/google/security/zynamics/zylib/gui/CodeDisplay/CodeDisplay.java