From 77df387e0606331105ef1fc2ece42b9f64394444 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Thu, 18 Jul 2024 23:04:47 +0400 Subject: [PATCH] GUI: improved pick choice (dialogs with searchable list, related to #12420): - dialog: added mana symbols and html support in headers and list; - dialog: added custom hints for each list's item (use setHintData); - dialog: added game object hint type (use object id as hint value); - dialog: added fast way to add key, value, sort and hint data (use choice.withItem()); - cheats: added commands list in popup hint; --- .../mage/client/dialog/PickChoiceDialog.java | 236 ++++++++++-------- .../org/mage/card/arcane/ManaSymbols.java | 3 +- .../src/main/java/mage/utils/SystemUtil.java | 20 +- Mage/src/main/java/mage/choices/Choice.java | 12 + .../java/mage/choices/ChoiceHintType.java | 8 +- .../main/java/mage/choices/ChoiceImpl.java | 44 +++- 6 files changed, 204 insertions(+), 119 deletions(-) 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 583b37813eb..cc03393e3a6 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java @@ -1,12 +1,5 @@ package mage.client.dialog; -import java.awt.*; -import java.awt.event.*; -import java.util.*; -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - import mage.cards.action.TransferData; import mage.choices.Choice; import mage.choices.ChoiceHintType; @@ -14,6 +7,7 @@ import mage.client.MageFrame; import mage.client.cards.BigCard; import mage.client.cards.VirtualCardInfo; import mage.client.components.MageEditorPane; +import mage.client.game.GamePanel; import mage.client.util.GUISizeHelper; import mage.client.util.gui.MageDialogState; import mage.game.command.Dungeon; @@ -21,6 +15,14 @@ import mage.view.CardView; import mage.view.DungeonView; import org.mage.card.arcane.ManaSymbols; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.*; +import java.util.List; +import java.util.*; + /** * GUI: choosing one of the list's item. Uses in game's and non game's GUI like fast search * @@ -89,11 +91,17 @@ public class PickChoiceDialog extends MageDialog { this.allItems.clear(); if (choice.isKeyChoice()) { for (Map.Entry entry : choice.getKeyChoices().entrySet()) { - this.allItems.add(new KeyValueItem(entry.getKey(), entry.getValue(), choice.getHintType())); + // default hints + String hintValue = entry.getValue(); + ChoiceHintType hintType = choice.getHintType(); + this.allItems.add(new KeyValueItem(entry.getKey(), entry.getValue(), hintValue, hintType)); } } else { for (String value : choice.getChoices()) { - this.allItems.add(new KeyValueItem(value, value, choice.getHintType())); + // default hints + String hintValue = value; + ChoiceHintType hintType = choice.getHintType(); + this.allItems.add(new KeyValueItem(value, value, hintValue, hintType)); } } @@ -106,6 +114,17 @@ public class PickChoiceDialog extends MageDialog { }); } + // custom hints (per item) + if (!choice.getHintData().isEmpty()) { + this.allItems.forEach(item -> { + List info = choice.getHintData().getOrDefault(item.key, null); + if (info != null) { + item.hintType = ChoiceHintType.valueOf(info.get(0)); + item.hint = info.get(1); + } + }); + } + // search if (choice.isSearchEnabled()) { panelSearch.setVisible(true); @@ -264,41 +283,52 @@ public class PickChoiceDialog extends MageDialog { } private void choiceHintShow(int modelIndex) { + // close old hint + if (lastModelIndex != modelIndex) { + cardInfo.onMouseExited(); + listChoices.setToolTipText(null); + } - switch (choice.getHintType()) { + KeyValueItem item = (KeyValueItem) listChoices.getModel().getElementAt(modelIndex); + switch (item.getHintType()) { case CARD: - case CARD_DUNGEON: { + case CARD_DUNGEON: + case GAME_OBJECT: { // as popup card if (lastModelIndex != modelIndex) { - // new card - KeyValueItem item = (KeyValueItem) listChoices.getModel().getElementAt(modelIndex); - String cardName = item.getValue(); - - if (choice.getHintType() == ChoiceHintType.CARD) { - cardInfo.init(cardName, this.bigCard, this.gameId); - } else if (choice.getHintType() == ChoiceHintType.CARD_DUNGEON) { - CardView cardView = new CardView(new DungeonView(Dungeon.createDungeon(cardName))); + // NEW + if (item.getHintType() == ChoiceHintType.CARD) { + // as card name + cardInfo.init(item.getHint(), this.bigCard, this.gameId); + } else if (item.getHintType() == ChoiceHintType.CARD_DUNGEON) { + // as card name + CardView cardView = new CardView(new DungeonView(Dungeon.createDungeon(item.getHint()))); cardInfo.init(cardView, this.bigCard, this.gameId); + } else if (item.getHintType() == ChoiceHintType.GAME_OBJECT) { + // as object + GamePanel game = MageFrame.getGame(this.gameId); + if (game != null) { + UUID objectId = UUID.fromString(item.getHint()); + CardView cardView = game.getLastGameData().findCard(objectId); + if (cardView != null) { + cardInfo.init(cardView, this.bigCard, this.gameId); + } + } } cardInfo.setPopupAutoLocationMode(TransferData.PopupAutoLocationMode.PUT_NEAR_MOUSE_POSITION); - cardInfo.onMouseEntered(MouseInfo.getPointerInfo().getLocation()); } else { - // old card + // OLD - keep it opened cardInfo.onMouseMoved(MouseInfo.getPointerInfo().getLocation()); } lastModelIndex = modelIndex; break; } - default: case TEXT: { // as popup text if (lastModelIndex != modelIndex) { - // new hint with GUI size and mana symbols support - listChoices.setToolTipText(null); - KeyValueItem item = (KeyValueItem) listChoices.getModel().getElementAt(modelIndex); - String hint = item.getValue(); + String hint = item.getHint(); hint = ManaSymbols.replaceSymbolsWithHTML(hint, ManaSymbols.Type.DIALOG); hint = GUISizeHelper.textToHtmlWithSize(hint, listChoices.getFont()); listChoices.setToolTipText(hint); @@ -306,26 +336,16 @@ public class PickChoiceDialog extends MageDialog { lastModelIndex = modelIndex; break; } + + default: { + throw new IllegalArgumentException("Unsupported hint type " + item.getHintType()); + } } } private void choiceHintHide() { - switch (choice.getHintType()) { - case CARD: - case CARD_DUNGEON: { - // as popup card - cardInfo.onMouseExited(); - break; - } - - default: - case TEXT: { - // as popup text - listChoices.setToolTipText(null); - break; - } - } - + cardInfo.onMouseExited(); + listChoices.setToolTipText(null); lastModelIndex = -1; } @@ -401,7 +421,7 @@ public class PickChoiceDialog extends MageDialog { KeyValueItem item = (KeyValueItem) this.listChoices.getSelectedValue(); boolean isSpecial = choice.isSpecialEnabled() && cbSpecial.isSelected(); - // auto select one item (after incemental filtering) + // auto select one item (after incremental filtering) if ((item == null) && (this.listChoices.getModel().getSize() == 1)) { this.listChoices.setSelectedIndex(0); item = (KeyValueItem) this.listChoices.getSelectedValue(); @@ -434,13 +454,15 @@ public class PickChoiceDialog extends MageDialog { static class KeyValueItem { protected final String key; - protected final String value; - protected final ChoiceHintType hint; + protected String value; + protected String hint; + protected ChoiceHintType hintType; - public KeyValueItem(String key, String value, ChoiceHintType hint) { + public KeyValueItem(String key, String value, String hint, ChoiceHintType hintType) { this.key = key; this.value = value; this.hint = hint; + this.hintType = hintType; } public String getKey() { @@ -451,13 +473,17 @@ public class PickChoiceDialog extends MageDialog { return this.value; } - public ChoiceHintType getHint() { + public String getHint() { return this.hint; } + public ChoiceHintType getHintType() { + return this.hintType; + } + @Override public String toString() { - return this.value; + return "" + ManaSymbols.replaceSymbolsWithHTML(this.getValue(), ManaSymbols.Type.TABLE); } } @@ -510,28 +536,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); @@ -554,27 +586,27 @@ 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() - .addComponent(cbSpecial) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 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() + .addComponent(cbSpecial) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 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) - .addComponent(cbSpecial)) - .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(cbSpecial)) + .addContainerGap()) ); getRootPane().setDefaultButton(btOK); @@ -582,28 +614,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, 371, 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, 371, 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, 268, 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, 268, 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/org/mage/card/arcane/ManaSymbols.java b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java index e3e9707a155..772ab75e2ef 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -580,9 +580,8 @@ public final class ManaSymbols { } - public enum Type { - TABLE, + TABLE, // TODO: merge TABLE and DIALOG into WINDOW CHAT, DIALOG, TOOLTIP, diff --git a/Mage.Common/src/main/java/mage/utils/SystemUtil.java b/Mage.Common/src/main/java/mage/utils/SystemUtil.java index 44f0e83abee..9d5f3f3593b 100644 --- a/Mage.Common/src/main/java/mage/utils/SystemUtil.java +++ b/Mage.Common/src/main/java/mage/utils/SystemUtil.java @@ -352,21 +352,21 @@ public final class SystemUtil { logger.info("Found " + groups.size() + " groups. Need to select."); // choice dialog - Map list = new LinkedHashMap<>(); - Map sort = new LinkedHashMap<>(); - for (int i = 0; i < groups.size(); i++) { - list.put(Integer.toString(i + 1), groups.get(i).getPrintNameWithStats()); - sort.put(Integer.toString(i + 1), i); - } - Choice groupChoice = new ChoiceImpl(false); groupChoice.setMessage("Choose commands group to run"); - groupChoice.setKeyChoices(list); - groupChoice.setSortData(sort); + for (int i = 0; i < groups.size(); i++) { + groupChoice.withItem( + Integer.toString(i + 1), + groups.get(i).getPrintNameWithStats(), + i, + ChoiceHintType.TEXT, + String.join("
", groups.get(i).commands) + ); + } if (feedbackPlayer.choose(Outcome.Benefit, groupChoice, game)) { String need = groupChoice.getChoiceKey(); - if ((need != null) && list.containsKey(need)) { + if (need != null) { runGroup = groups.get(Integer.parseInt(need) - 1); } } diff --git a/Mage/src/main/java/mage/choices/Choice.java b/Mage/src/main/java/mage/choices/Choice.java index 49e9558c912..cba73b1fb08 100644 --- a/Mage/src/main/java/mage/choices/Choice.java +++ b/Mage/src/main/java/mage/choices/Choice.java @@ -91,6 +91,18 @@ public interface Choice extends Serializable, Copyable { Map getSortData(); + // custom hints + void setHintData(Map> hintData); + + Map> getHintData(); + + // builder + + /** + * Fast add single key item. Use null value to ignore sort or hint data + */ + Choice withItem(String key, String value, Integer sort, ChoiceHintType hintType, String hintValue); + // random choice (for AI usage) void setRandomChoice(); diff --git a/Mage/src/main/java/mage/choices/ChoiceHintType.java b/Mage/src/main/java/mage/choices/ChoiceHintType.java index 86e7580f4c1..fb8314645e3 100644 --- a/Mage/src/main/java/mage/choices/ChoiceHintType.java +++ b/Mage/src/main/java/mage/choices/ChoiceHintType.java @@ -6,8 +6,8 @@ package mage.choices; * @author JayDi85 */ public enum ChoiceHintType { - - TEXT, - CARD, - CARD_DUNGEON + TEXT, // any text in hint + CARD, // card name in hint + CARD_DUNGEON, // card name in hint + GAME_OBJECT // UUID in hint } diff --git a/Mage/src/main/java/mage/choices/ChoiceImpl.java b/Mage/src/main/java/mage/choices/ChoiceImpl.java index da1c6bc95b7..8bb5435e6af 100644 --- a/Mage/src/main/java/mage/choices/ChoiceImpl.java +++ b/Mage/src/main/java/mage/choices/ChoiceImpl.java @@ -7,7 +7,11 @@ import org.apache.log4j.Logger; import java.util.*; /** - * @author BetaSteward_at_googlemail.com, JayDi85 + * Game's choose dialog to select one item from a list + *

+ * Support GUI related features like headers, sorting, tooltips/popups + * + * @author JayDi85 */ public class ChoiceImpl implements Choice { @@ -21,6 +25,7 @@ public class ChoiceImpl implements Choice { protected Set choices = new LinkedHashSet<>(); protected Map keyChoices = new LinkedHashMap<>(); protected Map sortData = new LinkedHashMap<>(); + protected Map> hintData = new LinkedHashMap<>(); // value -> [type, hint] protected String message; protected String subMessage; protected boolean searchEnabled = true; // enable for all windows by default @@ -40,6 +45,9 @@ public class ChoiceImpl implements Choice { this(required, ChoiceHintType.TEXT); } + /** + * @param hintType enable card popup hint (each value will be used as card/dungeon name) + */ public ChoiceImpl(boolean required, ChoiceHintType hintType) { this.required = required; this.hintType = hintType; @@ -228,6 +236,40 @@ public class ChoiceImpl implements Choice { return this.sortData; } + @Override + public Map> getHintData() { + return this.hintData; + } + + @Override + public Choice withItem(String key, String value, Integer sort, ChoiceHintType hintType, String hintValue) { + this.keyChoices.put(key, value); + if (sort != null) { + this.sortData.put(key, sort); + } + if (hintType != null) { + this.hintData.put(key, Arrays.asList(hintType.toString(), hintValue)); + } + return this; + } + + @Override + public void setHintData(Map> hintData) { + // runtime check + hintData.forEach((key, info) -> { + try { + ChoiceHintType hintType = ChoiceHintType.valueOf(info.get(0)); + if (hintType == ChoiceHintType.GAME_OBJECT) { + UUID objectId = UUID.fromString(info.get(1)); + } + } catch (Exception e) { + throw new IllegalArgumentException("Wrong code usage: hints info must contains valid data, but found - " + info); + } + }); + + this.hintData = hintData; + } + @Override public void setRandomChoice() {