001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.history;
003    
004    import java.awt.GridBagConstraints;
005    import java.awt.GridBagLayout;
006    import java.awt.Insets;
007    
008    import javax.swing.JPanel;
009    import javax.swing.JScrollPane;
010    import javax.swing.JTable;
011    import javax.swing.ListSelectionModel;
012    /**
013     * RelationMemberListViewer is a UI component which displays the  list of relation members of two
014     * version of a {@link Relation} in a {@link History}.
015     *
016     * <ul>
017     *   <li>on the left, it displays the list of relation members for the version at {@link PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
018     *   <li>on the right, it displays the list of relation members for the version at {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li>
019     * </ul>
020     *
021     */
022    
023    public class RelationMemberListViewer extends JPanel{
024    
025        private HistoryBrowserModel model;
026        private VersionInfoPanel referenceInfoPanel;
027        private VersionInfoPanel currentInfoPanel;
028        private AdjustmentSynchronizer adjustmentSynchronizer;
029        private SelectionSynchronizer selectionSynchronizer;
030    
031        protected JScrollPane embeddInScrollPane(JTable table) {
032            JScrollPane pane = new JScrollPane(table);
033            pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
034            pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
035            adjustmentSynchronizer.participateInSynchronizedScrolling(pane.getVerticalScrollBar());
036            return pane;
037        }
038    
039        protected JTable buildReferenceMemberListTable() {
040            JTable table = new JTable(
041                    model.getRelationMemberTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME),
042                    new RelationMemberTableColumnModel()
043            );
044            table.setName("table.referencememberlisttable");
045            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
046            selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
047            return table;
048        }
049    
050        protected JTable buildCurrentMemberListTable() {
051            JTable table = new JTable(
052                    model.getRelationMemberTableModel(PointInTimeType.CURRENT_POINT_IN_TIME),
053                    new RelationMemberTableColumnModel()
054            );
055            table.setName("table.currentmemberlisttable");
056            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
057            selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
058            return table;
059        }
060    
061        protected void build() {
062            setLayout(new GridBagLayout());
063            GridBagConstraints gc = new GridBagConstraints();
064    
065            // ---------------------------
066            gc.gridx = 0;
067            gc.gridy = 0;
068            gc.gridwidth = 1;
069            gc.gridheight = 1;
070            gc.weightx = 0.5;
071            gc.weighty = 0.0;
072            gc.insets = new Insets(5,5,5,0);
073            gc.fill = GridBagConstraints.HORIZONTAL;
074            gc.anchor = GridBagConstraints.FIRST_LINE_START;
075            referenceInfoPanel = new VersionInfoPanel(model, PointInTimeType.REFERENCE_POINT_IN_TIME);
076            add(referenceInfoPanel,gc);
077    
078            gc.gridx = 1;
079            gc.gridy = 0;
080            gc.gridwidth = 1;
081            gc.gridheight = 1;
082            gc.fill = GridBagConstraints.HORIZONTAL;
083            gc.weightx = 0.5;
084            gc.weighty = 0.0;
085            gc.anchor = GridBagConstraints.FIRST_LINE_START;
086            currentInfoPanel = new VersionInfoPanel(model, PointInTimeType.CURRENT_POINT_IN_TIME);
087            add(currentInfoPanel,gc);
088    
089            adjustmentSynchronizer = new AdjustmentSynchronizer();
090            selectionSynchronizer = new SelectionSynchronizer();
091    
092            // ---------------------------
093            gc.gridx = 0;
094            gc.gridy = 1;
095            gc.gridwidth = 1;
096            gc.gridheight = 1;
097            gc.weightx = 0.5;
098            gc.weighty = 1.0;
099            gc.fill = GridBagConstraints.BOTH;
100            gc.anchor = GridBagConstraints.NORTHWEST;
101            add(embeddInScrollPane(buildReferenceMemberListTable()),gc);
102    
103            gc.gridx = 1;
104            gc.gridy = 1;
105            gc.gridwidth = 1;
106            gc.gridheight = 1;
107            gc.weightx = 0.5;
108            gc.weighty = 1.0;
109            gc.fill = GridBagConstraints.BOTH;
110            gc.anchor = GridBagConstraints.NORTHWEST;
111            add(embeddInScrollPane(buildCurrentMemberListTable()),gc);
112        }
113    
114        public RelationMemberListViewer(HistoryBrowserModel model) {
115            setModel(model);
116            build();
117        }
118    
119        protected void unregisterAsObserver(HistoryBrowserModel model) {
120            if (currentInfoPanel != null) {
121                model.deleteObserver(currentInfoPanel);
122            }
123            if (referenceInfoPanel != null) {
124                model.deleteObserver(referenceInfoPanel);
125            }
126        }
127        protected void registerAsObserver(HistoryBrowserModel model) {
128            if (currentInfoPanel != null) {
129                model.addObserver(currentInfoPanel);
130            }
131            if (referenceInfoPanel != null) {
132                model.addObserver(referenceInfoPanel);
133            }
134        }
135    
136        public void setModel(HistoryBrowserModel model) {
137            if (this.model != null) {
138                unregisterAsObserver(model);
139            }
140            this.model = model;
141            if (this.model != null) {
142                registerAsObserver(model);
143            }
144        }
145    }