package tools.map.xml.creator;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Optional;
import java.util.TreeSet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import games.strategy.ui.SwingAction;
public class PlayerAndAlliancesPanel extends DynamicRowsPanel {
private final TreeSet<String> alliances = new TreeSet<>();
public PlayerAndAlliancesPanel(final JPanel stepActionPanel) {
super(stepActionPanel);
}
public static void layout(final MapXmlCreator mapXmlCreator) {
if (!me.isPresent() || !(me.get() instanceof PlayerAndAlliancesPanel)) {
me = Optional.of(new PlayerAndAlliancesPanel(mapXmlCreator.getStepActionPanel()));
}
DynamicRowsPanel.layout(mapXmlCreator);
}
@Override
protected ActionListener getAutoFillAction() {
return null;
}
@Override
protected void layoutComponents() {
final JLabel labelPlayerName = new JLabel("Player Name");
Dimension dimension = labelPlayerName.getPreferredSize();
dimension.width = DynamicRow.INPUT_FIELD_SIZE_MEDIUM;
labelPlayerName.setPreferredSize(dimension);
final JLabel labelPlayerAlliance = new JLabel("Player Alliance");
labelPlayerAlliance.setPreferredSize(dimension);
final JLabel labelInitialResource = new JLabel("Initial Resource");
dimension = (Dimension) dimension.clone();
dimension.width = 80;
labelInitialResource.setPreferredSize(dimension);
// <1> Set panel layout
final GridBagLayout gbl_stepActionPanel = new GridBagLayout();
setColumns(gbl_stepActionPanel);
setRows(gbl_stepActionPanel, MapXmlHelper.getPlayerNames().size());
getOwnPanel().setLayout(gbl_stepActionPanel);
// <2> Add Row Labels: Player Name, Alliance Name, Initial Resource
final GridBagConstraints gridBadConstLabelPlayerName = new GridBagConstraints();
gridBadConstLabelPlayerName.insets = new Insets(0, 0, 5, 5);
gridBadConstLabelPlayerName.gridy = 0;
gridBadConstLabelPlayerName.gridx = 0;
gridBadConstLabelPlayerName.anchor = GridBagConstraints.WEST;
getOwnPanel().add(labelPlayerName, gridBadConstLabelPlayerName);
final GridBagConstraints gridBadConstLabelPlayerAlliance = (GridBagConstraints) gridBadConstLabelPlayerName.clone();
gridBadConstLabelPlayerAlliance.gridx = 1;
getOwnPanel().add(labelPlayerAlliance, gridBadConstLabelPlayerAlliance);
final GridBagConstraints gridBadConstLabelInitialResource =
(GridBagConstraints) gridBadConstLabelPlayerName.clone();
gridBadConstLabelInitialResource.gridx = 2;
getOwnPanel().add(labelInitialResource, gridBadConstLabelInitialResource);
// <3> Add Main Input Rows
final String[] alliancesArray = alliances.toArray(new String[alliances.size()]);
int rowIndex = 1;
for (final String playerName : MapXmlHelper.getPlayerNames()) {
final GridBagConstraints gbc_tPlayerName = (GridBagConstraints) gridBadConstLabelPlayerName.clone();
gbc_tPlayerName.gridx = 0;
gridBadConstLabelPlayerName.gridy = rowIndex;
final PlayerAndAlliancesRow newRow = new PlayerAndAlliancesRow(this, getOwnPanel(), playerName,
MapXmlHelper.getPlayerAllianceMap().get(playerName), alliancesArray,
MapXmlHelper.getPlayerInitResourcesMap().get(playerName));
newRow.addToParentComponentWithGbc(getOwnPanel(), rowIndex, gbc_tPlayerName);
rows.add(newRow);
++rowIndex;
}
// <4> Add Final Button Row
final JButton buttonAddPlayer = new JButton("Add Player");
final JButton buttonAddAlliance = new JButton("Add Alliance");
final JButton buttonRemoveAlliance = new JButton("Remove Alliance");
buttonAddPlayer.setFont(MapXmlUIHelper.defaultMapXMLCreatorFont);
buttonAddPlayer.addActionListener(SwingAction.of("Add Player", e -> {
String newPlayerName = JOptionPane.showInputDialog(getOwnPanel(), "Enter a new player name:",
"Player" + (MapXmlHelper.getPlayerNames().size() + 1));
if (newPlayerName == null || newPlayerName.isEmpty()) {
return;
}
if (MapXmlHelper.getPlayerNames().contains(newPlayerName)) {
JOptionPane.showMessageDialog(getOwnPanel(), "Player '" + newPlayerName + "' already exists.", "Input error",
JOptionPane.ERROR_MESSAGE);
return;
}
newPlayerName = newPlayerName.trim();
String allianceName;
if (alliances.isEmpty()) {
allianceName = JOptionPane.showInputDialog(getOwnPanel(),
"Which alliance should player '" + newPlayerName + "' join?", "Alliance1");
if (allianceName == null) {
return;
}
allianceName = allianceName.trim();
alliances.add(allianceName);
} else {
allianceName = (String) JOptionPane.showInputDialog(getOwnPanel(),
"Which alliance should player '" + newPlayerName + "' join?",
"Choose Player's Alliance",
JOptionPane.QUESTION_MESSAGE, null,
alliances.toArray(new String[alliances.size()]), // Array of choices
alliances.iterator().next()); // Initial choice
}
MapXmlHelper.addPlayerName(newPlayerName);
MapXmlHelper.putPlayerAlliance(newPlayerName, allianceName);
MapXmlHelper.putPlayerInitResources(newPlayerName, 0);
// UI Update
setRows((GridBagLayout) getOwnPanel().getLayout(), MapXmlHelper.getPlayerNames().size());
addRowWith(newPlayerName, allianceName, 0);
SwingUtilities.invokeLater(() -> {
getOwnPanel().revalidate();
getOwnPanel().repaint();
});
}));
addButton(buttonAddPlayer);
buttonAddAlliance.setFont(MapXmlUIHelper.defaultMapXMLCreatorFont);
buttonAddAlliance.addActionListener(SwingAction.of("Add Alliance", e -> {
String newAllianceName = JOptionPane.showInputDialog(getOwnPanel(), "Enter a new alliance name:",
"Alliance" + (alliances.size() + 1));
if (newAllianceName == null || newAllianceName.isEmpty()) {
return;
}
if (alliances.contains(newAllianceName)) {
JOptionPane.showMessageDialog(getOwnPanel(), "Alliance '" + newAllianceName + "' already exists.",
"Input error",
JOptionPane.ERROR_MESSAGE);
return;
}
newAllianceName = newAllianceName.trim();
alliances.add(newAllianceName);
if (alliances.size() > 1) {
buttonRemoveAlliance.setEnabled(true);
}
// UI Update
addToComboBoxesAlliance(newAllianceName);
SwingUtilities.invokeLater(() -> {
getOwnPanel().revalidate();
getOwnPanel().repaint();
});
}));
addButton(buttonAddAlliance);
buttonRemoveAlliance.setFont(MapXmlUIHelper.defaultMapXMLCreatorFont);
buttonRemoveAlliance.setEnabled(alliances.size() > 1);
buttonRemoveAlliance.addActionListener(SwingAction.of("Remove Alliance", e -> {
final String removeAllianceName = (String) JOptionPane.showInputDialog(getOwnPanel(),
"Which alliance should get removed?", "Remove Alliance", JOptionPane.QUESTION_MESSAGE,
null, alliances.toArray(new String[alliances.size()]), // Array of choices
alliances.iterator().next()); // Initial choice
if (removeAllianceName == null || removeAllianceName.isEmpty()) {
return;
}
final ArrayList<String> playerStillUsing = new ArrayList<>();
for (final DynamicRow row : rows) {
if (((PlayerAndAlliancesRow) row).isAllianceSelected(removeAllianceName)) {
playerStillUsing.add(row.getRowName());
}
}
if (!playerStillUsing.isEmpty()) {
final StringBuilder formattedPlayerList = new StringBuilder();
final boolean plural = playerStillUsing.size() > 1;
for (final String playerString : playerStillUsing) {
formattedPlayerList.append("\r - ").append(playerString);
}
JOptionPane.showMessageDialog(getOwnPanel(), "Cannot remove alliance.\rThe following player"
+ (plural ? "s are" : " is") + " still assigned to alliance '"
+ removeAllianceName + "':"
+ formattedPlayerList, "Input error",
JOptionPane.ERROR_MESSAGE);
return;
}
alliances.remove(removeAllianceName);
if (alliances.size() <= 1) {
buttonRemoveAlliance.setEnabled(false);
}
// UI Update
removeFromComboBoxesAlliance(removeAllianceName);
SwingUtilities.invokeLater(() -> {
getOwnPanel().revalidate();
getOwnPanel().repaint();
});
}));
addButton(buttonRemoveAlliance);
final GridBagConstraints gridBadConstButtonAddPlayer = (GridBagConstraints) gridBadConstLabelPlayerName.clone();
gridBadConstButtonAddPlayer.gridx = 0;
gridBadConstButtonAddPlayer.gridy = rowIndex;
addFinalButtonRow(gridBadConstButtonAddPlayer);
}
protected void addToComboBoxesAlliance(final String newAlliance) {
for (final DynamicRow row : rows) {
((PlayerAndAlliancesRow) row).updateComboBoxesAlliance(newAlliance);
}
}
protected void removeFromComboBoxesAlliance(final String removeAlliance) {
for (final DynamicRow row : rows) {
((PlayerAndAlliancesRow) row).removeFromComboBoxesAlliance(removeAlliance);
}
}
private DynamicRow addRowWith(final String newPlayerName, final String allianceName, final int initialResource) {
final PlayerAndAlliancesRow newRow = new PlayerAndAlliancesRow(this, getOwnPanel(), newPlayerName, allianceName,
alliances.toArray(new String[alliances.size()]), initialResource);
addRow(newRow);
return newRow;
}
@Override
protected void initializeSpecifics() {
if (!MapXmlHelper.getPlayerAllianceMap().isEmpty()) {
alliances.clear();
}
alliances.addAll(MapXmlHelper.getPlayerAllianceMap().values());
}
@Override
protected void setColumns(final GridBagLayout gblPanel) {
gblPanel.columnWidths = new int[] {50, 60, 50, 30};
gblPanel.columnWeights = new double[] {0.0, 0.0, 0.0, 0.0};
}
}