getContents() {
+ return contents;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#getTotalMass()
+ */
+ @Override
+ public double getTotalMass() {
+ return GlobalParameters.getRoundedMass(super.getTotalMass() + getCargoMass());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#getTotalMass(edu.mit.spacenet.domain.ClassOfSupply)
+ */
+ @Override
+ public double getTotalMass(ClassOfSupply cos) {
+ double amount = super.getTotalMass(cos);
+
+ for(I_Resource resource : getContents().keySet()) {
+ if(resource.getClassOfSupply().isInstanceOf(cos)) {
+ amount += getContents().get(resource)*resource.getUnitMass();
+ }
+ }
+
+ return GlobalParameters.getRoundedMass(amount);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#print(int)
+ */
+ @Override
+ public void print(int tabOrder) {
+ super.print(tabOrder);
+ for(I_Resource r : contents.keySet()) {
+ r.print(tabOrder + 1);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#satisfyDemands(edu.mit.spacenet.domain.resource.DemandSet, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ @Override
+ public void satisfyDemands(DemandSet demands, I_Simulator simulator) {
+ super.satisfyDemands(demands, simulator);
+ for(Demand demand : demands) {
+ if(demand.getAmount() > 0) { // consumption
+ for(I_Resource resource : contents.keySet()) {
+ if(resource.isSubstitutableFor(demand.getResource())) {
+ if(demand.getAmount() >= contents.get(resource)) {
+ // don't consume science demands!
+ demand.setAmount(demand.getAmount() - contents.get(resource));
+ if(!demand.getResource().getClassOfSupply().isInstanceOf(ClassOfSupply.COS6))
+ contents.put(resource,0d);
+ } else {
+ // don't consume science demands!
+ if(!demand.getResource().getClassOfSupply().isInstanceOf(ClassOfSupply.COS6))
+ contents.put(resource, contents.get(resource)-demand.getAmount());
+ demand.setAmount(0);
+ break;
+ }
+ }
+ }
+ } else { // production
+ //TODO need to check for resource compatibility (e.g. water in water tanks)
+ boolean containsResource = false;
+ for(I_Resource resource : contents.keySet()) if(resource.equals(demand.getResource())) containsResource = true;
+ if(!containsResource) contents.put(demand.getResource(), 0d);
+ for(I_Resource resource : contents.keySet()) {
+ if(resource.equals(demand.getResource())) {
+ containsResource = true;
+ if(-demand.getAmount() > getMaxCargoMass() - getCargoMass()) {
+ demand.setAmount(demand.getAmount() + (getMaxCargoMass() - getCargoMass()));
+ contents.put(resource, contents.get(resource) + getMaxCargoMass() - getCargoMass());
+ } else {
+ contents.put(resource, contents.get(resource) + -demand.getAmount());
+ demand.setAmount(0);
+ }
+ }
+ }
+ }
+ }
+ demands.clean();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#getElementType()
+ */
+ @Override
+ public ElementType getElementType() {
+ return ElementType.RESOURCE_CONTAINER;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/element/ResourceContainerFactory.java b/src/main/java/edu/mit/spacenet/domain/element/ResourceContainerFactory.java
new file mode 100644
index 0000000..014ec9f
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/element/ResourceContainerFactory.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.element;
+
+import edu.mit.spacenet.domain.Environment;
+
+/**
+ * Class which is used to build the "default" resource containers used in
+ * auto-packing and auto-manifesting.
+ *
+ * @author Paul Grogan
+ */
+public abstract class ResourceContainerFactory {
+
+ /** The Constant DCTB_TID. */
+ public static final int DCTB_TID = -22;
+
+ /** The Constant DCTB_MAX_MASS. */
+ public static final double DCTB_MAX_MASS = 90.72;
+
+ /** The Constant DCTB_MAX_VOLUME. */
+ public static final double DCTB_MAX_VOLUME = 0.1058;
+
+ /**
+ * Creates a new double cargo transfer bag (DCTB).
+ *
+ * @return the cargo transfer bag
+ */
+ public static ResourceContainer createDCTB() {
+ // double cargo transfer bag
+ ResourceContainer ctb = new ResourceContainer();
+ ctb.setTid(DCTB_TID);
+ ctb.setMass(3.62);
+ ctb.setMaxCargoMass(DCTB_MAX_MASS);
+ ctb.setVolume(0.1058);
+ ctb.setMaxCargoVolume(DCTB_MAX_VOLUME);
+
+ ctb.setName("DCTB " + ctb.getUid());
+ return ctb;
+ }
+
+
+ /** The Constant CTB_TID. */
+ public static final int CTB_TID = -10;
+
+ /** The Constant CTB_MAX_MASS. */
+ public static final double CTB_MAX_MASS = 45.36;
+
+ /** The Constant CTB_MAX_VOLUME. */
+ public static final double CTB_MAX_VOLUME = 0.0529;
+
+ /**
+ * Creates a cargo transfer bag (CTB).
+ *
+ * @return the cargo transfer bag
+ */
+ public static ResourceContainer createCTB() {
+ // cargo transfer bag
+ ResourceContainer ctb = new ResourceContainer();
+ ctb.setTid(CTB_TID);
+ ctb.setMass(1.81);
+ ctb.setMaxCargoMass(CTB_MAX_MASS);
+ ctb.setVolume(0.0529);
+ ctb.setMaxCargoVolume(CTB_MAX_VOLUME);
+
+ ctb.setName("CTB " + ctb.getUid());
+ return ctb;
+ }
+
+ /** The Constant HCTB_TID. */
+ public static final int HCTB_TID = -11;
+
+ /** The Constant HCTB_MAX_MASS. */
+ public static final double HCTB_MAX_MASS = 27.22;
+
+ /** The Constant HCTB_MAX_VOLUME. */
+ public static final double HCTB_MAX_VOLUME = 0.0248;
+
+ /**
+ * Creates a half-size cargo transfer bag (CTB).
+ *
+ * @return the half cargo transfer bag
+ */
+ public static ResourceContainer createHCTB() {
+ // half cargo transfer bag
+ ResourceContainer ctb = new ResourceContainer();
+ ctb.setTid(HCTB_TID);
+ ctb.setMass(1);
+ ctb.setMaxCargoMass(HCTB_MAX_MASS);
+ ctb.setVolume(0.0248);
+ ctb.setMaxCargoVolume(HCTB_MAX_VOLUME);
+
+ ctb.setName("Half CTB " + ctb.getUid());
+ return ctb;
+ }
+
+ /** The Constant CWC_TID. */
+ public static final int CWC_TID = -12;
+
+ /**
+ * Creates a contingency water container (CWC).
+ *
+ * @return the contingency water container
+ */
+ public static ResourceContainer createCWC() {
+ // contingency water container
+ ResourceContainer cwc = new ResourceContainer();
+ cwc.setTid(CWC_TID);
+ cwc.setMass(1.361);
+ cwc.setMaxCargoMass(32.8);
+ cwc.setVolume(0.0328);
+ cwc.setMaxCargoVolume(0.0328);
+
+ cwc.setName("Contingency Water Container " + cwc.getUid());
+ return cwc;
+ }
+
+ /** The Constant LT_TID. */
+ public static final int LT_TID = -13;
+
+ /** The Constant LT_MAX_MASS. */
+ public static final double LT_MAX_MASS = 74.8;
+
+ /** The Constant LT_MAX_VOLUME. */
+ public static final double LT_MAX_VOLUME = 0.0748;
+
+ /**
+ * Creates a liquid tank (LT).
+ *
+ * @return the liquid tank
+ */
+ public static ResourceContainer createLT() {
+ // liquid tank
+ ResourceContainer lt = new ResourceContainer();
+ lt.setTid(LT_TID);
+ lt.setMass(34.37);
+ lt.setMaxCargoMass(LT_MAX_MASS);
+ lt.setVolume(0.0748);
+ lt.setMaxCargoVolume(LT_MAX_VOLUME);
+
+ lt.setName("Liquid Tank " + lt.getUid());
+ return lt;
+ }
+
+ /** The Constant LTD_TID. */
+ public static final int LTD_TID = -14;
+
+ /** The Constant LTD_MAX_MASS. */
+ public static final double LTD_MAX_MASS = 24.9333;
+
+ /** The Constant LTD_MAX_VOLUME. */
+ public static final double LTD_MAX_VOLUME = 0.0249;
+
+ /**
+ * Creates a derivative liquid tank (LT).
+ *
+ * @return the liquid tank
+ */
+ public static ResourceContainer createLTD() {
+ // liquid tank derivative
+ ResourceContainer ltd = new ResourceContainer();
+ ltd.setTid(LTD_TID);
+ ltd.setMass(11.4567);
+ ltd.setMaxCargoMass(LTD_MAX_MASS);
+ ltd.setVolume(0.0249);
+ ltd.setMaxCargoVolume(LTD_MAX_VOLUME);
+
+ ltd.setName("Liquid Tank Derivative " + ltd.getUid());
+ return ltd;
+ }
+
+ /** The Constant SHOSS_TID. */
+ public static final int SHOSS_TID = -15;
+
+ /** The Constant SHOSS_MAX_MASS. */
+ public static final double SHOSS_MAX_MASS = 200;
+
+ /** The Constant SHOSS_MAX_VOLUME. */
+ public static final double SHOSS_MAX_VOLUME = 0.4444;
+
+ /**
+ * Creates a SHOSS box.
+ *
+ * @return the SHOSS box
+ */
+ public static ResourceContainer createShoss() {
+ // shoss box
+ ResourceContainer shoss = new ResourceContainer();
+ shoss.setTid(SHOSS_TID);
+ shoss.setMass(120);
+ shoss.setMaxCargoMass(SHOSS_MAX_MASS);
+ shoss.setVolume(0.4444);
+ shoss.setMaxCargoVolume(SHOSS_MAX_VOLUME);
+
+ shoss.setName("Shoss " + shoss.getUid());
+ return shoss;
+ }
+
+ /** The Constant PSHOSS_TID. */
+ public static final int PSHOSS_TID = -16;
+
+ /** The Constant PSHOSS_MAX_MASS. */
+ public static final double PSHOSS_MAX_MASS = 200;
+
+ /** The Constant PSHOSS_MAX_VOLUME. */
+ public static final double PSHOSS_MAX_VOLUME = 0.8;
+
+ /**
+ * Creates a pressurized SHOSS box.
+ *
+ * @return the pressurized SHOSS box
+ */
+ public static ResourceContainer createPressShoss() {
+ // pressurized shoss box
+ ResourceContainer pshoss = new ResourceContainer();
+ pshoss.setTid(PSHOSS_TID);
+ pshoss.setMass(0);
+ pshoss.setMaxCargoMass(PSHOSS_MAX_MASS);
+ pshoss.setVolume(0.8);
+ pshoss.setMaxCargoVolume(PSHOSS_MAX_VOLUME);
+
+ pshoss.setName("Press. Shoss " + pshoss.getUid());
+ pshoss.setCargoEnvironment(Environment.PRESSURIZED);
+ return pshoss;
+ }
+
+ /** The Constant GT_TID. */
+ public static final int GT_TID = -17;
+
+ /** The Constant GT_MAX_MASS. */
+ public static final double GT_MAX_MASS = 100;
+
+ /** The Constant GT_MAX_VOLUME. */
+ public static final double GT_MAX_VOLUME = 2.75;
+
+ /**
+ * Creates a gas tank (GT).
+ *
+ * @return the gas tank
+ */
+ public static ResourceContainer createGT() {
+ // gas tank
+ ResourceContainer gt = new ResourceContainer();
+ gt.setTid(GT_TID);
+ gt.setMass(108);
+ gt.setMaxCargoMass(GT_MAX_MASS);
+ gt.setVolume(2.75);
+ gt.setMaxCargoVolume(GT_MAX_VOLUME);
+
+ gt.setName("Gas Tank " + gt.getUid());
+ return gt;
+ }
+
+ /** The Constant GTD_TID. */
+ public static final int GTD_TID = -17;
+
+ /** The Constant GTD_MAX_MASS. */
+ public static final double GTD_MAX_MASS = 10;
+
+ /** The Constant GTD_MAX_VOLUME. */
+ public static final double GTD_MAX_VOLUME = 0.275;
+
+ /**
+ * Creates a derivative gas tank (GT).
+ *
+ * @return the derivative gas tank
+ */
+ public static ResourceContainer createGTD() {
+ // gas tank derivative
+ ResourceContainer gtd = new ResourceContainer();
+ gtd.setTid(GTD_TID);
+ gtd.setMass(10.8);
+ gtd.setMaxCargoMass(GTD_MAX_MASS);
+ gtd.setVolume(0.275);
+ gtd.setMaxCargoVolume(GTD_MAX_VOLUME);
+
+ gtd.setName("Gas Tank Derivative " + gtd.getUid());
+ return gtd;
+ }
+
+ /** The Constant O2T_TID. */
+ public static final int O2T_TID = -18;
+
+ /**
+ * Creates an oxygen tank (O2T).
+ *
+ * @return the oxygen tank
+ */
+ public static ResourceContainer createO2T() {
+ // oxygen tank
+ ResourceContainer o2t = new ResourceContainer();
+ o2t.setTid(O2T_TID);
+ o2t.setMass(108);
+ o2t.setMaxCargoMass(108.9);
+ o2t.setVolume(2.75);
+ o2t.setMaxCargoVolume(2.275);
+
+ o2t.setName("O2 Tank " + o2t.getUid());
+ return o2t;
+ }
+
+ /** The Constant O2TD_TID. */
+ public static final int O2TD_TID = -19;
+
+ /**
+ * Creates a derivative oxygen tank (O2T).
+ *
+ * @return the derivative oxygen tank
+ */
+ public static ResourceContainer createO2TD() {
+ // oxygen tank derivative
+ ResourceContainer o2td = new ResourceContainer();
+ o2td.setTid(O2TD_TID);
+ o2td.setMass(10.8);
+ o2td.setMaxCargoMass(10.89);
+ o2td.setVolume(0.275);
+ o2td.setMaxCargoVolume(0.275);
+
+ o2td.setName("O2 Tank Derivative " + o2td.getUid());
+ return o2td;
+ }
+
+ /** The Constant N2T_TID. */
+ public static final int N2T_TID = -20;
+
+ /**
+ * Creats a nitrogen tank (N2T).
+ *
+ * @return the nitrogen tank
+ */
+ public static ResourceContainer createN2T() {
+ // nitrogen tank
+ ResourceContainer n2t = new ResourceContainer();
+ n2t.setTid(N2T_TID);
+ n2t.setMass(108);
+ n2t.setMaxCargoMass(94.8);
+ n2t.setVolume(2.732);
+ n2t.setMaxCargoVolume(2.732);
+
+ n2t.setName("N2 Tank " + n2t.getUid());
+ return n2t;
+ }
+
+ /** The Constant N2TD_TID. */
+ public static final int N2TD_TID = -21;
+
+ /**
+ * Creates a derivative nitrogen tank (N2T).
+ *
+ * @return the derivative nitrogen tank
+ */
+ public static ResourceContainer createN2TD() {
+ // nitrogen tank derivative
+ ResourceContainer n2td = new ResourceContainer();
+ n2td.setTid(N2TD_TID);
+ n2td.setMass(10.8);
+ n2td.setMaxCargoMass(9.48);
+ n2td.setVolume(0.2732);
+ n2td.setMaxCargoVolume(0.2732);
+
+ n2td.setName("N2 Tank Derivative " + n2td.getUid());
+ return n2td;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/element/ResourceTank.java b/src/main/java/edu/mit/spacenet/domain/element/ResourceTank.java
new file mode 100644
index 0000000..0b8ebd8
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/element/ResourceTank.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.element;
+
+
+import java.text.DecimalFormat;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.Environment;
+import edu.mit.spacenet.domain.resource.Demand;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.domain.resource.I_Resource;
+import edu.mit.spacenet.simulator.I_Simulator;
+import edu.mit.spacenet.util.GlobalParameters;
+
+/**
+ * An element that can hold at most one type of continuous resource up to a
+ * capacity constraint.A resource tank is assigned a resource (which
+ * itself has a unit mass which could be non-zero depending on the units for
+ * which consumption is measured by), a current amount, and a maximum amount.
+ *
+ * @author Paul Grogan
+ */
+public class ResourceTank extends Element implements I_ResourceContainer {
+ private I_Resource resource;
+ private double amount;
+ private double maxAmount;
+
+ /**
+ * The default constructor.
+ */
+ public ResourceTank() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#canAdd(edu.mit.spacenet.domain.resource.I_Resource, double)
+ */
+ public boolean canAdd(I_Resource resource, double amount) {
+ if(this.resource!=null && !this.resource.equals(resource)) return false;
+ else if(this.amount + amount - maxAmount > GlobalParameters.getDemandPrecision()/2d) return false;
+ else return true;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#add(edu.mit.spacenet.domain.resource.I_Resource, double)
+ */
+ public boolean add(I_Resource resource, double amount) {
+ if(canAdd(resource, amount)) {
+ if(this.resource==null) {
+ this.resource = resource;
+ }
+ this.amount += amount;
+ return true;
+ } else return false;
+ }
+
+ /**
+ * Adds an amount of resource to the tank.
+ *
+ * @param amount the amount
+ *
+ * @return true, if successful
+ */
+ public boolean add(double amount) {
+ return add(resource, amount);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#remove(edu.mit.spacenet.domain.resource.I_Resource, double)
+ */
+ public boolean remove(I_Resource resource, double amount) {
+ if(this.resource==null
+ || !this.resource.equals(resource)) {
+ return false;
+ } else if(this.amount - amount >= 0) {
+ this.amount = this.amount - amount;
+ return true;
+ } else return false;
+ }
+
+ /**
+ * Removes an amount of a resource from the tank.
+ *
+ * @param amount the amount
+ *
+ * @return true, if successful
+ */
+ public boolean remove(double amount) {
+ return remove(resource, amount);
+ }
+
+ /**
+ * Gets the contained resource.
+ *
+ * @return the contained resource
+ */
+ public I_Resource getResource() {
+ return resource;
+ }
+
+ /**
+ * Sets the contained resource.
+ *
+ * @param resource the contained resource
+ */
+ public void setResource(I_Resource resource) {
+ this.resource = resource;
+ }
+
+ /**
+ * Gets the amount of the contained resource.
+ *
+ * @return the amount of resource (units of resource consumption)
+ */
+ public double getAmount() {
+ return GlobalParameters.getRoundedDemand(amount);
+ }
+
+ /**
+ * Sets the amount of the contained resource.
+ *
+ * @param amount the amount of resource (units of resource consumption)
+ */
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+
+ /**
+ * Gets the maximum amount of the contained resource.
+ *
+ * @return the maximum amount of resource (units of resource consumption)
+ */
+ public double getMaxAmount() {
+ return GlobalParameters.getRoundedDemand(maxAmount);
+ }
+
+ /**
+ * Sets the maximum amount of the contained resource.
+ *
+ * @param maxAmount the maximum amount of resource (units of resource
+ * consumption)
+ */
+ public void setMaxAmount(double maxAmount) {
+ this.maxAmount = maxAmount;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#getTotalMass()
+ */
+ @Override
+ public double getTotalMass() {
+ return GlobalParameters.getRoundedMass(super.getTotalMass() + getCargoMass());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#getTotalMass(edu.mit.spacenet.domain.ClassOfSupply)
+ */
+ public double getTotalMass(ClassOfSupply cos) {
+ double mass = super.getTotalMass(cos);
+ if(resource!=null && getResource().getClassOfSupply().isInstanceOf(cos)) {
+ mass += getResource().getUnitMass()*getAmount();
+ }
+ return GlobalParameters.getRoundedMass(mass);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#toString()
+ */
+ public String toString() {
+ DecimalFormat format = new DecimalFormat("0.0");
+ if(resource==null)
+ return super.toString() + " (" + format.format(getAmount()) + " / "
+ + format.format(getMaxAmount()) + ")";
+ else
+ return super.toString() + " (" + format.format(getAmount()) + " / "
+ + format.format(getMaxAmount()) + " " + resource.getUnits()
+ + " " + resource + ")";
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#print(int)
+ */
+ @Override
+ public void print(int tabOrder) {
+ super.print(tabOrder);
+ resource.print(tabOrder+1);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#satisfyDemands(edu.mit.spacenet.domain.resource.DemandSet, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ @Override
+ public void satisfyDemands(DemandSet demands, I_Simulator simulator) {
+ super.satisfyDemands(demands, simulator);
+ for(Demand demand : demands) {
+ if(demand.getResource().isSubstitutableFor(resource)) {
+ if(demand.getAmount() > 0) { // consumption
+ if(demand.getAmount() > amount) {
+ demand.setAmount(demand.getAmount() - amount);
+ amount = 0;
+ } else {
+ amount -= demand.getAmount();
+ demand.setAmount(0);
+ }
+ } else { // production
+ if(-demand.getAmount() > maxAmount - amount) {
+ demand.setAmount(demand.getAmount() + (maxAmount - amount));
+ amount = maxAmount;
+ } else {
+ amount += -demand.getAmount();
+ demand.setAmount(0);
+ }
+ }
+ }
+ }
+ demands.clean();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#getCargoEnvironment()
+ */
+ public Environment getCargoEnvironment() {
+ return Environment.UNPRESSURIZED;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#getCargoMass()
+ */
+ public double getCargoMass() {
+ return resource==null?0:GlobalParameters.getRoundedMass(amount*resource.getUnitMass());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#getCargoVolume()
+ */
+ public double getCargoVolume() {
+ return resource==null?0:GlobalParameters.getRoundedVolume(amount*resource.getUnitVolume());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#getMaxCargoMass()
+ */
+ public double getMaxCargoMass() {
+ return resource==null?0:GlobalParameters.getRoundedMass(maxAmount*resource.getUnitMass());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#getMaxCargoVolume()
+ */
+ public double getMaxCargoVolume() {
+ return resource==null?0:GlobalParameters.getRoundedVolume(maxAmount*resource.getUnitVolume());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#setCargoEnvironment(edu.mit.spacenet.domain.Environment)
+ */
+ public void setCargoEnvironment(Environment cargoEnvironment) { }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#setMaxCargoMass(double)
+ */
+ public void setMaxCargoMass(double maxCargoMass) {
+ if(resource!=null) {
+ maxAmount=maxCargoMass/resource.getUnitMass();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#setMaxCargoVolume(double)
+ */
+ public void setMaxCargoVolume(double maxCargoVolume) {
+ if(resource!=null) {
+ maxAmount=maxCargoVolume/resource.getUnitVolume();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_ResourceContainer#getContents()
+ */
+ public SortedMap getContents() {
+ TreeMap contents = new TreeMap();
+ contents.put(resource, amount);
+ return contents;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Element#getElementType()
+ */
+ @Override
+ public ElementType getElementType() {
+ return ElementType.RESOURCE_TANK;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/element/State.java b/src/main/java/edu/mit/spacenet/domain/element/State.java
new file mode 100644
index 0000000..d000c55
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/element/State.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.element;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import edu.mit.spacenet.domain.DomainType;
+import edu.mit.spacenet.domain.model.I_DemandModel;
+import edu.mit.spacenet.domain.resource.Demand;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.simulator.I_Simulator;
+
+/**
+ * Class that defines an operational state of an element. An operational state
+ * is composed of a state type, one or more demand models, and an overall duty
+ * cycle.
+ *
+ * @author Paul Grogan
+ */
+public class State extends DomainType implements I_State {
+ private StateType stateType;
+ private SortedSet demandModels;
+
+ /**
+ * The default constructor sets the default values for name to Default,
+ * state type to ACTIVE, and duty cycle to 1. It also initializes the set of
+ * demand models, but does not add any.
+ */
+ public State() {
+ super();
+ setName("Default");
+ setStateType(StateType.ACTIVE);
+ this.demandModels = new TreeSet();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_State#getStateType()
+ */
+ public StateType getStateType() {
+ return stateType;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_State#setStateType(edu.mit.spacenet.domain.element.StateType)
+ */
+ public void setStateType(StateType stateType) {
+ this.stateType = stateType;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_State#getDemandModels()
+ */
+ public SortedSet getDemandModels() {
+ return demandModels;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_State#setDemandModels(java.util.SortedSet)
+ */
+ public void setDemandModels(SortedSet demandModels) {
+ this.demandModels = demandModels;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.I_State#generateDemands(double, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ public DemandSet generateDemands(double duration, I_Simulator simulator) {
+ DemandSet demands = new DemandSet();
+ for(I_DemandModel model : demandModels) {
+ for(Demand demand : model.generateDemands(duration, simulator)) {
+ demands.add(demand);
+ }
+ }
+ return demands;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(I_State state) {
+ if(getStateType().equals(state.getStateType())){
+ if(getName().equals(state.getName())) {
+ return new Integer(getTid()).compareTo(new Integer(state.getTid()));
+ } else {
+ return getName().compareTo(state.getName());
+ }
+ } else {
+ return getStateType().compareTo(state.getStateType());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#toString()
+ */
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/element/StateType.java b/src/main/java/edu/mit/spacenet/domain/element/StateType.java
new file mode 100644
index 0000000..603bf71
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/element/StateType.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.element;
+
+import javax.swing.ImageIcon;
+
+/**
+ * Enumeration that defines the four operational states for elements.
+ *
+ * @author Paul Grogan
+ */
+public enum StateType {
+
+ /** The active state type is used for states where the element is in a typical or nominal active condition. */
+ ACTIVE("Active", "icons/clock_play.png"),
+
+ /** The special state type is used for states where the element is in a special active condition. */
+ SPECIAL("Special", "icons/clock_add.png"),
+
+ /** The quiescent state type is used for states where the element is only operational part of the time (duty cycle < 1). */
+ QUIESCENT("Quiescent", "icons/clock_pause.png"),
+
+ /** The dormant state type is used for states where the element is operational for a small percentage of the time (duty cycle << 1). */
+ DORMANT("Dormant", "icons/clock_stop.png"),
+
+ /** The decommissioned state type is used for states where the element is not operational and will not become operational in the future. This state type is reserved for cannibalization of spare parts. */
+ DECOMMISSIONED("Decommissioned", "icons/clock_red.png");
+
+ private String name;
+ private ImageIcon icon;
+
+ private StateType(String name, String iconUrl) {
+ this.name = name;
+ this.icon = new ImageIcon(getClass().getClassLoader().getResource(iconUrl));
+ }
+
+ /**
+ * Gets the textual representation of the state type.
+ *
+ * @return the state type name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Enum#toString()
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Gets the icon representation of the state type.
+ *
+ * @return the state type icon
+ */
+ public ImageIcon getIcon() {
+ return icon;
+ }
+
+ /**
+ * Method to get a particular instance of a state type based on a
+ * case-insensitive string.
+ *
+ * @param name case-insensitive string of name
+ *
+ * @return the state type, returns null if unmatched
+ */
+ public static StateType getInstance(String name) {
+ for(StateType t : values()) {
+ if(t.getName().toLowerCase().equals(name.toLowerCase()))
+ return t;
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/element/SurfaceVehicle.java b/src/main/java/edu/mit/spacenet/domain/element/SurfaceVehicle.java
new file mode 100644
index 0000000..042644b
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/element/SurfaceVehicle.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.element;
+
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.simulator.I_Simulator;
+import edu.mit.spacenet.util.GlobalParameters;
+
+/**
+ * A vehicle with an assigned maximum speed and a resource container to
+ * represent a fuel tank. Note that unlike a propulsive vehicle, consumption of
+ * fuel should be handled by a demand model rather than through impulsive burns.
+ *
+ * @author Paul Grogan
+ */
+public class SurfaceVehicle extends Carrier {
+ private double maxSpeed;
+ private ResourceTank fuelTank;
+
+ /**
+ * The default constructor that initializes the fuel tank.
+ */
+ public SurfaceVehicle() {
+ super();
+ fuelTank = new ResourceTank();
+ fuelTank.setName(getName() + " Fuel Tank");
+ fuelTank.setContainer(this);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#setName(java.lang.String)
+ */
+ @Override
+ public void setName(String name) {
+ super.setName(name);
+ if(fuelTank!=null)
+ fuelTank.setName(getName() + " Fuel Tank");
+ }
+
+ /**
+ * Gets the maximum speed.
+ *
+ * @return the maximum speed (kilometers per hour)
+ */
+ public double getMaxSpeed() {
+ return maxSpeed;
+ }
+
+ /**
+ * Sets the maximum speed.
+ *
+ * @param maxSpeed the maximum speed (kilometers per hour)
+ */
+ public void setMaxSpeed(double maxSpeed) {
+ this.maxSpeed = maxSpeed;
+ }
+
+ /**
+ * Gets the fuel tank resource container.
+ *
+ * @return the fuel tank resource container
+ */
+ public ResourceTank getFuelTank() {
+ return fuelTank;
+ }
+
+ /**
+ * Sets the fuel tank resource container.
+ *
+ * @param fuelTank the fuel tank resource container
+ */
+ public void setFuelTank(ResourceTank fuelTank) {
+ this.fuelTank = fuelTank;
+ if(fuelTank!=null) {
+ fuelTank.setName(getName() + " Fuel Tank");
+ fuelTank.setContainer(this);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Carrier#getTotalMass()
+ */
+ @Override
+ public double getTotalMass() {
+ return GlobalParameters.getRoundedMass(super.getTotalMass() + fuelTank.getTotalMass());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Carrier#getTotalMass(edu.mit.spacenet.domain.ClassOfSupply)
+ */
+ @Override
+ public double getTotalMass(ClassOfSupply cos) {
+ double amount = super.getTotalMass(cos);
+ if(getFuelTank()!=null) amount += getFuelTank().getTotalMass(cos);
+ return GlobalParameters.getRoundedMass(amount);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Carrier#print(int)
+ */
+ @Override
+ public void print(int tabOrder) {
+ super.print(tabOrder);
+ fuelTank.print(tabOrder+1);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Carrier#satisfyDemands(edu.mit.spacenet.domain.resource.DemandSet, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ @Override
+ public void satisfyDemands(DemandSet demands, I_Simulator simulator) {
+ fuelTank.satisfyDemands(demands, simulator);
+ super.satisfyDemands(demands, simulator);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.element.Carrier#getElementType()
+ */
+ @Override
+ public ElementType getElementType() {
+ return ElementType.SURFACE_VEHICLE;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/model/AbstractDemandModel.java b/src/main/java/edu/mit/spacenet/domain/model/AbstractDemandModel.java
new file mode 100644
index 0000000..922972a
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/AbstractDemandModel.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+import edu.mit.spacenet.domain.DomainType;
+
+/**
+ * Base class for all demand models.
+ *
+ * @author Paul Grogan
+ */
+public abstract class AbstractDemandModel extends DomainType implements I_DemandModel {
+
+ /**
+ * The default constructor that sets a default name.
+ */
+ public AbstractDemandModel() {
+ setName(getDemandModelType().getName());
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(I_DemandModel demandModel) {
+ if(getName().equals(demandModel.getName())) {
+ return new Integer(getTid()).compareTo(new Integer(demandModel.getTid()));
+ } else {
+ return getName().compareTo(demandModel.getName());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/model/CrewConsumablesDemandModel.java b/src/main/java/edu/mit/spacenet/domain/model/CrewConsumablesDemandModel.java
new file mode 100644
index 0000000..67730ff
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/CrewConsumablesDemandModel.java
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.resource.Demand;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.domain.resource.GenericResource;
+import edu.mit.spacenet.scenario.Mission;
+import edu.mit.spacenet.simulator.I_Simulator;
+
+/**
+ * A mission-level demand model that estimates the resources needed to sustain
+ * a crew during a mission.
+ */
+public class CrewConsumablesDemandModel extends AbstractDemandModel {
+ private Mission mission;
+
+ private double reservesDuration, waterRecoveryRate, clothingLifetime;
+ private boolean transitDemandsOmitted;
+ private double waterRate, evaWaterRate, foodSupportRate, ambientFoodRate,
+ rfFoodRate, oxygenRate, evaOxygenRate, nitrogenRate, hygieneRate,
+ hygieneKit, clothingRate, personalItems;
+ private double officeEquipment, evaSuit, evaLithiumHydroxide,
+ healthEquipment, healthConsumables, safetyEquipment, commEquipment,
+ computerEquipment;
+ private double trashBagRate, wasteContainmentRate;
+
+ /**
+ * Instantiates a new crew consumables demand model.
+ *
+ * @param mission the mission for which to generate demands
+ */
+ public CrewConsumablesDemandModel(Mission mission) {
+ super();
+ this.mission = mission;
+ setReservesDuration(0);
+ setWaterRecoveryRate(0.42);
+ setClothingLifetime(4);
+ resetDefaultRates();
+ }
+
+ public CrewConsumablesDemandModel() {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Reset all rates to default values (based on SpaceNet 1.3).
+ */
+ public void resetDefaultRates() {
+ setWaterRate(3.6);
+ setEvaWaterRate(0.6875);
+ setFoodSupportRate(0.05556);
+ setAmbientFoodRate(0.76389);
+ setRfFoodRate(1.61667);
+ setOxygenRate(3.85714);
+ setEvaOxygenRate(0.07875);
+ setNitrogenRate(2.21429);
+ setHygieneRate(0.27778);
+ setHygieneKit(1.8);
+ setClothingRate(2.3);
+ setPersonalItems(10);
+
+ setOfficeEquipment(5);
+ setEvaSuit(107);
+ setEvaLithiumHydroxide(0.3625);
+ setHealthEquipment(20);
+ setHealthConsumables(0.1);
+ setSafetyEquipment(25);
+ setCommEquipment(20);
+ setComputerEquipment(5);
+
+ setTrashBagRate(0.05);
+ setWasteContainmentRate(0.05);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#generateDemands(double, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ public DemandSet generateDemands(double duration, I_Simulator simulator) {
+ DemandSet demands = new DemandSet();
+
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS201),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getWaterRate()*getMissionCrewSize()*(1-getWaterRecoveryRate())));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS201),
+ getMissionEvaCrewTime()*getEvaWaterRate()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS202),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getFoodSupportRate()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS202),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getAmbientFoodRate()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS202),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getRfFoodRate()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS203),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getOxygenRate()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS203),
+ getMissionEvaCrewTime()*getEvaOxygenRate()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS203),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getNitrogenRate()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS204),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getHygieneRate()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS204),
+ getHygieneKit()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS205),
+ (getMissionExplorationDuration()+getMissionTransitDuration())*getClothingRate()*getMissionCrewSize()/getClothingLifetime()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS206),
+ getPersonalItems()*getMissionCrewSize()));
+
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS301),
+ getOfficeEquipment()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS302),
+ getEvaSuit()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS302),
+ getEvaLithiumHydroxide()*getMissionEvaCrewTime()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS303),
+ getHealthEquipment()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS303),
+ getHealthConsumables()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS304),
+ getSafetyEquipment()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS305),
+ getCommEquipment()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS306),
+ getComputerEquipment()*getMissionCrewSize()));
+
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS701),
+ (getMissionExplorationDuration()+getMissionTransitDuration())*getTrashBagRate()*getMissionCrewSize()));
+ demands.add(new Demand(new GenericResource(ClassOfSupply.COS702),
+ (getMissionExplorationDuration()+getMissionTransitDuration()+getReservesDuration())*getWasteContainmentRate()*getMissionCrewSize()));
+ return demands;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#getDemandModelType()
+ */
+ public DemandModelType getDemandModelType() {
+ return DemandModelType.CREW_CONSUMABLES;
+ }
+
+ /**
+ * Gets the mission crew size.
+ *
+ * @return the crew size
+ */
+ public int getMissionCrewSize() {
+ return mission.getCrewSize();
+ }
+
+ /**
+ * Gets the mission EVA crew time.
+ *
+ * @return the mission EVA crew time (crew-hour)
+ */
+ public double getMissionEvaCrewTime() {
+ return mission.getEvaCrewTime();
+ }
+
+ /**
+ * Gets the mission exploration duration.
+ *
+ * @return the exploration duration (days)
+ */
+ public double getMissionExplorationDuration() {
+ return mission.getDestinationDuration();
+ }
+
+ /**
+ * Gets the mission transit duration.
+ *
+ * @return the mission transit duration (days)
+ */
+ public double getMissionTransitDuration() {
+ if(isTransitDemandsOmitted()) {
+ return 0;
+ } else {
+ return mission.getTransitDuration() + mission.getReturnTransitDuration();
+ }
+ }
+
+ /**
+ * Gets the reserves duration.
+ *
+ * @return the reserves duration (days)
+ */
+ public double getReservesDuration() {
+ return reservesDuration;
+ }
+
+ /**
+ * Sets the reserves duration.
+ *
+ * @param reservesDuration the new reserves duration (days)
+ */
+ public void setReservesDuration(double reservesDuration) {
+ this.reservesDuration = reservesDuration;
+ }
+
+ /**
+ * Gets the water recovery rate.
+ *
+ * @return the water recovery rate ([0:1])
+ */
+ public double getWaterRecoveryRate() {
+ return waterRecoveryRate;
+ }
+
+ /**
+ * Sets the water recovery rate.
+ *
+ * @param waterRecoveryRate the new water recovery rate ([0:1])
+ */
+ public void setWaterRecoveryRate(double waterRecoveryRate) {
+ this.waterRecoveryRate = Math.max(0,Math.min(waterRecoveryRate,1));
+ }
+
+ /**
+ * Gets the EVA water rate.
+ *
+ * @return the EVA water rate (kilograms/crew/hour)
+ */
+ public double getEvaWaterRate() {
+ return evaWaterRate;
+ }
+
+ /**
+ * Sets the EVA water rate.
+ *
+ * @param evaWaterRate the new EVA water rate (kilograms/crew/hour)
+ */
+ public void setEvaWaterRate(double evaWaterRate) {
+ this.evaWaterRate = evaWaterRate;
+ }
+
+ /**
+ * Gets the clothing lifetime.
+ *
+ * @return the clothing lifetime (days)
+ */
+ public double getClothingLifetime() {
+ return clothingLifetime;
+ }
+
+ /**
+ * Sets the clothing lifetime (minimum 1 day).
+ *
+ * @param clothingLifetime the new clothing lifetime (days)
+ */
+ public void setClothingLifetime(double clothingLifetime) {
+ this.clothingLifetime = Math.max(1, clothingLifetime);
+ }
+
+ /**
+ * Gets the water rate.
+ *
+ * @return the water rate (kilograms/crew/day)
+ */
+ public double getWaterRate() {
+ return waterRate;
+ }
+
+ /**
+ * Sets the water rate.
+ *
+ * @param waterRate the new water rate (kilograms/crew/day)
+ */
+ public void setWaterRate(double waterRate) {
+ this.waterRate = waterRate;
+ }
+
+ /**
+ * Gets the food support rate.
+ *
+ * @return the food support rate (kilograms/crew/day)
+ */
+ public double getFoodSupportRate() {
+ return foodSupportRate;
+ }
+
+ /**
+ * Sets the food support rate.
+ *
+ * @param foodSupportRate the new food support rate (kilograms/crew/day)
+ */
+ public void setFoodSupportRate(double foodSupportRate) {
+ this.foodSupportRate = foodSupportRate;
+ }
+
+ /**
+ * Gets the ambient food rate.
+ *
+ * @return the ambient food rate (kilograms/crew/day)
+ */
+ public double getAmbientFoodRate() {
+ return ambientFoodRate;
+ }
+
+ /**
+ * Sets the ambient food rate.
+ *
+ * @param ambientFoodRate the new ambient food rate (kilograms/crew/day)
+ */
+ public void setAmbientFoodRate(double ambientFoodRate) {
+ this.ambientFoodRate = ambientFoodRate;
+ }
+
+ /**
+ * Gets the R/F food rate.
+ *
+ * @return the R/F food rate (kilograms/crew/day)
+ */
+ public double getRfFoodRate() {
+ return rfFoodRate;
+ }
+
+ /**
+ * Sets the R/F food rate.
+ *
+ * @param rfFoodRate the new R/F food rate (kilograms/crew/day)
+ */
+ public void setRfFoodRate(double rfFoodRate) {
+ this.rfFoodRate = rfFoodRate;
+ }
+
+ /**
+ * Gets the oxygen rate.
+ *
+ * @return the oxygen rate (kilograms/crew/day)
+ */
+ public double getOxygenRate() {
+ return oxygenRate;
+ }
+
+ /**
+ * Sets the oxygen rate.
+ *
+ * @param oxygenRate the new oxygen rate (kilograms/crew/day)
+ */
+ public void setOxygenRate(double oxygenRate) {
+ this.oxygenRate = oxygenRate;
+ }
+
+ /**
+ * Gets the EVA oxygen rate.
+ *
+ * @return the EVA oxygen rate (kilograms/crew/hour)
+ */
+ public double getEvaOxygenRate() {
+ return evaOxygenRate;
+ }
+
+ /**
+ * Sets the EVA oxygen rate.
+ *
+ * @param evaOxygenRate the new EVA oxygen rate (kilograms/crew/hour)
+ */
+ public void setEvaOxygenRate(double evaOxygenRate) {
+ this.evaOxygenRate = evaOxygenRate;
+ }
+
+ /**
+ * Gets the nitrogen rate.
+ *
+ * @return the nitrogen rate (kilograms/crew/day)
+ */
+ public double getNitrogenRate() {
+ return nitrogenRate;
+ }
+
+ /**
+ * Sets the nitrogen rate.
+ *
+ * @param nitrogenRate the new nitrogen rate (kilograms/crew/day)
+ */
+ public void setNitrogenRate(double nitrogenRate) {
+ this.nitrogenRate = nitrogenRate;
+ }
+
+ /**
+ * Gets the hygiene rate.
+ *
+ * @return the hygiene rate (kilograms/crew/day)
+ */
+ public double getHygieneRate() {
+ return hygieneRate;
+ }
+
+ /**
+ * Sets the hygiene rate.
+ *
+ * @param hygieneRate the new hygiene rate (kilograms/crew/day)
+ */
+ public void setHygieneRate(double hygieneRate) {
+ this.hygieneRate = hygieneRate;
+ }
+
+ /**
+ * Gets the hygiene kit.
+ *
+ * @return the hygiene kit (kilograms/crew)
+ */
+ public double getHygieneKit() {
+ return hygieneKit;
+ }
+
+ /**
+ * Sets the hygiene kit.
+ *
+ * @param hygieneKit the new hygiene kit (kilograms/crew)
+ */
+ public void setHygieneKit(double hygieneKit) {
+ this.hygieneKit = hygieneKit;
+ }
+
+ /**
+ * Gets the clothing rate.
+ *
+ * @return the clothing rate (kilograms/crew/change)
+ */
+ public double getClothingRate() {
+ return clothingRate;
+ }
+
+ /**
+ * Sets the clothing rate.
+ *
+ * @param clothingRate the new clothing rate (kilograms/crew/change)
+ */
+ public void setClothingRate(double clothingRate) {
+ this.clothingRate = clothingRate;
+ }
+
+ /**
+ * Gets the personal items.
+ *
+ * @return the personal items (kilograms/crew)
+ */
+ public double getPersonalItems() {
+ return personalItems;
+ }
+
+ /**
+ * Sets the personal items.
+ *
+ * @param personalItems the new personal items (kilograms/crew)
+ */
+ public void setPersonalItems(double personalItems) {
+ this.personalItems = personalItems;
+ }
+
+ /**
+ * Gets the office equipment.
+ *
+ * @return the office equipment (kilograms/crew)
+ */
+ public double getOfficeEquipment() {
+ return officeEquipment;
+ }
+
+ /**
+ * Sets the office equipment.
+ *
+ * @param officeEquipment the new office equipment (kilograms/crew)
+ */
+ public void setOfficeEquipment(double officeEquipment) {
+ this.officeEquipment = officeEquipment;
+ }
+
+ /**
+ * Gets the eva suit.
+ *
+ * @return the eva suit (kilograms/crew)
+ */
+ public double getEvaSuit() {
+ return evaSuit;
+ }
+
+ /**
+ * Sets the eva suit.
+ *
+ * @param evaSuit the new eva suit (kilograms/crew)
+ */
+ public void setEvaSuit(double evaSuit) {
+ this.evaSuit = evaSuit;
+ }
+
+ /**
+ * Gets the EVA lithium hydroxide.
+ *
+ * @return the EVA lithium hydroxide (kilograms/crew/hour)
+ */
+ public double getEvaLithiumHydroxide() {
+ return evaLithiumHydroxide;
+ }
+
+ /**
+ * Sets the EVA lithium hydroxide.
+ *
+ * @param evaLithiumHydroxide the new EVA lithium hydroxide (kilograms/crew/hour)
+ */
+ public void setEvaLithiumHydroxide(double evaLithiumHydroxide) {
+ this.evaLithiumHydroxide = evaLithiumHydroxide;
+ }
+
+ /**
+ * Gets the health equipment.
+ *
+ * @return the health equipment (kilograms)
+ */
+ public double getHealthEquipment() {
+ return healthEquipment;
+ }
+
+ /**
+ * Sets the health equipment.
+ *
+ * @param healthEquipment the new health equipment (kilograms)
+ */
+ public void setHealthEquipment(double healthEquipment) {
+ this.healthEquipment = healthEquipment;
+ }
+
+ /**
+ * Gets the health consumables.
+ *
+ * @return the health consumables (kilograms/crew/day)
+ */
+ public double getHealthConsumables() {
+ return healthConsumables;
+ }
+
+ /**
+ * Sets the health consumables.
+ *
+ * @param healthConsumables the new health consumables (kilograms/crew/day)
+ */
+ public void setHealthConsumables(double healthConsumables) {
+ this.healthConsumables = healthConsumables;
+ }
+
+ /**
+ * Gets the safety equipment.
+ *
+ * @return the safety equipment (kilograms)
+ */
+ public double getSafetyEquipment() {
+ return safetyEquipment;
+ }
+
+ /**
+ * Sets the safety equipment.
+ *
+ * @param safetyEquipment the new safety equipment (kilograms)
+ */
+ public void setSafetyEquipment(double safetyEquipment) {
+ this.safetyEquipment = safetyEquipment;
+ }
+
+ /**
+ * Gets the communications equipment.
+ *
+ * @return the communications equipment (kilograms)
+ */
+ public double getCommEquipment() {
+ return commEquipment;
+ }
+
+ /**
+ * Sets the communications equipment.
+ *
+ * @param commEquipment the new communications equipment (kilograms)
+ */
+ public void setCommEquipment(double commEquipment) {
+ this.commEquipment = commEquipment;
+ }
+
+ /**
+ * Gets the computer equipment.
+ *
+ * @return the computer equipment (kilograms)
+ */
+ public double getComputerEquipment() {
+ return computerEquipment;
+ }
+
+ /**
+ * Sets the computer equipment.
+ *
+ * @param computerEquipment the new computer equipment (kilograms)
+ */
+ public void setComputerEquipment(double computerEquipment) {
+ this.computerEquipment = computerEquipment;
+ }
+
+ /**
+ * Gets the trashBag rate.
+ *
+ * @return the trashBag rate (kilograms/crew/day)
+ */
+ public double getTrashBagRate() {
+ return trashBagRate;
+ }
+
+ /**
+ * Sets the trash bag rate.
+ *
+ * @param trashBagRate the new trash bag rate (kilograms/crew/day)
+ */
+ public void setTrashBagRate(double trashBagRate) {
+ this.trashBagRate = trashBagRate;
+ }
+
+ /**
+ * Gets the waste containment rate.
+ *
+ * @return the waste containment rate (kilograms/crew/day)
+ */
+ public double getWasteContainmentRate() {
+ return wasteContainmentRate;
+ }
+
+ /**
+ * Sets the waste containment rate.
+ *
+ * @param wasteContainmentRate the new waste containment rate (kilograms/crew/day)
+ */
+ public void setWasteContainmentRate(double wasteContainmentRate) {
+ this.wasteContainmentRate = wasteContainmentRate;
+ }
+
+ /**
+ * Checks if is transit demands are omitted.
+ *
+ * @return true, if is transit demands omitted
+ */
+ public boolean isTransitDemandsOmitted() {
+ return transitDemandsOmitted;
+ }
+
+ /**
+ * Sets if the transit demands are omitted.
+ *
+ * @param transitDemandsOmitted whether the transit demands are omitted
+ */
+ public void setTransitDemandsOmitted(boolean transitDemandsOmitted) {
+ this.transitDemandsOmitted = transitDemandsOmitted;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/model/DemandModelFactory.java b/src/main/java/edu/mit/spacenet/domain/model/DemandModelFactory.java
new file mode 100644
index 0000000..24b2c62
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/DemandModelFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.scenario.Mission;
+
+/**
+ * A factory for creating demand models.
+ *
+ * @author Paul Grogan
+ */
+public abstract class DemandModelFactory {
+
+ /**
+ * Creates a new DemandModel object for a mission.
+ *
+ * @param mission the mission
+ * @param type the type of demand model
+ *
+ * @return the demand model
+ */
+ public static I_DemandModel createDemandModel(Mission mission,
+ DemandModelType type) {
+ switch(type) {
+ case CREW_CONSUMABLES: return new CrewConsumablesDemandModel(mission);
+ case RATED: return new RatedDemandModel();
+ case TIMED_IMPULSE: return new TimedImpulseDemandModel();
+ default: throw new RuntimeException("Unsupported Demand Model");
+ }
+ }
+
+ /**
+ * Creates a new DemandModel object for an element.
+ *
+ * @param element the element
+ * @param type the type of demand model
+ *
+ * @return the demand model
+ */
+ public static I_DemandModel createDemandModel(I_Element element,
+ DemandModelType type) {
+ switch(type) {
+ case RATED: return new RatedDemandModel();
+ case SPARING_BY_MASS: return new SparingByMassDemandModel(element);
+ case TIMED_IMPULSE: return new TimedImpulseDemandModel();
+ default: throw new RuntimeException("Unsupported Demand Model");
+ }
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/model/DemandModelType.java b/src/main/java/edu/mit/spacenet/domain/model/DemandModelType.java
new file mode 100644
index 0000000..21440da
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/DemandModelType.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+import javax.swing.ImageIcon;
+
+/**
+ * An enumeration for the demand model types.
+ *
+ * @author Paul Grogan
+ */
+public enum DemandModelType {
+
+ /** The crew consumables model type. */
+ CREW_CONSUMABLES("Crew Consumables Demand Model", "icons/comment.png"),
+
+ /** The timed impulse model type. */
+ TIMED_IMPULSE("Timed Impulse Demand Model", "icons/comment.png"),
+
+ /** The rated model type. */
+ RATED("Rated Demand Model", "icons/comment.png"),
+
+ /** The sparing by mass model type. */
+ SPARING_BY_MASS("Sparing by Mass Demand Model", "icons/comment.png");
+
+ private String name;
+ private ImageIcon icon;
+
+ private DemandModelType(String name, String iconUrl) {
+ this.name = name;
+ this.icon = new ImageIcon(getClass().getClassLoader().getResource(iconUrl));
+ }
+
+ /**
+ * Gets the name of the demand model type.
+ *
+ * @return the demand model type name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Enum#toString()
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Gets the icon for the demand model type.
+ *
+ * @return the demand model type icon
+ */
+ public ImageIcon getIcon() {
+ return icon;
+ }
+
+ /**
+ * Gets the enumeration value based on a passed name.
+ *
+ * @param name the name to match
+ *
+ * @return the matching demand model type (null if no match found)
+ */
+ public static DemandModelType getInstance(String name) {
+ for(DemandModelType t : DemandModelType.values()) {
+ if(t.getName().toLowerCase().equals(name.toLowerCase())) {
+ return t;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/model/I_DemandModel.java b/src/main/java/edu/mit/spacenet/domain/model/I_DemandModel.java
new file mode 100644
index 0000000..883e61e
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/I_DemandModel.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+
+
+import edu.mit.spacenet.domain.I_DomainType;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.simulator.I_Simulator;
+
+/**
+ * Interface for broad class of demand models. A demand model generates a set
+ * of demands based on the duration of time that has elapsed.
+ *
+ * @author Paul Grogan
+ */
+public interface I_DemandModel extends I_DomainType, Comparable {
+
+ /**
+ * Generates a set of demands based on the duration (in days) of time that
+ * has elapsed.
+ *
+ * @param duration the duration (in days) to generate for
+ * @param simulator the simulator requesting the demands
+ *
+ * @return the set of demands
+ */
+ public DemandSet generateDemands(double duration, I_Simulator simulator);
+
+ /**
+ * Gets the demand model type.
+ *
+ * @return the demand model type
+ */
+ public DemandModelType getDemandModelType();
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/model/RatedDemandModel.java b/src/main/java/edu/mit/spacenet/domain/model/RatedDemandModel.java
new file mode 100644
index 0000000..dbc2f30
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/RatedDemandModel.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import edu.mit.spacenet.domain.resource.Demand;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.simulator.I_Simulator;
+
+/**
+ * Demand model that generates an amount of a set demands proportional to a rate
+ * constant. For discrete items, it aggregates the fractional items until at
+ * least a whole unit can be demanded.
+ *
+ * @author Paul Grogan
+ */
+public class RatedDemandModel extends AbstractDemandModel {
+ private SortedSet demandRates;
+
+ /**
+ * Default constructor that initializes the demand rates and item
+ * generation structures.
+ */
+ public RatedDemandModel() {
+ demandRates = new TreeSet();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#generateDemands(double, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ public DemandSet generateDemands(double duration, I_Simulator simulator) {
+ DemandSet demands = new DemandSet();
+ for(Demand demand : demandRates) {
+ Demand resource = new Demand();
+ resource.setResource(demand.getResource());
+ resource.setAmount(demand.getAmount()*duration);
+ demands.add(resource);
+ }
+ return demands;
+ }
+
+ /**
+ * Gets the set of demand rates.
+ *
+ * @return the set of demands with rate constant in place of amount
+ */
+ public SortedSet getDemandRates() {
+ return demandRates;
+ }
+
+ /**
+ * Sets the set of demand rates.
+ *
+ * @param demandRates the set of demands with rate constant in place of
+ * amount
+ */
+ public void setDemandRates(SortedSet demandRates) {
+ this.demandRates = demandRates;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#getDemandModelType()
+ */
+ public DemandModelType getDemandModelType() {
+ return DemandModelType.RATED;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/model/SparingByMassDemandModel.java b/src/main/java/edu/mit/spacenet/domain/model/SparingByMassDemandModel.java
new file mode 100644
index 0000000..cb3838d
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/SparingByMassDemandModel.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.Environment;
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.domain.element.PartApplication;
+import edu.mit.spacenet.domain.resource.Demand;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.domain.resource.GenericResource;
+import edu.mit.spacenet.simulator.I_Simulator;
+
+/**
+ * Crude sparing demand model that demands generic class of supply 4 resources
+ * proportional to the element's mass, a annual sparing rate, and the duration.
+ * An option allows an element's parts list to be utilized to generate specific
+ * resource demands if desired.
+ *
+ * @author Paul Grogan
+ */
+public class SparingByMassDemandModel extends AbstractDemandModel {
+ private I_Element element;
+ private double unpressurizedSparesRate;
+ private double pressurizedSparesRate;
+ private boolean partsListEnabled;
+
+ /**
+ * The default constructor sets the default packaging factors.
+ *
+ * @param element the element
+ */
+ public SparingByMassDemandModel(I_Element element) {
+ this.element = element;
+ this.partsListEnabled = true;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#generateDemands(double, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ public DemandSet generateDemands(double duration, I_Simulator simulator) {
+ return generateDemands(duration, pressurizedSparesRate, unpressurizedSparesRate, partsListEnabled);
+ }
+
+ /**
+ * Generate demands.
+ *
+ * @param duration the duration
+ * @param pressurizedSparesRate the pressurized spares rate
+ * @param unpressurizedSparesRate the unpressurized spares rate
+ * @param partsListEnabled the parts list enabled
+ * @return the demand set
+ */
+ public DemandSet generateDemands(double duration, double pressurizedSparesRate,
+ double unpressurizedSparesRate, boolean partsListEnabled) {
+ DemandSet demands = new DemandSet();
+
+ double pressPartMass = 0;
+ double unpressPartMass = 0;
+ double genericPartMass = 0;
+
+ if(partsListEnabled) {
+ for(PartApplication p : element.getParts()) {
+ if(p.getQuantity()>0) {
+ if(p.getPart().getEnvironment().equals(Environment.PRESSURIZED)) {
+ pressPartMass += p.getQuantity()*p.getPart().getUnitMass();
+ } else if(p.getPart().getEnvironment().equals(Environment.UNPRESSURIZED)) {
+ unpressPartMass += p.getQuantity()*p.getPart().getUnitMass();
+ }
+ }
+ }
+ // TODO: should check for error conditions:
+ // pressPartMass > element.getMass()
+ // unpressPartMass > element.getMass()
+ // pressPartMass + unpressPartMass > element.getMass()
+ genericPartMass = Math.max(0,element.getMass()-pressPartMass-unpressPartMass);
+ for(PartApplication p : element.getParts()) {
+ if(p.getQuantity()>0) {
+ Demand demand = new Demand();
+ demand.setResource(p.getPart());
+ if(p.getPart().getEnvironment().equals(Environment.PRESSURIZED)) {
+ demand.setAmount(duration*pressurizedSparesRate/365*element.getMass()*p.getQuantity()/(genericPartMass + pressPartMass));
+ } else if(p.getPart().getEnvironment().equals(Environment.UNPRESSURIZED)) {
+ demand.setAmount(duration*unpressurizedSparesRate/365*element.getMass()*p.getQuantity()/(genericPartMass + unpressPartMass));
+ }
+ demands.add(demand);
+ }
+ }
+ } else {
+ genericPartMass = element.getMass();
+ }
+
+ Demand unpressSpares = new Demand();
+ unpressSpares.setResource(new GenericResource(ClassOfSupply.COS4));
+ unpressSpares.getResource().setEnvironment(Environment.UNPRESSURIZED);
+ unpressSpares.setAmount(duration*unpressurizedSparesRate/365*element.getMass()*genericPartMass/(genericPartMass+unpressPartMass));
+ demands.add(unpressSpares);
+
+ Demand pressSpares = new Demand();
+ pressSpares.setResource(new GenericResource(ClassOfSupply.COS4));
+ pressSpares.getResource().setEnvironment(Environment.PRESSURIZED);
+ pressSpares.setAmount(duration*pressurizedSparesRate/365*element.getMass()*genericPartMass/(genericPartMass+pressPartMass));
+ demands.add(pressSpares);
+
+ return demands;
+ }
+
+ /**
+ * Gets the element.
+ *
+ * @return the element
+ */
+ public I_Element getElement() {
+ return element;
+ }
+
+ /**
+ * Sets the element.
+ *
+ * @param element the element
+ */
+ public void setElement(I_Element element) {
+ this.element = element;
+ }
+
+ /**
+ * Gets the unpressurized sparing rate.
+ *
+ * @return the sparing rate (percent element mass per year)
+ */
+ public double getUnpressurizedSparesRate() {
+ return unpressurizedSparesRate;
+ }
+
+ /**
+ * Sets the unpressurized sparing rate.
+ *
+ * @param sparesRate the sparing rate (percent element mass per year)
+ */
+ public void setUnpressurizedSparesRate(double sparesRate) {
+ this.unpressurizedSparesRate = sparesRate;
+ }
+
+ /**
+ * Gets the pressurized sparing rate.
+ *
+ * @return the sparing rate (percent element mass per year)
+ */
+ public double getPressurizedSparesRate() {
+ return pressurizedSparesRate;
+ }
+
+ /**
+ * Sets the pressurized sparing rate.
+ *
+ * @param sparesRate the spares rate
+ */
+ public void setPressurizedSparesRate(double sparesRate) {
+ this.pressurizedSparesRate = sparesRate;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#getDemandModelType()
+ */
+ public DemandModelType getDemandModelType() {
+ return DemandModelType.SPARING_BY_MASS;
+ }
+
+ /**
+ * Checks if is parts list enabled, allowing demands for generic and
+ * specific resources.
+ *
+ * @return true, if is parts list enabled
+ */
+ public boolean isPartsListEnabled() {
+ return partsListEnabled;
+ }
+
+ /**
+ * Sets the parts list enabled, allowing demands for generic and specific
+ * resources.
+ *
+ * @param partsListEnabled the new parts list enabled
+ */
+ public void setPartsListEnabled(boolean partsListEnabled) {
+ this.partsListEnabled = partsListEnabled;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/model/TimedImpulseDemandModel.java b/src/main/java/edu/mit/spacenet/domain/model/TimedImpulseDemandModel.java
new file mode 100644
index 0000000..97eda64
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/model/TimedImpulseDemandModel.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.model;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import edu.mit.spacenet.domain.resource.Demand;
+import edu.mit.spacenet.domain.resource.DemandSet;
+import edu.mit.spacenet.simulator.I_Simulator;
+
+/**
+ * Demand model that generates an impulse demand on its first call to generate
+ * demands, and nothing afterwards.
+ *
+ * @author Paul Grogan
+ */
+public class TimedImpulseDemandModel extends AbstractDemandModel {
+ private SortedSet demands;
+ private boolean flag = false;
+
+ /**
+ * The default constructor initializes the set of demands.
+ */
+ public TimedImpulseDemandModel() {
+ demands = new TreeSet();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#generateDemands(double, edu.mit.spacenet.simulator.I_Simulator)
+ */
+ public DemandSet generateDemands(double duration, I_Simulator simulator) {
+ if(!flag) {
+ flag = true;
+ DemandSet d = new DemandSet();
+ for(Demand demand : demands) {
+ d.add(demand);
+ }
+ return d;
+ } else return new DemandSet();
+ }
+
+ /**
+ * Gets the set of demands to generate.
+ *
+ * @return the set of demands
+ */
+ public SortedSet getDemands() {
+ return demands;
+ }
+
+ /**
+ * Sets the set of demands to generate.
+ *
+ * @param demands the set of demands
+ */
+ public void setDemands(SortedSet demands) {
+ this.demands = demands;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.model.I_DemandModel#getDemandModelType()
+ */
+ public DemandModelType getDemandModelType() {
+ return DemandModelType.TIMED_IMPULSE;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/Location.java b/src/main/java/edu/mit/spacenet/domain/network/Location.java
new file mode 100644
index 0000000..9120dfa
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/Location.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.DomainType;
+import edu.mit.spacenet.domain.I_Container;
+import edu.mit.spacenet.domain.element.CrewMember;
+import edu.mit.spacenet.domain.element.I_Carrier;
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.simulator.I_Simulator;
+
+/**
+ * Base class for any network component (e.g. node or edge).
+ *
+ * @author Paul Grogan
+ */
+public abstract class Location extends DomainType implements I_Container, Comparable {
+ private SortedSet contents;
+
+ /**
+ * The default constructor initializes the contents structure.
+ */
+ public Location() {
+ contents = new TreeSet();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#getContents()
+ */
+ public SortedSet getContents() {
+ return contents;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#getCompleteContents()
+ */
+ public SortedSet getCompleteContents() {
+ SortedSet elements = new TreeSet();
+ for(I_Element element : contents) recursiveAdd(elements, element);
+ return elements;
+ }
+ private void recursiveAdd(SortedSet elements, I_Element element) {
+ elements.add(element);
+ if(element instanceof I_Container) {
+ for(I_Element child : ((I_Container)element).getContents()) {
+ recursiveAdd(elements, child);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#canAdd(edu.mit.spacenet.domain.element.I_Element)
+ */
+ public boolean canAdd(I_Element element) {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#canAdd(double)
+ */
+ public boolean canAdd(double addedMass) {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#add(edu.mit.spacenet.domain.element.I_Element)
+ */
+ public boolean add(I_Element element) {
+ if(element.getContainer()!=null) element.getContainer().remove(element);
+ element.setContainer(this);
+ return contents.add(element);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#remove(edu.mit.spacenet.domain.element.I_Element)
+ */
+ public boolean remove(I_Element element) {
+ element.setContainer(null);
+ return contents.remove(element);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#getCargoMass()
+ */
+ public double getCargoMass() {
+ double mass = 0;
+ for(I_Element i : contents) {
+ if(!(i instanceof CrewMember)) {
+ mass += i.getTotalMass();
+ }
+ }
+ return mass;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#getCargoVolume()
+ */
+ public double getCargoVolume() {
+ double volume = 0;
+ for(I_Element e : contents) {
+ if(!(e instanceof CrewMember)) {
+ volume += e.getVolume();
+ }
+ }
+ return volume;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#getCrewSize()
+ */
+ public int getCrewSize() {
+ int crew = 0;
+ for(I_Element e : contents) {
+ if(e instanceof CrewMember) {
+ crew++;
+ }
+ }
+ return crew;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#getTotalCrewSize()
+ */
+ public int getTotalCrewSize() {
+ int crew = 0;
+ for(I_Element e : contents) {
+ if(e instanceof CrewMember) {
+ crew++;
+ } else if(e instanceof I_Carrier) {
+ crew+=((I_Carrier)e).getTotalCrewSize();
+ }
+ }
+ return crew;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.I_Container#getTotalMass()
+ */
+ public double getTotalMass() {
+ return getCargoMass();
+ }
+
+ /**
+ * Gets the total volume.
+ *
+ * @return the total volume
+ */
+ public double getTotalVolume() {
+ return getCargoVolume();
+ }
+
+ /**
+ * Gets the total mass.
+ *
+ * @param cos the cos
+ * @param simulator the simulator
+ *
+ * @return the total mass
+ */
+ public double getTotalMass(ClassOfSupply cos, I_Simulator simulator) {
+ double amount = 0;
+ for(I_Element element : getContents()) {
+ amount+=element.getTotalMass(cos);
+ }
+ return amount;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#toString()
+ */
+ public String toString() {
+ return getName();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#print(int)
+ */
+ public void print(int tabOrder) {
+ super.print(tabOrder);
+ for(I_Element i : ((I_Container)this).getContents()) {
+ i.print(tabOrder+1);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Location location) {
+ //return new Integer(getTid()).compareTo(new Integer(location.getTid()));
+ if(getTid()==location.getTid()) return 0;
+ else if(getName()!=null && !getName().equals(location.getName()))
+ return getName().compareTo(location.getName());
+ else return new Integer(getTid()).compareTo(new Integer(location.getTid()));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/Network.java b/src/main/java/edu/mit/spacenet/domain/network/Network.java
new file mode 100644
index 0000000..f3265e9
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/Network.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import edu.mit.spacenet.domain.I_Container;
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.domain.network.edge.Edge;
+import edu.mit.spacenet.domain.network.node.Node;
+
+/**
+ * Represents the network of nodes and edges for the simulation to act over.
+ *
+ * @author Paul Grogan
+ */
+public class Network {
+ private SortedSet nodes;
+ private SortedSet edges;
+ private SortedMap registrar;
+ private SortedMap removedRegistrar;
+
+ /**
+ * Default constructor that initializes the structures for the nodes and
+ * edges.
+ */
+ public Network() {
+ nodes = new TreeSet();
+ edges = new TreeSet();
+ registrar = new TreeMap();
+ removedRegistrar = new TreeMap();
+ }
+
+ /**
+ * Gets the set of nodes.
+ *
+ * @return the set of nodes
+ */
+ public SortedSet getNodes() {
+ return nodes;
+ }
+
+ /**
+ * Gets a node by its type identifier.
+ *
+ * @param tid the node's type identifier (primary key)
+ *
+ * @return the node, or null if not found
+ */
+ public Node getNodeByTid(int tid) {
+ Node node = null;
+ for(Node n : nodes) {
+ if(n.getTid() == tid) {
+ node = n;
+ break;
+ }
+ }
+ return node;
+ }
+
+ /**
+ * Gets the set of edges.
+ *
+ * @return the set of edges
+ */
+ public SortedSet getEdges() {
+ return edges;
+ }
+
+ /**
+ * Gets an edge by its type identifier.
+ *
+ * @param tid the edge's type identifier (primary key)
+ *
+ * @return the edge, or null if not found
+ */
+ public Edge getEdgeByTid(int tid) {
+ Edge edge = null;
+ for(Edge e : edges) {
+ if(e.getTid() == tid) {
+ edge = e;
+ break;
+ }
+ }
+ return edge;
+ }
+
+ /**
+ * Adds a network component (node or edge) to the network. In the case of an
+ * edge, the origin and destination node must exist in the network to be
+ * successful.
+ *
+ * @param c the network component
+ *
+ * @return true, if successful, false otherwise
+ */
+ public boolean add(Location c) {
+ if(c instanceof Node) return nodes.add((Node)c);
+ else {
+ Edge e = (Edge)c;
+ if(nodes.contains(e.getOrigin()) && nodes.contains(e.getDestination()))
+ return edges.add(e);
+ else return false;
+ }
+ }
+
+ /**
+ * Removes a network component (node or edge) from the network. In the case
+ * of a node, it will also remove all associated edges from the network.
+ *
+ * @param n the network component
+ *
+ * @return true, if successful, false otherwise
+ */
+ public boolean remove(Location n) {
+ if(n instanceof Node) {
+ Set edgesToRemove = new HashSet();
+ for(Edge e : edges) {
+ if(e.getOrigin().equals(n) || e.getDestination().equals(n))
+ edgesToRemove.add(e);
+ }
+ for(Edge e : edgesToRemove) {
+ edges.remove(e);
+ }
+ return nodes.remove((Node)n);
+ }
+ else return edges.remove((Edge)n);
+ }
+
+ /**
+ * Gets the locations.
+ *
+ * @return the locations
+ */
+ public List getLocations() {
+ ArrayList locations = new ArrayList();
+ for(Node node : getNodes()) {
+ locations.add(node);
+ }
+ for(Edge edge : getEdges()) {
+ locations.add(edge);
+ }
+ Collections.sort(locations);
+ return locations;
+ }
+
+ /**
+ * Gets the registry of elements.
+ *
+ * @return the element registry
+ */
+ public SortedMap getRegistrar() {
+ return registrar;
+ }
+
+ /**
+ * Gets the registry of removed elements.
+ *
+ * @return the removed element registry
+ */
+ public SortedMap getRemovedRegistrar() {
+ if(removedRegistrar==null) removedRegistrar = new TreeMap();
+ return removedRegistrar;
+ }
+
+ /**
+ * Gets the contents of.
+ *
+ * @param container the container
+ *
+ * @return the contents of
+ */
+ public SortedSet getContentsOf(I_Container container) {
+ TreeSet elements = new TreeSet();
+ for(I_Element element : getRegistrar().values()) {
+ if(element.getContainer().equals(container)) elements.add(element);
+ }
+ return elements;
+ }
+
+ /**
+ * Gets the complete contents of.
+ *
+ * @param location the location
+ *
+ * @return the complete contents of
+ */
+ public SortedSet getCompleteContentsOf(Location location) {
+ TreeSet elements = new TreeSet();
+ for(I_Element element : getRegistrar().values()) {
+ if(element.getLocation().equals(location)) elements.add(element);
+ }
+ return elements;
+ }
+
+ /**
+ * Prints a network representation to console.
+ */
+ public void print() {
+ System.out.println("Network Nodes");
+ for(Node n : nodes) {
+ n.print(1);
+ }
+ System.out.println("Network Edges");
+ for(Edge e : edges) {
+ e.print(1);
+ }
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/Burn.java b/src/main/java/edu/mit/spacenet/domain/network/edge/Burn.java
new file mode 100644
index 0000000..1bc0107
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/Burn.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+import edu.mit.spacenet.domain.DomainType;
+
+/**
+ * Class that represents an impulsive burn (either OMS or RCS) to achieve a
+ * specified delta-v (m/s), offset from the propulsive maneuver by a time.
+ *
+ * @author Paul Grogan
+ */
+public class Burn extends DomainType implements Comparable {
+ private double time;
+ private BurnType burnType;
+ private double deltaV;
+
+ /**
+ * The default constructor sets the burn type to OMS.
+ */
+ public Burn() {
+ super();
+ setBurnType(BurnType.OMS);
+ }
+
+ /**
+ * The inline constructor.
+ *
+ * @param time the burn time (days)
+ * @param burnType the burn type
+ * @param deltaV the delta-v (meters per second)
+ */
+ public Burn(double time, BurnType burnType, double deltaV) {
+ super();
+ setTime(time);
+ setBurnType(burnType);
+ setDeltaV(deltaV);
+ }
+
+ /**
+ * Gets the time offset from the initial propulsive maneuver.
+ *
+ * @return the time offset (days)
+ */
+ public double getTime() {
+ return time;
+ }
+
+ /**
+ * Sets the time offset from the initial propulsive maneuver.
+ *
+ * @param time the time offset (days)
+ */
+ public void setTime(double time) {
+ this.time = time;
+ }
+
+ /**
+ * Gets the burn type.
+ *
+ * @return the burn type
+ */
+ public BurnType getBurnType() {
+ return burnType;
+ }
+
+ /**
+ * Sets the burn type.
+ *
+ * @param burnType the burn type
+ */
+ public void setBurnType(BurnType burnType) {
+ this.burnType = burnType;
+ }
+
+ /**
+ * Gets the delta-v.
+ *
+ * @return the delta-v (meters per second)
+ */
+ public double getDeltaV() {
+ return deltaV;
+ }
+
+ /**
+ * Sets the delta-v.
+ *
+ * @param deltaV the delta-v (meters per second)
+ */
+ public void setDeltaV(double deltaV) {
+ this.deltaV = deltaV;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#toString()
+ */
+ @Override
+ public String toString() {
+ return burnType + " (" + deltaV + " m/s)";
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Burn o) {
+ if(o==null) return -1;
+ return new Double(getTime()).compareTo(o.getTime());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/BurnType.java b/src/main/java/edu/mit/spacenet/domain/network/edge/BurnType.java
new file mode 100644
index 0000000..865b745
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/BurnType.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+import java.io.Serializable;
+
+/**
+ * Enumeration of the two types of propulsive burns (OMS for Orbit Maneuvering
+ * System, RCS for Reaction Control System).
+ *
+ * @author Paul Grogan
+ */
+public enum BurnType implements Serializable {
+
+ /** Abbreviation for Orbit Maneuvering System. */
+ OMS("OMS"),
+
+ /** Abbreviation for Reaction Control System. */
+ RCS("RCS");
+
+ private String name;
+
+ /**
+ * The default constructor.
+ * @param name the name of the burn type to display
+ */
+ private BurnType(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets the name of the burn type.
+ *
+ * @return the burn type name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Enum#toString()
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Method to get a particular instance of a state type based on a
+ * case-insensitive string.
+ *
+ * @param name case-insensitive string of name
+ *
+ * @return the burn type, returns RCS if unknown name
+ */
+ public static BurnType getInstance(String name) {
+ if(name.toLowerCase().equals(OMS.getName().toLowerCase())) return OMS;
+ else return RCS;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/Edge.java b/src/main/java/edu/mit/spacenet/domain/network/edge/Edge.java
new file mode 100644
index 0000000..fe229dd
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/Edge.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+import edu.mit.spacenet.domain.network.Location;
+import edu.mit.spacenet.domain.network.node.Node;
+
+/**
+ * Base class for network components that connect two nodes (edges).
+ *
+ * @author Paul Grogan
+ */
+public abstract class Edge extends Location {
+ private Node origin;
+ private Node destination;
+ private EdgeType edgetype;
+
+ /**
+ * The default constructor.
+ */
+ public Edge() {
+ super();
+ }
+
+ /**
+ * Gets the origin.
+ *
+ * @return the origin
+ */
+ public Node getOrigin() {
+ return origin;
+ }
+
+ /**
+ * Sets the origin.
+ *
+ * @param origin the origin
+ */
+ public void setOrigin(Node origin) {
+ this.origin = origin;
+ }
+
+ /**
+ * Gets the destination.
+ *
+ * @return the destination
+ */
+ public Node getDestination() {
+ return destination;
+ }
+
+ /**
+ * Sets the destination.
+ *
+ * @param destination the destination
+ */
+ public void setDestination(Node destination) {
+ this.destination = destination;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.Location#compareTo(edu.mit.spacenet.domain.network.Location)
+ */
+ public int compareTo(Location location) {
+ if(location instanceof Edge) {
+ return super.compareTo(location);
+ /* TODO ordering by node origin breaks compatibility
+ Edge edge = (Edge)location;
+ if(getOrigin().equals(edge.getOrigin()))
+ // if both edges have same origin, order by name/id
+ return super.compareTo(location);
+ else
+ // if edges have different origin, order by origin
+ return getOrigin().compareTo(edge.getOrigin());
+ */
+ } else if(location instanceof Node) {
+ Node node = (Node)location;
+ if(getOrigin().equals(node))
+ // if node is edge's origin, order node first
+ return 1;
+ else
+ // else order by origin node
+ return getOrigin().compareTo(node);
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Gets the edge type.
+ *
+ * @return the edge type
+ */
+ public EdgeType getEdgeType(){
+ return edgetype;
+ }
+
+ public void setEdgeType(EdgeType edgetype1) {
+ this.edgetype=edgetype1;
+
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/EdgeType.java b/src/main/java/edu/mit/spacenet/domain/network/edge/EdgeType.java
new file mode 100644
index 0000000..1a8b0e2
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/EdgeType.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+import java.awt.Color;
+
+import javax.swing.ImageIcon;
+
+/**
+ * Enumeration to represent the different subclasses of edges.
+ *
+ * @author Paul Grogan
+ */
+public enum EdgeType {
+
+ /** The flight edge type. */
+ FLIGHT("Flight", "icons/edge_yellow.png", Color.YELLOW),
+
+ /** The space edge type. */
+ SPACE("Space", "icons/edge_red.png", Color.RED),
+
+ /** The surface edge type. */
+ SURFACE("Surface", "icons/edge_green.png", Color.GREEN),
+
+ /** The time dependent edge type. */
+ TIME_DEPENDENT("Time-Dependent", "icons/edge_red.png", Color.RED);
+
+ private String name;
+ private ImageIcon icon;
+ private Color color;
+
+ private EdgeType(String name, String iconUrl, Color color) {
+ this.name = name;
+ this.icon = new ImageIcon(getClass().getClassLoader().getResource(iconUrl));
+ this.color = color;
+ }
+
+ /**
+ * Gets the name of the edge type.
+ *
+ * @return the edge type name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Enum#toString()
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Gets the icon of the edge type.
+ *
+ * @return the edge type icon
+ */
+ public ImageIcon getIcon() {
+ return icon;
+ }
+
+ /**
+ * Gets the color of the edge type (used in visualizations).
+ *
+ * @return the edge type color
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Gets the edge type based on a given name.
+ *
+ * @param name the edge type name
+ *
+ * @return the edge type, return null if not found
+ */
+ public static EdgeType getInstance(String name) {
+ for(EdgeType t : EdgeType.values()) {
+ if(t.getName().toLowerCase().equals(name.toLowerCase())) {
+ return t;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/FlightEdge.java b/src/main/java/edu/mit/spacenet/domain/network/edge/FlightEdge.java
new file mode 100644
index 0000000..2706dec
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/FlightEdge.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+import edu.mit.spacenet.util.GlobalParameters;
+
+/**
+ * Edge that represents an abstracted flight with a finite duration and
+ * capacity constraints on crew and cargo mass.
+ *
+ * @author Paul Grogan
+ */
+public class FlightEdge extends Edge {
+ private double duration;
+ private int maxCrewSize;
+ private double maxCargoMass;
+
+ /**
+ * The default constructor.
+ */
+ public FlightEdge() {
+ super();
+ }
+
+ /**
+ * Gets the flight duration.
+ *
+ * @return the duration (days)
+ */
+ public double getDuration() {
+ return GlobalParameters.getRoundedTime(duration);
+ }
+
+ /**
+ * Sets the flight duration, rounding to nearest time precision.
+ *
+ * @param duration the duration (days)
+ */
+ public void setDuration(double duration) {
+ this.duration = duration;
+ }
+
+ /**
+ * Gets the maximum crew size.
+ *
+ * @return the maximum crew size
+ */
+ public int getMaxCrewSize() {
+ return maxCrewSize;
+ }
+
+ /**
+ * Sets the maximum crew size.
+ *
+ * @param maxCrewSize the maximum crew size
+ */
+ public void setMaxCrewSize(int maxCrewSize) {
+ this.maxCrewSize = maxCrewSize;
+ }
+
+ /**
+ * Gets the maximum cargo mass.
+ *
+ * @return the maximum caro mass (kilograms)
+ */
+ public double getMaxCargoMass() {
+ return maxCargoMass;
+ }
+
+ /**
+ * Sets the maximum cargo mass.
+ *
+ * @param maxCargoMass the maximum cargo mass (kilograms)
+ */
+ public void setMaxCargoMass(double maxCargoMass) {
+ this.maxCargoMass = maxCargoMass;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.edge.Edge#getEdgeType()
+ */
+ @Override
+ public EdgeType getEdgeType() {
+ return EdgeType.FLIGHT;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/SpaceEdge.java b/src/main/java/edu/mit/spacenet/domain/network/edge/SpaceEdge.java
new file mode 100644
index 0000000..dae7f3d
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/SpaceEdge.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.mit.spacenet.util.GlobalParameters;
+
+/**
+ * Edge that represents a series of propulsive burns with a finite duration.
+ *
+ * @author Paul Grogan
+ */
+public class SpaceEdge extends Edge {
+ private double duration;
+ private List burns;
+
+ /**
+ * The default constructor that initializes the list of burns.
+ */
+ public SpaceEdge() {
+ super();
+ burns = new ArrayList();
+ }
+
+ /**
+ * Gets the duration.
+ *
+ * @return the duration (days)
+ */
+ public double getDuration() {
+ return GlobalParameters.getRoundedTime(duration);
+ }
+
+ /**
+ * Sets the duration, rounding to nearest time precision.
+ *
+ * @param duration the duration (days)
+ */
+ public void setDuration(double duration) {
+ this.duration = duration;
+ }
+
+ /**
+ * Gets the list of burns.
+ *
+ * @return the list of burns
+ */
+ public List getBurns() {
+ return burns;
+ }
+
+ /**
+ * Sets the list of burns.
+ *
+ * @param burns the list of burns
+ */
+ public void setBurns(List burns) {
+ this.burns = burns;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.edge.Edge#getEdgeType()
+ */
+ @Override
+ public EdgeType getEdgeType() {
+ return EdgeType.SPACE;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/SurfaceEdge.java b/src/main/java/edu/mit/spacenet/domain/network/edge/SurfaceEdge.java
new file mode 100644
index 0000000..7701b15
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/SurfaceEdge.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+/**
+ * Edge that represents a surface transfer with a specified distance.
+ *
+ * @author Paul Grogan
+ */
+public class SurfaceEdge extends Edge {
+
+ /** The distance. */
+ double distance;
+
+ /**
+ * The default constructor.
+ */
+ public SurfaceEdge() {
+ super();
+ }
+
+ /**
+ * Gets the distance.
+ *
+ * @return the distance (kilometers)
+ */
+ public double getDistance() {
+ return this.distance;
+ }
+
+ /**
+ * Sets the distance.
+ *
+ * @param distance the distance (kilometers)
+ */
+ public void setDistance(double distance) {
+ this.distance = distance;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.edge.Edge#getEdgeType()
+ */
+ @Override
+ public EdgeType getEdgeType() {
+ return EdgeType.SURFACE;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/edge/TimeDependentEdge.java b/src/main/java/edu/mit/spacenet/domain/network/edge/TimeDependentEdge.java
new file mode 100644
index 0000000..ac78acc
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/edge/TimeDependentEdge.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.edge;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
+import edu.mit.spacenet.domain.network.node.OrbitalNode;
+
+public class TimeDependentEdge extends Edge {
+ private OrbitalNode origin, destination;
+
+ @Override
+ public OrbitalNode getOrigin() {
+ return origin;
+ }
+ public void setOrigin(OrbitalNode origin) {
+ this.origin = origin;
+ }
+ @Override
+ public OrbitalNode getDestination() {
+ return destination;
+ }
+ public void setDestination(OrbitalNode destination) {
+ this.destination = destination;
+ }
+
+ private String filePath;
+
+ @SuppressWarnings("deprecation")
+ public List getEdges(Date departureDate, double originPeriapsis, double originApoapsis, double destinationPeriapsis, double destinationApoapsis, double departureC3Limit, double arrivalC3Limit, boolean usesAerocapture) throws IOException {
+ List edges = new ArrayList();
+
+ // add code to open file @ filePath
+ // read data into SpaceEdge structures
+ // add SpaceEdge structures into List
+
+ // create poi file system
+ // open poi workbook
+ // open poi worksheet
+
+ POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(filePath));
+ HSSFWorkbook wb = new HSSFWorkbook(fs);
+
+ HSSFSheet infoSheet = wb.getSheetAt(0);
+ HSSFRow infoRow = infoSheet.getRow(2);
+
+ // date of origin (0,0) in the C3 chart
+ // Date originDate = infoRow.getCell(0).getDateCellValue();
+ int originDateJulian = (int) infoRow.getCell(1).getNumericCellValue();
+ // departure date axis
+ // int xAxisRange = (int) infoRow.getCell(2).getNumericCellValue();
+ // int xCellNum = (int) infoRow.getCell(3).getNumericCellValue();
+ int xStepSize = (int) infoRow.getCell(4).getNumericCellValue();
+ // TOF axis
+ // int yAxisRange = (int) infoRow.getCell(5).getNumericCellValue();
+ int yCellNum = (int) infoRow.getCell(6).getNumericCellValue();
+ int yStepSize = (int) infoRow.getCell(7).getNumericCellValue();
+ // departure/arrival planet
+ // String departurePlanet = infoRow.getCell(8).toString();
+ double radiusOriginBody = infoRow.getCell(9).getNumericCellValue();
+ double muOriginBody = infoRow.getCell(10).getNumericCellValue();
+ // String arrivalPlanet = infoRow.getCell(11).toString();
+ double radiusDestinationBody = infoRow.getCell(12).getNumericCellValue();
+ double muDestinationBody = infoRow.getCell(13).getNumericCellValue();
+
+ // Julian Day for departure date
+ int departureDateYear = departureDate.getYear();
+ int departureDateMonth = departureDate.getMonth();
+ int departureDateDate = departureDate.getDate();
+ int departureDateHour = 12;
+ int departureDateMinute = 0;
+ int departureDateSecond = 0;
+ double departureDateHMD = departureDateHour+departureDateMinute/60+departureDateSecond/(60*60);
+ double departureDateJulian = 367*departureDateYear-Math.floor(7*(departureDateYear+Math.floor((departureDateMonth+9)/12))/4)+Math.floor(275*departureDateMonth/9)+departureDateDate+departureDateHMD/24+1721013.5;
+
+ // radii of origin and destination orbits
+ double radiusOriginPeriapsis = radiusOriginBody + originPeriapsis; // [km]
+ double radiusOriginApoapsis = radiusOriginBody + originApoapsis; // [km]
+ double radiusDestinationPeriapsis = radiusDestinationBody + destinationPeriapsis; // [km]
+ double radiusDestinationApoapsis = radiusDestinationBody + destinationApoapsis; // [km]
+
+ // departure Julian Date -> row number
+ int departureDateRowNumber = (int) Math.ceil((departureDateJulian-originDateJulian)/xStepSize);
+
+ // C3d worksheet
+ // C3d row
+ HSSFSheet C3dSheet = wb.getSheetAt(1);
+ HSSFRow C3dRow = C3dSheet.getRow(departureDateRowNumber);
+
+ // C3a worksheet
+ // C3a row
+ HSSFSheet C3aSheet = wb.getSheetAt(2);
+ HSSFRow C3aRow = C3aSheet.getRow(departureDateRowNumber);
+
+ // for each row until end
+ for(int j = 0; j <= yCellNum - 1; j++) {
+ // read C3d and C3a
+ double C3d = C3dRow.getCell(j).getNumericCellValue();
+ double C3a = C3aRow.getCell(j).getNumericCellValue();
+
+ // check against departure limit
+ // check against arrival limit
+ // if within bounds:
+ if(C3d <= departureC3Limit && C3a <= arrivalC3Limit) {
+ // create new space edge
+ SpaceEdge edge = new SpaceEdge();
+
+ // copy same information (id, name, origin, destination, description)
+ edge.setTid(getTid());
+ edge.setName(getName());
+ edge.setOrigin(getOrigin());
+ edge.setDestination(getDestination());
+ edge.setDescription(getDescription());
+
+ // read and fill duration and burns
+ // TOF = duration [days]
+ double TOF = j*yStepSize;
+ edge.setDuration(TOF);
+
+ // delta-V's = burn [m/s]
+ // C3 -> delta-V conversion
+ // assuming both departure and arrival at periapsis
+ double departureDeltaV = (Math.sqrt(C3d+2*muOriginBody/radiusOriginPeriapsis)-Math.sqrt(muOriginBody/radiusOriginPeriapsis)*Math.sqrt(2*radiusOriginApoapsis/(radiusOriginPeriapsis+radiusOriginApoapsis)))*1000;
+ double arrivalDeltaV = (Math.sqrt(C3a+2*muDestinationBody/radiusDestinationPeriapsis)-Math.sqrt(muDestinationBody/radiusDestinationPeriapsis)*Math.sqrt(2*radiusDestinationApoapsis/(radiusDestinationPeriapsis+radiusDestinationApoapsis)))*1000;
+ edge.getBurns().add(new Burn(0, BurnType.OMS, departureDeltaV));
+ if(usesAerocapture == false) {
+ edge.getBurns().add(new Burn(TOF, BurnType.OMS, arrivalDeltaV));
+ }
+
+ // add new edge to list
+ edges.add(edge);
+
+ // end if
+ }
+ // end for
+ }
+
+ return edges;
+ }
+ public String getFilePath() {
+ return filePath;
+ }
+ public void setFilePath(String filePath) {
+ this.filePath = filePath;
+ }
+ @Override
+ public EdgeType getEdgeType() {
+ return EdgeType.TIME_DEPENDENT;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/node/Body.java b/src/main/java/edu/mit/spacenet/domain/network/node/Body.java
new file mode 100644
index 0000000..2a56bae
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/node/Body.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.node;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.Serializable;
+
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+
+/**
+ * Enumeration of the celestial bodies.
+ *
+ * @author Paul Grogan
+ */
+public enum Body implements Serializable {
+
+ /** The sun */
+ SUN("Sun", Color.YELLOW, "/icons/sun.png", null, 33200., 109., 0, "icons/sun_icon.png"),
+
+ /** Venus */
+ VENUS("Venus", Color.WHITE, null, SUN, 0.815, 0.950, 0.723, "icons/venus_icon.png"),
+
+ /** Earth */
+ EARTH("Earth", Color.BLUE, "/icons/earth.png", SUN, 1., 1., 1., "icons/earth_icon.png"),
+
+ /** The moon */
+ MOON("Moon", Color.LIGHT_GRAY, "/icons/moon.png", EARTH, 0.0123, 0.273, 0.00257, "icons/moon_icon.png"),
+
+ /** Mars */
+ MARS("Mars", Color.RED, "/icons/mars.png", SUN, 0.11, 0.532, 1.52, "icons/mars_icon.png"),
+
+ /** Phobos */
+ PHOBOS("Phobos", Color.DARK_GRAY, null, MARS, 1.8*Math.pow(10,-9), 11.1/6378., 9377.2/(150*Math.pow(10,6)), "icons/phobos_icon.png"),
+
+ /** Deimos */
+ DEIMOS("Deimos", Color.DARK_GRAY, null, MARS, 0.25*Math.pow(10,-9), 6.2/6378., 23460/(150*Math.pow(10,6)), "icons/deimos_icon.png"),
+
+ /** Jupiter */
+ JUPITER("Jupiter", Color.RED, null, SUN, 317.8, 11.209, 5.20, "icons/jupiter_icon.png");
+
+ /** 1 AU (astronomical unit) in kilometers. */
+ public static final long AU = Math.round(150*Math.pow(10,6));
+
+ /** Earth's radius (kilometers). */
+ public static final long EARTH_RADIUS = 6378;
+
+ /** Earth's mass (kilograms). */
+ public static final long EARTH_MASS = Math.round(5.9736*Math.pow(10,27));
+
+ /**
+ * Gets the nicely-formatted name of the body.
+ *
+ * @return the body's name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the body's color representation.
+ *
+ * @return the body's color
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Gets the body's Lambert-Azimuthal projection.
+ *
+ * @return the body's image
+ */
+ public BufferedImage getImage() {
+ return image;
+ }
+
+ /**
+ * Gets the parent body about which this body is orbiting.
+ *
+ * @return the parent
+ */
+ public Body getParent() {
+ return parent;
+ }
+
+ /**
+ * Gets the mass.
+ *
+ * @return the body's mass (units of Earth mass)
+ */
+ public double getMass() {
+ return mass;
+ }
+
+ /**
+ * Gets the mean planetary radius.
+ *
+ * @return the body's mean radius (units of Earth radius)
+ */
+ public double getPlanetaryRadius() {
+ return planetaryRadius;
+ }
+
+ /**
+ * Gets the mean orbital radius.
+ *
+ * @return the body's mean orbital radius (units of AU)
+ */
+ public double getOrbitalRadius() {
+ return orbitalRadius;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Enum#toString()
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Method to get a particular instance of a body based on a
+ * case-insensitive string.
+ *
+ * @param name case-insensitive string of name
+ *
+ * @return the body, returns null if unknown name
+ */
+ public static Body getInstance(String name) {
+ for(Body body : Body.values()) {
+ if(body.getName().toLowerCase().equals(name.toLowerCase())) return body;
+ }
+ return null;
+ }
+
+ /**
+ * Gets the icon of the body type.
+ *
+ * @return the body type icon
+ */
+ public ImageIcon getIcon() {
+ return icon;
+ }
+
+ // PRIVATE
+
+ private String name;
+ private Color color;
+ private BufferedImage image;
+ private Body parent;
+ private double mass;
+ private double planetaryRadius;
+ private double orbitalRadius;
+ private ImageIcon icon;
+
+ /**
+ * The default constructor.
+ *
+ * @param name the name to display
+ * @param color the color
+ * @param imageUrl the image url
+ * @param parent the parent
+ * @param mass the mass (earth mass)
+ * @param planetaryRadius the planetary radius (earth radii)
+ * @param orbitalRadius the orbital radius (astronomical units)
+ * @param iconUrl the icon url
+ */
+ private Body(String name, Color color, String imageUrl, Body parent, double mass, double planetaryRadius, double orbitalRadius, String iconUrl) {
+ this.name = name;
+ this.color = color;
+ if(imageUrl!=null) {
+ try {
+ image = ImageIO.read(getClass().getResource(imageUrl));
+ } catch (IOException e) {
+ System.out.println("error opening image");
+ }
+ }
+ this.parent = parent;
+ this.mass = mass;
+ this.planetaryRadius = planetaryRadius;
+ this.orbitalRadius = orbitalRadius;
+ this.icon = new ImageIcon(getClass().getClassLoader().getResource(iconUrl));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/node/LagrangeNode.java b/src/main/java/edu/mit/spacenet/domain/network/node/LagrangeNode.java
new file mode 100644
index 0000000..cbd1266
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/node/LagrangeNode.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.node;
+
+/**
+ * Node that represents Lagrangian points in space.
+ *
+ * @author Paul Grogan
+ */
+public class LagrangeNode extends SpaceNode {
+ private Body minorBody;
+ private int number;
+
+ /**
+ * The default constructor.
+ */
+ public LagrangeNode() {
+ super();
+ }
+
+ /**
+ * Gets the Lagrangian number.
+ *
+ * @return the Lagrangian number
+ */
+ public int getNumber() {
+ return number;
+ }
+
+ /**
+ * Sets the Lagrangian number.
+ *
+ * @param number the Lagrangian number
+ */
+ public void setNumber(int number) {
+ this.number = number;
+ }
+
+ /**
+ * Gets the minor body of the Lagrangian.
+ *
+ * @return the minor body
+ */
+ public Body getMinorBody() {
+ return minorBody;
+ }
+
+ /**
+ * Sets the major body of the Lagrangian.
+ *
+ * @param minorBody the minor body
+ */
+ public void setMinorBody(Body minorBody) {
+ this.minorBody = minorBody;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.node.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.LAGRANGE;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/node/Node.java b/src/main/java/edu/mit/spacenet/domain/network/node/Node.java
new file mode 100644
index 0000000..11e78fe
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/node/Node.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.node;
+
+import edu.mit.spacenet.domain.network.Location;
+import edu.mit.spacenet.domain.network.edge.Edge;
+
+/**
+ * Network component that represents a static location on a planetary body, a
+ * stable orbit, or a Lagrangian point.
+ *
+ * @author Paul Grogan
+ */
+public abstract class Node extends Location {
+ private Body body;
+
+ /**
+ * The default constructor.
+ */
+ public Node() {
+ super();
+ }
+
+ /**
+ * Gets the main body associated with the node.
+ *
+ * @return the main body
+ */
+ public Body getBody() {
+ return body;
+ }
+
+ /**
+ * Sets the main body associated with the node.
+ *
+ * @param body the main body
+ */
+ public void setBody(Body body) {
+ this.body = body;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.Location#compareTo(edu.mit.spacenet.domain.network.Location)
+ */
+ public int compareTo(Location location) {
+ if(location instanceof Node) {
+ Node node = (Node)location;
+ if(getBody().equals(node.getBody())) {
+ if(getBody().equals(Body.EARTH)) {
+ // in the case of the Earth, order nodes surface then space
+ if(this instanceof SurfaceNode && node instanceof SpaceNode)
+ return -1;
+ else if(this instanceof SpaceNode && node instanceof SurfaceNode)
+ return 1;
+ else
+ return super.compareTo(location);
+ } else {
+ // for all other bodies, order nodes space then surface
+ if(this instanceof SurfaceNode && node instanceof SpaceNode)
+ return 1;
+ else if(this instanceof SpaceNode && node instanceof SurfaceNode)
+ return -1;
+ else
+ return super.compareTo(location);
+ }
+ } else if(node.getBody()==Body.EARTH) {
+ return 1;
+ } else if(getBody()==Body.EARTH) {
+ return -1;
+ } else {
+ return getBody().compareTo(node.getBody());
+ }
+ } else if(location instanceof Edge) {
+ Edge edge = (Edge)location;
+ if(this.equals(edge.getOrigin()))
+ // if edge has same origin, order node first
+ return -1;
+ else
+ // else order by origin node
+ return this.compareTo(edge.getOrigin());
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Gets the node type.
+ *
+ * @return the node type
+ */
+ public abstract NodeType getNodeType();
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/node/NodeType.java b/src/main/java/edu/mit/spacenet/domain/network/node/NodeType.java
new file mode 100644
index 0000000..55e3183
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/node/NodeType.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.node;
+
+import javax.swing.ImageIcon;
+
+/**
+ * An enumeration that represents the different subclasses of nodes.
+ *
+ * @author Paul Grogan
+ */
+public enum NodeType {
+ /** The lagrange node type. */
+ LAGRANGE("Lagrange", "icons/bullet_purple.png"),
+
+ /** The orbital node type. */
+ ORBITAL("Orbital", "icons/bullet_red.png"),
+
+ /** The surface node type. */
+ SURFACE("Surface", "icons/bullet_yellow.png"), ;
+
+ private String name;
+ private ImageIcon icon;
+
+ private NodeType(String name, String iconUrl) {
+ this.name = name;
+ this.icon = new ImageIcon(getClass().getClassLoader().getResource(iconUrl));
+ }
+
+ /**
+ * Gets the name of the node type.
+ *
+ * @return the node type name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Enum#toString()
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Gets the icon of the node type.
+ *
+ * @return the node type icon
+ */
+ public ImageIcon getIcon() {
+ return icon;
+ }
+
+ /**
+ * Gets the node type instance based on a passed name.
+ *
+ * @param name the node type name
+ *
+ * @return the node type, null if not found
+ */
+ public static NodeType getInstance(String name) {
+ for(NodeType t : NodeType.values()) {
+ if(t.getName().toLowerCase().equals(name.toLowerCase())) {
+ return t;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/node/OrbitalNode.java b/src/main/java/edu/mit/spacenet/domain/network/node/OrbitalNode.java
new file mode 100644
index 0000000..3f9a201
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/node/OrbitalNode.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.node;
+
+/**
+ * Node that represents stable orbits around planetary bodies.
+ *
+ * @author Paul Grogan
+ */
+public class OrbitalNode extends SpaceNode {
+ private double inclination;
+ private double periapsis;
+ private double apoapsis;
+
+ /**
+ * The default constructor.
+ */
+ public OrbitalNode() {
+ super();
+ }
+
+ /**
+ * Gets the inclination of the orbit.
+ *
+ * @return the inclination (degrees)
+ */
+ public double getInclination() {
+ return inclination;
+ }
+
+ /**
+ * Sets the inclination of the orbit.
+ *
+ * @param inclination the inclination (degrees)
+ */
+ public void setInclination(double inclination) {
+ this.inclination = inclination;
+ }
+
+ /**
+ * Gets the periapsis, or distance from the center of the planetary body to
+ * the point on the orbit closest to the planetary body.
+ *
+ * @return periapsis the orbital periapsis (kilometers)
+ */
+ public double getPeriapsis() {
+ return periapsis;
+ }
+
+ /**
+ * Sets the periapsis, or distance from the center of the planetary body to
+ * the point on the orbit closest to the planetary body.
+ *
+ * @param periapsis the orbital periapsis (kilometers)
+ */
+ public void setPeriapsis(double periapsis) {
+ this.periapsis = periapsis;
+ }
+
+ /**
+ * Gets the apoapsis, or distance from the center of the planetary body to
+ * the point on the orbit farthest away to the planetary body.
+ *
+ * @return the orbital apoapsis (kilometers)
+ */
+ public double getApoapsis() {
+ return apoapsis;
+ }
+
+ /**
+ * Sets the apoapsis, or distance from the center of the planetary body to
+ * the point on the orbit farthest away to the planetary body.
+ *
+ * @param apoapsis the apoapsis (kilometers)
+ */
+ public void setApoapsis(double apoapsis) {
+ this.apoapsis = apoapsis;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.node.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.ORBITAL;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/network/node/SpaceNode.java b/src/main/java/edu/mit/spacenet/domain/network/node/SpaceNode.java
new file mode 100644
index 0000000..ea9d7ab
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/node/SpaceNode.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.node;
+
+/**
+ * Abstract node that represents nodes not on the surface of planetary bodies.
+ *
+ * @author Paul Grogan
+ */
+public abstract class SpaceNode extends Node {
+
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/network/node/SurfaceNode.java b/src/main/java/edu/mit/spacenet/domain/network/node/SurfaceNode.java
new file mode 100644
index 0000000..d36cb43
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/network/node/SurfaceNode.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.network.node;
+
+/**
+ * Node that represents a point on a planetary body's surface.
+ *
+ * @author Paul Grogan
+ */
+public class SurfaceNode extends Node {
+ private double latitude;
+ private double longitude;
+
+ /**
+ * The default constructor.
+ */
+ public SurfaceNode() {
+ super();
+ }
+
+ /**
+ * Gets the latitude of the point.
+ *
+ * @return the latitude (degrees)
+ */
+ public double getLatitude() {
+ return latitude;
+ }
+
+ /**
+ * Sets the latitude of the point.
+ *
+ * @param latitude the latitude (degrees)
+ */
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ /**
+ * Gets the longitude of the point.
+ *
+ * @return the longitude (degrees)
+ */
+ public double getLongitude() {
+ return longitude;
+ }
+
+ /**
+ * Sets the longitude of the point.
+ *
+ * @param longitude the longitude (degrees)
+ */
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.network.node.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.SURFACE;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/Demand.java b/src/main/java/edu/mit/spacenet/domain/resource/Demand.java
new file mode 100644
index 0000000..e3de3a1
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/Demand.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+import java.text.DecimalFormat;
+
+import edu.mit.spacenet.util.GlobalParameters;
+
+/**
+ * Represents a demanded resource and the demanded amount.
+ *
+ * @author Paul Grogan
+ */
+public class Demand implements Comparable {
+ private I_Resource resource;
+ private double amount;
+
+ /**
+ * The default constructor.
+ */
+ public Demand() {
+
+ }
+
+ /**
+ * Gets the mass of the associated demand.
+ *
+ * @return the mass of the associated demand (kilograms)
+ */
+ public double getMass() {
+ if(resource==null) return 0;
+ else return GlobalParameters.getRoundedMass(resource.getUnitMass()*amount);
+ }
+
+ /**
+ * Gets the volume of the associated demand.
+ *
+ * @return the volume of the associated demand (cubic meters)
+ */
+ public double getVolume() {
+ if(resource==null) return 0;
+ else return GlobalParameters.getRoundedVolume(resource.getUnitVolume()*amount);
+ }
+
+ /**
+ * A constructor that sets the resource and amount.
+ *
+ * @param resource the resource
+ * @param amount the amount
+ */
+ public Demand(I_Resource resource, double amount) {
+ super();
+ setResource(resource);
+ setAmount(amount);
+ }
+
+ /**
+ * Gets the demanded resource.
+ *
+ * @return the resource
+ */
+ public I_Resource getResource() {
+ return resource;
+ }
+
+ /**
+ * Sets the demanded resource.
+ *
+ * @param resource the resource
+ */
+ public void setResource(I_Resource resource) {
+ this.resource = resource;
+ }
+
+ /**
+ * Gets the demanded amount.
+ *
+ * @return the demanded amount (units of resource)
+ */
+ public double getAmount() {
+ return GlobalParameters.getRoundedDemand(amount);
+ }
+
+ /**
+ * Sets the demanded amount.
+ *
+ * @param amount the demanded amount (units of resource)
+ */
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ DecimalFormat format = new DecimalFormat("0.00");
+ if(resource == null) {
+ return format.format(getAmount()) + " units of unknown";
+ } else {
+ return format.format(getAmount()) + " " + resource.getUnits() + " of " + resource.getName();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Demand demand) {
+ if(getResource() == null) {
+ if(demand.getResource() == null) return 0;
+ else return -1;
+ } else {
+ return getResource().compareTo(demand.getResource());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/DemandSet.java b/src/main/java/edu/mit/spacenet/domain/resource/DemandSet.java
new file mode 100644
index 0000000..4f25830
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/DemandSet.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import edu.mit.spacenet.util.GlobalParameters;
+
+/**
+ * A wrapper for a set of demands that performs grouping operations.
+ *
+ * @author Paul Grogan
+ */
+public class DemandSet implements Iterable {
+ private static final long serialVersionUID = 153270744123011256L;
+ private SortedSet demands;
+
+ /**
+ * The constructor.
+ */
+ public DemandSet() {
+ demands = new TreeSet();
+ }
+
+ /**
+ * Adds a demand.
+ *
+ * @param demand the demand
+ *
+ * @return whether the operation was successful
+ */
+ public boolean add(Demand demand) {
+ for(Demand d : demands) {
+ if(d.getResource().equals((demand.getResource()))) {
+ d.setAmount(d.getAmount() + demand.getAmount());
+ return true;
+ }
+ }
+ Demand d = new Demand();
+ d.setResource(demand.getResource());
+ d.setAmount(demand.getAmount());
+ return demands.add(d);
+ }
+
+ /**
+ * Adds a set of demands.
+ *
+ * @param demands the demands
+ */
+ public void addAll(Iterable demands) {
+ for(Demand demand : demands) {
+ add(demand);
+ }
+ }
+
+ /**
+ * Removes a demand.
+ *
+ * @param demand the demand
+ *
+ * @return whether the operation was successful
+ */
+ public boolean remove(Demand demand) {
+ for(Demand d : demands) {
+ if(d.getResource().equals(demand.getResource())) {
+ if(d.getAmount() >= demand.getAmount()) {
+ d.setAmount(d.getAmount() - demand.getAmount());
+ demand.setAmount(0);
+ return true;
+ } else {
+ demand.setAmount(demand.getAmount() - d.getAmount());
+ d.setAmount(0);
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets the total mass of all demands.
+ *
+ * @return the mass (kilograms)
+ */
+ public double getTotalMass() {
+ double mass = 0;
+ for(Demand demand : demands) {
+ mass += demand.getMass();
+ }
+ return GlobalParameters.getRoundedMass(mass);
+ }
+
+ /**
+ * Gets the total volume of all demands.
+ *
+ * @return the volume (cubic meters)
+ */
+ public double getTotalVolume() {
+ double volume = 0;
+ for(Demand demand : demands) {
+ volume += demand.getVolume();
+ }
+ return GlobalParameters.getRoundedVolume(volume);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Iterable#iterator()
+ */
+ public Iterator iterator() {
+ return demands.iterator();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return demands.toString();
+ }
+
+ /**
+ * Gets the number of different demands.
+ *
+ * @return the size of the set
+ */
+ public int size() {
+ return demands.size();
+ }
+
+ /**
+ * Clears all of the demands.
+ */
+ public void clear() {
+ demands.clear();
+ }
+
+ /**
+ * Removes any demands with zero amount.
+ */
+ public void clean() {
+ List forRemoval = new ArrayList();
+ for(Demand demand : this) {
+ if(demand==null||demand.getAmount()==0)
+ forRemoval.add(demand);
+ }
+ for(Demand d : forRemoval) {
+ demands.remove(d);
+ }
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/GenericResource.java b/src/main/java/edu/mit/spacenet/domain/resource/GenericResource.java
new file mode 100644
index 0000000..6422197
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/GenericResource.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.Environment;
+
+/**
+ * A specific type of resource that is forced to have type identifier -cos and
+ * (unit) mass 1.
+ *
+ * @author Paul Grogan
+ */
+public class GenericResource extends Resource {
+
+ /**
+ * The constructor that assigns a TID of -COS and a (unit) mass of 1. It
+ * also sets the class of supply and creates a generic name based on it.
+ *
+ * @param classOfSupply the resource class of supply
+ */
+ public GenericResource(ClassOfSupply classOfSupply) {
+ super();
+ setTid(-classOfSupply.getId());
+ setName("Generic COS " + classOfSupply.getId() + " (" + classOfSupply.getName() + ")");
+ setUnitMass(1);
+ setUnits("kg");
+ setClassOfSupply(classOfSupply);
+ }
+
+ /**
+ * Constructor that sets the class of supply and environment. Also assigns
+ * a TID of -COS and a (unit) mass of 1.
+ *
+ * @param classOfSupply the resource class of supply
+ * @param environment the resource environment
+ */
+ public GenericResource(ClassOfSupply classOfSupply, Environment environment) {
+ this(classOfSupply);
+ setEnvironment(environment);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.Resource#getUnitVolume()
+ */
+ @Override
+ public double getUnitVolume() {
+ if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS1)) return 1900/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS201)) return 1/1000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS2)) return 7000/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS3)) return 5000/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS4)) return 3000/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS5)) return 7000/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS6)) return 5000/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS7)) return 5000/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS8)) return 3500/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS9)) return 3500/1000000d;
+ else if(getClassOfSupply().isInstanceOf(ClassOfSupply.COS10)) return 7000/1000000d;
+ else return super.getUnitVolume();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.Resource#getPackingFactor()
+ */
+ @Override
+ public double getPackingFactor() {
+ if(getClassOfSupply().equals(ClassOfSupply.COS203)) return 1.0;
+ else if(getClassOfSupply().equals(ClassOfSupply.COS201)) return 0.5;
+ else if(getClassOfSupply().equals(ClassOfSupply.COS6)) return 0;
+ else if(getEnvironment().equals(Environment.UNPRESSURIZED)) return 0.6;
+ //else if(getEnvironment().equals(Environment.PRESSURIZED_INTERNAL)) return 0.2;
+ //else if(getEnvironment().equals(Environment.PRESSURIZED_EXTERNAL)) return 1.2;
+ else if(getEnvironment().equals(Environment.PRESSURIZED)) return 1.2;
+ else return super.getPackingFactor();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.Resource#getResourceType()
+ */
+ @Override
+ public ResourceType getResourceType() {
+ return ResourceType.GENERIC;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/I_Item.java b/src/main/java/edu/mit/spacenet/domain/resource/I_Item.java
new file mode 100644
index 0000000..a77db0f
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/I_Item.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+/**
+ * Interface that represents discrete supply items.
+ *
+ * @author Paul Grogan
+ */
+public interface I_Item extends I_Resource {
+
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/I_Resource.java b/src/main/java/edu/mit/spacenet/domain/resource/I_Resource.java
new file mode 100644
index 0000000..fd6ef17
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/I_Resource.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.Environment;
+import edu.mit.spacenet.domain.I_DomainType;
+
+/**
+ * Interface that represents any supply item (discrete or continuous).
+ *
+ * @author Paul Grogan
+ */
+public interface I_Resource extends I_DomainType, Comparable {
+
+ /**
+ * Gets the class of supply.
+ *
+ * @return the class of supply
+ */
+ public ClassOfSupply getClassOfSupply();
+
+ /**
+ * Sets the class of supply.
+ *
+ * @param classOfSupply the class of supply
+ */
+ public void setClassOfSupply(ClassOfSupply classOfSupply);
+
+ /**
+ * Gets the resource environment.
+ *
+ * @return the environment
+ */
+ public Environment getEnvironment();
+
+ /**
+ * Sets the resource environment.
+ *
+ * @param environment the environment
+ */
+ public void setEnvironment(Environment environment);
+
+ /**
+ * Gets the packing factor, which is the factor of additional COS 5 demands
+ * that is added to unpacked demand figures.
+ *
+ * @return the packing factor
+ */
+ public double getPackingFactor();
+
+ /**
+ * Sets the packing factor, which is the factor of additional COS 5 demands
+ * that is added to unpacked demand figures.
+ *
+ * @param factor the packing factor
+ */
+ public void setPackingFactor(double factor);
+
+ /**
+ * Gets the units of measure.
+ *
+ * @return the units of measure
+ */
+ public String getUnits();
+
+ /**
+ * Sets the units of measure.
+ *
+ * @param units the units of measure
+ */
+ public void setUnits(String units);
+
+ /**
+ * Gets the unit mass.
+ *
+ * @return the unit mass (kilograms per unit of consumption)
+ */
+ public double getUnitMass();
+
+ /**
+ * Sets the unit mass.
+ *
+ * @param unitMass the unit mass
+ */
+ public void setUnitMass(double unitMass);
+
+ /**
+ * Gets the unit volume.
+ *
+ * @return the unit volume (cubic meters per unit)
+ */
+ public double getUnitVolume();
+
+ /**
+ * Sets the unit volume.
+ *
+ * @param unitVolume the unit volume (cubic meters per unit)
+ */
+ public void setUnitVolume(double unitVolume);
+
+ /**
+ * Checks whether this resource is substitutable (same or higher level of
+ * fidelity) for a given resource during demand consumption.
+ *
+ * @param resource the resource to check for substitutability
+ *
+ * @return true if this can be substituted for resource, false otherwise
+ */
+ public boolean isSubstitutableFor(I_Resource resource);
+
+ /**
+ * Gets the resource type.
+ *
+ * @return the resource type
+ */
+ public ResourceType getResourceType();
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/Item.java b/src/main/java/edu/mit/spacenet/domain/resource/Item.java
new file mode 100644
index 0000000..30564fe
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/Item.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+/**
+ * A discrete resource.
+ *
+ * @author Paul Grogan
+ */
+public class Item extends Resource implements I_Item {
+
+ /**
+ * The default constructor.
+ */
+ public Item() {
+ super();
+ setUnits("item");
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.Resource#getResourceType()
+ */
+ @Override
+ public ResourceType getResourceType() {
+ return ResourceType.ITEM;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/Resource.java b/src/main/java/edu/mit/spacenet/domain/resource/Resource.java
new file mode 100644
index 0000000..bb66640
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/Resource.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+import edu.mit.spacenet.domain.ClassOfSupply;
+import edu.mit.spacenet.domain.DomainType;
+import edu.mit.spacenet.domain.Environment;
+
+/**
+ * A continuous resource.
+ *
+ * @author Paul Grogan
+ */
+public class Resource extends DomainType implements I_Resource {
+ private ClassOfSupply classOfSupply;
+ private Environment environment;
+ private String units;
+ private double unitMass;
+ private double unitVolume;
+ private double packingFactor;
+
+ /**
+ * The default constructor that sets a default name, sets the default class
+ * of supply to COS 0, sets the environment to unpressurized, and sets
+ * default units to kilograms.
+ */
+ public Resource() {
+ super();
+ setName("New " + getClass().getSimpleName());
+ setClassOfSupply(ClassOfSupply.COS0);
+ setEnvironment(Environment.UNPRESSURIZED);
+ setUnitMass(1);
+ setUnits("kg");
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#getClassOfSupply()
+ */
+ public ClassOfSupply getClassOfSupply() {
+ return classOfSupply;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#setClassOfSupply(edu.mit.spacenet.domain.ClassOfSupply)
+ */
+ public void setClassOfSupply(ClassOfSupply classOfSupply) {
+ this.classOfSupply = classOfSupply;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#getEnvironment()
+ */
+ public Environment getEnvironment() {
+ return environment;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#setEnvironment(edu.mit.spacenet.domain.Environment)
+ */
+ public void setEnvironment(Environment environment) {
+ this.environment = environment;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#getUnits()
+ */
+ public String getUnits() {
+ return units;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#setUnits(java.lang.String)
+ */
+ public void setUnits(String units) {
+ this.units = units;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#getUnitMass()
+ */
+ public double getUnitMass() {
+ return unitMass;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#setUnitMass(double)
+ */
+ public void setUnitMass(double unitMass) {
+ this.unitMass = unitMass;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#getUnitVolume()
+ */
+ public double getUnitVolume() {
+ return unitVolume;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#setUnitVolume(double)
+ */
+ public void setUnitVolume(double unitVolume) {
+ this.unitVolume = unitVolume;
+ }
+
+ /**
+ * Gets the total mass.
+ *
+ * @return the total mass
+ */
+ public double getTotalMass() {
+ return getUnitMass();
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.DomainType#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object object) {
+ if(super.equals(object) && object instanceof I_Resource) {
+ return getEnvironment().equals(((I_Resource)object).getEnvironment());
+ } else return false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(I_Resource resource) {
+ if(getClassOfSupply().equals(resource.getClassOfSupply())) {
+ if(getTid()==resource.getTid()) {
+ return getEnvironment().compareTo(resource.getEnvironment());
+ } else return new Integer(getTid()).compareTo(resource.getTid());
+ } else return getClassOfSupply().compareTo(resource.getClassOfSupply());
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#isSubstitutableFor(edu.mit.spacenet.domain.resource.I_Resource)
+ */
+ public boolean isSubstitutableFor(I_Resource resource) {
+ if(getTid() < 0) {
+ // tid < 0 means this is a generic resource
+ if(getClassOfSupply().equals(resource.getClassOfSupply())
+ || getClassOfSupply().isSubclassOf(resource.getClassOfSupply())) {
+ // if this class of supply is the same as or more specific
+ // than target class of supply this resource can be substituted
+ // for target resource
+ return true;
+ } else {
+ return false;
+ }
+ } else if(getTid() > 0) {
+ // tid > 0 means this is a specific resource loaded from the database
+ if(getTid() == resource.getTid()) {
+ // if this type id is the same as the target type id, the two
+ // resources are mutually substitutable
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // tid == 0 means this resource was created during execution
+ System.out.println("Cannot currently use non-database resources in demands.");
+ return false;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#getPackingFactor()
+ */
+ public double getPackingFactor() {
+ return packingFactor;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#setPackingFactor(double)
+ */
+ public void setPackingFactor(double packingFactor) {
+ this.packingFactor = packingFactor;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.domain.resource.I_Resource#getResourceType()
+ */
+ public ResourceType getResourceType() {
+ return ResourceType.RESOURCE;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/domain/resource/ResourceType.java b/src/main/java/edu/mit/spacenet/domain/resource/ResourceType.java
new file mode 100644
index 0000000..064c5a1
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/domain/resource/ResourceType.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.domain.resource;
+
+import javax.swing.ImageIcon;
+
+/**
+ * An enumeration for the different subclasses of resources.
+ *
+ * @author Paul Grogan
+ */
+public enum ResourceType {
+
+ /** The generic resource type. */
+ GENERIC("Generic", "icons/bullet_pink.png"),
+
+ /** The continuous resource type. */
+ RESOURCE("Continuous", "icons/bullet_blue.png"),
+
+ /** The discrete resource type. */
+ ITEM("Discrete", "icons/bullet_wrench.png");
+
+ private String name;
+ private ImageIcon icon;
+
+ private ResourceType(String name, String iconUrl) {
+ this.name = name;
+ this.icon = new ImageIcon(getClass().getClassLoader().getResource(iconUrl));
+ }
+
+ /**
+ * Gets the name of the resource type.
+ *
+ * @return the resource type name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Enum#toString()
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Gets the icon of the resource type.
+ *
+ * @return the resource type icon
+ */
+ public ImageIcon getIcon() {
+ return icon;
+ }
+
+ /**
+ * Gets the resource type instance based on a passed name.
+ *
+ * @param name the resource type name
+ *
+ * @return the resource type, null if not found
+ */
+ public static ResourceType getInstance(String name) {
+ for(ResourceType t : ResourceType.values()) {
+ if(t.getName().toLowerCase().equals(name.toLowerCase())) {
+ return t;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/AboutDialog.java b/src/main/java/edu/mit/spacenet/gui/AboutDialog.java
new file mode 100644
index 0000000..9499215
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/AboutDialog.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextPane;
+
+/**
+ * Dialog that displays information about SpaceNet, including the version
+ * number, the authors, and any licensing details.
+ *
+ * @author Paul Grogan
+ */
+public class AboutDialog extends JDialog {
+ private static final long serialVersionUID = -802497885876127342L;
+
+ /**
+ * Initializes a new about dialog.
+ *
+ * @param spaceNetFrame the parent space net frame
+ */
+ public AboutDialog() {
+ super(SpaceNetFrame.getInstance(), "About SpaceNet", true);
+ setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
+ buildDialog();
+ pack();
+ }
+
+ /**
+ * Builds the dialog.
+ */
+ private void buildDialog() {
+ JPanel contentPanel = new JPanel();
+ contentPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ contentPanel.setBackground(new Color(153,51,51));
+ contentPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0;
+ c.weighty = 0;
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ JLabel mitLogo = new JLabel(new ImageIcon(getClass().getClassLoader().getResource("icons/mit_footer.png")));
+ mitLogo.setOpaque(false);
+ contentPanel.add(mitLogo, c);
+ c.gridy++;
+ c.fill = GridBagConstraints.NONE;
+ JLabel spaceNetLogo = new JLabel(new ImageIcon(getClass().getClassLoader().getResource("icons/spacenet_splash.png")));
+ spaceNetLogo.setPreferredSize(new Dimension(138,119));
+ contentPanel.add(spaceNetLogo, c);
+ c.gridy++;
+ JLabel titleLabel = new JLabel("SpaceNet 2.5r2");
+ titleLabel.setForeground(Color.WHITE);
+ titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD).deriveFont(18f));
+ contentPanel.add(titleLabel, c);
+ c.gridy++;
+ JLabel websiteLabel = new JLabel("http://spacenet.mit.edu");
+ websiteLabel.setForeground(Color.WHITE);
+ contentPanel.add(websiteLabel, c);
+ c.gridy++;
+ c.weighty = 1;
+ c.fill = GridBagConstraints.BOTH;
+ JTextPane textPane = new JTextPane();
+ textPane.setText("Copyright (c) 2010 MIT Strategic Engineering Research Group" +
+ "\n\nSpaceNet 2.5r2 is released under the GNU General Public License (GPL) Version 3." +
+ "\n\nThis project was paritally supported by the Jet Propulsion Laboratory (JPL) " +
+ "under the Strategic University Relations Program (SURP) and contract number 1344341." +
+ "\n\nResearch Advisor:\tOlivier de Weck" +
+ "\n\nJPL Contacts:\t\tGene Lee\n\t\tLiz Jordan" +
+ "\n\nLead Developer:\tPaul Grogan" +
+ "\n\nContributors:\t\tNii Armar\n\t\tIvo Ferreira\n\t\tAbe Grindle\n\t\tTakuto Ishimatsu\n\t\tBasant Sagar\n\t\tRobert Shishko\n\t\tAfreen Siddiqi" +
+ "\n\nPast Developers:\tJaemyung Ahn\n\t\tErica Gralla\n\t\tDiego Klabjan\n\t\tJason Mellein\n\t\tSarah Shull" +
+ "\n\nTest Subjects:\t\tTorin Clark\n\t\tBen Corbin\n\t\tJustin Kaderka\n\t\tGreg O'Neill\n\t\tDaniel Selva\n\t\tNarek Shougarian\n\t\tAnthony Wicht\n\t\tHoward Yue" +
+ "\n\nIcon Set:\t\tMark James, FamFamFam Silk" +
+ "\n\nLook and Feel:\t\tNNL Technology, InfoNode");
+ textPane.setEditable(false);
+ textPane.setCaretPosition(0);
+ JScrollPane textScroll = new JScrollPane(textPane);
+ textScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ textScroll.setPreferredSize(new Dimension(300,200));
+ contentPanel.add(textScroll, c);
+ c.weighty = 0;
+ c.gridy++;
+ c.fill = GridBagConstraints.NONE;
+ JButton okButton = new JButton("OK");
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ dispose();
+ }
+ });
+ contentPanel.add(okButton, c);
+ getRootPane().setDefaultButton(okButton);
+
+ setContentPane(contentPanel);
+ }
+
+ /**
+ * Show dialog.
+ */
+ public void showDialog() {
+ pack();
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/OptionsDialog.java b/src/main/java/edu/mit/spacenet/gui/OptionsDialog.java
new file mode 100644
index 0000000..50b8aa2
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/OptionsDialog.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.Hashtable;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.JSpinner;
+import javax.swing.JTabbedPane;
+import javax.swing.SpinnerNumberModel;
+
+import edu.mit.spacenet.gui.component.UnitsWrapper;
+import edu.mit.spacenet.scenario.ItemDiscretization;
+
+/**
+ * Dialog that displays options related to a specific scenario.
+ *
+ * @author Paul Grogan
+ */
+public class OptionsDialog extends JDialog {
+ private static final long serialVersionUID = -802497885876127342L;
+
+ private ScenarioPanel scenarioPanel;
+
+ private JPanel precisionPanel, constraintsPanel, demandsPanel, simulationPanel;
+ private SpinnerNumberModel timeModel, demandModel, massModel, volumeModel;
+ private JSpinner timeSpinner, demandSpinner, massSpinner, volumeSpinner;
+ private JCheckBox volumeConstrained, environmentConstrained;
+
+ private JComboBox discretizationCombo;
+ private JSlider aggregationSlider;
+ private JCheckBox scavengeSparesCheck;
+
+ private JCheckBox explorationCheck, evaCheck;
+
+ /**
+ * Instantiates a new options dialog.
+ *
+ * @param scenarioPanel the scenario panel
+ */
+ public OptionsDialog(ScenarioPanel scenarioPanel) {
+ super(scenarioPanel.getSpaceNetFrame(), "Scenario Options", true);
+ this.scenarioPanel = scenarioPanel;
+
+ buildDialog();
+ setResizable(false);
+ setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ }
+
+ /**
+ * Builds the dialog.
+ */
+ private void buildDialog() {
+ buildPrecisionPanel();
+ buildConstraintsPanel();
+ buildDemandsPanel();
+ buildSimulationPanel();
+
+ JPanel contentPanel = new JPanel();
+ contentPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 1;
+ c.weighty = 1;
+ c.fill = GridBagConstraints.BOTH;
+ JTabbedPane tabbedPane = new JTabbedPane();
+ tabbedPane.addTab("Precision", precisionPanel);
+ tabbedPane.addTab("Constraints", constraintsPanel);
+ tabbedPane.addTab("Demands", demandsPanel);
+ tabbedPane.addTab("Simulation", simulationPanel);
+ contentPanel.add(tabbedPane, c);
+ c.gridy++;
+ c.weighty = 0;
+ c.anchor = GridBagConstraints.LAST_LINE_END;
+ c.fill = GridBagConstraints.NONE;
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 3, 0));
+ JButton okButton = new JButton("OK");
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ saveOptions();
+ scenarioPanel.updateView();
+ dispose();
+ }
+ });
+ buttonPanel.add(okButton, c);
+ getRootPane().setDefaultButton(okButton);
+ JButton cancelButton = new JButton("Cancel");
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ dispose();
+ }
+ });
+ buttonPanel.add(cancelButton, c);
+ contentPanel.add(buttonPanel, c);
+
+ setModal(true);
+ setContentPane(contentPanel);
+ setMinimumSize(new Dimension(300,250));
+ }
+
+ /**
+ * Builds the precision panel.
+ */
+ private void buildPrecisionPanel() {
+ precisionPanel = new JPanel();
+ precisionPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ precisionPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.fill = GridBagConstraints.NONE;
+ precisionPanel.add(new JLabel("Time Precision: "), c);
+ c.gridy++;
+ precisionPanel.add(new JLabel("Demand Precision: "), c);
+ c.gridy++;
+ precisionPanel.add(new JLabel("Mass Precision: "), c);
+ c.gridy++;
+ precisionPanel.add(new JLabel("Volume Precision: "), c);
+ c.gridy++;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.NONE;
+ c.gridx = 1;
+ c.gridy = 0;
+ timeModel = new SpinnerNumberModel(0.001,0.001,1.000,0.001);
+ timeSpinner = new JSpinner(timeModel);
+ precisionPanel.add(new UnitsWrapper(timeSpinner, "days"), c);
+ c.gridy++;
+ demandModel = new SpinnerNumberModel(0.001,0.001,1.000,0.001);
+ demandSpinner = new JSpinner(demandModel);
+ precisionPanel.add(new UnitsWrapper(demandSpinner, "units"), c);
+ c.gridy++;
+ massModel = new SpinnerNumberModel(0.001,0.001,1.000,0.001);
+ massSpinner = new JSpinner(massModel);
+ precisionPanel.add(new UnitsWrapper(massSpinner, "kg"), c);
+ c.gridy++;
+ volumeModel = new SpinnerNumberModel(0.1,0.1,100.,0.1);
+ volumeSpinner = new JSpinner(volumeModel);
+ precisionPanel.add(new UnitsWrapper(volumeSpinner, "cm^3"), c);
+ c.gridy++;
+ c.weightx = 1;
+ c.weighty = 1;
+ c.fill = GridBagConstraints.BOTH;
+ precisionPanel.add(new JLabel(), c);
+ }
+
+ /**
+ * Builds the constraints panel.
+ */
+ private void buildConstraintsPanel() {
+ constraintsPanel = new JPanel();
+ constraintsPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ constraintsPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ volumeConstrained = new JCheckBox("Volume Constraints Enforced");
+ volumeConstrained.setOpaque(false);
+ constraintsPanel.add(volumeConstrained, c);
+ c.gridy++;
+ environmentConstrained = new JCheckBox("Environment Constraints Enforced");
+ environmentConstrained.setOpaque(false);
+ constraintsPanel.add(environmentConstrained, c);
+ c.gridy++;
+ c.weightx = 1;
+ c.weighty = 1;
+ c.fill = GridBagConstraints.BOTH;
+ constraintsPanel.add(new JLabel(), c);
+ }
+
+ /**
+ * Builds the demands panel.
+ */
+ private void buildDemandsPanel() {
+ demandsPanel = new JPanel();
+ demandsPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ demandsPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.anchor = GridBagConstraints.LINE_END;
+ demandsPanel.add(new JLabel("Item Discretization: "), c);
+ c.gridy++;
+ c.anchor = GridBagConstraints.FIRST_LINE_END;
+ demandsPanel.add(new JLabel("Item Aggregation: "), c);
+ c.weightx = 1;
+ c.gridx = 1;
+ c.gridy = 0;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.BOTH;
+ discretizationCombo = new JComboBox();
+ discretizationCombo.setToolTipText("Discretize demands for items to integer values at the selected level");
+ for(ItemDiscretization t : ItemDiscretization.values()) {
+ discretizationCombo.addItem(t);
+ }
+ discretizationCombo.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ if(e.getStateChange()==ItemEvent.SELECTED) {
+ aggregationSlider.setEnabled(discretizationCombo.getSelectedItem()!=ItemDiscretization.NONE);
+ }
+ }
+ });
+ demandsPanel.add(discretizationCombo, c);
+ c.gridy++;
+ aggregationSlider = new JSlider(JSlider.VERTICAL,0,4,0);
+ aggregationSlider.setOpaque(false);
+ aggregationSlider.setFocusable(false);
+ aggregationSlider.setToolTipText("Aggregate discretized item demands ahead or behind demands.");
+ Hashtable labelTable = new Hashtable();
+ labelTable.put(new Integer(0), new JLabel("First Demand", JLabel.LEFT));
+ labelTable.put(new Integer(2), new JLabel("Half Demand", JLabel.LEFT));
+ labelTable.put(new Integer(4), new JLabel("Unit Demand", JLabel.RIGHT));
+ aggregationSlider.setLabelTable(labelTable);
+ aggregationSlider.setPaintLabels(true);
+ aggregationSlider.setMajorTickSpacing(1);
+ aggregationSlider.setSnapToTicks(true);
+ aggregationSlider.setPaintTicks(true);
+ aggregationSlider.setPreferredSize(new Dimension(100,100));
+ demandsPanel.add(aggregationSlider, c);
+ c.gridy++;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridwidth = 2;
+ c.gridx = 0;
+ scavengeSparesCheck = new JCheckBox("Scavenge Spares");
+ scavengeSparesCheck.setOpaque(false);
+ demandsPanel.add(scavengeSparesCheck, c);
+ c.gridy++;
+ c.weightx = 1;
+ c.weighty = 1;
+ c.fill = GridBagConstraints.BOTH;
+ demandsPanel.add(new JLabel(), c);
+ }
+
+ /**
+ * Builds the simulation panel.
+ */
+ private void buildSimulationPanel() {
+ simulationPanel = new JPanel();
+ simulationPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ simulationPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.BOTH;
+ explorationCheck = new JCheckBox("Detailed Explorations");
+ explorationCheck.setOpaque(false);
+ simulationPanel.add(explorationCheck, c);
+ c.gridy++;
+ evaCheck = new JCheckBox("Detailed EVAs");
+ evaCheck.setOpaque(false);
+ simulationPanel.add(evaCheck, c);
+ c.gridy++;
+ c.weightx = 1;
+ c.weighty = 1;
+ c.fill = GridBagConstraints.BOTH;
+ simulationPanel.add(new JLabel(), c);
+ }
+
+ /**
+ * Saves the options.
+ */
+ private void saveOptions() {
+ scenarioPanel.updateView();
+ scenarioPanel.getScenario().setTimePrecision(timeModel.getNumber().doubleValue());
+ scenarioPanel.getScenario().setDemandPrecision(demandModel.getNumber().doubleValue());
+ scenarioPanel.getScenario().setMassPrecision(massModel.getNumber().doubleValue());
+ scenarioPanel.getScenario().setVolumePrecision(volumeModel.getNumber().doubleValue()/1000000D);
+ scenarioPanel.getScenario().setVolumeConstrained(volumeConstrained.isSelected());
+ scenarioPanel.getScenario().setEnvironmentConstrained(environmentConstrained.isSelected());
+ scenarioPanel.getScenario().setItemDiscretization((ItemDiscretization)discretizationCombo.getSelectedItem());
+ scenarioPanel.getScenario().setItemAggregation(aggregationSlider.getValue()/4D);
+ scenarioPanel.getScenario().setScavengeSpares(scavengeSparesCheck.isSelected());
+ scenarioPanel.getScenario().setDetailedEva(evaCheck.isSelected());
+ scenarioPanel.getScenario().setDetailedExploration(explorationCheck.isSelected());
+ }
+
+ /**
+ * Initializes the dialog with the options data.
+ */
+ private void initialize() {
+ timeModel.setValue(scenarioPanel.getScenario().getTimePrecision());
+ demandModel.setValue(scenarioPanel.getScenario().getDemandPrecision());
+ massModel.setValue(scenarioPanel.getScenario().getMassPrecision());
+ volumeModel.setValue(scenarioPanel.getScenario().getVolumePrecision()*1000000);
+
+ volumeConstrained.setSelected(scenarioPanel.getScenario().isVolumeConstrained());
+ environmentConstrained.setSelected(scenarioPanel.getScenario().isEnvironmentConstrained());
+
+ discretizationCombo.setSelectedItem(scenarioPanel.getScenario().getItemDiscretization());
+ aggregationSlider.setEnabled(discretizationCombo.getSelectedItem()!=ItemDiscretization.NONE);
+ aggregationSlider.setValue((int)(4*scenarioPanel.getScenario().getItemAggregation()));
+ scavengeSparesCheck.setSelected(scenarioPanel.getScenario().isScavengeSpares());
+
+ explorationCheck.setSelected(scenarioPanel.getScenario().isDetailedExploration());
+ evaCheck.setSelected(scenarioPanel.getScenario().isDetailedEva());
+ }
+
+ /**
+ * Initializes the view components, re-positions the dialog to the center
+ * of the frame, and enabled visibility.
+ */
+ public void showDialog() {
+ initialize();
+ pack();
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/ScenarioPanel.java b/src/main/java/edu/mit/spacenet/gui/ScenarioPanel.java
new file mode 100644
index 0000000..b9625ca
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/ScenarioPanel.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.text.SimpleDateFormat;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import com.toedter.calendar.JDateChooser;
+
+import edu.mit.spacenet.data.DataSourceType;
+import edu.mit.spacenet.gui.command.LoadDataSourceCommand;
+import edu.mit.spacenet.gui.data.DataSourceDialog;
+import edu.mit.spacenet.gui.demand.DemandsTab;
+import edu.mit.spacenet.gui.manifest.ManifestTab;
+import edu.mit.spacenet.gui.mission.MissionsTab;
+import edu.mit.spacenet.gui.network.NetworkTab;
+import edu.mit.spacenet.gui.simulation.SimulationTab;
+import edu.mit.spacenet.scenario.Scenario;
+
+/**
+ * The main component for displaying and organizing scenario information. A
+ * JSplitPane with the top component being the "details panel" (red background),
+ * and the bottom component being a JTabbedView with the five major modules
+ * (Network, Missions, Demands, Manifest, Simulation).
+ *
+ * @author Paul Grogan
+ */
+public class ScenarioPanel extends JSplitPane {
+ private static final long serialVersionUID = 6919650461629452601L;
+
+ private SpaceNetFrame spaceNetFrame;
+ private Scenario scenario;
+
+ private OptionsDialog optionsDialog;
+
+ private JTextField nameText, ownerText;
+ private JDateChooser startDate;
+ private JLabel dataSourceLabel, lastLoadLabel;
+ private JButton optionsButton, dataSourceButton, reloadButton;
+ private JTextArea descriptionText;
+
+ private JTabbedPane tabs;
+ private NetworkTab networkTab;
+ private MissionsTab missionsTab;
+ private DemandsTab demandsTab;
+ private ManifestTab manifestTab;
+ private SimulationTab simulationTab;
+
+ /**
+ * Instantiates a new scenario panel.
+ *
+ * @param spaceNetFrame the space net frame
+ */
+ public ScenarioPanel(SpaceNetFrame spaceNetFrame) {
+ super(JSplitPane.VERTICAL_SPLIT);
+ this.spaceNetFrame = spaceNetFrame;
+ optionsDialog = new OptionsDialog(this);
+
+ buildPanel();
+
+ setBackground(Color.LIGHT_GRAY);
+ setDividerSize(5);
+ setOneTouchExpandable(true);
+ setDividerLocation(100);
+ setResizeWeight(0);
+ }
+
+ /**
+ * Builds the panel.
+ */
+ private void buildPanel() {
+ JPanel detailsPanel = new JPanel();
+ detailsPanel.setForeground(Color.WHITE);
+ detailsPanel.setBackground(new Color(153,51,51));
+ detailsPanel.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
+ detailsPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0;
+ c.weighty = 0;
+ c.gridheight = 3;
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.BOTH;
+ ImageIcon icon = new ImageIcon(getClass().getClassLoader().getResource("icons/spacenet_splash.png"));
+ icon.setImage(icon.getImage().getScaledInstance(75, 75, Image.SCALE_SMOOTH));
+ detailsPanel.add(new JLabel(icon), c);
+
+ c.gridx++;
+ c.weightx = .05;
+ c.gridheight = 1;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.fill = GridBagConstraints.NONE;
+ detailsPanel.add(new HeaderLabel("Name: "), c);
+ c.gridy++;
+ detailsPanel.add(new HeaderLabel("Start Date: "), c);
+ c.gridy++;
+ detailsPanel.add(new HeaderLabel("Created By: "), c);
+
+ c.gridx++;
+ c.gridy = 0;
+ c.weightx = .25;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ nameText = new JTextField(20);
+ nameText.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ scenario.setName(nameText.getText());
+ spaceNetFrame.repaint(); // update frame title
+ }
+ });
+ detailsPanel.add(nameText, c);
+ c.gridy++;
+ startDate = new JDateChooser();
+ startDate.addPropertyChangeListener(new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent e) {
+ if(e.getPropertyName().equals("date")) {
+ scenario.setStartDate(startDate.getDate());
+ }
+ }
+ });
+ detailsPanel.add(startDate, c);
+ c.gridy++;
+ ownerText = new JTextField(15);
+ ownerText.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ scenario.setCreatedBy(ownerText.getText());
+ }
+ });
+ detailsPanel.add(ownerText, c);
+
+ c.gridx++;
+ c.gridy = 0;
+ c.weightx = .05;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.fill = GridBagConstraints.NONE;
+ detailsPanel.add(new HeaderLabel("Description: "), c);
+
+ c.gridx++;
+ c.weightx = .4;
+ c.weighty = 1;
+ c.gridheight = 4;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.BOTH;
+ descriptionText = new JTextArea();
+ descriptionText.setLineWrap(true);
+ descriptionText.setWrapStyleWord(true);
+ descriptionText.setFont(new Font("Sans-Serif", Font.PLAIN, 11));
+ descriptionText.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ scenario.setDescription(descriptionText.getText());
+ }
+ });
+ JScrollPane descriptionScroll = new JScrollPane(descriptionText);
+ descriptionScroll.setPreferredSize(new Dimension(250,50));
+ detailsPanel.add(descriptionScroll, c);
+
+ c.gridx++;
+ c.gridy = 0;
+ c.weightx = .05;
+ c.weighty = 0;
+ c.gridheight = 1;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.fill = GridBagConstraints.NONE;
+ detailsPanel.add(new HeaderLabel("Options: "), c);
+ c.gridy++;
+ detailsPanel.add(new HeaderLabel("Data Source: "), c);
+
+ c.gridx++;
+ c.gridy = 0;
+ c.weightx = .1;
+ c.anchor = GridBagConstraints.LINE_START;
+ optionsButton = new JButton("Edit", new ImageIcon(getClass().getClassLoader().getResource("icons/cog_edit.png")));
+ optionsButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ optionsDialog.showDialog();
+ }
+ });
+ detailsPanel.add(optionsButton, c);
+ c.gridy++;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ JPanel dataPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 3, 0));
+ dataPanel.setOpaque(false);
+ dataSourceLabel = new JLabel("");
+ dataSourceLabel.setForeground(Color.WHITE);
+ dataPanel.add(dataSourceLabel);
+ dataSourceButton = new JButton("Edit", new ImageIcon(getClass().getClassLoader().getResource("icons/database_edit.png")));
+ dataSourceButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ DataSourceDialog.createAndShowGUI(getThis());
+ }
+ });
+ dataPanel.add(dataSourceButton);
+ reloadButton = new JButton("Reload", new ImageIcon(getClass().getClassLoader().getResource("icons/database_refresh.png")));
+ reloadButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ LoadDataSourceCommand command = new LoadDataSourceCommand(getThis());
+ command.execute();
+ }
+ });
+ dataPanel.add(reloadButton);
+ detailsPanel.add(dataPanel, c);
+ c.gridy++;
+ lastLoadLabel = new JLabel();
+ lastLoadLabel.setForeground(Color.WHITE);
+ detailsPanel.add(lastLoadLabel, c);
+
+ setTopComponent(detailsPanel);
+
+ tabs = new JTabbedPane();
+
+ networkTab = new NetworkTab(this);
+ tabs.addTab("Network", new ImageIcon(getClass().getClassLoader().getResource("icons/world.png")), networkTab);
+
+ missionsTab = new MissionsTab(this);
+ tabs.addTab("Missions", new ImageIcon(getClass().getClassLoader().getResource("icons/flag_red.png")), missionsTab);
+
+ demandsTab = new DemandsTab(this);
+ tabs.addTab("Demands", new ImageIcon(getClass().getClassLoader().getResource("icons/comment.png")), demandsTab);
+
+ manifestTab = new ManifestTab(this);
+ tabs.addTab("Manifest", new ImageIcon(getClass().getClassLoader().getResource("icons/book_open.png")), manifestTab);
+
+ simulationTab = new SimulationTab(this);
+ tabs.addTab("Simulation", new ImageIcon(getClass().getClassLoader().getResource("icons/lightning.png")), simulationTab);
+
+ setBottomComponent(tabs);
+
+ tabs.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ if(!tabs.getSelectedComponent().equals(networkTab)
+ && scenario.getNetwork().getNodes().size()==0) {
+ tabs.setSelectedComponent(networkTab);
+ JOptionPane.showMessageDialog(spaceNetFrame,
+ "At least one network node is required.",
+ "SpaceNet Warning", JOptionPane.WARNING_MESSAGE,
+ null);
+ } else if(!tabs.getSelectedComponent().equals(networkTab)
+ && !tabs.getSelectedComponent().equals(missionsTab)
+ && scenario.getMissionList().size()==0) {
+ tabs.setSelectedComponent(missionsTab);
+ JOptionPane.showMessageDialog(spaceNetFrame,
+ "At least one mission is required.",
+ "SpaceNet Warning", JOptionPane.WARNING_MESSAGE,
+ null);
+ } else if(tabs.getSelectedComponent().equals(networkTab)) {
+ // network tab is initialized when the scenario is
+ // loaded and is not dependent on any other components
+ } else if(tabs.getSelectedComponent().equals(missionsTab)) {
+ missionsTab.initialize();
+ } else if(tabs.getSelectedComponent().equals(demandsTab)) {
+ demandsTab.initialize();
+ } else if(tabs.getSelectedComponent().equals(manifestTab)) {
+ // do not re-initialize manifest
+ } else if(tabs.getSelectedComponent().equals(simulationTab)) {
+ // do not re-initialize scenario
+ }
+ spaceNetFrame.repaint();
+ }
+ });
+ }
+
+ private void initialize() {
+ nameText.setEnabled(scenario!=null);
+ startDate.setEnabled(scenario!=null);
+ ownerText.setEnabled(scenario!=null);
+ optionsButton.setEnabled(scenario!=null);
+ dataSourceButton.setEnabled(scenario!=null);
+ reloadButton.setEnabled(scenario!=null);
+ descriptionText.setEnabled(scenario!=null);
+ if(scenario!=null) {
+ nameText.setText(scenario.getName());
+ startDate.setDate(scenario.getStartDate());
+ ownerText.setText(scenario.getCreatedBy());
+ descriptionText.setText(scenario.getDescription());
+ if(scenario.getDataSource()==null) {
+ dataSourceLabel.setText(DataSourceType.NONE.getName());
+ dataSourceLabel.setIcon(DataSourceType.NONE.getIcon());
+ } else {
+ dataSourceLabel.setText(getScenario().getDataSource().getDataSourceType().getName());
+ dataSourceLabel.setIcon(getScenario().getDataSource().getDataSourceType().getIcon());
+ }
+ networkTab.initialize();
+ manifestTab.initialize();
+ simulationTab.initialize();
+ editNetwork();
+ }
+ }
+
+ /**
+ * Opens the tab to edit the network.
+ */
+ public void editNetwork() {
+ tabs.setSelectedComponent(networkTab);
+ }
+
+ /**
+ * Gets whether the network tab is being edited.
+ *
+ * @return whether the network is being edited
+ */
+ public boolean isEditingNetwork() {
+ return tabs.getSelectedComponent().equals(networkTab);
+ }
+
+ /**
+ * Opens the tab to edit the missions.
+ */
+ public void editMissions() {
+ tabs.setSelectedComponent(missionsTab);
+ }
+
+ /**
+ * Gets whether the missions tab is being edited.
+ *
+ * @return whether the missions are being edited
+ */
+ public boolean isEditingMissions() {
+ return tabs.getSelectedComponent().equals(missionsTab);
+ }
+
+ /**
+ * Opens the tab to edit the demands.
+ */
+ public void editDemands() {
+ tabs.setSelectedComponent(demandsTab);
+ }
+
+ /**
+ * Gets whether the demands tab is being edited.
+ *
+ * @return whether the demands tab is being edited
+ */
+ public boolean isEditingDemands() {
+ return tabs.getSelectedComponent().equals(demandsTab);
+ }
+
+ /**
+ * Opens the tab to edit the manifest.
+ */
+ public void editManifest() {
+ tabs.setSelectedComponent(manifestTab);
+ }
+
+ /**
+ * Gets whether the manifest tab is being edited.
+ *
+ * @return whether the manifest tab is being edited
+ */
+ public boolean isEditingManifest() {
+ return tabs.getSelectedComponent().equals(manifestTab);
+ }
+
+ /**
+ * Opens the tab to edit the simulation.
+ */
+ public void editSimulation() {
+ tabs.setSelectedComponent(simulationTab);
+ }
+
+ /**
+ * Gets whether the simulation tab is being edited.
+ *
+ * @return whether the simulation tab is being edited
+ */
+ public boolean isEditingSimulation() {
+ return tabs.getSelectedComponent().equals(simulationTab);
+ }
+
+ /**
+ * A custom JLabel class to format the labels in the scenario details panel.
+ */
+ private class HeaderLabel extends JLabel {
+ private static final long serialVersionUID = -7501636123809460913L;
+ public HeaderLabel(String text) {
+ super(text);
+ setFont(getFont().deriveFont(Font.BOLD));
+ setForeground(Color.WHITE);
+ }
+ }
+
+ /**
+ * Gets this.
+ *
+ * @return this
+ */
+ private ScenarioPanel getThis() {
+ return this;
+ }
+
+ /**
+ * Gets the scenario.
+ *
+ * @return the scenario
+ */
+ public Scenario getScenario() {
+ return scenario;
+ }
+
+ /**
+ * Sets the scenario and refreshes all visible components.
+ *
+ * @param scenario the new scenario
+ */
+ public void setScenario(Scenario scenario) {
+ this.scenario = scenario;
+ initialize();
+ }
+
+ /**
+ * Orders the scenario panel to update itself by reloading information from
+ * the model. Also orders the current open tab to update itself.
+ */
+ public void updateView() {
+ SpaceNetFrame.getInstance().getStatusBar().setStatusMessage("Updating...");
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ if(getScenario().getDataSource()==null) {
+ reloadButton.setEnabled(false);
+ dataSourceLabel.setText(DataSourceType.NONE.getName());
+ dataSourceLabel.setIcon(DataSourceType.NONE.getIcon());
+ lastLoadLabel.setText(null);
+ } else {
+ reloadButton.setEnabled(true);
+ dataSourceLabel.setText(getScenario().getDataSource().getName());
+ dataSourceLabel.setIcon(getScenario().getDataSource().getDataSourceType().getIcon());
+ SimpleDateFormat format = new SimpleDateFormat("MMM, d yyyy h:mm a zzz");
+ lastLoadLabel.setText("Last Loaded: " + (getScenario().getDataSource().getLastLoadDate()==null?"Never":format.format(getScenario().getDataSource().getLastLoadDate())));
+ }
+
+ if(isEditingNetwork()) {
+ networkTab.updateView();
+ } else if(isEditingMissions()) {
+ missionsTab.updateView();
+ } else if(isEditingDemands()) {
+ demandsTab.updateView();
+ } else if(isEditingManifest()) {
+ manifestTab.updateView();
+ } else if(isEditingSimulation()) {
+ simulationTab.updateView();
+ }
+
+ SpaceNetFrame.getInstance().getStatusBar().clearStatusMessage();
+ setCursor(Cursor.getDefaultCursor());
+ }
+
+ /**
+ * Gets the parent SpaceNet frame.
+ *
+ * @return the parent SpaceNet frame
+ */
+ public SpaceNetFrame getSpaceNetFrame() {
+ return spaceNetFrame;
+ }
+
+ /**
+ * Gets the options dialog.
+ *
+ * @return the options dialog
+ */
+ public OptionsDialog getOptionsDialog() {
+ return optionsDialog;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/gui/SpaceNetFrame.java b/src/main/java/edu/mit/spacenet/gui/SpaceNetFrame.java
new file mode 100644
index 0000000..ec58b07
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/SpaceNetFrame.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Image;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.io.XMLFileFilter;
+import edu.mit.spacenet.io.XStreamEngine;
+import edu.mit.spacenet.scenario.Scenario;
+import edu.mit.spacenet.util.IconLibrary;
+import edu.mit.spacenet.util.IdGenerator;
+
+/**
+ * The frame to contain the SpaceNet application.
+ *
+ * @author Paul Grogan
+ */
+public class SpaceNetFrame extends JFrame {
+ private static final long serialVersionUID = -6005760557525734285L;
+
+ private static SpaceNetFrame instance;
+
+ /**
+ * Gets the singleton reference to the SpaceNet frame.
+ *
+ * @return the singleton frame
+ */
+ public static SpaceNetFrame getInstance() {
+ if(instance==null) instance = new SpaceNetFrame();
+ return instance;
+ }
+
+ private JFileChooser scenarioChooser;
+ private SpaceNetSettingsDialog spaceNetSettingsDialog;
+ private AboutDialog aboutDialog;
+ private SpaceNetMenuBar menuBar;
+ private JPanel contentPanel;
+ private ScenarioPanel scenarioPanel;
+ private SpaceNetStatusBar statusBar;
+
+ private SpaceNetFrame() {
+ scenarioChooser = new JFileChooser(SpaceNetSettings.getInstance().getDefaultDirectory()) {
+ private static final long serialVersionUID = 5853237903722516861L;
+ public void approveSelection() {
+ if(getDialogType()==JFileChooser.SAVE_DIALOG) {
+ File file = getSelectedFile();
+ if (file != null && file.exists()) {
+ int answer = JOptionPane.showOptionDialog(this,
+ "Scenario '" + file.getAbsolutePath() + "' already exists. Overwrite?",
+ "Save Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
+ if (answer == JOptionPane.NO_OPTION) {
+ return;
+ }
+ }
+ }
+ super.approveSelection();
+ }
+ };
+ scenarioChooser.setFileFilter(new XMLFileFilter());
+ scenarioPanel = new ScenarioPanel(this);
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ setMinimumSize(new Dimension(800,600));
+ // try to specify multiple icon sizes (used for windows 7 task bar)
+ try {
+ java.lang.reflect.Method method = Class.forName("java.awt.Window").getDeclaredMethod("setIconImages", java.util.List.class);
+ ArrayList images = new ArrayList();
+ images.add(IconLibrary.getIcon("spacenet_icon_16").getImage());
+ images.add(IconLibrary.getIcon("spacenet_icon_32").getImage());
+ method.invoke(this,images);
+ } catch( Exception e ) {
+ // otherwise assign small icon only
+ setIconImage(IconLibrary.getIcon("spacenet_icon_16").getImage());
+ }
+ buildFrame();
+ }
+
+ /**
+ * Builds the frame.
+ */
+ private void buildFrame() {
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ exitSpaceNet();
+ }
+ });
+
+ menuBar = new SpaceNetMenuBar();
+ setJMenuBar(menuBar);
+
+ setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 1;
+ c.weighty = 1;
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.BOTH;
+ contentPanel = new JPanel();
+ contentPanel.setLayout(new BorderLayout());
+ contentPanel.setBackground(Color.LIGHT_GRAY);
+ add(contentPanel, c);
+ c.gridy++;
+ c.weighty = 0;
+ statusBar = new SpaceNetStatusBar();
+ add(statusBar, c);
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.Container#paint(java.awt.Graphics)
+ */
+ public void paint(Graphics g) {
+ super.paint(g);
+ if(scenarioPanel.getScenario()==null) setTitle("SpaceNet 2.5r2");
+ else setTitle("SpaceNet 2.5r2 | " + scenarioPanel.getScenario().getName());
+ }
+
+ /**
+ * Gets the about dialog.
+ *
+ * @return the about dialog
+ */
+ public AboutDialog getAboutDialog() {
+ if(aboutDialog==null) aboutDialog = new AboutDialog();
+ return aboutDialog;
+ }
+
+ /**
+ * Gets the settings dialog.
+ *
+ * @return the settings dialog
+ */
+ public SpaceNetSettingsDialog getSpaceNetSettingsDialog() {
+ if(spaceNetSettingsDialog==null) spaceNetSettingsDialog = new SpaceNetSettingsDialog();
+ return spaceNetSettingsDialog;
+ }
+
+ /**
+ * Gets the status bar.
+ *
+ * @return the status bar
+ */
+ public SpaceNetStatusBar getStatusBar() {
+ return statusBar;
+ }
+
+ /**
+ * Creates and displays a new scenario.
+ */
+ public void newScenario() {
+ setScenario(new Scenario());
+ }
+
+ /**
+ * Opens a saved scenario from a passed file path.
+ *
+ * @param filePath the file path of the saved scenario
+ */
+ public void openScenario(String filePath) {
+ try {
+ Scenario scenario = XStreamEngine.openScenario(filePath);
+ scenario.setFilePath(filePath);
+ setScenario(scenario);
+ } catch(FileNotFoundException e) {
+ JOptionPane.showMessageDialog(this,
+ "The scenario file path (" + filePath + ") is invalid.",
+ "SpaceNet Error",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (IOException e) {
+ JOptionPane.showMessageDialog(this,
+ "The open process failed due to an I/O exception.",
+ "SpaceNet Error",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ /**
+ * Closes the scenario.
+ */
+ public void closeScenario() {
+ setScenario(null);
+ }
+
+ /**
+ * Saves the open scenario.
+ */
+ public void saveScenario() {
+ try {
+ XStreamEngine.saveScenario(scenarioPanel.getScenario());
+ } catch (FileNotFoundException e) {
+ JOptionPane.showMessageDialog(this,
+ "The scenario file path (" + scenarioPanel.getScenario().getFilePath() + ") is invalid.",
+ "SpaceNet Error",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (IOException e) {
+ JOptionPane.showMessageDialog(this,
+ "The save process failed due to an I/O exception.",
+ "SpaceNet Error",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ /**
+ * Sets the scenario (and updates the id generator last value) and updates
+ * the scenario panel, or closes the scenario if null.
+ *
+ * @param scenario the new scenario
+ */
+ private void setScenario(Scenario scenario) {
+ if(scenario==null) {
+ scenarioPanel.setScenario(null);
+ contentPanel.removeAll();
+ } else {
+ int lastUid = 0;
+ for(I_Element element : scenario.getElements()) {
+ if(element.getUid()>lastUid) lastUid = element.getUid();
+ }
+ for(I_Element container : scenario.getManifest().getContainers()) {
+ if(container.getUid()>lastUid) lastUid = container.getUid();
+ }
+ IdGenerator.setLastUid(lastUid);
+ scenarioPanel.setScenario(scenario);
+ contentPanel.removeAll();
+ contentPanel.add(scenarioPanel, BorderLayout.CENTER);
+ }
+ validate();
+ repaint();
+ }
+
+ /**
+ * Gets the scenario panel component.
+ *
+ * @return the scenario panel.
+ */
+ public ScenarioPanel getScenarioPanel() {
+ return scenarioPanel;
+ }
+
+ /**
+ * Gets the scenario file chooser.
+ *
+ * @return the scenario file chooser
+ */
+ public JFileChooser getScenarioChooser() {
+ return scenarioChooser;
+ }
+
+ /**
+ * Exit space net.
+ */
+ public void exitSpaceNet() {
+ if(getScenarioPanel().getScenario() != null) {
+ int answer = JOptionPane.showOptionDialog(this,
+ "Save '" + scenarioPanel.getScenario().getName() + "' before exiting?",
+ "Close Warning", JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.WARNING_MESSAGE, null, null, null);
+ if (answer == JOptionPane.YES_OPTION) {
+ saveScenario();
+ }
+ if (answer != JOptionPane.CANCEL_OPTION) {
+ SpaceNetSettings.saveSettings();
+ System.exit(0);
+ }
+ } else {
+ SpaceNetSettings.saveSettings();
+ System.exit(0);
+ }
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/SpaceNetMenuBar.java b/src/main/java/edu/mit/spacenet/gui/SpaceNetMenuBar.java
new file mode 100644
index 0000000..d2ce1c5
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/SpaceNetMenuBar.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JSeparator;
+import javax.swing.KeyStroke;
+
+import edu.mit.spacenet.gui.command.CloseScenarioCommand;
+import edu.mit.spacenet.gui.command.NewScenarioCommand;
+import edu.mit.spacenet.gui.command.OpenScenarioCommand;
+import edu.mit.spacenet.gui.command.SaveScenarioAsCommand;
+import edu.mit.spacenet.gui.command.SaveScenarioCommand;
+import edu.mit.spacenet.gui.data.DataSourceDialog;
+
+/**
+ * The menu bar that contains all of the items in the pull-down menus. Most menu
+ * items use commands which abstract the actual triggering of the various
+ * features so they can be used elsewhere (e.g. exit on window close OR on
+ * selecting the exit command).
+ *
+ * @author Paul Grogan
+ */
+public class SpaceNetMenuBar extends JMenuBar {
+ private static final long serialVersionUID = -5251667632821734398L;
+
+ private JMenu fileMenu, editMenu, toolsMenu, helpMenu;
+ private JMenuItem newScenarioMenuItem, openScenarioMenuItem,
+ closeScenarioMenuItem, saveScenarioMenuItem, saveScenarioAsMenuItem,
+ exitMenuItem, optionsMenuItem, dataSourceMenuItem, preferencesMenuItem,
+ helpMenuItem, aboutMenuItem;
+ private JRadioButtonMenuItem networkMenuItem, missionsMenuItem,
+ demandsMenuItem, manifestMenuItem, simulationMenuItem;
+ private JCheckBoxMenuItem autoRefreshMenuItem;
+
+ /**
+ * The constructor.
+ *
+ * @param spaceNet the parent SpaceNet frame
+ */
+ public SpaceNetMenuBar() {
+ buildFileMenu();
+ add(fileMenu);
+
+ buildEditMenu();
+ add(editMenu);
+
+ buildToolsMenu();
+ add(toolsMenu);
+
+ buildHelpMenu();
+ add(helpMenu);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.JComponent#paint(java.awt.Graphics)
+ */
+ public void paint(Graphics g) {
+ super.paint(g);
+ boolean fileOpen = SpaceNetFrame.getInstance().getScenarioPanel().getScenario()!=null;
+ newScenarioMenuItem.setEnabled(!fileOpen);
+ openScenarioMenuItem.setEnabled(!fileOpen);
+ closeScenarioMenuItem.setEnabled(fileOpen);
+ saveScenarioMenuItem.setEnabled(fileOpen);
+ saveScenarioAsMenuItem.setEnabled(fileOpen);
+ editMenu.setEnabled(fileOpen);
+ if(fileOpen) {
+ networkMenuItem.setSelected(SpaceNetFrame.getInstance().getScenarioPanel().isEditingNetwork());
+ missionsMenuItem.setSelected(SpaceNetFrame.getInstance().getScenarioPanel().isEditingMissions());
+ demandsMenuItem.setSelected(SpaceNetFrame.getInstance().getScenarioPanel().isEditingDemands());
+ manifestMenuItem.setSelected(SpaceNetFrame.getInstance().getScenarioPanel().isEditingManifest());
+ simulationMenuItem.setSelected(SpaceNetFrame.getInstance().getScenarioPanel().isEditingSimulation());
+ }
+ }
+
+ /**
+ * Builds the file menu.
+ */
+ private void buildFileMenu() {
+ fileMenu = new JMenu("File");
+ fileMenu.setMnemonic(KeyEvent.VK_F);
+
+ newScenarioMenuItem = new JMenuItem("New Scenario", KeyEvent.VK_N);
+ newScenarioMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ KeyEvent.VK_N, ActionEvent.CTRL_MASK));
+ newScenarioMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ NewScenarioCommand command = new NewScenarioCommand(SpaceNetFrame.getInstance());
+ command.execute();
+ }
+ });
+ fileMenu.add(newScenarioMenuItem);
+
+ openScenarioMenuItem = new JMenuItem("Open Scenario", KeyEvent.VK_O);
+ openScenarioMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ KeyEvent.VK_O, ActionEvent.CTRL_MASK));
+ openScenarioMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ OpenScenarioCommand command = new OpenScenarioCommand(SpaceNetFrame.getInstance());
+ command.execute();
+ }
+ });
+ fileMenu.add(openScenarioMenuItem);
+
+ closeScenarioMenuItem = new JMenuItem("Close Scenario", KeyEvent.VK_C);
+ closeScenarioMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ KeyEvent.VK_W, ActionEvent.CTRL_MASK));
+ closeScenarioMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ CloseScenarioCommand command = new CloseScenarioCommand(SpaceNetFrame.getInstance());
+ command.execute();
+ }
+ });
+ fileMenu.add(closeScenarioMenuItem);
+
+ fileMenu.addSeparator();
+
+ saveScenarioMenuItem = new JMenuItem("Save Scenario", KeyEvent.VK_S);
+ saveScenarioMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ KeyEvent.VK_S, ActionEvent.CTRL_MASK));
+ saveScenarioMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SaveScenarioCommand command = new SaveScenarioCommand(SpaceNetFrame.getInstance());
+ command.execute();
+ }
+ });
+ fileMenu.add(saveScenarioMenuItem);
+
+ saveScenarioAsMenuItem = new JMenuItem("Save Scenario As...", KeyEvent.VK_A);
+ saveScenarioAsMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ KeyEvent.VK_S, ActionEvent.CTRL_MASK + ActionEvent.SHIFT_MASK));
+ saveScenarioAsMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SaveScenarioAsCommand command = new SaveScenarioAsCommand(SpaceNetFrame.getInstance());
+ command.execute();
+ }
+ });
+ fileMenu.add(saveScenarioAsMenuItem);
+
+ fileMenu.addSeparator();
+
+ exitMenuItem = new JMenuItem("Exit");
+ exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
+ exitMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().exitSpaceNet();
+ }
+ });
+ fileMenu.add(exitMenuItem);
+ }
+
+ /**
+ * Builds the edit menu.
+ */
+ private void buildEditMenu() {
+ editMenu = new JMenu("Edit");
+ editMenu.setMnemonic(KeyEvent.VK_E);
+
+ optionsMenuItem = new JMenuItem("Options");
+ optionsMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getScenarioPanel().getOptionsDialog().showDialog();
+ }
+ });
+ editMenu.add(optionsMenuItem);
+
+ dataSourceMenuItem = new JMenuItem("Data Source");
+ dataSourceMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ DataSourceDialog.createAndShowGUI(SpaceNetFrame.getInstance().getScenarioPanel());
+ }
+ });
+ editMenu.add(dataSourceMenuItem);
+
+ editMenu.add(new JSeparator());
+
+ networkMenuItem = new JRadioButtonMenuItem("Network");
+ networkMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getScenarioPanel().editNetwork();
+ }
+ });
+ editMenu.add(networkMenuItem);
+
+ missionsMenuItem = new JRadioButtonMenuItem("Missions");
+ missionsMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getScenarioPanel().editMissions();
+ }
+ });
+ editMenu.add(missionsMenuItem);
+
+ demandsMenuItem = new JRadioButtonMenuItem("Demands");
+ demandsMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getScenarioPanel().editDemands();
+ }
+ });
+ editMenu.add(demandsMenuItem);
+
+ manifestMenuItem = new JRadioButtonMenuItem("Manifest");
+ manifestMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getScenarioPanel().editManifest();
+ }
+ });
+ editMenu.add(manifestMenuItem);
+
+ simulationMenuItem = new JRadioButtonMenuItem("Simulation");
+ simulationMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getScenarioPanel().editSimulation();
+ }
+ });
+ editMenu.add(simulationMenuItem);
+ }
+
+ /**
+ * Builds the tools menu.
+ */
+ private void buildToolsMenu() {
+ toolsMenu = new JMenu("Tools");
+ toolsMenu.setMnemonic(KeyEvent.VK_T);
+
+ autoRefreshMenuItem = new JCheckBoxMenuItem("Auto-Refresh Charts");
+ autoRefreshMenuItem.setSelected(SpaceNetSettings.getInstance().isAutoRefresh());
+ autoRefreshMenuItem.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ SpaceNetSettings.getInstance().setAutoRefresh(e.getStateChange()==ItemEvent.SELECTED);
+ SpaceNetSettings.saveSettings();
+ SpaceNetFrame.getInstance().getScenarioPanel().updateView();
+ }
+ });
+ toolsMenu.add(autoRefreshMenuItem);
+
+ toolsMenu.addSeparator();
+
+ preferencesMenuItem = new JMenuItem("Preferences", KeyEvent.VK_P);
+ preferencesMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getSpaceNetSettingsDialog().showDialog();
+ }
+ });
+ toolsMenu.add(preferencesMenuItem);
+
+ }
+
+ /**
+ * Builds the help menu.
+ */
+ private void buildHelpMenu() {
+ helpMenu = new JMenu("Help");
+ helpMenu.setMnemonic(KeyEvent.VK_H);
+
+ helpMenuItem = new JMenuItem("Help", KeyEvent.VK_H);
+ helpMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ JOptionPane.showMessageDialog(SpaceNetFrame.getInstance(),
+ "For help with SpaceNet, please see:\n\n" +
+ "SpaceNet User's Manual (docs/manual)\n" +
+ "Quick Start Tutorial (docs/tutorial)\n" +
+ "SpaceNet Website (http://spacenet.mit.edu)",
+ "SpaceNet Help", JOptionPane.PLAIN_MESSAGE);
+ }
+ });
+ helpMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
+ helpMenu.add(helpMenuItem);
+
+ helpMenu.addSeparator();
+
+ aboutMenuItem = new JMenuItem("About SpaceNet", KeyEvent.VK_A);
+ aboutMenuItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ SpaceNetFrame.getInstance().getAboutDialog().showDialog();
+ }
+ });
+ helpMenu.add(aboutMenuItem);
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/SpaceNetSettings.java b/src/main/java/edu/mit/spacenet/gui/SpaceNetSettings.java
new file mode 100644
index 0000000..85cddd1
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/SpaceNetSettings.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.Rectangle;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * The Class SpaceNetSettings.
+ */
+public class SpaceNetSettings implements Serializable {
+ private static final long serialVersionUID = 6683421611404213906L;
+ private static final String filePath = "config";
+ private String defaultDirectory;
+ private boolean autoRefresh;
+ private Rectangle lastBounds;
+
+ /**
+ * Instantiates a new space net settings.
+ */
+ private SpaceNetSettings() {
+ lastBounds = new Rectangle();
+ autoRefresh = true;
+ }
+
+ private static SpaceNetSettings instance;
+
+ /**
+ * Gets the single instance of SpaceNetSettings.
+ *
+ * @return single instance of SpaceNetSettings
+ */
+ public static SpaceNetSettings getInstance() {
+ if(instance==null) loadSettings();
+ return instance;
+ }
+
+ /**
+ * Gets the default directory.
+ *
+ * @return the default directory
+ */
+ public String getDefaultDirectory() {
+ if(defaultDirectory==null) return System.getProperty("user.dir");
+ else return defaultDirectory;
+ }
+
+ /**
+ * Sets the default directory.
+ *
+ * @param defaultDirectory the new default directory
+ */
+ public void setDefaultDirectory(String defaultDirectory) {
+ this.defaultDirectory = defaultDirectory;
+ }
+
+ /**
+ * Gets the last bounds.
+ *
+ * @return the last bounds
+ */
+ public Rectangle getLastBounds() {
+ return lastBounds;
+ }
+
+ /**
+ * Sets the last bounds.
+ *
+ * @param bounds the new last bounds
+ */
+ public void setLastBounds(Rectangle bounds) {
+ this.lastBounds = bounds;
+ }
+
+ /**
+ * Load settings.
+ */
+ public static void loadSettings() {
+ FileInputStream fis;
+ try {
+ fis = new FileInputStream(filePath);
+ ObjectInputStream inStream = new ObjectInputStream(fis);
+ instance = (SpaceNetSettings)inStream.readObject();
+ inStream.close();
+ fis.close();
+ } catch (Exception e) {
+ // there was a problem loading the settings, reverting to defaults
+ instance = new SpaceNetSettings();
+ }
+ }
+
+ /**
+ * Save settings.
+ */
+ public static void saveSettings() {
+ SpaceNetSettings.getInstance().setLastBounds(SpaceNetFrame.getInstance().getBounds());
+ FileOutputStream fos;
+ try {
+ fos = new FileOutputStream(filePath);
+ ObjectOutputStream outStream = new ObjectOutputStream(fos);
+ outStream.writeObject(SpaceNetSettings.getInstance());
+ outStream.flush();
+ outStream.close();
+ fos.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Checks if is auto refresh.
+ *
+ * @return true, if is auto refresh
+ */
+ public boolean isAutoRefresh() {
+ return autoRefresh;
+ }
+
+ /**
+ * Sets the auto refresh.
+ *
+ * @param autoRefresh the new auto refresh
+ */
+ public void setAutoRefresh(boolean autoRefresh) {
+ this.autoRefresh = autoRefresh;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/SpaceNetSettingsDialog.java b/src/main/java/edu/mit/spacenet/gui/SpaceNetSettingsDialog.java
new file mode 100644
index 0000000..688fddb
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/SpaceNetSettingsDialog.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import edu.mit.spacenet.util.IconLibrary;
+
+/**
+ * A dialog to edit the global SpaceNet preferences.
+ *
+ * @author Paul Grogan
+ */
+public class SpaceNetSettingsDialog extends JDialog {
+ private static final long serialVersionUID = -802497885876127342L;
+
+ private JFileChooser directoryChooser;
+ private JCheckBox autoRefreshCheck;
+ private JTextField defaultDirectoryText;
+
+ /**
+ * The constructor.
+ *
+ * @param spaceNetFrame the parent SpaceNet frame
+ */
+ public SpaceNetSettingsDialog() {
+ super(SpaceNetFrame.getInstance(), "SpaceNet Settings", true);
+ directoryChooser = new JFileChooser();
+ directoryChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ buildDialog();
+ pack();
+ setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
+ }
+
+ /**
+ * Builds the dialog components.
+ */
+ private void buildDialog() {
+ JPanel contentPanel = new JPanel();
+ contentPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+ contentPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0;
+ c.weighty = 0;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.LINE_END;
+ contentPanel.add(new JLabel("Default directory: "), c);
+ c.gridx++;
+ c.weightx = 1;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.LINE_START;
+ defaultDirectoryText = new JTextField();
+ defaultDirectoryText.setEnabled(false);
+ defaultDirectoryText.setPreferredSize(new Dimension(300,20));
+ contentPanel.add(defaultDirectoryText, c);
+ c.gridx++;
+ c.weightx = 0;
+ JButton browseButton = new JButton("Browse...", IconLibrary.getIcon("folder_explore"));
+ browseButton.setMargin(new Insets(3,3,3,3));
+ browseButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ directoryChooser.setCurrentDirectory(new File(SpaceNetSettings.getInstance().getDefaultDirectory()));
+ int returnVal = directoryChooser.showOpenDialog(SpaceNetFrame.getInstance());
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ defaultDirectoryText.setText(directoryChooser.getSelectedFile().getAbsolutePath());
+ }
+ }
+ });
+ contentPanel.add(browseButton, c);
+ c.gridy++;
+ c.gridx = 0;
+ c.gridwidth = 3;
+ autoRefreshCheck = new JCheckBox("Auto-refresh charts (lags with large scenarios)");
+ contentPanel.add(autoRefreshCheck, c);
+
+ c.gridy++;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.fill = GridBagConstraints.NONE;
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 3, 0));
+ JButton okButton = new JButton("OK");
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ savePreferences();
+ setVisible(false);
+ }
+ });
+ buttonPanel.add(okButton);
+ getRootPane().setDefaultButton(okButton);
+ JButton cancelButton = new JButton("Cancel");
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ setVisible(false);
+ }
+ });
+ buttonPanel.add(cancelButton);
+ contentPanel.add(buttonPanel, c);
+ setContentPane(contentPanel);
+ }
+
+ /**
+ * Initializes the dialog.
+ */
+ private void initialize() {
+ defaultDirectoryText.setText(SpaceNetSettings.getInstance().getDefaultDirectory());
+ autoRefreshCheck.setSelected(SpaceNetSettings.getInstance().isAutoRefresh());
+ }
+
+ /**
+ * Save preferences.
+ */
+ private void savePreferences() {
+ SpaceNetSettings.getInstance().setAutoRefresh(autoRefreshCheck.isSelected());
+ SpaceNetSettings.getInstance().setDefaultDirectory(defaultDirectoryText.getText().equals("")||defaultDirectoryText.getText().equals(System.getProperty("user.dir"))?null:defaultDirectoryText.getText());
+ }
+
+ /**
+ * Show dialog.
+ */
+ public void showDialog() {
+ initialize();
+ pack();
+ setLocationRelativeTo(getParent());
+ setVisible(true);
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/SpaceNetStatusBar.java b/src/main/java/edu/mit/spacenet/gui/SpaceNetStatusBar.java
new file mode 100644
index 0000000..9ae341e
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/SpaceNetStatusBar.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+
+/**
+ * The status bar sits at the bottom of the main SpaceNet application and
+ * provides feedback on long-duration processes (e.g. simulation, loading, etc)
+ * with a status label and progress bar, similar to many web browsers.
+ *
+ * @author Paul Grogan
+ */
+public class SpaceNetStatusBar extends JPanel {
+ private static final long serialVersionUID = 8714221468753419089L;
+
+ private JLabel statusLabel;
+ private JProgressBar progressBar;
+
+ /**
+ * The constructor.
+ */
+ public SpaceNetStatusBar() {
+ buildStatusBar();
+ }
+ private void buildStatusBar() {
+ setLayout(new GridBagLayout());
+ setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY));
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weighty = 1;
+ c.weightx = .9;
+ c.fill = GridBagConstraints.BOTH;
+ c.anchor = GridBagConstraints.LINE_START;
+ statusLabel = new JLabel();
+ add(statusLabel, c);
+ c.gridx++;
+ c.weightx = .1;
+ progressBar = new JProgressBar();
+ add(progressBar, c);
+ }
+
+ /**
+ * Sets the status message in the lower-left hand corner and triggers the
+ * indeterminate progress bar.
+ *
+ * @param message the status message to display
+ */
+ public void setStatusMessage(String message) {
+ setStatusMessage(message, true);
+ }
+
+ /**
+ * Sets the status message in the lower-left hand corner with the option to
+ * trigger the progress bar.
+ *
+ * @param message the message to display
+ * @param triggerProcess whether to trigger the progress bar
+ */
+ public void setStatusMessage(String message, boolean triggerProcess) {
+ statusLabel.setText(message);
+ if(triggerProcess) progressBar.setIndeterminate(true);
+ }
+
+ /**
+ * Clears the status message and resets the progress bar.
+ */
+ public void clearStatusMessage() {
+ statusLabel.setText("");
+ progressBar.setIndeterminate(false);
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/SplashScreen.java b/src/main/java/edu/mit/spacenet/gui/SplashScreen.java
new file mode 100644
index 0000000..37e9c25
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/SplashScreen.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JWindow;
+
+/**
+ * The splash screen is a window that is displayed while the rest of the
+ * application is loading.
+ *
+ * @author Paul Grogan, ptgrogan@mit.edu
+ */
+public class SplashScreen extends JWindow {
+ private static final long serialVersionUID = -1859950222357089575L;
+
+ /**
+ * Instantiates a new splash screen.
+ */
+ public SplashScreen() {
+ JPanel content = new JPanel(new GridBagLayout());
+ content.setBackground(new Color(153,51,51));
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.anchor = GridBagConstraints.LINE_START;
+
+ c.gridheight = 2;
+ JLabel logo = new JLabel(new ImageIcon(getClass().getClassLoader().getResource("icons/spacenet_splash.png")));
+ logo.setPreferredSize(new Dimension(138,119));
+ content.add(logo, c);
+
+ c.gridx++;
+ c.gridheight = 1;
+ c.insets = new Insets(20, 20, 2, 20);
+ c.anchor = GridBagConstraints.LAST_LINE_START;
+ JLabel title = new JLabel ("SpaceNet 2.5");
+ title.setForeground(Color.WHITE);
+ title.setFont(new Font("Arial", Font.BOLD, 36));
+ content.add(title, c);
+
+ c.gridy++;
+ c.insets = new Insets(2, 20, 10, 20);
+ c.anchor = GridBagConstraints.FIRST_LINE_START;
+ JLabel subtitle = new JLabel("Simulation and modeling software for space logistics");
+ subtitle.setForeground(Color.WHITE);
+ subtitle.setFont(new Font("Arial", Font.BOLD, 12));
+ content.add(subtitle, c);
+
+ c.gridy++;
+ c.gridx = 0;
+ c.gridwidth = 2;
+ c.insets = new Insets(10, 20, 5, 20);
+ c.anchor = GridBagConstraints.CENTER;
+ JLabel loading = new JLabel("Loading...");
+ loading.setFont(new Font ("Arial", Font.BOLD, 12));
+ loading.setForeground(Color.WHITE);
+ content.add(loading, c);
+
+ c.gridy++;
+ c.insets = new Insets(5, 20, 20, 20);
+ JProgressBar progressBar = new JProgressBar();
+ progressBar.setIndeterminate(true);
+ progressBar.setForeground(new Color(153, 51, 51));
+ progressBar.setBackground(Color.WHITE);
+ progressBar.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+ content.add(progressBar, c);
+
+ add(content);
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/AddMissionCommand.java b/src/main/java/edu/mit/spacenet/gui/command/AddMissionCommand.java
new file mode 100644
index 0000000..7a9b915
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/AddMissionCommand.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import edu.mit.spacenet.gui.mission.MissionsTab;
+import edu.mit.spacenet.scenario.Mission;
+import edu.mit.spacenet.util.DateFunctions;
+
+/**
+ * The command to add a mission to a scenario, pre-filling data as available and
+ * triggering a secondary command to edit the newly-created mission.
+ *
+ * @author Paul Grogan
+ */
+public class AddMissionCommand implements I_Command {
+ private MissionsTab missionsTab;
+ private Mission mission;
+
+ /**
+ * The constructor.
+ *
+ * @param missionsTab the missions tab component
+ * @param mission the mission to add
+ */
+ public AddMissionCommand(MissionsTab missionsTab, Mission mission) {
+ this.missionsTab = missionsTab;
+ this.mission = mission;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ if(missionsTab.getScenarioPanel().getScenario().getMissionList().size() > 0) {
+ Mission prevMission = missionsTab.getScenarioPanel().getScenario().getMissionList().get(missionsTab.getScenarioPanel().getScenario().getMissionList().size()-1);
+ mission.setStartDate(DateFunctions.getDate(prevMission.getStartDate(), prevMission.getDuration()));
+ mission.setOrigin(prevMission.getOrigin());
+ mission.setDestination(prevMission.getDestination());
+ mission.setReturnOrigin(prevMission.getReturnOrigin());
+ mission.setReturnDestination(prevMission.getReturnDestination());
+ } else {
+ mission.setStartDate(missionsTab.getScenarioPanel().getScenario().getStartDate());
+ if(missionsTab.getScenarioPanel().getScenario().getNetwork().getNodes().size() > 0) {
+ mission.setOrigin(missionsTab.getScenarioPanel().getScenario().getNetwork().getNodes().first());
+ mission.setDestination(missionsTab.getScenarioPanel().getScenario().getNetwork().getNodes().first());
+ }
+ }
+ missionsTab.getScenarioPanel().getScenario().getMissionList().add(mission);
+ missionsTab.editMission(mission);
+ }
+
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/CloseScenarioCommand.java b/src/main/java/edu/mit/spacenet/gui/command/CloseScenarioCommand.java
new file mode 100644
index 0000000..925bb92
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/CloseScenarioCommand.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import javax.swing.JOptionPane;
+
+import edu.mit.spacenet.gui.SpaceNetFrame;
+
+/**
+ * The command to close a scenario.
+ *
+ * @author Paul Grogan
+ */
+public class CloseScenarioCommand {
+ private SpaceNetFrame spaceNetFrame;
+
+ /**
+ * The constructor.
+ *
+ * @param spaceNetFrame the SpaceNet frame component.
+ */
+ public CloseScenarioCommand(SpaceNetFrame spaceNetFrame) {
+ this.spaceNetFrame=spaceNetFrame;
+ }
+
+ /**
+ * Execute.
+ */
+ public void execute() {
+ int answer = JOptionPane.showOptionDialog(spaceNetFrame,
+ "Save " + spaceNetFrame.getScenarioPanel().getScenario().getName() + " before closing?",
+ "Close Warning", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
+ if(answer == JOptionPane.YES_OPTION) {
+ SaveScenarioCommand command = new SaveScenarioCommand(spaceNetFrame);
+ command.execute();
+ }
+ if(answer != JOptionPane.CANCEL_OPTION) spaceNetFrame.closeScenario();
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/CopyMissionCommand.java b/src/main/java/edu/mit/spacenet/gui/command/CopyMissionCommand.java
new file mode 100644
index 0000000..fe6eb7d
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/CopyMissionCommand.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import edu.mit.spacenet.domain.element.CrewMember;
+import edu.mit.spacenet.domain.element.I_Carrier;
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.domain.element.I_ResourceContainer;
+import edu.mit.spacenet.domain.element.I_State;
+import edu.mit.spacenet.domain.network.edge.Edge;
+import edu.mit.spacenet.domain.network.edge.FlightEdge;
+import edu.mit.spacenet.domain.network.edge.SpaceEdge;
+import edu.mit.spacenet.domain.network.edge.SurfaceEdge;
+import edu.mit.spacenet.domain.network.node.Node;
+import edu.mit.spacenet.gui.mission.MissionsTab;
+import edu.mit.spacenet.scenario.Mission;
+import edu.mit.spacenet.scenario.Scenario;
+import edu.mit.spacenet.simulator.event.AddEvent;
+import edu.mit.spacenet.simulator.event.BurnEvent;
+import edu.mit.spacenet.simulator.event.BurnStageItem;
+import edu.mit.spacenet.simulator.event.CreateEvent;
+import edu.mit.spacenet.simulator.event.DemandEvent;
+import edu.mit.spacenet.simulator.event.EvaEvent;
+import edu.mit.spacenet.simulator.event.ExplorationProcess;
+import edu.mit.spacenet.simulator.event.FlightTransport;
+import edu.mit.spacenet.simulator.event.I_Event;
+import edu.mit.spacenet.simulator.event.MoveEvent;
+import edu.mit.spacenet.simulator.event.ReconfigureEvent;
+import edu.mit.spacenet.simulator.event.ReconfigureGroupEvent;
+import edu.mit.spacenet.simulator.event.SpaceTransport;
+import edu.mit.spacenet.simulator.event.SurfaceTransport;
+import edu.mit.spacenet.simulator.event.TransferEvent;
+import edu.mit.spacenet.util.SerializeUtil;
+
+/**
+ * The command to copy a mission, performing all housekeeping operations to
+ * reset unique identifiers and redirect pointers after serialization.
+ *
+ * @author Paul Grogan
+ */
+public class CopyMissionCommand implements I_Command {
+ private MissionsTab missionsTab;
+ private Mission mission;
+
+ /**
+ * The constructor.
+ *
+ * @param missionsTab the missionsTab component
+ * @param mission the mission to copy
+ */
+ public CopyMissionCommand(MissionsTab missionsTab, Mission mission) {
+ this.missionsTab = missionsTab;
+ this.mission = mission;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ Mission mission = (Mission)SerializeUtil.deepClone(this.mission);
+ missionsTab.getScenarioPanel().getScenario().getMissionList().add(mission);
+ mission.setName(mission.getName() + " (Copy)");
+ GregorianCalendar g = new GregorianCalendar();
+ g.setTime(mission.getStartDate());
+ g.add(Calendar.MONTH, 1);
+ mission.setStartDate(g.getTime());
+ // note: must reset all links to data objects that were destroyed in serialization
+ mission.setScenario(missionsTab.getScenarioPanel().getScenario());
+ if(mission.getOrigin()!=null) {
+ mission.setOrigin(getNode(mission.getOrigin().getTid()));
+ }
+ if(mission.getDestination()!=null) {
+ mission.setDestination(getNode(mission.getDestination().getTid()));
+ }
+ if(mission.getReturnOrigin()!=null) {
+ mission.setReturnOrigin(getNode(mission.getReturnOrigin().getTid()));
+ }
+ if(mission.getReturnDestination()!=null) {
+ mission.setReturnDestination(getNode(mission.getReturnDestination().getTid()));
+ }
+ for(I_Event event : mission.getEventList()) {
+ event.resetUid();
+ if(event.getLocation() instanceof Edge) {
+ event.setLocation(getEdge(event.getLocation().getTid()));
+ } else if(event.getLocation() instanceof Node) {
+ event.setLocation(getNode(event.getLocation().getTid()));
+ }
+ if(event instanceof CreateEvent) {
+ for(I_Element o : ((CreateEvent)event).getElements()) {
+ o.resetUid();
+ }
+ if(((CreateEvent)event).getContainer() instanceof Node) {
+ ((CreateEvent)event).setContainer(event.getLocation());
+ } else if(((CreateEvent) event).getContainer() instanceof I_Carrier) {
+ ((CreateEvent)event).setContainer((I_Carrier)getElement(((I_Carrier)((CreateEvent)event).getContainer()).getUid()));
+ }
+ } else if(event instanceof MoveEvent) {
+ if(((MoveEvent)event).getContainer() instanceof Node) {
+ ((MoveEvent)event).setContainer(event.getLocation());
+ } else if(((MoveEvent) event).getContainer() instanceof I_Carrier) {
+ ((MoveEvent)event).setContainer((I_Carrier)getElement(((I_Carrier)((MoveEvent)event).getContainer()).getUid()));
+ }
+ List elements = new ArrayList();
+ for(I_Element element : ((MoveEvent)event).getElements()) {
+ elements.add(getElement(element.getUid()));
+ }
+ ((MoveEvent)event).getElements().clear();
+ ((MoveEvent)event).getElements().addAll(elements);
+ } else if(event instanceof TransferEvent) {
+ ((TransferEvent)event).setOriginContainer(
+ (I_ResourceContainer)getElement(
+ ((I_ResourceContainer)((TransferEvent)event).getOriginContainer()).getUid()));
+ ((TransferEvent)event).setDestinationContainer(
+ (I_ResourceContainer)getElement(
+ ((I_ResourceContainer)((TransferEvent)event).getDestinationContainer()).getUid()));
+ } else if(event instanceof AddEvent) {
+ ((AddEvent)event).setContainer(
+ (I_ResourceContainer)getElement(
+ ((I_ResourceContainer)((AddEvent)event).getContainer()).getUid()));
+ } else if(event instanceof DemandEvent) {
+ ((DemandEvent)event).setElement(
+ (I_ResourceContainer)getElement(
+ ((I_ResourceContainer)((DemandEvent)event).getElement()).getUid()));
+ } else if(event instanceof ReconfigureEvent) {
+ ((ReconfigureEvent)event).setElement(
+ (I_ResourceContainer)getElement(
+ ((I_ResourceContainer)((ReconfigureEvent)event).getElement()).getUid()));
+ for(I_State state : ((ReconfigureEvent)event).getElement().getStates()) {
+ if(state.equals(((ReconfigureEvent)event).getState())) {
+ ((ReconfigureEvent)event).setState(state);
+ break;
+ }
+ }
+ } else if(event instanceof ReconfigureGroupEvent) {
+ List elements = new ArrayList();
+ for(I_Element element : ((ReconfigureGroupEvent)event).getElements()) {
+ elements.add(getElement(element.getUid()));
+ }
+ ((ReconfigureGroupEvent)event).getElements().clear();
+ ((ReconfigureGroupEvent)event).getElements().addAll(elements);
+ } else if(event instanceof BurnEvent) {
+ for(BurnStageItem item : ((BurnEvent)event).getBurnStageSequence()) {
+ item.setElement(getElement(item.getElement().getUid()));
+ }
+ List elements = new ArrayList();
+ for(I_Element element : ((BurnEvent)event).getElements()) {
+ elements.add(getElement(element.getUid()));
+ }
+ ((BurnEvent)event).getElements().clear();
+ ((BurnEvent)event).getElements().addAll(elements);
+ } else if(event instanceof EvaEvent) {
+ Map map = new HashMap();
+ for(CrewMember crew : ((EvaEvent)event).getStateMap().keySet()) {
+ I_State s = ((EvaEvent)event).getStateMap().get(crew);
+ if(s==null) {
+ map.put((CrewMember)getElement(crew.getUid()), null);
+ } else {
+ for(I_State state : getElement(crew.getUid()).getStates()) {
+ if(state.equals(s)) {
+ map.put((CrewMember)getElement(crew.getUid()), state);
+ break;
+ }
+ }
+ }
+ }
+ ((EvaEvent)event).getStateMap().clear();
+ for(CrewMember crew : map.keySet()) {
+ ((EvaEvent)event).getStateMap().put(crew, map.get(crew));
+ }
+ ((EvaEvent)event).setVehicle((I_Carrier)getElement(((EvaEvent)event).getVehicle().getUid()));
+ } else if(event instanceof ExplorationProcess) {
+ Map map = new HashMap();
+ for(CrewMember crew : ((ExplorationProcess)event).getStateMap().keySet()) {
+ I_State s = ((ExplorationProcess)event).getStateMap().get(crew);
+ if(s==null) {
+ map.put((CrewMember)getElement(crew.getUid()), null);
+ } else {
+ for(I_State state : getElement(crew.getUid()).getStates()) {
+ if(state.equals(s)) {
+ map.put((CrewMember)getElement(crew.getUid()), state);
+ break;
+ }
+ }
+ }
+ }
+ ((ExplorationProcess)event).getStateMap().clear();
+ for(CrewMember crew : map.keySet()) {
+ ((ExplorationProcess)event).getStateMap().put(crew, map.get(crew));
+ }
+ ((ExplorationProcess)event).setVehicle((I_Carrier)getElement(((ExplorationProcess)event).getVehicle().getUid()));
+ } else if(event instanceof SpaceTransport) {
+ List> sequenceList = new ArrayList>();
+ for(List list : ((SpaceTransport)event).getBurnStageSequence()) {
+ List sequence = new ArrayList();
+ for(BurnStageItem item : list) {
+ item.setElement(getElement(item.getElement().getUid()));
+ sequence.add(item);
+ }
+ sequenceList.add(sequence);
+ }
+ ((SpaceTransport)event).setEdge((SpaceEdge)getEdge(((SpaceTransport)event).getEdge().getTid()));
+ ((SpaceTransport)event).getBurnStageSequence().clear();
+ for(List list : sequenceList) {
+ ((SpaceTransport)event).getBurnStageSequence().add(list);
+ }
+ List elements = new ArrayList();
+ for(I_Element element : ((SpaceTransport)event).getElements()) {
+ elements.add(getElement(element.getUid()));
+ }
+ ((SpaceTransport)event).getElements().clear();
+ ((SpaceTransport)event).getElements().addAll(elements);
+ } else if(event instanceof SurfaceTransport) {
+ ((SurfaceTransport)event).setEdge((SurfaceEdge)getEdge(((SurfaceTransport)event).getEdge().getTid()));
+ List elements = new ArrayList();
+ for(I_Element element : ((SurfaceTransport)event).getElements()) {
+ elements.add(getElement(element.getUid()));
+ }
+ ((SurfaceTransport)event).getElements().clear();
+ ((SurfaceTransport)event).getElements().addAll(elements);
+ } else if(event instanceof FlightTransport) {
+ ((FlightTransport)event).setEdge((FlightEdge)getEdge(((FlightTransport)event).getEdge().getTid()));
+ List elements = new ArrayList();
+ for(I_Element element : ((FlightTransport)event).getElements()) {
+ elements.add(getElement(element.getUid()));
+ }
+ ((FlightTransport)event).getElements().clear();
+ ((FlightTransport)event).getElements().addAll(elements);
+ }
+ }
+ missionsTab.editMission(mission);
+ }
+ private Node getNode(int tid) {
+ return getScenario().getNetwork().getNodeByTid(tid);
+ }
+ private Edge getEdge(int tid) {
+ return getScenario().getNetwork().getEdgeByTid(tid);
+ }
+ private I_Element getElement(int uid) {
+ return getScenario().getElementByUid(uid);
+ }
+ private Scenario getScenario() {
+ return missionsTab.getScenarioPanel().getScenario();
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/EditMissionCommand.java b/src/main/java/edu/mit/spacenet/gui/command/EditMissionCommand.java
new file mode 100644
index 0000000..9d1fd3b
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/EditMissionCommand.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import edu.mit.spacenet.gui.mission.MissionsTab;
+import edu.mit.spacenet.scenario.Mission;
+
+/**
+ * The command to edit a mission.
+ *
+ * @author Paul Grogan
+ */
+public class EditMissionCommand implements I_Command {
+ private MissionsTab missionsTab;
+ private Mission mission;
+
+ /**
+ * The constructor.
+ *
+ * @param missionsTab the missions tab component.
+ * @param mission the mission to edit
+ */
+ public EditMissionCommand(MissionsTab missionsTab, Mission mission) {
+ this.missionsTab = missionsTab;
+ this.mission = mission;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ missionsTab.editMission(mission);
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/FilterNetworkCommand.java b/src/main/java/edu/mit/spacenet/gui/command/FilterNetworkCommand.java
new file mode 100644
index 0000000..d51c96d
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/FilterNetworkCommand.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.mit.spacenet.domain.network.Location;
+import edu.mit.spacenet.domain.network.edge.Edge;
+import edu.mit.spacenet.domain.network.node.Node;
+import edu.mit.spacenet.scenario.Scenario;
+
+/**
+ * The command to filter the scenario network based on its scenario type. Any
+ * nodes or edges that are in use will not be removed by this operation.
+ *
+ * @author Paul Grogan
+ */
+public class FilterNetworkCommand implements I_Command {
+ private Scenario scenario;
+
+ /**
+ * The constructor.
+ *
+ * @param scenarioPanel the scenario panel component
+ */
+ public FilterNetworkCommand(Scenario scenario) {
+ this.scenario = scenario;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ List forAddition = new ArrayList();
+ List forRemoval = new ArrayList();
+ for(Node node : scenario.getDataSource().getNodeLibrary()) {
+ if(!scenario.getNetwork().getNodes().contains(node)
+ && scenario.getScenarioType().isNodeVisible(node)) {
+ forAddition.add(node);
+ } else if(scenario.getNetwork().getNodes().contains(node)
+ && !scenario.isNodeUsed(node)
+ && !scenario.getScenarioType().isNodeVisible(node)) {
+ forRemoval.add(node);
+ }
+ }
+ for(Edge edge : scenario.getDataSource().getEdgeLibrary()) {
+ if(!scenario.getNetwork().getEdges().contains(edge)
+ && scenario.getScenarioType().isEdgeVisible(edge)) {
+ forAddition.add(edge);
+ } else if(scenario.getNetwork().getEdges().contains(edge)
+ && !scenario.isEdgeUsed(edge)
+ && !scenario.getScenarioType().isEdgeVisible(edge)) {
+ forRemoval.add(edge);
+ }
+ }
+ for(Location location : forAddition) {
+ scenario.getNetwork().add(location);
+ }
+ for(Location location : forRemoval) {
+ scenario.getNetwork().remove(location);
+ }
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/I_Command.java b/src/main/java/edu/mit/spacenet/gui/command/I_Command.java
new file mode 100644
index 0000000..4e1a4af
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/I_Command.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+/**
+ * Interface for all SpaceNet commands.
+ *
+ * @author Paul Grogan
+ */
+public interface I_Command {
+
+ /**
+ * Executes the command.
+ */
+ public void execute();
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/LoadDataSourceCommand.java b/src/main/java/edu/mit/spacenet/gui/command/LoadDataSourceCommand.java
new file mode 100644
index 0000000..b9fbfd8
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/LoadDataSourceCommand.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.util.List;
+
+import javax.swing.BoxLayout;
+import javax.swing.DefaultListModel;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingWorker;
+
+import edu.mit.spacenet.domain.element.Carrier;
+import edu.mit.spacenet.domain.element.CrewMember;
+import edu.mit.spacenet.domain.element.ElementType;
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.domain.element.PropulsiveVehicle;
+import edu.mit.spacenet.domain.element.ResourceContainer;
+import edu.mit.spacenet.domain.element.SurfaceVehicle;
+import edu.mit.spacenet.gui.ScenarioPanel;
+import edu.mit.spacenet.gui.SpaceNetFrame;
+import edu.mit.spacenet.gui.data.DataSourceDialog;
+
+/**
+ * Command to load the libraries from the scenario data source.
+ *
+ * @author Paul Grogan
+ */
+public class LoadDataSourceCommand implements I_Command {
+ private DataSourceDialog dataSourceDialog;
+ private ScenarioPanel scenarioPanel;
+
+ /**
+ * The constructor if called from the data source dialog.
+ *
+ * @param dataSourceDialog the data source dialog component
+ */
+ public LoadDataSourceCommand(DataSourceDialog dataSourceDialog) {
+ this.dataSourceDialog = dataSourceDialog;
+ scenarioPanel = dataSourceDialog.getScenarioPanel();
+ }
+
+ /**
+ * The constructor if called from the scenario panel.
+ *
+ * @param scenarioPanel the scenario panel
+ */
+ public LoadDataSourceCommand(ScenarioPanel scenarioPanel) {
+ this.scenarioPanel = scenarioPanel;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ SwingWorker worker = new SwingWorker() {
+ public Void doInBackground() {
+ SpaceNetFrame.getInstance().getStatusBar().setStatusMessage("Loading Data Source...");
+ scenarioPanel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ try {
+ List errors = scenarioPanel.getScenario().getDataSource().validateData();
+ if(errors.size() > 0) {
+ JPanel errorPanel = new JPanel();
+ errorPanel.setLayout(new BoxLayout(errorPanel, BoxLayout.PAGE_AXIS));
+ errorPanel.add(new JLabel("The following errors occurred: "));
+ DefaultListModel errorsModel = new DefaultListModel();
+ for(String e : errors) {
+ errorsModel.addElement(e);
+ }
+ errorPanel.add(new JScrollPane(new JList(errorsModel)));
+ errorPanel.add(new JLabel("Please make the necessary changes and reload database."));
+ JOptionPane.showMessageDialog(getComponent(), errorPanel, "Load Error", JOptionPane.ERROR_MESSAGE);
+ } else {
+ if(dataSourceDialog==null) {
+ scenarioPanel.getScenario().getDataSource().loadLibraries();
+ } else {
+ scenarioPanel.getScenario().getDataSource().loadLibraries(
+ dataSourceDialog.updateNodes(),
+ dataSourceDialog.updateEdges(),
+ dataSourceDialog.updateResources());
+ }
+ if(dataSourceDialog!=null&&dataSourceDialog.updateInstantiatedElements()) {
+ for(I_Element element : scenarioPanel.getScenario().getElements()) {
+ if(element.getTid() > 0) {
+ I_Element mirror = scenarioPanel.getScenario().getDataSource().loadElement(element.getTid());
+ if(mirror.getClass().equals(element.getClass())) {
+ element.setAccommodationMass(mirror.getAccommodationMass());
+ element.setClassOfSupply(mirror.getClassOfSupply());
+ element.setDescription(mirror.getDescription());
+ element.setEnvironment(mirror.getEnvironment());
+ element.setMass(mirror.getMass());
+ element.setStates(mirror.getStates());
+ element.setCurrentState(mirror.getCurrentState());
+ element.setParts(mirror.getParts());
+ element.setVolume(mirror.getVolume());
+ element.setIconType(mirror.getIconType());
+ if(element.getElementType()==ElementType.RESOURCE_CONTAINER) {
+ ((ResourceContainer)element).setMaxCargoMass(((ResourceContainer)mirror).getMaxCargoMass());
+ ((ResourceContainer)element).setMaxCargoVolume(((ResourceContainer)mirror).getMaxCargoVolume());
+ ((ResourceContainer)element).setCargoEnvironment(((ResourceContainer)mirror).getCargoEnvironment());
+ // NOTE: presently does not carry over any changes to contents
+ } else if(element.getElementType()==ElementType.CARRIER) {
+ ((Carrier)element).setMaxCrewSize(((Carrier)mirror).getMaxCrewSize());
+ ((Carrier)element).setMaxCargoMass(((Carrier)mirror).getMaxCargoMass());
+ ((Carrier)element).setMaxCargoVolume(((Carrier)mirror).getMaxCargoVolume());
+ ((Carrier)element).setCargoEnvironment(((Carrier)mirror).getCargoEnvironment());
+ } else if(element.getElementType()==ElementType.PROPULSIVE_VEHICLE) {
+ ((PropulsiveVehicle)element).setMaxCrewSize(((PropulsiveVehicle)mirror).getMaxCrewSize());
+ ((PropulsiveVehicle)element).setMaxCargoMass(((PropulsiveVehicle)mirror).getMaxCargoMass());
+ ((PropulsiveVehicle)element).setMaxCargoVolume(((PropulsiveVehicle)mirror).getMaxCargoVolume());
+ ((PropulsiveVehicle)element).setCargoEnvironment(((PropulsiveVehicle)mirror).getCargoEnvironment());
+ ((PropulsiveVehicle)element).setOmsIsp(((PropulsiveVehicle)mirror).getOmsIsp());
+ ((PropulsiveVehicle)element).setOmsFuelTank(((PropulsiveVehicle)mirror).getOmsFuelTank());
+ ((PropulsiveVehicle)element).setRcsIsp(((PropulsiveVehicle)mirror).getRcsIsp());
+ ((PropulsiveVehicle)element).setRcsFuelTank(((PropulsiveVehicle)mirror).getRcsFuelTank());
+ } else if(element.getElementType()==ElementType.SURFACE_VEHICLE) {
+ ((SurfaceVehicle)element).setMaxCrewSize(((SurfaceVehicle)mirror).getMaxCrewSize());
+ ((SurfaceVehicle)element).setMaxCargoMass(((SurfaceVehicle)mirror).getMaxCargoMass());
+ ((SurfaceVehicle)element).setMaxCargoVolume(((SurfaceVehicle)mirror).getMaxCargoVolume());
+ ((SurfaceVehicle)element).setCargoEnvironment(((SurfaceVehicle)mirror).getCargoEnvironment());
+ ((SurfaceVehicle)element).setMaxSpeed(((SurfaceVehicle)mirror).getMaxSpeed());
+ ((SurfaceVehicle)element).setFuelTank(((SurfaceVehicle)mirror).getFuelTank());
+ } else if(element.getElementType()==ElementType.CREW_MEMBER) {
+ ((CrewMember)element).setAvailableTimeFraction(((CrewMember)mirror).getAvailableTimeFraction());
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch(Exception ex) {
+ JOptionPane.showMessageDialog(getComponent(),
+ "There was a problem opening the data source.",
+ "SpaceNet Error", JOptionPane.ERROR_MESSAGE);
+ ex.printStackTrace();
+ }
+ return null;
+ }
+ public void done() {
+ SpaceNetFrame.getInstance().getStatusBar().clearStatusMessage();
+ scenarioPanel.setCursor(Cursor.getDefaultCursor());
+
+ if(scenarioPanel.getScenario().getNetwork().getLocations().size()==0) {
+ FilterNetworkCommand command = new FilterNetworkCommand(scenarioPanel.getScenario());
+ command.execute();
+ }
+
+ if(dataSourceDialog!=null) dataSourceDialog.updateTables();
+ scenarioPanel.updateView();
+ }
+ };
+ worker.execute();
+ }
+ private Component getComponent() {
+ if(dataSourceDialog==null) return scenarioPanel;
+ else return dataSourceDialog;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/NewScenarioCommand.java b/src/main/java/edu/mit/spacenet/gui/command/NewScenarioCommand.java
new file mode 100644
index 0000000..1f84479
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/NewScenarioCommand.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import edu.mit.spacenet.gui.SpaceNetFrame;
+
+/**
+ * The command to create a new scenario.
+ *
+ * @author Paul Grogan
+ */
+public class NewScenarioCommand implements I_Command {
+ private SpaceNetFrame spaceNetFrame;
+
+ /**
+ * The constructor.
+ *
+ * @param spaceNetFrame the SpaceNet frame
+ */
+ public NewScenarioCommand(SpaceNetFrame spaceNetFrame) {
+ this.spaceNetFrame=spaceNetFrame;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ spaceNetFrame.newScenario();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/gui/command/OpenScenarioCommand.java b/src/main/java/edu/mit/spacenet/gui/command/OpenScenarioCommand.java
new file mode 100644
index 0000000..0186dff
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/OpenScenarioCommand.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import java.awt.Cursor;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import javax.swing.SwingWorker;
+
+import edu.mit.spacenet.gui.SpaceNetFrame;
+
+/**
+ * The command to open a saved scenario.
+ *
+ * @author Paul Grogan
+ */
+public class OpenScenarioCommand implements I_Command {
+ private SpaceNetFrame spaceNetFrame;
+
+ /**
+ * The constructor.
+ *
+ * @param spaceNetFrame the SpaceNet frame
+ */
+ public OpenScenarioCommand(SpaceNetFrame spaceNetFrame) {
+ this.spaceNetFrame=spaceNetFrame;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ int returnVal = spaceNetFrame.getScenarioChooser().showOpenDialog(spaceNetFrame);
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ SwingWorker worker = new SwingWorker() {
+ public Void doInBackground() {
+ SpaceNetFrame.getInstance().getStatusBar().setStatusMessage("Opening Scenario...");
+ spaceNetFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ try {
+ spaceNetFrame.openScenario(spaceNetFrame.getScenarioChooser().getSelectedFile().getAbsolutePath());
+ } catch(Exception ex) {
+ // display error message if one occurs... since this
+ // is inside a worker thread, the stack trace will
+ // not be printed unless directed handled here
+ JOptionPane.showMessageDialog(null,
+ "An error of type \"" +
+ ex.getClass().getSimpleName() +
+ "\" occurred while opening " +
+ spaceNetFrame.getScenarioChooser().getSelectedFile() +
+ ".\n",
+ "SpaceNet Error",
+ JOptionPane.ERROR_MESSAGE);
+ ex.printStackTrace();
+ }
+ return null;
+ }
+ public void done() {
+ SpaceNetFrame.getInstance().getStatusBar().clearStatusMessage();
+ spaceNetFrame.setCursor(Cursor.getDefaultCursor());
+ }
+ };
+ worker.execute();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/mit/spacenet/gui/command/RemoveMissionCommand.java b/src/main/java/edu/mit/spacenet/gui/command/RemoveMissionCommand.java
new file mode 100644
index 0000000..d19ac34
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/RemoveMissionCommand.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.List;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import edu.mit.spacenet.gui.mission.MissionsTab;
+import edu.mit.spacenet.scenario.Mission;
+
+/**
+ * The command to remove one or more missions.
+ *
+ * @author Paul Grogan
+ */
+public class RemoveMissionCommand implements I_Command {
+ private MissionsTab missionsTab;
+ private List missions;
+
+ /**
+ * The constructor.
+ *
+ * @param missionsTab the missions tab component
+ * @param missions the missions to remove
+ */
+ public RemoveMissionCommand(MissionsTab missionsTab, List missions) {
+ this.missionsTab = missionsTab;
+ this.missions = missions;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ JPanel warningPanel = new JPanel();
+ warningPanel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0;
+ c.weighty = 0;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.BOTH;
+ warningPanel.add(new JLabel("Permanently delete the following missions?"), c);
+ c.gridy++;
+ c.weighty = 1;
+ DefaultListModel missionsList = new DefaultListModel();
+ for(Mission m : missions) {
+ missionsList.addElement(m);
+ }
+ warningPanel.add(new JScrollPane(new JList(missionsList)), c);
+ int answer = JOptionPane.showOptionDialog(missionsTab,
+ warningPanel,
+ "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
+ if (answer == JOptionPane.YES_OPTION) {
+ for(Mission mission : missions) {
+ missionsTab.getScenarioPanel().getScenario().getMissionList().remove(mission);
+ }
+ }
+ missionsTab.updateView();
+ }
+
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/SaveScenarioAsCommand.java b/src/main/java/edu/mit/spacenet/gui/command/SaveScenarioAsCommand.java
new file mode 100644
index 0000000..beebeb8
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/SaveScenarioAsCommand.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import java.io.File;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+
+import edu.mit.spacenet.gui.SpaceNetFrame;
+import edu.mit.spacenet.gui.SpaceNetSettings;
+import edu.mit.spacenet.io.XMLFileFilter;
+
+/**
+ * The command to save a scenario with a new filename.
+ *
+ * @author Paul Grogan
+ */
+public class SaveScenarioAsCommand implements I_Command {
+ private SpaceNetFrame spaceNetFrame;
+
+ /**
+ * The constructor.
+ *
+ * @param spaceNetFrame the SpaceNet frame
+ */
+ public SaveScenarioAsCommand(SpaceNetFrame spaceNetFrame) {
+ this.spaceNetFrame=spaceNetFrame;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ JFileChooser fileChooser = new JFileChooser(SpaceNetSettings.getInstance().getDefaultDirectory()) {
+ private static final long serialVersionUID = 5853237903722516861L;
+ public void approveSelection() {
+ File file = getSelectedFile();
+ if (file != null && file.exists()) {
+ int answer = JOptionPane.showOptionDialog(spaceNetFrame,
+ "File " + file.getAbsolutePath() + " already exists. Overwrite?",
+ "Save Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
+ if (answer == JOptionPane.NO_OPTION) {
+ return;
+ }
+ }
+ super.approveSelection();
+ }
+ };
+ fileChooser.setFileFilter(new XMLFileFilter());
+ if (fileChooser.showSaveDialog(spaceNetFrame) == JFileChooser.APPROVE_OPTION) {
+ String filepath = fileChooser.getSelectedFile().getAbsolutePath();
+ if(!filepath.substring(filepath.length() - 4, filepath.length()).equals(".xml")) {
+ filepath += ".xml";
+ }
+ spaceNetFrame.getScenarioPanel().getScenario().setFilePath(filepath);
+ SaveScenarioCommand command = new SaveScenarioCommand(spaceNetFrame);
+ command.execute();
+ }
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/command/SaveScenarioCommand.java b/src/main/java/edu/mit/spacenet/gui/command/SaveScenarioCommand.java
new file mode 100644
index 0000000..0fe6070
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/command/SaveScenarioCommand.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.command;
+
+import java.awt.Cursor;
+
+import javax.swing.SwingWorker;
+
+import edu.mit.spacenet.gui.SpaceNetFrame;
+
+/**
+ * The command to save a scenario with the current filename (launches a save as
+ * command if no file name exists).
+ *
+ * @author Paul Grogan
+ */
+public class SaveScenarioCommand implements I_Command {
+ private SpaceNetFrame spaceNetFrame;
+
+ /**
+ * The constructor.
+ *
+ * @param spaceNetFrame the SpaceNet frame
+ */
+ public SaveScenarioCommand(SpaceNetFrame spaceNetFrame) {
+ this.spaceNetFrame=spaceNetFrame;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.mit.spacenet.gui.command.I_Command#execute()
+ */
+ public void execute() {
+ if(spaceNetFrame.getScenarioPanel().getScenario().getFilePath() == null) {
+ SaveScenarioAsCommand command = new SaveScenarioAsCommand(spaceNetFrame);
+ command.execute();
+ } else {
+ SwingWorker worker = new SwingWorker() {
+ public Void doInBackground() {
+ SpaceNetFrame.getInstance().getStatusBar().setStatusMessage("Saving Scenario "
+ + spaceNetFrame.getScenarioPanel().getScenario().getFileName()
+ + "...");
+ spaceNetFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ spaceNetFrame.saveScenario();
+ return null;
+ }
+ public void done() {
+ SpaceNetFrame.getInstance().getStatusBar().clearStatusMessage();
+ spaceNetFrame.setCursor(Cursor.getDefaultCursor());
+ SpaceNetFrame.getInstance().getStatusBar().setStatusMessage("Scenario "
+ + spaceNetFrame.getScenarioPanel().getScenario().getFileName()
+ + " Saved Successfully", false);
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(3000);
+ } catch(InterruptedException e) { }
+ spaceNetFrame.getStatusBar().setStatusMessage("", false);
+ }
+ });
+
+ }
+ };
+ worker.execute();
+ }
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/component/CapacityPanel.java b/src/main/java/edu/mit/spacenet/gui/component/CapacityPanel.java
new file mode 100644
index 0000000..0cfdd93
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/component/CapacityPanel.java
@@ -0,0 +1,254 @@
+package edu.mit.spacenet.gui.component;
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.text.DecimalFormat;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+
+import edu.mit.spacenet.domain.Environment;
+import edu.mit.spacenet.domain.element.I_Carrier;
+import edu.mit.spacenet.domain.element.I_ResourceContainer;
+import edu.mit.spacenet.domain.network.Location;
+import edu.mit.spacenet.util.GlobalParameters;
+
+/**
+ * The CapacityPanel class displays capacity progress bars for mass, volume,
+ * (if volume-constrained), and crew (if carrier).
+ */
+public class CapacityPanel extends JPanel {
+ private static final long serialVersionUID = 8033464124593156155L;
+ private JProgressBar massCapacity, volumeCapacity, crewCapacity;
+ private JLabel environmentLabel, massLabel, volumeLabel, crewLabel;
+ private DecimalFormat massFormat = new DecimalFormat("0.0"),
+ volumeFormat = new DecimalFormat("0.000");
+
+ /**
+ * Instantiates a new capacity panel.
+ */
+ public CapacityPanel() {
+ initializePanel();
+ }
+
+ /**
+ * Initialize panel.
+ */
+ private void initializePanel() {
+ setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.insets = new Insets(2,2,2,2);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 0;
+ c.weighty = 0;
+ c.gridwidth = 2;
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ environmentLabel = new JLabel();
+ environmentLabel.setHorizontalAlignment(JLabel.CENTER);
+ add(environmentLabel, c);
+ c.gridy++;
+ c.gridwidth = 1;
+ c.weightx = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ massCapacity = new JProgressBar(0, 100);
+ massCapacity.setStringPainted(true);
+ massCapacity.setVisible(false);
+ add(massCapacity, c);
+ c.gridy++;
+ volumeCapacity = new JProgressBar(0, 100);
+ volumeCapacity.setStringPainted(true);
+ volumeCapacity.setVisible(false);
+ add(volumeCapacity, c);
+ c.gridy++;
+ crewCapacity = new JProgressBar(0, 100);
+ crewCapacity.setStringPainted(true);
+ crewCapacity.setVisible(false);
+ add(crewCapacity, c);
+ c.fill = GridBagConstraints.NONE;
+ c.gridx++;
+ c.gridy = 1;
+ c.weightx = 0;
+ c.anchor = GridBagConstraints.LINE_START;
+ massLabel = new JLabel(" Cargo Mass");
+ massLabel.setVisible(false);
+ add(massLabel, c);
+ c.gridy++;
+ volumeLabel = new JLabel(" Cargo Volume");
+ volumeLabel.setVisible(false);
+ add(volumeLabel, c);
+ c.gridy++;
+ crewLabel = new JLabel(" Crew");
+ crewLabel.setVisible(false);
+ add(crewLabel, c);
+ }
+
+ /**
+ * Update capacities.
+ *
+ * @param element the element
+ * @param mass the mass
+ * @param volume the volume
+ * @param crew the crew
+ * @return true, if successful
+ */
+ public boolean updateCapacities(I_ResourceContainer container, double mass, double volume) {
+ boolean hasErrors = false;
+ if(GlobalParameters.isEnvironmentConstrained()) {
+ environmentLabel.setVisible(true);
+ environmentLabel.setText(container.getCargoEnvironment().getName());
+ } else {
+ environmentLabel.setVisible(false);
+ }
+ massCapacity.setVisible(true);
+ massLabel.setVisible(true);
+ if(mass > container.getMaxCargoMass()) {
+ hasErrors = true;
+ massCapacity.setForeground(new Color(153, 0, 0));
+ } else {
+ massCapacity.setForeground(new Color(0, 153, 0));
+ }
+ if(container.getMaxCargoMass()==0) {
+ massCapacity.setValue(100);
+ } else {
+ massCapacity.setValue((int)(100*mass/container.getMaxCargoMass()));
+ }
+ massCapacity.setString(massFormat.format(mass) + " / "
+ + massFormat.format(container.getMaxCargoMass()) + " kg");
+ if(GlobalParameters.isVolumeConstrained()) {
+ volumeCapacity.setVisible(true);
+ volumeLabel.setVisible(true);
+ if(volume > container.getMaxCargoVolume()) {
+ hasErrors = hasErrors||GlobalParameters.isVolumeConstrained();
+ volumeCapacity.setForeground(new Color(153, 0, 0));
+ } else {
+ volumeCapacity.setForeground(new Color(0, 153, 0));
+ }
+ if(container.getMaxCargoVolume()==0) {
+ volumeCapacity.setValue(100);
+ } else {
+ volumeCapacity.setValue((int)(100*volume/container.getMaxCargoVolume()));
+ }
+ volumeCapacity.setString(volumeFormat.format(volume) + " / "
+ + volumeFormat.format(container.getMaxCargoVolume()) + " m^3");
+ } else {
+ volumeCapacity.setVisible(false);
+ volumeLabel.setVisible(false);
+ }
+ crewCapacity.setVisible(false);
+ crewLabel.setVisible(false);
+ return hasErrors;
+ }
+
+ /**
+ * Update capacities.
+ *
+ * @param carrier the carrier
+ * @param mass the mass
+ * @param volume the volume
+ * @param crew the crew
+ * @return true, if successful
+ */
+ public boolean updateCapacities(I_Carrier carrier, double mass, double volume, int crew) {
+ boolean hasErrors = false;
+ if(GlobalParameters.isEnvironmentConstrained()) {
+ environmentLabel.setVisible(true);
+ environmentLabel.setText(carrier.getCargoEnvironment().getName());
+ } else {
+ environmentLabel.setVisible(false);
+ }
+ massCapacity.setVisible(true);
+ massLabel.setVisible(true);
+ if(mass > carrier.getMaxCargoMass()) {
+ hasErrors = true;
+ massCapacity.setForeground(new Color(153, 0, 0));
+ } else {
+ massCapacity.setForeground(new Color(0, 153, 0));
+ }
+ if(carrier.getMaxCargoMass()==0) {
+ massCapacity.setValue(100);
+ } else {
+ massCapacity.setValue((int)(100*mass/carrier.getMaxCargoMass()));
+ }
+ massCapacity.setString(massFormat.format(mass) + " / "
+ + massFormat.format(carrier.getMaxCargoMass()) + " kg");
+ if(GlobalParameters.isVolumeConstrained()) {
+ volumeCapacity.setVisible(true);
+ volumeLabel.setVisible(true);
+ if(volume > carrier.getMaxCargoVolume()) {
+ hasErrors = hasErrors||GlobalParameters.isVolumeConstrained();
+ volumeCapacity.setForeground(new Color(153, 0, 0));
+ } else {
+ volumeCapacity.setForeground(new Color(0, 153, 0));
+ }
+ if(carrier.getMaxCargoVolume()==0) {
+ volumeCapacity.setValue(100);
+ } else {
+ volumeCapacity.setValue((int)(100*volume/carrier.getMaxCargoVolume()));
+ }
+ volumeCapacity.setString(volumeFormat.format(volume) + " / "
+ + volumeFormat.format(carrier.getMaxCargoVolume()) + " m^3");
+ } else {
+ volumeCapacity.setVisible(false);
+ volumeLabel.setVisible(false);
+ }
+ crewCapacity.setVisible(true);
+ crewLabel.setVisible(true);
+ if(crew > carrier.getMaxCrewSize()) {
+ hasErrors = true;
+ crewCapacity.setForeground(new Color(153, 0, 0));
+ } else {
+ crewCapacity.setForeground(new Color(0, 153, 0));
+ }
+ if(carrier.getMaxCrewSize()==0) {
+ crewCapacity.setValue(100);
+ } else {
+ crewCapacity.setValue((int)(100*crew/carrier.getMaxCrewSize()));
+ }
+ crewCapacity.setString((int)crew + " / "
+ + carrier.getMaxCrewSize() + " crew");
+ return hasErrors;
+ }
+
+ /**
+ * Update capacities.
+ *
+ * @param location the location
+ * @param mass the mass
+ * @param volume the volume
+ * @param crew the crew
+ * @return true, if successful
+ */
+ public boolean updateCapacities(Location location, double mass, double volume, int crew) {
+ if(GlobalParameters.isEnvironmentConstrained()) {
+ environmentLabel.setText(Environment.UNPRESSURIZED.getName());
+ } else {
+ environmentLabel.setVisible(false);
+ }
+ massCapacity.setVisible(true);
+ massLabel.setVisible(true);
+ massCapacity.setForeground(new Color(0, 153, 0));
+ massCapacity.setValue(0);
+ massCapacity.setString(massFormat.format(mass) + " kg");
+ if(GlobalParameters.isVolumeConstrained()) {
+ volumeCapacity.setVisible(true);
+ volumeLabel.setVisible(true);
+ volumeCapacity.setForeground(new Color(0, 153, 0));
+ volumeCapacity.setValue(0);
+ volumeCapacity.setString(volumeFormat.format(volume) + " m^3");
+ } else {
+ volumeCapacity.setVisible(false);
+ volumeLabel.setVisible(false);
+ }
+ crewCapacity.setVisible(true);
+ crewLabel.setVisible(true);
+ crewCapacity.setForeground(new Color(0, 153, 0));
+ crewCapacity.setValue(0);
+ crewCapacity.setString((int)crew + " crew");
+ return false;
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/component/CheckBoxNode.java b/src/main/java/edu/mit/spacenet/gui/component/CheckBoxNode.java
new file mode 100644
index 0000000..1644940
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/component/CheckBoxNode.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.component;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import edu.mit.spacenet.domain.I_Container;
+import edu.mit.spacenet.domain.element.I_Element;
+
+/**
+ * Node for the associated CheckBoxTree that represents elements as a check box,
+ * so they can easily be checked or unchecked for selection.
+ *
+ * @author Paul Grogan
+ */
+public class CheckBoxNode extends DefaultMutableTreeNode {
+ private static final long serialVersionUID = -2315502537628420250L;
+ private CheckBoxNodeComponent component;
+
+ /**
+ * The constructor.
+ *
+ * @param checkBox the underlying check box component
+ */
+ public CheckBoxNode(CheckBoxNodeComponent checkBox) {
+ super(checkBox);
+ this.component = checkBox;
+ }
+
+ /**
+ * Gets the check box component for display.
+ *
+ * @return the check box component
+ */
+ public CheckBoxNodeComponent getCheckBox() {
+ return component;
+ }
+
+ /**
+ * Gets the element packaged inside the node.
+ *
+ * @return the element
+ */
+ public I_Element getElement() {
+ return component.getElement();
+ }
+
+ /**
+ * Gets whether the check box is checked.
+ *
+ * @return whether the check box is checked
+ */
+ public boolean isChecked() {
+ return component.isChecked();
+ }
+
+ /**
+ * Sets whether the check box is checked.
+ *
+ * @param isChecked whether the check box is checked
+ */
+ public void setChecked(boolean isChecked) {
+ component.setChecked(isChecked);
+ }
+
+ /**
+ * Static method to create a new tree node hierarchy for elements and nested
+ * elements.
+ *
+ * @param object the root object
+ *
+ * @return the tree node
+ */
+ public static DefaultMutableTreeNode createNode(Object object) {
+ DefaultMutableTreeNode node = null;
+ if(object instanceof I_Element) {
+ node = new CheckBoxNode(new CheckBoxNodeComponent((I_Element)object));
+ } else {
+ node = new DefaultMutableTreeNode(object);
+ }
+
+ if(object instanceof I_Container) {
+ int index = 0;
+ for(I_Element e : ((I_Container) object).getContents()) {
+ node.insert(createNode(e), index++);
+ }
+ }
+ return node;
+ }
+
+ /**
+ * The Class CheckBoxNodeComponent.
+ *
+ * @author Paul Grogan
+ * The visual component of a check box node. Includes a reference to the
+ * underlying element to be represented along with a check box and a label
+ * (for display of the element icon).
+ */
+ public static class CheckBoxNodeComponent extends JPanel {
+ private static final long serialVersionUID = -4070444077100724836L;
+ private I_Element element;
+ private JCheckBox checkBox;
+ private JLabel label;
+
+ /**
+ * The constructor.
+ *
+ * @param element the element to represent
+ * @param isChecked whether the check box should initially be checked
+ */
+ public CheckBoxNodeComponent(I_Element element, boolean isChecked) {
+ super();
+ setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
+ setOpaque(false);
+ checkBox = new JCheckBox("",isChecked);
+ checkBox.setOpaque(false);
+ this.element = element;
+ label = new JLabel(getElement().getName(), getElement().getIcon(), JLabel.LEFT);
+ label.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
+ label.setOpaque(true);
+ add(checkBox);
+ add(label);
+ }
+
+ /**
+ * The constructor.
+ *
+ * @param element the element to represent
+ */
+ public CheckBoxNodeComponent(I_Element element) {
+ this(element, false);
+ }
+
+ /**
+ * Gets the underlying element.
+ *
+ * @return the element
+ */
+ public I_Element getElement() {
+ return element;
+ }
+
+ /**
+ * Gets the check box component.
+ *
+ * @return the check box component
+ */
+ public JCheckBox getCheckBox() {
+ return checkBox;
+ }
+
+ /**
+ * Gets the label component.
+ *
+ * @return the label component
+ */
+ public JLabel getLabel() {
+ return label;
+ }
+
+ /**
+ * Gets whether the check box is checked.
+ *
+ * @return whether the check box is checked
+ */
+ public boolean isChecked() {
+ return checkBox.isSelected();
+ }
+
+ /**
+ * Sets whether the check box is checked.
+ *
+ * @param isChecked whether the check box is checked
+ */
+ public void setChecked(boolean isChecked) {
+ checkBox.setSelected(isChecked);
+ }
+ }
+
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/component/CheckBoxTableModel.java b/src/main/java/edu/mit/spacenet/gui/component/CheckBoxTableModel.java
new file mode 100644
index 0000000..2153eb7
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/component/CheckBoxTableModel.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.component;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.table.AbstractTableModel;
+
+/**
+ * Table that creates a listing of objects with the first column reserved for
+ * a boolean marker, graphically represented by a check box.
+ *
+ * @param the object type to list
+ *
+ * @author Paul Grogan
+ */
+public class CheckBoxTableModel extends AbstractTableModel {
+ private static final long serialVersionUID = 4160394859308981241L;
+ private List objects;
+ private Map checked;
+
+ /**
+ * The constructor.
+ */
+ public CheckBoxTableModel() {
+ objects = new ArrayList();
+ checked = new HashMap();
+ }
+
+ /**
+ * Adds a new object to the listing.
+ *
+ * @param t the object to add
+ */
+ public void addObject(T t) {
+ if(!objects.contains(t)) {
+ objects.add(t);
+ checked.put(t, true);
+ fireTableRowsInserted(objects.indexOf(t), objects.indexOf(t));
+ }
+ }
+
+ /**
+ * Adds a new object to the listing with passed checked state.
+ *
+ * @param t the object to add
+ * @param isChecked whether the object should be checked
+ */
+ public void addObject(T t, boolean isChecked) {
+ if(!objects.contains(t)) {
+ objects.add(t);
+ checked.put(t, isChecked);
+ fireTableRowsInserted(objects.indexOf(t), objects.indexOf(t));
+ }
+ }
+
+ /**
+ * Clears the list of objects.
+ */
+ public void clear() {
+ objects.clear();
+ checked.clear();
+ fireTableDataChanged();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getColumnCount()
+ */
+ public int getColumnCount() {
+ return 2;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getRowCount()
+ */
+ public int getRowCount() {
+ return objects.size();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getValueAt(int, int)
+ */
+ public Object getValueAt(int row, int col) {
+ if(col==0) {
+ return checked.get(objects.get(row));
+ } else {
+ return objects.get(row);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
+ */
+ public boolean isCellEditable(int row, int col) {
+ if(col==0) return true;
+ else return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.AbstractTableModel#getColumnClass(int)
+ */
+ public Class> getColumnClass(int col) {
+ if(col==0) return Boolean.class;
+ else return Object.class;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object, int, int)
+ */
+ public void setValueAt(Object value, int row, int col) {
+ if(col==0) {
+ checked.put(objects.get(row), (Boolean)value);
+ } else {
+ throw new RuntimeException("Cannot modify objects");
+ }
+ fireTableCellUpdated(row, col);
+ }
+
+ /**
+ * Gets a list of the unchecked objects.
+ *
+ * @return the list of unchecked objects
+ */
+ public List getDeselectedObjects() {
+ ArrayList deselected = new ArrayList();
+ for(T t : objects) {
+ if(checked.get(t).equals(Boolean.FALSE)) {
+ deselected.add(t);
+ }
+ }
+ return deselected;
+ }
+
+ /**
+ * Gets a list of the checked objects.
+ *
+ * @return the list of checked objects
+ */
+ public List getSelectedObjects() {
+ ArrayList selected = new ArrayList();
+ for(T t : objects) {
+ if(checked.get(t).equals(Boolean.TRUE)) {
+ selected.add(t);
+ }
+ }
+ return selected;
+ }
+
+ /**
+ * Gets all the objects.
+ *
+ * @return the objects
+ */
+ public List getAllObjects() {
+ return objects;
+ }
+
+ /**
+ * Checks an object.
+ *
+ * @param t the object
+ */
+ public void selectObject(T t) {
+ if(checked.containsKey(t)) {
+ checked.put(t, true);
+ fireTableCellUpdated(objects.indexOf(t), 0);
+ }
+ }
+
+ /**
+ * Unchecks an object.
+ *
+ * @param t the object to uncheck
+ */
+ public void deselectObject(T t) {
+ if(checked.containsKey(t)) {
+ checked.put(t, false);
+ fireTableCellUpdated(objects.indexOf(t), 0);
+ }
+ }
+
+ /**
+ * Checks all objects in the list.
+ */
+ public void selectAll() {
+ for(T t : checked.keySet()) {
+ checked.put(t, Boolean.TRUE);
+ }
+ fireTableDataChanged();
+ }
+
+ /**
+ * Unchecks all objects in the list.
+ */
+ public void deselectAll() {
+ for(T t : checked.keySet()) {
+ checked.put(t, Boolean.FALSE);
+ }
+ fireTableDataChanged();
+ }
+}
diff --git a/src/main/java/edu/mit/spacenet/gui/component/CheckBoxTree.java b/src/main/java/edu/mit/spacenet/gui/component/CheckBoxTree.java
new file mode 100644
index 0000000..c330acf
--- /dev/null
+++ b/src/main/java/edu/mit/spacenet/gui/component/CheckBoxTree.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2010 MIT Strategic Engineering Research Group
+ *
+ * This file is part of SpaceNet 2.5r2.
+ *
+ * SpaceNet 2.5r2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SpaceNet 2.5r2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SpaceNet 2.5r2. If not, see .
+ */
+package edu.mit.spacenet.gui.component;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseEvent;
+import java.util.EventObject;
+
+import javax.swing.BorderFactory;
+import javax.swing.JTree;
+import javax.swing.UIManager;
+import javax.swing.tree.DefaultTreeCellEditor;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreePath;
+
+import edu.mit.spacenet.gui.component.CheckBoxNode.CheckBoxNodeComponent;
+
+/**
+ * A tree representation of check box nodes.
+ *
+ * @author Paul Grogan
+ */
+public class CheckBoxTree extends JTree {
+ private static final long serialVersionUID = 1702544297754862171L;
+
+ /**
+ * The constructor.
+ *
+ * @param model the check box tree model
+ */
+ public CheckBoxTree(CheckBoxTreeModel model) {
+ super(model);
+ setCellRenderer(new DefaultTreeCellRenderer() {
+ private static final long serialVersionUID = -1994646294945996581L;
+ public Component getTreeCellRendererComponent(JTree tree, Object value,
+ boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ if(value instanceof CheckBoxNode) {
+ CheckBoxNodeComponent component = ((CheckBoxNode)value).getCheckBox();
+ if(selected) {
+ component.getLabel().setBackground(UIManager.getColor("Tree.selectionBackground"));
+ component.getLabel().setForeground(UIManager.getColor("Tree.selectionForeground"));
+ component.getLabel().setBorder(BorderFactory.createLineBorder(UIManager.getColor("Tree.selectionBorderColor"),1));
+ } else {
+ component.getLabel().setBackground(UIManager.getColor("Tree.textBackground"));
+ component.getLabel().setForeground(UIManager.getColor("Tree.textForeground"));
+ component.getLabel().setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
+ }
+ return component;
+ } else {
+ return super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
+ }
+ }
+ });
+
+ setCellEditor(new DefaultTreeCellEditor(this, (DefaultTreeCellRenderer)getCellRenderer()) {
+ public boolean isCellEditable(EventObject event) {
+ boolean returnValue = false;
+ if (event instanceof MouseEvent) {
+ MouseEvent mouseEvent = (MouseEvent) event;
+ TreePath path = tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
+ if (path != null) {
+ Object node = path.getLastPathComponent();
+ if ((node != null) && (node instanceof CheckBoxNode)) {
+ returnValue = true;
+ }
+ }
+ }
+ return returnValue;
+ }
+ public Component getTreeCellEditorComponent(JTree tree, Object value,
+ boolean selected, boolean expanded, boolean leaf, int row) {
+ Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
+ if(editor instanceof CheckBoxNodeComponent) {
+ final CheckBoxNode node = (CheckBoxNode)value;
+ ItemListener itemListener = new ItemListener() {
+ public void itemStateChanged(ItemEvent itemEvent) {
+ getModel().nodeChanged(node);
+ if (itemEvent.getStateChange()==ItemEvent.SELECTED) {
+ getModel().checkChildren(node);
+ } else {
+ getModel().uncheckChildren(node);
+ }
+ }
+ };
+ ((CheckBoxNodeComponent)editor).getCheckBox().addItemListener(itemListener);
+ }
+ return editor;
+ }
+ });
+
+ setEditable(true);
+ }
+
+ /**
+ * Expands all nodes.
+ */
+ public void expandAll() {
+ for(int i=0; i.
+ */
+package edu.mit.spacenet.gui.component;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+
+import edu.mit.spacenet.domain.element.I_Element;
+import edu.mit.spacenet.domain.network.node.Node;
+
+/**
+ * The model for the check box tree.
+ *
+ * @author Paul Grogan
+ */
+public class CheckBoxTreeModel extends DefaultTreeModel {
+ private static final long serialVersionUID = 2682670639071078594L;
+ private boolean childrenChecked;
+
+ /**
+ * The constructor.
+ *
+ * @param node the root of the model
+ */
+ public CheckBoxTreeModel(Node node) {
+ super(CheckBoxNode.createNode(node));
+ childrenChecked = true;
+ }
+
+ /**
+ * The constructor which places a blank default node at the root.
+ */
+ public CheckBoxTreeModel() {
+ super(new DefaultMutableTreeNode());
+ childrenChecked = true;
+ }
+ private Set getCheckedElements(TreeNode node) {
+ HashSet elements = new HashSet();
+ for(int i=0; i < node.getChildCount(); i++) {
+ if(node.getChildAt(i) instanceof CheckBoxNode) {
+ CheckBoxNode child = (CheckBoxNode)node.getChildAt(i);
+ if(child.isChecked()) {
+ elements.add(child.getElement());
+ } else {
+ elements.addAll(getCheckedElements(child));
+ }
+ }
+ }
+ return elements;
+ }
+
+ /**
+ * Gets a set of elements from all of the checked nodes.
+ *
+ * @return the set of elements
+ */
+ public Set getCheckedElements() {
+ return getCheckedElements(root);
+ }
+
+ /**
+ * Gets a set of elements from only the top-level of checked nodes (no
+ * nested checked elements).
+ *
+ * @return the set of elements
+ */
+ public Set