Ignore:
Timestamp:
2009-10-11T16:33:29+02:00 (17 years ago)
Author:
stoecker
Message:

first partial support for sub preferences, not yet functional

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java

    r2017 r2272  
    55
    66import java.awt.GridBagLayout;
     7import java.awt.event.ActionEvent;
     8import java.awt.event.ActionListener;
     9
     10import java.util.Collection;
    711
    812import javax.swing.BorderFactory;
    9 import javax.swing.Box;
    1013import javax.swing.JComboBox;
    1114import javax.swing.JLabel;
     15import javax.swing.JOptionPane;
    1216import javax.swing.JPanel;
    1317import javax.swing.JScrollPane;
    1418
    1519import org.openstreetmap.josm.Main;
     20import org.openstreetmap.josm.data.Bounds;
    1621import org.openstreetmap.josm.data.coor.CoordinateFormat;
    1722import org.openstreetmap.josm.data.projection.Mercator;
    1823import org.openstreetmap.josm.data.projection.Projection;
     24import org.openstreetmap.josm.data.projection.ProjectionSubPrefs;
    1925import org.openstreetmap.josm.tools.GBC;
    2026
    … …  
    3137     */
    3238    private JComboBox projectionCombo = new JComboBox(Projection.allProjections);
     39
     40    /**
     41     * Combobox with all coordinate display possibilities
     42     */
    3343    private JComboBox coordinatesCombo = new JComboBox(CoordinateFormat.values());
    3444
     45    /**
     46     * This variable holds the JPanel with the projection's preferences. If the
     47     * selected projection does not implement this, it will be set to an empty
     48     * Panel.
     49     */
     50    private JPanel projSubPrefPanel;
     51
     52    private JLabel projectionCode = new JLabel();
     53    private JLabel bounds = new JLabel();
     54
     55    /**
     56     * This is the panel holding all projection preferences
     57     */
     58    private JPanel projPanel = new JPanel();
     59
     60    /**
     61     * The GridBagConstraints for the Panel containing the ProjectionSubPrefs.
     62     * This is required twice in the code, creating it here keeps both occurrences
     63     * in sync
     64     */
     65    static private GBC projSubPrefPanelGBC = GBC.eol().fill(GBC.BOTH).insets(20,5,5,5);
     66
    3567    public void addGui(PreferenceDialog gui) {
    36 
    37         for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
    38             if (projectionCombo.getItemAt(i).getClass().getName().equals(Main.pref.get("projection", Mercator.class.getName()))) {
    39                 projectionCombo.setSelectedIndex(i);
    40                 break;
    41             }
    42         }
     68        clearSubProjPrefs();
     69        setupProjectionCombo();
    4370
    4471        for (int i = 0; i < coordinatesCombo.getItemCount(); ++i) {
    … …  
    4976        }
    5077
    51         JPanel projPanel = new JPanel();
    5278        projPanel.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
    5379        projPanel.setLayout(new GridBagLayout());
    … …  
    5884        projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
    5985        projPanel.add(projectionCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
    60         projPanel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH));
     86        projPanel.add(new JLabel(tr("Projection code")), GBC.std().insets(25,5,0,5));
     87        projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
     88        projPanel.add(projectionCode, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
     89        projPanel.add(new JLabel(tr("Bounds")), GBC.std().insets(25,5,0,5));
     90        projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
     91        projPanel.add(bounds, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
     92        projPanel.add(projSubPrefPanel, projSubPrefPanelGBC);
    6193        JScrollPane scrollpane = new JScrollPane(projPanel);
    6294        gui.mapcontent.addTab(tr("Map Projection"), scrollpane);
     95
     96        projectionCode.setText(Main.proj.toCode());
     97        Bounds b = Main.proj.getWorldBoundsLatLon();
     98        CoordinateFormat cf = CoordinateFormat.getDefaultFormat();
     99        bounds.setText(b.min.latToString(cf)+"; "+b.min.lonToString(cf)+" : "+b.max.latToString(cf)+"; "+b.max.lonToString(cf));
     100        /* TODO: Fix bugs, refresh code line and world bounds, fix design (e.g. add border around sub-prefs-stuff */
    63101    }
    64102
    65103    public boolean ok() {
    66         String projname = projectionCombo.getSelectedItem().getClass().getName();
     104        Projection proj = (Projection) projectionCombo.getSelectedItem();
     105
     106        String projname = proj.getClass().getName();
     107        Collection<String> prefs = null;
     108        if(projHasPrefs(proj))
     109            prefs = ((ProjectionSubPrefs) proj).getPreferences();
     110
    67111        if(Main.pref.put("projection", projname)) {
    68             Main.setProjection(projname);
    69         }
     112            setProjection(projname, prefs);
     113        }
     114
    70115        if(Main.pref.put("coordinates",
    71116                ((CoordinateFormat)coordinatesCombo.getSelectedItem()).name())) {
    72117            CoordinateFormat.setCoordinateFormat((CoordinateFormat)coordinatesCombo.getSelectedItem());
    73118        }
     119
     120        // We get the change to remove these panels on closing the preferences
     121        // dialog, so take it. TODO: Make this work always, even when canceling
     122        // the dialog
     123        clearSubProjPrefs();
     124
    74125        return false;
    75126    }
     127
     128    /**
     129     * Finds out if the given projection implements the ProjectionPreference
     130     * interface
     131     * @param proj
     132     * @return
     133     */
     134    @SuppressWarnings("unchecked")
     135    static private boolean projHasPrefs(Projection proj) {
     136        Class[] ifaces = proj.getClass().getInterfaces();
     137        for(int i = 0; i < ifaces.length; i++) {
     138            if(ifaces[i].getSimpleName().equals("ProjectionSubPrefs"))
     139                return true;
     140        }
     141        return false;
     142    }
     143
     144    static public void setProjection()
     145    {
     146        setProjection(Main.pref.get("projection", Mercator.class.getName()),
     147        Main.pref.getCollection("projection.sub", null));
     148    }
     149
     150    static public void setProjection(String name, Collection<String> coll)
     151    {
     152        Bounds b = (Main.map != null && Main.map.mapView != null) ? Main.map.mapView.getRealBounds() : null;
     153        Projection oldProj = Main.proj;
     154
     155        try {
     156            Main.proj = (Projection)Class.forName(name).newInstance();
     157        } catch (final Exception e) {
     158            JOptionPane.showMessageDialog(
     159                    Main.parent,
     160                    tr("The projection {0} could not be activated. Using Mercator", name),
     161                    tr("Error"),
     162                    JOptionPane.ERROR_MESSAGE
     163            );
     164            coll = null;
     165            Main.proj = new Mercator();
     166        }
     167        if(!Main.proj.equals(oldProj) && b != null)
     168        {
     169            Main.map.mapView.zoomTo(b);
     170            /* TODO - remove layers with fixed projection */
     171        }
     172        Main.pref.putCollection("projection.sub", coll);
     173        if(coll != null && projHasPrefs(Main.proj))
     174            ((ProjectionSubPrefs) Main.proj).setPreferences(coll);
     175    }
     176
     177    /**
     178     * Handles all the work related to update the projection-specific
     179     * preferences
     180     * @param proj
     181     */
     182    private void selectedProjectionChanged(Projection proj) {
     183        if(!projHasPrefs(proj)) {
     184            projSubPrefPanel = new JPanel();
     185        } else {
     186            ProjectionSubPrefs projPref = (ProjectionSubPrefs) proj;
     187            projSubPrefPanel = projPref.getPreferencePanel();
     188        }
     189
     190        // Don't try to update if we're still starting up
     191        int size = projPanel.getComponentCount();
     192        if(size < 1)
     193            return;
     194
     195        // Replace old panel with new one
     196        projPanel.remove(size - 1);
     197        projPanel.add(projSubPrefPanel, projSubPrefPanelGBC);
     198        projPanel.revalidate();
     199    }
     200
     201    /**
     202     * Sets up projection combobox with default values and action listener
     203     */
     204    private void setupProjectionCombo() {
     205        for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
     206            Projection proj = (Projection)projectionCombo.getItemAt(i);
     207            if (proj.getClass().getName().equals(Main.pref.get("projection", Mercator.class.getName()))) {
     208                projectionCombo.setSelectedIndex(i);
     209                selectedProjectionChanged(proj);
     210                break;
     211            }
     212        }
     213
     214        projectionCombo.addActionListener(new ActionListener() {
     215            public void actionPerformed(ActionEvent e) {
     216                JComboBox cb = (JComboBox)e.getSource();
     217                Projection proj = (Projection)cb.getSelectedItem();
     218                selectedProjectionChanged(proj);
     219            }
     220        });
     221    }
     222
     223    /**
     224     * Method to clean up the preference panels made by each projection. This
     225     * requires them to be regenerated when the prefs dialog is opened again,
     226     * but this also makes them react to changes to their preferences from the
     227     * outside
     228     */
     229    static private void clearSubProjPrefs() {
     230        for(Projection proj : Projection.allProjections) {
     231            if(projHasPrefs(proj)) {
     232                ((ProjectionSubPrefs) proj).destroyCachedPanel();
     233            }
     234        }
     235    }
    76236}
Note: See TracChangeset for help on using the changeset viewer.