Changeset 5538 in josm
- Timestamp:
- 2012-10-20T09:08:17+02:00 (12 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/Main.java
r5519 r5538 7 7 import java.awt.GridBagConstraints; 8 8 import java.awt.GridBagLayout; 9 import java.awt.Window; 9 10 import java.awt.event.ComponentEvent; 10 11 import java.awt.event.ComponentListener; … … 18 19 import java.text.MessageFormat; 19 20 import java.util.ArrayList; 21 import java.util.Arrays; 20 22 import java.util.Collection; 21 23 import java.util.Iterator; … … 912 914 synchronized(Main.class) { 913 915 Iterator<WeakReference<ProjectionChangeListener>> it = listeners.iterator(); 914 while (it.hasNext()){916 while (it.hasNext()){ 915 917 WeakReference<ProjectionChangeListener> wr = it.next(); 916 918 ProjectionChangeListener listener = wr.get(); … … 930 932 931 933 /** 932 * Register a projection change listener 934 * Register a projection change listener. 933 935 * 934 936 * @param listener the listener. Ignored if <code>null</code>. … … 946 948 947 949 /** 948 * Removes a projection change listener 950 * Removes a projection change listener. 949 951 * 950 952 * @param listener the listener. Ignored if <code>null</code>. … … 954 956 synchronized(Main.class){ 955 957 Iterator<WeakReference<ProjectionChangeListener>> it = listeners.iterator(); 956 while (it.hasNext()){958 while (it.hasNext()){ 957 959 WeakReference<ProjectionChangeListener> wr = it.next(); 958 // remove the listener - and any other listener which go dgarbage960 // remove the listener - and any other listener which got garbage 959 961 // collected in the meantime 960 962 if (wr.get() == null || wr.get() == listener) { … … 964 966 } 965 967 } 968 969 /** 970 * Listener for window switch events. 971 * 972 * These are events, when the user activates a window of another application 973 * or comes back to JOSM. Window switches from one JOSM window to another 974 * are not reported. 975 */ 976 public static interface WindowSwitchListener { 977 /** 978 * Called when the user activates a window of another application. 979 */ 980 void toOtherApplication(); 981 /** 982 * Called when the user comes from a window of another application 983 * back to JOSM. 984 */ 985 void fromOtherApplication(); 986 } 987 988 private static final ArrayList<WeakReference<WindowSwitchListener>> windowSwitchListeners = new ArrayList<WeakReference<WindowSwitchListener>>(); 989 990 /** 991 * Register a window switch listener. 992 * 993 * @param listener the listener. Ignored if <code>null</code>. 994 */ 995 public static void addWindowSwitchListener(WindowSwitchListener listener) { 996 if (listener == null) return; 997 synchronized (Main.class) { 998 for (WeakReference<WindowSwitchListener> wr : windowSwitchListeners) { 999 // already registered ? => abort 1000 if (wr.get() == listener) return; 1001 } 1002 boolean wasEmpty = windowSwitchListeners.isEmpty(); 1003 windowSwitchListeners.add(new WeakReference<WindowSwitchListener>(listener)); 1004 if (wasEmpty) { 1005 // The following call will have no effect, when there is no window 1006 // at the time. Therefore, MasterWindowListener.setup() will also be 1007 // called, as soon as the main window is shown. 1008 MasterWindowListener.setup(); 1009 } 1010 } 1011 } 1012 1013 /** 1014 * Removes a window switch listener. 1015 * 1016 * @param listener the listener. Ignored if <code>null</code>. 1017 */ 1018 public static void removeWindowSwitchListener(WindowSwitchListener listener) { 1019 if (listener == null) return; 1020 synchronized (Main.class){ 1021 Iterator<WeakReference<WindowSwitchListener>> it = windowSwitchListeners.iterator(); 1022 while (it.hasNext()){ 1023 WeakReference<WindowSwitchListener> wr = it.next(); 1024 // remove the listener - and any other listener which got garbage 1025 // collected in the meantime 1026 if (wr.get() == null || wr.get() == listener) { 1027 it.remove(); 1028 } 1029 } 1030 if (windowSwitchListeners.isEmpty()) { 1031 MasterWindowListener.teardown(); 1032 } 1033 } 1034 } 1035 1036 /** 1037 * WindowListener, that is registered on all Windows of the application. 1038 * 1039 * Its purpose is to notify WindowSwitchListeners, that the user switches to 1040 * another application, e.g. a browser, or back to JOSM. 1041 * 1042 * When changing from JOSM to another application and back (e.g. two times 1043 * alt+tab), the active Window within JOSM may be different. 1044 * Therefore, we need to register listeners to <strong>all</strong> (visible) 1045 * Windows in JOSM, and it does not suffice to monitor the one that was 1046 * deactivated last. 1047 * 1048 * This class is only "active" on demand, i.e. when there is at least one 1049 * WindowSwitchListener registered. 1050 */ 1051 protected static class MasterWindowListener extends WindowAdapter { 1052 1053 private static MasterWindowListener INSTANCE; 1054 1055 public static MasterWindowListener getInstance() { 1056 if (INSTANCE == null) { 1057 INSTANCE = new MasterWindowListener(); 1058 } 1059 return INSTANCE; 1060 } 1061 1062 /** 1063 * Register listeners to all non-hidden windows. 1064 * 1065 * Windows that are created later, will be cared for in {@link #windowDeactivated(WindowEvent)}. 1066 */ 1067 public static void setup() { 1068 if (!windowSwitchListeners.isEmpty()) { 1069 for (Window w : Window.getWindows()) { 1070 if (w.isShowing()) { 1071 if (!Arrays.asList(w.getWindowListeners()).contains(getInstance())) { 1072 w.addWindowListener(getInstance()); 1073 } 1074 } 1075 } 1076 } 1077 } 1078 1079 /** 1080 * Unregister all listeners. 1081 */ 1082 public static void teardown() { 1083 for (Window w : Window.getWindows()) { 1084 w.removeWindowListener(getInstance()); 1085 } 1086 } 1087 1088 @Override 1089 public void windowActivated(WindowEvent e) { 1090 if (e.getOppositeWindow() == null) { // we come from a window of a different application 1091 // fire WindowSwitchListeners 1092 synchronized (Main.class) { 1093 Iterator<WeakReference<WindowSwitchListener>> it = windowSwitchListeners.iterator(); 1094 while (it.hasNext()){ 1095 WeakReference<WindowSwitchListener> wr = it.next(); 1096 WindowSwitchListener listener = wr.get(); 1097 if (listener == null) { 1098 it.remove(); 1099 continue; 1100 } 1101 listener.fromOtherApplication(); 1102 } 1103 } 1104 } 1105 } 1106 1107 @Override 1108 public void windowDeactivated(WindowEvent e) { 1109 // set up windows that have been created in the meantime 1110 for (Window w : Window.getWindows()) { 1111 if (!w.isShowing()) { 1112 w.removeWindowListener(getInstance()); 1113 } else { 1114 if (!Arrays.asList(w.getWindowListeners()).contains(getInstance())) { 1115 w.addWindowListener(getInstance()); 1116 } 1117 } 1118 } 1119 if (e.getOppositeWindow() == null) { // we go to a window of a different application 1120 // fire WindowSwitchListeners 1121 synchronized (Main.class) { 1122 Iterator<WeakReference<WindowSwitchListener>> it = windowSwitchListeners.iterator(); 1123 while (it.hasNext()){ 1124 WeakReference<WindowSwitchListener> wr = it.next(); 1125 WindowSwitchListener listener = wr.get(); 1126 if (listener == null) { 1127 it.remove(); 1128 continue; 1129 } 1130 listener.toOtherApplication(); 1131 } 1132 } 1133 } 1134 } 1135 } 1136 966 1137 } -
trunk/src/org/openstreetmap/josm/gui/MainApplication.java
r5365 r5538 351 351 splash.dispose(); 352 352 mainFrame.setVisible(true); 353 Main.MasterWindowListener.setup(); 353 354 354 355 boolean maximized = Boolean.parseBoolean(Main.pref.get("gui.maximized")); -
trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java
r5463 r5538 78 78 import org.openstreetmap.josm.tools.Utils; 79 79 80 public class MapPaintDialog extends ToggleDialog {80 public class MapPaintDialog extends ToggleDialog implements Main.WindowSwitchListener { 81 81 82 82 protected StylesTable tblStyles; … … 178 178 } 179 179 180 /** 181 * Reload local styles when they have been changed in an external editor. 182 * 183 * Checks file modification time when an WindowEvent is invoked. Because 184 * any dialog window can get activated, when switching to another app and back, 185 * we have to register listeners to all windows in JOSM. 186 */ 187 protected static class ReloadWindowListener extends WindowAdapter { 188 189 private static ReloadWindowListener INSTANCE; 190 191 public static ReloadWindowListener getInstance() { 192 if (INSTANCE == null) { 193 INSTANCE = new ReloadWindowListener(); 194 } 195 return INSTANCE; 196 } 197 198 public static void setup() { 199 for (Window w : Window.getWindows()) { 200 if (w.isShowing()) { 201 w.addWindowListener(getInstance()); 180 @Override 181 public void toOtherApplication() { 182 // nothing 183 } 184 185 @Override 186 public void fromOtherApplication() { 187 // Reload local styles when they have been changed in an external editor. 188 // Checks file modification time. 189 List<StyleSource> toReload = new ArrayList<StyleSource>(); 190 for (StyleSource s : MapPaintStyles.getStyles().getStyleSources()) { 191 if (s.isLocal()) { 192 File f = new File(s.url); 193 long mtime = f.lastModified(); 194 if (mtime > s.getLastMTime()) { 195 toReload.add(s); 196 s.setLastMTime(mtime); 202 197 } 203 198 } 204 199 } 205 206 public static void teardown() { 207 for (Window w : Window.getWindows()) { 208 w.removeWindowListener(getInstance()); 209 } 210 } 211 212 @Override 213 public void windowActivated(WindowEvent e) { 214 if (e.getOppositeWindow() == null) { // we come from a native window, e.g. editor 215 // reload local styles, if necessary 216 List<StyleSource> toReload = new ArrayList<StyleSource>(); 217 for (StyleSource s : MapPaintStyles.getStyles().getStyleSources()) { 218 if (s.isLocal()) { 219 File f = new File(s.url); 220 long mtime = f.lastModified(); 221 if (mtime > s.getLastMTime()) { 222 toReload.add(s); 223 s.setLastMTime(mtime); 224 } 225 } 226 } 227 if (!toReload.isEmpty()) { 228 System.out.println(trn("Reloading {0} map style.", "Reloading {0} map styles.", toReload.size(), toReload.size())); 229 Main.worker.submit(new MapPaintStyleLoader(toReload)); 230 } 231 } 232 } 233 234 @Override 235 public void windowDeactivated(WindowEvent e) { 236 // set up windows that have been created in the meantime 237 for (Window w : Window.getWindows()) { 238 w.removeWindowListener(getInstance()); 239 if (w.isShowing()) { 240 w.addWindowListener(getInstance()); 241 } 242 } 200 if (!toReload.isEmpty()) { 201 System.out.println(trn("Reloading {0} map style.", "Reloading {0} map styles.", toReload.size(), toReload.size())); 202 Main.worker.submit(new MapPaintStyleLoader(toReload)); 243 203 } 244 204 } … … 249 209 Main.main.menu.wireFrameToggleAction.addButtonModel(cbWireframe.getModel()); 250 210 if (Main.pref.getBoolean("mappaint.auto_reload_local_styles", true)) { 251 ReloadWindowListener.setup();211 Main.addWindowSwitchListener(this); 252 212 } 253 213 } … … 258 218 MapPaintStyles.removeMapPaintSylesUpdateListener(model); 259 219 if (Main.pref.getBoolean("mappaint.auto_reload_local_styles", true)) { 260 ReloadWindowListener.teardown();220 Main.removeWindowSwitchListener(this); 261 221 } 262 222 }
Note:
See TracChangeset
for help on using the changeset viewer.