package com.xrosstools.xunit.editor.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class UnitNodePanel implements UnitNodeContainer { private CompositeUnitNode parent; private List<UnitNode> units = new ArrayList<UnitNode>(); private int UNLIMITED_SIZE = -1; private int fixedSize = UNLIMITED_SIZE; private boolean vertical = true; private PropertyChangeSupport listeners = new PropertyChangeSupport(this); public UnitNodePanel(CompositeUnitNode parent){ this(parent, true); } public UnitNodePanel(CompositeUnitNode parent, boolean vertical){ this.parent = parent; this.vertical = vertical; } public UnitNodePanel(CompositeUnitNode parent, int fixedSize){ this(parent, true); this.fixedSize = fixedSize; init(); } private void init(){ if(fixedSize == UNLIMITED_SIZE) return; for(int i = 0; i< fixedSize; i++) units.add(null); } private void firePropertyChange(String propertyName){ listeners.firePropertyChange(propertyName, null, null); } public boolean isVertical(){ return vertical; } public int size(){ int i = 0; for(UnitNode unit:units) i += (unit == null ? 0 : 1); return i; } public int indexOf(UnitNode unit){ return units.indexOf(unit); } public boolean contains(UnitNode unit){ return units.contains(unit); } public UnitNode get(int index){ return units.get(index); } public List<UnitNode> getAll(){ List<UnitNode> tmpUnits = new ArrayList<UnitNode>(); for(UnitNode unit:units) if(unit != null) tmpUnits.add(unit); return tmpUnits; } public boolean isFixedSize(){ return fixedSize != UNLIMITED_SIZE; } public int getFixedSize(){ return fixedSize; } public boolean checkDropAllowed(int index){ if(fixedSize == UNLIMITED_SIZE) return true; return fixedSize != size(); } public boolean add(int index, UnitNode unit) { if(!checkDropAllowed(index)) return false; if(isFixedSize()){ if(index < fixedSize && units.get(index) == null) set(index, unit); else if(index == fixedSize && units.get(0) != null) set(1, unit); else if(index == 1 && units.get(0) == null) set(0, unit); else return false; } else units.add(index, unit); forceRefresh(); parent.unitAdded(index, unit); firePropertyChange(PROP_NODE); return true; } public boolean add(UnitNode unit){ if(!checkDropAllowed(size())) return false; if(!isFixedSize()) return add(size(), unit); if(units.get(0) == null) set(0, unit); else set(1, unit); return true; } public void set(int index, UnitNode unit){ if(!checkDropAllowed(index)) return; units.set(index, unit); parent.unitSet(index, unit); firePropertyChange(PROP_NODE); } public void remove(UnitNode unit) { if(!units.contains(unit)) return; if(isFixedSize()) units.set(indexOf(unit), null); else units.remove(unit); parent.unitRemoved(unit); firePropertyChange(PROP_NODE); } public void move(int newIndex, UnitNode unit){ // For non fixed size or full fixed size if(!isFixedSize()){ UnitNode after = newIndex < units.size() ? units.get(newIndex) : null; units.remove(unit); units.add(after == null ? units.size() : units.indexOf(after), unit); }else{ // just switch. should only be the bi-branch case Collections.reverse(units); } forceRefresh(); parent.unitMoved(unit); firePropertyChange(PROP_NODE); } private void forceRefresh(){ if(!isFixedSize()) return; List<UnitNode> tmpUnits = new ArrayList<UnitNode>(units); // Force for(int i = 0; i < fixedSize; i++) units.set(i, null); firePropertyChange(PROP_NODE); for(int i = 0; i < fixedSize; i++) units.set(i, tmpUnits.get(i)); firePropertyChange(PROP_NODE); } public void addPropertyChangeListener(PropertyChangeListener lilistener) { listeners.addPropertyChangeListener(lilistener); } public void removePropertyChangeListener(PropertyChangeListener lilistener) { listeners.removePropertyChangeListener(lilistener); } }