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
041    public JMapViewerTree(String name, boolean treeVisible) {
042        super();
043        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
044
045        tree = new CheckBoxTree(name);
046        treePanel = new JPanel();
047        treePanel.setLayout(new BorderLayout());
048        treePanel.add(tree, BorderLayout.CENTER);
049        treePanel.add(new JLabel("<html><center>Use right mouse button to<br />show/hide texts</center></html>"), BorderLayout.SOUTH);
050        map = new JMapViewer();
051
052        splitPane.setOneTouchExpandable(true);
053        splitPane.setDividerLocation(150);
054
055        //Provide minimum sizes for the two components in the split pane
056        Dimension minimumSize = new Dimension(100, 50);
057        //tree.setMinimumSize(minimumSize);
058        map.setMinimumSize(minimumSize);
059        createRefresh();
060        setLayout(new BorderLayout());
061        setTreeVisible(treeVisible);
062        tree.addNodeListener(new MouseAdapter() {
063            @Override
064            public void mousePressed(MouseEvent e) {
065                maybeShowPopup(e);
066            }
067
068            @Override
069            public void mouseReleased(MouseEvent e) {
070                maybeShowPopup(e);
071            }
072
073            private void maybeShowPopup(MouseEvent e) {
074                if (e.isPopupTrigger()) {
075                    AbstractLayer layer = ((CheckBoxNodePanel) e.getComponent()).getData().getAbstractLayer();
076                    if (layer != null)
077                        JMapViewerTree.this.createPopupMenu(layer).show(e.getComponent(), e.getX(), e.getY());
078                }
079            }
080        });
081    }
082
083    private JPopupMenu createPopupMenu(final AbstractLayer layer) {
084        JMenuItem menuItemShow = new JMenuItem("show texts");
085        JMenuItem menuItemHide = new JMenuItem("hide texts");
086
087        //Create the popup menu.
088        JPopupMenu popup = new JPopupMenu();
089
090        // Create items
091        if (layer.isVisibleTexts() == null) {
092            popup.add(menuItemShow);
093            popup.add(menuItemHide);
094        } else if (layer.isVisibleTexts()) popup.add(menuItemHide);
095        else popup.add(menuItemShow);
096
097        menuItemShow.addActionListener(new ActionListener() {
098            @Override
099            public void actionPerformed(ActionEvent arg0) {
100                setVisibleTexts(layer, true);
101                if (layer.getParent() != null) layer.getParent().calculateVisibleTexts();
102                map.repaint();
103            }
104        });
105        menuItemHide.addActionListener(new ActionListener() {
106            @Override
107            public void actionPerformed(ActionEvent arg0) {
108                setVisibleTexts(layer, false);
109                if (layer.getParent() != null) layer.getParent().calculateVisibleTexts();
110                map.repaint();
111            }
112        });
113
114        return popup;
115    }
116
117    private static void setVisibleTexts(AbstractLayer layer, boolean visible) {
118        layer.setVisibleTexts(visible);
119        if (layer instanceof LayerGroup) {
120            LayerGroup group = (LayerGroup) layer;
121            if (group.getLayers() != null)
122                for (AbstractLayer al: group.getLayers()) {
123                    setVisibleTexts(al, visible);
124                }
125        }
126    }
127
128    public Layer addLayer(String name) {
129        Layer layer = new Layer(name);
130        this.addLayer(layer);
131        return layer;
132    }
133
134    public JMapViewerTree addLayer(Layer layer) {
135        tree.addLayer(layer);
136        return this;
137    }
138
139    public JMapViewerTree addLayer(MapObject element) {
140        //element.getLayer().add(element);
141        return addLayer(element.getLayer());
142    }
143
144    public Layer removeFromLayer(MapObject element) {
145        element.getLayer().getElements().remove(element);
146        return element.getLayer();
147    }
148
149    public static int size(List<?> list) {
150        return list == null ? 0 : list.size();
151    }
152
153    public JMapViewer getViewer() {
154        return map;
155    }
156
157    public CheckBoxTree getTree() {
158        return tree;
159    }
160
161    public void addMapObject(MapObject o){
162
163    }
164
165    public void setTreeVisible(boolean visible) {
166        removeAll();
167        revalidate();
168        if (visible) {
169            splitPane.setLeftComponent(treePanel);
170            splitPane.setRightComponent(map);
171            add(splitPane, BorderLayout.CENTER);
172        } else add(map, BorderLayout.CENTER);
173        repaint();
174    }
175
176    private void createRefresh() {
177        tree.getModel().addTreeModelListener(new TreeModelListener() {
178            @Override
179            public void treeNodesChanged(final TreeModelEvent e) {
180                repaint();
181            }
182
183            @Override
184            public void treeNodesInserted(TreeModelEvent arg0) {
185                // TODO Auto-generated method stub
186            }
187
188            @Override
189            public void treeNodesRemoved(TreeModelEvent arg0) {
190                // TODO Auto-generated method stub
191            }
192
193            @Override
194            public void treeStructureChanged(TreeModelEvent arg0) {
195                // TODO Auto-generated method stub
196            }
197        });
198    }
199}