package net.sf.openrocket.gui.main; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.gui.main.componenttree.ComponentTreeModel; import net.sf.openrocket.rocketcomponent.RocketComponent; public class DocumentSelectionModel { private static final Simulation[] NO_SIMULATION = new Simulation[0]; private final ComponentTreeSelectionListener componentTreeSelectionListener = new ComponentTreeSelectionListener(); private final SimulationListSelectionListener simulationListSelectionListener = new SimulationListSelectionListener(); private final OpenRocketDocument document; private RocketComponent componentSelection = null; private Simulation[] simulationSelection = NO_SIMULATION; private TreeSelectionModel componentTreeSelectionModel = null; private ListSelectionModel simulationListSelectionModel = null; private final List<DocumentSelectionListener> listeners = new ArrayList<DocumentSelectionListener>(); public DocumentSelectionModel(OpenRocketDocument document) { this.document = document; } /** * Return the currently selected simulations. Returns an empty array if none * are selected. * * @return an array of the currently selected simulations, may be of zero length. */ public Simulation[] getSelectedSimulations() { return Arrays.copyOf(simulationSelection, simulationSelection.length); } public void setSelectedSimulations(Simulation[] sims) { simulationSelection = sims; clearComponentSelection(); simulationListSelectionModel.clearSelection(); for (Simulation s: sims) { int index = document.getSimulationIndex(s); if (index >= 0) { simulationListSelectionModel.addSelectionInterval(index, index); } } } /** * Return the currently selected rocket component. Returns <code>null</code> * if no rocket component is selected. * * @return the currently selected rocket component, or <code>null</code>. */ public RocketComponent getSelectedComponent() { return componentSelection; } public void setSelectedComponent(RocketComponent component) { componentSelection = component; clearSimulationSelection(); TreePath path = ComponentTreeModel.makeTreePath(component); componentTreeSelectionModel.setSelectionPath(path); } public void attachComponentTreeSelectionModel(TreeSelectionModel model) { if (componentTreeSelectionModel != null) componentTreeSelectionModel.removeTreeSelectionListener( componentTreeSelectionListener); componentTreeSelectionModel = model; if (model != null) model.addTreeSelectionListener(componentTreeSelectionListener); clearComponentSelection(); } public void attachSimulationListSelectionModel(ListSelectionModel model) { if (simulationListSelectionModel != null) simulationListSelectionModel.removeListSelectionListener( simulationListSelectionListener); simulationListSelectionModel = model; if (model != null) model.addListSelectionListener(simulationListSelectionListener); clearSimulationSelection(); } public void clearSimulationSelection() { if (simulationSelection.length == 0) return; simulationSelection = NO_SIMULATION; if (simulationListSelectionModel != null) simulationListSelectionModel.clearSelection(); fireDocumentSelection(DocumentSelectionListener.SIMULATION_SELECTION_CHANGE); } public void clearComponentSelection() { if (componentSelection == null) return; componentSelection = null; if (componentTreeSelectionModel != null) componentTreeSelectionModel.clearSelection(); fireDocumentSelection(DocumentSelectionListener.COMPONENT_SELECTION_CHANGE); } public void addDocumentSelectionListener(DocumentSelectionListener l) { listeners.add(l); } public void removeDocumentSelectionListener(DocumentSelectionListener l) { listeners.remove(l); } protected void fireDocumentSelection(int type) { DocumentSelectionListener[] array = listeners.toArray(new DocumentSelectionListener[0]); for (DocumentSelectionListener l: array) { l.valueChanged(type); } } private class ComponentTreeSelectionListener implements TreeSelectionListener { @Override public void valueChanged(TreeSelectionEvent e) { TreePath path = componentTreeSelectionModel.getSelectionPath(); if (path == null) { componentSelection = null; fireDocumentSelection(DocumentSelectionListener.COMPONENT_SELECTION_CHANGE); return; } componentSelection = (RocketComponent)path.getLastPathComponent(); clearSimulationSelection(); fireDocumentSelection(DocumentSelectionListener.COMPONENT_SELECTION_CHANGE); } } private class SimulationListSelectionListener implements ListSelectionListener { @Override public void valueChanged(ListSelectionEvent e) { int min = simulationListSelectionModel.getMinSelectionIndex(); int max = simulationListSelectionModel.getMaxSelectionIndex(); if (min < 0 || max < 0) { simulationSelection = NO_SIMULATION; fireDocumentSelection(DocumentSelectionListener.SIMULATION_SELECTION_CHANGE); return; } ArrayList<Simulation> list = new ArrayList<Simulation>(); for (int i = min; i <= max; i++) { if (simulationListSelectionModel.isSelectedIndex(i) && (i < document.getSimulationCount())) { list.add(document.getSimulation(i)); } } simulationSelection = list.toArray(NO_SIMULATION); clearComponentSelection(); fireDocumentSelection(DocumentSelectionListener.SIMULATION_SELECTION_CHANGE); } } }