// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.opendata.core.gui; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.CoordinateFormat; import org.openstreetmap.josm.data.projection.Projection; import org.openstreetmap.josm.gui.ExtendedDialog; import org.openstreetmap.josm.gui.preferences.projection.ProjectionChoice; import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference; import org.openstreetmap.josm.gui.preferences.projection.SubPrefsOptions; import org.openstreetmap.josm.tools.GBC; /** * Projection chooser, ugly copy-paste of ProjectionPreference. * FIXME: to be refactored in core for reuse by plugins. */ public class ProjectionChooser extends ExtendedDialog { /** * Combobox with all projections available */ private final JComboBox<ProjectionChoice> projectionCombo = new JComboBox<>( ProjectionPreference.getProjectionChoices().toArray(new ProjectionChoice[0])); /** * This variable holds the JPanel with the projection's preferences. If the * selected projection does not implement this, it will be set to an empty * Panel. */ private JPanel projSubPrefPanel; private JPanel projSubPrefPanelWrapper = new JPanel(new GridBagLayout()); private JLabel projectionCodeLabel; private Component projectionCodeGlue; private JLabel projectionCode = new JLabel(); private JLabel projectionNameLabel; private Component projectionNameGlue; private JLabel projectionName = new JLabel(); private JLabel bounds = new JLabel(); /** * This is the panel holding all projection preferences */ private final JPanel projPanel = new JPanel(new GridBagLayout()); /** * The GridBagConstraints for the Panel containing the ProjectionSubPrefs. * This is required twice in the code, creating it here keeps both occurrences * in sync */ private static final GBC projSubPrefPanelGBC = GBC.std().fill(GBC.BOTH).weight(1.0, 1.0); public ProjectionChooser(Component parent) { this(parent, tr("Projection method"), new String[] {tr("OK"), tr("Cancel")}); } protected ProjectionChooser(Component parent, String title, String[] buttonTexts) { super(parent, title, buttonTexts); setMinimumSize(new Dimension(600, 200)); addGui(); } public void addGui() { projPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); projPanel.setLayout(new GridBagLayout()); projPanel.add(new JLabel(tr("Projection method")), GBC.std().insets(5, 5, 0, 5)); projPanel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL)); projPanel.add(projectionCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0, 5, 5, 5)); projPanel.add(projectionCodeLabel = new JLabel(tr("Projection code")), GBC.std().insets(25, 5, 0, 5)); projPanel.add(projectionCodeGlue = GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL)); projPanel.add(projectionCode, GBC.eop().fill(GBC.HORIZONTAL).insets(0, 5, 5, 5)); projPanel.add(projectionNameLabel = new JLabel(tr("Projection name")), GBC.std().insets(25, 5, 0, 5)); projPanel.add(projectionNameGlue = GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL)); projPanel.add(projectionName, GBC.eop().fill(GBC.HORIZONTAL).insets(0, 5, 5, 5)); projPanel.add(new JLabel(tr("Bounds")), GBC.std().insets(25, 5, 0, 5)); projPanel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL)); projPanel.add(bounds, GBC.eop().fill(GBC.HORIZONTAL).insets(0, 5, 5, 5)); projPanel.add(projSubPrefPanelWrapper, GBC.eol().fill(GBC.HORIZONTAL).insets(20, 5, 5, 5)); selectedProjectionChanged((ProjectionChoice) projectionCombo.getSelectedItem()); projectionCombo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ProjectionChoice pc = (ProjectionChoice) projectionCombo.getSelectedItem(); selectedProjectionChanged(pc); } }); setContent(projPanel); } private void selectedProjectionChanged(final ProjectionChoice pc) { // Don't try to update if we're still starting up int size = projPanel.getComponentCount(); if (size < 1) return; final ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateMeta(pc); } }; // Replace old panel with new one projSubPrefPanelWrapper.removeAll(); projSubPrefPanel = pc.getPreferencePanel(listener); projSubPrefPanelWrapper.add(projSubPrefPanel, projSubPrefPanelGBC); projPanel.revalidate(); projSubPrefPanel.repaint(); updateMeta(pc); } private void updateMeta(ProjectionChoice pc) { pc.setPreferences(pc.getPreferences(projSubPrefPanel)); Projection proj = pc.getProjection(); projectionCode.setText(proj.toCode()); projectionName.setText(proj.toString()); Bounds b = proj.getWorldBoundsLatLon(); CoordinateFormat cf = CoordinateFormat.getDefaultFormat(); bounds.setText(b.getMin().lonToString(cf)+", "+b.getMin().latToString(cf)+" : "+ b.getMax().lonToString(cf)+", "+b.getMax().latToString(cf)); boolean showCode = true; boolean showName = false; if (pc instanceof SubPrefsOptions) { showCode = ((SubPrefsOptions) pc).showProjectionCode(); showName = ((SubPrefsOptions) pc).showProjectionName(); } projectionCodeLabel.setVisible(showCode); projectionCodeGlue.setVisible(showCode); projectionCode.setVisible(showCode); projectionNameLabel.setVisible(showName); projectionNameGlue.setVisible(showName); projectionName.setVisible(showName); } public Projection getProjection() { ProjectionChoice pc = (ProjectionChoice) projectionCombo.getSelectedItem(); if (pc != null) { Main.info("Chosen projection: "+pc+" ("+pc.getProjection()+")"); return pc.getProjection(); } else { return null; } } }