Subject: [PATCH] Fix #22727: Use a lock instead of a boolean to avoid infinite recursions
---
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
diff --git a/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java b/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java
a
|
b
|
|
29 | 29 | import java.util.Objects; |
30 | 30 | import java.util.Optional; |
31 | 31 | import java.util.concurrent.Future; |
| 32 | import java.util.concurrent.locks.ReentrantLock; |
32 | 33 | import java.util.function.UnaryOperator; |
33 | 34 | import java.util.stream.Collectors; |
34 | 35 | import java.util.stream.IntStream; |
… |
… |
|
298 | 299 | private void addButtonsForImageLayers() { |
299 | 300 | List<MoveImgDisplayPanel<?>> alreadyAdded = this.getImageTabs().collect(Collectors.toList()); |
300 | 301 | // Avoid the setVisible call recursively calling this method and adding duplicates |
301 | | alreadyAdded.forEach(m -> m.finishedAddingButtons = false); |
| 302 | alreadyAdded.forEach(m -> m.finishedAddingButtons.lock()); |
302 | 303 | List<Layer> availableLayers = MainApplication.getLayerManager().getLayers(); |
303 | 304 | List<IGeoImageLayer> geoImageLayers = availableLayers.stream() |
304 | 305 | .sorted(Comparator.comparingInt(entry -> /*reverse*/-availableLayers.indexOf(entry))) |
… |
… |
|
322 | 323 | do { |
323 | 324 | int index = layers.indexOfTabComponent(source); |
324 | 325 | if (index >= 0) { |
325 | | getImageTabs().forEach(m -> m.finishedAddingButtons = false); |
| 326 | getImageTabs().forEach(m -> m.finishedAddingButtons.lock()); |
326 | 327 | removeImageTab(((MoveImgDisplayPanel<?>) layers.getComponentAt(index)).layer); |
327 | | getImageTabs().forEach(m -> m.finishedAddingButtons = true); |
| 328 | getImageTabs().forEach(m -> m.finishedAddingButtons.unlock()); |
328 | 329 | getImageTabs().forEach(m -> m.setVisible(m.isVisible())); |
329 | 330 | return; |
330 | 331 | } |
… |
… |
|
343 | 344 | .collect(Collectors.toList()).forEach(this::removeImageTab); |
344 | 345 | |
345 | 346 | // This is need to avoid the first button becoming visible, and then recalling this method. |
346 | | this.getImageTabs().forEach(m -> m.finishedAddingButtons = true); |
| 347 | alreadyAdded.forEach(m -> m.finishedAddingButtons.unlock()); |
347 | 348 | // After that, trigger the visibility set code |
348 | 349 | this.getImageTabs().forEach(m -> m.setVisible(m.isVisible())); |
349 | 350 | } |
… |
… |
|
768 | 769 | * The purpose of this field is to avoid having the same tab added to the dialog multiple times. This is only a problem when the dialog |
769 | 770 | * has multiple tabs on initialization (like from a session). |
770 | 771 | */ |
771 | | boolean finishedAddingButtons; |
| 772 | private final ReentrantLock finishedAddingButtons = new ReentrantLock(); |
772 | 773 | MoveImgDisplayPanel(ImageDisplay imgDisplay, T layer) { |
773 | 774 | super(new BorderLayout()); |
774 | 775 | this.layer = layer; |
… |
… |
|
780 | 781 | super.setVisible(visible); |
781 | 782 | JTabbedPane layers = ImageViewerDialog.getInstance().layers; |
782 | 783 | int index = layers.indexOfComponent(this); |
783 | | if (visible && this.finishedAddingButtons) { |
784 | | if (!this.layer.getSelection().isEmpty() && !this.layer.getSelection().contains(ImageViewerDialog.getCurrentImage())) { |
785 | | ImageViewerDialog.getInstance().displayImages(this.layer.getSelection()); |
786 | | this.layer.invalidate(); // This will force the geoimage layers to update properly. |
787 | | } |
788 | | if (this.imgDisplay.getParent() != this) { |
789 | | this.add(this.imgDisplay, BorderLayout.CENTER); |
790 | | this.imgDisplay.invalidate(); |
791 | | this.revalidate(); |
792 | | } |
793 | | if (index >= 0) { |
794 | | layers.setTitleAt(index, "* " + getLabel(MainApplication.getLayerManager().getLayers())); |
| 784 | if (visible && !this.finishedAddingButtons.isLocked()) { |
| 785 | this.finishedAddingButtons.lock(); |
| 786 | try { |
| 787 | if (!this.layer.getSelection().isEmpty() && !this.layer.getSelection().contains(ImageViewerDialog.getCurrentImage())) { |
| 788 | ImageViewerDialog.getInstance().displayImages(this.layer.getSelection()); |
| 789 | this.layer.invalidate(); // This will force the geoimage layers to update properly. |
| 790 | } |
| 791 | if (this.imgDisplay.getParent() != this) { |
| 792 | this.add(this.imgDisplay, BorderLayout.CENTER); |
| 793 | this.imgDisplay.invalidate(); |
| 794 | this.revalidate(); |
| 795 | } |
| 796 | if (index >= 0) { |
| 797 | layers.setTitleAt(index, "* " + getLabel(MainApplication.getLayerManager().getLayers())); |
| 798 | } |
| 799 | } finally { |
| 800 | this.finishedAddingButtons.unlock(); |
795 | 801 | } |
796 | 802 | } else if (index >= 0) { |
797 | 803 | layers.setTitleAt(index, getLabel(MainApplication.getLayerManager().getLayers())); |