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