/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.cismet.cismap.commons.gui.layerwidget; import org.openide.util.NbBundle; import java.awt.Component; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.TreeMap; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import de.cismet.cismap.commons.featureservice.AbstractFeatureService; import de.cismet.cismap.commons.rasterservice.MapService; /** * DOCUMENT ME! * * @author therter * @version $Revision$, $Date$ */ public class LayerCombobox extends JComboBox { //~ Instance fields -------------------------------------------------------- private LayerComboboxModel model; //~ Constructors ----------------------------------------------------------- /** * Creates a new LayerCombobox object. */ public LayerCombobox() { } /** * Creates a new LayerCombobox object. * * @param layerModel DOCUMENT ME! */ public LayerCombobox(final ActiveLayerModel layerModel) { this(layerModel, null); } /** * Creates a new LayerCombobox object. * * @param layerModel DOCUMENT ME! * @param themeLayerWidget DOCUMENT ME! */ public LayerCombobox(final ActiveLayerModel layerModel, final ThemeLayerWidget themeLayerWidget) { super(); model = new LayerComboboxModel(layerModel, themeLayerWidget); super.setModel(model); super.setRenderer(new CustomRenderer()); } //~ Inner Classes ---------------------------------------------------------- /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class CustomRenderer extends DefaultListCellRenderer { //~ Instance fields ---------------------------------------------------- private int indent = UIManager.getInt("Tree.leftChildIndent"); //~ Methods ------------------------------------------------------------ @Override public Component getListCellRendererComponent(final JList<?> list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { final Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (c instanceof JLabel) { final JLabel lbl = (JLabel)c; if (value instanceof DefaultLayerFilter) { final DefaultLayerFilter lf = (DefaultLayerFilter)value; if (lf.getIcon() != null) { lbl.setIcon(lf.getIcon()); } } if (value instanceof SingleLayerFilter) { final SingleLayerFilter lf = (SingleLayerFilter)value; if (lf.getDepth() > 0) { lbl.setBorder(new EmptyBorder(0, lf.getDepth() * indent, 0, 0)); } } } return c; } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class LayerComboboxModel extends DefaultComboBoxModel { //~ Instance fields ---------------------------------------------------- private final ActiveLayerModel layerModel; private final ThemeLayerWidget themeLayerWidget; private final List<LayerFilter> filter = new ArrayList<LayerFilter>(); //~ Constructors ------------------------------------------------------- /** * Creates a new LayerComboboxModel object. * * @param layerModel DOCUMENT ME! * @param themeLayerWidget DOCUMENT ME! */ public LayerComboboxModel(final ActiveLayerModel layerModel, final ThemeLayerWidget themeLayerWidget) { this.layerModel = layerModel; this.themeLayerWidget = themeLayerWidget; layerModel.addTreeModelListener(new TreeModelListener() { @Override public void treeNodesChanged(final TreeModelEvent e) { // This means, that the layer was disabled, the visibility was changed, the name was changed or // the progress was changed } @Override public void treeNodesInserted(final TreeModelEvent e) { initModel(); } @Override public void treeNodesRemoved(final TreeModelEvent e) { initModel(); } @Override public void treeStructureChanged(final TreeModelEvent e) { initModel(); } }); initModel(); } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! */ private void initModel() { final List<LayerFilter> entryList = new ArrayList<LayerFilter>(); final Object selectedObject = getSelectedItem(); if (filter.isEmpty()) { if (themeLayerWidget != null) { filter.add(new SelectedLayerFilter(themeLayerWidget)); } filter.add(new SelectableLayersFilter(layerModel)); filter.add(new TopMostLayerFilter(layerModel)); filter.add(new VisibleLayersFilter(layerModel)); filter.add(new AllLayersFilter()); } for (final LayerFilter lf : filter) { entryList.add(lf); } final TreeMap<Integer, Object> map = layerModel.getMapServicesAndCollections(); final Integer[] keys = new Integer[map.keySet().size()]; int i = 0; for (final Integer key : map.keySet()) { keys[i++] = key; } Arrays.sort(keys, Collections.reverseOrder()); for (final Integer key : keys) { final Object layer = map.get(key); if (layer instanceof Collection) { entryList.addAll(getLayersFromCollection((Collection)layer, 1)); } else { entryList.add(new SingleLayerFilter(layer, 0)); } } this.removeAllElements(); for (final Object entry : entryList) { this.addElement(entry); } if (entryList.contains(selectedObject)) { setSelectedItem(selectedObject); } } /** * DOCUMENT ME! * * @param layer DOCUMENT ME! * @param depth DOCUMENT ME! * * @return DOCUMENT ME! */ private List<LayerFilter> getLayersFromCollection(final Collection layer, final int depth) { final List<LayerFilter> entryList = new ArrayList<LayerFilter>(); entryList.add(new SingleLayerFilter(layer, depth - 1)); for (final Object subLayer : layer) { if (subLayer instanceof Collection) { entryList.addAll(getLayersFromCollection((Collection)subLayer, depth + 1)); } else { entryList.add(new SingleLayerFilter(subLayer, depth)); } } return entryList; } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private abstract class DefaultLayerFilter implements LayerFilter { //~ Instance fields ---------------------------------------------------- private final String name; private Icon icon; //~ Constructors ------------------------------------------------------- /** * Creates a new DefaultLayerFilter object. * * @param name DOCUMENT ME! */ public DefaultLayerFilter(final String name) { this.name = name; } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! * * @param icon DOCUMENT ME! */ public void setIcon(final Icon icon) { this.icon = icon; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public Icon getIcon() { return icon; } @Override public String toString() { return name; } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class TopMostLayerFilter extends DefaultLayerFilter { //~ Instance fields ---------------------------------------------------- private MapService topMostLayer; private final ActiveLayerModel model; //~ Constructors ------------------------------------------------------- /** * Creates a new TopMostLayerFilter object. * * @param model DOCUMENT ME! */ public TopMostLayerFilter(final ActiveLayerModel model) { super(NbBundle.getMessage(TopMostLayerFilter.class, "LayerCombobox.TopMostLayerFilter")); this.model = model; setTopMostLayer(); model.addTreeModelListener(new TreeModelListener() { @Override public void treeNodesChanged(final TreeModelEvent e) { setTopMostLayer(); } @Override public void treeNodesInserted(final TreeModelEvent e) { setTopMostLayer(); } @Override public void treeNodesRemoved(final TreeModelEvent e) { setTopMostLayer(); } @Override public void treeStructureChanged(final TreeModelEvent e) { setTopMostLayer(); } }); } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! */ private void setTopMostLayer() { final TreeMap<Integer, MapService> map = model.getMapServices(); if (!map.keySet().isEmpty()) { final Integer[] keys = new Integer[map.keySet().size()]; int i = 0; for (final Integer key : map.keySet()) { keys[i++] = key; } Arrays.sort(keys, Collections.reverseOrder()); topMostLayer = map.get(keys[0]); } else { topMostLayer = null; } } @Override public boolean isLayerAllowed(final MapService layer) { if (topMostLayer != null) { return layer.equals(topMostLayer); } else { return false; } } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class VisibleLayersFilter extends DefaultLayerFilter { //~ Instance fields ---------------------------------------------------- private final List<MapService> visibleLayer = new ArrayList<MapService>(); private final ActiveLayerModel model; //~ Constructors ------------------------------------------------------- /** * Creates a new VisibleLayersFilter object. * * @param model DOCUMENT ME! */ public VisibleLayersFilter(final ActiveLayerModel model) { super(NbBundle.getMessage(VisibleLayersFilter.class, "LayerCombobox.VisibleLayersFilter")); this.model = model; setVisibleLayerFilterLayer(); model.addTreeModelListener(new TreeModelListener() { @Override public void treeNodesChanged(final TreeModelEvent e) { setVisibleLayerFilterLayer(); } @Override public void treeNodesInserted(final TreeModelEvent e) { setVisibleLayerFilterLayer(); } @Override public void treeNodesRemoved(final TreeModelEvent e) { setVisibleLayerFilterLayer(); } @Override public void treeStructureChanged(final TreeModelEvent e) { setVisibleLayerFilterLayer(); } }); } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! */ private void setVisibleLayerFilterLayer() { final TreeMap<Integer, MapService> map = model.getMapServices(); visibleLayer.clear(); for (final Integer key : map.keySet()) { final MapService service = map.get(key); if (service.getPNode().getVisible()) { visibleLayer.add(service); } } } @Override public boolean isLayerAllowed(final MapService layer) { return visibleLayer.contains(layer); } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class SelectableLayersFilter extends DefaultLayerFilter { //~ Instance fields ---------------------------------------------------- private final List<MapService> selectableLayer = new ArrayList<MapService>(); private final ActiveLayerModel model; //~ Constructors ------------------------------------------------------- /** * Creates a new VisibleLayersFilter object. * * @param model DOCUMENT ME! */ public SelectableLayersFilter(final ActiveLayerModel model) { super(NbBundle.getMessage(VisibleLayersFilter.class, "LayerCombobox.SelectableLayersFilter")); this.model = model; setSelectableLayerFilterLayer(); model.addTreeModelListener(new TreeModelListener() { @Override public void treeNodesChanged(final TreeModelEvent e) { setSelectableLayerFilterLayer(); } @Override public void treeNodesInserted(final TreeModelEvent e) { setSelectableLayerFilterLayer(); } @Override public void treeNodesRemoved(final TreeModelEvent e) { setSelectableLayerFilterLayer(); } @Override public void treeStructureChanged(final TreeModelEvent e) { setSelectableLayerFilterLayer(); } }); } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! */ private void setSelectableLayerFilterLayer() { final TreeMap<Integer, MapService> map = model.getMapServices(); selectableLayer.clear(); for (final Integer key : map.keySet()) { final MapService service = map.get(key); if ((service instanceof AbstractFeatureService) && ((AbstractFeatureService)service).isSelectable()) { selectableLayer.add(service); } } } @Override public boolean isLayerAllowed(final MapService layer) { return selectableLayer.contains(layer); } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class SelectedLayerFilter extends DefaultLayerFilter { //~ Instance fields ---------------------------------------------------- private final List<MapService> selectedLayer = new ArrayList<MapService>(); private final ThemeLayerWidget themeLayer; //~ Constructors ------------------------------------------------------- /** * Creates a new SelectedLayerFilter object. * * @param themeLayer DOCUMENT ME! */ public SelectedLayerFilter(final ThemeLayerWidget themeLayer) { super(NbBundle.getMessage(SelectedLayerFilter.class, "LayerCombobox.SelectedLayerFilter")); this.themeLayer = themeLayer; setSelectedLayers(); themeLayer.addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(final TreeSelectionEvent e) { setSelectedLayers(); model.initModel(); } }); } //~ Methods ------------------------------------------------------------ /** * DOCUMENT ME! */ private void setSelectedLayers() { final TreePath[] selectionPath = themeLayer.getSelectionPath(); selectedLayer.clear(); if (selectionPath != null) { for (final TreePath path : selectionPath) { final Object o = path.getLastPathComponent(); if (o instanceof MapService) { selectedLayer.add((MapService)o); } } } } @Override public boolean isLayerAllowed(final MapService layer) { return selectedLayer.contains(layer); } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class AllLayersFilter extends DefaultLayerFilter { //~ Constructors ------------------------------------------------------- /** * Creates a new AllLayersFilter object. */ public AllLayersFilter() { super(NbBundle.getMessage(AllLayersFilter.class, "LayerCombobox.AllLayersFilter")); } //~ Methods ------------------------------------------------------------ @Override public boolean isLayerAllowed(final MapService layer) { return true; } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private class SingleLayerFilter extends DefaultLayerFilter { //~ Instance fields ---------------------------------------------------- private final Object layer; private final int depth; //~ Constructors ------------------------------------------------------- /** * Creates a new SingleLayerFilter object. * * @param layer DOCUMENT ME! * @param depth DOCUMENT ME! */ public SingleLayerFilter(final Object layer, final int depth) { super(layer.toString()); super.setIcon(getIcon(layer)); this.layer = layer; this.depth = depth; } //~ Methods ------------------------------------------------------------ @Override public boolean isLayerAllowed(final MapService layer) { return this.layer.equals(layer); } /** * DOCUMENT ME! * * @param layer DOCUMENT ME! * * @return DOCUMENT ME! */ private Icon getIcon(final Object layer) { return new ImageIcon(getClass().getResource("/de/cismet/cismap/commons/gui/layerwidget/res/layer.png")); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getDepth() { return depth; } } }