Changeset 2871 in josm


Ignore:
Timestamp:
2010-01-17T16:37:24+01:00 (14 years ago)
Author:
jttt
Message:

Partially fix situation after last layer removal - most objects still stay in memory but at least there are less references and forgotten listeners

Location:
trunk/src/org/openstreetmap/josm
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/JosmAction.java

    r2759 r2871  
    9494        }
    9595        MapView.removeLayerChangeListener(layerChangeAdapter);
    96         if (DataSet.selListeners != null) {
    97             DataSet.selListeners.remove(selectionChangeAdapter);
    98         }
     96        DataSet.selListeners.remove(selectionChangeAdapter);
    9997    }
    10098
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r2845 r2871  
    271271     * dataset. (However, the selection does only change in the active layer)
    272272     */
    273     public static Collection<SelectionChangedListener> selListeners =
     273    public static final Collection<SelectionChangedListener> selListeners =
    274274        Collections.synchronizedList(new LinkedList<SelectionChangedListener>());
    275275
  • trunk/src/org/openstreetmap/josm/data/osm/history/HistoryDataSet.java

    r2845 r2871  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.data.osm.history;
    3 
    4 import static org.openstreetmap.josm.tools.I18n.tr;
    53
    64import java.text.MessageFormat;
  • trunk/src/org/openstreetmap/josm/gui/IconToggleButton.java

    r2005 r2871  
    1010import javax.swing.JToggleButton;
    1111
     12import org.openstreetmap.josm.tools.Destroyable;
     13
    1214/**
    1315 * Just a toggle button, with smaller border and icon only to display in
     
    1618 * @author imi
    1719 */
    18 public class IconToggleButton extends JToggleButton implements PropertyChangeListener {
     20public class IconToggleButton extends JToggleButton implements PropertyChangeListener, Destroyable {
    1921
    2022    public boolean groupbutton;
     
    4951        }
    5052    }
     53
     54    public void destroy() {
     55        Action action = getAction();
     56        if (action instanceof Destroyable) {
     57            ((Destroyable) action).destroy();
     58        }
     59    }
    5160}
  • trunk/src/org/openstreetmap/josm/gui/MapFrame.java

    r2869 r2871  
    187187        for (int i = 0; i < toolBarActions.getComponentCount(); ++i)
    188188            if (toolBarActions.getComponent(i) instanceof Destroyable) {
    189                 ((Destroyable)toolBarActions).destroy();
     189                ((Destroyable)toolBarActions.getComponent(i)).destroy();
    190190            }
    191191        for (int i = 0; i < toolBarToggle.getComponentCount(); ++i)
    192192            if (toolBarToggle.getComponent(i) instanceof Destroyable) {
    193                 ((Destroyable)toolBarToggle).destroy();
     193                ((Destroyable)toolBarToggle.getComponent(i)).destroy();
    194194            }
    195195
  • trunk/src/org/openstreetmap/josm/gui/MapStatus.java

    r2869 r2871  
    6969     */
    7070    final MapView mv;
     71    final Collector collector;
    7172
    7273    /**
     
    143144         */
    144145        public void run() {
    145             for (;;) {
    146 
    147                 MouseState ms = new MouseState();
    148                 synchronized (this) {
    149                     try {wait();} catch (InterruptedException e) {}
    150                     ms.modifiers = mouseState.modifiers;
    151                     ms.mousePos = mouseState.mousePos;
    152                 }
    153                 if (parent != Main.map)
    154                     return; // exit, if new parent.
    155 
    156                 // Do nothing, if required data is missing
    157                 if(ms.mousePos == null || mv.center == null) {
    158                     continue;
    159                 }
    160 
    161                 // Freeze display when holding down CTRL
    162                 if ((ms.modifiers & MouseEvent.CTRL_DOWN_MASK) != 0) {
    163                     // update the information popup's labels though, because
    164                     // the selection might have changed from the outside
    165                     popupUpdateLabels();
    166                     continue;
    167                 }
    168 
    169                 // This try/catch is a hack to stop the flooding bug reports about this.
    170                 // The exception needed to handle with in the first place, means that this
    171                 // access to the data need to be restarted, if the main thread modifies
    172                 // the data.
    173                 try {
    174                     // Set the text label in the bottom status bar
    175                     statusBarElementUpdate(ms);
    176 
    177                     // The popup != null check is required because a left-click
    178                     // produces several events as well, which would make this
    179                     // variable true. Of course we only want the popup to show
    180                     // if the middle mouse button has been pressed in the first
    181                     // place
    182                     boolean isAtOldPosition = (oldMousePos != null
    183                             && oldMousePos.equals(ms.mousePos)
    184                             && popup != null);
    185                     boolean middleMouseDown = (ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0;
    186 
    187                     // Popup Information
    188                     // display them if the middle mouse button is pressed and
    189                     // keep them until the mouse is moved
    190                     if (middleMouseDown || isAtOldPosition)
    191                     {
    192                         Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos);
    193 
    194                         if (osms == null) {
    195                             continue;
     146            registerListeners();
     147            try {
     148                for (;;) {
     149
     150                    MouseState ms = new MouseState();
     151                    synchronized (this) {
     152                        // TODO Would be better if the timeout wasn't necessary
     153                        try {wait(1000);} catch (InterruptedException e) {}
     154                        ms.modifiers = mouseState.modifiers;
     155                        ms.mousePos = mouseState.mousePos;
     156                    }
     157                    if (parent != Main.map)
     158                        return; // exit, if new parent.
     159
     160                    // Do nothing, if required data is missing
     161                    if(ms.mousePos == null || mv.center == null) {
     162                        continue;
     163                    }
     164
     165                    // Freeze display when holding down CTRL
     166                    if ((ms.modifiers & MouseEvent.CTRL_DOWN_MASK) != 0) {
     167                        // update the information popup's labels though, because
     168                        // the selection might have changed from the outside
     169                        popupUpdateLabels();
     170                        continue;
     171                    }
     172
     173                    // This try/catch is a hack to stop the flooding bug reports about this.
     174                    // The exception needed to handle with in the first place, means that this
     175                    // access to the data need to be restarted, if the main thread modifies
     176                    // the data.
     177                    try {
     178                        // Set the text label in the bottom status bar
     179                        statusBarElementUpdate(ms);
     180
     181                        // The popup != null check is required because a left-click
     182                        // produces several events as well, which would make this
     183                        // variable true. Of course we only want the popup to show
     184                        // if the middle mouse button has been pressed in the first
     185                        // place
     186                        boolean isAtOldPosition = (oldMousePos != null
     187                                && oldMousePos.equals(ms.mousePos)
     188                                && popup != null);
     189                        boolean middleMouseDown = (ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0;
     190
     191                        // Popup Information
     192                        // display them if the middle mouse button is pressed and
     193                        // keep them until the mouse is moved
     194                        if (middleMouseDown || isAtOldPosition)
     195                        {
     196                            Collection<OsmPrimitive> osms = mv.getAllNearest(ms.mousePos);
     197
     198                            if (osms == null) {
     199                                continue;
     200                            }
     201
     202                            final JPanel c = new JPanel(new GridBagLayout());
     203                            final JLabel lbl = new JLabel(
     204                                    "<html>"+tr("Middle click again to cycle through.<br>"+
     205                                    "Hold CTRL to select directly from this list with the mouse.<hr>")+"</html>",
     206                                    null,
     207                                    JLabel.HORIZONTAL
     208                            );
     209                            lbl.setHorizontalAlignment(JLabel.LEFT);
     210                            c.add(lbl, GBC.eol().insets(2, 0, 2, 0));
     211
     212                            // Only cycle if the mouse has not been moved and the
     213                            // middle mouse button has been pressed at least twice
     214                            // (the reason for this is the popup != null check for
     215                            // isAtOldPosition, see above. This is a nice side
     216                            // effect though, because it does not change selection
     217                            // of the first middle click)
     218                            if(isAtOldPosition && middleMouseDown) {
     219                                // Hand down mouse modifiers so the SHIFT mod can be
     220                                // handled correctly (see funcion)
     221                                popupCycleSelection(osms, ms.modifiers);
     222                            }
     223
     224                            // These labels may need to be updated from the outside
     225                            // so collect them
     226                            List<JLabel> lbls = new ArrayList<JLabel>();
     227                            for (final OsmPrimitive osm : osms) {
     228                                JLabel l = popupBuildPrimitiveLabels(osm);
     229                                lbls.add(l);
     230                                c.add(l, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2));
     231                            }
     232
     233                            popupShowPopup(popupCreatePopup(c, ms), lbls);
     234                        } else {
     235                            popupHidePopup();
    196236                        }
    197237
    198                         final JPanel c = new JPanel(new GridBagLayout());
    199                         final JLabel lbl = new JLabel(
    200                                 "<html>"+tr("Middle click again to cycle through.<br>"+
    201                                 "Hold CTRL to select directly from this list with the mouse.<hr>")+"</html>",
    202                                 null,
    203                                 JLabel.HORIZONTAL
    204                         );
    205                         lbl.setHorizontalAlignment(JLabel.LEFT);
    206                         c.add(lbl, GBC.eol().insets(2, 0, 2, 0));
    207 
    208                         // Only cycle if the mouse has not been moved and the
    209                         // middle mouse button has been pressed at least twice
    210                         // (the reason for this is the popup != null check for
    211                         // isAtOldPosition, see above. This is a nice side
    212                         // effect though, because it does not change selection
    213                         // of the first middle click)
    214                         if(isAtOldPosition && middleMouseDown) {
    215                             // Hand down mouse modifiers so the SHIFT mod can be
    216                             // handled correctly (see funcion)
    217                             popupCycleSelection(osms, ms.modifiers);
    218                         }
    219 
    220                         // These labels may need to be updated from the outside
    221                         // so collect them
    222                         List<JLabel> lbls = new ArrayList<JLabel>();
    223                         for (final OsmPrimitive osm : osms) {
    224                             JLabel l = popupBuildPrimitiveLabels(osm);
    225                             lbls.add(l);
    226                             c.add(l, GBC.eol().fill(GBC.HORIZONTAL).insets(2, 0, 2, 2));
    227                         }
    228 
    229                         popupShowPopup(popupCreatePopup(c, ms), lbls);
    230                     } else {
    231                         popupHidePopup();
     238                        oldMousePos = ms.mousePos;
     239                    } catch (ConcurrentModificationException x) {
     240                        //x.printStackTrace();
     241                    } catch (NullPointerException x) {
     242                        //x.printStackTrace();
    232243                    }
    233 
    234                     oldMousePos = ms.mousePos;
    235                 } catch (ConcurrentModificationException x) {
    236                     //x.printStackTrace();
    237                 } catch (NullPointerException x) {
    238                     //x.printStackTrace();
    239                 }
     244                }
     245            } finally {
     246                unregisterListeners();
    240247            }
    241248        }
     
    496503    MouseState mouseState = new MouseState();
    497504
     505    private AWTEventListener awtListener = new AWTEventListener() {
     506        public void eventDispatched(AWTEvent event) {
     507            if (event instanceof ComponentEvent &&
     508                    ((ComponentEvent)event).getComponent() == mv) {
     509                synchronized (collector) {
     510                    mouseState.modifiers = ((InputEvent)event).getModifiersEx();
     511                    if (event instanceof MouseEvent) {
     512                        mouseState.mousePos = ((MouseEvent)event).getPoint();
     513                    }
     514                    collector.notify();
     515                }
     516            }
     517        }
     518    };
     519
     520    private MouseMotionListener mouseMotionListener = new MouseMotionListener() {
     521        public void mouseMoved(MouseEvent e) {
     522            synchronized (collector) {
     523                mouseState.modifiers = e.getModifiersEx();
     524                mouseState.mousePos = e.getPoint();
     525                collector.notify();
     526            }
     527        }
     528
     529        public void mouseDragged(MouseEvent e) {
     530            mouseMoved(e);
     531        }
     532    };
     533
     534    private KeyAdapter keyAdapter = new KeyAdapter() {
     535        @Override public void keyPressed(KeyEvent e) {
     536            synchronized (collector) {
     537                mouseState.modifiers = e.getModifiersEx();
     538                collector.notify();
     539            }
     540        }
     541
     542        @Override public void keyReleased(KeyEvent e) {
     543            keyPressed(e);
     544        }
     545    };
     546
     547    private void registerListeners() {
     548        // Listen to keyboard/mouse events for pressing/releasing alt key and
     549        // inform the collector.
     550        try {
     551            Toolkit.getDefaultToolkit().addAWTEventListener(awtListener,
     552                    AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
     553        } catch (SecurityException ex) {
     554            mv.addMouseMotionListener(mouseMotionListener);
     555            mv.addKeyListener(keyAdapter);
     556        }
     557    }
     558
     559    private void unregisterListeners() {
     560        try {
     561            Toolkit.getDefaultToolkit().removeAWTEventListener(awtListener);
     562        } catch (SecurityException e) {
     563            // Don't care, awtListener probably wasn't registered anyway
     564        }
     565        mv.removeMouseMotionListener(mouseMotionListener);
     566        mv.removeKeyListener(keyAdapter);
     567    }
     568
     569
    498570    /**
    499571     * Construct a new MapStatus and attach it to the map view.
     
    502574    public MapStatus(final MapFrame mapFrame) {
    503575        this.mv = mapFrame.mapView;
     576        this.collector = new Collector(mapFrame);
    504577
    505578        JumpToAction JumpToAct = new JumpToAction();
     
    539612
    540613        // The background thread
    541         final Collector collector = new Collector(mapFrame);
    542614        thread = new Thread(collector, "Map Status Collector");
    543615        thread.setDaemon(true);
    544616        thread.start();
    545 
    546         // Listen to keyboard/mouse events for pressing/releasing alt key and
    547         // inform the collector.
    548         try {
    549             Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener(){
    550                 public void eventDispatched(AWTEvent event) {
    551                     if (event instanceof ComponentEvent &&
    552                             ((ComponentEvent)event).getComponent() == mapFrame.mapView) {
    553                         synchronized (collector) {
    554                             mouseState.modifiers = ((InputEvent)event).getModifiersEx();
    555                             if (event instanceof MouseEvent) {
    556                                 mouseState.mousePos = ((MouseEvent)event).getPoint();
    557                             }
    558                             collector.notify();
    559                         }
    560                     }
    561                 }
    562             }, AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
    563         } catch (SecurityException ex) {
    564             mapFrame.mapView.addMouseMotionListener(new MouseMotionListener() {
    565                 public void mouseMoved(MouseEvent e) {
    566                     synchronized (collector) {
    567                         mouseState.modifiers = e.getModifiersEx();
    568                         mouseState.mousePos = e.getPoint();
    569                         collector.notify();
    570                     }
    571                 }
    572 
    573                 public void mouseDragged(MouseEvent e) {
    574                     mouseMoved(e);
    575                 }
    576             });
    577 
    578             mapFrame.mapView.addKeyListener(new KeyAdapter() {
    579                 @Override public void keyPressed(KeyEvent e) {
    580                     synchronized (collector) {
    581                         mouseState.modifiers = e.getModifiersEx();
    582                         collector.notify();
    583                     }
    584                 }
    585 
    586                 @Override public void keyReleased(KeyEvent e) {
    587                     keyPressed(e);
    588                 }
    589             });
    590         }
    591617    }
    592618
  • trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java

    r2710 r2871  
    6464    protected ShowHistoryAction showHistoryAction;
    6565    protected ReloadAction reloadAction;
     66
     67    public HistoryDialog() {
     68        super(tr("History"), "history", tr("Display the history of all selected items."),
     69                Shortcut.registerShortcut("subwindow:history", tr("Toggle: {0}", tr("History")), KeyEvent.VK_H,
     70                        Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
     71        build();
     72        DataSet.selListeners.add(model);
     73    }
    6674
    6775    /**
     
    128136    }
    129137
    130     public HistoryDialog() {
    131         super(tr("History"), "history", tr("Display the history of all selected items."),
    132                 Shortcut.registerShortcut("subwindow:history", tr("Toggle: {0}", tr("History")), KeyEvent.VK_H,
    133                         Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
    134         build();
    135         DataSet.selListeners.add(model);
     138    @Override
     139    public void showNotify() {
    136140        HistoryDataSet.getInstance().addHistoryDataSetListener(this);
     141    }
     142
     143    @Override
     144    public void hideNotify() {
     145        HistoryDataSet.getInstance().removeHistoryDataSetListener(this);
    137146    }
    138147
  • trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java

    r2869 r2871  
    106106        setMinimumSize(new Dimension(0,0));
    107107        this.preferredHeight = preferredHeight;
    108         toggleAction = new ToggleDialogAction(name, "dialogs/"+iconName, tooltip, shortcut, iconName);
     108        toggleAction = new ToggleDialogAction(this, name, "dialogs/"+iconName, tooltip, shortcut, iconName);
    109109        String helpId = "Dialog/"+getClass().getName().substring(getClass().getName().lastIndexOf('.')+1);
    110110        toggleAction.putValue("help", helpId.substring(0, helpId.length()-6));
     
    134134     *
    135135     */
    136     public final class ToggleDialogAction extends JosmAction {
    137         private ToggleDialogAction(String name, String iconName, String tooltip, Shortcut shortcut, String prefname) {
     136    public final static class ToggleDialogAction extends JosmAction {
     137
     138        private ToggleDialog dialog;
     139
     140        private ToggleDialogAction(ToggleDialog dialog, String name, String iconName, String tooltip, Shortcut shortcut, String prefname) {
    138141            super(name, iconName, tooltip, shortcut, false);
     142            this.dialog = dialog;
    139143        }
    140144
    141145        public void actionPerformed(ActionEvent e) {
    142             toggleButtonHook();
    143             if (isShowing) {
    144                 hideDialog();
    145                 dialogsPanel.reconstruct(Action.ELEMENT_SHRINKS, null);
     146            dialog.toggleButtonHook();
     147            if (dialog.isShowing) {
     148                dialog.hideDialog();
     149                dialog.dialogsPanel.reconstruct(Action.ELEMENT_SHRINKS, null);
    146150            } else {
    147                 showDialog();
    148                 if (isDocked && isCollapsed) {
    149                     expand();
     151                dialog.showDialog();
     152                if (dialog.isDocked && dialog.isCollapsed) {
     153                    dialog.expand();
    150154                }
    151                 if (isDocked) {
    152                     dialogsPanel.reconstruct(Action.INVISIBLE_TO_DEFAULT, ToggleDialog.this);
     155                if (dialog.isDocked) {
     156                    dialog.dialogsPanel.reconstruct(Action.INVISIBLE_TO_DEFAULT, dialog);
    153157                }
    154158            }
     159        }
     160
     161        @Override
     162        public void destroy() {
     163            super.destroy();
     164            dialog = null;
    155165        }
    156166    }
Note: See TracChangeset for help on using the changeset viewer.