Changeset 3783 in josm for trunk/src/org/openstreetmap/josm


Ignore:
Timestamp:
2011-01-10T21:50:46+01:00 (13 years ago)
Author:
jttt
Message:

Fix #5814 middleclick on way getting drawn locks josm completely

File:
1 edited

Legend:

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

    r3782 r3783  
    145145                for (;;) {
    146146
    147                     MouseState ms = new MouseState();
     147                    final MouseState ms = new MouseState();
    148148                    synchronized (this) {
    149149                        // TODO Would be better if the timeout wasn't necessary
     
    160160                    }
    161161
    162                     // Freeze display when holding down CTRL
    163                     if ((ms.modifiers & MouseEvent.CTRL_DOWN_MASK) != 0) {
    164                         // update the information popup's labels though, because
    165                         // the selection might have changed from the outside
    166                         popupUpdateLabels();
    167                         continue;
    168                     }
    169 
    170                     // This try/catch is a hack to stop the flooding bug reports about this.
    171                     // The exception needed to handle with in the first place, means that this
    172                     // access to the data need to be restarted, if the main thread modifies
    173                     // the data.
    174                     DataSet ds = null;
    175                     // The popup != null check is required because a left-click
    176                     // produces several events as well, which would make this
    177                     // variable true. Of course we only want the popup to show
    178                     // if the middle mouse button has been pressed in the first
    179                     // place
    180                     boolean isAtOldPosition = (oldMousePos != null
    181                             && oldMousePos.equals(ms.mousePos)
    182                             && popup != null);
    183                     boolean middleMouseDown = (ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0;
    184162                    try {
    185                         ds = mv.getCurrentDataSet();
    186                         if (ds != null) {
    187                             // This is not perfect, if current dataset was changed during execution, the lock would be useless
    188                             if(isAtOldPosition && middleMouseDown) {
    189                                 // Write lock is necessary when selecting in popupCycleSelection
    190                                 // locks can not be upgraded -> if do read lock here and write lock later (in OsmPrimitive.updateFlags)
    191                                 // then always occurs deadlock (#5814)
    192                                 ds.beginUpdate();
    193                             } else {
    194                                 ds.getReadLock().lock();
     163                        EventQueue.invokeAndWait(new Runnable() {
     164
     165                            @Override
     166                            public void run() {
     167                                // Freeze display when holding down CTRL
     168                                if ((ms.modifiers & MouseEvent.CTRL_DOWN_MASK) != 0) {
     169                                    // update the information popup's labels though, because
     170                                    // the selection might have changed from the outside
     171                                    popupUpdateLabels();
     172                                    return;
     173                                }
     174
     175                                // This try/catch is a hack to stop the flooding bug reports about this.
     176                                // The exception needed to handle with in the first place, means that this
     177                                // access to the data need to be restarted, if the main thread modifies
     178                                // the data.
     179                                DataSet ds = null;
     180                                // The popup != null check is required because a left-click
     181                                // produces several events as well, which would make this
     182                                // variable true. Of course we only want the popup to show
     183                                // if the middle mouse button has been pressed in the first
     184                                // place
     185                                boolean isAtOldPosition = (oldMousePos != null
     186                                        && oldMousePos.equals(ms.mousePos)
     187                                        && popup != null);
     188                                boolean middleMouseDown = (ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0;
     189                                try {
     190                                    ds = mv.getCurrentDataSet();
     191                                    if (ds != null) {
     192                                        // This is not perfect, if current dataset was changed during execution, the lock would be useless
     193                                        if(isAtOldPosition && middleMouseDown) {
     194                                            // Write lock is necessary when selecting in popupCycleSelection
     195                                            // locks can not be upgraded -> if do read lock here and write lock later (in OsmPrimitive.updateFlags)
     196                                            // then always occurs deadlock (#5814)
     197                                            ds.beginUpdate();
     198                                        } else {
     199                                            ds.getReadLock().lock();
     200                                        }
     201                                    }
     202
     203                                    // Set the text label in the bottom status bar
     204                                    statusBarElementUpdate(ms);
     205
     206
     207                                    // Popup Information
     208                                    // display them if the middle mouse button is pressed and
     209                                    // keep them until the mouse is moved
     210                                    if (middleMouseDown || isAtOldPosition)
     211                                    {
     212                                        Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos, OsmPrimitive.isUsablePredicate);
     213
     214                                        if (osms == null)
     215                                            return;
     216
     217                                        final JPanel c = new JPanel(new GridBagLayout());
     218                                        final JLabel lbl = new JLabel(
     219                                                "<html>"+tr("Middle click again to cycle through.<br>"+
     220                                                "Hold CTRL to select directly from this list with the mouse.<hr>")+"</html>",
     221                                                null,
     222                                                JLabel.HORIZONTAL
     223                                        );
     224                                        lbl.setHorizontalAlignment(JLabel.LEFT);
     225                                        c.add(lbl, GBC.eol().insets(2, 0, 2, 0));
     226
     227                                        // Only cycle if the mouse has not been moved and the
     228                                        // middle mouse button has been pressed at least twice
     229                                        // (the reason for this is the popup != null check for
     230                                        // isAtOldPosition, see above. This is a nice side
     231                                        // effect though, because it does not change selection
     232                                        // of the first middle click)
     233                                        if(isAtOldPosition && middleMouseDown) {
     234                                            // Hand down mouse modifiers so the SHIFT mod can be
     235                                            // handled correctly (see funcion)
     236                                            popupCycleSelection(osms, ms.modifiers);
     237                                        }
     238
     239                                        // These labels may need to be updated from the outside
     240                                        // so collect them
     241                                        List<JLabel> lbls = new ArrayList<JLabel>();
     242                                        for (final OsmPrimitive osm : osms) {
     243                                            JLabel l = popupBuildPrimitiveLabels(osm);
     244                                            lbls.add(l);
     245                                            c.add(l, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2));
     246                                        }
     247
     248                                        popupShowPopup(popupCreatePopup(c, ms), lbls);
     249                                    } else {
     250                                        popupHidePopup();
     251                                    }
     252
     253                                    oldMousePos = ms.mousePos;
     254                                } catch (ConcurrentModificationException x) {
     255                                    //x.printStackTrace();
     256                                } catch (NullPointerException x) {
     257                                    //x.printStackTrace();
     258                                } finally {
     259                                    if (ds != null) {
     260                                        if(isAtOldPosition && middleMouseDown) {
     261                                            ds.endUpdate();
     262                                        } else {
     263                                            ds.getReadLock().unlock();
     264                                        }
     265                                    }
     266                                }
    195267                            }
    196                         }
    197 
    198                         // Set the text label in the bottom status bar
    199                         statusBarElementUpdate(ms);
    200 
    201 
    202                         // Popup Information
    203                         // display them if the middle mouse button is pressed and
    204                         // keep them until the mouse is moved
    205                         if (middleMouseDown || isAtOldPosition)
    206                         {
    207                             Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos, OsmPrimitive.isUsablePredicate);
    208 
    209                             if (osms == null) {
    210                                 continue;
    211                             }
    212 
    213                             final JPanel c = new JPanel(new GridBagLayout());
    214                             final JLabel lbl = new JLabel(
    215                                     "<html>"+tr("Middle click again to cycle through.<br>"+
    216                                     "Hold CTRL to select directly from this list with the mouse.<hr>")+"</html>",
    217                                     null,
    218                                     JLabel.HORIZONTAL
    219                             );
    220                             lbl.setHorizontalAlignment(JLabel.LEFT);
    221                             c.add(lbl, GBC.eol().insets(2, 0, 2, 0));
    222 
    223                             // Only cycle if the mouse has not been moved and the
    224                             // middle mouse button has been pressed at least twice
    225                             // (the reason for this is the popup != null check for
    226                             // isAtOldPosition, see above. This is a nice side
    227                             // effect though, because it does not change selection
    228                             // of the first middle click)
    229                             if(isAtOldPosition && middleMouseDown) {
    230                                 // Hand down mouse modifiers so the SHIFT mod can be
    231                                 // handled correctly (see funcion)
    232                                 popupCycleSelection(osms, ms.modifiers);
    233                             }
    234 
    235                             // These labels may need to be updated from the outside
    236                             // so collect them
    237                             List<JLabel> lbls = new ArrayList<JLabel>();
    238                             for (final OsmPrimitive osm : osms) {
    239                                 JLabel l = popupBuildPrimitiveLabels(osm);
    240                                 lbls.add(l);
    241                                 c.add(l, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2));
    242                             }
    243 
    244                             popupShowPopup(popupCreatePopup(c, ms), lbls);
    245                         } else {
    246                             popupHidePopup();
    247                         }
    248 
    249                         oldMousePos = ms.mousePos;
    250                     } catch (ConcurrentModificationException x) {
    251                         //x.printStackTrace();
    252                     } catch (NullPointerException x) {
    253                         //x.printStackTrace();
    254                     } finally {
    255                         if (ds != null) {
    256                             if(isAtOldPosition && middleMouseDown) {
    257                                 ds.endUpdate();
    258                             } else {
    259                                 ds.getReadLock().unlock();
    260                             }
    261                         }
     268                        });
     269                    } catch (Exception e) {
     270
    262271                    }
    263272                }
Note: See TracChangeset for help on using the changeset viewer.