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