//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2011.04.21 at 02:35:28 PM CDT 
//

package org.eclipse.ptp.rm.jaxb.core.data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;

/**
 * <p>
 * Java class for fill-layout-type complex type.
 * 
 * <p>
 * The following schema fragment specifies the expected content contained within
 * this class.
 * 
 * <pre>
 * &lt;complexType name="fill-layout-type">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;attribute name="marginHeight" type="{http://www.w3.org/2001/XMLSchema}int" />
 *       &lt;attribute name="marginWidth" type="{http://www.w3.org/2001/XMLSchema}int" />
 *       &lt;attribute name="spacing" type="{http://www.w3.org/2001/XMLSchema}int" />
 *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "fill-layout-type")
public class FillLayoutType {

	@XmlAttribute
	protected Integer marginHeight;
	@XmlAttribute
	protected Integer marginWidth;
	@XmlAttribute
	protected Integer spacing;
	@XmlAttribute
	protected String type;

	/**
	 * Gets the value of the marginHeight property.
	 * 
	 * @return possible object is {@link Integer }
	 * 
	 */
	public Integer getMarginHeight() {
		return marginHeight;
	}

	/**
	 * Gets the value of the marginWidth property.
	 * 
	 * @return possible object is {@link Integer }
	 * 
	 */
	public Integer getMarginWidth() {
		return marginWidth;
	}

	/**
	 * Gets the value of the spacing property.
	 * 
	 * @return possible object is {@link Integer }
	 * 
	 */
	public Integer getSpacing() {
		return spacing;
	}

	/**
	 * Gets the value of the type property.
	 * 
	 * @return possible object is {@link String }
	 * 
	 */
	public String getType() {
		return type;
	}

	/**
	 * Sets the value of the marginHeight property.
	 * 
	 * @param value
	 *            allowed object is {@link Integer }
	 * 
	 */
	public void setMarginHeight(Integer value) {
		this.marginHeight = value;
	}

	/**
	 * Sets the value of the marginWidth property.
	 * 
	 * @param value
	 *            allowed object is {@link Integer }
	 * 
	 */
	public void setMarginWidth(Integer value) {
		this.marginWidth = value;
	}

	/**
	 * Sets the value of the spacing property.
	 * 
	 * @param value
	 *            allowed object is {@link Integer }
	 * 
	 */
	public void setSpacing(Integer value) {
		this.spacing = value;
	}

	/**
	 * Sets the value of the type property.
	 * 
	 * @param value
	 *            allowed object is {@link String }
	 * 
	 */
	public void setType(String value) {
		this.type = value;
	}

}
