@Override
	public Dimension getPreferredSize() {
		Insets insets = getInsets();
		Dimension size = new Dimension(insets.left + insets.right, insets.top + insets.bottom);
		List<Column> columns = mModel.getColumns();
		boolean needRevalidate = false;

		for (Column col : columns) {
			int width = col.getWidth();
			if (width == -1) {
				width = col.getPreferredWidth(this);
				col.setWidth(width);
				needRevalidate = true;
			}
			if (col.isVisible()) {
				size.width += width + (mDrawColumnDividers ? 1 : 0);
			}
		}
		if (mDrawColumnDividers && !mModel.getColumns().isEmpty()) {
			size.width--;
		}

		if (needRevalidate) {
			revalidateView();
		}

		boolean needHeightAdjust = false;
		for (int i = getFirstRowToDisplay(); i <= getLastRowToDisplay(); i++) {
			Row row = mModel.getRowAtIndex(i);
			if (!mModel.isRowFiltered(row)) {
				int height = row.getHeight();
				if (height == -1) {
					height = row.getPreferredHeight(columns);
					row.setHeight(height);
				}
				size.height += height + (mDrawRowDividers ? 1 : 0);
				needHeightAdjust = true;
			}
		}
		if (mDrawRowDividers && needHeightAdjust) {
			size.height--;
		}

		if (isMinimumSizeSet()) {
			Dimension minSize = getMinimumSize();
			if (size.width < minSize.width) {
				size.width = minSize.width;
			}
			if (size.height < minSize.height) {
				size.height = minSize.height;
			}
		}
		return size;
	}