private void computeLayoutTable(Container target) {
		int[] unfinishedSpans = null;
		int row = 0;
		int column = 0;
		int layoutColumns = nColumns;
		int nComponents = target.getComponentCount();
		boolean nextEndRow = false;
		layoutTable = new HashMap();
		for (int i = 0; i < nComponents; i++) {
			Component comp = target.getComponent(i);
			TableConstraints tc = getConstraints(comp);
			if (tc.gridx != GridBagConstraints.RELATIVE) column = tc.gridx;
			if (tc.gridy != GridBagConstraints.RELATIVE) row = tc.gridy;
			if (nRows > 0 && row >= nRows) {
				throw new ErrorException("TableLayout: Too many rows specified");
			}
			while (unfinishedSpans != null && column < unfinishedSpans.length && unfinishedSpans[column] > 0) {
				column++;
				if (layoutColumns > 0 && column >= layoutColumns) {
					for (int c = 0; c < unfinishedSpans.length; c++) {
						if (unfinishedSpans[c] > 0) unfinishedSpans[c]--;
					}
					row++;
					column = getFirstAvailableColumn(unfinishedSpans);
				}
			}
			tc.gridx = column;
			tc.gridy = row;
			boolean endrow = nextEndRow;
			setMaxProperty("width" + column, tc.width);
			setMaxProperty("height" + row, tc.height);
			setMaxProperty("weightx" + column, tc.weightx);
			setMaxProperty("weighty" + row, tc.weighty);
			int colspan = 1;
			switch (tc.gridwidth) {
			  case GridBagConstraints.REMAINDER:
				endrow = true;
				if (layoutColumns > 0) colspan = layoutColumns - column;
				break;
			  case GridBagConstraints.RELATIVE:
				if (layoutColumns <= 0) {
					throw new ErrorException("TableLayout: Illegal to use gridwidth=RELATIVE in first row");
				}
				colspan = layoutColumns - column - 1;
				nextEndRow = true;
				break;
			  default:
				colspan = tc.gridwidth;
				endrow = (nColumns > 0 && column + tc.gridwidth >= nColumns);
				break;
			}
			if (colspan > 1 && unfinishedSpans != null) {
				for (int c = column; c < Math.min(unfinishedSpans.length, column + colspan); c++) {
					if (unfinishedSpans[c] != 0) {
						throw new ErrorException("TableLayout: Overlapping cells");
					}
				}
			}
			int rowspan = 1;
			switch (tc.gridheight) {
			  case GridBagConstraints.REMAINDER:
				rowspan = Integer.MAX_VALUE;
				break;
			  case GridBagConstraints.RELATIVE:
				throw new ErrorException("TableLayout: Illegal to use gridheight=RELATIVE");
			  default:
				rowspan = tc.gridheight;
				break;
			}
			if (rowspan > 1) {
				if (unfinishedSpans == null) {
					unfinishedSpans = new int[column + colspan];
				} else if (unfinishedSpans.length < column + colspan) {
					int[] oldSpans = unfinishedSpans;
					unfinishedSpans = new int[column + colspan];
					System.arraycopy(oldSpans, 0, unfinishedSpans, 0, oldSpans.length);
				}
				for (int c = column; c < column + colspan; c++) {
					unfinishedSpans[c] = rowspan;
				}
			}
			tc.gridwidth = colspan;
			tc.gridheight = rowspan;
			layoutTable.put(comp, tc);
			column += colspan;
			while (endrow || (layoutColumns > 0 && column >= layoutColumns)) {
				if (layoutColumns <= 0) layoutColumns = column;
				if (unfinishedSpans != null) {
					for (int c = 0; c < unfinishedSpans.length; c++) {
						if (unfinishedSpans[c] > 0) unfinishedSpans[c]--;
					}
				}
				row++;
				column = getFirstAvailableColumn(unfinishedSpans);
				endrow = false;
			}
		}
		if (layoutColumns <= 0) layoutColumns = column;
		setIntProperty("nColumns", layoutColumns);
		setIntProperty("nRows", row + 1);
	}