/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * Copyright (C) 2003 Vivid Solutions * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * For more information, contact: * * Vivid Solutions * Suite #1A * 2328 Government Street * Victoria BC V8T 5G5 * Canada * * (250)385-6040 * www.vividsolutions.com */ package com.vividsolutions.jump.workbench.ui.plugin.wms; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.tree.DefaultTreeCellRenderer; import com.vividsolutions.jts.util.Assert; import com.vividsolutions.jump.I18N; import com.vividsolutions.jump.util.StringUtil; import com.vividsolutions.jump.workbench.ui.GUIUtil; import com.vividsolutions.jump.workbench.ui.InputChangedFirer; import com.vividsolutions.jump.workbench.ui.InputChangedListener; import com.vividsolutions.jump.workbench.ui.addremove.AddRemoveListModel; import com.vividsolutions.jump.workbench.ui.addremove.AddRemovePanel; import com.vividsolutions.jump.workbench.ui.addremove.DefaultAddRemoveList; import com.vividsolutions.jump.workbench.ui.addremove.TreeAddRemoveList; import com.vividsolutions.jump.workbench.ui.addremove.TreeAddRemoveListModel; import com.vividsolutions.jump.workbench.ui.images.IconLoader; import com.vividsolutions.wms.MapLayer; import com.vividsolutions.wms.WMService; public class MapLayerPanel extends JPanel { public final static ImageIcon ICON = GUIUtil.resize(IconLoader.icon( "country.gif"), 13); private InputChangedFirer inputChangedFirer = new InputChangedFirer(); private GridBagLayout gridBagLayout1 = new GridBagLayout(); private AddRemovePanel addRemovePanel = new AddRemovePanel(true); private JCheckBox checkBox = new JCheckBox(I18N.get("ui.plugin.wms.MapLayerPanel.sort"), true); public MapLayerPanel() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } initAddRemovePanel(); } public List getChosenMapLayers() { ArrayList mapLayers = new ArrayList(); for (Iterator i = addRemovePanel.getRightItems().iterator(); i.hasNext();) { MapLayerTreeModel.LayerNode node = (MapLayerTreeModel.LayerNode) i.next(); Assert.isTrue(node.getLayer().getName() != null); mapLayers.add(node.getLayer()); } return mapLayers; } private void setRendererText(JLabel renderer, MapLayer layer) { renderer.setText(layer.getTitle() + " [" + StringUtil.toCommaDelimitedString(layer.getFullSRSList()) + "]"); } void jbInit() throws Exception { addRemovePanel.setRightText(I18N.get("ui.plugin.wms.MapLayerPanel.chosen-layers")); this.setLayout(gridBagLayout1); this.add(addRemovePanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); } public void add(InputChangedListener listener) { inputChangedFirer.add(listener); } public void remove(InputChangedListener listener) { inputChangedFirer.remove(listener); } private void addIfOnList(MapLayer layer, AddRemoveListModel model, Collection names) { if (names.contains(layer.getName())) { //Just leave the second argument as null, because it's only needed for sorting the left list, and //here we're dealing with the right list. [Jon Aquino] model.add(new MapLayerTreeModel.LayerNode(layer, null)); } for (Iterator i = layer.getSubLayerList().iterator(); i.hasNext();) { MapLayer child = (MapLayer) i.next(); addIfOnList(child, model, names); } } public List commonSRSList() { List mapLayers = getChosenMapLayers(); if (mapLayers.isEmpty()) { return new ArrayList(); } ArrayList commonSRSList = new ArrayList(((MapLayer) mapLayers.get(0)).getFullSRSList()); for (Iterator i = mapLayers.iterator(); i.hasNext();) { MapLayer layer = (MapLayer) i.next(); commonSRSList.retainAll(layer.getFullSRSList()); } return commonSRSList; } private void initAddRemovePanel() { TreeAddRemoveList leftList = new TreeAddRemoveList() { public List getSelectedItems() { List selectedItems = new ArrayList(super.getSelectedItems()); for (Iterator i = selectedItems.iterator(); i.hasNext();) { MapLayerTreeModel.LayerNode node = (MapLayerTreeModel.LayerNode) i.next(); //Don't want to add containers to the right-hand list. [Jon Aquino] if (node.isContainer()) { i.remove(); } } return selectedItems; } }; addRemovePanel.setLeftList(leftList); leftList.getTree().setCellRenderer(new DefaultTreeCellRenderer() { public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { JLabel component = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); if (!(value instanceof MapLayerTreeModel.LayerNode)) { //This happens during initialization. [Jon Aquino] return component; } MapLayer layer = ((MapLayerTreeModel.LayerNode) value).getLayer(); setRendererText(component, layer); if (layer.getName() == null) { //Node is just a container. [Jon Aquino] if (expanded) { component.setIcon(UIManager.getIcon("Tree.openIcon")); } else { component.setIcon(UIManager.getIcon( "Tree.closedIcon")); } } else { component.setIcon(ICON); } return component; } }); DefaultAddRemoveList rightList = new DefaultAddRemoveList(new DefaultListModel() { public void addElement(Object obj) { if (contains(obj)) { //Possible because items are never removed from the tree on the left. [Jon Aquino] return; } super.addElement(obj); } }); addRemovePanel.setRightList(rightList); rightList.getList().setCellRenderer(new DefaultListCellRenderer() { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); MapLayer layer = ((MapLayerTreeModel.LayerNode) value).getLayer(); setRendererText(component, layer); component.setIcon(ICON); return component; } }); leftList.add(new InputChangedListener() { public void inputChanged() { inputChangedFirer.fire(); } }); rightList.add(new InputChangedListener() { public void inputChanged() { inputChangedFirer.fire(); } }); rightList.getList().getModel().addListDataListener(new ListDataListener() { public void intervalAdded(ListDataEvent e) { inputChangedFirer.fire(); } public void intervalRemoved(ListDataEvent e) { inputChangedFirer.fire(); } public void contentsChanged(ListDataEvent e) { inputChangedFirer.fire(); } }); JPanel leftLabelPanel = new JPanel(); leftLabelPanel.setLayout(new GridBagLayout()); leftLabelPanel.add(new JLabel(I18N.get("ui.plugin.wms.MapLayerPanel.available-layers")), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); leftLabelPanel.add(new JPanel(), new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); checkBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setSorted( checkBox.isSelected() ); } }); leftLabelPanel.add(checkBox, new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); addRemovePanel.setLeftLabel(leftLabelPanel); } private void setSorted( boolean isSorted ) { TreeAddRemoveList tarl = (TreeAddRemoveList) addRemovePanel.getLeftList(); TreeAddRemoveListModel tarlm = (TreeAddRemoveListModel) tarl.getModel(); MapLayerTreeModel mltm = (MapLayerTreeModel) tarlm.getTreeModel(); mltm.setSorted( isSorted ); } /** * @param initialChosenMapLayers null to leave unspecified */ public void init(WMService service, Collection initialChosenMapLayers) { final MapLayerTreeModel treeModel = new MapLayerTreeModel(service.getCapabilities() .getTopLayer()); treeModel.setSorted( checkBox.isSelected() ); TreeAddRemoveListModel treeAddRemoveListModel = new TreeAddRemoveListModel(treeModel) { public List getItems() { ArrayList items = new ArrayList(items((MapLayerTreeModel.LayerNode) treeModel.getRoot())); for (Iterator i = items.iterator(); i.hasNext();) { MapLayerTreeModel.LayerNode node = (MapLayerTreeModel.LayerNode) i.next(); //Don't want to add containers to the right-hand list. [Jon Aquino] if (node.isContainer()) { i.remove(); } } return items; } }; ((TreeAddRemoveList) addRemovePanel.getLeftList()).setModel(treeAddRemoveListModel); if (initialChosenMapLayers != null) { addIfOnList(service.getCapabilities().getTopLayer(), addRemovePanel.getRightList().getModel(), initialChosenMapLayers); } addRemovePanel.updateEnabled(); } private List items(MapLayerTreeModel.LayerNode node) { ArrayList items = new ArrayList(); items.add(node); for (Enumeration e = node.children(); e.hasMoreElements();) { MapLayerTreeModel.LayerNode child = (MapLayerTreeModel.LayerNode) e.nextElement(); items.addAll(items(child)); } //Remove any items already on the right-hand list, so that the ">>" button enables/disables properly. [Jon Aquino] items.removeAll(addRemovePanel.getRightItems()); return items; } }