package tools.map.xml.creator; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import com.google.common.collect.Maps; import games.strategy.util.Triple; class PlayerAndAlliancesRow extends DynamicRow { private JTextField textFieldPlayerName; private JComboBox<String> comboBoxPlayerAlliance; private JTextField textFieldInitialResource; public PlayerAndAlliancesRow(final DynamicRowsPanel parentRowPanel, final JPanel stepActionPanel, final String playerName, final String allianceName, final String[] alliances, final int initialResource) { super(playerName, parentRowPanel, stepActionPanel); textFieldPlayerName = new JTextField(playerName); comboBoxPlayerAlliance = new JComboBox<>(alliances); textFieldInitialResource = new JTextField(Integer.toString(initialResource)); Dimension dimension = textFieldPlayerName.getPreferredSize(); dimension.width = INPUT_FIELD_SIZE_MEDIUM; textFieldPlayerName.setPreferredSize(dimension); MapXmlUIHelper.addNewFocusListenerForTextField(textFieldPlayerName, () -> { final String inputText = textFieldPlayerName.getText().trim(); if (currentRowName.equals(inputText)) { return; } if (MapXmlHelper.getPlayerNames().contains(inputText)) { textFieldPlayerName.selectAll(); JOptionPane.showMessageDialog(stepActionPanel, "Player '" + inputText + "' already exists.", "Input error", JOptionPane.ERROR_MESSAGE); parentRowPanel.setDataIsConsistent(false); SwingUtilities.invokeLater(() -> textFieldPlayerName.requestFocus()); return; } // everything is okay with the new player namer, lets rename everything MapXmlHelper.getPlayerNames().remove(currentRowName); MapXmlHelper.getPlayerNames().add(inputText); MapXmlHelper.getPlayerAllianceMap().remove(currentRowName); MapXmlHelper.getPlayerAllianceMap().put(inputText, MapXmlHelper.getPlayerAllianceMap().get(currentRowName)); MapXmlHelper.getPlayerInitResourcesMap().remove(currentRowName); MapXmlHelper.getPlayerInitResourcesMap().put(inputText, MapXmlHelper.getPlayerInitResourcesMap().get(currentRowName)); if (!MapXmlHelper.getPlayerSequenceMap().isEmpty()) { // Replace Player Names for Player Sequence final LinkedHashMap<String, Triple<String, String, Integer>> updatesPlayerSequence = Maps.newLinkedHashMap(); for (final Entry<String, Triple<String, String, Integer>> playerSequence : MapXmlHelper.getPlayerSequenceMap() .entrySet()) { final Triple<String, String, Integer> oldTriple = playerSequence.getValue(); if (currentRowName.equals(oldTriple.getSecond())) { updatesPlayerSequence.put(playerSequence.getKey(), Triple.of(oldTriple.getFirst(), inputText, oldTriple.getThird())); } } for (final Entry<String, Triple<String, String, Integer>> playerSequence : updatesPlayerSequence.entrySet()) { MapXmlHelper.getPlayerSequenceMap().put(playerSequence.getKey(), playerSequence.getValue()); } } if (!MapXmlHelper.getProductionFrontiersMap().isEmpty()) { final List<String> productionFrontier = MapXmlHelper.getProductionFrontiersMap().get(currentRowName); if (productionFrontier != null) { MapXmlHelper.getProductionFrontiersMap().remove(currentRowName); MapXmlHelper.getProductionFrontiersMap().put(inputText, productionFrontier); } } if (!MapXmlHelper.getTechnologyDefinitionsMap().isEmpty()) { // Delete Technology Definitions for this Player Name (techKey ending with '_' + PlayerName) final Map<String, List<String>> newEntryMap = Maps.newLinkedHashMap(); final String compareValue = "_" + currentRowName; for (final Entry<String, List<String>> technologyDefinition : MapXmlHelper.getTechnologyDefinitionsMap() .entrySet()) { final String techKey = technologyDefinition.getKey(); if (techKey.endsWith(compareValue)) { final List<String> techValues = technologyDefinition.getValue(); techValues.set(0, inputText); newEntryMap.put(techKey.substring(0, techKey.lastIndexOf(compareValue)) + "_" + inputText, techValues); } else { newEntryMap.put(techKey, technologyDefinition.getValue()); } } MapXmlHelper.setTechnologyDefinitions(newEntryMap); } currentRowName = inputText; parentRowPanel.setDataIsConsistent(true); }); dimension = comboBoxPlayerAlliance.getPreferredSize(); dimension.width = INPUT_FIELD_SIZE_MEDIUM; comboBoxPlayerAlliance.setPreferredSize(dimension); comboBoxPlayerAlliance.setSelectedIndex(Arrays.binarySearch(alliances, allianceName)); comboBoxPlayerAlliance.addFocusListener(FocusListenerFocusLost.withAction(() -> // everything is okay with the new technology name, lets rename everything MapXmlHelper.getPlayerAllianceMap().put(playerName, (String) comboBoxPlayerAlliance.getSelectedItem()))); dimension = textFieldInitialResource.getPreferredSize(); dimension.width = INPUT_FIELD_SIZE_SMALL; textFieldInitialResource.setPreferredSize(dimension); textFieldInitialResource.addFocusListener(new FocusListener() { String prevValue = Integer.toString(initialResource); @Override public void focusLost(final FocusEvent arg0) { final String inputText = textFieldInitialResource.getText().trim(); try { MapXmlHelper.getPlayerInitResourcesMap().put(playerName, Integer.parseInt(inputText)); } catch (final NumberFormatException e) { textFieldInitialResource.setText(prevValue); JOptionPane.showMessageDialog(stepActionPanel, "'" + inputText + "' is no integer value.", "Input error", JOptionPane.ERROR_MESSAGE); parentRowPanel.setDataIsConsistent(false); parentRowPanel.setDataIsConsistent(false); SwingUtilities.invokeLater(() -> { textFieldInitialResource.updateUI(); textFieldInitialResource.requestFocus(); textFieldInitialResource.selectAll(); }); return; } prevValue = inputText; parentRowPanel.setDataIsConsistent(true); } @Override public void focusGained(final FocusEvent arg0) { textFieldInitialResource.selectAll(); } }); } public boolean isAllianceSelected(final String removeAllianceName) { return comboBoxPlayerAlliance.getSelectedItem().equals(removeAllianceName); } public void removeFromComboBoxesAlliance(final String removeAlliance) { comboBoxPlayerAlliance.removeItem(removeAlliance); } public void updateComboBoxesAlliance(final String newAlliance) { comboBoxPlayerAlliance.addItem(newAlliance); } @Override protected ArrayList<JComponent> getComponentList() { final ArrayList<JComponent> componentList = new ArrayList<>(); componentList.add(textFieldPlayerName); componentList.add(comboBoxPlayerAlliance); componentList.add(textFieldInitialResource); return componentList; } @Override public void addToParentComponent(final JComponent parent, final GridBagConstraints gbcTemplate) { parent.add(textFieldPlayerName, gbcTemplate); final GridBagConstraints gbc_tPlayerAlliance = (GridBagConstraints) gbcTemplate.clone(); gbc_tPlayerAlliance.gridx = 1; parent.add(comboBoxPlayerAlliance, gbc_tPlayerAlliance); final GridBagConstraints gbc_tInitialResource = (GridBagConstraints) gbcTemplate.clone(); gbc_tInitialResource.gridx = 2; parent.add(textFieldInitialResource, gbc_tInitialResource); final GridBagConstraints gridBadConstButtonRemove = (GridBagConstraints) gbcTemplate.clone(); gridBadConstButtonRemove.gridx = 3; parent.add(buttonRemovePerRow, gridBadConstButtonRemove); } @Override protected void adaptRowSpecifics(final DynamicRow newRow) { final PlayerAndAlliancesRow newRowPlayerAndAlliancesRow = (PlayerAndAlliancesRow) newRow; this.textFieldPlayerName.setText(newRowPlayerAndAlliancesRow.textFieldPlayerName.getText()); this.comboBoxPlayerAlliance.setSelectedIndex(newRowPlayerAndAlliancesRow.comboBoxPlayerAlliance.getSelectedIndex()); this.textFieldInitialResource.setText(newRowPlayerAndAlliancesRow.textFieldInitialResource.getText()); } @Override protected void removeRowAction() { MapXmlHelper.getPlayerNames().remove(currentRowName); MapXmlHelper.getPlayerAllianceMap().remove(currentRowName); MapXmlHelper.getPlayerInitResourcesMap().remove(currentRowName); if (!MapXmlHelper.getPlayerSequenceMap().isEmpty()) { // Replace Player Sequences using the deleted Player Name final ArrayList<String> deleteKeys = new ArrayList<>(); for (final Entry<String, Triple<String, String, Integer>> playerSequence : MapXmlHelper.getPlayerSequenceMap() .entrySet()) { final Triple<String, String, Integer> oldTriple = playerSequence.getValue(); if (currentRowName.equals(oldTriple.getSecond())) { deleteKeys.add(playerSequence.getKey()); } } for (final String deleteKey : deleteKeys) { MapXmlHelper.getPlayerSequenceMap().remove(deleteKey); } } if (!MapXmlHelper.getTechnologyDefinitionsMap().isEmpty()) { // Replace Technology Definitions using the deleted Player Name final ArrayList<String> deleteKeys = new ArrayList<>(); final String compareValue = "_" + currentRowName; for (final Entry<String, List<String>> technologyDefinition : MapXmlHelper.getTechnologyDefinitionsMap() .entrySet()) { final String techKey = technologyDefinition.getKey(); if (techKey.endsWith(compareValue)) { deleteKeys.add(techKey); } } for (final String deleteKey : deleteKeys) { MapXmlHelper.getTechnologyDefinitionsMap().remove(deleteKey); } } } }