From 4495d75d8abc00af9a4c77fb746200db0d44f757 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 18 Dec 2018 17:17:10 +0400 Subject: [PATCH 01/11] Fixed NPE error on AI calcs --- .../card/dl/sources/ScryfallImageSource.java | 45 +++++--- .../card/dl/sources/TokensMtgImageSource.java | 8 +- .../dl/sources/WizardCardsImageSource.java | 105 +++++++----------- .../src/mage/player/ai/ComputerPlayer7.java | 5 +- .../java/mage/verify/VerifyCardDataTest.java | 4 +- 5 files changed, 79 insertions(+), 88 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index fa6dc551c3..6554780bfb 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -1,6 +1,6 @@ package org.mage.plugins.card.dl.sources; -import mage.client.dialog.PreferencesDialog; +import mage.client.util.CardLanguage; import org.mage.plugins.card.images.CardDownloadData; import java.util.*; @@ -14,20 +14,22 @@ public enum ScryfallImageSource implements CardImageSource { private final Set supportedSets; private final Map languageAliases; + private CardLanguage currentLanguage = CardLanguage.ENGLISH; // working language ScryfallImageSource() { // https://scryfall.com/docs/api/languages languageAliases = new HashMap<>(); - languageAliases.put("en", "en"); - languageAliases.put("es", "es"); - languageAliases.put("jp", "ja"); - languageAliases.put("it", "it"); - languageAliases.put("fr", "fr"); - languageAliases.put("cn", "zhs"); // Simplified Chinese - languageAliases.put("de", "de"); - languageAliases.put("ko", "ko"); - languageAliases.put("pt", "pt"); - languageAliases.put("ru", "ru"); + languageAliases.put(CardLanguage.ENGLISH.getCode(), "en"); + languageAliases.put(CardLanguage.SPANISH.getCode(), "es"); + languageAliases.put(CardLanguage.FRENCH.getCode(), "fr"); + languageAliases.put(CardLanguage.GERMAN.getCode(), "de"); + languageAliases.put(CardLanguage.ITALIAN.getCode(), "it"); + languageAliases.put(CardLanguage.PORTUGUESE.getCode(), "pt"); + languageAliases.put(CardLanguage.JAPANESE.getCode(), "ja"); + languageAliases.put(CardLanguage.KOREAN.getCode(), "ko"); + languageAliases.put(CardLanguage.RUSSIAN.getCode(), "ru"); + languageAliases.put(CardLanguage.CHINES_SIMPLE.getCode(), "zhs"); + languageAliases.put(CardLanguage.CHINES_TRADITION.getCode(), "zht"); supportedSets = new LinkedHashSet<>(); // supportedSets.add("PTC"); // @@ -245,9 +247,9 @@ public enum ScryfallImageSource implements CardImageSource { @Override public CardImageUrls generateURL(CardDownloadData card) throws Exception { - String preferredLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en"); - String defaultCode = "en"; - String localizedCode = languageAliases.getOrDefault(preferredLanguage, defaultCode); + String preferredCode = this.getCurrentLanguage().getCode(); + String defaultCode = CardLanguage.ENGLISH.getCode(); + String localizedCode = languageAliases.getOrDefault(preferredCode, defaultCode); // loc example: https://api.scryfall.com/cards/xln/121/ru?format=image // WARNING, some cards haven't direct images and uses random GUID: @@ -345,6 +347,21 @@ public enum ScryfallImageSource implements CardImageSource { return false; } + @Override + public boolean isLanguagesSupport() { + return true; + } + + @Override + public void setCurrentLanguage(CardLanguage cardLanguage) { + this.currentLanguage = cardLanguage; + } + + @Override + public CardLanguage getCurrentLanguage() { + return currentLanguage; + } + @Override public void doPause(String httpImageUrl) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java index da76bfc8b6..ae000f70da 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java @@ -20,7 +20,7 @@ import java.util.logging.Level; import mage.constants.SubType; import org.apache.log4j.Logger; import org.mage.plugins.card.images.CardDownloadData; -import org.mage.plugins.card.images.DownloadPictures; +import org.mage.plugins.card.images.DownloadPicturesService; import org.mage.plugins.card.utils.CardImageUtils; /** @@ -182,7 +182,7 @@ public enum TokensMtgImageSource implements CardImageSource { private HashMap> getTokensData() throws IOException { synchronized (tokensDataSync) { if (tokensData == null) { - DownloadPictures.getInstance().updateAndViewMessage("Creating token data..."); + DownloadPicturesService.getInstance().updateAndViewMessage("Find tokens data..."); tokensData = new HashMap<>(); // get tokens data from resource file @@ -233,10 +233,10 @@ public enum TokensMtgImageSource implements CardImageSource { } } } - DownloadPictures.getInstance().updateAndViewMessage(""); + DownloadPicturesService.getInstance().updateAndViewMessage(""); } catch (Exception ex) { logger.warn("Failed to get tokens description from tokens.mtg.onl", ex); - DownloadPictures.getInstance().updateAndViewMessage(ex.getMessage()); + DownloadPicturesService.getInstance().updateAndViewMessage(ex.getMessage()); } } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java index 5d39a943f6..7580c000f2 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java @@ -1,22 +1,10 @@ package org.mage.plugins.card.dl.sources; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; import mage.cards.Sets; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; -import mage.client.dialog.PreferencesDialog; +import mage.client.util.CardLanguage; import org.apache.log4j.Logger; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -24,6 +12,12 @@ import org.jsoup.select.Elements; import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.utils.CardImageUtils; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + /** * @author North */ @@ -37,6 +31,7 @@ public enum WizardCardsImageSource implements CardImageSource { private final Map languageAliases; private final Map> sets; private final Set supportedSets; + private CardLanguage currentLanguage = CardLanguage.ENGLISH; // working language @Override public String getSourceName() { @@ -44,6 +39,20 @@ public enum WizardCardsImageSource implements CardImageSource { } WizardCardsImageSource() { + + languageAliases = new HashMap<>(); + languageAliases.put(CardLanguage.ENGLISH.getCode(), "English"); + languageAliases.put(CardLanguage.SPANISH.getCode(), "Spanish"); + languageAliases.put(CardLanguage.FRENCH.getCode(), "French"); + languageAliases.put(CardLanguage.GERMAN.getCode(), "German"); + languageAliases.put(CardLanguage.ITALIAN.getCode(), "Italian"); + languageAliases.put(CardLanguage.PORTUGUESE.getCode(), "Portuguese (Brazil)"); + languageAliases.put(CardLanguage.JAPANESE.getCode(), "Japanese"); + languageAliases.put(CardLanguage.KOREAN.getCode(), "Korean"); + languageAliases.put(CardLanguage.RUSSIAN.getCode(), "Russian"); + languageAliases.put(CardLanguage.CHINES_SIMPLE.getCode(), "Chinese Simplified"); + languageAliases.put(CardLanguage.CHINES_TRADITION.getCode(), "Chinese Traditional "); + supportedSets = new LinkedHashSet<>(); // supportedSets.add("PTC"); // Prerelease Events supportedSets.add("LEA"); @@ -430,18 +439,6 @@ public enum WizardCardsImageSource implements CardImageSource { setsAliases.put("WTH", "Weatherlight"); setsAliases.put("WWK", "Worldwake"); setsAliases.put("ZEN", "Zendikar"); - - languageAliases = new HashMap<>(); - languageAliases.put("en", "English"); - languageAliases.put("es", "Spanish"); - languageAliases.put("jp", "Japanese"); - languageAliases.put("it", "Italian"); - languageAliases.put("fr", "French"); - languageAliases.put("cn", "Chinese Simplified"); - languageAliases.put("de", "German"); - languageAliases.put("ko", "Korean"); - languageAliases.put("pt", "Portuguese (Brazil)"); - languageAliases.put("ru", "Russian"); } @Override @@ -517,7 +514,7 @@ public enum WizardCardsImageSource implements CardImageSource { if (setNames == null) { setNames = Sets.getInstance().get(cardSet).getName(); } - String preferredLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en"); + for (String setName : setNames.split("\\^")) { // String URLSetName = URLEncoder.encode(setName, "UTF-8"); String URLSetName = setName.replaceAll(" ", "%20"); @@ -555,7 +552,7 @@ public enum WizardCardsImageSource implements CardImageSource { cardName = cardName.substring(0, pos1); } } - Integer preferredMultiverseId = getLocalizedMultiverseId(preferredLanguage, multiverseId); + Integer preferredMultiverseId = getLocalizedMultiverseId(getCurrentLanguage().getCode(), multiverseId); setLinks.put(cardName.toLowerCase(Locale.ENGLISH) + numberChar, generateLink(preferredMultiverseId)); } } @@ -618,7 +615,7 @@ public enum WizardCardsImageSource implements CardImageSource { } private int getLocalizedMultiverseId(String preferredLanguage, Integer multiverseId) throws IOException { - if (preferredLanguage.equals("en")) { + if (preferredLanguage.equals(CardLanguage.ENGLISH.getCode())) { return multiverseId; } @@ -682,43 +679,6 @@ public enum WizardCardsImageSource implements CardImageSource { return 60.0f; } - // private final class GetImageLinkTask implements Runnable { -// -// private int multiverseId; -// private String cardName; -// private String preferredLanguage; -// private LinkedHashMap setLinks; -// -// public GetImageLinkTask(int multiverseId, String cardName, String preferredLanguage, LinkedHashMap setLinks) { -// try { -// this.multiverseId = multiverseId; -// this.cardName = cardName; -// this.preferredLanguage = preferredLanguage; -// this.setLinks = setLinks; -// } catch (Exception ex) { -// logger.error(ex.getMessage()); -// logger.error("multiverseId: " + multiverseId); -// logger.error("cardName: " + cardName); -// logger.error("preferredLanguage: " + preferredLanguage); -// logger.error("setLinks: " + setLinks.toString()); -// } -// } -// -// @Override -// public void run() { -// try { -// if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) { -// setLinks.putAll(getLandVariations(multiverseId, cardName)); -// } else { -// Integer preferredMultiverseId = getLocalizedMultiverseId(preferredLanguage, multiverseId); -// setLinks.put(cardName.toLowerCase(Locale.ENGLISH), generateLink(preferredMultiverseId)); -// } -// } catch (IOException | NumberFormatException ex) { -// logger.error("Exception when parsing the wizards page: " + ex.getMessage()); -// } -// } -// -// } @Override public int getTotalImages() { return -1; @@ -729,6 +689,21 @@ public enum WizardCardsImageSource implements CardImageSource { return false; } + @Override + public boolean isLanguagesSupport() { + return true; + } + + @Override + public void setCurrentLanguage(CardLanguage cardLanguage) { + this.currentLanguage = cardLanguage; + } + + @Override + public CardLanguage getCurrentLanguage() { + return currentLanguage; + } + @Override public void doPause(String httpImageUrl) { } diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java index 628472299c..448105209f 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java @@ -111,9 +111,8 @@ public class ComputerPlayer7 extends ComputerPlayer6 { Game sim = createSimulation(game); SimulationNode2.resetCount(); root = new SimulationNode2(null, sim, maxDepth, playerId); - addActionsTimed(); - if (root.children != null - && !root.children.isEmpty()) { + addActionsTimed(); // TODO: root can be null again after addActionsTimed O_o need to research (it's a CPU AI problem?) + if (root != null && root.children != null && !root.children.isEmpty()) { logger.trace("After add actions timed: root.children.size = " + root.children.size()); root = root.children.get(0); // prevent repeating always the same action with no cost diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 0d11f3230a..6dc4d00213 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -14,7 +14,7 @@ import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import org.mage.plugins.card.images.CardDownloadData; -import org.mage.plugins.card.images.DownloadPictures; +import org.mage.plugins.card.images.DownloadPicturesService; import org.reflections.Reflections; import java.io.IOException; @@ -425,7 +425,7 @@ public class VerifyCardDataTest { } // tok file's data - ArrayList tokFileTokens = DownloadPictures.getTokenCardUrls(); + ArrayList tokFileTokens = DownloadPicturesService.getTokenCardUrls(); LinkedHashMap tokDataClassesIndex = new LinkedHashMap<>(); LinkedHashMap tokDataNamesIndex = new LinkedHashMap<>(); for (CardDownloadData tokData : tokFileTokens) { From bd644c273f0d6e4e7591198f4342a458167b396f Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 18 Dec 2018 17:31:13 +0400 Subject: [PATCH 02/11] Fixed card numbers in PUMA set; --- Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java b/Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java index 26eb20d571..545985a829 100644 --- a/Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java +++ b/Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java @@ -36,9 +36,9 @@ public final class UltimateBoxTopperPromos extends ExpansionSet { cards.add(new SetCardInfo("Gaddock Teeg", "U21", Rarity.MYTHIC, mage.cards.g.GaddockTeeg.class)); cards.add(new SetCardInfo("Goryo's Vengeance", "U9", Rarity.MYTHIC, mage.cards.g.GoryosVengeance.class)); cards.add(new SetCardInfo("Karakas", "U36", Rarity.MYTHIC, mage.cards.k.Karakas.class)); - cards.add(new SetCardInfo("Karn Liberated", "U02", Rarity.MYTHIC, mage.cards.k.KarnLiberated.class)); + cards.add(new SetCardInfo("Karn Liberated", "U2", Rarity.MYTHIC, mage.cards.k.KarnLiberated.class)); cards.add(new SetCardInfo("Kitchen Finks", "U27", Rarity.MYTHIC, mage.cards.k.KitchenFinks.class)); - cards.add(new SetCardInfo("Kozilek, Butcher of Truth", "U03", Rarity.MYTHIC, mage.cards.k.KozilekButcherOfTruth.class)); + cards.add(new SetCardInfo("Kozilek, Butcher of Truth", "U3", Rarity.MYTHIC, mage.cards.k.KozilekButcherOfTruth.class)); cards.add(new SetCardInfo("Lavaclaw Reaches", "U37", Rarity.MYTHIC, mage.cards.l.LavaclawReaches.class)); cards.add(new SetCardInfo("Leovold, Emissary of Trest", "U22", Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); cards.add(new SetCardInfo("Life from the Loam", "U17", Rarity.MYTHIC, mage.cards.l.LifeFromTheLoam.class)); From 70012af6dbeec66c6d4562406499487ffc149f06 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 18 Dec 2018 17:50:19 +0400 Subject: [PATCH 03/11] Refactor: improved language support in card images sources; --- .../mage/client/dialog/PreferencesDialog.form | 6 +- .../mage/client/dialog/PreferencesDialog.java | 12 +++- .../java/mage/client/util/CardLanguage.java | 68 +++++++++++++++++++ .../card/dl/sources/CardImageSource.java | 18 ++++- .../card/dl/sources/ScryfallImageSource.java | 26 +++---- .../dl/sources/WizardCardsImageSource.java | 30 ++++---- 6 files changed, 125 insertions(+), 35 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/util/CardLanguage.java diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form index f122cdc1c4..4d8fb9ea08 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form @@ -236,7 +236,7 @@ - + @@ -267,7 +267,7 @@ - + @@ -4425,6 +4425,7 @@ + @@ -4451,6 +4452,7 @@ + diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index 5826d2c85b..ef53c3308e 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -41,6 +41,8 @@ import mage.client.MageFrame; import mage.client.SessionHandler; import mage.client.components.KeyBindButton; import static mage.client.constants.Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR; + +import mage.client.util.CardLanguage; import mage.client.util.Config; import mage.client.util.GUISizeHelper; import mage.client.util.ImageHelper; @@ -338,6 +340,10 @@ public class PreferencesDialog extends javax.swing.JDialog { fc_i.addChoosableFileFilter(new ImageFileFilter()); } + public static CardLanguage getPrefImagesLanguage() { + return CardLanguage.valueByCode(getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, CardLanguage.ENGLISH.getCode())); + } + private static class ImageFileFilter extends FileFilter { @Override @@ -374,7 +380,7 @@ public class PreferencesDialog extends javax.swing.JDialog { cbProxyType.setModel(new DefaultComboBoxModel<>(Connection.ProxyType.values())); addAvatars(); - cbPreferedImageLanguage.setModel(new DefaultComboBoxModel<>(new String[]{"en", "de", "fr", "it", "es", "pt", "jp", "cn", "ru", "tw", "ko"})); + cbPreferedImageLanguage.setModel(new DefaultComboBoxModel<>(CardLanguage.toList())); cbNumberOfDownloadThreads.setModel(new DefaultComboBoxModel<>(new String[]{"10", "9", "8", "7", "6", "5", "4", "3", "2", "1"})); } @@ -1558,6 +1564,7 @@ public class PreferencesDialog extends javax.swing.JDialog { } }); + cbPreferedImageLanguage.setMaximumRowCount(20); cbPreferedImageLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); labelPreferedImageLanguage.setText("Prefered image language:"); @@ -1565,6 +1572,7 @@ public class PreferencesDialog extends javax.swing.JDialog { labelNumberOfDownloadThreads.setText("Number of download threads:"); + cbNumberOfDownloadThreads.setMaximumRowCount(20); cbNumberOfDownloadThreads.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); org.jdesktop.layout.GroupLayout panelCardImagesLayout = new org.jdesktop.layout.GroupLayout(panelCardImages); @@ -3411,7 +3419,7 @@ public class PreferencesDialog extends javax.swing.JDialog { load(prefs, dialog.cbCheckForNewImages, KEY_CARD_IMAGES_CHECK, "true"); load(prefs, dialog.cbSaveToZipFiles, KEY_CARD_IMAGES_SAVE_TO_ZIP, "true"); dialog.cbNumberOfDownloadThreads.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_THREADS, "10")); - dialog.cbPreferedImageLanguage.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_PREF_LANGUAGE, "en")); + dialog.cbPreferedImageLanguage.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_PREF_LANGUAGE, CardLanguage.ENGLISH.getCode())); // rendering settings load(prefs, dialog.cbCardRenderImageFallback, KEY_CARD_RENDERING_FALLBACK, "true"); diff --git a/Mage.Client/src/main/java/mage/client/util/CardLanguage.java b/Mage.Client/src/main/java/mage/client/util/CardLanguage.java new file mode 100644 index 0000000000..2be99682c2 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/util/CardLanguage.java @@ -0,0 +1,68 @@ +package mage.client.util; + +import java.util.ArrayList; + +/** + * @author JayDi85 + */ +public enum CardLanguage { + + ENGLISH("en", "English"), + SPANISH("es", "Spanish"), + FRENCH("fr", "French"), + GERMAN("de", "German"), + ITALIAN("it", "Italian"), + PORTUGUESE("pt", "Portuguese"), + JAPANESE("jp", "Japanese"), + KOREAN("ko", "Korean"), + RUSSIAN("ru", "Russian"), + CHINES_SIMPLE("cns", "Chinese Simplified"), + CHINES_TRADITION("cnt", "Chinese Traditional"); + + private final String code; + private final String text; + + CardLanguage(String code, String text) { + this.code = code; + this.text = text; + } + + @Override + public String toString() { + return code; + } + + public String getCode() { + return code; + } + + public String getText() { + return text; + } + + public static String[] toList() { + ArrayList res = new ArrayList<>(); + for (CardLanguage l : values()) { + res.add(l.toString()); + } + return res.toArray(new String[0]); + } + + public static CardLanguage valueByText(String text) { + for (CardLanguage type : values()) { + if (type.text.equals(text)) { + return type; + } + } + return CardLanguage.ENGLISH; + } + + public static CardLanguage valueByCode(String code) { + for (CardLanguage type : values()) { + if (type.code.equals(code)) { + return type; + } + } + return CardLanguage.ENGLISH; + } +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java index f2d0fabf75..8fb85388bf 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java @@ -1,10 +1,11 @@ package org.mage.plugins.card.dl.sources; -import java.util.ArrayList; +import mage.client.util.CardLanguage; import org.mage.plugins.card.images.CardDownloadData; +import java.util.ArrayList; + /** - * * @author North */ public interface CardImageSource { @@ -31,10 +32,21 @@ public interface CardImageSource { return false; } + default boolean isLanguagesSupport() { + return false; + } + + default void setCurrentLanguage(CardLanguage cardLanguage) { + } + + default CardLanguage getCurrentLanguage() { + return CardLanguage.ENGLISH; + } + void doPause(String httpImageUrl); default ArrayList getSupportedSets() { - return null; + return new ArrayList<>(); } default boolean isSetSupportedComplete(String setCode) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 6554780bfb..b14d4993a9 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -13,23 +13,23 @@ public enum ScryfallImageSource implements CardImageSource { instance; private final Set supportedSets; - private final Map languageAliases; + private final Map languageAliases; private CardLanguage currentLanguage = CardLanguage.ENGLISH; // working language ScryfallImageSource() { // https://scryfall.com/docs/api/languages languageAliases = new HashMap<>(); - languageAliases.put(CardLanguage.ENGLISH.getCode(), "en"); - languageAliases.put(CardLanguage.SPANISH.getCode(), "es"); - languageAliases.put(CardLanguage.FRENCH.getCode(), "fr"); - languageAliases.put(CardLanguage.GERMAN.getCode(), "de"); - languageAliases.put(CardLanguage.ITALIAN.getCode(), "it"); - languageAliases.put(CardLanguage.PORTUGUESE.getCode(), "pt"); - languageAliases.put(CardLanguage.JAPANESE.getCode(), "ja"); - languageAliases.put(CardLanguage.KOREAN.getCode(), "ko"); - languageAliases.put(CardLanguage.RUSSIAN.getCode(), "ru"); - languageAliases.put(CardLanguage.CHINES_SIMPLE.getCode(), "zhs"); - languageAliases.put(CardLanguage.CHINES_TRADITION.getCode(), "zht"); + languageAliases.put(CardLanguage.ENGLISH, "en"); + languageAliases.put(CardLanguage.SPANISH, "es"); + languageAliases.put(CardLanguage.FRENCH, "fr"); + languageAliases.put(CardLanguage.GERMAN, "de"); + languageAliases.put(CardLanguage.ITALIAN, "it"); + languageAliases.put(CardLanguage.PORTUGUESE, "pt"); + languageAliases.put(CardLanguage.JAPANESE, "ja"); + languageAliases.put(CardLanguage.KOREAN, "ko"); + languageAliases.put(CardLanguage.RUSSIAN, "ru"); + languageAliases.put(CardLanguage.CHINES_SIMPLE, "zhs"); + languageAliases.put(CardLanguage.CHINES_TRADITION, "zht"); supportedSets = new LinkedHashSet<>(); // supportedSets.add("PTC"); // @@ -249,7 +249,7 @@ public enum ScryfallImageSource implements CardImageSource { String preferredCode = this.getCurrentLanguage().getCode(); String defaultCode = CardLanguage.ENGLISH.getCode(); - String localizedCode = languageAliases.getOrDefault(preferredCode, defaultCode); + String localizedCode = languageAliases.getOrDefault(this.getCurrentLanguage(), defaultCode); // loc example: https://api.scryfall.com/cards/xln/121/ru?format=image // WARNING, some cards haven't direct images and uses random GUID: diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java index 7580c000f2..d0555b8242 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java @@ -28,7 +28,7 @@ public enum WizardCardsImageSource implements CardImageSource { private static final Logger logger = Logger.getLogger(WizardCardsImageSource.class); private final Map setsAliases; - private final Map languageAliases; + private final Map languageAliases; private final Map> sets; private final Set supportedSets; private CardLanguage currentLanguage = CardLanguage.ENGLISH; // working language @@ -41,17 +41,17 @@ public enum WizardCardsImageSource implements CardImageSource { WizardCardsImageSource() { languageAliases = new HashMap<>(); - languageAliases.put(CardLanguage.ENGLISH.getCode(), "English"); - languageAliases.put(CardLanguage.SPANISH.getCode(), "Spanish"); - languageAliases.put(CardLanguage.FRENCH.getCode(), "French"); - languageAliases.put(CardLanguage.GERMAN.getCode(), "German"); - languageAliases.put(CardLanguage.ITALIAN.getCode(), "Italian"); - languageAliases.put(CardLanguage.PORTUGUESE.getCode(), "Portuguese (Brazil)"); - languageAliases.put(CardLanguage.JAPANESE.getCode(), "Japanese"); - languageAliases.put(CardLanguage.KOREAN.getCode(), "Korean"); - languageAliases.put(CardLanguage.RUSSIAN.getCode(), "Russian"); - languageAliases.put(CardLanguage.CHINES_SIMPLE.getCode(), "Chinese Simplified"); - languageAliases.put(CardLanguage.CHINES_TRADITION.getCode(), "Chinese Traditional "); + languageAliases.put(CardLanguage.ENGLISH, "English"); + languageAliases.put(CardLanguage.SPANISH, "Spanish"); + languageAliases.put(CardLanguage.FRENCH, "French"); + languageAliases.put(CardLanguage.GERMAN, "German"); + languageAliases.put(CardLanguage.ITALIAN, "Italian"); + languageAliases.put(CardLanguage.PORTUGUESE, "Portuguese (Brazil)"); + languageAliases.put(CardLanguage.JAPANESE, "Japanese"); + languageAliases.put(CardLanguage.KOREAN, "Korean"); + languageAliases.put(CardLanguage.RUSSIAN, "Russian"); + languageAliases.put(CardLanguage.CHINES_SIMPLE, "Chinese Simplified"); + languageAliases.put(CardLanguage.CHINES_TRADITION, "Chinese Traditional "); supportedSets = new LinkedHashSet<>(); // supportedSets.add("PTC"); // Prerelease Events @@ -552,7 +552,7 @@ public enum WizardCardsImageSource implements CardImageSource { cardName = cardName.substring(0, pos1); } } - Integer preferredMultiverseId = getLocalizedMultiverseId(getCurrentLanguage().getCode(), multiverseId); + Integer preferredMultiverseId = getLocalizedMultiverseId(getCurrentLanguage(), multiverseId); setLinks.put(cardName.toLowerCase(Locale.ENGLISH) + numberChar, generateLink(preferredMultiverseId)); } } @@ -614,8 +614,8 @@ public enum WizardCardsImageSource implements CardImageSource { return "/Handlers/Image.ashx?multiverseid=" + landMultiverseId + "&type=card"; } - private int getLocalizedMultiverseId(String preferredLanguage, Integer multiverseId) throws IOException { - if (preferredLanguage.equals(CardLanguage.ENGLISH.getCode())) { + private int getLocalizedMultiverseId(CardLanguage preferredLanguage, Integer multiverseId) throws IOException { + if (preferredLanguage.equals(CardLanguage.ENGLISH)) { return multiverseId; } From c799fa94ecc8a48af9ca1539370ca278e00857db Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 18 Dec 2018 17:52:28 +0400 Subject: [PATCH 04/11] Refactor: removed closed images source magiccards.info (it was migrated to scryfall); --- .../dl/sources/MagicCardsImageSource.java | 439 ------------------ 1 file changed, 439 deletions(-) delete mode 100644 Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java deleted file mode 100644 index dfee0c9a46..0000000000 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java +++ /dev/null @@ -1,439 +0,0 @@ -package org.mage.plugins.card.dl.sources; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import mage.client.dialog.PreferencesDialog; -import org.mage.plugins.card.images.CardDownloadData; -import org.mage.plugins.card.utils.CardImageUtils; - -/** - * @author North - */ -public enum MagicCardsImageSource implements CardImageSource { - - instance; - - private static final Set supportedSets = new LinkedHashSet() { - { - // add("PTC"); // Prerelease Events - add("LEA"); - add("LEB"); - add("2ED"); - add("ARN"); - add("ATQ"); - add("3ED"); - add("LEG"); - add("DRK"); - add("FEM"); - add("4ED"); - add("ICE"); - add("CHR"); - add("HML"); - add("ALL"); - add("MIR"); - add("VIS"); - add("5ED"); - add("POR"); - add("WTH"); - add("TMP"); - add("STH"); - add("EXO"); - add("P02"); - add("UGL"); - add("USG"); - add("DD3DVD"); - add("DD3EVG"); - add("DD3GVL"); - add("DD3JVC"); - - add("ULG"); - add("6ED"); - add("UDS"); - add("PTK"); - add("S99"); - add("MMQ"); - // add("BRB");Battle Royale Box Set - add("NEM"); - add("S00"); - add("PCY"); - add("INV"); - // add("BTD"); // Beatdown Boxset - add("PLS"); - add("7ED"); - add("APC"); - add("ODY"); - // add("DKM"); // Deckmasters 2001 - add("TOR"); - add("JUD"); - add("ONS"); - add("LGN"); - add("SCG"); - add("8ED"); - add("MRD"); - add("DST"); - add("5DN"); - add("CHK"); - add("UNH"); - add("BOK"); - add("SOK"); - add("9ED"); - add("RAV"); - add("GPT"); - add("DIS"); - add("CSP"); - add("TSP"); - add("TSB"); - add("PLC"); - add("FUT"); - add("10E"); - add("MED"); - add("LRW"); - add("EVG"); - add("MOR"); - add("SHM"); - add("EVE"); - add("DRB"); - add("ME2"); - add("ALA"); - add("DD2"); - add("CON"); - add("DDC"); - add("ARB"); - add("M10"); - // add("TD0"); // Magic Online Deck Series - add("V09"); - add("HOP"); - add("ME3"); - add("ZEN"); - add("DDD"); - add("H09"); - add("WWK"); - add("DDE"); - add("ROE"); - add("DPA"); - add("ARC"); - add("M11"); - add("V10"); - add("DDF"); - add("SOM"); - // add("TD0"); // Commander Theme Decks - add("PD2"); - add("ME4"); - add("MBS"); - add("DDG"); - add("NPH"); - add("CMD"); - add("M12"); - add("V11"); - add("DDH"); - add("ISD"); - add("PD3"); - add("DKA"); - add("DDI"); - add("AVR"); - add("PC2"); - add("M13"); - add("V12"); - add("DDJ"); - add("RTR"); - add("CM1"); - // add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia - add("GTC"); - add("DDK"); - add("DGM"); - add("MMA"); - add("M14"); - add("V13"); - add("DDL"); - add("THS"); - add("C13"); - add("BNG"); - add("DDM"); - add("JOU"); - // add("MD1"); // Modern Event Deck - add("CNS"); - add("VMA"); - add("M15"); - add("V14"); - add("DDN"); - add("KTK"); - add("C14"); - // add("DD3"); // Duel Decks Anthology - add("FRF"); - add("DDO"); - add("DTK"); - add("TPR"); - add("MM2"); - add("ORI"); - add("V15"); - add("DDP"); - add("BFZ"); - add("EXP"); - add("C15"); - // add("PZ1"); // Legendary Cube - add("OGW"); - add("DDQ"); - add("W16"); - add("SOI"); - add("EMA"); - add("EMN"); - add("V16"); - add("CN2"); - add("DDR"); - add("KLD"); - add("MPS"); - // add("PZ2"); // Treasure Chests - add("C16"); - add("PCA"); - add("AER"); - add("MM3"); - add("DDS"); - add("W17"); - add("AKH"); - add("MPS"); - add("CMA"); - add("E01"); - add("HOU"); - add("C17"); - add("XLN"); - add("DDT"); - add("DDU"); - add("IMA"); - add("E02"); - add("V17"); - add("UST"); - add("RIX"); - add("A25"); - add("DOM"); -// add("CM2"); -// add("M19"); - } - }; - - private static final Map setNameTokenReplacement = new HashMap() { - { - put("10E", "tenth-edition"); - put("AER", "aether-revolt"); - put("AKH", "amonkhet"); - put("ALA", "shards-of-alara"); - put("ANB", "archenemy-nicol-bolas"); - put("APAC", "asia-pacific-land-program"); - put("APC", "player-rewards-2001"); - put("ARB", "alara-reborn"); - put("ARC", "archenemy"); - put("ARENA", "arena-league"); - put("AVR", "avacyn-restored"); - put("BFZ", "battle-for-zendikar"); - put("BNG", "born-of-the-gods"); - put("C13", "commander-2013-edition"); - put("C14", "commander-2014"); - put("C15", "commander-2015"); - put("C16", "commander-2016"); - put("CLASH", "clash-pack"); - put("CMA", "commander-anthology"); - put("CMA", "commanders-arsenal"); - put("CMD", "commander"); - put("CN2", "conspiracy-take-the-crown"); - put("CNS", "conspiracy"); - put("CON", "conflux"); - put("CP", "champs"); - put("CSP", "coldsnap"); - put("DD2", "duel-decks-jace-vs-chandra"); - put("DD3DVD", "duel-decks-anthology-divine-vs-demonic"); - put("DD3EVG", "duel-decks-anthology-elves-vs-goblins"); - put("DD3GVL", "duel-decks-anthology-garruk-vs-liliana"); - put("DD3JVC", "duel-decks-anthology-jace-vs-chandra"); - put("DDC", "duel-decks-divine-vs-demonic"); - put("DDD", "duel-decks-garruk-vs-liliana"); - put("DDE", "duel-decks-phyrexia-vs-the-coalition"); - put("DDF", "duel-decks-elspeth-vs-tezzeret"); - put("DDG", "duel-decks-knights-vs-dragons"); - put("DDH", "duel-decks-ajani-vs-nicol-bolas"); - put("DDI", "duel-decks-venser-vs-koth"); - put("DDJ", "duel-decks-izzet-vs-golgari"); - put("DDK", "duel-decks-sorin-vs-tibalt"); - put("DDL", "duel-decks-heroes-vs-monsters"); - put("DDM", "duel-decks-jace-vs-vraska"); - put("DDN", "duel-decks-speed-vs-cunning"); - put("DDO", "duel-decks-elspeth-vs-kiora"); - put("DDP", "duel-decks-zendikar-vs-eldrazi"); - put("DDQ", "duel-decks-blessed-vs-cursed"); - put("DDR", "duel-decks-nissa-vs-ob-nixilis"); - put("DDS", "duel-decks-mind-vs-might"); - put("DDT", "duel-decks-merfolk-vs-goblin"); - put("DDU", "duel-decks-elves-vs-inventors"); - put("DGM", "dragons-maze"); - put("DKA", "dark-ascension"); - put("DRB", "from-the-vault-dragons"); - put("DTK", "dragons-of-tarkir"); - put("EMA", "eternal-masters"); - put("EMN", "eldritch-moon"); - put("EURO", "european-land-program"); - put("EVE", "eventide"); - put("EVG", "duel-decks-elves-vs-goblins"); - put("EXP", "zendikar-expeditions"); - put("FNMP", "friday-night-magic"); - put("FRF", "fate-reforged"); - put("GPX", "grand-prix"); - put("GRC", "wpngateway"); - put("GTC", "gatecrash"); - put("HOP", "planechase"); - put("HOU", "hour-of-devastation"); - put("INV", "player-rewards-2001"); - put("ISD", "innistrad"); - put("JOU", "journey-into-nyx"); - put("JR", "judge-gift-program"); - put("KLD", "kaladesh"); - put("KTK", "khans-of-tarkir"); - put("LRW", "lorwyn"); - put("M10", "magic-2010"); - put("M11", "magic-2011"); - put("M12", "magic-2012"); - put("M13", "magic-2013"); - put("M14", "magic-2014"); - put("M15", "magic-2015"); - put("MBP", "media-inserts"); - put("MBS", "mirrodin-besieged"); - put("MGDC", "magic-game-day-cards"); - put("MLP", "launch-party"); - put("MM2", "modern-masters-2015"); - put("MM3", "modern-masters-2017"); - put("MMA", "modern-masters"); - put("MOR", "morningtide"); - put("MPRP", "magic-player-rewards"); - put("MPS", "masterpiece-series"); - put("NPH", "new-phyrexia"); - put("ODY", "player-rewards-2002"); - put("OGW", "oath-of-the-gatewatch"); - put("ORG", "oath-of-the-gatewatch"); - put("ORI", "magic-origins"); - put("PC2", "planechase-2012-edition"); - put("PO2", "portal-second-age"); - put("PLS", "player-rewards-2001"); - put("POR", "portal"); - put("PTC", "prerelease-events"); - put("PTK", "portal-three-kingdoms"); - put("ROE", "rise-of-the-eldrazi"); - put("RTR", "return-to-ravnica"); - put("SHM", "shadowmoor"); - put("SOI", "shadows-over-innistrad"); - put("SOM", "scars-of-mirrodin"); - put("SUS", "super-series"); - put("THS", "theros"); - put("TPR", "tempest-remastered"); - put("UGIN", "ugins-fate"); - put("V09", "from-the-vault-exiled"); - put("V10", "from-the-vault-relics"); - put("V11", "from-the-vault-legends"); - put("V12", "from-the-vault-realms"); - put("V13", "from-the-vault-twenty"); - put("V14", "from-the-vault-annihilation"); - put("V15", "from-the-vault-angels"); - put("V16", "from-the-vault-lore"); - put("VMA", "vintage-masters"); - put("W16", "welcome-deck-2016"); - put("W17", "welcome-deck-2017"); - put("WMCQ", "world-magic-cup-qualifier"); - put("WWK", "worldwake"); - put("ZEN", "zendikar"); - } - - private static final long serialVersionUID = 1L; - }; - - @Override - public String getSourceName() { - return "magiccards.info"; - } - - @Override - public String getNextHttpImageUrl() { - return null; - } - - @Override - public String getFileForHttpImage(String httpImageUrl) { - return null; - } - - @Override - public CardImageUrls generateURL(CardDownloadData card) throws Exception { - String collectorId = card.getCollectorId(); - String cardSet = card.getSet(); - if (collectorId == null || cardSet == null) { - throw new Exception("Wrong parameters for image: collector id: " + collectorId + ",card set: " + cardSet); - } - String set = CardImageUtils.updateSet(cardSet, true); - - String preferedLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en"); - - StringBuilder url = new StringBuilder("http://magiccards.info/scans/").append(preferedLanguage).append('/'); - url.append(set.toLowerCase(Locale.ENGLISH)).append('/').append(collectorId); - - if (card.isTwoFacedCard()) { - url.append(card.isSecondSide() ? "b" : "a"); - } - if (card.isSplitCard()) { - url.append('a'); - } - if (card.isFlipCard()) { - if (card.isFlippedSide()) { // download rotated by 180 degree image - url.append('b'); - } else { - url.append('a'); - } - } - url.append(".jpg"); - - return new CardImageUrls(url.toString()); - } - - @Override - public CardImageUrls generateTokenUrl(CardDownloadData card) { - String name = card.getName(); - // add type to name if it's not 0 - if (card.getType() > 0) { - name = name + ' ' + card.getType(); - } - name = name.replaceAll(" ", "-").replace(",", "").toLowerCase(Locale.ENGLISH); - String set = "not-supported-set"; - if (setNameTokenReplacement.containsKey(card.getSet())) { - set = setNameTokenReplacement.get(card.getSet()); - } else { - set += '-' + card.getSet(); - } - return new CardImageUrls("http://magiccards.info/extras/token/" + set + '/' + name + ".jpg"); - } - - @Override - public float getAverageSize() { - return 70.0f; - } - - @Override - public int getTotalImages() { - return -1; - } - - @Override - public boolean isTokenSource() { - return true; - } - - @Override - public ArrayList getSupportedSets() { - ArrayList supportedSetsCopy = new ArrayList<>(); - supportedSetsCopy.addAll(supportedSets); - return supportedSetsCopy; - } - - @Override - public void doPause(String httpImageUrl) { - } - -} From 79370108eb30c863d290688b2b14fefceefbf42a Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 18 Dec 2018 17:57:46 +0400 Subject: [PATCH 05/11] Refactor: extract make window centered code; --- .../components/ability/AbilityPicker.java | 46 +- .../client/dialog/PickCheckBoxDialog.java | 451 +++++++++--------- .../mage/client/dialog/PickChoiceDialog.java | 355 +++++++------- .../mage/client/dialog/PickNumberDialog.java | 105 ++-- .../mage/client/dialog/PickPileDialog.java | 23 +- 5 files changed, 463 insertions(+), 517 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java b/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java index 98881758db..90eff9c8ec 100644 --- a/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java +++ b/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java @@ -1,9 +1,8 @@ package mage.client.components.ability; import mage.client.SessionHandler; +import mage.client.dialog.MageDialog; import mage.client.util.ImageHelper; -import mage.client.util.SettingsManager; -import mage.client.util.gui.GuiDisplayUtil; import mage.remote.Session; import mage.view.AbilityPickerView; import org.apache.log4j.Logger; @@ -17,8 +16,8 @@ import org.mage.card.arcane.UI; import javax.swing.*; import java.awt.*; import java.awt.event.*; -import java.util.*; import java.util.List; +import java.util.*; /** * Dialog for choosing abilities. @@ -112,10 +111,7 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener { this.selected = false; // back to false - waiting for selection setVisible(true); - Point centered = SettingsManager.instance.getComponentPosition(DIALOG_WIDTH, DIALOG_HEIGHT); - this.setLocation(centered.x, centered.y); - GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this); - + MageDialog.makeWindowCentered(this, DIALOG_WIDTH, DIALOG_HEIGHT); //startModal(); } @@ -188,28 +184,28 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener { GroupLayout.TRAILING, layout.createSequentialGroup().addContainerGap().add( layout.createParallelGroup(GroupLayout.TRAILING).add(GroupLayout.LEADING, jScrollPane2, GroupLayout.DEFAULT_SIZE, 422, Short.MAX_VALUE).add(GroupLayout.LEADING, - layout.createSequentialGroup().add(jLabel1).addPreferredGap(LayoutStyle.RELATED, 175, Short.MAX_VALUE).add(1, 1, 1)).add( - GroupLayout.LEADING, - layout.createSequentialGroup().add(layout.createParallelGroup(GroupLayout.LEADING) - ) - .addPreferredGap(LayoutStyle.RELATED) - .add( - layout.createParallelGroup(GroupLayout.TRAILING) - .add( - GroupLayout.LEADING, layout.createParallelGroup(GroupLayout.LEADING))))).add(10, 10, 10))); + layout.createSequentialGroup().add(jLabel1).addPreferredGap(LayoutStyle.RELATED, 175, Short.MAX_VALUE).add(1, 1, 1)).add( + GroupLayout.LEADING, + layout.createSequentialGroup().add(layout.createParallelGroup(GroupLayout.LEADING) + ) + .addPreferredGap(LayoutStyle.RELATED) + .add( + layout.createParallelGroup(GroupLayout.TRAILING) + .add( + GroupLayout.LEADING, layout.createParallelGroup(GroupLayout.LEADING))))).add(10, 10, 10))); layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.LEADING).add( layout.createSequentialGroup().add( layout.createParallelGroup(GroupLayout.LEADING).add( - layout.createSequentialGroup().add(jLabel1, GroupLayout.PREFERRED_SIZE, 36, GroupLayout.PREFERRED_SIZE) - .add(5, 5, 5) - .add( - layout.createParallelGroup(GroupLayout.BASELINE) - ) - ).add(layout.createSequentialGroup().add(8, 8, 8))) - .addPreferredGap(LayoutStyle.RELATED).add(layout.createParallelGroup(GroupLayout.BASELINE)).addPreferredGap(LayoutStyle.RELATED).add( - layout.createParallelGroup(GroupLayout.BASELINE)).addPreferredGap(LayoutStyle.RELATED).add(layout.createParallelGroup(GroupLayout.LEADING)).addPreferredGap( - LayoutStyle.RELATED).add(jScrollPane2, GroupLayout.PREFERRED_SIZE, 180, GroupLayout.PREFERRED_SIZE).addContainerGap(23, Short.MAX_VALUE))); + layout.createSequentialGroup().add(jLabel1, GroupLayout.PREFERRED_SIZE, 36, GroupLayout.PREFERRED_SIZE) + .add(5, 5, 5) + .add( + layout.createParallelGroup(GroupLayout.BASELINE) + ) + ).add(layout.createSequentialGroup().add(8, 8, 8))) + .addPreferredGap(LayoutStyle.RELATED).add(layout.createParallelGroup(GroupLayout.BASELINE)).addPreferredGap(LayoutStyle.RELATED).add( + layout.createParallelGroup(GroupLayout.BASELINE)).addPreferredGap(LayoutStyle.RELATED).add(layout.createParallelGroup(GroupLayout.LEADING)).addPreferredGap( + LayoutStyle.RELATED).add(jScrollPane2, GroupLayout.PREFERRED_SIZE, 180, GroupLayout.PREFERRED_SIZE).addContainerGap(23, Short.MAX_VALUE))); } @Override diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickCheckBoxDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickCheckBoxDialog.java index a9d86c2044..1fccfa7533 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickCheckBoxDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickCheckBoxDialog.java @@ -1,37 +1,17 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package mage.client.dialog; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Point; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.*; -import javax.swing.AbstractAction; -import javax.swing.ActionMap; -import javax.swing.DefaultListModel; -import javax.swing.InputMap; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JLayeredPane; -import javax.swing.KeyStroke; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import mage.choices.Choice; import mage.client.MageFrame; -import mage.client.util.SettingsManager; -import mage.client.util.gui.GuiDisplayUtil; import mage.client.util.gui.MageDialogState; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.*; +import java.util.*; + /** - * * @author JayDi85 * @author Salco */ @@ -42,28 +22,29 @@ public class PickCheckBoxDialog extends MageDialog { ArrayList allItems = new ArrayList<>(); DefaultListModel dataModel = new DefaultListModel(); CheckBoxList.CheckBoxListModel m_dataModel; - + CheckBoxList tList; - + final private static String HTML_TEMPLATE = "
%s
"; - private void setFocus(CheckBoxList obj){ - + private void setFocus(CheckBoxList obj) { + if (!(obj instanceof java.awt.Component)) { throw new IllegalArgumentException("Must be a java.awt.Component!"); } - this.scrollList.setViewportView((java.awt.Component)obj); - } - private javax.swing.JList get_a_Jlist_from_ScrollListView(){ - return ((javax.swing.JList)this.scrollList.getViewport().getView()); + this.scrollList.setViewportView((java.awt.Component) obj); } - private void restoreData(Object dataFrom){ + private javax.swing.JList get_a_Jlist_from_ScrollListView() { + return ((javax.swing.JList) this.scrollList.getViewport().getView()); + } + + private void restoreData(Object dataFrom) { this.allItems.forEach((item) -> { - ((CheckBoxList.CheckBoxListModel)dataFrom).addElement(item.getObjectValue()); + ((CheckBoxList.CheckBoxListModel) dataFrom).addElement(item.getObjectValue()); }); } - + public void showDialog(Choice choice) { showDialog(choice, null, null, null); } @@ -75,47 +56,45 @@ public class PickCheckBoxDialog extends MageDialog { public void showDialog(Choice choice, UUID objectId, MageDialogState mageDialogState) { showDialog(choice, objectId, mageDialogState, null); } - + public void showDialog(Choice choice, UUID objectId, MageDialogState mageDialogState, String startSelectionValue) { this.choice = choice; KeyValueItem tempKeyValue; int indexInTList; - + setLabelText(this.labelMessage, choice.getMessage()); setLabelText(this.labelSubMessage, choice.getSubMessage()); - + btCancel.setEnabled(!choice.isRequired()); - + // 2 modes: string or key-values // sore data in allItems for inremental filtering // http://logicbig.com/tutorials/core-java-tutorial/swing/list-filter/ this.allItems.clear(); - if (choice.isKeyChoice()){ - for (Map.Entry entry: choice.getKeyChoices().entrySet()) { - if(tList != null){ + if (choice.isKeyChoice()) { + for (Map.Entry entry : choice.getKeyChoices().entrySet()) { + if (tList != null) { indexInTList = m_dataModel.indexOf(entry.getKey()); - tempKeyValue=new KeyValueItem(entry.getKey(), entry.getValue(),(CheckBoxList.CheckBoxListItem) this.tList.getModel().getElementAt(indexInTList)); - } - else{ - tempKeyValue=new KeyValueItem(entry.getKey(), entry.getValue()); + tempKeyValue = new KeyValueItem(entry.getKey(), entry.getValue(), (CheckBoxList.CheckBoxListItem) this.tList.getModel().getElementAt(indexInTList)); + } else { + tempKeyValue = new KeyValueItem(entry.getKey(), entry.getValue()); } this.allItems.add(tempKeyValue); } } else { - for (String value: choice.getChoices()){ - if(tList != null){ + for (String value : choice.getChoices()) { + if (tList != null) { indexInTList = m_dataModel.indexOf(value); - tempKeyValue=new KeyValueItem(value, value,(CheckBoxList.CheckBoxListItem) tList.getModel().getElementAt(indexInTList)); - } - else{ - tempKeyValue=new KeyValueItem(value, value); + tempKeyValue = new KeyValueItem(value, value, (CheckBoxList.CheckBoxListItem) tList.getModel().getElementAt(indexInTList)); + } else { + tempKeyValue = new KeyValueItem(value, value); } this.allItems.add(tempKeyValue); } } // sorting - if(choice.isSortEnabled()){ + if (choice.isSortEnabled()) { Collections.sort(this.allItems, new Comparator() { @Override public int compare(KeyValueItem o1, KeyValueItem o2) { @@ -125,38 +104,37 @@ public class PickCheckBoxDialog extends MageDialog { } }); } - + // search - if(choice.isSearchEnabled()) - { + if (choice.isSearchEnabled()) { panelSearch.setVisible(true); this.editSearch.setText(choice.getSearchText()); - }else{ + } else { panelSearch.setVisible(false); this.editSearch.setText(""); } - + // listeners for inremental filtering editSearch.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - choice.setSearchText(editSearch.getText()); - loadData(); - } + @Override + public void insertUpdate(DocumentEvent e) { + choice.setSearchText(editSearch.getText()); + loadData(); + } - @Override - public void removeUpdate(DocumentEvent e) { - choice.setSearchText(editSearch.getText()); - loadData(); - } + @Override + public void removeUpdate(DocumentEvent e) { + choice.setSearchText(editSearch.getText()); + loadData(); + } - @Override - public void changedUpdate(DocumentEvent e) { - choice.setSearchText(editSearch.getText()); - loadData(); - } + @Override + public void changedUpdate(DocumentEvent e) { + choice.setSearchText(editSearch.getText()); + loadData(); + } }); - + // listeners for select up and down without edit focus lost editSearch.addKeyListener(new KeyListener() { @Override @@ -165,10 +143,10 @@ public class PickCheckBoxDialog extends MageDialog { } @Override - public void keyPressed(KeyEvent e) { - if(e.getKeyCode() == KeyEvent.VK_UP){ + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_UP) { doPrevSelect(); - }else if(e.getKeyCode() == KeyEvent.VK_DOWN){ + } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { doNextSelect(); } } @@ -178,19 +156,19 @@ public class PickCheckBoxDialog extends MageDialog { //System.out.println("released"); } }); - + // listeners double click choose listChoices.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if(e.getClickCount() == 2){ + if (e.getClickCount() == 2) { doChoose(); } } }); - + // listeners for ESC close - if(!choice.isRequired()){ + if (!choice.isRequired()) { String cancelName = "cancel"; InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName); @@ -201,107 +179,106 @@ public class PickCheckBoxDialog extends MageDialog { } }); } - + // window settings - if (this.isModal()){ + if (this.isModal()) { MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER); - }else{ + } else { MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER); } if (mageDialogState != null) { mageDialogState.setStateToDialog(this); - } else { - Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); - this.setLocation(centered.x, centered.y); - GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this); + this.makeWindowCentered(); } // final load loadData(); // start selection - if((startSelectionValue != null)){ + if ((startSelectionValue != null)) { javax.swing.JList currentlistChoices;// = new javax.swing.JList(); - currentlistChoices=this.get_a_Jlist_from_ScrollListView(); + currentlistChoices = this.get_a_Jlist_from_ScrollListView(); /*currentlistChoices = this.listChoices;*/ int selectIndex = -1; - for(int i = 0; i < this.listChoices.getModel().getSize(); i++){ + for (int i = 0; i < this.listChoices.getModel().getSize(); i++) { //KeyValueItem listItem = (KeyValueItem)currentlistChoices.getModel().getElementAt(i); String elementOfList = currentlistChoices.getModel().getElementAt(i).toString(); - if (elementOfList.equals(startSelectionValue)){ + if (elementOfList.equals(startSelectionValue)) { selectIndex = i; break; } } - if(selectIndex >= 0){ - // currentlistChoices=this.get_a_Jlist_from_ScrollListView(); + if (selectIndex >= 0) { + // currentlistChoices=this.get_a_Jlist_from_ScrollListView(); /*currentlistChoices = this.listChoices;*/ - currentlistChoices.setSelectedIndex(selectIndex); - currentlistChoices.ensureIndexIsVisible(selectIndex); + currentlistChoices.setSelectedIndex(selectIndex); + currentlistChoices.ensureIndexIsVisible(selectIndex); } } this.setVisible(true); } - - public void setWindowSize(int width, int heigth){ + + public void setWindowSize(int width, int heigth) { this.setSize(new Dimension(width, heigth)); } - - private void loadData(){ + + private void loadData() { // load data to datamodel after filter or on startup - String filter = choice.getSearchText(); - if (filter == null){ filter = ""; } + String filter = choice.getSearchText(); + if (filter == null) { + filter = ""; + } filter = filter.toLowerCase(); - + this.dataModel.clear(); this.m_dataModel.clear(); - for(KeyValueItem item: this.allItems){ - if(!choice.isSearchEnabled() || item.Value.toLowerCase().contains(filter)){ + for (KeyValueItem item : this.allItems) { + if (!choice.isSearchEnabled() || item.Value.toLowerCase().contains(filter)) { this.dataModel.addElement(item); this.m_dataModel.addElement(item.getObjectValue()); } } } - - private void setLabelText(JLabel label, String text){ - if ((text != null) && !text.equals("")){ + + private void setLabelText(JLabel label, String text) { + if ((text != null) && !text.equals("")) { label.setText(String.format(HTML_TEMPLATE, text)); label.setVisible(true); - }else{ + } else { label.setText(""); label.setVisible(false); - } - } - - private void doNextSelect(){ - int newSel = this.listChoices.getSelectedIndex() + 1; - int maxSel = this.listChoices.getModel().getSize() - 1; - if(newSel <= maxSel){ - this.listChoices.setSelectedIndex(newSel); - this.listChoices.ensureIndexIsVisible(newSel); } } - - private void doPrevSelect(){ - int newSel = this.listChoices.getSelectedIndex() - 1; - if(newSel >= 0){ + + private void doNextSelect() { + int newSel = this.listChoices.getSelectedIndex() + 1; + int maxSel = this.listChoices.getModel().getSize() - 1; + if (newSel <= maxSel) { this.listChoices.setSelectedIndex(newSel); this.listChoices.ensureIndexIsVisible(newSel); } } - private void doChoose(){ - if((tList != null)||(setChoice())){ + private void doPrevSelect() { + int newSel = this.listChoices.getSelectedIndex() - 1; + if (newSel >= 0) { + this.listChoices.setSelectedIndex(newSel); + this.listChoices.ensureIndexIsVisible(newSel); + } + } + + private void doChoose() { + if ((tList != null) || (setChoice())) { this.m_dataModel.clear(); restoreData(this.m_dataModel); this.hideDialog(); } } - - private void doCancel(){ + + private void doCancel() { this.listChoices.clearSelection(); this.choice.clearChoice(); hideDialog(); @@ -309,91 +286,93 @@ public class PickCheckBoxDialog extends MageDialog { /** * Creates new form PickChoiceDialog - * @param list + * + * @param list */ public PickCheckBoxDialog(CheckBoxList list) { initComponents(); - tList=list; - + tList = list; + this.listChoices.setModel(dataModel); this.setModal(true); - if(tList != null) - { + if (tList != null) { this.listChoices.setVisible(false); - - m_dataModel= ( CheckBoxList.CheckBoxListModel )tList.getModel(); + + m_dataModel = (CheckBoxList.CheckBoxListModel) tList.getModel(); tList.setSelectionForeground(Color.BLUE); - - if(this.tList instanceof javax.swing.JList){ - setFocus(tList); - } - + + if (this.tList instanceof javax.swing.JList) { + setFocus(tList); + } + } } + /** * Creates new form PickChoiceDialog */ public PickCheckBoxDialog() { this(null); } - + public boolean setChoice() { - KeyValueItem item = (KeyValueItem)this.listChoices.getSelectedValue(); - + KeyValueItem item = (KeyValueItem) this.listChoices.getSelectedValue(); + // auto select one item (after incemental filtering) - if((item == null) && (this.listChoices.getModel().getSize() == 1)){ + if ((item == null) && (this.listChoices.getModel().getSize() == 1)) { this.listChoices.setSelectedIndex(0); - item = (KeyValueItem)this.listChoices.getSelectedValue(); + item = (KeyValueItem) this.listChoices.getSelectedValue(); } - - if(item != null){ - if(choice.isKeyChoice()){ + + if (item != null) { + if (choice.isKeyChoice()) { choice.setChoiceByKey(item.getKey()); - }else{ + } else { choice.setChoice(item.getKey()); } return true; - }else{ + } else { choice.clearChoice(); return false; } } - - class KeyValueItem - { + + class KeyValueItem { private final String Key; private final String Value; private final CheckBoxList.CheckBoxListItem objectValue; - - public KeyValueItem(String value) { - this(value,null,null); - } - public KeyValueItem(String value, String label) { - this(value,label,null); + + public KeyValueItem(String value) { + this(value, null, null); } - public KeyValueItem(String value, String label,CheckBoxList.CheckBoxListItem object) { + + public KeyValueItem(String value, String label) { + this(value, label, null); + } + + public KeyValueItem(String value, String label, CheckBoxList.CheckBoxListItem object) { this.Key = value; this.Value = label; - this.objectValue = object; + this.objectValue = object; } public String getKey() { return this.Key; - } + } public String getValue() { return this.Value; } - - public Object getObjectValue(){ - return (CheckBoxList.CheckBoxListItem)this.objectValue; + + public Object getObjectValue() { + return (CheckBoxList.CheckBoxListItem) this.objectValue; } @Override public String toString() { return this.Value; - } + } } /** @@ -428,20 +407,20 @@ public class PickCheckBoxDialog extends MageDialog { javax.swing.GroupLayout panelHeaderLayout = new javax.swing.GroupLayout(panelHeader); panelHeader.setLayout(panelHeaderLayout); panelHeaderLayout.setHorizontalGroup( - panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelHeaderLayout.createSequentialGroup() - .addGroup(panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING)) - .addGap(0, 0, 0)) + panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelHeaderLayout.createSequentialGroup() + .addGroup(panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING)) + .addGap(0, 0, 0)) ); panelHeaderLayout.setVerticalGroup( - panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelHeaderLayout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(labelMessage) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(labelSubMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 30, Short.MAX_VALUE)) + panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelHeaderLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(labelMessage) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(labelSubMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 30, Short.MAX_VALUE)) ); labelSearch.setText("Search:"); @@ -451,28 +430,34 @@ public class PickCheckBoxDialog extends MageDialog { javax.swing.GroupLayout panelSearchLayout = new javax.swing.GroupLayout(panelSearch); panelSearch.setLayout(panelSearchLayout); panelSearchLayout.setHorizontalGroup( - panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelSearchLayout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(labelSearch) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(editSearch) - .addGap(0, 0, 0)) + panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelSearchLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(labelSearch) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(editSearch) + .addGap(0, 0, 0)) ); panelSearchLayout.setVerticalGroup( - panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelSearchLayout.createSequentialGroup() - .addGap(3, 3, 3) - .addGroup(panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(labelSearch) - .addComponent(editSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(3, 3, 3)) + panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelSearchLayout.createSequentialGroup() + .addGap(3, 3, 3) + .addGroup(panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(labelSearch) + .addComponent(editSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(3, 3, 3)) ); listChoices.setModel(new javax.swing.AbstractListModel() { - String[] strings = { "item1", "item2", "item3" }; - public int getSize() { return strings.length; } - public Object getElementAt(int i) { return strings[i]; } + String[] strings = {"item1", "item2", "item3"}; + + public int getSize() { + return strings.length; + } + + public Object getElementAt(int i) { + return strings[i]; + } }); scrollList.setViewportView(listChoices); @@ -501,25 +486,25 @@ public class PickCheckBoxDialog extends MageDialog { javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands); panelCommands.setLayout(panelCommandsLayout); panelCommandsLayout.setHorizontalGroup( - panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelCommandsLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btClear, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btOK) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btClear, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btOK) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelCommandsLayout.setVerticalGroup( - panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelCommandsLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btCancel) - .addComponent(btOK) - .addComponent(btClear, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btCancel) + .addComponent(btOK) + .addComponent(btClear, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) ); getRootPane().setDefaultButton(btOK); @@ -528,28 +513,28 @@ public class PickCheckBoxDialog extends MageDialog { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollList, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(panelCommands, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelHeader, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelSearch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scrollList, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(panelCommands, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelHeader, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelSearch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(panelHeader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(panelHeader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); pack(); diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java index 9a73c93a9b..28bf5227ee 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java @@ -1,36 +1,17 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package mage.client.dialog; -import java.awt.Dimension; -import java.awt.Point; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.*; -import javax.swing.AbstractAction; -import javax.swing.ActionMap; -import javax.swing.DefaultListModel; -import javax.swing.InputMap; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JLayeredPane; -import javax.swing.KeyStroke; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import mage.choices.Choice; import mage.client.MageFrame; -import mage.client.util.SettingsManager; -import mage.client.util.gui.GuiDisplayUtil; import mage.client.util.gui.MageDialogState; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.*; +import java.util.*; + /** - * * @author JayDi85 */ @@ -39,7 +20,7 @@ public class PickChoiceDialog extends MageDialog { Choice choice; ArrayList allItems = new ArrayList<>(); DefaultListModel dataModel = new DefaultListModel(); - + final private static String HTML_TEMPLATE = "
%s
"; public void showDialog(Choice choice) { @@ -53,31 +34,31 @@ public class PickChoiceDialog extends MageDialog { public void showDialog(Choice choice, UUID objectId, MageDialogState mageDialogState) { showDialog(choice, objectId, mageDialogState, null); } - + public void showDialog(Choice choice, UUID objectId, MageDialogState mageDialogState, String startSelectionValue) { this.choice = choice; - + setLabelText(this.labelMessage, choice.getMessage()); setLabelText(this.labelSubMessage, choice.getSubMessage()); - + btCancel.setEnabled(!choice.isRequired()); - + // 2 modes: string or key-values // sore data in allItems for inremental filtering // http://logicbig.com/tutorials/core-java-tutorial/swing/list-filter/ this.allItems.clear(); - if (choice.isKeyChoice()){ - for (Map.Entry entry: choice.getKeyChoices().entrySet()) { - this.allItems.add(new KeyValueItem(entry.getKey(), entry.getValue())); + if (choice.isKeyChoice()) { + for (Map.Entry entry : choice.getKeyChoices().entrySet()) { + this.allItems.add(new KeyValueItem(entry.getKey(), entry.getValue())); } } else { - for (String value: choice.getChoices()){ - this.allItems.add(new KeyValueItem(value, value)); + for (String value : choice.getChoices()) { + this.allItems.add(new KeyValueItem(value, value)); } } // sorting - if(choice.isSortEnabled()){ + if (choice.isSortEnabled()) { Collections.sort(this.allItems, new Comparator() { @Override public int compare(KeyValueItem o1, KeyValueItem o2) { @@ -87,38 +68,37 @@ public class PickChoiceDialog extends MageDialog { } }); } - + // search - if(choice.isSearchEnabled()) - { + if (choice.isSearchEnabled()) { panelSearch.setVisible(true); this.editSearch.setText(choice.getSearchText()); - }else{ + } else { panelSearch.setVisible(false); this.editSearch.setText(""); } - + // listeners for inremental filtering editSearch.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - choice.setSearchText(editSearch.getText()); - loadData(); - } + @Override + public void insertUpdate(DocumentEvent e) { + choice.setSearchText(editSearch.getText()); + loadData(); + } - @Override - public void removeUpdate(DocumentEvent e) { - choice.setSearchText(editSearch.getText()); - loadData(); - } + @Override + public void removeUpdate(DocumentEvent e) { + choice.setSearchText(editSearch.getText()); + loadData(); + } - @Override - public void changedUpdate(DocumentEvent e) { - choice.setSearchText(editSearch.getText()); - loadData(); - } + @Override + public void changedUpdate(DocumentEvent e) { + choice.setSearchText(editSearch.getText()); + loadData(); + } }); - + // listeners for select up and down without edit focus lost editSearch.addKeyListener(new KeyListener() { @Override @@ -127,10 +107,10 @@ public class PickChoiceDialog extends MageDialog { } @Override - public void keyPressed(KeyEvent e) { - if(e.getKeyCode() == KeyEvent.VK_UP){ + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_UP) { doPrevSelect(); - }else if(e.getKeyCode() == KeyEvent.VK_DOWN){ + } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { doNextSelect(); } } @@ -140,19 +120,19 @@ public class PickChoiceDialog extends MageDialog { //System.out.println("released"); } }); - + // listeners double click choose listChoices.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if(e.getClickCount() == 2){ + if (e.getClickCount() == 2) { doChoose(); } } }); - + // listeners for ESC close - if(!choice.isRequired()){ + if (!choice.isRequired()) { String cancelName = "cancel"; InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName); @@ -163,37 +143,35 @@ public class PickChoiceDialog extends MageDialog { } }); } - + // window settings - if (this.isModal()){ + if (this.isModal()) { MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER); - }else{ + } else { MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER); } if (mageDialogState != null) { mageDialogState.setStateToDialog(this); - + } else { - Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); - this.setLocation(centered.x, centered.y); - GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this); + this.makeWindowCentered(); } // final load loadData(); // start selection - if((startSelectionValue != null)){ + if ((startSelectionValue != null)) { int selectIndex = -1; - for(int i = 0; i < this.listChoices.getModel().getSize(); i++){ - KeyValueItem listItem = (KeyValueItem)this.listChoices.getModel().getElementAt(i); - if (listItem.Key.equals(startSelectionValue)){ + for (int i = 0; i < this.listChoices.getModel().getSize(); i++) { + KeyValueItem listItem = (KeyValueItem) this.listChoices.getModel().getElementAt(i); + if (listItem.Key.equals(startSelectionValue)) { selectIndex = i; break; } } - if(selectIndex >= 0){ + if (selectIndex >= 0) { this.listChoices.setSelectedIndex(selectIndex); this.listChoices.ensureIndexIsVisible(selectIndex); } @@ -201,59 +179,61 @@ public class PickChoiceDialog extends MageDialog { this.setVisible(true); } - - public void setWindowSize(int width, int heigth){ + + public void setWindowSize(int width, int heigth) { this.setSize(new Dimension(width, heigth)); } - - private void loadData(){ + + private void loadData() { // load data to datamodel after filter or on startup String filter = choice.getSearchText(); - if (filter == null){ filter = ""; } + if (filter == null) { + filter = ""; + } filter = filter.toLowerCase(Locale.ENGLISH); - + this.dataModel.clear(); - for(KeyValueItem item: this.allItems){ - if(!choice.isSearchEnabled() || item.Value.toLowerCase(Locale.ENGLISH).contains(filter)){ + for (KeyValueItem item : this.allItems) { + if (!choice.isSearchEnabled() || item.Value.toLowerCase(Locale.ENGLISH).contains(filter)) { this.dataModel.addElement(item); } } } - - private void setLabelText(JLabel label, String text){ - if ((text != null) && !text.equals("")){ + + private void setLabelText(JLabel label, String text) { + if ((text != null) && !text.equals("")) { label.setText(String.format(HTML_TEMPLATE, text)); label.setVisible(true); - }else{ + } else { label.setText(""); label.setVisible(false); - } - } - - private void doNextSelect(){ - int newSel = this.listChoices.getSelectedIndex() + 1; - int maxSel = this.listChoices.getModel().getSize() - 1; - if(newSel <= maxSel){ - this.listChoices.setSelectedIndex(newSel); - this.listChoices.ensureIndexIsVisible(newSel); } } - - private void doPrevSelect(){ - int newSel = this.listChoices.getSelectedIndex() - 1; - if(newSel >= 0){ + + private void doNextSelect() { + int newSel = this.listChoices.getSelectedIndex() + 1; + int maxSel = this.listChoices.getModel().getSize() - 1; + if (newSel <= maxSel) { this.listChoices.setSelectedIndex(newSel); this.listChoices.ensureIndexIsVisible(newSel); } } - private void doChoose(){ - if(setChoice()){ + private void doPrevSelect() { + int newSel = this.listChoices.getSelectedIndex() - 1; + if (newSel >= 0) { + this.listChoices.setSelectedIndex(newSel); + this.listChoices.ensureIndexIsVisible(newSel); + } + } + + private void doChoose() { + if (setChoice()) { this.hideDialog(); } } - - private void doCancel(){ + + private void doCancel() { this.listChoices.clearSelection(); this.choice.clearChoice(); hideDialog(); @@ -267,34 +247,33 @@ public class PickChoiceDialog extends MageDialog { this.listChoices.setModel(dataModel); this.setModal(true); } - + public boolean setChoice() { - KeyValueItem item = (KeyValueItem)this.listChoices.getSelectedValue(); - + KeyValueItem item = (KeyValueItem) this.listChoices.getSelectedValue(); + // auto select one item (after incemental filtering) - if((item == null) && (this.listChoices.getModel().getSize() == 1)){ + if ((item == null) && (this.listChoices.getModel().getSize() == 1)) { this.listChoices.setSelectedIndex(0); - item = (KeyValueItem)this.listChoices.getSelectedValue(); + item = (KeyValueItem) this.listChoices.getSelectedValue(); } - - if(item != null){ - if(choice.isKeyChoice()){ + + if (item != null) { + if (choice.isKeyChoice()) { choice.setChoiceByKey(item.getKey()); - }else{ + } else { choice.setChoice(item.getKey()); } return true; - }else{ + } else { choice.clearChoice(); return false; } } - - class KeyValueItem - { + + class KeyValueItem { private final String Key; private final String Value; - + public KeyValueItem(String value, String label) { this.Key = value; this.Value = label; @@ -311,7 +290,7 @@ public class PickChoiceDialog extends MageDialog { @Override public String toString() { return this.Value; - } + } } /** @@ -345,20 +324,20 @@ public class PickChoiceDialog extends MageDialog { javax.swing.GroupLayout panelHeaderLayout = new javax.swing.GroupLayout(panelHeader); panelHeader.setLayout(panelHeaderLayout); panelHeaderLayout.setHorizontalGroup( - panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelHeaderLayout.createSequentialGroup() - .addGroup(panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE) - .addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)) - .addGap(0, 0, 0)) + panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelHeaderLayout.createSequentialGroup() + .addGroup(panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE) + .addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)) + .addGap(0, 0, 0)) ); panelHeaderLayout.setVerticalGroup( - panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelHeaderLayout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(labelMessage) - .addGap(0, 0, 0) - .addComponent(labelSubMessage)) + panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelHeaderLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(labelMessage) + .addGap(0, 0, 0) + .addComponent(labelSubMessage)) ); labelSearch.setText("Search:"); @@ -368,28 +347,34 @@ public class PickChoiceDialog extends MageDialog { javax.swing.GroupLayout panelSearchLayout = new javax.swing.GroupLayout(panelSearch); panelSearch.setLayout(panelSearchLayout); panelSearchLayout.setHorizontalGroup( - panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelSearchLayout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(labelSearch) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(editSearch) - .addGap(0, 0, 0)) + panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelSearchLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(labelSearch) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(editSearch) + .addGap(0, 0, 0)) ); panelSearchLayout.setVerticalGroup( - panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelSearchLayout.createSequentialGroup() - .addGap(3, 3, 3) - .addGroup(panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(labelSearch) - .addComponent(editSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(3, 3, 3)) + panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelSearchLayout.createSequentialGroup() + .addGap(3, 3, 3) + .addGroup(panelSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(labelSearch) + .addComponent(editSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(3, 3, 3)) ); listChoices.setModel(new javax.swing.AbstractListModel() { - String[] strings = { "item1", "item2", "item3" }; - public int getSize() { return strings.length; } - public Object getElementAt(int i) { return strings[i]; } + String[] strings = {"item1", "item2", "item3"}; + + public int getSize() { + return strings.length; + } + + public Object getElementAt(int i) { + return strings[i]; + } }); scrollList.setViewportView(listChoices); @@ -410,25 +395,25 @@ public class PickChoiceDialog extends MageDialog { javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands); panelCommands.setLayout(panelCommandsLayout); panelCommandsLayout.setHorizontalGroup( - panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelCommandsLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btOK) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btOK) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); - panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btCancel, btOK}); + panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[]{btCancel, btOK}); panelCommandsLayout.setVerticalGroup( - panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelCommandsLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btCancel) - .addComponent(btOK)) - .addContainerGap()) + panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btCancel) + .addComponent(btOK)) + .addContainerGap()) ); getRootPane().setDefaultButton(btOK); @@ -436,28 +421,28 @@ public class PickChoiceDialog extends MageDialog { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(scrollList, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(panelCommands, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelHeader, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelSearch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(scrollList, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(panelCommands, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelHeader, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelSearch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(panelHeader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(panelHeader, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); pack(); diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickNumberDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickNumberDialog.java index f24f80dc01..4bf068f553 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickNumberDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickNumberDialog.java @@ -1,31 +1,21 @@ - - -/* - * PickNumberDialog.java - * - * Created on Feb 25, 2010, 12:03:39 PM - */ - package mage.client.dialog; -import java.awt.Point; +import mage.client.MageFrame; + +import javax.swing.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; -import javax.swing.*; - -import mage.client.MageFrame; -import mage.client.util.SettingsManager; -import mage.client.util.gui.GuiDisplayUtil; /** - * * @author BetaSteward_at_googlemail.com */ public class PickNumberDialog extends MageDialog { private boolean cancel; - /** Creates new form PickNumberDialog */ + /** + * Creates new form PickNumberDialog + */ public PickNumberDialog() { initComponents(); this.setModal(true); @@ -40,16 +30,16 @@ public class PickNumberDialog extends MageDialog { this.pack(); // window settings - if (this.isModal()){ + if (this.isModal()) { MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER); - }else{ + } else { MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER); } this.getRootPane().setDefaultButton(this.btnOk); // restore default button after root panel change (no need actually) // enable spinner's enter key like text (one enter press instead two) // https://stackoverflow.com/questions/3873870/java-keylistener-not-firing-on-jspinner - ((JSpinner.DefaultEditor)this.spnAmount.getEditor()).getTextField().addKeyListener(new KeyListener(){ + ((JSpinner.DefaultEditor) this.spnAmount.getEditor()).getTextField().addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { @@ -68,23 +58,22 @@ public class PickNumberDialog extends MageDialog { }); - Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); - this.setLocation(centered.x, centered.y); - GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this); + this.makeWindowCentered(); // TODO: need to fix focus restore on second popup (it's not focues, test on Manamorphose) this.setVisible(true); } public int getAmount() { - return ((Number)spnAmount.getValue()).intValue(); + return ((Number) spnAmount.getValue()).intValue(); } public boolean isCancel() { return cancel; } - /** This method is called from within the constructor to + /** + * This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. @@ -105,7 +94,7 @@ public class PickNumberDialog extends MageDialog { lblMessage.setEditable(false); lblMessage.setText("long text long text long text long text long text long text long text long text"); - lblMessage.setCursor(null ); + lblMessage.setCursor(null); lblMessage.setFocusable(false); lblMessage.setOpaque(false); jScrollPane1.setViewportView(lblMessage); @@ -129,22 +118,22 @@ public class PickNumberDialog extends MageDialog { javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands); panelCommands.setLayout(panelCommandsLayout); panelCommandsLayout.setHorizontalGroup( - panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelCommandsLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOk) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnCancel) - .addContainerGap()) + panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnOk) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnCancel) + .addContainerGap()) ); panelCommandsLayout.setVerticalGroup( - panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelCommandsLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnOk) - .addComponent(btnCancel)) - .addContainerGap()) + panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnOk) + .addComponent(btnCancel)) + .addContainerGap()) ); getRootPane().setDefaultButton(btnOk); @@ -152,27 +141,27 @@ public class PickNumberDialog extends MageDialog { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE) - .addComponent(panelCommands, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addComponent(spnAmount, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE) + .addComponent(panelCommands, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(spnAmount, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnAmount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnAmount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); pack(); diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java index 4bed9829d6..442e8ae49d 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickPileDialog.java @@ -1,23 +1,16 @@ - package mage.client.dialog; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Point; -import java.util.UUID; -import javax.swing.JButton; -import javax.swing.JLayeredPane; -import javax.swing.JPanel; import mage.client.MageFrame; import mage.client.cards.BigCard; import mage.client.cards.CardArea; -import mage.client.util.SettingsManager; -import mage.client.util.gui.GuiDisplayUtil; import mage.view.CardsView; import org.mage.card.arcane.CardPanel; +import javax.swing.*; +import java.awt.*; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class PickPileDialog extends MageDialog { @@ -81,18 +74,16 @@ public class PickPileDialog extends MageDialog { } pack(); - Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); - this.setLocation(centered.x, centered.y); - GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this); + this.makeWindowCentered(); this.revalidate(); this.repaint(); this.setModal(true); // window settings - if (this.isModal()){ + if (this.isModal()) { MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER); - }else{ + } else { MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER); } From 617f4d4b4bf535f512cad98e0554db24d9f1aef3 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 18 Dec 2018 18:01:35 +0400 Subject: [PATCH 06/11] UI: added new download images dialog: * new option to download all modern cards; * new option with language selection; * new button for sets fast search; * new language support: Chinese Traditional; * all sets are sorted by date and have released date; * fixed selection reset on source changes; --- .../src/main/java/mage/client/MageFrame.java | 6 +- .../collection/viewer/MageBook.java | 2 +- .../client/dialog/DownloadImagesDialog.form | 514 ++++++++++++++++++ .../client/dialog/DownloadImagesDialog.java | 401 ++++++++++++++ ...ures.java => DownloadPicturesService.java} | 497 ++++++++--------- 5 files changed, 1151 insertions(+), 269 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form create mode 100644 Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java rename Mage.Client/src/main/java/org/mage/plugins/card/images/{DownloadPictures.java => DownloadPicturesService.java} (69%) diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 4e55087e0f..d0f3ebde88 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -47,7 +47,7 @@ import net.java.truevfs.access.TConfig; import net.java.truevfs.kernel.spec.FsAccessOption; import org.apache.log4j.Logger; import org.mage.card.arcane.ManaSymbols; -import org.mage.plugins.card.images.DownloadPictures; +import org.mage.plugins.card.images.DownloadPicturesService; import org.mage.plugins.card.info.CardInfoPaneImpl; import org.mage.plugins.card.utils.impl.ImageManagerImpl; @@ -1010,7 +1010,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { }//GEN-LAST:event_btnImagesActionPerformed public void downloadImages() { - DownloadPictures.startDownload(); + DownloadPicturesService.startDownload(); } public void exitApp() { @@ -1380,7 +1380,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { Plugins.instance.downloadSymbols(); break; case CLIENT_DOWNLOAD_CARD_IMAGES: - DownloadPictures.startDownload(); + DownloadPicturesService.startDownload(); break; case CLIENT_DISCONNECT: if (SessionHandler.isConnected()) { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java index fd53051191..7749b95c80 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java @@ -41,7 +41,7 @@ import mage.view.PlaneView; import org.apache.log4j.Logger; import org.mage.card.arcane.ManaSymbols; import org.mage.plugins.card.images.CardDownloadData; -import static org.mage.plugins.card.images.DownloadPictures.getTokenCardUrls; +import static org.mage.plugins.card.images.DownloadPicturesService.getTokenCardUrls; /** * Mage book with cards and page flipping. diff --git a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form new file mode 100644 index 0000000000..da0aaa4ea0 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form @@ -0,0 +1,514 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java new file mode 100644 index 0000000000..130a5799fa --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java @@ -0,0 +1,401 @@ +package mage.client.dialog; + +import mage.client.MageFrame; +import mage.client.util.gui.FastSearchUtil; +import mage.client.util.gui.MageDialogState; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +/** + * @author JayDi85 + */ +public class DownloadImagesDialog extends MageDialog { + + public static final int RET_CANCEL = 0; + public static final int RET_OK = 1; + + private Dimension sizeModeMessageOnly; + private Dimension sizeModeMessageAndControls; + + + /** + * Creates new form DownloadImagesDialog + */ + public DownloadImagesDialog() { + initComponents(); + this.setModal(true); + + // save default sizes + // + this.sizeModeMessageAndControls = new Dimension(580, 330); // dialog -> properties -> designer size + // + this.sizeModeMessageOnly = new Dimension(this.sizeModeMessageAndControls.getSize()); + sizeModeMessageOnly.height = 25 * 3; + sizeModeMessageOnly.width = sizeModeMessageOnly.width / 2; + + // Close the dialog when Esc is pressed + String cancelName = "cancel"; + InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName); + ActionMap actionMap = getRootPane().getActionMap(); + actionMap.put(cancelName, new AbstractAction() { + public void actionPerformed(ActionEvent e) { + doClose(RET_CANCEL); + } + }); + } + + public void setWindowSize(int width, int heigth) { + this.setSize(new Dimension(width, heigth)); + } + + public void showDialog() { + showDialog(null); + } + + public void showDialog(MageDialogState mageDialogState) { + showDownloadControls(false); // call to change window size + + // window settings + if (this.isModal()) { + MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER); + } else { + MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER); + } + if (mageDialogState != null) { + mageDialogState.setStateToDialog(this); + } else { + this.makeWindowCentered(); + } + this.setVisible(true); + } + + public void setGlobalInfo(String info) { + this.labelGlobal.setText(info); + } + + public void setCurrentInfo(String info) { + this.labelInfo.setText(info); + } + + public JComboBox getSourcesCombo() { + return this.comboSource; + } + + public JComboBox getLaunguagesCombo() { + return this.comboLanguage; + } + + public JComboBox getSetsCombo() { + return this.comboSets; + } + + public JButton getStartButton() { + return this.buttonOK; + } + + public JButton getCancelButton() { + return this.buttonCancel; + } + + public JProgressBar getProgressBar() { + return this.progress; + } + + public void showLanguagesSupport(boolean haveSupport) { + labelLanguage.setEnabled(haveSupport); + comboLanguage.setEnabled(haveSupport); + } + + private void setTabTitle(int tabIndex, String title, String iconResourceName) { + // tab caption with left sided icon + // https://stackoverflow.com/questions/1782224/jtabbedpane-icon-on-left-side-of-tabs + JLabel lbl = new JLabel(title); + Icon icon = new ImageIcon(getClass().getResource(iconResourceName)); + lbl.setIcon(icon); + lbl.setIconTextGap(5); + lbl.setHorizontalTextPosition(SwingConstants.RIGHT); + tabsList.setTabComponentAt(tabIndex, lbl); + } + + public void showDownloadControls(boolean needToShow) { + // 2 modes: + // - only message; + // - message + download controls and buttons + this.panelGlobal.setVisible(true); + this.tabsList.setVisible(needToShow); + this.panelCommands.setVisible(needToShow); + + // auto-size form + if (needToShow) { + this.setWindowSize(this.sizeModeMessageAndControls.width, this.sizeModeMessageAndControls.height); + } else { + this.setWindowSize(this.sizeModeMessageOnly.width, this.sizeModeMessageOnly.height); + } + //this.setLocationRelativeTo(null); // center screen //FIX + + // icons on tabs left side + setTabTitle(0, "Standard download", "/buttons/card_panel.png"); + setTabTitle(1, "Custom download", "/buttons/list_panel.png"); + + // TODO: add manual mode as tab + this.tabsList.getTabComponentAt(1).setEnabled(false); + this.tabsList.setEnabledAt(1, false); + } + + /** + * @return the return status of this dialog - one of RET_OK or RET_CANCEL + */ + public int getReturnStatus() { + return returnStatus; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + panelGlobal = new javax.swing.JPanel(); + fillerGlobal1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); + labelGlobal = new javax.swing.JLabel(); + fillerglobal2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); + tabsList = new javax.swing.JTabbedPane(); + tabMain = new javax.swing.JPanel(); + panelInfo = new javax.swing.JPanel(); + fillerInfo1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); + labelInfo = new javax.swing.JLabel(); + fillerInfo2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); + panelSource = new javax.swing.JPanel(); + panelSourceLeft = new javax.swing.JPanel(); + labelSource = new javax.swing.JLabel(); + comboSource = new javax.swing.JComboBox<>(); + panelSourceRight = new javax.swing.JPanel(); + labelLanguage = new javax.swing.JLabel(); + comboLanguage = new javax.swing.JComboBox<>(); + panelMode = new javax.swing.JPanel(); + panelModeInner = new javax.swing.JPanel(); + labelMode = new javax.swing.JLabel(); + panelModeSelect = new javax.swing.JPanel(); + comboSets = new javax.swing.JComboBox<>(); + fillerMode1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + buttonSearchSet = new javax.swing.JButton(); + fillerMode = new javax.swing.Box.Filler(new java.awt.Dimension(130, 0), new java.awt.Dimension(130, 0), new java.awt.Dimension(130, 32767)); + fillerMain1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 10), new java.awt.Dimension(0, 10), new java.awt.Dimension(32767, 10)); + panelProgress = new javax.swing.JPanel(); + fillerProgress1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + progress = new javax.swing.JProgressBar(); + fillerProgress2 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + fillerMain2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767)); + tabCustom = new javax.swing.JPanel(); + panelCommands = new javax.swing.JPanel(); + buttonOK = new javax.swing.JButton(); + buttonCancel = new javax.swing.JButton(); + + setTitle("Downloading images"); + setPreferredSize(new java.awt.Dimension(600, 400)); + getContentPane().setLayout(new java.awt.BorderLayout()); + + panelGlobal.setLayout(new javax.swing.BoxLayout(panelGlobal, javax.swing.BoxLayout.Y_AXIS)); + panelGlobal.add(fillerGlobal1); + + labelGlobal.setText("Initializing image download..."); + labelGlobal.setAlignmentX(0.5F); + panelGlobal.add(labelGlobal); + panelGlobal.add(fillerglobal2); + + getContentPane().add(panelGlobal, java.awt.BorderLayout.NORTH); + + tabsList.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT); + + tabMain.setLayout(new javax.swing.BoxLayout(tabMain, javax.swing.BoxLayout.Y_AXIS)); + + panelInfo.setLayout(new javax.swing.BoxLayout(panelInfo, javax.swing.BoxLayout.Y_AXIS)); + panelInfo.add(fillerInfo1); + + labelInfo.setText("Missing: 12345 card images / 789 token images"); + labelInfo.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 7, 0, 0)); + panelInfo.add(labelInfo); + panelInfo.add(fillerInfo2); + + tabMain.add(panelInfo); + + panelSource.setMaximumSize(new java.awt.Dimension(65536, 55)); + panelSource.setMinimumSize(new java.awt.Dimension(352, 55)); + panelSource.setPreferredSize(new java.awt.Dimension(593, 55)); + panelSource.setLayout(new javax.swing.BoxLayout(panelSource, javax.swing.BoxLayout.X_AXIS)); + + panelSourceLeft.setMinimumSize(new java.awt.Dimension(430, 30)); + panelSourceLeft.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING)); + + labelSource.setText("Images source to download:"); + panelSourceLeft.add(labelSource); + + comboSource.setMaximumRowCount(10); + comboSource.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); + comboSource.setMinimumSize(new java.awt.Dimension(300, 20)); + comboSource.setPreferredSize(new java.awt.Dimension(400, 25)); + panelSourceLeft.add(comboSource); + + panelSource.add(panelSourceLeft); + + panelSourceRight.setAlignmentX(0.0F); + panelSourceRight.setMaximumSize(new java.awt.Dimension(130, 32767)); + panelSourceRight.setMinimumSize(new java.awt.Dimension(130, 30)); + panelSourceRight.setPreferredSize(new java.awt.Dimension(130, 100)); + panelSourceRight.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING)); + + labelLanguage.setText("Language:"); + panelSourceRight.add(labelLanguage); + + comboLanguage.setMaximumRowCount(20); + comboLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); + comboLanguage.setPreferredSize(new java.awt.Dimension(90, 25)); + panelSourceRight.add(comboLanguage); + + panelSource.add(panelSourceRight); + + tabMain.add(panelSource); + + panelMode.setMaximumSize(new java.awt.Dimension(32869, 55)); + panelMode.setMinimumSize(new java.awt.Dimension(322, 55)); + panelMode.setPreferredSize(new java.awt.Dimension(100, 55)); + panelMode.setLayout(new javax.swing.BoxLayout(panelMode, javax.swing.BoxLayout.LINE_AXIS)); + + panelModeInner.setMinimumSize(new java.awt.Dimension(430, 43)); + panelModeInner.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + labelMode.setText("Sets to download:"); + labelMode.setAlignmentY(0.0F); + panelModeInner.add(labelMode); + + panelModeSelect.setLayout(new javax.swing.BoxLayout(panelModeSelect, javax.swing.BoxLayout.X_AXIS)); + + comboSets.setMaximumRowCount(20); + comboSets.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); + comboSets.setPreferredSize(new java.awt.Dimension(373, 25)); + panelModeSelect.add(comboSets); + panelModeSelect.add(fillerMode1); + + buttonSearchSet.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/search_24.png"))); // NOI18N + buttonSearchSet.setToolTipText("Fast search your flag"); + buttonSearchSet.setAlignmentX(1.0F); + buttonSearchSet.setPreferredSize(new java.awt.Dimension(25, 25)); + buttonSearchSet.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonSearchSetActionPerformed(evt); + } + }); + panelModeSelect.add(buttonSearchSet); + + panelModeInner.add(panelModeSelect); + + panelMode.add(panelModeInner); + panelMode.add(fillerMode); + + tabMain.add(panelMode); + tabMain.add(fillerMain1); + + panelProgress.setMaximumSize(new java.awt.Dimension(32777, 30)); + panelProgress.setMinimumSize(new java.awt.Dimension(20, 30)); + panelProgress.setPreferredSize(new java.awt.Dimension(564, 30)); + panelProgress.setLayout(new javax.swing.BoxLayout(panelProgress, javax.swing.BoxLayout.X_AXIS)); + panelProgress.add(fillerProgress1); + + progress.setValue(75); + progress.setMaximumSize(new java.awt.Dimension(32767, 25)); + progress.setString("123 of 12313 (120 cards/546 tokens) image downloads finished! Please wait! [123 Mb]"); + progress.setStringPainted(true); + panelProgress.add(progress); + panelProgress.add(fillerProgress2); + + tabMain.add(panelProgress); + tabMain.add(fillerMain2); + + tabsList.addTab("Standard download", new javax.swing.ImageIcon(getClass().getResource("/buttons/card_panel.png")), tabMain); // NOI18N + + tabCustom.setLayout(new javax.swing.BoxLayout(tabCustom, javax.swing.BoxLayout.Y_AXIS)); + tabsList.addTab("Custom download", new javax.swing.ImageIcon(getClass().getResource("/buttons/list_panel.png")), tabCustom); // NOI18N + + getContentPane().add(tabsList, java.awt.BorderLayout.CENTER); + + panelCommands.setAlignmentX(0.0F); + panelCommands.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.TRAILING)); + + buttonOK.setText("Start download"); + buttonOK.setPreferredSize(new java.awt.Dimension(120, 30)); + panelCommands.add(buttonOK); + getRootPane().setDefaultButton(buttonOK); + + buttonCancel.setText("Cancel"); + buttonCancel.setPreferredSize(new java.awt.Dimension(80, 30)); + panelCommands.add(buttonCancel); + + getContentPane().add(panelCommands, java.awt.BorderLayout.SOUTH); + + pack(); + }// //GEN-END:initComponents + + /** + * Closes the dialog + */ + private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog + doClose(RET_CANCEL); + }//GEN-LAST:event_closeDialog + + private void buttonSearchSetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSearchSetActionPerformed + FastSearchUtil.showFastSearchForStringComboBox(comboSets, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE); + }//GEN-LAST:event_buttonSearchSetActionPerformed + + private void doClose(int retStatus) { + returnStatus = retStatus; + setVisible(false); + dispose(); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton buttonCancel; + private javax.swing.JButton buttonOK; + private javax.swing.JButton buttonSearchSet; + private javax.swing.JComboBox comboLanguage; + private javax.swing.JComboBox comboSets; + private javax.swing.JComboBox comboSource; + private javax.swing.Box.Filler fillerGlobal1; + private javax.swing.Box.Filler fillerInfo1; + private javax.swing.Box.Filler fillerInfo2; + private javax.swing.Box.Filler fillerMain1; + private javax.swing.Box.Filler fillerMain2; + private javax.swing.Box.Filler fillerMode; + private javax.swing.Box.Filler fillerMode1; + private javax.swing.Box.Filler fillerProgress1; + private javax.swing.Box.Filler fillerProgress2; + private javax.swing.Box.Filler fillerglobal2; + private javax.swing.JLabel labelGlobal; + private javax.swing.JLabel labelInfo; + private javax.swing.JLabel labelLanguage; + private javax.swing.JLabel labelMode; + private javax.swing.JLabel labelSource; + private javax.swing.JPanel panelCommands; + private javax.swing.JPanel panelGlobal; + private javax.swing.JPanel panelInfo; + private javax.swing.JPanel panelMode; + private javax.swing.JPanel panelModeInner; + private javax.swing.JPanel panelModeSelect; + private javax.swing.JPanel panelProgress; + private javax.swing.JPanel panelSource; + private javax.swing.JPanel panelSourceLeft; + private javax.swing.JPanel panelSourceRight; + private javax.swing.JProgressBar progress; + private javax.swing.JPanel tabCustom; + private javax.swing.JPanel tabMain; + private javax.swing.JTabbedPane tabsList; + // End of variables declaration//GEN-END:variables + + private int returnStatus = RET_CANCEL; +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java similarity index 69% rename from Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java rename to Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java index 7be47db2d1..47b669ef2a 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java @@ -1,28 +1,14 @@ package org.mage.plugins.card.images; -import java.awt.*; -import java.awt.event.ItemEvent; -import java.io.*; -import java.net.*; -import java.nio.file.AccessDeniedException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import javax.swing.*; - import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; import mage.client.MageFrame; +import mage.client.dialog.DownloadImagesDialog; import mage.client.dialog.PreferencesDialog; +import mage.client.util.CardLanguage; import mage.client.util.sets.ConstructedFormats; import mage.remote.Connection; import mage.util.StreamUtils; @@ -35,46 +21,43 @@ import org.mage.plugins.card.dl.sources.*; import org.mage.plugins.card.properties.SettingsManager; import org.mage.plugins.card.utils.CardImageUtils; +import javax.swing.*; +import java.awt.event.ItemEvent; +import java.io.*; +import java.net.*; +import java.nio.file.AccessDeniedException; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; -public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable { +public class DownloadPicturesService extends DefaultBoundedRangeModel implements Runnable { - // don't forget to remove new sets from ignore.urls to download (propeties file in resources) - private static DownloadPictures instance; + // don't forget to remove new sets from ignore.urls to download (properties file in resources) + private static DownloadPicturesService instance; + private static final Logger logger = Logger.getLogger(DownloadPicturesService.class); - private static final Logger logger = Logger.getLogger(DownloadPictures.class); + public static final String ALL_IMAGES = "- ALL images from selected source (can be slow)"; + public static final String ALL_MODERN_IMAGES = "- MODERN images (can be slow)"; + public static final String ALL_STANDARD_IMAGES = "- STANDARD images"; + public static final String ALL_TOKENS = "- TOKEN images"; - public static final String ALL_IMAGES = "- ALL images from selected source (CAN BE VERY SLOW)"; - public static final String ALL_STANDARD_IMAGES = "- Only images from STANDARD sets"; - public static final String ALL_TOKENS = "- Only token images from selected source"; - - private JDialog dialog; - private final JProgressBar bar; - private final JOptionPane dlg; - private boolean cancel; - private final JButton closeButton; - private final JButton startDownloadButton; + private DownloadImagesDialog uiDialog; + private boolean needCancel; private int cardIndex; - private List allCardsMissingImage; + + private List cardsMissing; private List cardsToDownload; + private int missingCardsCount = 0; + private int missingTokensCount = 0; - private int missingCards = 0; - private int missingTokens = 0; - - List selectedSetCodes = new ArrayList<>(); - - private final JComboBox jComboBoxServer; - private final JLabel jLabelMessage; - private final JLabel jLabelAllMissing; - private final JLabel jLabelServer; - - private final JComboBox jComboBoxSet; - private final JLabel jLabelSet; + List selectedSets = new ArrayList<>(); + private static CardImageSource selectedSource; private final Object sync = new Object(); - - private static CardImageSource cardImageSource; - private Proxy p = Proxy.NO_PROXY; enum DownloadSources { @@ -87,7 +70,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab ALTERNATIVE("7. alternative.mtg.onl", AltMtgOnlTokensImageSource.instance), COPYPASTE("8. Copy and Paste Image URLs", CopyPasteImageSource.instance); // MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), Not working correctly yet - // MAGICCARDS("magiccards.info", MagicCardsImageSource.instance) private final String text; private final CardImageSource source; @@ -108,7 +90,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } - public static DownloadPictures getInstance() { + public static DownloadPicturesService getInstance() { return instance; } @@ -117,243 +99,225 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } public static void startDownload() { + // load images info in background task + instance = new DownloadPicturesService(MageFrame.getInstance()); + new Thread(new LoadMissingCardDataNew(instance)).start(); - /* - * if (cards == null || cards.isEmpty()) { - * JOptionPane.showMessageDialog(null, - * "All card pictures have been downloaded."); return; } - */ - instance = new DownloadPictures(MageFrame.getInstance()); - Thread t1 = new Thread(new LoadMissingCardData(instance)); - t1.start(); - instance.getDlg().setVisible(true); - instance.getDlg().dispose(); - instance.cancel = true; + // show dialog + instance.setNeedCancel(false); + instance.uiDialog.showDialog(); + instance.uiDialog.dispose(); + instance.setNeedCancel(true); } - public JDialog getDlg() { - return dialog; + public boolean getNeedCancel() { + return this.needCancel; } - public void setCancel(boolean cancel) { - this.cancel = cancel; + public void setNeedCancel(boolean needCancel) { + this.needCancel = needCancel; } - static int WIDTH = 400; - - public DownloadPictures(JFrame frame) { - + public DownloadPicturesService(JFrame frame) { + // init service and dialog cardsToDownload = new ArrayList<>(); + uiDialog = new DownloadImagesDialog(); - JPanel p0 = new JPanel(); - p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); + // MESSAGE + uiDialog.setGlobalInfo("Initializing image download..."); - p0.add(Box.createVerticalStrut(5)); - - jLabelMessage = new JLabel(); - jLabelMessage.setAlignmentX(Component.CENTER_ALIGNMENT); - jLabelMessage.setText("Initializing image download..."); - p0.add(jLabelMessage); - p0.add(Box.createVerticalStrut(5)); - - jLabelAllMissing = new JLabel(); - - jLabelAllMissing.setAlignmentX(Component.LEFT_ALIGNMENT); - // jLabelAllMissing.setText("Computing number of missing images..."); - p0.add(jLabelAllMissing); - p0.add(Box.createVerticalStrut(5)); - - jLabelServer = new JLabel(); - jLabelServer.setText("Please select image source:"); - jLabelServer.setAlignmentX(Component.LEFT_ALIGNMENT); - jLabelServer.setVisible(false); - p0.add(jLabelServer); - - p0.add(Box.createVerticalStrut(5)); - - jComboBoxServer = new JComboBox(); - jComboBoxServer.setModel(new DefaultComboBoxModel(DownloadSources.values())); - jComboBoxServer.setAlignmentX(Component.LEFT_ALIGNMENT); - jComboBoxServer.setAlignmentY(Component.LEFT_ALIGNMENT); - jComboBoxServer.addItemListener((ItemEvent event) -> { + // SOURCES - scryfall is default source + uiDialog.getSourcesCombo().setModel(new DefaultComboBoxModel(DownloadSources.values())); + uiDialog.getSourcesCombo().setSelectedItem(DownloadSources.SCRYFALL); + selectedSource = ScryfallImageSource.instance; + uiDialog.getSourcesCombo().addItemListener((ItemEvent event) -> { if (event.getStateChange() == ItemEvent.SELECTED) { - comboBoxServerItemSelected(event); - } - }); - Dimension d = jComboBoxServer.getPreferredSize(); - d.width = WIDTH; - jComboBoxServer.setPreferredSize(d); - p0.add(jComboBoxServer); - jComboBoxServer.setVisible(false); - - // set the first source as default - cardImageSource = WizardCardsImageSource.instance; - - p0.add(Box.createVerticalStrut(5)); - - // Set selection --------------------------------- - jLabelSet = new JLabel(); - jLabelSet.setText("Please select sets to download the images for:"); - jLabelSet.setAlignmentX(Component.LEFT_ALIGNMENT); - jLabelSet.setVisible(false); - p0.add(jLabelSet); - - jComboBoxSet = new JComboBox(); -// jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); - jComboBoxSet.setAlignmentX(Component.LEFT_ALIGNMENT); - jComboBoxSet.addItemListener((ItemEvent event) -> { - if (event.getStateChange() == ItemEvent.SELECTED) { - comboBoxSetItemSelected(event); + comboboxSourceSelected(event); } }); - p0.add(jComboBoxSet); - jComboBoxSet.setVisible(false); + // TODO: LANGUAGES + uiDialog.getLaunguagesCombo().setModel(new DefaultComboBoxModel(CardLanguage.values())); + uiDialog.getLaunguagesCombo().setSelectedItem(PreferencesDialog.getPrefImagesLanguage()); + reloadLanguagesForSelectedSource(); - p0.add(Box.createVerticalStrut(5)); - - // Start - startDownloadButton = new JButton("Start download"); - startDownloadButton.addActionListener(e -> { - new Thread(DownloadPictures.this).start(); - startDownloadButton.setEnabled(false); + // SETS (fills after source and language select) + //uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel(DownloadSources.values())); + uiDialog.getSetsCombo().addItemListener((ItemEvent event) -> { + if (event.getStateChange() == ItemEvent.SELECTED) { + comboboxSetSelected(event); + } }); - p0.add(Box.createVerticalStrut(5)); - // Progress - bar = new JProgressBar(this); - p0.add(bar); - bar.setStringPainted(true); + // BUTTON START + uiDialog.getStartButton().addActionListener(e -> { + // selected language setup + if (selectedSource != null) { + if (selectedSource.isLanguagesSupport()) { + selectedSource.setCurrentLanguage((CardLanguage) uiDialog.getLaunguagesCombo().getSelectedItem()); + } + } - d = bar.getPreferredSize(); - d.width = WIDTH; - bar.setPreferredSize(d); - bar.setVisible(false); + // run + new Thread(DownloadPicturesService.this).start(); + uiDialog.getStartButton().setEnabled(false); + }); - // JOptionPane - Object[] options = {startDownloadButton, closeButton = new JButton("Cancel")}; - startDownloadButton.setVisible(false); - closeButton.addActionListener(e -> dialog.setVisible(false)); - closeButton.setVisible(false); + // BUTTON CANCEL + uiDialog.getCancelButton().addActionListener(e -> uiDialog.setVisible(false)); - dlg = new JOptionPane(p0, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]); - dialog = this.dlg.createDialog(frame, "Downloading images"); + // PROGRESS BAR + uiDialog.getProgressBar().setValue(0); + + uiDialog.showDownloadControls(false); } public void setAllMissingCards() { - updateAndViewMessage("Get all available cards from the repository..."); + updateAndViewMessage("Loading cards list..."); List cards = CardRepository.instance.findCards(new CardCriteria()); - updateAndViewMessage("Check which images are missing ..."); - this.allCardsMissingImage = getNeededCards(cards); - updateAndViewMessage("Check which images the current source is providing ..."); - jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); - updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); + updateAndViewMessage("Find missing images..."); + this.cardsMissing = getNeededCards(cards); - jComboBoxServer.setVisible(true); - jLabelServer.setVisible(true); - jComboBoxSet.setVisible(true); - jLabelSet.setVisible(true); - bar.setVisible(true); - startDownloadButton.setVisible(true); - closeButton.setVisible(true); + updateAndViewMessage("Find available sets from selected source..."); + this.uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); + reloadCardsToDownload(this.uiDialog.getSetsCombo().getSelectedItem().toString()); + this.uiDialog.showDownloadControls(true); updateAndViewMessage(""); } - private void comboBoxServerItemSelected(ItemEvent evt) { - if (jComboBoxServer.isEnabled()) { - cardImageSource = ((DownloadSources) evt.getItem()).getSource(); - // update the available sets / token comboBox - jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); - updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); + private void reloadLanguagesForSelectedSource() { + this.uiDialog.showLanguagesSupport(selectedSource != null && selectedSource.isLanguagesSupport()); + } + + private void reloadSetsForSelectedSource() { + // update the available sets / token combobox + Object oldSelection = this.uiDialog.getSetsCombo().getSelectedItem(); + this.uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); + if (oldSelection != null) { + this.uiDialog.getSetsCombo().setSelectedItem(oldSelection); + } + reloadCardsToDownload(this.uiDialog.getSetsCombo().getSelectedItem().toString()); + } + + private void comboboxSourceSelected(ItemEvent evt) { + if (this.uiDialog.getSourcesCombo().isEnabled()) { + selectedSource = ((DownloadSources) evt.getItem()).getSource(); + reloadSetsForSelectedSource(); + reloadLanguagesForSelectedSource(); } } public void updateAndViewMessage(String text) { - jLabelMessage.setText(text); - if (dialog != null) { - dialog.pack(); - dialog.validate(); - dialog.repaint(); + this.uiDialog.setGlobalInfo(text); + + // auto-size on empty message (on complete) + if (text.isEmpty()) { + this.uiDialog.showDownloadControls(true); } } + private String getSetNameWithYear(ExpansionSet exp) { + Calendar cal = Calendar.getInstance(); + cal.setTime(exp.getReleaseDate()); + String year = String.valueOf(cal.get(Calendar.YEAR)); + + if (!exp.getName().contains(year)) { + return exp.getName() + " (" + year + ")"; + } else { + return exp.getName(); + } + } + + private ExpansionSet findSetByNameWithYear(String name) { + return Sets.getInstance().values().stream() + .filter(exp -> getSetNameWithYear(exp).equals(name)) + .findFirst() + .orElse(null); + } + private Object[] getSetsForCurrentImageSource() { // Set the available sets to the combo box - ArrayList supportedSets = cardImageSource.getSupportedSets(); + ArrayList supportedSets = selectedSource.getSupportedSets(); List setNames = new ArrayList<>(); - if (supportedSets != null) { - setNames.add(ALL_IMAGES); - setNames.add(ALL_STANDARD_IMAGES); - } - if (cardImageSource.isTokenSource()) { + + // multiple sets selection + setNames.add(ALL_IMAGES); + setNames.add(ALL_MODERN_IMAGES); + setNames.add(ALL_STANDARD_IMAGES); + if (selectedSource.isTokenSource()) { setNames.add(ALL_TOKENS); } - if (supportedSets != null) { - for (String setCode : supportedSets) { - ExpansionSet expansionSet = Sets.findSet(setCode); - if (expansionSet != null) { - setNames.add(expansionSet.getName()); - } else { - logger.warn("Source: " + cardImageSource.getSourceName() + ": Expansion set for code " + setCode + " not found in xmage sets!"); - } - } - } + // single set selection + Collection dbSets = Sets.getInstance().values(); + Collection comboSets = dbSets.stream() + .filter(exp -> supportedSets.contains(exp.getCode())) + .sorted(Comparator.comparing(ExpansionSet::getReleaseDate).reversed()) + .map(this::getSetNameWithYear) + .collect(Collectors.toList()); + setNames.addAll(comboSets); + if (setNames.isEmpty()) { - logger.error("Source " + cardImageSource.getSourceName() + " creates no selectable items."); - setNames.add("not avalable"); + logger.error("Source " + selectedSource.getSourceName() + " creates no selectable items."); + setNames.add("not available"); } return setNames.toArray(new String[0]); } - private void updateCardsToDownload(String itemText) { - selectedSetCodes.clear(); - switch (itemText) { + private void reloadCardsToDownload(String selectedItem) { + // find selected sets + selectedSets.clear(); + List formatSets; + List sourceSets = selectedSource.getSupportedSets(); + switch (selectedItem) { + case ALL_IMAGES: - if (cardImageSource.getSupportedSets() == null) { - selectedSetCodes = cardImageSource.getSupportedSets(); - } else { - selectedSetCodes.addAll(cardImageSource.getSupportedSets()); - } + selectedSets.addAll(selectedSource.getSupportedSets()); break; + case ALL_STANDARD_IMAGES: - List standardSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD); - for (String setCode : cardImageSource.getSupportedSets()) { - if (standardSets.contains(setCode)) { - selectedSetCodes.add(setCode); - } else { - logger.debug("Set code " + setCode + " from download source " + cardImageSource.getSourceName()); - } - } + formatSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD); + formatSets.stream() + .filter(sourceSets::contains) + .forEachOrdered(selectedSets::add); break; + + case ALL_MODERN_IMAGES: + formatSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.MODERN); + formatSets.stream() + .filter(sourceSets::contains) + .forEachOrdered(selectedSets::add); + break; + case ALL_TOKENS: break; + default: - int nonSetEntries = 0; - if (cardImageSource.getSupportedSets() != null) { - nonSetEntries = 2; + // selects one set + ExpansionSet selectedExp = findSetByNameWithYear(selectedItem); + if (selectedExp != null) { + selectedSets.add(selectedExp.getCode()); } - if (cardImageSource.isTokenSource()) { - nonSetEntries++; - } - selectedSetCodes.add(cardImageSource.getSupportedSets().get(jComboBoxSet.getSelectedIndex() - nonSetEntries)); + break; } + + // find missing cards to download cardsToDownload.clear(); int numberTokenImagesAvailable = 0; int numberCardImagesAvailable = 0; - for (CardDownloadData data : allCardsMissingImage) { + for (CardDownloadData data : cardsMissing) { if (data.isToken()) { - if (cardImageSource.isTokenSource() && cardImageSource.isImageProvided(data.getSet(), data.getName())) { + if (selectedSource.isTokenSource() && selectedSource.isImageProvided(data.getSet(), data.getName())) { numberTokenImagesAvailable++; cardsToDownload.add(data); } else { //logger.warn("Source do not support token (set " + data.getSet() + ", token " + data.getName() + ")"); } } else { - if (selectedSetCodes != null && selectedSetCodes.contains(data.getSet())) { - if (cardImageSource.isSetSupportedComplete(data.getSet()) || cardImageSource.isImageProvided(data.getSet(), data.getName())) { + if (selectedSets != null && selectedSets.contains(data.getSet())) { + if (selectedSource.isSetSupportedComplete(data.getSet()) || selectedSource.isImageProvided(data.getSet(), data.getName())) { numberCardImagesAvailable++; cardsToDownload.add(data); } @@ -363,24 +327,28 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab updateProgressText(numberCardImagesAvailable, numberTokenImagesAvailable); } - private void comboBoxSetItemSelected(ItemEvent event) { + private void comboboxSetSelected(ItemEvent event) { // Update the cards to download related to the selected set - updateCardsToDownload(event.getItem().toString()); + reloadCardsToDownload(event.getItem().toString()); } private void updateProgressText(int cardCount, int tokenCount) { - missingTokens = 0; - for (CardDownloadData card : allCardsMissingImage) { + missingTokensCount = 0; + for (CardDownloadData card : cardsMissing) { if (card.isToken()) { - missingTokens++; + missingTokensCount++; } } - missingCards = allCardsMissingImage.size() - missingTokens; - jLabelAllMissing.setText("Missing: " + missingCards + " card images / " + missingTokens + " token images"); + missingCardsCount = cardsMissing.size() - missingTokensCount; + uiDialog.setCurrentInfo("Missing: " + missingCardsCount + " card images / " + missingTokensCount + " token images"); int imageSum = cardCount + tokenCount; - float mb = (imageSum * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format(cardIndex == imageSum ? "%d of %d (%d cards/%d tokens) image downloads finished! Please close!" - : "%d of %d (%d cards/%d tokens) image downloads finished! Please wait! [%.1f Mb]", 0, imageSum, cardCount, tokenCount, mb)); + float mb = (imageSum * selectedSource.getAverageSize()) / 1024; + uiDialog.getProgressBar().setString(String.format( + cardIndex == imageSum + ? "%d of %d (%d cards/%d tokens) image downloads finished! Please close!" + : "%d of %d (%d cards/%d tokens) image downloads finished! Please wait! [%.1f Mb]", + 0, imageSum, cardCount, tokenCount, mb + )); } private static String createDownloadName(CardInfo card) { @@ -479,8 +447,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab public static ArrayList getTokenCardUrls() throws RuntimeException { ArrayList list = new ArrayList<>(); - InputStream in = DownloadPictures.class - .getClassLoader().getResourceAsStream("card-pictures-tok.txt"); + InputStream in = DownloadPicturesService.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt"); if (in == null) { logger.error("resources input stream is null"); @@ -545,7 +512,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } catch (Exception ex) { logger.error(ex); - throw new RuntimeException("DownloadPictures : readFile() error"); + throw new RuntimeException("DownloadPicturesService : readFile() error"); } return list; } @@ -581,7 +548,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab Integer port = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_PORT, "80")); p = new Proxy(type, new InetSocketAddress(address, port)); } catch (Exception ex) { - throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex); + throw new RuntimeException("Gui_DownloadPicturesService : error 1 - " + ex); } } @@ -589,11 +556,13 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab HashSet ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); update(0, cardsToDownload.size()); - logger.info("Started download of " + cardsToDownload.size() + " images from source: " + cardImageSource.getSourceName()); + logger.info("Started download of " + cardsToDownload.size() + + " images from source: " + selectedSource.getSourceName() + + ", language: " + selectedSource.getCurrentLanguage().getCode()); int numberOfThreads = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_THREADS, "10")); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); - for (int i = 0; i < cardsToDownload.size() && !cancel; i++) { + for (int i = 0; i < cardsToDownload.size() && !this.getNeedCancel(); i++) { try { CardDownloadData card = cardsToDownload.get(i); @@ -606,24 +575,24 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (!"0".equals(card.getCollectorId())) { continue; } - urls = cardImageSource.generateTokenUrl(card); + urls = selectedSource.generateTokenUrl(card); } else { - urls = cardImageSource.generateURL(card); + urls = selectedSource.generateURL(card); } if (urls == null) { - String imageRef = cardImageSource.getNextHttpImageUrl(); - String fileName = cardImageSource.getFileForHttpImage(imageRef); + String imageRef = selectedSource.getNextHttpImageUrl(); + String fileName = selectedSource.getFileForHttpImage(imageRef); if (imageRef != null && fileName != null) { - imageRef = cardImageSource.getSourceName() + imageRef; + imageRef = selectedSource.getSourceName() + imageRef; try { - card.setToken(cardImageSource.isTokenSource()); - Runnable task = new DownloadTask(card, imageRef, fileName, cardImageSource.getTotalImages()); + card.setToken(selectedSource.isTokenSource()); + Runnable task = new DownloadTask(card, imageRef, fileName, selectedSource.getTotalImages()); executor.execute(task); } catch (Exception ex) { } - } else if (cardImageSource.getTotalImages() == -1) { - logger.info("Image not available on " + cardImageSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); + } else if (selectedSource.getTotalImages() == -1) { + logger.info("Image not available on " + selectedSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); synchronized (sync) { update(cardIndex + 1, cardsToDownload.size()); } @@ -653,11 +622,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } finally { // } - closeButton.setText("Close"); - updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); + reloadCardsToDownload(uiDialog.getSetsCombo().getSelectedItem().toString()); } - static String convertStreamToString(java.io.InputStream is) { + static String convertStreamToString(InputStream is) { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; } @@ -692,7 +660,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab @Override public void run() { - if (cancel) { + if (DownloadPicturesService.getInstance().getNeedCancel()) { synchronized (sync) { update(cardIndex + 1, count); } @@ -773,12 +741,12 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab URL url = new URL(currentUrl); // on download cancel need to stop - if (cancel) { + if (DownloadPicturesService.getInstance().getNeedCancel()) { return; } // download - cardImageSource.doPause(url.getPath()); + selectedSource.doPause(url.getPath()); httpConn = url.openConnection(p); httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2"); httpConn.connect(); @@ -819,7 +787,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab int len; while ((len = in.read(buf)) != -1) { // user cancelled - if (cancel) { + if (DownloadPicturesService.getInstance().getNeedCancel()) { // stop download, save current state and exit TFile archive = destFile.getTopLevelArchive(); ///* not need to unmout/close - it's auto action @@ -885,12 +853,12 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab this.cardIndex = card; if (cardIndex < count) { - float mb = ((count - card) * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format("%d of %d image downloads finished! Please wait! [%.1f Mb]", + float mb = ((count - card) * selectedSource.getAverageSize()) / 1024; + uiDialog.getProgressBar().setString(String.format("%d of %d image downloads finished! Please wait! [%.1f Mb]", card, count, mb)); } else { List remainingCards = Collections.synchronizedList(new ArrayList<>()); - DownloadPictures.this.allCardsMissingImage.parallelStream().forEach(cardDownloadData -> { + DownloadPicturesService.this.cardsMissing.parallelStream().forEach(cardDownloadData -> { TFile file = new TFile(CardImageUtils.buildImagePathToCard(cardDownloadData)); if (!file.exists()) { remainingCards.add(cardDownloadData); @@ -898,16 +866,16 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab }); // remove the cards not downloaded to get the siccessfull downloaded cards - DownloadPictures.this.cardsToDownload.removeAll(remainingCards); - DownloadPictures.this.allCardsMissingImage.removeAll(DownloadPictures.this.cardsToDownload); + DownloadPicturesService.this.cardsToDownload.removeAll(remainingCards); + DownloadPicturesService.this.cardsMissing.removeAll(DownloadPicturesService.this.cardsToDownload); count = remainingCards.size(); if (count == 0) { - bar.setString("0 images remaining! Please close!"); + uiDialog.getProgressBar().setString("0 images remaining! Please close!"); } else { -// bar.setString(String.format("%d cards remaining! Please choose another source!", count)); - startDownloadButton.setEnabled(true); + //bar.setString(String.format("%d cards remaining! Please choose another source!", count)); + uiDialog.getStartButton().setEnabled(true); } } } @@ -916,22 +884,21 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } -class LoadMissingCardData implements Runnable { +class LoadMissingCardDataNew implements Runnable { - private static DownloadPictures downloadPictures; + private static DownloadPicturesService downloadPicturesService; - public LoadMissingCardData(DownloadPictures downloadPictures) { - LoadMissingCardData.downloadPictures = downloadPictures; + public LoadMissingCardDataNew(DownloadPicturesService downloadPicturesService) { + this.downloadPicturesService = downloadPicturesService; } @Override public void run() { - downloadPictures.setAllMissingCards(); + downloadPicturesService.setAllMissingCards(); } public static void main() { - - (new Thread(new LoadMissingCardData(downloadPictures))).start(); + (new Thread(new LoadMissingCardDataNew(downloadPicturesService))).start(); } } From 110f8a20abf19448786108edf1c01a411c9979db Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 18 Dec 2018 18:06:32 +0400 Subject: [PATCH 07/11] UI improved for mage dialogs: * added working popup hints for buttons and cards while user in choose mode; * fixed wrong windows position after tray icon clicks or mouse moves; * added big combobox's popups support (now users can select/choose items from outer space); --- .../java/mage/client/dialog/MageDialog.java | 84 ++++++++++++------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java b/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java index 513f4ede22..334422f1bb 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java @@ -1,31 +1,19 @@ - - - /* - * MageDialog.java - * - * Created on 15-Dec-2009, 10:28:27 PM - */ package mage.client.dialog; -import java.awt.AWTEvent; -import java.awt.ActiveEvent; -import java.awt.Component; -import java.awt.EventQueue; -import java.awt.KeyboardFocusManager; -import java.awt.MenuComponent; -import java.awt.TrayIcon; +import mage.client.MageFrame; +import mage.client.util.SettingsManager; +import mage.client.util.gui.GuiDisplayUtil; +import org.apache.log4j.Logger; + +import javax.swing.*; +import java.awt.*; import java.awt.event.InvocationEvent; import java.awt.event.MouseEvent; import java.beans.PropertyVetoException; import java.lang.reflect.InvocationTargetException; import java.util.logging.Level; -import javax.swing.*; - -import mage.client.MageFrame; -import org.apache.log4j.Logger; /** - * * @author BetaSteward_at_googlemail.com */ public class MageDialog extends javax.swing.JInternalFrame { @@ -75,7 +63,7 @@ public class MageDialog extends javax.swing.JInternalFrame { this.toFront(); - if (modal){ + if (modal) { startModal(); } } @@ -105,6 +93,7 @@ public class MageDialog extends javax.swing.JInternalFrame { } private synchronized void startModal() { + // modal loop -- all mouse events must be ignored by other windows try { if (SwingUtilities.isEventDispatchThread()) { EventQueue theQueue = getToolkit().getSystemEventQueue(); @@ -115,18 +104,46 @@ public class MageDialog extends javax.swing.JInternalFrame { // https://github.com/magefree/mage/issues/584 - Let's hope this will fix the Linux window problem if (event.getSource() != null && event.getSource() instanceof TrayIcon && !(event instanceof InvocationEvent)) { - return; + dispatch = false; + //return; // JayDi85: users can move mouse over try icon to disable modal mode (it's a bug but can be used in the future) } + + // ignore mouse events outside from panel, only drag and move allowed -- as example: + // combobox's popup will be selectable outside + // cards and button hints will be works + Component popupComponent = null; + MouseEvent popupEvent = null; if (event instanceof MouseEvent && event.getSource() instanceof Component) { MouseEvent e = (MouseEvent) event; MouseEvent m = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, this); - if (!this.contains(m.getPoint()) && e.getID() != MouseEvent.MOUSE_DRAGGED) { - dispatch = false; + + // disable all outer events (except some actions) + if (!this.contains(m.getPoint())) { + boolean allowedEvent = false; + + // need any mouse move (for hints) + if (e.getID() == MouseEvent.MOUSE_DRAGGED || e.getID() == MouseEvent.MOUSE_MOVED) { + allowedEvent = true; + } + + // need popup clicks and mouse wheel (for out of bound actions) + if (!allowedEvent) { + popupComponent = SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY()); // show root component (popups creates at root) + if (popupComponent != null && popupComponent.getClass().getName().contains("BasicComboPopup")) { + popupEvent = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, popupComponent); + allowedEvent = true; + } + } + + dispatch = allowedEvent; } } if (dispatch) { - if (event instanceof ActiveEvent) { + if (popupEvent != null) { + // process outer popup events, it's must be FIRST check + popupComponent.dispatchEvent(popupEvent); + } else if (event instanceof ActiveEvent) { ((ActiveEvent) event).dispatch(); } else if (source instanceof Component) { ((Component) source).dispatchEvent(event); @@ -174,14 +191,21 @@ public class MageDialog extends javax.swing.JInternalFrame { java.util.logging.Logger.getLogger(MageDialog.class.getName()).log(Level.SEVERE, "setClosed(false) failed", ex); } MageFrame.getDesktop().remove(this); + } + public void makeWindowCentered() { + makeWindowCentered(this, getWidth(), getHeight()); + } + + public static void makeWindowCentered(Component component, int width, int height) { + Point centered = SettingsManager.instance.getComponentPosition(width, height); + component.setLocation(centered.x, centered.y); + GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, component); } /** * Used to set a tooltip text on icon and titel bar * - * used in {@link ExileZoneDialog} and {@link ShowCardsDialog} - * * @param text */ public void setTitelBarToolTip(final String text) { @@ -209,12 +233,12 @@ public class MageDialog extends javax.swing.JInternalFrame { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 394, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 394, Short.MAX_VALUE) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 274, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 274, Short.MAX_VALUE) ); pack(); From 8df4ba3871317212db16c7a00317d13415cda5b1 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 19 Dec 2018 05:19:29 +0400 Subject: [PATCH 08/11] UI: added images re-download mode and improved dialog UX; --- .../client/dialog/DownloadImagesDialog.form | 50 +++++- .../client/dialog/DownloadImagesDialog.java | 56 ++++++- .../card/images/DownloadPicturesService.java | 158 +++++++++++------- 3 files changed, 189 insertions(+), 75 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form index da0aaa4ea0..a4d0a72b56 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form @@ -128,7 +128,7 @@
- + @@ -349,22 +349,56 @@ - + + - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java index 130a5799fa..1f9b55f882 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java @@ -8,6 +8,8 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; +import java.util.HashMap; +import java.util.Map; /** * @author JayDi85 @@ -19,6 +21,7 @@ public class DownloadImagesDialog extends MageDialog { private Dimension sizeModeMessageOnly; private Dimension sizeModeMessageAndControls; + private Map actionsControlStates = new HashMap<>(); /** @@ -28,6 +31,9 @@ public class DownloadImagesDialog extends MageDialog { initComponents(); this.setModal(true); + // fix for panelInfo (it's resets aligmentX after netbeans designer opened) + panelInfo.setAlignmentX(CENTER_ALIGNMENT); + // save default sizes // this.sizeModeMessageAndControls = new Dimension(580, 330); // dialog -> properties -> designer size @@ -105,11 +111,36 @@ public class DownloadImagesDialog extends MageDialog { return this.progress; } + public JCheckBox getRedownloadCheckbox() { + return this.checkboxRedownload; + } + public void showLanguagesSupport(boolean haveSupport) { labelLanguage.setEnabled(haveSupport); comboLanguage.setEnabled(haveSupport); } + private void enableActionControl(boolean enable, Component comp) { + if (enable) { + // restore last enable state + comp.setEnabled(actionsControlStates.getOrDefault(comp, true)); + } else { + // save enable state and disable it + actionsControlStates.putIfAbsent(comp, comp.isEnabled()); + comp.setEnabled(false); + } + } + + public void enableActionControls(boolean enable) { + // restrict user actions while downloading/processing (all buttons, comboboxes and edits) + enableActionControl(enable, tabsList); + enableActionControl(enable, comboSource); + enableActionControl(enable, comboSets); + enableActionControl(enable, buttonSearchSet); + enableActionControl(enable, comboLanguage); + enableActionControl(enable, checkboxRedownload); + } + private void setTabTitle(int tabIndex, String title, String iconResourceName) { // tab caption with left sided icon // https://stackoverflow.com/questions/1782224/jtabbedpane-icon-on-left-side-of-tabs @@ -186,7 +217,9 @@ public class DownloadImagesDialog extends MageDialog { comboSets = new javax.swing.JComboBox<>(); fillerMode1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); buttonSearchSet = new javax.swing.JButton(); - fillerMode = new javax.swing.Box.Filler(new java.awt.Dimension(130, 0), new java.awt.Dimension(130, 0), new java.awt.Dimension(130, 32767)); + panelRedownload = new javax.swing.JPanel(); + checkboxRedownload = new javax.swing.JCheckBox(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 3), new java.awt.Dimension(32767, 5)); fillerMain1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 10), new java.awt.Dimension(0, 10), new java.awt.Dimension(32767, 10)); panelProgress = new javax.swing.JPanel(); fillerProgress1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); @@ -216,10 +249,11 @@ public class DownloadImagesDialog extends MageDialog { tabMain.setLayout(new javax.swing.BoxLayout(tabMain, javax.swing.BoxLayout.Y_AXIS)); + panelInfo.setAlignmentX(0.5F); panelInfo.setLayout(new javax.swing.BoxLayout(panelInfo, javax.swing.BoxLayout.Y_AXIS)); panelInfo.add(fillerInfo1); - labelInfo.setText("Missing: 12345 card images / 789 token images"); + labelInfo.setText("Missing stats: 12345 card images / 789 token images"); labelInfo.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 7, 0, 0)); panelInfo.add(labelInfo); panelInfo.add(fillerInfo2); @@ -297,7 +331,19 @@ public class DownloadImagesDialog extends MageDialog { panelModeInner.add(panelModeSelect); panelMode.add(panelModeInner); - panelMode.add(fillerMode); + + panelRedownload.setAlignmentX(0.0F); + panelRedownload.setMaximumSize(new java.awt.Dimension(130, 32767)); + panelRedownload.setMinimumSize(new java.awt.Dimension(130, 30)); + panelRedownload.setPreferredSize(new java.awt.Dimension(130, 100)); + panelRedownload.setLayout(new java.awt.BorderLayout()); + + checkboxRedownload.setText("Re-download selected images"); + checkboxRedownload.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); + panelRedownload.add(checkboxRedownload, java.awt.BorderLayout.CENTER); + panelRedownload.add(filler1, java.awt.BorderLayout.PAGE_END); + + panelMode.add(panelRedownload); tabMain.add(panelMode); tabMain.add(fillerMain1); @@ -363,15 +409,16 @@ public class DownloadImagesDialog extends MageDialog { private javax.swing.JButton buttonCancel; private javax.swing.JButton buttonOK; private javax.swing.JButton buttonSearchSet; + private javax.swing.JCheckBox checkboxRedownload; private javax.swing.JComboBox comboLanguage; private javax.swing.JComboBox comboSets; private javax.swing.JComboBox comboSource; + private javax.swing.Box.Filler filler1; private javax.swing.Box.Filler fillerGlobal1; private javax.swing.Box.Filler fillerInfo1; private javax.swing.Box.Filler fillerInfo2; private javax.swing.Box.Filler fillerMain1; private javax.swing.Box.Filler fillerMain2; - private javax.swing.Box.Filler fillerMode; private javax.swing.Box.Filler fillerMode1; private javax.swing.Box.Filler fillerProgress1; private javax.swing.Box.Filler fillerProgress2; @@ -388,6 +435,7 @@ public class DownloadImagesDialog extends MageDialog { private javax.swing.JPanel panelModeInner; private javax.swing.JPanel panelModeSelect; private javax.swing.JPanel panelProgress; + private javax.swing.JPanel panelRedownload; private javax.swing.JPanel panelSource; private javax.swing.JPanel panelSourceLeft; private javax.swing.JPanel panelSourceRight; diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java index 47b669ef2a..a173e1845e 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java @@ -22,10 +22,12 @@ import org.mage.plugins.card.properties.SettingsManager; import org.mage.plugins.card.utils.CardImageUtils; import javax.swing.*; +import java.awt.*; import java.awt.event.ItemEvent; import java.io.*; import java.net.*; import java.nio.file.AccessDeniedException; +import java.util.List; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -34,6 +36,9 @@ import java.util.stream.Collectors; import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; +/** + * @author JayDi85 + */ public class DownloadPicturesService extends DefaultBoundedRangeModel implements Runnable { // don't forget to remove new sets from ignore.urls to download (properties file in resources) @@ -49,8 +54,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements private boolean needCancel; private int cardIndex; + private List cardsAll; private List cardsMissing; - private List cardsToDownload; + private List cardsDownloadQueue; private int missingCardsCount = 0; private int missingTokensCount = 0; @@ -120,7 +126,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements public DownloadPicturesService(JFrame frame) { // init service and dialog - cardsToDownload = new ArrayList<>(); + cardsAll = Collections.synchronizedList(new ArrayList<>()); + cardsMissing = Collections.synchronizedList(new ArrayList<>()); + cardsDownloadQueue = Collections.synchronizedList(new ArrayList<>()); uiDialog = new DownloadImagesDialog(); // MESSAGE @@ -136,11 +144,16 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } }); - // TODO: LANGUAGES + // LANGUAGES uiDialog.getLaunguagesCombo().setModel(new DefaultComboBoxModel(CardLanguage.values())); uiDialog.getLaunguagesCombo().setSelectedItem(PreferencesDialog.getPrefImagesLanguage()); reloadLanguagesForSelectedSource(); + // REDOWNLOAD + uiDialog.getRedownloadCheckbox().setSelected(false); + uiDialog.getRedownloadCheckbox().addItemListener(this::checkboxRedowloadChanged); + + // SETS (fills after source and language select) //uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel(DownloadSources.values())); uiDialog.getSetsCombo().addItemListener((ItemEvent event) -> { @@ -159,8 +172,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } // run - new Thread(DownloadPicturesService.this).start(); + uiDialog.enableActionControls(false); uiDialog.getStartButton().setEnabled(false); + new Thread(DownloadPicturesService.this).start(); }); // BUTTON CANCEL @@ -172,14 +186,19 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements uiDialog.showDownloadControls(false); } - public void setAllMissingCards() { + public void findMissingCards() { + updateAndViewMessage("Loading..."); + this.cardsAll.clear(); + this.cardsMissing.clear(); + this.cardsDownloadQueue.clear(); + updateAndViewMessage("Loading cards list..."); - List cards = CardRepository.instance.findCards(new CardCriteria()); + this.cardsAll = Collections.synchronizedList(CardRepository.instance.findCards(new CardCriteria())); - updateAndViewMessage("Find missing images..."); - this.cardsMissing = getNeededCards(cards); + updateAndViewMessage("Finding missing images..."); + this.cardsMissing = prepareMissingCards(this.cardsAll, uiDialog.getRedownloadCheckbox().isSelected()); - updateAndViewMessage("Find available sets from selected source..."); + updateAndViewMessage("Finding available sets from selected source..."); this.uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); reloadCardsToDownload(this.uiDialog.getSetsCombo().getSelectedItem().toString()); @@ -304,14 +323,14 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } // find missing cards to download - cardsToDownload.clear(); + cardsDownloadQueue.clear(); int numberTokenImagesAvailable = 0; int numberCardImagesAvailable = 0; for (CardDownloadData data : cardsMissing) { if (data.isToken()) { if (selectedSource.isTokenSource() && selectedSource.isImageProvided(data.getSet(), data.getName())) { numberTokenImagesAvailable++; - cardsToDownload.add(data); + cardsDownloadQueue.add(data); } else { //logger.warn("Source do not support token (set " + data.getSet() + ", token " + data.getName() + ")"); } @@ -319,7 +338,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements if (selectedSets != null && selectedSets.contains(data.getSet())) { if (selectedSource.isSetSupportedComplete(data.getSet()) || selectedSource.isImageProvided(data.getSet(), data.getName())) { numberCardImagesAvailable++; - cardsToDownload.add(data); + cardsDownloadQueue.add(data); } } } @@ -332,6 +351,17 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements reloadCardsToDownload(event.getItem().toString()); } + private void checkboxRedowloadChanged(ItemEvent event) { + MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR)); + try { + this.cardsMissing.clear(); + this.cardsMissing = prepareMissingCards(this.cardsAll, uiDialog.getRedownloadCheckbox().isSelected()); + reloadCardsToDownload(uiDialog.getSetsCombo().getSelectedItem().toString()); + } finally { + MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + } + private void updateProgressText(int cardCount, int tokenCount) { missingTokensCount = 0; for (CardDownloadData card : cardsMissing) { @@ -340,6 +370,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } } missingCardsCount = cardsMissing.size() - missingTokensCount; + uiDialog.setCurrentInfo("Missing: " + missingCardsCount + " card images / " + missingTokensCount + " token images"); int imageSum = cardCount + tokenCount; float mb = (imageSum * selectedSource.getAverageSize()) / 1024; @@ -356,16 +387,10 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements return className.substring(className.lastIndexOf('.') + 1); } - private static List getNeededCards(List allCards) { - - /** - * read all card names and urls - */ + private static List prepareMissingCards(List allCards, boolean redownloadMode) { HashSet ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); - /** - * get filter for Standard Type 2 cards - */ + // get filter for Standard Type 2 cards Set type2SetsFilter = new HashSet<>(); List constructedFormats = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD); if (constructedFormats != null && !constructedFormats.isEmpty()) { @@ -374,6 +399,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements logger.warn("No formats defined. Try connecting to a server first!"); } + // prepare checking list List allCardsUrls = Collections.synchronizedList(new ArrayList<>()); try { allCards.parallelStream().forEach(card -> { @@ -423,26 +449,28 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements logger.info("Card was not selected: " + card.getName()); } }); + allCardsUrls.addAll(getTokenCardUrls()); } catch (Exception e) { logger.error(e); } - /** - * check to see which cards we already have - */ + // find missing files List cardsToDownload = Collections.synchronizedList(new ArrayList<>()); allCardsUrls.parallelStream().forEach(card -> { - File file = new TFile(CardImageUtils.buildImagePathToCard(card)); - logger.debug(card.getName() + " (is_token=" + card.isToken() + "). Image is here:" + file.getAbsolutePath() + " (exists=" + file.exists() + ')'); - if (!file.exists()) { - logger.debug("Missing: " + file.getAbsolutePath()); - // logger.info("Missing image: " + (card.isToken() ? "TOKEN " : "CARD ") + card.getSet() + "/" + card.getName() + " type: " + card.getType()); + if (redownloadMode) { + // need all cards cardsToDownload.add(card); + } else { + // need missing cards + File file = new TFile(CardImageUtils.buildImagePathToCard(card)); + if (!file.exists()) { + cardsToDownload.add(card); + } } }); - return new ArrayList<>(cardsToDownload); + return Collections.synchronizedList(new ArrayList<>(cardsToDownload)); } public static ArrayList getTokenCardUrls() throws RuntimeException { @@ -555,22 +583,20 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements if (p != null) { HashSet ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); - update(0, cardsToDownload.size()); - logger.info("Started download of " + cardsToDownload.size() - + " images from source: " + selectedSource.getSourceName() + update(0, cardsDownloadQueue.size()); + logger.info("Started download of " + cardsDownloadQueue.size() + " images" + + " from source: " + selectedSource.getSourceName() + ", language: " + selectedSource.getCurrentLanguage().getCode()); int numberOfThreads = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_THREADS, "10")); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); - for (int i = 0; i < cardsToDownload.size() && !this.getNeedCancel(); i++) { + for (int i = 0; i < cardsDownloadQueue.size() && !this.getNeedCancel(); i++) { try { - - CardDownloadData card = cardsToDownload.get(i); + CardDownloadData card = cardsDownloadQueue.get(i); logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')'); CardImageUrls urls; - if (ignoreUrls.contains(card.getSet()) || card.isToken()) { if (!"0".equals(card.getCollectorId())) { continue; @@ -594,18 +620,18 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } else if (selectedSource.getTotalImages() == -1) { logger.info("Image not available on " + selectedSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); synchronized (sync) { - update(cardIndex + 1, cardsToDownload.size()); + update(cardIndex + 1, cardsDownloadQueue.size()); } } } else { - Runnable task = new DownloadTask(card, urls, cardsToDownload.size()); + Runnable task = new DownloadTask(card, urls, cardsDownloadQueue.size()); executor.execute(task); } - } catch (Exception ex) { logger.error(ex, ex); } } + executor.shutdown(); while (!executor.isTerminated()) { try { @@ -614,6 +640,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } } } + try { TVFS.umount(); } catch (FsSyncException e) { @@ -622,6 +649,8 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } finally { // } + + // stop reloadCardsToDownload(uiDialog.getSetsCombo().getSelectedItem().toString()); } @@ -638,10 +667,6 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements private final String actualFilename; private final boolean useSpecifiedPaths; - DownloadTask(CardDownloadData card, String baseUrl, int count) { - this(card, new CardImageUrls(baseUrl, null), count); - } - DownloadTask(CardDownloadData card, CardImageUrls urls, int count) { this.card = card; this.urls = urls; @@ -704,20 +729,23 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } // FILE already exists (in zip or in dir) + // don't use, images can be re-downloaded + /* if (destFile.exists()) { synchronized (sync) { update(cardIndex + 1, count); } return; } + */ - // zip can't be read + // check zip access TFile testArchive = destFile.getTopLevelArchive(); if (testArchive != null && testArchive.exists()) { try { testArchive.list(); } catch (Exception e) { - logger.error("Error reading archive, may be it was corrapted. Try to delete it: " + testArchive.toString()); + logger.error("Error reading archive, it's can be corrupted. Try to delete it: " + testArchive.toString()); synchronized (sync) { update(cardIndex + 1, count); @@ -849,34 +877,38 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements } } - private void update(int card, int count) { - this.cardIndex = card; + private void update(int lastCardIndex, int needDownloadCount) { + this.cardIndex = lastCardIndex; - if (cardIndex < count) { - float mb = ((count - card) * selectedSource.getAverageSize()) / 1024; + if (cardIndex < needDownloadCount) { + // downloading + float mb = ((needDownloadCount - lastCardIndex) * selectedSource.getAverageSize()) / 1024; uiDialog.getProgressBar().setString(String.format("%d of %d image downloads finished! Please wait! [%.1f Mb]", - card, count, mb)); + lastCardIndex, needDownloadCount, mb)); } else { - List remainingCards = Collections.synchronizedList(new ArrayList<>()); + // finished + List downloadedCards = Collections.synchronizedList(new ArrayList<>()); DownloadPicturesService.this.cardsMissing.parallelStream().forEach(cardDownloadData -> { TFile file = new TFile(CardImageUtils.buildImagePathToCard(cardDownloadData)); - if (!file.exists()) { - remainingCards.add(cardDownloadData); + if (file.exists()) { + downloadedCards.add(cardDownloadData); } }); - // remove the cards not downloaded to get the siccessfull downloaded cards - DownloadPicturesService.this.cardsToDownload.removeAll(remainingCards); - DownloadPicturesService.this.cardsMissing.removeAll(DownloadPicturesService.this.cardsToDownload); + // remove all downloaded cards, missing must be remains + this.cardsDownloadQueue.removeAll(downloadedCards); + this.cardsMissing.removeAll(downloadedCards); - count = remainingCards.size(); - - if (count == 0) { - uiDialog.getProgressBar().setString("0 images remaining! Please close!"); + if (this.cardsDownloadQueue.size() == 0) { + // stop download + uiDialog.getProgressBar().setString("0 images remaining. Please close."); } else { - //bar.setString(String.format("%d cards remaining! Please choose another source!", count)); - uiDialog.getStartButton().setEnabled(true); + // try download again } + + this.uiDialog.getRedownloadCheckbox().setSelected(false); + uiDialog.enableActionControls(true); + uiDialog.getStartButton().setEnabled(true); } } @@ -894,7 +926,7 @@ class LoadMissingCardDataNew implements Runnable { @Override public void run() { - downloadPicturesService.setAllMissingCards(); + downloadPicturesService.findMissingCards(); } public static void main() { From af5e48668e516229e1bf065f871491e1d1a5d9a1 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 21 Dec 2018 17:31:55 +0400 Subject: [PATCH 09/11] UI: added cancel button for images downloading startup; --- .../client/dialog/DownloadImagesDialog.form | 12 ++++++++ .../client/dialog/DownloadImagesDialog.java | 30 +++++++++++++++---- .../card/images/DownloadPicturesService.java | 3 +- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form index a4d0a72b56..794e733d89 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.form @@ -58,6 +58,18 @@ + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java index 1f9b55f882..84f8e0d6f6 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java @@ -39,7 +39,7 @@ public class DownloadImagesDialog extends MageDialog { this.sizeModeMessageAndControls = new Dimension(580, 330); // dialog -> properties -> designer size // this.sizeModeMessageOnly = new Dimension(this.sizeModeMessageAndControls.getSize()); - sizeModeMessageOnly.height = 25 * 3; + sizeModeMessageOnly.height = 25 * 4; sizeModeMessageOnly.width = sizeModeMessageOnly.width / 2; // Close the dialog when Esc is pressed @@ -106,6 +106,10 @@ public class DownloadImagesDialog extends MageDialog { public JButton getCancelButton() { return this.buttonCancel; } + + public JButton getStopButton() { + return this.buttonStop; + } public JProgressBar getProgressBar() { return this.progress; @@ -157,6 +161,7 @@ public class DownloadImagesDialog extends MageDialog { // - only message; // - message + download controls and buttons this.panelGlobal.setVisible(true); + this.buttonStop.setVisible(!needToShow); // stop button only for loading mode this.tabsList.setVisible(needToShow); this.panelCommands.setVisible(needToShow); @@ -196,6 +201,7 @@ public class DownloadImagesDialog extends MageDialog { panelGlobal = new javax.swing.JPanel(); fillerGlobal1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); labelGlobal = new javax.swing.JLabel(); + buttonStop = new javax.swing.JButton(); fillerglobal2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5)); tabsList = new javax.swing.JTabbedPane(); tabMain = new javax.swing.JPanel(); @@ -241,6 +247,16 @@ public class DownloadImagesDialog extends MageDialog { labelGlobal.setText("Initializing image download..."); labelGlobal.setAlignmentX(0.5F); panelGlobal.add(labelGlobal); + + buttonStop.setText("Cancel"); + buttonStop.setAlignmentX(0.5F); + buttonStop.setPreferredSize(new java.awt.Dimension(65, 30)); + buttonStop.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonStopActionPerformed(evt); + } + }); + panelGlobal.add(buttonStop); panelGlobal.add(fillerglobal2); getContentPane().add(panelGlobal, java.awt.BorderLayout.NORTH); @@ -249,7 +265,6 @@ public class DownloadImagesDialog extends MageDialog { tabMain.setLayout(new javax.swing.BoxLayout(tabMain, javax.swing.BoxLayout.Y_AXIS)); - panelInfo.setAlignmentX(0.5F); panelInfo.setLayout(new javax.swing.BoxLayout(panelInfo, javax.swing.BoxLayout.Y_AXIS)); panelInfo.add(fillerInfo1); @@ -272,7 +287,7 @@ public class DownloadImagesDialog extends MageDialog { panelSourceLeft.add(labelSource); comboSource.setMaximumRowCount(10); - comboSource.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); + comboSource.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); comboSource.setMinimumSize(new java.awt.Dimension(300, 20)); comboSource.setPreferredSize(new java.awt.Dimension(400, 25)); panelSourceLeft.add(comboSource); @@ -289,7 +304,7 @@ public class DownloadImagesDialog extends MageDialog { panelSourceRight.add(labelLanguage); comboLanguage.setMaximumRowCount(20); - comboLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); + comboLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); comboLanguage.setPreferredSize(new java.awt.Dimension(90, 25)); panelSourceRight.add(comboLanguage); @@ -312,7 +327,7 @@ public class DownloadImagesDialog extends MageDialog { panelModeSelect.setLayout(new javax.swing.BoxLayout(panelModeSelect, javax.swing.BoxLayout.X_AXIS)); comboSets.setMaximumRowCount(20); - comboSets.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); + comboSets.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); comboSets.setPreferredSize(new java.awt.Dimension(373, 25)); panelModeSelect.add(comboSets); panelModeSelect.add(fillerMode1); @@ -399,6 +414,10 @@ public class DownloadImagesDialog extends MageDialog { FastSearchUtil.showFastSearchForStringComboBox(comboSets, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE); }//GEN-LAST:event_buttonSearchSetActionPerformed + private void buttonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStopActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_buttonStopActionPerformed + private void doClose(int retStatus) { returnStatus = retStatus; setVisible(false); @@ -409,6 +428,7 @@ public class DownloadImagesDialog extends MageDialog { private javax.swing.JButton buttonCancel; private javax.swing.JButton buttonOK; private javax.swing.JButton buttonSearchSet; + private javax.swing.JButton buttonStop; private javax.swing.JCheckBox checkboxRedownload; private javax.swing.JComboBox comboLanguage; private javax.swing.JComboBox comboSets; diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java index a173e1845e..29db91b289 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java @@ -177,8 +177,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements new Thread(DownloadPicturesService.this).start(); }); - // BUTTON CANCEL + // BUTTON CANCEL (dialog and loading) uiDialog.getCancelButton().addActionListener(e -> uiDialog.setVisible(false)); + uiDialog.getStopButton().addActionListener(e -> uiDialog.setVisible(false)); // PROGRESS BAR uiDialog.getProgressBar().setValue(0); From 97c9659f1e7a5960dc15ebd65db85d01c128bedf Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 21 Dec 2018 17:35:41 +0400 Subject: [PATCH 10/11] UI: fixed window download centered after startup complete --- .../src/main/java/mage/client/dialog/DownloadImagesDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java index 84f8e0d6f6..3990c565d9 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/DownloadImagesDialog.java @@ -171,6 +171,7 @@ public class DownloadImagesDialog extends MageDialog { } else { this.setWindowSize(this.sizeModeMessageOnly.width, this.sizeModeMessageOnly.height); } + this.makeWindowCentered(); //this.setLocationRelativeTo(null); // center screen //FIX // icons on tabs left side From c3ea8ddd7ac6d2bc2aad8b3ba3e1202567fc464b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 21 Dec 2018 17:53:24 +0400 Subject: [PATCH 11/11] UI: added images cache reset after downloads finish (no more xmage restart for new images); --- .../card/images/DownloadPicturesService.java | 3 ++ .../mage/plugins/card/images/ImageCache.java | 30 +++++++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java index 29db91b289..c4f4c6f024 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java @@ -653,6 +653,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements // stop reloadCardsToDownload(uiDialog.getSetsCombo().getSelectedItem().toString()); + + // reset images cache + ImageCache.clearCache(); } static String convertStreamToString(InputStream is) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index 2edf005832..a3aac320d4 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -3,15 +3,6 @@ package org.mage.plugins.card.images; import com.google.common.base.Function; import com.google.common.collect.ComputationException; import com.google.common.collect.MapMaker; -import java.awt.*; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.imageio.ImageIO; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import mage.client.util.TransformedImageCache; @@ -23,13 +14,23 @@ import org.apache.log4j.Logger; import org.mage.plugins.card.dl.sources.DirectLinksForDownload; import org.mage.plugins.card.utils.CardImageUtils; +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * This class stores ALL card images in a cache with soft values. this means * that the images may be garbage collected when they are not needed any more, * but will be kept as long as possible. - * + *

* Key format: "[cardname]#[setname]#[type]#[collectorID]#[param]" - * + *

* where param is: *

    *
  • size of image
  • @@ -228,6 +229,10 @@ public final class ImageCache { }); } + public static void clearCache() { + IMAGE_CACHE.clear(); + } + public static String getFilePath(CardView card, int width) { String key = getKey(card, card.getName(), Integer.toString(width)); boolean usesVariousArt = false; @@ -389,7 +394,7 @@ public final class ImageCache { return getImage(getKey(card, card.getName(), "")); } -// public static BufferedImage getImageFaceOriginal(CardView card) { + // public static BufferedImage getImageFaceOriginal(CardView card) { // return getFaceImage(getFaceKey(card, card.getName(), card.getExpansionSetCode())); // } public static BufferedImage getImageOriginalAlternateName(CardView card) { @@ -472,6 +477,7 @@ public final class ImageCache { // return alternateName + "#" + card.getExpansionSetCode() + "#" +card.getType()+ "#" + card.getCardNumber() + "#" // + (card.getTokenSetCode() == null ? "":card.getTokenSetCode()); // } + /** * Load image from file *