blob: eafd20ff77f62bbfb3e097c4f088e1217ca1b426 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.layout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.Geometry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CBanner;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.TrimDragPreferences;
/**
* Lays out the children of a Composite. One control occupies the center of the
* composite, and any number of controls may be attached to the top, bottom, and
* sides. This is a common layout for application windows, which typically have
* a central work area and a number of small widgets (toolbars, status lines,
* etc.) attached to the edge.
*
* <p>
* Unlike most other SWT layouts, this layout does not require layout data to be
* attached to each child control. Instead, member functions on the Layout are
* used to control the positioning of controls within the layout.
* </p>
*
* <p>
* The interface to this layout is intended to easily support drag-and-drop.
* Trim widgets can be added, removed, or inserted between other existing
* widgets and the layout will adjust accordingly. If one side of the layout
* contains no trim widgets, the central area will expand to reclaim the unused
* space.
* </p>
*
* <p>
* This layout must be told about every widget that it is supposed to arrange.
* If the composite contains additional widgets, they will not be moved by the
* layout and may be arranged through other means.
* </p>
*
* @since 3.0
*/
public class TrimLayout extends Layout implements ICachingLayout, ITrimManager {
/**
* Trim area ID.
*/
public static final Integer TOP_ID = new Integer(TOP);
/**
* Trim area ID.
*/
public static final Integer BOTTOM_ID = new Integer(BOTTOM);
/**
* Trim area ID.
*/
public static final Integer LEFT_ID = new Integer(LEFT);
/**
* Trim area ID.
*/
public static final Integer RIGHT_ID = new Integer(RIGHT);
/**
* Trim area ID.
*/
public static final Integer NONTRIM_ID = new Integer(NONTRIM);
/**
* IDs for the current trim areas we support.
*/
private static final int[] TRIM_ID_INFO = { LEFT, RIGHT, TOP, BOTTOM };
private SizeCache centerArea = new SizeCache();
/**
* Map of TrimAreas by IDs.
*/
private Map fTrimArea = new HashMap();
/**
* Map of TrimDescriptors by IDs.
*/
private Map fTrimDescriptors = new HashMap();
private int marginWidth;
private int marginHeight;
private int topSpacing;
private int bottomSpacing;
private int leftSpacing;
private int rightSpacing;
private int spacing = 3;
private boolean trimLocked;
/**
* Creates a new (initially empty) trim layout.
*/
public TrimLayout() {
// Determine whether or not the trim is 'locked'
final IPreferenceStore store = PlatformUI.getPreferenceStore();
trimLocked = store.getBoolean(IWorkbenchPreferenceConstants.LOCK_TRIM);
createTrimArea(TOP_ID, TOP_ID.toString(), SWT.DEFAULT, SWT.TOP);
createTrimArea(BOTTOM_ID, BOTTOM_ID.toString(), SWT.DEFAULT, SWT.BOTTOM);
createTrimArea(LEFT_ID, LEFT_ID.toString(), SWT.DEFAULT, SWT.LEFT);
createTrimArea(RIGHT_ID, RIGHT_ID.toString(), SWT.DEFAULT, SWT.RIGHT);
}
private void createTrimArea(Integer id, String displayName, int trimSize,
int trimMods) {
TrimArea top = new TrimArea(id.intValue(), displayName);
top.setTrimSize(trimSize);
top.setControlModifiers(trimMods);
fTrimArea.put(id, top);
}
/**
* Sets the empty space surrounding the center area. This whitespace is
* located between the trim and the central widget.
*
* @param left
* pixel width
* @param right
* pixel width
* @param top
* pixel width
* @param bottom
* pixel width
*/
public void setSpacing(int left, int right, int top, int bottom) {
leftSpacing = left;
rightSpacing = right;
topSpacing = top;
bottomSpacing = bottom;
}
/**
* Sets the empty space around the outside of the layout. This whitespace is
* located outside the trim widgets.
*
* @param marginWidth
* @param marginHeight
*/
public void setMargins(int marginWidth, int marginHeight) {
this.marginWidth = marginWidth;
this.marginHeight = marginHeight;
}
/**
* Sets the trimSize (pixels) for the given side of the layout. If
* SWT.DEFAULT, then the trim size will be computed from child controls.
*
* @param areaId
* the area ID
* @param size
* in pixels
* @see #getAreaIds()
*/
public void setTrimSize(int areaId, int size) {
TrimArea area = (TrimArea) fTrimArea.get(new Integer(areaId));
if (area != null) {
area.setTrimSize(size);
}
}
/**
* Returns the location of the given trim control. For example, returns
* SWT.LEFT if the control is docked on the left, SWT.RIGHT if docked on the
* right, etc. Returns SWT.DEFAULT if the given control is not a trim
* control.
*
* @param trimControl
* control to query
* @return The area ID of this control. If the control is not part of our
* trim, return SWT.DEFAULT.
* @see #getAreaIds()
*/
public int getTrimAreaId(Control trimControl) {
TrimDescriptor desc = findTrimDescription(trimControl);
if (desc != null) {
return desc.getAreaId();
}
return SWT.DEFAULT;
}
/**
* @param control
* new window trim to be added
* @param areaId
* the area ID
* @see #getAreaIds()
* @deprecated
*/
public void addTrim(IWindowTrim control, int areaId) {
addTrim(areaId, control, null);
}
/**
*
* @param trim
* new window trim to be added
* @param areaId
* the area ID
* @param beforeMe
* if null, the control will be inserted as the last trim widget
* on this side of the layout. Otherwise, the control will be
* inserted before the given widget.
* @see #getAreaIds()
* @deprecated
*/
public void addTrim(IWindowTrim trim, int areaId, IWindowTrim beforeMe) {
addTrim(areaId, trim, beforeMe);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#addTrim(int,
* org.eclipse.ui.internal.IWindowTrim)
*/
public void addTrim(int areaId, IWindowTrim trim) {
addTrim(areaId, trim, null);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#addTrim(int,
* org.eclipse.ui.internal.IWindowTrim,
* org.eclipse.ui.internal.IWindowTrim)
*/
public void addTrim(int areaId, IWindowTrim trim, IWindowTrim beforeMe) {
TrimArea area = (TrimArea) fTrimArea.get(new Integer(areaId));
if (area == null) {
return;
}
// remove the trim from the current layout
removeTrim(trim);
// Create a new trim descriptor for the new area...
TrimDescriptor desc = new TrimDescriptor(trim, areaId);
// If the trim can be relocated then add a docking handle
if (!trimLocked && trim.getValidSides() != SWT.NONE) {
// Create a 'docking' handle to allow dragging the trim
Composite dockingHandle = new TrimCommonUIHandle(this, trim, areaId);
desc.setDockingCache(new SizeCache(dockingHandle));
}
// Add the trim control
SizeCache cache = new SizeCache(trim.getControl());
trim.getControl().setLayoutData(trim);
desc.setCache(cache);
// Add a dispose listener so we can clean up if the Client disposes the trim
trim.getControl().addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
Control control = (Control) e.widget;
if (control.getLayoutData() instanceof IWindowTrim) {
IWindowTrim trim = (IWindowTrim) control.getLayoutData();
removeTrim(trim);
//forceLayout();
}
}
});
// Add the new descriptor to the map
fTrimDescriptors.put(desc.getId(), desc);
// insert before behaviour, revisited
if (beforeMe != null) {
TrimDescriptor beforeDesc = (TrimDescriptor) fTrimDescriptors
.get(beforeMe.getId());
if (beforeDesc != null && beforeDesc.getAreaId() == areaId) {
area.addTrim(desc, beforeDesc);
} else {
area.addTrim(desc);
}
} else {
area.addTrim(desc);
}
}
/**
* Force a layout of the trim
*/
public void forceLayout() {
removeDisposed();
// we hack this by calling the LayoutUtil with the
// first piece of trim that we find...(kludge!!)
Iterator d = fTrimDescriptors.values().iterator();
while (d.hasNext()) {
TrimDescriptor desc = (TrimDescriptor) d.next();
if (desc.getTrim().getControl() != null) {
LayoutUtil.resize(desc.getTrim().getControl());
return;
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#removeTrim(org.eclipse.ui.internal.IWindowTrim)
*/
public void removeTrim(IWindowTrim toRemove) {
TrimDescriptor desc = (TrimDescriptor) fTrimDescriptors.remove(toRemove
.getId());
if (desc == null) {
return;
}
TrimArea area = (TrimArea) fTrimArea.get(new Integer(desc.getAreaId()));
if (area != null) {
area.removeTrim(desc);
desc.getCache().getControl().setLayoutData(null);
}
// If we had a trim UI handle then dispose it
if (desc.getDockingCache() != null) {
Control ctrl = desc.getDockingCache().getControl();
// KLUDGE!! we'll leak a handle rather than losing the
// mouse capture (for now...)
ctrl.setVisible(false);
//ctrl.dispose();
desc.setDockingCache(null);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#getTrim(java.lang.String)
*/
public IWindowTrim getTrim(String id) {
TrimDescriptor desc = (TrimDescriptor) fTrimDescriptors.get(id);
if (desc != null) {
return desc.getTrim();
}
return null;
}
/**
* Removes any disposed widgets from this layout. This is still experimental
* code.
*/
private void removeDisposed() {
Iterator a = fTrimArea.values().iterator();
while (a.hasNext()) {
TrimArea area = (TrimArea) a.next();
Iterator d = area.getDescriptors().iterator();
while (d.hasNext()) {
TrimDescriptor desc = (TrimDescriptor) d.next();
Control nextControl = desc.getTrim().getControl();
if (nextControl == null || nextControl.isDisposed()) {
// Remvoe the trim from the area's list (not the local copy)
area.removeTrim(desc);
// Remove it from the map
fTrimDescriptors.remove(desc.getId());
}
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite,
* int, int, boolean)
*/
protected Point computeSize(Composite composite, int wHint, int hHint,
boolean flushCache) {
Point result = new Point(wHint, hHint);
TrimArea top = (TrimArea) fTrimArea.get(TOP_ID);
TrimArea bottom = (TrimArea) fTrimArea.get(BOTTOM_ID);
TrimArea left = (TrimArea) fTrimArea.get(LEFT_ID);
TrimArea right = (TrimArea) fTrimArea.get(RIGHT_ID);
int horizontalTrim = left.calculateTrimSize(wHint, hHint)
+ right.calculateTrimSize(wHint, hHint) + (2 * marginWidth)
+ leftSpacing + rightSpacing;
int verticalTrim = top.calculateTrimSize(wHint, hHint)
+ bottom.calculateTrimSize(wHint, hHint) + (2 * marginHeight)
+ topSpacing + bottomSpacing;
Point innerSize = centerArea.computeSize(wHint == SWT.DEFAULT ? wHint
: wHint - horizontalTrim, hHint == SWT.DEFAULT ? hHint : hHint
- verticalTrim);
if (wHint == SWT.DEFAULT) {
result.x = innerSize.x + horizontalTrim;
} else if (hHint == SWT.DEFAULT) {
result.y = innerSize.y + verticalTrim;
}
return new Point(0, 0);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite,
* boolean)
*/
protected void layout(Composite composite, boolean flushCache) {
removeDisposed();
TrimArea top = (TrimArea) fTrimArea.get(TOP_ID);
TrimArea bottom = (TrimArea) fTrimArea.get(BOTTOM_ID);
TrimArea left = (TrimArea) fTrimArea.get(LEFT_ID);
TrimArea right = (TrimArea) fTrimArea.get(RIGHT_ID);
Rectangle clientArea = composite.getClientArea();
clientArea.x += marginWidth;
clientArea.width -= 2 * marginWidth;
clientArea.y += marginHeight;
clientArea.height -= 2 * marginHeight;
// Get the max of the trim's preferred size for each side
int trim_top = top.calculateTrimSize(clientArea.width,
clientArea.height);
int trim_bottom = bottom.calculateTrimSize(clientArea.width,
clientArea.height);
int trim_left = left.calculateTrimSize(clientArea.width,
clientArea.height);
int trim_right = right.calculateTrimSize(clientArea.width,
clientArea.height);
// Determine the amount of 'useable' space for the trim
int leftOfLayout = clientArea.x;
int leftOfCenterPane = leftOfLayout + trim_left + leftSpacing;
int widthOfCenterPane = clientArea.width - trim_left - trim_right
- leftSpacing - rightSpacing;
int rightOfCenterPane = clientArea.x + clientArea.width - trim_right;
// HACK!! Surgical Fix: Ideally the fix would handle 'wrapping' trim
// on any side. The following code is in place specifically to
// handle the CBanner's CoolBar wrapping. The code that calculates 'trim_top'
// above won't pick up if the CoolBar wraps and uses extra height
// So we have to re-calc the value based on the actual trim height
// as laid out.
// Do the layout of the top and update the height to match the actual
// height used
int topOfLayout = clientArea.y;
trim_top = arrange(new Rectangle(leftOfLayout, topOfLayout, clientArea.width,
trim_top), top.getCaches(), !top.isVertical(), spacing);
// Now that we have an accurate value for the top's height we can
// proceed with the rest of the layout 'normally'.
int topOfCenterPane = topOfLayout + trim_top + topSpacing;
int heightOfCenterPane = clientArea.height - trim_top - trim_bottom
- topSpacing - bottomSpacing;
int bottomOfCenterPane = clientArea.y + clientArea.height - trim_bottom;
arrange(new Rectangle(leftOfCenterPane, bottomOfCenterPane,
widthOfCenterPane, trim_bottom), bottom.getCaches(), !bottom
.isVertical(), spacing);
arrange(new Rectangle(leftOfLayout, topOfCenterPane, trim_left,
clientArea.height - trim_top), left.getCaches(), !left
.isVertical(), spacing);
arrange(new Rectangle(rightOfCenterPane, topOfCenterPane, trim_right,
clientArea.height - trim_top), right.getCaches(), !right
.isVertical(), spacing);
if (centerArea.getControl() != null) {
centerArea.getControl().setBounds(leftOfCenterPane,
topOfCenterPane, widthOfCenterPane, heightOfCenterPane);
}
}
/**
* Arranges all the given controls in a horizontal row that fills the given
* rectangle.
*
* @param area
* area to be filled by the controls
* @param caches
* a list of SizeCaches for controls that will span the rectangle
* @param horizontally
* how we are filling the rectangle
* @param spacing
* in pixels
*/
private static int arrange(Rectangle area, List caches,
boolean horizontally, int spacing) {
Point currentPosition = new Point(area.x, area.y);
List resizable = new ArrayList(caches.size());
List nonResizable = new ArrayList(caches.size());
TrimArea.filterResizable(caches, resizable, nonResizable, horizontally);
int[] sizes = new int[nonResizable.size()];
int idx = 0;
int used = 0;
int hint = Geometry.getDimension(area, !horizontally);
// Compute the sizes of non-resizable controls
Iterator iter = nonResizable.iterator();
while (iter.hasNext()) {
SizeCache next = (SizeCache) iter.next();
sizes[idx] = TrimArea.getSize(next, hint, horizontally);
used += sizes[idx];
idx++;
}
int available = Geometry.getDimension(area, horizontally) - used
- spacing * (caches.size() - 1);
idx = 0;
int remainingResizable = resizable.size();
iter = caches.iterator();
while (iter.hasNext()) {
SizeCache next = (SizeCache) iter.next();
if (next.getControl().isVisible()) {
int thisSize;
if (TrimArea.isResizable(next.getControl(), horizontally)) {
thisSize = available / remainingResizable;
available -= thisSize;
remainingResizable--;
} else {
thisSize = sizes[idx];
idx++;
}
if (TrimDragPreferences.showRaggedTrim()) {
Point prefSize = next.computeSize(SWT.DEFAULT, SWT.DEFAULT);
if (horizontally) {
// HACK!! Surgical Fix: Ideally the fix would handle 'wrapping' trim
// on any side. The following code is in place specifically to
// handle the CBanner's CoolBar wrapping. We need to pick up
// if the CoolBar wraps and uses extra height
// So we have to re-calc the value based on the actual trim height
// as laid out.
if (next.getControl() instanceof CBanner) {
prefSize = next.getControl().computeSize(thisSize, SWT.DEFAULT);
if (prefSize.y > hint)
hint = prefSize.y;
}
next.getControl().setBounds(currentPosition.x,
currentPosition.y, thisSize, prefSize.y);
currentPosition.x += thisSize + spacing;
} else {
next.getControl().setBounds(currentPosition.x,
currentPosition.y, prefSize.x, thisSize);
currentPosition.y += thisSize + spacing;
}
}
else {
if (horizontally) {
next.getControl().setBounds(currentPosition.x,
currentPosition.y, thisSize, hint);
currentPosition.x += thisSize + spacing;
} else {
next.getControl().setBounds(currentPosition.x,
currentPosition.y, hint, thisSize);
currentPosition.y += thisSize + spacing;
}
}
}
}
return hint;
}
/**
* Sets the widget that will occupy the central area of the layout.
* Typically, this will be a composite that contains the main widgetry of
* the application.
*
* @param center
* control that will occupy the center of the layout, or null if
* none
*/
public void setCenterControl(Control center) {
centerArea.setControl(center);
}
/**
* Returns the control in the center of this layout
*
* @return the center area control.
*/
public Control getCenterControl() {
return centerArea.getControl();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ICachingLayout#flush(org.eclipse.swt.widgets.Control)
*/
public void flush(Control dirtyControl) {
if (dirtyControl == centerArea.getControl()) {
centerArea.flush();
} else {
TrimDescriptor desc = findTrimDescription(dirtyControl);
if (desc != null) {
desc.flush();
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#getAreaIds()
*/
public int[] getAreaIds() {
return (int[]) TRIM_ID_INFO.clone();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#getAreaTrim(int)
*/
public List getAreaTrim(int areaId) {
TrimArea area = (TrimArea) fTrimArea.get(new Integer(areaId));
if (area == null) {
return Collections.EMPTY_LIST;
}
return area.getTrims();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#updateAreaTrim(int,
* java.util.List, boolean)
*/
public void updateAreaTrim(int id, List trim, boolean removeExtra) {
TrimArea area = (TrimArea) fTrimArea.get(new Integer(id));
if (area == null) {
return;
}
List current = area.getTrims();
// add back the trim ... this takes care of moving it
// from one trim area to another.
Iterator i = trim.iterator();
while (i.hasNext()) {
IWindowTrim t = (IWindowTrim) i.next();
t.dock(id); // Ensure that the trim is properly oriented
addTrim(id, t, null);
current.remove(t);
}
if (removeExtra) {
// if it wasn't removed from the current list, then it's extra
// trim we don't need.
i = current.iterator();
while (i.hasNext()) {
IWindowTrim t = (IWindowTrim) i.next();
removeTrim(t);
}
}
}
/**
* Return a trim area rectangle.
*
* @param window
* the window that has the trim
* @param areaId
* the side it's on
* @return the area rectangle.
* @since 3.2
* @see #getAreaIds()
*/
public Rectangle getTrimRect(Composite window, int areaId) {
Rectangle bb = window.getBounds();
Rectangle cr = window.getClientArea();
Rectangle tr = window.computeTrim(cr.x, cr.y, cr.width, cr.height);
// Place the Client Area 'within' its window
Geometry.moveRectangle(cr, new Point(bb.x - tr.x, bb.y - tr.y));
TrimArea top = (TrimArea) fTrimArea.get(TOP_ID);
TrimArea bottom = (TrimArea) fTrimArea.get(BOTTOM_ID);
TrimArea left = (TrimArea) fTrimArea.get(LEFT_ID);
TrimArea right = (TrimArea) fTrimArea.get(RIGHT_ID);
int trim_top = top.calculateTrimSize(cr.width, cr.height);
int trim_bottom = bottom.calculateTrimSize(cr.width, cr.height);
int trim_left = left.calculateTrimSize(cr.width, cr.height);
int trim_right = right.calculateTrimSize(cr.width, cr.height);
// Adjust the trim sizes to incorporate the margins for sides that
// don't currently have trim
if (trim_top == 0) {
trim_top = marginHeight;
}
if (trim_bottom == 0) {
trim_bottom = marginHeight;
}
if (trim_left == 0) {
trim_left = marginWidth;
}
if (trim_right == 0) {
trim_right = marginWidth;
}
Rectangle trimRect = new Rectangle(0, 0, 0, 0);
switch (areaId) {
case TOP:
trimRect.x = cr.x;
trimRect.width = cr.width;
trimRect.y = cr.y;
trimRect.height = trim_top;
break;
case BOTTOM:
trimRect.x = cr.x;
trimRect.width = cr.width;
trimRect.y = (cr.y + cr.height) - trim_bottom;
trimRect.height = trim_bottom;
break;
case LEFT:
trimRect.x = cr.x;
trimRect.width = trim_left;
trimRect.y = cr.y + trim_top;
trimRect.height = cr.height - (trim_top + trim_bottom);
break;
case RIGHT:
trimRect.x = (cr.x + cr.width) - trim_right;
trimRect.width = trim_right;
trimRect.y = cr.y + trim_top;
trimRect.height = cr.height - (trim_top + trim_bottom);
break;
}
return trimRect;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#getAllTrim()
*/
public List getAllTrim() {
List trimList = new ArrayList(fTrimDescriptors.size());
Iterator d = fTrimDescriptors.values().iterator();
while (d.hasNext()) {
TrimDescriptor desc = (TrimDescriptor) d.next();
trimList.add(desc.getTrim());
}
return trimList;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.layout.ITrimManager#setTrimVisible(org.eclipse.ui.internal.IWindowTrim,
* boolean)
*/
public void setTrimVisible(IWindowTrim trim, boolean visible) {
TrimDescriptor desc = findTrimDescription(trim.getControl());
if (desc != null) {
desc.setVisible(visible);
}
}
/**
* Find the trim descriptor for this control.
*
* @param trim
* the Control to find.
* @return the trim descriptor, or <code>null</code> if not found.
* @since 3.2
*/
private TrimDescriptor findTrimDescription(Control trim) {
Iterator d = fTrimDescriptors.values().iterator();
while (d.hasNext()) {
TrimDescriptor desc = (TrimDescriptor) d.next();
if (desc.getTrim().getControl() == trim) {
return desc;
}
if (desc.getDockingCache() != null
&& desc.getDockingCache().getControl() == trim) {
return desc;
}
}
return null;
}
/**
* Return the trim area associated with the given id
*
* @param areaId
* The id of the trim area to get
* @return The TrimArea or <code>null</code> if the id is not found
*/
public TrimArea getTrimArea(int areaId) {
return (TrimArea) fTrimArea.get(new Integer(areaId));
}
}