Ignore:
Timestamp:
2015-06-15T08:24:47+02:00 (5 years ago)
Author:
Don-vip
Message:

fix #11562 - use CopyOnWriteArrayList for listeners to avoid ConcurrentModificationException

File:
1 edited

Legend:

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

    r8441 r8489  
    1212import java.awt.event.ActionListener;
    1313import java.awt.event.KeyEvent;
    14 import java.util.ArrayList;
    1514import java.util.List;
    1615import java.util.Set;
    1716import java.util.TreeSet;
     17import java.util.concurrent.CopyOnWriteArrayList;
    1818
    1919import javax.swing.JFrame;
     
    3636    private Timer timer;
    3737
    38     private final List<KeyPressReleaseListener> keyListeners = new ArrayList<>();
    39     private final List<ModifierListener> modifierListeners = new ArrayList<>();
     38    private final List<KeyPressReleaseListener> keyListeners = new CopyOnWriteArrayList<>();
     39    private final List<ModifierListener> modifierListeners = new CopyOnWriteArrayList<>();
    4040    private int previousModifiers;
    4141
     
    4646     * @param l listener to add
    4747     */
    48     public synchronized void addKeyListener(KeyPressReleaseListener l) {
     48    public void addKeyListener(KeyPressReleaseListener l) {
    4949        keyListeners.add(l);
    5050    }
     
    5454     * @param l listener to add
    5555     */
    56     public synchronized void addModifierListener(ModifierListener l) {
     56    public void addModifierListener(ModifierListener l) {
    5757        modifierListeners.add(l);
    5858    }
     
    6262     * @param l listener to remove
    6363     */
    64     public synchronized void removeKeyListener(KeyPressReleaseListener l) {
     64    public void removeKeyListener(KeyPressReleaseListener l) {
    6565        keyListeners.remove(l);
    6666    }
     
    7070     * @param l listener to remove
    7171     */
    72     public synchronized void removeModifierListener(ModifierListener l) {
     72    public void removeModifierListener(ModifierListener l) {
    7373        modifierListeners.remove(l);
    7474    }
     
    8888                timer.stop();
    8989                if (set.remove(releaseEvent.getKeyCode()) && enabled) {
    90                     synchronized (AdvancedKeyPressDetector.this) {
    91                         if (isFocusInMainWindow()) {
    92                             for (KeyPressReleaseListener q: keyListeners) {
    93                                 q.doKeyReleased(releaseEvent);
    94                             }
     90                    if (isFocusInMainWindow()) {
     91                        for (KeyPressReleaseListener q: keyListeners) {
     92                            q.doKeyReleased(releaseEvent);
    9593                        }
    9694                    }
     
    107105        timer.stop();
    108106        set.clear();
    109         synchronized (this) {
    110             if (!keyListeners.isEmpty()) {
    111                 Main.warn(tr("Some of the key listeners forgot to remove themselves: {0}"), keyListeners.toString());
    112             }
    113             if (!modifierListeners.isEmpty()) {
    114                 Main.warn(tr("Some of the key modifier listeners forgot to remove themselves: {0}"), modifierListeners.toString());
    115             }
     107        if (!keyListeners.isEmpty()) {
     108            Main.warn(tr("Some of the key listeners forgot to remove themselves: {0}"), keyListeners.toString());
     109        }
     110        if (!modifierListeners.isEmpty()) {
     111            Main.warn(tr("Some of the key modifier listeners forgot to remove themselves: {0}"), modifierListeners.toString());
    116112        }
    117113        try {
     
    130126                timer.stop();
    131127            } else if (set.add(e.getKeyCode()) && enabled) {
    132                 synchronized (this) {
    133                     if (isFocusInMainWindow()) {
    134                         for (KeyPressReleaseListener q: keyListeners) {
    135                             if (Main.isDebugEnabled()) {
    136                                 Main.debug(q+" => doKeyPressed("+e+")");
    137                             }
    138                             q.doKeyPressed(e);
     128                if (isFocusInMainWindow()) {
     129                    for (KeyPressReleaseListener q: keyListeners) {
     130                        if (Main.isDebugEnabled()) {
     131                            Main.debug(q+" => doKeyPressed("+e+")");
    139132                        }
     133                        q.doKeyPressed(e);
    140134                    }
    141135                }
     
    145139                timer.stop();
    146140                if (set.remove(e.getKeyCode()) && enabled) {
    147                     synchronized (this) {
    148                         if (isFocusInMainWindow()) {
    149                             for (KeyPressReleaseListener q: keyListeners) {
    150                                 if (Main.isDebugEnabled()) {
    151                                     Main.debug(q+" => doKeyReleased("+e+")");
    152                                 }
    153                                 q.doKeyReleased(e);
     141                    if (isFocusInMainWindow()) {
     142                        for (KeyPressReleaseListener q: keyListeners) {
     143                            if (Main.isDebugEnabled()) {
     144                                Main.debug(q+" => doKeyReleased("+e+")");
    154145                            }
     146                            q.doKeyReleased(e);
    155147                        }
    156148                    }
     
    174166        if (previousModifiers != modif) {
    175167            previousModifiers = modif;
    176             synchronized (this) {
    177                 for (ModifierListener m: modifierListeners) {
    178                     m.modifiersChanged(modif);
    179                 }
     168            for (ModifierListener m: modifierListeners) {
     169                m.modifiersChanged(modif);
    180170            }
    181171        }
Note: See TracChangeset for help on using the changeset viewer.