source: josm/trunk/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java@ 16609

Last change on this file since 16609 was 16609, checked in by simon04, 4 years ago

fix #19330 - History browser: Add semantic check to select equivalent nodes/members on opposite sides

  • Property svn:eol-style set to native
File size: 2.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3
4import java.util.Arrays;
5import java.util.HashSet;
6import java.util.Objects;
7import java.util.Set;
8import java.util.function.BiFunction;
9import java.util.stream.IntStream;
10
11import javax.swing.ListSelectionModel;
12import javax.swing.event.ListSelectionEvent;
13import javax.swing.event.ListSelectionListener;
14
15import org.openstreetmap.josm.gui.util.TableHelper;
16
17/**
18 * Helper class to ensure that two (or more) {@link javax.swing.JTable}s always
19 * have the same entries selected.
20 *
21 * The tables are usually displayed side-by-side.
22 */
23public class SelectionSynchronizer implements ListSelectionListener {
24
25 private final Set<ListSelectionModel> participants;
26 private boolean preventRecursion;
27 private BiFunction<Integer, ListSelectionModel, IntStream> selectionIndexMapper = (i, model) -> IntStream.of(i);
28
29 /**
30 * Constructs a new {@code SelectionSynchronizer}.
31 */
32 public SelectionSynchronizer() {
33 participants = new HashSet<>();
34 }
35
36 /**
37 * Add {@link ListSelectionModel} of the table to participate in selection
38 * synchronization.
39 *
40 * Call this method for all tables that should have their selection synchronized.
41 * @param model the selection model of the table
42 */
43 public void participateInSynchronizedSelection(ListSelectionModel model) {
44 if (model == null)
45 return;
46 if (participants.contains(model))
47 return;
48 participants.add(model);
49 model.addListSelectionListener(this);
50 }
51
52 void setSelectionIndexMapper(BiFunction<Integer, ListSelectionModel, IntStream> selectionIndexMapper) {
53 this.selectionIndexMapper = Objects.requireNonNull(selectionIndexMapper);
54 }
55
56 @Override
57 public void valueChanged(ListSelectionEvent e) {
58 if (preventRecursion) {
59 return;
60 }
61 preventRecursion = true;
62 ListSelectionModel referenceModel = (ListSelectionModel) e.getSource();
63 int[] selectedIndices = TableHelper.getSelectedIndices(referenceModel);
64 for (ListSelectionModel model : participants) {
65 if (model == referenceModel) {
66 continue;
67 }
68 TableHelper.setSelectedIndices(model,
69 Arrays.stream(selectedIndices).flatMap(i -> selectionIndexMapper.apply(i, referenceModel)));
70 }
71 preventRecursion = false;
72 }
73}
Note: See TracBrowser for help on using the repository browser.