Changeset 8509 in josm for trunk/src/org/openstreetmap/josm/gui/MapStatus.java
- Timestamp:
- 2015-06-20T14:36:00+02:00 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/MapStatus.java
r8470 r8509 228 228 229 229 /** 230 * The collector class that waits for notification and then update 231 * the display objects. 230 * The collector class that waits for notification and then update the display objects. 232 231 * 233 232 * @author imi 234 233 */ 235 234 private final class Collector implements Runnable { 235 private final class CollectorWorker implements Runnable { 236 private final MouseState ms; 237 238 private CollectorWorker(MouseState ms) { 239 this.ms = ms; 240 } 241 242 @Override 243 public void run() { 244 // Freeze display when holding down CTRL 245 if ((ms.modifiers & MouseEvent.CTRL_DOWN_MASK) != 0) { 246 // update the information popup's labels though, because the selection might have changed from the outside 247 popupUpdateLabels(); 248 return; 249 } 250 251 // This try/catch is a hack to stop the flooding bug reports about this. 252 // The exception needed to handle with in the first place, means that this 253 // access to the data need to be restarted, if the main thread modifies the data. 254 DataSet ds = null; 255 // The popup != null check is required because a left-click produces several events as well, 256 // which would make this variable true. Of course we only want the popup to show 257 // if the middle mouse button has been pressed in the first place 258 boolean mouseNotMoved = oldMousePos != null 259 && oldMousePos.equals(ms.mousePos); 260 boolean isAtOldPosition = mouseNotMoved && popup != null; 261 boolean middleMouseDown = (ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0; 262 try { 263 ds = mv.getCurrentDataSet(); 264 if (ds != null) { 265 // This is not perfect, if current dataset was changed during execution, the lock would be useless 266 if(isAtOldPosition && middleMouseDown) { 267 // Write lock is necessary when selecting in popupCycleSelection 268 // locks can not be upgraded -> if do read lock here and write lock later 269 // (in OsmPrimitive.updateFlags) then always occurs deadlock (#5814) 270 ds.beginUpdate(); 271 } else { 272 ds.getReadLock().lock(); 273 } 274 } 275 276 // Set the text label in the bottom status bar 277 // "if mouse moved only" was added to stop heap growing 278 if (!mouseNotMoved) { 279 statusBarElementUpdate(ms); 280 } 281 282 // Popup Information 283 // display them if the middle mouse button is pressed and keep them until the mouse is moved 284 if (middleMouseDown || isAtOldPosition) { 285 Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos, OsmPrimitive.isUsablePredicate); 286 287 final JPanel c = new JPanel(new GridBagLayout()); 288 final JLabel lbl = new JLabel( 289 "<html>"+tr("Middle click again to cycle through.<br>"+ 290 "Hold CTRL to select directly from this list with the mouse.<hr>")+"</html>", 291 null, 292 JLabel.HORIZONTAL 293 ); 294 lbl.setHorizontalAlignment(JLabel.LEFT); 295 c.add(lbl, GBC.eol().insets(2, 0, 2, 0)); 296 297 // Only cycle if the mouse has not been moved and the middle mouse button has been pressed at least 298 // twice (the reason for this is the popup != null check for isAtOldPosition, see above. 299 // This is a nice side effect though, because it does not change selection of the first middle click) 300 if (isAtOldPosition && middleMouseDown) { 301 // Hand down mouse modifiers so the SHIFT mod can be handled correctly (see function) 302 popupCycleSelection(osms, ms.modifiers); 303 } 304 305 // These labels may need to be updated from the outside so collect them 306 List<JLabel> lbls = new ArrayList<>(osms.size()); 307 for (final OsmPrimitive osm : osms) { 308 JLabel l = popupBuildPrimitiveLabels(osm); 309 lbls.add(l); 310 c.add(l, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2)); 311 } 312 313 popupShowPopup(popupCreatePopup(c, ms), lbls); 314 } else { 315 popupHidePopup(); 316 } 317 318 oldMousePos = ms.mousePos; 319 } catch (ConcurrentModificationException x) { 320 Main.warn(x); 321 } finally { 322 if (ds != null) { 323 if(isAtOldPosition && middleMouseDown) { 324 ds.endUpdate(); 325 } else { 326 ds.getReadLock().unlock(); 327 } 328 } 329 } 330 } 331 } 332 236 333 /** 237 334 * the mouse position of the previous iteration. This is used to show … … 285 382 286 383 try { 287 EventQueue.invokeAndWait(new Runnable() { 288 289 @Override 290 public void run() { 291 // Freeze display when holding down CTRL 292 if ((ms.modifiers & MouseEvent.CTRL_DOWN_MASK) != 0) { 293 // update the information popup's labels though, because 294 // the selection might have changed from the outside 295 popupUpdateLabels(); 296 return; 297 } 298 299 // This try/catch is a hack to stop the flooding bug reports about this. 300 // The exception needed to handle with in the first place, means that this 301 // access to the data need to be restarted, if the main thread modifies 302 // the data. 303 DataSet ds = null; 304 // The popup != null check is required because a left-click 305 // produces several events as well, which would make this 306 // variable true. Of course we only want the popup to show 307 // if the middle mouse button has been pressed in the first place 308 boolean mouseNotMoved = oldMousePos != null 309 && oldMousePos.equals(ms.mousePos); 310 boolean isAtOldPosition = mouseNotMoved && popup != null; 311 boolean middleMouseDown = (ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0; 312 try { 313 ds = mv.getCurrentDataSet(); 314 if (ds != null) { 315 // This is not perfect, if current dataset was changed during execution, the lock would be useless 316 if(isAtOldPosition && middleMouseDown) { 317 // Write lock is necessary when selecting in popupCycleSelection 318 // locks can not be upgraded -> if do read lock here and write lock later (in OsmPrimitive.updateFlags) 319 // then always occurs deadlock (#5814) 320 ds.beginUpdate(); 321 } else { 322 ds.getReadLock().lock(); 323 } 324 } 325 326 // Set the text label in the bottom status bar 327 // "if mouse moved only" was added to stop heap growing 328 if (!mouseNotMoved) { 329 statusBarElementUpdate(ms); 330 } 331 332 // Popup Information 333 // display them if the middle mouse button is pressed and keep them until the mouse is moved 334 if (middleMouseDown || isAtOldPosition) { 335 Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos, OsmPrimitive.isUsablePredicate); 336 337 final JPanel c = new JPanel(new GridBagLayout()); 338 final JLabel lbl = new JLabel( 339 "<html>"+tr("Middle click again to cycle through.<br>"+ 340 "Hold CTRL to select directly from this list with the mouse.<hr>")+"</html>", 341 null, 342 JLabel.HORIZONTAL 343 ); 344 lbl.setHorizontalAlignment(JLabel.LEFT); 345 c.add(lbl, GBC.eol().insets(2, 0, 2, 0)); 346 347 // Only cycle if the mouse has not been moved and the middle mouse button has been pressed at least 348 // twice (the reason for this is the popup != null check for isAtOldPosition, see above. 349 // This is a nice side effect though, because it does not change selection of the first middle click) 350 if (isAtOldPosition && middleMouseDown) { 351 // Hand down mouse modifiers so the SHIFT mod can be handled correctly (see function) 352 popupCycleSelection(osms, ms.modifiers); 353 } 354 355 // These labels may need to be updated from the outside so collect them 356 List<JLabel> lbls = new ArrayList<>(osms.size()); 357 for (final OsmPrimitive osm : osms) { 358 JLabel l = popupBuildPrimitiveLabels(osm); 359 lbls.add(l); 360 c.add(l, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2)); 361 } 362 363 popupShowPopup(popupCreatePopup(c, ms), lbls); 364 } else { 365 popupHidePopup(); 366 } 367 368 oldMousePos = ms.mousePos; 369 } catch (ConcurrentModificationException x) { 370 Main.warn(x); 371 } finally { 372 if (ds != null) { 373 if(isAtOldPosition && middleMouseDown) { 374 ds.endUpdate(); 375 } else { 376 ds.getReadLock().unlock(); 377 } 378 } 379 } 380 } 381 }); 384 EventQueue.invokeAndWait(new CollectorWorker(ms)); 382 385 } catch (InterruptedException e) { 383 386 // Occurs frequently during JOSM shutdown, log set to trace only
Note:
See TracChangeset
for help on using the changeset viewer.