@Override
	public void layoutContainer(final Container target) {

		final Dimension d = target.getSize();
		final Insets insets = target.getInsets();

		// preferred layout size for Image5dCanvas
		final Dimension prefCanvasSize = new Dimension(d);

		contentBounds.x = insets.left;
		contentBounds.y = insets.top;

		// Widths of canvasses
		contentBounds.width =
			d.width - (contentBounds.x + getVerticalControlsWidth() + insets.right);
		if (slice != null) {
			contentBounds.width =
				Math.max(contentBounds.width, slice.getMinimumSize().width + 2 * hgap);
		}
		if (frame != null) {
			contentBounds.width =
				Math.max(contentBounds.width, frame.getMinimumSize().width + 2 * hgap);
		}
		prefCanvasSize.width =
			(int) Math.floor((contentBounds.width - hgap) / (double) nCanvassesX) -
				hgap;

		// Heights of canvasses
		contentBounds.height = d.height - (contentBounds.y + insets.bottom);
		if (channel != null) {
			contentBounds.height =
				Math.max(contentBounds.height, channel.getMinimumSize().height + 2 *
					vgap);
		}
		contentBounds.height -= getHorizontalControlsHeight();
		prefCanvasSize.height =
			(int) Math.floor((contentBounds.height - vgap) / (double) nCanvassesY) -
				vgap;

		// Resize the ImageCanvas5D. This also resizes its "satellite" canvasses
		// in montage display mode.
		final Dimension canvasDim =
			ic5d.resizeCanvasI5D(prefCanvasSize.width, prefCanvasSize.height);

		final int offsX = insets.left;
		final int offsY = insets.top;

		// Place canvasses in center of area spanned by the controls.
		final int mainOffsX =
			offsX +
				(d.width - offsX - getVerticalControlsWidth() - insets.right -
					canvasDim.width * nCanvassesX - hgap * (nCanvassesX - 1)) / 2;
		final int mainOffsY =
			offsY +
				(d.height - offsY - getHorizontalControlsHeight() - insets.bottom -
					canvasDim.height * nCanvassesY - hgap * (nCanvassesY - 1)) / 2;

		// Set location of canvasses and store location and size in
		// canvasRectangles.
		// Canvas #0 is in lower right corner
		for (int i = 0; i < nCanvassesX * nCanvassesY; i++) {
			// Canvas #0 is in lower right corner (overlay). The others start from top
			// left.
			int j = 0;
			if (i == 0) j = nCanvassesX * nCanvassesY - 1;
			else j = i - 1;

			final int nX = j % nCanvassesX;
			final int nY = j / nCanvassesX;
			final int tempOffsX = mainOffsX + nX * (canvasDim.width + hgap);
			final int tempOffsY = mainOffsY + nY * (canvasDim.height + vgap);
			if (i < imageCanvasses.size()) {
				((Canvas) imageCanvasses.get(i)).setLocation(tempOffsX, tempOffsY);
				final Rectangle imageRect = imageRectangles.get(i);
				imageRect.x = tempOffsX;
				imageRect.y = tempOffsY;
				imageRect.width = canvasDim.width;
				imageRect.height = canvasDim.height;

			} // TODO: Add black Canvasses to locations up to n-1 (??)
		}

		// Set locations and sizes of controls.
		int y = d.height - insets.bottom - getHorizontalControlsHeight() - vgap;
		if (slice != null) {
			slice.setSize(contentBounds.width - 2 * hgap,
				slice.getPreferredSize().height);
			y += vgap;
			slice.setLocation(offsX + hgap, y);
			y += slice.getPreferredSize().height;
		}
		if (frame != null) {
			frame.setSize(contentBounds.width - 2 * hgap,
				frame.getPreferredSize().height);
			y += vgap;
			frame.setLocation(offsX + hgap, y);
			y += frame.getPreferredSize().height;
		}

		int x = d.width - insets.right - getVerticalControlsWidth() - vgap;
		if (channel != null) {
			channel.setSize(channel.getPreferredSize().width, d.height - insets.top -
				insets.bottom - 2 * vgap);
			x += hgap;
			channel.setLocation(x, offsY + vgap);
			x += channel.getPreferredSize().width;
		}
	}