001// License: GPL. For details, see Readme.txt file.
002package org.openstreetmap.gui.jmapviewer;
003
004import java.awt.BorderLayout;
005import java.awt.Dimension;
006import java.awt.event.ActionEvent;
007import java.awt.event.ActionListener;
008import java.awt.event.MouseAdapter;
009import java.awt.event.MouseEvent;
010import java.util.List;
011
012import javax.swing.JLabel;
013import javax.swing.JMenuItem;
014import javax.swing.JPanel;
015import javax.swing.JPopupMenu;
016import javax.swing.JSplitPane;
017import javax.swing.event.TreeModelEvent;
018import javax.swing.event.TreeModelListener;
019
020import org.openstreetmap.gui.jmapviewer.checkBoxTree.CheckBoxNodePanel;
021import org.openstreetmap.gui.jmapviewer.checkBoxTree.CheckBoxTree;
022import org.openstreetmap.gui.jmapviewer.interfaces.MapObject;
023
024/**
025 * Tree of layers for JMapViewer component
026 * @author galo
027 */
028public class JMapViewerTree extends JPanel{
029    /** Serial Version UID */
030    private static final long serialVersionUID = 3050203054402323972L;
031
032    private JMapViewer map;
033    private CheckBoxTree tree;
034    private JPanel treePanel;
035    private JSplitPane splitPane;
036
037    public JMapViewerTree(String name){
038        this(name, false);
039    }
040    public JMapViewerTree(String name, boolean treeVisible){
041        super();
042        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
043        
044        tree = new CheckBoxTree(name);
045        treePanel = new JPanel();
046        treePanel.setLayout(new BorderLayout());
047        treePanel.add(tree, BorderLayout.CENTER);
048        treePanel.add(new JLabel("<html><center>Use right mouse button to<br />show/hide texts</center></html>"), BorderLayout.SOUTH);
049        map = new JMapViewer();
050
051        splitPane.setOneTouchExpandable(true);
052        splitPane.setDividerLocation(150);
053        
054        //Provide minimum sizes for the two components in the split pane
055        Dimension minimumSize = new Dimension(100, 50);
056        //tree.setMinimumSize(minimumSize);
057        map.setMinimumSize(minimumSize);
058        createRefresh();
059        setLayout(new BorderLayout());
060        setTreeVisible(treeVisible);
061        tree.addNodeListener(new MouseAdapter() {
062            public void mousePressed(MouseEvent e) {
063                maybeShowPopup(e);
064            }
065            public void mouseReleased(MouseEvent e) {
066                maybeShowPopup(e);
067            }
068            private void maybeShowPopup(MouseEvent e) {
069                if (e.isPopupTrigger()) {
070                    e.getSource();
071                    AbstractLayer layer = ((CheckBoxNodePanel)e.getComponent()).getData().getAbstractLayer();
072                    if(layer!=null)
073                        JMapViewerTree.this.createPopupMenu(layer).show(e.getComponent(), e.getX(), e.getY());
074                }
075            }
076        });
077    }
078    private JPopupMenu createPopupMenu(final AbstractLayer layer) {
079        JMenuItem menuItemShow = new JMenuItem("show texts");
080        JMenuItem menuItemHide = new JMenuItem("hide texts");
081 
082        //Create the popup menu.
083        JPopupMenu popup = new JPopupMenu();
084        
085        // Create items
086        if(layer.isVisibleTexts()==null){
087            popup.add(menuItemShow);
088            popup.add(menuItemHide);
089        }else if(layer.isVisibleTexts()) popup.add(menuItemHide);
090        else popup.add(menuItemShow);
091        
092        menuItemShow.addActionListener(new ActionListener(){
093            @Override
094            public void actionPerformed(ActionEvent arg0) {
095                setVisibleTexts(layer, true);
096                if(layer.getParent()!=null) layer.getParent().calculateVisibleTexts();
097                map.repaint();
098            }
099        });
100        menuItemHide.addActionListener(new ActionListener(){
101            @Override
102            public void actionPerformed(ActionEvent arg0) {
103                setVisibleTexts(layer, false);
104                if(layer.getParent()!=null) layer.getParent().calculateVisibleTexts();
105                map.repaint();
106            }
107        });
108 
109        return popup;
110    }
111    private void setVisibleTexts(AbstractLayer layer, boolean visible){
112        layer.setVisibleTexts(visible);
113        if(layer instanceof LayerGroup){
114            LayerGroup group = (LayerGroup)layer;
115            if(group.getLayers()!=null) for(AbstractLayer al: group.getLayers()) setVisibleTexts(al, visible);
116        }
117    }
118    public Layer addLayer(String name){
119        Layer layer = new Layer(name);
120        this.addLayer(layer);
121        return layer;
122    }
123    public JMapViewerTree addLayer(Layer layer){
124        tree.addLayer(layer);
125        return this;
126    }
127    public JMapViewerTree addLayer(MapObject element){
128        //element.getLayer().add(element);
129        return addLayer(element.getLayer());
130    }
131    public Layer removeFromLayer(MapObject element){
132        element.getLayer().getElements().remove(element);
133        return element.getLayer();
134    }
135    public static int size(List<?> list){
136        return list==null?0:list.size();
137    }
138    public JMapViewer getViewer(){
139        return map;
140    }
141    public CheckBoxTree getTree(){
142        return tree;
143    }
144    public void addMapObject(MapObject o){
145        
146    }
147    public void setTreeVisible(boolean visible){
148        removeAll();
149        revalidate();
150        if(visible){
151            splitPane.setLeftComponent(treePanel);
152            splitPane.setRightComponent(map);
153            add(splitPane, BorderLayout.CENTER);
154        }else add(map, BorderLayout.CENTER);
155        repaint();
156    }
157    private void createRefresh(){
158        tree.getModel().addTreeModelListener(new TreeModelListener() {
159            @Override
160            public void treeNodesChanged(final TreeModelEvent e) {
161                repaint();
162            }
163            @Override
164            public void treeNodesInserted(TreeModelEvent arg0) {
165                // TODO Auto-generated method stub
166            }
167            @Override
168            public void treeNodesRemoved(TreeModelEvent arg0) {
169                // TODO Auto-generated method stub
170            }
171            @Override
172            public void treeStructureChanged(TreeModelEvent arg0) {
173                // TODO Auto-generated method stub
174            }
175        });
176    }
177}