001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.history;
003
004import java.awt.GridBagLayout;
005import java.util.ArrayList;
006import java.util.List;
007
008import javax.swing.AbstractAction;
009import javax.swing.JPanel;
010
011import org.openstreetmap.josm.actions.JosmAction;
012import org.openstreetmap.josm.tools.Destroyable;
013
014/**
015 * Superclass of history browsing panels, backed by an {@link HistoryBrowserModel}.
016 * @since 14463
017 */
018public abstract class HistoryBrowserPanel extends JPanel implements Destroyable {
019
020    /** the model */
021    protected transient HistoryBrowserModel model;
022    /** the common info panel for the history object in role REFERENCE_POINT_IN_TIME */
023    protected VersionInfoPanel referenceInfoPanel;
024    /** the common info panel for the history object in role CURRENT_POINT_IN_TIME */
025    protected VersionInfoPanel currentInfoPanel;
026
027    private final List<JosmAction> josmActions = new ArrayList<>();
028
029    protected HistoryBrowserPanel() {
030        super(new GridBagLayout());
031    }
032
033    protected void registerAsChangeListener(HistoryBrowserModel model) {
034        if (currentInfoPanel != null) {
035            model.addChangeListener(currentInfoPanel);
036        }
037        if (referenceInfoPanel != null) {
038            model.addChangeListener(referenceInfoPanel);
039        }
040    }
041
042    protected void unregisterAsChangeListener(HistoryBrowserModel model) {
043        if (currentInfoPanel != null) {
044            model.removeChangeListener(currentInfoPanel);
045        }
046        if (referenceInfoPanel != null) {
047            model.removeChangeListener(referenceInfoPanel);
048        }
049    }
050
051    /**
052     * Sets the history browsing model for this viewer.
053     *
054     * @param model the history browsing model
055     */
056    protected final void setModel(HistoryBrowserModel model) {
057        if (this.model != null) {
058            unregisterAsChangeListener(this.model);
059        }
060        this.model = model;
061        if (this.model != null) {
062            registerAsChangeListener(model);
063        }
064    }
065
066    protected final <T extends AbstractAction> T trackJosmAction(T action) {
067        if (action instanceof JosmAction) {
068            josmActions.add((JosmAction) action);
069        }
070        return action;
071    }
072
073    @Override
074    public void destroy() {
075        setModel(null);
076        if (referenceInfoPanel != null)
077            referenceInfoPanel.destroy();
078        if (currentInfoPanel != null)
079            currentInfoPanel.destroy();
080        josmActions.forEach(JosmAction::destroy);
081        josmActions.clear();
082    }
083}