diff --git a/src/main/java/se/lantz/db/DbConnector.java b/src/main/java/se/lantz/db/DbConnector.java index 534e30a..d2d6a64 100644 --- a/src/main/java/se/lantz/db/DbConnector.java +++ b/src/main/java/se/lantz/db/DbConnector.java @@ -220,7 +220,7 @@ public class DbConnector //Construct SQL StringBuilder sqlBuilder = new StringBuilder(); - sqlBuilder.append("SELECT title, rowid, favorite FROM gameinfo "); + sqlBuilder.append("SELECT title, gamefile, rowid, favorite FROM gameinfo "); sqlBuilder.append(view.getSqlQuery()); sqlBuilder.append(" ORDER BY title COLLATE NOCASE ASC"); @@ -232,7 +232,7 @@ public class DbConnector while (rs.next()) { GameListData data = - new GameListData(rs.getString("Title"), Integer.toString(rs.getInt("rowid")), rs.getInt("Favorite")); + new GameListData(rs.getString("Title"), rs.getString("GameFile"), Integer.toString(rs.getInt("rowid")), rs.getInt("Favorite")); returnList.add(data); } } diff --git a/src/main/java/se/lantz/gui/GameListDataRenderer.java b/src/main/java/se/lantz/gui/GameListDataRenderer.java index 01b5b78..85978b7 100644 --- a/src/main/java/se/lantz/gui/GameListDataRenderer.java +++ b/src/main/java/se/lantz/gui/GameListDataRenderer.java @@ -11,6 +11,7 @@ import javax.swing.ImageIcon; import javax.swing.JList; import javax.swing.SwingConstants; +import se.lantz.manager.SavedStatesManager; import se.lantz.model.data.GameListData; import se.lantz.model.data.GameView; @@ -33,9 +34,11 @@ public class GameListDataRenderer extends DefaultListCellRenderer private final Font bold; private final Font boldItalic; + private SavedStatesManager savedStatesManager; - public GameListDataRenderer() + public GameListDataRenderer(SavedStatesManager savedStatesManager) { + this.savedStatesManager = savedStatesManager; this.boldItalic = getFont().deriveFont(Font.BOLD + Font.ITALIC); this.bold = getFont().deriveFont(Font.BOLD); this.setHorizontalTextPosition(SwingConstants.LEADING); @@ -64,7 +67,6 @@ public class GameListDataRenderer extends DefaultListCellRenderer private void handleGameListData(Object value, boolean isSelected) { - this.setIcon(null); GameListData listData = (GameListData) value; if (listData.isFavorite()) { @@ -74,7 +76,6 @@ public class GameListDataRenderer extends DefaultListCellRenderer { case 1: this.setForeground(isSelected ? fav1ColorSelected : fav1Color); - this.setIcon(new ImageIcon(this.getClass().getResource("/se/lantz/16x16SaveIcon-1.png"))); break; case 2: this.setForeground(isSelected ? fav2ColorSelected : fav2Color); @@ -112,18 +113,40 @@ public class GameListDataRenderer extends DefaultListCellRenderer break; } } - + //Decide which icon to use + int numberOfSavedStates = savedStatesManager.getNumberOfSavedStatesForGame(listData.getGameFileName()); + if (numberOfSavedStates == 1) + { + this.setIcon(new ImageIcon(this.getClass().getResource("/se/lantz/16x16SaveIcon-1.png"))); + } + else if (numberOfSavedStates == 2) + { + this.setIcon(new ImageIcon(this.getClass().getResource("/se/lantz/16x16SaveIcon-2.png"))); + } + else if (numberOfSavedStates == 3) + { + this.setIcon(new ImageIcon(this.getClass().getResource("/se/lantz/16x16SaveIcon-3.png"))); + } + else if (numberOfSavedStates == 4) + { + this.setIcon(new ImageIcon(this.getClass().getResource("/se/lantz/16x16SaveIcon-4.png"))); + } + else + { + this.setIcon(null); + } } - + private void handleGameListView(Object value, boolean isSelected, int index) { + this.setIcon(null); this.setBorder(null); GameView view = (GameView) value; if (view.getGameViewId() == GameView.FAVORITES_ID) { this.setFont(bold); this.setForeground(isSelected ? fav1ColorSelected : fav1Color); - if(index > -1) + if (index > -1) { this.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.LIGHT_GRAY)); } @@ -172,24 +195,28 @@ public class GameListDataRenderer extends DefaultListCellRenderer { this.setFont(boldItalic); this.setForeground(isSelected ? fav5ColorSelected : fav5Color); - if(index > -1) + if (index > -1) { this.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.LIGHT_GRAY)); - } + } } } - + @Override - public void setBounds(int x, int y, int width, int height) { - super.setBounds(x, y, width, height); - if (getIcon() != null) { - int padding = 1; - int textWidth = getFontMetrics(getFont()).stringWidth(getText()); - Insets insets = getInsets(); - int iconTextGap = width - textWidth - getIcon().getIconWidth() - insets.left - insets.right - padding; - setIconTextGap(iconTextGap); - } else { - setIconTextGap(0); - } + public void setBounds(int x, int y, int width, int height) + { + super.setBounds(x, y, width, height); + if (getIcon() != null) + { + int padding = 1; + int textWidth = getFontMetrics(getFont()).stringWidth(getText()); + Insets insets = getInsets(); + int iconTextGap = width - textWidth - getIcon().getIconWidth() - insets.left - insets.right - padding; + setIconTextGap(iconTextGap); + } + else + { + setIconTextGap(0); + } } } diff --git a/src/main/java/se/lantz/gui/ListPanel.java b/src/main/java/se/lantz/gui/ListPanel.java index 82a81c5..a76dbb7 100644 --- a/src/main/java/se/lantz/gui/ListPanel.java +++ b/src/main/java/se/lantz/gui/ListPanel.java @@ -172,7 +172,7 @@ public class ListPanel extends JPanel } }); listViewComboBox.setModel(uiModel.getGameViewModel()); - listViewComboBox.setRenderer(new GameListDataRenderer()); + listViewComboBox.setRenderer(new GameListDataRenderer(uiModel.getSavedStatesManager())); listViewComboBox.addPopupMenuListener(new PopupMenuListener() { @Override @@ -434,7 +434,7 @@ public class ListPanel extends JPanel } }); list.setModel(uiModel.getGameListModel()); - list.setCellRenderer(new GameListDataRenderer()); + list.setCellRenderer(new GameListDataRenderer(uiModel.getSavedStatesManager())); //Remove from tootlipManager to avoid throwing a nullpointer for CTRL+F1 ToolTipManager.sharedInstance().unregisterComponent(list); } diff --git a/src/main/java/se/lantz/manager/SavedStatesManager.java b/src/main/java/se/lantz/manager/SavedStatesManager.java index f829eed..b781289 100644 --- a/src/main/java/se/lantz/manager/SavedStatesManager.java +++ b/src/main/java/se/lantz/manager/SavedStatesManager.java @@ -12,6 +12,8 @@ import java.nio.file.PathMatcher; import java.nio.file.StandardCopyOption; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.TimeZone; import java.util.stream.Stream; @@ -54,10 +56,17 @@ public class SavedStatesManager private int noFilesCopied = 0; + /** + * Map holding available saved states with fileName (subfolder) as key and number of saved states available as value + * (1-4). + */ + private Map savedStatesMap = new HashMap<>(); + public SavedStatesManager(MainViewModel model) { this.model = model; this.savedStatesModel = model.getSavedStatesModel(); + readSavedStatesAndUpdateMap(); } public void saveSavedStates() @@ -76,6 +85,7 @@ public class SavedStatesManager String fileName = model.getInfoModel().getGamesFile(); Path saveFolder = new File(SAVES + fileName).toPath(); + int numberofSaves = 0; //Check which ones are available Path mta0Path = saveFolder.resolve(MTA0); Path vsz0Path = saveFolder.resolve(VSZ0); @@ -85,6 +95,7 @@ public class SavedStatesManager storePlayTime(mta0Path, savedStatesModel.getState1time()); copyVsfFile(vsz0Path, savedStatesModel.getState1Path()); copyPngFile(png0Path, savedStatesModel.getState1PngImage()); + numberofSaves++; } Path mta1Path = saveFolder.resolve(MTA1); Path vsz1Path = saveFolder.resolve(VSZ1); @@ -94,6 +105,7 @@ public class SavedStatesManager storePlayTime(mta1Path, savedStatesModel.getState2time()); copyVsfFile(vsz1Path, savedStatesModel.getState2Path()); copyPngFile(png1Path, savedStatesModel.getState2PngImage()); + numberofSaves++; } Path mta2Path = saveFolder.resolve(MTA2); Path vsz2Path = saveFolder.resolve(VSZ2); @@ -103,6 +115,7 @@ public class SavedStatesManager storePlayTime(mta2Path, savedStatesModel.getState3time()); copyVsfFile(vsz2Path, savedStatesModel.getState3Path()); copyPngFile(png2Path, savedStatesModel.getState3PngImage()); + numberofSaves++; } Path mta3Path = saveFolder.resolve(MTA3); Path vsz3Path = saveFolder.resolve(VSZ3); @@ -112,7 +125,10 @@ public class SavedStatesManager storePlayTime(mta3Path, savedStatesModel.getState4time()); copyVsfFile(vsz3Path, savedStatesModel.getState4Path()); copyPngFile(png3Path, savedStatesModel.getState4PngImage()); + numberofSaves++; } + //Update current map also + savedStatesMap.put(fileName, numberofSaves); } public void readSavedStates() @@ -403,4 +419,61 @@ public class SavedStatesManager { return noFilesCopied; } + + private void readSavedStatesAndUpdateMap() + { + //Read all files in the saves folder + File saveFolder = new File(SAVES); + try (Stream stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1)) + { + stream.forEachOrdered(sourcePath -> { + try + { + //Ignore first folder + if (sourcePath.equals(saveFolder.toPath().toAbsolutePath())) + { + return; + } + + //Check which files are available + Path save1 = sourcePath.resolve(MTA0); + Path save2 = sourcePath.resolve(MTA1); + Path save3 = sourcePath.resolve(MTA2); + Path save4 = sourcePath.resolve(MTA3); + int noSavesAvailable = 0; + if (save1.toFile().exists()) + { + noSavesAvailable++; + } + if (save2.toFile().exists()) + { + noSavesAvailable++; + } + if (save3.toFile().exists()) + { + noSavesAvailable++; + } + if (save4.toFile().exists()) + { + noSavesAvailable++; + } + //Add to map + savedStatesMap.put(sourcePath.toFile().getName(), noSavesAvailable); + } + catch (Exception e) + { + ExceptionHandler.logException(e, "Could not check available saved states for " + sourcePath.toString()); + } + }); + } + catch (IOException e1) + { + ExceptionHandler.handleException(e1, "Could not construct savedStates Map"); + } + } + + public int getNumberOfSavedStatesForGame(String gameFileName) + { + return savedStatesMap.get(gameFileName) != null ? savedStatesMap.get(gameFileName) : 0; + } } diff --git a/src/main/java/se/lantz/model/MainViewModel.java b/src/main/java/se/lantz/model/MainViewModel.java index 454f38c..421d9ca 100644 --- a/src/main/java/se/lantz/model/MainViewModel.java +++ b/src/main/java/se/lantz/model/MainViewModel.java @@ -77,6 +77,11 @@ public class MainViewModel extends AbstractModel { this.stateManager = savedStatesManager; } + + public SavedStatesManager getSavedStatesManager() + { + return this.stateManager; + } public void initialize() { @@ -688,7 +693,7 @@ public class MainViewModel extends AbstractModel public void addNewGameListData() { - gameListModel.addElement(new GameListData("New Game", "", 0)); + gameListModel.addElement(new GameListData("New Game", "", "", 0)); selectedGameView.setGameCount(gameListModel.getSize()); //Update all games count allGamesCount++; diff --git a/src/main/java/se/lantz/model/data/GameListData.java b/src/main/java/se/lantz/model/data/GameListData.java index 392eb3f..cfd7baf 100644 --- a/src/main/java/se/lantz/model/data/GameListData.java +++ b/src/main/java/se/lantz/model/data/GameListData.java @@ -3,13 +3,15 @@ package se.lantz.model.data; public class GameListData implements Comparable { private String title; + private String gameFileName; private String gameId; private int favorite; - public GameListData(String title, String gameId, int favorite) + public GameListData(String title, String gameFileName, String gameId, int favorite) { super(); this.title = title; + this.gameFileName = gameFileName; this.gameId = gameId; this.favorite = favorite; } @@ -59,6 +61,16 @@ public class GameListData implements Comparable this.favorite = favorite; } + public String getGameFileName() + { + return gameFileName; + } + + public void setGameFileName(String gameFileName) + { + this.gameFileName = gameFileName; + } + @Override public String toString() {