All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.telenav.mesakit.plugins.josm.geojson.GeoJsonPanel Maven / Gradle / Ivy

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// © 2011-2021 Telenav, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package com.telenav.mesakit.plugins.josm.geojson;

import com.telenav.kivakit.core.string.Strings;
import com.telenav.kivakit.ui.desktop.component.Components;
import com.telenav.mesakit.map.utilities.geojson.GeoJsonFeature;
import com.telenav.mesakit.plugins.josm.library.BaseJosmPanel;
import org.openstreetmap.josm.actions.JosmAction;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.MainMenu;
import org.openstreetmap.josm.gui.layer.Layer;
import org.openstreetmap.josm.tools.Shortcut;

import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class GeoJsonPanel extends BaseJosmPanel
{
    private static final long serialVersionUID = -684114141790912097L;

    private final DefaultListModel listModel = new DefaultListModel<>();

    private final JList list = new JList<>(listModel);

    private final JLabel status = new JLabel();

    private final JTextField search = new JTextField();

    public GeoJsonPanel(GeoJsonPlugin plugin)
    {
        super(plugin);

        var panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        var constraints = new GridBagConstraints();
        constraints.insets = new Insets(4, 4, 4, 4);

        constraints.anchor = GridBagConstraints.NORTH;
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.weightx = 1;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        panel.add(status, constraints);

        constraints.anchor = GridBagConstraints.NORTH;
        constraints.gridx = 0;
        constraints.gridy++;
        constraints.weightx = 1;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        panel.add(search, constraints);

        constraints.gridx = 0;
        constraints.gridy++;
        constraints.weightx = 1;
        constraints.weighty = 1;
        constraints.fill = GridBagConstraints.BOTH;

        var scrollPane = new JScrollPane();
        scrollPane.setViewportView(list);
        panel.add(scrollPane, constraints);

        addNextShortCut();
        addPreviousShortCut();

        list.setAutoscrolls(true);
        list.addMouseListener(new MouseAdapter()
        {

            @Override
            public void mouseClicked(MouseEvent e)
            {
                if (SwingUtilities.isLeftMouseButton(e))
                {
                    zoomToSelected();
                }
            }

            @Override
            public void mousePressed(MouseEvent e)
            {
                if (e.isPopupTrigger())
                {
                    popup(e);
                }
            }

            @Override
            public void mouseReleased(MouseEvent e)
            {
                if (e.isPopupTrigger())
                {
                    popup(e);
                }
            }
        });
        list.addKeyListener(new KeyAdapter()
        {

            @Override
            public void keyReleased(KeyEvent e)
            {
                if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN)
                {
                    zoomToSelected();
                }
            }
        });
        search.getDocument().addDocumentListener(new DocumentListener()
        {

            @Override
            public void changedUpdate(DocumentEvent e)
            {
                refresh();
            }

            @Override
            public void insertUpdate(DocumentEvent e)
            {
                refresh();
            }

            @Override
            public void removeUpdate(DocumentEvent e)
            {
                refresh();
            }
        });

        overrideMenuAcceleratorKeys(search);

        var font = new Font("Helvetica", Font.PLAIN, 12);
        Components.children(panel, component -> component.setFont(font));

        createLayout(panel, false, Collections.emptyList());
    }

    public boolean isVisible(GeoJsonFeature feature)
    {
        for (var i = 0; i < listModel.size(); i++)
        {
            if (listModel.getElementAt(i).equals(feature))
            {
                return true;
            }
        }
        return false;
    }

    @Override
    public GeoJsonLayer layer()
    {
        var layer = super.layer();
        if (layer instanceof GeoJsonLayer)
        {
            return (GeoJsonLayer) layer;
        }
        return null;
    }

    public void selectFeature(GeoJsonFeature feature)
    {
        list.setSelectedValue(feature, true);
        list.repaint();
    }

    @Override
    protected void onActiveLayerChanged()
    {
        refresh();
    }

    @Override
    protected void onHide()
    {
        refresh();
    }

    @Override
    protected void onLayerAdded()
    {
        showPanel();
        refresh();
    }

    @Override
    protected void onLayerRemoving(Layer layer)
    {
        if (layer() == null)
        {
            hidePanel();
        }
        else
        {
            refresh();
        }
    }

    @Override
    protected void onLayerReorder()
    {
        refresh();
    }

    @Override
    protected void onRefresh()
    {

        if (layer() != null)
        {

            // Get the GeoJson document we're showing
            var document = layer().getDocument();

            // Get features that match the search text
            List matches = new ArrayList<>();
            if (document != null)
            {
                for (var feature : document)
                {
                    if (Strings.isNullOrBlank(search.getText())
                            || feature.title().toUpperCase().contains(search.getText().toUpperCase()))
                    {
                        matches.add(feature);
                    }
                }
            }

            // If the features have changed
            if (isNewModel(matches))
            {

                // then update the list
                listModel.removeAllElements();
                for (var match : matches)
                {
                    listModel.addElement(match);
                }
                if (document != null)
                {
                    say("Showing " + matches.size() + " of " + document.size() + " features from "
                            + layer().getFile().fileName());
                }
                list.clearSelection();
                list.repaint();
                repaint();
                if (layer() != null)
                {
                    layer().forceRepaint();
                }
            }
        }
    }

    @Override
    protected void onShow()
    {
        refresh();
    }

    protected void popup(MouseEvent e)
    {
        list.setSelectedIndex(list.locationToIndex(e.getPoint()));
        var selectedValue = list.getSelectedValue();
        var layer = layer();
        if (layer != null)
        {
            layer.zoomToFeature(selectedValue);
        }
        var menu = new GeoJsonFeaturePopUpMenu(selectedValue);
        menu.show(e.getComponent(), e.getX(), e.getY());
    }

    private void addNextShortCut()
    {
        var shortcutName = "Next GeoJson Feature";
        var shortcut = Shortcut.registerShortcut(shortcutName, shortcutName, KeyEvent.VK_DOWN,
                Shortcut.ALT_CTRL_SHIFT);
        var next = new JosmAction(shortcutName, null, shortcutName, shortcut, false)
        {

            private static final long serialVersionUID = 9209000550528190850L;

            @Override
            public void actionPerformed(ActionEvent e)
            {
                var index = list.getSelectedIndex();
                if (index + 1 < list.getModel().getSize())
                {
                    list.setSelectedIndex(index + 1);
                }
                zoomToSelected();
            }
        };
        var menu = MainApplication.getMenu().toolsMenu;
        MainMenu.add(menu, next, MainMenu.WINDOW_MENU_GROUP.VOLATILE);
    }

    private void addPreviousShortCut()
    {
        var shortcutName = "Previous GeoJson Feature";
        var shortcut = Shortcut.registerShortcut(shortcutName, shortcutName, KeyEvent.VK_DOWN,
                Shortcut.ALT_CTRL_SHIFT);
        var previous = new JosmAction(shortcutName, null, shortcutName, shortcut, false)
        {

            private static final long serialVersionUID = 9209000550528190850L;

            @Override
            public void actionPerformed(ActionEvent e)
            {
                var index = list.getSelectedIndex();
                if (index - 1 >= 0)
                {
                    list.setSelectedIndex(index - 1);
                }
                zoomToSelected();
            }
        };
        var menu = MainApplication.getMenu().toolsMenu;
        MainMenu.add(menu, previous, MainMenu.WINDOW_MENU_GROUP.VOLATILE);
    }

    private boolean isNewModel(List features)
    {
        if (listModel.size() == features.size())
        {
            for (var i = 0; i < listModel.size(); i++)
            {
                if (!listModel.getElementAt(i).equals(features.get(i)))
                {
                    return true;
                }
            }
            return false;
        }
        return true;
    }

    private void say(String message)
    {
        status.setText(message);
    }

    private void zoomToSelected()
    {
        var layer = layer();
        if (layer != null)
        {
            layer.zoomToFeature(list.getSelectedValue());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy