source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java@ 2646

Last change on this file since 2646 was 2516, checked in by stoecker, 14 years ago

close #4015 - Zoomlevel changes whenever the preference dialog is closed

  • Property svn:eol-style set to native
File size: 9.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.preferences;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.awt.event.ActionEvent;
8import java.awt.event.ActionListener;
9
10import java.util.Collection;
11
12import javax.swing.BorderFactory;
13import javax.swing.JComboBox;
14import javax.swing.JLabel;
15import javax.swing.JOptionPane;
16import javax.swing.JPanel;
17import javax.swing.JScrollPane;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.data.Bounds;
21import org.openstreetmap.josm.data.coor.CoordinateFormat;
22import org.openstreetmap.josm.data.projection.Mercator;
23import org.openstreetmap.josm.data.projection.Projection;
24import org.openstreetmap.josm.data.projection.ProjectionSubPrefs;
25import org.openstreetmap.josm.tools.GBC;
26
27public class ProjectionPreference implements PreferenceSetting {
28
29 public static class Factory implements PreferenceSettingFactory {
30 public PreferenceSetting createPreferenceSetting() {
31 return new ProjectionPreference();
32 }
33 }
34
35 /**
36 * Combobox with all projections available
37 */
38 private JComboBox projectionCombo = new JComboBox(Projection.allProjections);
39
40 /**
41 * Combobox with all coordinate display possibilities
42 */
43 private JComboBox coordinatesCombo = new JComboBox(CoordinateFormat.values());
44
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
67 public void addGui(PreferenceDialog gui) {
68 setupProjectionCombo();
69
70 for (int i = 0; i < coordinatesCombo.getItemCount(); ++i) {
71 if (((CoordinateFormat)coordinatesCombo.getItemAt(i)).name().equals(Main.pref.get("coordinates"))) {
72 coordinatesCombo.setSelectedIndex(i);
73 break;
74 }
75 }
76
77 projPanel.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
78 projPanel.setLayout(new GridBagLayout());
79 projPanel.add(new JLabel(tr("Display coordinates as")), GBC.std().insets(5,5,0,5));
80 projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
81 projPanel.add(coordinatesCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
82 projPanel.add(new JLabel(tr("Projection method")), GBC.std().insets(5,5,0,5));
83 projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
84 projPanel.add(projectionCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
85 projPanel.add(new JLabel(tr("Projection code")), GBC.std().insets(25,5,0,5));
86 projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
87 projPanel.add(projectionCode, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
88 projPanel.add(new JLabel(tr("Bounds")), GBC.std().insets(25,5,0,5));
89 projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
90 projPanel.add(bounds, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
91 projPanel.add(projSubPrefPanel, projSubPrefPanelGBC);
92
93 JScrollPane scrollpane = new JScrollPane(projPanel);
94 gui.mapcontent.addTab(tr("Map Projection"), scrollpane);
95
96 updateMeta(Main.proj);
97 }
98
99 private void updateMeta(Projection proj)
100 {
101 projectionCode.setText(proj.toCode());
102 Bounds b = proj.getWorldBoundsLatLon();
103 CoordinateFormat cf = CoordinateFormat.getDefaultFormat();
104 bounds.setText(b.getMin().latToString(cf)+"; "+b.getMin().lonToString(cf)+" : "+b.getMax().latToString(cf)+"; "+b.getMax().lonToString(cf));
105 }
106
107 public boolean ok() {
108 Projection proj = (Projection) projectionCombo.getSelectedItem();
109
110 String projname = proj.getClass().getName();
111 Collection<String> prefs = null;
112 if(projHasPrefs(proj))
113 prefs = ((ProjectionSubPrefs) proj).getPreferences(projSubPrefPanel);
114
115 Main.pref.put("projection", projname);
116 setProjection(projname, prefs);
117
118 if(Main.pref.put("coordinates",
119 ((CoordinateFormat)coordinatesCombo.getSelectedItem()).name())) {
120 CoordinateFormat.setCoordinateFormat((CoordinateFormat)coordinatesCombo.getSelectedItem());
121 }
122
123 return false;
124 }
125
126 /**
127 * Finds out if the given projection implements the ProjectionPreference
128 * interface
129 * @param proj
130 * @return
131 */
132 @SuppressWarnings("unchecked")
133 static private boolean projHasPrefs(Projection proj) {
134 Class[] ifaces = proj.getClass().getInterfaces();
135 for(int i = 0; i < ifaces.length; i++) {
136 if(ifaces[i].getSimpleName().equals("ProjectionSubPrefs"))
137 return true;
138 }
139 return false;
140 }
141
142 static public void setProjection()
143 {
144 setProjection(Main.pref.get("projection", Mercator.class.getName()),
145 Main.pref.getCollection("projection.sub", null));
146 }
147
148 static public void setProjection(String name, Collection<String> coll)
149 {
150 Bounds b = (Main.map != null && Main.map.mapView != null) ? Main.map.mapView.getRealBounds() : null;
151 Projection oldProj = Main.proj;
152
153 try {
154 Main.proj = (Projection)Class.forName(name).newInstance();
155 } catch (final Exception e) {
156 JOptionPane.showMessageDialog(
157 Main.parent,
158 tr("The projection {0} could not be activated. Using Mercator", name),
159 tr("Error"),
160 JOptionPane.ERROR_MESSAGE
161 );
162 coll = null;
163 Main.proj = new Mercator();
164 name = Main.proj.getClass().getName();
165 }
166 Main.pref.putCollection("projection.sub", coll);
167 String sname = name.substring(name.lastIndexOf(".")+1);
168 Main.pref.putCollection("projection.sub."+sname, coll);
169 if(projHasPrefs(Main.proj))
170 ((ProjectionSubPrefs) Main.proj).setPreferences(coll);
171 if(b != null && (!Main.proj.getClass().getName().equals(oldProj.getClass().getName()) || Main.proj.hashCode() != oldProj.hashCode()))
172 {
173 Main.map.mapView.zoomTo(b);
174 /* TODO - remove layers with fixed projection */
175 }
176 }
177
178 private class SBPanel extends JPanel
179 {
180 private Projection p;
181 public SBPanel(Projection pr)
182 {
183 super();
184 p = pr;
185 }
186 @Override
187 public void paint(java.awt.Graphics g)
188 {
189 super.paint(g);
190 ((ProjectionSubPrefs) p).setPreferences(((ProjectionSubPrefs) p).getPreferences(this));
191 updateMeta(p);
192 }
193 };
194
195 /**
196 * Handles all the work related to update the projection-specific
197 * preferences
198 * @param proj
199 */
200 private void selectedProjectionChanged(Projection proj) {
201 if(!projHasPrefs(proj)) {
202 projSubPrefPanel = new JPanel();
203 } else {
204 ProjectionSubPrefs projPref = (ProjectionSubPrefs) proj;
205 projSubPrefPanel = new SBPanel(proj);
206 projPref.setupPreferencePanel(projSubPrefPanel);
207 }
208
209 // Don't try to update if we're still starting up
210 int size = projPanel.getComponentCount();
211 if(size < 1)
212 return;
213
214 // Replace old panel with new one
215 projPanel.remove(size - 1);
216 projPanel.add(projSubPrefPanel, projSubPrefPanelGBC);
217 projPanel.revalidate();
218 projSubPrefPanel.repaint();
219 updateMeta(proj);
220 }
221
222 /**
223 * Sets up projection combobox with default values and action listener
224 */
225 private void setupProjectionCombo() {
226 for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
227 Projection proj = (Projection)projectionCombo.getItemAt(i);
228 String name = proj.getClass().getName();
229 String sname = name.substring(name.lastIndexOf(".")+1);
230 if(projHasPrefs(proj))
231 ((ProjectionSubPrefs) proj).setPreferences(Main.pref.getCollection("projection.sub."+sname, null));
232 if (name.equals(Main.pref.get("projection", Mercator.class.getName()))) {
233 projectionCombo.setSelectedIndex(i);
234 selectedProjectionChanged(proj);
235 break;
236 }
237 }
238
239 projectionCombo.addActionListener(new ActionListener() {
240 public void actionPerformed(ActionEvent e) {
241 JComboBox cb = (JComboBox)e.getSource();
242 Projection proj = (Projection)cb.getSelectedItem();
243 selectedProjectionChanged(proj);
244 }
245 });
246 }
247}
Note: See TracBrowser for help on using the repository browser.