Ticket #16869: 16869-PreferenceChangedListener.patch

File 16869-PreferenceChangedListener.patch, 32.8 KB (added by simon04, 7 years ago)

Migrate some PreferenceChangedListener to ValueChangeListener

  • src/org/openstreetmap/josm/actions/PreferenceToggleAction.java

    commit 31b90bef7c1f7cb6c98c6249a56de7a5f6606657
    Author: Simon Legner <Simon.Legner@gmail.com>
    Date:   Sun Oct 21 21:36:09 2018 +0200
    
        see #16869 - Migrate some PreferenceChangedListener to ValueChangeListener
    
    diff --git a/src/org/openstreetmap/josm/actions/PreferenceToggleAction.java b/src/org/openstreetmap/josm/actions/PreferenceToggleAction.java
    index 14243d7b1..1a480a994 100644
    a b  
    55
    66import javax.swing.JCheckBoxMenuItem;
    77
    8 import org.openstreetmap.josm.data.Preferences;
    98import org.openstreetmap.josm.data.preferences.BooleanProperty;
    10 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    119import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    1210
    1311/**
     
    1614 * A user action will just change a preference value. To take any real action,
    1715 * register another {@link PreferenceChangedListener} for the given preference key.
    1816 */
    19 public class PreferenceToggleAction extends JosmAction implements PreferenceChangedListener {
     17public class PreferenceToggleAction extends JosmAction {
    2018
    2119    private final JCheckBoxMenuItem checkbox;
    2220    private final BooleanProperty pref;
    public PreferenceToggleAction(String name, String tooltip, String prefKey, boole  
    3432        this.pref = new BooleanProperty(prefKey, prefDefault);
    3533        checkbox = new JCheckBoxMenuItem(this);
    3634        checkbox.setSelected(pref.get());
    37         Preferences.main().addWeakKeyPreferenceChangeListener(prefKey, this);
     35        this.pref.addWeakListener(event -> checkbox.setSelected(event.getProperty().get()));
    3836    }
    3937
    4038    @Override
    public void actionPerformed(ActionEvent e) {  
    4947    public JCheckBoxMenuItem getCheckbox() {
    5048        return checkbox;
    5149    }
    52 
    53     @Override
    54     public void preferenceChanged(PreferenceChangeEvent e) {
    55         checkbox.setSelected(pref.get());
    56     }
    5750}
  • src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java

    diff --git a/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java b/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java
    index 1df0a64c2..1e83eae21 100644
    a b  
    1717import javax.swing.JCheckBoxMenuItem;
    1818import javax.swing.JPopupMenu;
    1919
    20 import org.openstreetmap.josm.data.Preferences;
    2120import org.openstreetmap.josm.data.coor.EastNorth;
    2221import org.openstreetmap.josm.data.coor.LatLon;
    2322import org.openstreetmap.josm.data.osm.DataSet;
    2423import org.openstreetmap.josm.data.osm.Node;
    2524import org.openstreetmap.josm.data.osm.Way;
    2625import org.openstreetmap.josm.data.osm.WaySegment;
     26import org.openstreetmap.josm.data.preferences.ListProperty;
    2727import org.openstreetmap.josm.gui.MainApplication;
    2828import org.openstreetmap.josm.gui.MapView;
    2929import org.openstreetmap.josm.gui.MapViewState;
     
    3131import org.openstreetmap.josm.gui.draw.MapViewPath;
    3232import org.openstreetmap.josm.gui.draw.SymbolShape;
    3333import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    34 import org.openstreetmap.josm.spi.preferences.Config;
    3534import org.openstreetmap.josm.tools.Logging;
    3635import org.openstreetmap.josm.tools.Utils;
    3736
    public void mouseClicked(MouseEvent e) {  
    6463        };
    6564    }
    6665
    67     private static final String DRAW_ANGLESNAP_ANGLES = "draw.anglesnap.angles";
     66    private static final ListProperty DRAW_ANGLESNAP_ANGLES = new ListProperty("draw.anglesnap.angles",
     67            Arrays.asList("0", "30", "45", "60", "90", "120", "135", "150", "180"));
    6868
    6969    private static final class RepeatedAction extends AbstractAction {
    7070        RepeatedAction(DrawSnapHelper snapHelper) {
    public void init() {  
    233233        absoluteFix = false;
    234234
    235235        computeSnapAngles();
    236         Preferences.main().addWeakKeyPreferenceChangeListener(DRAW_ANGLESNAP_ANGLES, e -> this.computeSnapAngles());
     236        DRAW_ANGLESNAP_ANGLES.addWeakListener(event -> computeSnapAngles());
    237237    }
    238238
    239239    private void computeSnapAngles() {
    240         snapAngles = Config.getPref().getList(DRAW_ANGLESNAP_ANGLES,
    241                 Arrays.asList("0", "30", "45", "60", "90", "120", "135", "150", "180"))
     240        snapAngles = DRAW_ANGLESNAP_ANGLES.get()
    242241                .stream()
    243242                .mapToDouble(DrawSnapHelper::parseSnapAngle)
    244243                .flatMap(s -> DoubleStream.of(s, 360-s))
    private static double parseSnapAngle(String string) {  
    259258     * @param angles The angles
    260259     */
    261260    public void saveAngles(String... angles) {
    262         Config.getPref().putList(DRAW_ANGLESNAP_ANGLES, Arrays.asList(angles));
     261        DRAW_ANGLESNAP_ANGLES.put(Arrays.asList(angles));
    263262    }
    264263
    265264    /**
  • src/org/openstreetmap/josm/data/osm/ChangesetCache.java

    diff --git a/src/org/openstreetmap/josm/data/osm/ChangesetCache.java b/src/org/openstreetmap/josm/data/osm/ChangesetCache.java
    index a86768846..23ed1cf1d 100644
    a b  
    1212import java.util.stream.Collectors;
    1313
    1414import org.openstreetmap.josm.data.UserIdentityManager;
    15 import org.openstreetmap.josm.spi.preferences.Config;
    16 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    17 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
     15import org.openstreetmap.josm.io.OsmApi;
    1816import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    1917
    2018/**
     
    3129 * clears itself if the OSM API URL is changed in the preferences.
    3230 *
    3331 */
    34 public final class ChangesetCache implements PreferenceChangedListener {
     32public final class ChangesetCache {
    3533    /** the unique instance */
    3634    private static final ChangesetCache INSTANCE = new ChangesetCache();
    3735
     
    4442     * Constructs a new {@code ChangesetCache}.
    4543     */
    4644    private ChangesetCache() {
    47         Config.getPref().addPreferenceChangeListener(this);
     45        OsmApi.SERVER_URL_PROPERTY.addListener(event -> clear());
    4846    }
    4947
    5048    /**
    public void clear() {  
    252250                    object -> UserIdentityManager.getInstance().isCurrentUser(object.getUser())));
    253251        }
    254252    }
    255 
    256     /* ------------------------------------------------------------------------- */
    257     /* interface PreferenceChangedListener                                       */
    258     /* ------------------------------------------------------------------------- */
    259     @Override
    260     public void preferenceChanged(PreferenceChangeEvent e) {
    261         if (e.getKey() == null || !"osm-server.url".equals(e.getKey()))
    262             return;
    263 
    264         // clear the cache when the API url changes
    265         if (e.getOldValue() == null || e.getNewValue() == null || !e.getOldValue().equals(e.getNewValue())) {
    266             clear();
    267         }
    268     }
    269253}
  • src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java

    diff --git a/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java b/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
    index cc22c4ec3..aa2057bf3 100644
    a b  
    1212import java.util.List;
    1313import java.util.Optional;
    1414import java.util.Set;
     15import java.util.stream.Stream;
    1516
    1617import org.openstreetmap.josm.data.coor.EastNorth;
    1718import org.openstreetmap.josm.data.osm.DataSet;
     
    2324import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
    2425import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
    2526import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
     27import org.openstreetmap.josm.data.preferences.ListProperty;
    2628import org.openstreetmap.josm.data.projection.Projection;
    2729import org.openstreetmap.josm.data.projection.ProjectionRegistry;
    2830import org.openstreetmap.josm.spi.preferences.Config;
    29 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    30 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    3131import org.openstreetmap.josm.tools.Geometry;
    3232import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter;
    3333import org.openstreetmap.josm.tools.Logging;
     34import org.openstreetmap.josm.tools.Pair;
    3435
    3536/**
    3637 * Multipolygon data used to represent complex areas, see <a href="https://wiki.openstreetmap.org/wiki/Relation:multipolygon">wiki</a>.
     
    4142    /** preference key for a collection of roles which indicate that the respective member belongs to an
    4243     * <em>outer</em> polygon. Default is <code>outer</code>.
    4344     */
    44     public static final String PREF_KEY_OUTER_ROLES = "mappaint.multipolygon.outer.roles";
     45    public static final ListProperty PREF_KEY_OUTER_ROLES = new ListProperty("mappaint.multipolygon.outer.roles", Collections.emptyList());
    4546
    4647    /** preference key for collection of role prefixes which indicate that the respective
    4748     *  member belongs to an <em>outer</em> polygon. Default is empty.
    4849     */
    49     public static final String PREF_KEY_OUTER_ROLE_PREFIXES = "mappaint.multipolygon.outer.role-prefixes";
     50    public static final ListProperty PREF_KEY_OUTER_ROLE_PREFIXES = new ListProperty("mappaint.multipolygon.outer.role-prefixes", Collections.emptyList());
    5051
    5152    /** preference key for a collection of roles which indicate that the respective member belongs to an
    5253     * <em>inner</em> polygon. Default is <code>inner</code>.
    5354     */
    54     public static final String PREF_KEY_INNER_ROLES = "mappaint.multipolygon.inner.roles";
     55    public static final ListProperty PREF_KEY_INNER_ROLES = new ListProperty("mappaint.multipolygon.inner.roles", Collections.emptyList());
    5556
    5657    /** preference key for collection of role prefixes which indicate that the respective
    5758     *  member belongs to an <em>inner</em> polygon. Default is empty.
    5859     */
    59     public static final String PREF_KEY_INNER_ROLE_PREFIXES = "mappaint.multipolygon.inner.role-prefixes";
     60    public static final ListProperty PREF_KEY_INNER_ROLE_PREFIXES = new ListProperty("mappaint.multipolygon.inner.role-prefixes", Collections.emptyList());
    6061
    6162    /**
    6263     * <p>Kind of strategy object which is responsible for deciding whether a given
     
    6667     * <p>The decision is taken based on preference settings, see the four preference keys
    6768     * above.</p>
    6869     */
    69     private static class MultipolygonRoleMatcher implements PreferenceChangedListener {
     70    private static class MultipolygonRoleMatcher {
    7071        private final List<String> outerExactRoles = new ArrayList<>();
    7172        private final List<String> outerRolePrefixes = new ArrayList<>();
    7273        private final List<String> innerExactRoles = new ArrayList<>();
    private static void setNormalized(Collection<String> literals, List<String> targ  
    9798        private void initFromPreferences() {
    9899            initDefaults();
    99100            if (Config.getPref() == null) return;
    100             Collection<String> literals;
    101             literals = Config.getPref().getList(PREF_KEY_OUTER_ROLES);
    102             if (literals != null && !literals.isEmpty()) {
    103                 setNormalized(literals, outerExactRoles);
    104             }
    105             literals = Config.getPref().getList(PREF_KEY_OUTER_ROLE_PREFIXES);
    106             if (literals != null && !literals.isEmpty()) {
    107                 setNormalized(literals, outerRolePrefixes);
    108             }
    109             literals = Config.getPref().getList(PREF_KEY_INNER_ROLES);
    110             if (literals != null && !literals.isEmpty()) {
    111                 setNormalized(literals, innerExactRoles);
    112             }
    113             literals = Config.getPref().getList(PREF_KEY_INNER_ROLE_PREFIXES);
    114             if (literals != null && !literals.isEmpty()) {
    115                 setNormalized(literals, innerRolePrefixes);
    116             }
     101            Stream.of(
     102                    new Pair<>(PREF_KEY_OUTER_ROLES, outerExactRoles),
     103                    new Pair<>(PREF_KEY_OUTER_ROLE_PREFIXES, outerRolePrefixes),
     104                    new Pair<>(PREF_KEY_INNER_ROLES, innerExactRoles),
     105                    new Pair<>(PREF_KEY_INNER_ROLE_PREFIXES, innerRolePrefixes)
     106            ).forEach(pair -> {
     107                final Collection<String> literals = pair.a.get();
     108                if (literals != null && !literals.isEmpty()) {
     109                    setNormalized(literals, pair.b);
     110                }
     111            });
    117112        }
    118113
    119         @Override
    120         public void preferenceChanged(PreferenceChangeEvent evt) {
    121             if (PREF_KEY_INNER_ROLE_PREFIXES.equals(evt.getKey()) ||
    122                     PREF_KEY_INNER_ROLES.equals(evt.getKey()) ||
    123                     PREF_KEY_OUTER_ROLE_PREFIXES.equals(evt.getKey()) ||
    124                     PREF_KEY_OUTER_ROLES.equals(evt.getKey())) {
    125                 initFromPreferences();
    126             }
     114        private void registerPreferenceListeners() {
     115            PREF_KEY_OUTER_ROLES.addListener(event -> initFromPreferences());
     116            PREF_KEY_OUTER_ROLE_PREFIXES.addListener(event -> initFromPreferences());
     117            PREF_KEY_INNER_ROLES.addListener(event -> initFromPreferences());
     118            PREF_KEY_INNER_ROLE_PREFIXES.addListener(event -> initFromPreferences());
    127119        }
    128120
    129121        boolean isOuterRole(String role) {
    private static synchronized MultipolygonRoleMatcher getMultipolygonRoleMatcher()  
    158150        if (roleMatcher == null) {
    159151            roleMatcher = new MultipolygonRoleMatcher();
    160152            if (Config.getPref() != null) {
     153                roleMatcher.registerPreferenceListeners();
    161154                roleMatcher.initFromPreferences();
    162                 Config.getPref().addPreferenceChangeListener(roleMatcher);
    163155            }
    164156        }
    165157        return roleMatcher;
  • src/org/openstreetmap/josm/gui/MainMenu.java

    diff --git a/src/org/openstreetmap/josm/gui/MainMenu.java b/src/org/openstreetmap/josm/gui/MainMenu.java
    index f17f7cf7a..c24b31d97 100644
    a b  
    115115import org.openstreetmap.josm.actions.audio.AudioSlowerAction;
    116116import org.openstreetmap.josm.actions.search.SearchAction;
    117117import org.openstreetmap.josm.data.UndoRedoHandler;
     118import org.openstreetmap.josm.data.preferences.BooleanProperty;
    118119import org.openstreetmap.josm.gui.dialogs.MenuItemSearchDialog;
    119120import org.openstreetmap.josm.gui.io.RecentlyOpenedFilesMenu;
    120121import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
     
    123124import org.openstreetmap.josm.gui.preferences.imagery.ImageryPreference;
    124125import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
    125126import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetSearchPrimitiveDialog;
    126 import org.openstreetmap.josm.spi.preferences.Config;
    127127import org.openstreetmap.josm.tools.PlatformManager;
    128128import org.openstreetmap.josm.tools.Shortcut;
    129129
    public void initialize() {  
    814814                MainMenu.WINDOW_MENU_GROUP.ALWAYS);
    815815        changesetManager.addButtonModel(mi.getModel());
    816816
    817         if (!Config.getPref().getBoolean("audio.menuinvisible", false)) {
     817        final BooleanProperty audioMenuInvisible = new BooleanProperty("audio.menuinvisible", false);
     818        if (!audioMenuInvisible.get()) {
    818819            showAudioMenu(true);
    819820        }
    820 
    821         Config.getPref().addPreferenceChangeListener(e -> {
    822             if ("audio.menuinvisible".equals(e.getKey())) {
    823                 showAudioMenu(!Boolean.parseBoolean(e.getNewValue().toString()));
    824             }
    825         });
     821        audioMenuInvisible.addListener(event -> showAudioMenu(!event.getProperty().get()));
    826822
    827823        add(helpMenu, new MenuItemSearchDialog.Action());
    828824        helpMenu.addSeparator();
  • src/org/openstreetmap/josm/gui/MapFrame.java

    diff --git a/src/org/openstreetmap/josm/gui/MapFrame.java b/src/org/openstreetmap/josm/gui/MapFrame.java
    index a51bf3758..4d8de2b37 100644
    a b  
    5252import org.openstreetmap.josm.actions.mapmode.SelectAction;
    5353import org.openstreetmap.josm.actions.mapmode.ZoomAction;
    5454import org.openstreetmap.josm.data.ViewportData;
     55import org.openstreetmap.josm.data.preferences.AbstractProperty;
    5556import org.openstreetmap.josm.data.preferences.BooleanProperty;
    5657import org.openstreetmap.josm.data.preferences.IntegerProperty;
    5758import org.openstreetmap.josm.gui.dialogs.ChangesetDialog;
     
    7879import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
    7980import org.openstreetmap.josm.gui.util.AdvancedKeyPressDetector;
    8081import org.openstreetmap.josm.spi.preferences.Config;
    81 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    8282import org.openstreetmap.josm.tools.Destroyable;
    8383import org.openstreetmap.josm.tools.GBC;
    8484import org.openstreetmap.josm.tools.ImageProvider;
    public void destroy() {  
    345345        MainApplication.getLayerManager().removeLayerChangeListener(this);
    346346        MainApplication.getLayerManager().removeActiveLayerChangeListener(this);
    347347        dialogsPanel.destroy();
    348         Config.getPref().removePreferenceChangeListener(sidetoolbarPreferencesChangedListener);
     348        removeSideToolbarPreferencesChangedListener.run();
    349349        for (int i = 0; i < toolBarActions.getComponentCount(); ++i) {
    350350            if (toolBarActions.getComponent(i) instanceof Destroyable) {
    351351                ((Destroyable) toolBarActions.getComponent(i)).destroy();
    public void fillPanel(Container panel) {  
    547547            final ScrollViewport svp = new ScrollViewport(sideToolBar, ScrollViewport.VERTICAL_DIRECTION);
    548548            sideToolBar = svp;
    549549        }
    550         sideToolBar.setVisible(Config.getPref().getBoolean("sidetoolbar.visible", true));
    551         sidetoolbarPreferencesChangedListener = e -> {
    552             if ("sidetoolbar.visible".equals(e.getKey())) {
    553                 sideToolBar.setVisible(Config.getPref().getBoolean("sidetoolbar.visible"));
    554             }
    555         };
    556         Config.getPref().addPreferenceChangeListener(sidetoolbarPreferencesChangedListener);
     550        final BooleanProperty sideToolbarVisible = new BooleanProperty("sidetoolbar.visible", true);
     551        sideToolBar.setVisible(sideToolbarVisible.get());
     552        final AbstractProperty.ValueChangeListener<Boolean> sideToolbarPreferencesChangedListener = event ->
     553                sideToolBar.setVisible(event.getProperty().get());
     554        sideToolbarVisible.addListener(sideToolbarPreferencesChangedListener);
     555        removeSideToolbarPreferencesChangedListener = () -> sideToolbarVisible.removeListener(sideToolbarPreferencesChangedListener);
    557556
    558557        /**
    559558         * sideToolBar: add it to the panel
    public void addTopPanel(Component c) {  
    796795     */
    797796    private static final CopyOnWriteArrayList<MapModeChangeListener> mapModeChangeListeners = new CopyOnWriteArrayList<>();
    798797
    799     private transient PreferenceChangedListener sidetoolbarPreferencesChangedListener;
     798    private transient Runnable removeSideToolbarPreferencesChangedListener;
    800799    /**
    801800     * Adds a mapMode change listener
    802801     *
  • src/org/openstreetmap/josm/gui/MapMover.java

    diff --git a/src/org/openstreetmap/josm/gui/MapMover.java b/src/org/openstreetmap/josm/gui/MapMover.java
    index e293734b7..8420d9ea1 100644
    a b  
    2121import org.openstreetmap.josm.data.preferences.BooleanProperty;
    2222import org.openstreetmap.josm.gui.MapViewState.MapViewPoint;
    2323import org.openstreetmap.josm.gui.layer.Layer;
    24 import org.openstreetmap.josm.spi.preferences.Config;
    25 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    26 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    2724import org.openstreetmap.josm.tools.Destroyable;
    2825import org.openstreetmap.josm.tools.Pair;
    2926import org.openstreetmap.josm.tools.PlatformManager;
     
    4340    public static final BooleanProperty PROP_ZOOM_REVERSE_WHEEL = new BooleanProperty("zoom.reverse-wheel", false);
    4441
    4542    static {
    46         new JMapViewerUpdater();
     43        PROP_ZOOM_REVERSE_WHEEL.addListener(event -> updateJMapViewer());
     44        updateJMapViewer();
    4745    }
    4846
    49     private static class JMapViewerUpdater implements PreferenceChangedListener {
    50 
    51         JMapViewerUpdater() {
    52             Config.getPref().addPreferenceChangeListener(this);
    53             updateJMapViewer();
    54         }
    55 
    56         @Override
    57         public void preferenceChanged(PreferenceChangeEvent e) {
    58             if (MapMover.PROP_ZOOM_REVERSE_WHEEL.getKey().equals(e.getKey())) {
    59                 updateJMapViewer();
    60             }
    61         }
    62 
    63         private static void updateJMapViewer() {
    64             JMapViewer.zoomReverseWheel = MapMover.PROP_ZOOM_REVERSE_WHEEL.get();
    65         }
     47    private static void updateJMapViewer() {
     48        JMapViewer.zoomReverseWheel = MapMover.PROP_ZOOM_REVERSE_WHEEL.get();
    6649    }
    6750
    6851    private final class ZoomerAction extends AbstractAction {
  • src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java

    diff --git a/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java b/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java
    index 9bc799d0b..fcedeaf20 100644
    a b  
    5252import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    5353import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
    5454import org.openstreetmap.josm.gui.widgets.OSDLabel;
    55 import org.openstreetmap.josm.spi.preferences.Config;
    56 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    57 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    5855import org.openstreetmap.josm.tools.Logging;
    5956
    6057/**
     
    6360 * @since 12400
    6461 */
    6562public final class AutoFilterManager
    66 implements ZoomChangeListener, MapModeChangeListener, DataSetListener, PreferenceChangedListener, LayerChangeListener {
     63implements ZoomChangeListener, MapModeChangeListener, DataSetListener, LayerChangeListener {
    6764
    6865    /**
    6966     * Property to determines if the auto filter feature is enabled.
    public static AutoFilterManager getInstance() {  
    123120
    124121    private AutoFilterManager() {
    125122        MapFrame.addMapModeChangeListener(this);
    126         Config.getPref().addPreferenceChangeListener(this);
     123        registerPropertyListeners();
    127124        NavigatableComponent.addZoomChangeListener(this);
    128125        MainApplication.getLayerManager().addLayerChangeListener(this);
    129126        DatasetEventManager.getInstance().addDatasetListener(this, FireMode.IN_EDT_CONSOLIDATED);
    private void resetCurrentAutoFilter() {  
    397394        }
    398395    }
    399396
    400     @Override
    401     public void preferenceChanged(PreferenceChangeEvent e) {
    402         if (e.getKey().equals(PROP_AUTO_FILTER_ENABLED.getKey())) {
     397    private void registerPropertyListeners() {
     398        PROP_AUTO_FILTER_ENABLED.addListener(event -> {
    403399            if (PROP_AUTO_FILTER_ENABLED.get()) {
    404400                enableAutoFilterRule(PROP_AUTO_FILTER_RULE.get());
    405401                updateButtons();
    public void preferenceChanged(PreferenceChangeEvent e) {  
    407403                enableAutoFilterRule((AutoFilterRule) null);
    408404                resetCurrentAutoFilter();
    409405            }
    410         } else if (e.getKey().equals(PROP_AUTO_FILTER_RULE.getKey())) {
     406        });
     407        PROP_AUTO_FILTER_RULE.addListener(event -> {
    411408            enableAutoFilterRule(PROP_AUTO_FILTER_RULE.get());
    412409            resetCurrentAutoFilter();
    413410            updateButtons();
    414         }
     411        });
    415412    }
    416413
    417414    @Override
  • src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java b/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
    index dc072e29b..8fff76c8f 100644
    a b  
    4848import javax.swing.SwingUtilities;
    4949
    5050import org.openstreetmap.josm.actions.JosmAction;
     51import org.openstreetmap.josm.data.preferences.AbstractProperty;
    5152import org.openstreetmap.josm.data.preferences.BooleanProperty;
    5253import org.openstreetmap.josm.data.preferences.ParametrizedEnumProperty;
    5354import org.openstreetmap.josm.gui.MainApplication;
     
    6667import org.openstreetmap.josm.gui.util.WindowGeometry.WindowGeometryException;
    6768import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    6869import org.openstreetmap.josm.spi.preferences.Config;
    69 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    70 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    7170import org.openstreetmap.josm.tools.Destroyable;
    7271import org.openstreetmap.josm.tools.GBC;
    7372import org.openstreetmap.josm.tools.ImageProvider;
     
    7877 * This class is a toggle dialog that can be turned on and off.
    7978 * @since 8
    8079 */
    81 public class ToggleDialog extends JPanel implements ShowHideButtonListener, Helpful, AWTEventListener, Destroyable, PreferenceChangedListener {
     80public class ToggleDialog extends JPanel implements ShowHideButtonListener, Helpful, AWTEventListener, Destroyable, AbstractProperty.ValueChangeListener<Boolean> {
    8281
    8382    /**
    8483     * The button-hiding strategy in toggler dialogs.
    public ToggleDialog(String name, String iconName, String tooltip, Shortcut short  
    256255        setBorder(BorderFactory.createEtchedBorder());
    257256
    258257        MainApplication.redirectToMainContentPane(this);
    259         Config.getPref().addPreferenceChangeListener(this);
     258        PROP_DYNAMIC_BUTTONS.addListener(this);
    260259
    261260        registerInWindowMenu();
    262261    }
    public void destroy() {  
    467466        } catch (SecurityException e) {
    468467            Logging.log(Logging.LEVEL_ERROR, "Unable to remove AWT event listener", e);
    469468        }
    470         Config.getPref().removePreferenceChangeListener(this);
     469        PROP_DYNAMIC_BUTTONS.removeListener(this);
    471470        destroyComponents(this, false);
    472471    }
    473472
    public void eventDispatched(AWTEvent event) {  
    967966    }
    968967
    969968    @Override
    970     public void preferenceChanged(PreferenceChangeEvent e) {
    971         if (e.getKey().equals(PROP_DYNAMIC_BUTTONS.getKey())) {
    972             dynamicButtonsPropertyChanged();
    973         }
     969    public void valueChanged(AbstractProperty.ValueChangeEvent<? extends Boolean> e) {
     970        dynamicButtonsPropertyChanged();
    974971    }
    975972
    976973    private void dynamicButtonsPropertyChanged() {
  • src/org/openstreetmap/josm/gui/io/UploadDialog.java

    diff --git a/src/org/openstreetmap/josm/gui/io/UploadDialog.java b/src/org/openstreetmap/josm/gui/io/UploadDialog.java
    index 8221f605e..9c3d6843c 100644
    a b  
    5252import org.openstreetmap.josm.io.UploadStrategy;
    5353import org.openstreetmap.josm.io.UploadStrategySpecification;
    5454import org.openstreetmap.josm.spi.preferences.Config;
    55 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    56 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    57 import org.openstreetmap.josm.spi.preferences.Setting;
    5855import org.openstreetmap.josm.tools.GBC;
    5956import org.openstreetmap.josm.tools.ImageOverlay;
    6057import org.openstreetmap.josm.tools.ImageProvider;
     
    6764 * the upload changeset and the strategy for opening/closing a changeset.
    6865 * @since 2025
    6966 */
    70 public class UploadDialog extends AbstractUploadDialog implements PropertyChangeListener, PreferenceChangedListener {
     67public class UploadDialog extends AbstractUploadDialog implements PropertyChangeListener {
    7168    /** the unique instance of the upload dialog */
    7269    private static UploadDialog uploadDialog;
    7370
    public void actionPerformed(ActionEvent e) {  
    246243
    247244        setMinimumSize(new Dimension(600, 350));
    248245
    249         Config.getPref().addPreferenceChangeListener(this);
     246        OsmApi.SERVER_URL_PROPERTY.addWeakListener(event -> {
     247            String url = event.getProperty().get();
     248            if (url == null) {
     249                url = OsmApi.getOsmApi().getBaseUrl();
     250            }
     251            setTitle(tr("Upload to ''{0}''", url));
     252        });
    250253    }
    251254
    252255    /**
    public void propertyChange(PropertyChangeEvent evt) {  
    633636        }
    634637    }
    635638
    636     /* -------------------------------------------------------------------------- */
    637     /* Interface PreferenceChangedListener                                        */
    638     /* -------------------------------------------------------------------------- */
    639     @Override
    640     public void preferenceChanged(PreferenceChangeEvent e) {
    641         if (e.getKey() == null || !"osm-server.url".equals(e.getKey()))
    642             return;
    643         final Setting<?> newValue = e.getNewValue();
    644         final String url;
    645         if (newValue == null || newValue.getValue() == null) {
    646             url = OsmApi.getOsmApi().getBaseUrl();
    647         } else {
    648             url = newValue.getValue().toString();
    649         }
    650         setTitle(tr("Upload to ''{0}''", url));
    651     }
    652 
    653639    private static String getLastChangesetTagFromHistory(String historyKey, List<String> def) {
    654640        Collection<String> history = Config.getPref().getList(historyKey, def);
    655641        int age = (int) (System.currentTimeMillis() / 1000 - Config.getPref().getInt(BasicUploadSettingsPanel.HISTORY_LAST_USED_KEY, 0));
  • src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java

    diff --git a/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java b/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java
    index d936dd52c..0fc5ee453 100644
    a b  
    6666import org.openstreetmap.josm.actions.ParameterizedActionDecorator;
    6767import org.openstreetmap.josm.data.imagery.ImageryInfo;
    6868import org.openstreetmap.josm.data.imagery.ImageryLayerInfo;
     69import org.openstreetmap.josm.data.preferences.BooleanProperty;
    6970import org.openstreetmap.josm.gui.MainApplication;
    7071import org.openstreetmap.josm.gui.help.HelpUtil;
    7172import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
     
    8586public class ToolbarPreferences implements PreferenceSettingFactory {
    8687
    8788    private static final String EMPTY_TOOLBAR_MARKER = "<!-empty-!>";
     89    private static final BooleanProperty PROP_TOOLBAR_VISIBLE = new BooleanProperty("toolbar.visible", true);
    8890
    8991    /**
    9092     * The prefix for imagery toolbar entries.
    public ToolbarPreferences() {  
    10081010            control.setFloatable(false);
    10091011            control.setComponentPopupMenu(popupMenu);
    10101012        });
    1011         Config.getPref().addPreferenceChangeListener(e -> {
    1012             if ("toolbar.visible".equals(e.getKey())) {
    1013                 refreshToolbarControl();
    1014             }
    1015         });
     1013        PROP_TOOLBAR_VISIBLE.addListener(event -> refreshToolbarControl());
    10161014    }
    10171015
    10181016    private void loadAction(DefaultMutableTreeNode node, MenuElement menu) {
    public void refreshToolbarControl() {  
    11941192            }
    11951193        }
    11961194
    1197         boolean visible = Config.getPref().getBoolean("toolbar.visible", true);
     1195        boolean visible = PROP_TOOLBAR_VISIBLE.get();
    11981196
    11991197        control.setFocusTraversalKeysEnabled(!unregisterTab);
    12001198        control.setVisible(visible && control.getComponentCount() != 0);
  • src/org/openstreetmap/josm/io/OsmApi.java

    diff --git a/src/org/openstreetmap/josm/io/OsmApi.java b/src/org/openstreetmap/josm/io/OsmApi.java
    index 858d7ed51..7ac4909cc 100644
    a b  
    3030import org.openstreetmap.josm.data.osm.IPrimitive;
    3131import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3232import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     33import org.openstreetmap.josm.data.preferences.StringProperty;
    3334import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    3435import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3536import org.openstreetmap.josm.io.Capabilities.CapabilitiesParser;
     
    7879    @Deprecated
    7980    public static final String DEFAULT_API_URL = "https://api.openstreetmap.org/api";
    8081
     82    public static StringProperty SERVER_URL_PROPERTY = new StringProperty(
     83            "osm-server.url", Config.getUrls().getDefaultOsmApiUrl());
     84
    8185    // The collection of instantiated OSM APIs
    8286    private static final Map<String, OsmApi> instances = new HashMap<>();
    8387
    protected static void cacheInstance(OsmApi api) {  
    136140        instances.put(api.getServerUrl(), api);
    137141    }
    138142
    139     private static String getServerUrlFromPref() {
    140         return Config.getPref().get("osm-server.url", Config.getUrls().getDefaultOsmApiUrl());
    141     }
    142 
    143143    /**
    144144     * Replies the {@link OsmApi} for the URL given by the preference <code>osm-server.url</code>
    145145     *
    146146     * @return the OsmApi
    147147     */
    148148    public static OsmApi getOsmApi() {
    149         return getOsmApi(getServerUrlFromPref());
     149        return getOsmApi(SERVER_URL_PROPERTY.get());
    150150    }
    151151
    152152    /** Server URL */
    public String getHost() {  
    212212
    213213        @Override
    214214        protected void checkOfflineAccess() {
    215             OnlineResource.OSM_API.checkOfflineAccess(getBaseUrl(getServerUrlFromPref(), "0.6")+CAPABILITIES, getServerUrlFromPref());
     215            final String serverUrl = SERVER_URL_PROPERTY.get();
     216            OnlineResource.OSM_API.checkOfflineAccess(getBaseUrl(serverUrl, "0.6")+CAPABILITIES, serverUrl);
    216217        }
    217218
    218219        @Override