diff --git a/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java b/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java index 757d2d07e5b..b6dae5bc959 100644 --- a/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java +++ b/game-app/game-core/src/main/java/games/strategy/engine/data/GameDataEvent.java @@ -1,12 +1,14 @@ package games.strategy.engine.data; import games.strategy.engine.data.changefactory.ObjectPropertyChange; +import games.strategy.triplea.Constants; import java.util.Optional; /** Enum that represents various possible game data change events. */ public enum GameDataEvent { UNIT_MOVED, - GAME_STEP_CHANGED; + GAME_STEP_CHANGED, + TECH_ATTACHMENT_CHANGED; /** * Converts a 'Change' object to a 'GameDataEvent' object, returns empty if the change object does @@ -16,6 +18,12 @@ static Optional lookupEvent(final Change change) { if (hasMoveChange(change)) { return Optional.of(UNIT_MOVED); } + if (change instanceof ChangeAttachmentChange) { + ChangeAttachmentChange attachmentChange = (ChangeAttachmentChange) change; + if (attachmentChange.getAttachmentName().equals(Constants.TECH_ATTACHMENT_NAME)) { + return Optional.of(TECH_ATTACHMENT_CHANGED); + } + } return Optional.empty(); } diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java b/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java index ef606427d4b..3e3920b5fad 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/image/UnitImageFactory.java @@ -25,7 +25,9 @@ import java.io.IOException; import java.net.URL; import java.nio.file.Files; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import javax.imageio.ImageIO; @@ -60,6 +62,7 @@ public class UnitImageFactory { private final Map icons = new HashMap<>(); // Temporary colorized image files used for URLs for html views (e.g. unit stats table). private final Map colorizedTempFiles = new HashMap<>(); + private final List tempFiles = new ArrayList<>(); // Scaling factor for unit images private final double scaleFactor; private final ResourceLoader resourceLoader; @@ -76,6 +79,18 @@ public UnitImageFactory( this.mapData = mapData; } + public void clearCache() { + images.clear(); + icons.clear(); + deleteTempFiles(); + colorizedTempFiles.clear(); + } + + public void deleteTempFiles() { + tempFiles.forEach(File::delete); + tempFiles.clear(); + } + @Value @Builder public static class ImageKey { @@ -283,6 +298,7 @@ public Optional getPossiblyTransformedImageUrl(final ImageKey imageKey) { File file = Files.createTempFile(key.getFullName(), ".png").toFile(); // Delete the file on exit. file.deleteOnExit(); + tempFiles.add(file); ImageIO.write(bufferedImage, "PNG", file); return file.toURI().toURL(); } catch (IOException e) { diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java b/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java index c9058641787..82ccbcf0920 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/ui/TechResultsDisplay.java @@ -69,25 +69,17 @@ class TechResultsDisplay extends JPanel { final JPanel dice = new JPanel(); dice.setLayout(new BoxLayout(dice, BoxLayout.X_AXIS)); final int remainder = msg.getRemainder(); + final var diceFactory = uiContext.getDiceImageFactory(); for (int i = 0; i < msg.getRolls().length; i++) { // add 1 since dice are 0 based final int roll = msg.getRolls()[i] + 1; - final JLabel die; + final Die.DieType dieType; if (remainder > 0) { - die = - new JLabel( - uiContext - .getDiceImageFactory() - .getDieIcon(roll, roll <= remainder ? Die.DieType.HIT : Die.DieType.MISS)); + dieType = (roll <= remainder) ? Die.DieType.HIT : Die.DieType.MISS; } else { - die = - new JLabel( - uiContext - .getDiceImageFactory() - .getDieIcon( - roll, roll == data.getDiceSides() ? Die.DieType.HIT : Die.DieType.MISS)); + dieType = (roll == data.getDiceSides()) ? Die.DieType.HIT : Die.DieType.MISS; } - dice.add(die); + dice.add(new JLabel(diceFactory.getDieIcon(roll, dieType))); dice.add(Box.createHorizontalStrut(2)); dice.setMaximumSize(new Dimension(200, (int) dice.getMaximumSize().getHeight())); } diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java b/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java index ee59cbf0deb..e6804c19691 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/ui/UiContext.java @@ -179,6 +179,7 @@ public void shutDown() { } activeToDeactivate.clear(); windowsToCloseOnShutdown.clear(); + unitImageFactory.deleteTempFiles(); } StackTraceReportModel.setCurrentMapName(null); resourceLoader.close(); diff --git a/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java b/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java index f90935578b4..489ba97369d 100644 --- a/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java +++ b/game-app/game-headed/src/main/java/games/strategy/triplea/ui/TripleAFrame.java @@ -441,10 +441,17 @@ protected void paintComponent(final Graphics g) { // force a data change event to update the UI for edit mode dataChangeListener.gameDataChanged(ChangeFactory.EMPTY_CHANGE); data.addDataChangeListener(dataChangeListener); - game.getData().addGameDataEventListener(GameDataEvent.GAME_STEP_CHANGED, this::updateStep); + data.addGameDataEventListener(GameDataEvent.GAME_STEP_CHANGED, this::updateStep); + // Clear cached unit images when getting standard tech like jet power. + data.addGameDataEventListener( + GameDataEvent.TECH_ATTACHMENT_CHANGED, this::clearCachedUnitImages); uiContext.addShutdownWindow(this); } + private void clearCachedUnitImages() { + uiContext.getUnitImageFactory().clearCache(); + } + /** * Constructs a new instance of a TripleAFrame, but executes required IO-Operations off the EDT. */