This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
JRummikub/src/jrummikub/view/impl/SettingsPanel.java
Matthias Schiffer 751d5a3aa9 Fixed player name label HTML bug
git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@440 72836036-5685-4462-b002-a69064685172
2011-06-14 18:07:42 +02:00

1059 lines
30 KiB
Java

package jrummikub.view.impl;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import jrummikub.model.GameSettings;
import jrummikub.model.PlayerSettings;
import jrummikub.model.PlayerSettings.Type;
import jrummikub.model.StoneColor;
import jrummikub.util.Event;
import jrummikub.util.Event1;
import jrummikub.util.Event2;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.util.IEvent2;
import jrummikub.view.ISettingsPanel;
@SuppressWarnings("serial")
class SettingsPanel extends JPanel implements ISettingsPanel {
private List<List<Type>> playerTypeChoices = Collections.emptyList();
private List<Boolean> removeButtonsEnabled = Collections.emptyList();
private List<Boolean> playerNamesEditable = Collections.emptyList();
private SettingsMode settingsMode = SettingsMode.DEFAULT;
private JTabbedPane tabbedPane;
private JPanel playerSetupPanel;
private JPanel playerSettingsViewport;
private JPanel optionsPanel;
private JButton addPlayerButton;
private JLabel errorMessageLabel;
private JButton startButton;
private JButton offerButton;
private List<PlayerSettingsPanel> playerSettingsPanels = new ArrayList<PlayerSettingsPanel>();
private JLabel variantLabel;
private JPanel variantPanel;
private JButton setVariantDefaultButton;
private JButton setVariantChildrenButton;
private JSpinner initialMeldThresholdSpinner;
private JSpinner stoneSetNumberSpinner;
private JSpinner highestValueSpinner;
private JSpinner numberOfStonesDealtSpinner;
private JSpinner jokerNumberSpinner;
private JSpinner timeSpinner;
private JCheckBox noLimitsBox;
private JPanel colorSelectionPanel;
private Map<StoneColor, JToggleButton> colorButtons = new HashMap<StoneColor, JToggleButton>();
private JPanel colorLabelPanel;
private JLabel initialMeldThresholdLabel;
private JLabel stoneSetNumberLabel;
private JLabel highestValueLabel;
private JLabel numberOfStonesDealtLabel;
private JLabel jokerNumberLabel;
private JLabel timeLabel;
private JLabel noLimitsLabel;
private JButton loadButton;
private JButton networkButton;
private JButton backButton;
private JPanel buttonPanel;
private Event startGameEvent = new Event();
private Event loadGameEvent = new Event();
private Event networkGameEvent = new Event();
private Event offerGameEvent = new Event();
private Event backEvent = new Event();
private Event addPlayerEvent = new Event();
private Event1<Integer> removePlayerEvent = new Event1<Integer>();
private Event2<Integer, Color> changePlayerColorEvent = new Event2<Integer, Color>();
private Event2<Integer, String> changePlayerNameEvent = new Event2<Integer, String>();
private Event2<Integer, Type> changePlayerTypeEvent = new Event2<Integer, Type>();
private Event1<Integer> changeInitialMeldThresholdEvent = new Event1<Integer>();
private Event1<Integer> changeJokerNumberEvent = new Event1<Integer>();
private Event1<Integer> changeStoneSetNumberEvent = new Event1<Integer>();
private Event1<Integer> changeNumberOfStonesDealtEvent = new Event1<Integer>();
private Event1<Integer> changeHighestValueEvent = new Event1<Integer>();
private Event1<Set<StoneColor>> changeStoneColorsEvent = new Event1<Set<StoneColor>>();
private Event1<Integer> changeTimeEvent = new Event1<Integer>();
private Event1<Boolean> changeNoLimitsEvent = new Event1<Boolean>();
private Event setVariantDefaultEvent = new Event();
private Event setVariantChildrenEvent = new Event();
@Override
public IEvent getStartGameEvent() {
return startGameEvent;
}
@Override
public IEvent getOfferGameEvent() {
return offerGameEvent;
}
IEvent getLoadGameEvent() {
return loadGameEvent;
}
IEvent getNetworkGameEvent() {
return networkGameEvent;
}
@Override
public IEvent getAddPlayerEvent() {
return addPlayerEvent;
}
@Override
public IEvent1<Integer> getRemovePlayerEvent() {
return removePlayerEvent;
}
@Override
public IEvent2<Integer, Color> getChangePlayerColorEvent() {
return changePlayerColorEvent;
}
@Override
public IEvent2<Integer, String> getChangePlayerNameEvent() {
return changePlayerNameEvent;
}
@Override
public IEvent1<Integer> getChangeInitialMeldThresholdEvent() {
return changeInitialMeldThresholdEvent;
}
@Override
public IEvent1<Integer> getChangeStoneSetNumberEvent() {
return changeStoneSetNumberEvent;
}
@Override
public IEvent1<Integer> getChangeNumberOfStonesDealtEvent() {
return changeNumberOfStonesDealtEvent;
}
@Override
public IEvent1<Integer> getChangeHighestValueEvent() {
return changeHighestValueEvent;
}
@Override
public IEvent1<Integer> getChangeJokerNumberEvent() {
return changeJokerNumberEvent;
}
@Override
public IEvent2<Integer, Type> getChangePlayerTypeEvent() {
return changePlayerTypeEvent;
}
@Override
public IEvent1<Integer> getChangeTimeEvent() {
return changeTimeEvent;
}
@Override
public IEvent1<Boolean> getChangeNoLimitsEvent() {
return changeNoLimitsEvent;
}
@Override
public IEvent1<Set<StoneColor>> getChangeStoneColorsEvent() {
return changeStoneColorsEvent;
}
@Override
public IEvent getSetVariantDefaultEvent() {
return setVariantDefaultEvent;
}
@Override
public IEvent getSetVariantChildrenEvent() {
return setVariantChildrenEvent;
}
@Override
public IEvent getBackEvent() {
return backEvent;
}
@Override
public void setPlayerTypeChoices(List<List<Type>> choices) {
playerTypeChoices = choices;
}
@Override
public void setError(SettingsError error) {
switch (error) {
case NO_ERROR:
errorMessageLabel.setText(" ");
break;
case DUPLICATE_PLAYER_NAME_ERROR:
errorMessageLabel
.setText("Jeder Spielername darf nur einmal verwendet werden.");
errorMessageLabel.setForeground(Color.RED);
break;
case NO_PLAYER_NAME_ERROR:
errorMessageLabel.setText("Jeder Spieler muss einen Namen haben.");
errorMessageLabel.setForeground(Color.RED);
break;
case NOT_ENOUGH_STONES_ERROR:
errorMessageLabel
.setText("Es gibt nicht genug Steine f\u00fcr die gew\u00e4hlte Spieleranzahl.");
errorMessageLabel.setForeground(Color.RED);
break;
case NOT_ENOUGH_COLORS_ERROR:
errorMessageLabel
.setText("Es m\u00fcssen mindestens drei Farben ausgew\u00e4hlt werden.");
errorMessageLabel.setForeground(Color.RED);
break;
case COMPUTER_PLAYERS_ONLY_WARNING:
errorMessageLabel.setText("Es gibt keinen menschlichen Spieler.");
errorMessageLabel.setForeground(Color.ORANGE.darker());
break;
case TOO_HIGH_THRESHOLD_WARNING:
errorMessageLabel
.setText("Die gew\u00e4hlte Schranke ist m\u00f6glicherweise zu hoch");
errorMessageLabel.setForeground(Color.ORANGE.darker());
break;
}
}
@Override
public void enableStartGameButton(boolean enable) {
startButton.setEnabled(enable);
offerButton.setEnabled(enable);
}
@Override
public void enableAddPlayerButton(boolean enable) {
addPlayerButton.setVisible(enable);
}
@Override
public void enableRemovePlayerButtons(List<Boolean> enable) {
removeButtonsEnabled = enable;
Iterator<Boolean> it = enable.iterator();
for (PlayerSettingsPanel psp : playerSettingsPanels) {
if (!it.hasNext()) {
psp.enableRemoveButton(false);
} else {
psp.enableRemoveButton(it.next());
}
}
}
@Override
public void setPlayerNamesEditable(List<Boolean> editable) {
playerNamesEditable = editable;
Iterator<Boolean> it = editable.iterator();
for (PlayerSettingsPanel psp : playerSettingsPanels) {
if (!it.hasNext()) {
psp.setPlayerNameEditable(true);
} else {
psp.setPlayerNameEditable(it.next());
}
}
}
@Override
public void setGameSettings(GameSettings gameSettings) {
while (playerSettingsPanels.size() > gameSettings.getPlayerList().size()) {
removePlayerSettingsPanel();
}
for (int i = 0; i < gameSettings.getPlayerList().size(); ++i) {
List<Type> choices = Collections.emptyList();
if (i < playerTypeChoices.size()) {
choices = playerTypeChoices.get(i);
}
updatePlayerSettingsPanel(i, gameSettings.getPlayerList().get(i), choices);
}
initialMeldThresholdSpinner
.setValue(gameSettings.getInitialMeldThreshold());
stoneSetNumberSpinner.setValue(gameSettings.getStoneSetNumber());
highestValueSpinner.setValue(gameSettings.getHighestValue());
numberOfStonesDealtSpinner.setValue(gameSettings.getNumberOfStonesDealt());
jokerNumberSpinner.setValue(gameSettings.getJokerNumber());
timeSpinner.setValue(gameSettings.getTotalTime());
noLimitsBox.setSelected(gameSettings.isNoLimits());
initialMeldThresholdLabel.setText(gameSettings.getInitialMeldThreshold()
+ " Punkte");
stoneSetNumberLabel.setText(Integer.toString(gameSettings
.getStoneSetNumber()));
highestValueLabel.setText(Integer.toString(gameSettings.getHighestValue()));
numberOfStonesDealtLabel.setText(Integer.toString(gameSettings
.getNumberOfStonesDealt()));
jokerNumberLabel.setText(Integer.toString(gameSettings.getJokerNumber()));
timeLabel.setText(gameSettings.getTotalTime() + " Sekunden");
noLimitsLabel.setText(gameSettings.isNoLimits() ? "An" : "Aus");
colorLabelPanel.removeAll();
for (StoneColor color : StoneColor.values()) {
boolean contained = gameSettings.getStoneColors().contains(color);
colorButtons.get(color).getModel().setSelected(contained);
if (contained) {
colorLabelPanel.add(new JLabel(ImageUtil.createColorIcon(
StonePainter.getColor(color), 16, 1)));
}
}
playerSettingsViewport.revalidate();
}
private void updatePlayerSettingsPanel(int i, PlayerSettings settings,
List<Type> choices) {
if (i < playerSettingsPanels.size()) {
playerSettingsPanels.get(i).setChoices(choices);
playerSettingsPanels.get(i).setSettings(settings);
} else {
addPlayerSettingsPanel(i, settings, choices);
}
}
private void addPlayerSettingsPanel(int i, PlayerSettings settings,
List<Type> choices) {
PlayerSettingsPanel panel = new PlayerSettingsPanel(i, settings, choices,
settingsMode != SettingsMode.NETWORK_OFFER
&& settingsMode != SettingsMode.NETWORK_JOIN);
playerSettingsPanels.add(panel);
playerSettingsViewport.add(panel,
playerSettingsViewport.getComponentCount() - 1);
enableRemovePlayerButtons(removeButtonsEnabled);
setPlayerNamesEditable(playerNamesEditable);
}
private void removePlayerSettingsPanel() {
PlayerSettingsPanel p = playerSettingsPanels.remove(playerSettingsPanels
.size() - 1);
playerSettingsViewport.remove(p);
}
private void createPlayerSetupPanel() {
playerSetupPanel = new JPanel();
playerSetupPanel.setLayout(new BorderLayout());
playerSettingsViewport = new JPanel();
playerSettingsViewport.setLayout(new BoxLayout(playerSettingsViewport,
BoxLayout.Y_AXIS));
JScrollPane scrollPane = new JScrollPane(playerSettingsViewport,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
playerSetupPanel.add(scrollPane);
JPanel addPlayerPanel = new JPanel();
addPlayerPanel.setLayout(new FlowLayout(FlowLayout.TRAILING, 0, 2));
playerSettingsViewport.add(addPlayerPanel);
addPlayerButton = new JButton("+");
addPlayerButton.setFont(addPlayerButton.getFont().deriveFont(Font.BOLD));
addPlayerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addPlayerEvent.emit();
}
});
addPlayerPanel.add(addPlayerButton);
}
private JComponent makeFiller() {
return new Box.Filler(new Dimension(0, 0), new Dimension(0, 0),
new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
}
private void createOptionsPanel() {
optionsPanel = new JPanel();
GridBagLayout layout = new GridBagLayout();
optionsPanel.setLayout(layout);
int row = 1;
variantLabel = new JLabel("Variante:");
makeVariantPanel();
makeOptionLabel(row++, "Auslegeschranke:");
initialMeldThresholdLabel = new JLabel();
initialMeldThresholdSpinner = createOptionSpinner(1, 999, 1,
changeInitialMeldThresholdEvent);
makeOptionLabel(row++, "Anzahl Steins\u00e4tze:");
stoneSetNumberLabel = new JLabel();
stoneSetNumberSpinner = createOptionSpinner(1, 999, 1,
changeStoneSetNumberEvent);
makeOptionLabel(row++, "H\u00f6chster Steinwert:");
highestValueLabel = new JLabel();
highestValueSpinner = createOptionSpinner(3, 99, 1, changeHighestValueEvent);
makeOptionLabel(row++, "Anzahl Startsteine:");
numberOfStonesDealtLabel = new JLabel();
numberOfStonesDealtSpinner = createOptionSpinner(1, 999, 1,
changeNumberOfStonesDealtEvent);
makeOptionLabel(row++, "Jokeranzahl:");
jokerNumberLabel = new JLabel();
jokerNumberSpinner = createOptionSpinner(1, 999, 1, changeJokerNumberEvent);
makeOptionLabel(row++, "Zeit für Spielzug:");
timeLabel = new JLabel();
timeSpinner = createOptionSpinner(1, 999, 1, changeTimeEvent);
makeOptionLabel(row++, "No Limits:");
noLimitsLabel = new JLabel();
noLimitsBox = createOptionCheckbox(changeNoLimitsEvent);
makeOptionLabel(row, "Steinfarben:");
createColorSelectionPanel();
colorLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 1;
c.gridy = row;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
optionsPanel.add(makeFiller(), c);
}
private void removeOptionPanelComponentsAndLabels() {
optionsPanel.remove(variantLabel);
optionsPanel.remove(variantPanel);
optionsPanel.remove(initialMeldThresholdSpinner);
optionsPanel.remove(initialMeldThresholdLabel);
optionsPanel.remove(stoneSetNumberSpinner);
optionsPanel.remove(stoneSetNumberLabel);
optionsPanel.remove(highestValueSpinner);
optionsPanel.remove(highestValueLabel);
optionsPanel.remove(numberOfStonesDealtSpinner);
optionsPanel.remove(numberOfStonesDealtLabel);
optionsPanel.remove(jokerNumberSpinner);
optionsPanel.remove(jokerNumberLabel);
optionsPanel.remove(timeSpinner);
optionsPanel.remove(timeLabel);
optionsPanel.remove(noLimitsBox);
optionsPanel.remove(noLimitsLabel);
optionsPanel.remove(colorSelectionPanel);
optionsPanel.remove(colorLabelPanel);
}
private void addOptionPanelComponents() {
removeOptionPanelComponentsAndLabels();
int row = 0;
addOptionPanelComponent(variantLabel, true, row);
addOptionPanelComponent(variantPanel, false, row++);
addOptionPanelComponent(initialMeldThresholdSpinner, false, row++);
addOptionPanelComponent(stoneSetNumberSpinner, false, row++);
addOptionPanelComponent(highestValueSpinner, false, row++);
addOptionPanelComponent(numberOfStonesDealtSpinner, false, row++);
addOptionPanelComponent(jokerNumberSpinner, false, row++);
addOptionPanelComponent(timeSpinner, false, row++);
addOptionPanelComponent(noLimitsBox, false, row++);
addOptionPanelComponent(colorSelectionPanel, false, row++);
}
private void addOptionPanelLabels() {
removeOptionPanelComponentsAndLabels();
int row = 1;
addOptionPanelComponent(initialMeldThresholdLabel, false, row++);
addOptionPanelComponent(stoneSetNumberLabel, false, row++);
addOptionPanelComponent(highestValueLabel, false, row++);
addOptionPanelComponent(numberOfStonesDealtLabel, false, row++);
addOptionPanelComponent(jokerNumberLabel, false, row++);
addOptionPanelComponent(timeLabel, false, row++);
addOptionPanelComponent(noLimitsLabel, false, row++);
addOptionPanelComponent(colorLabelPanel, false, row++);
}
private void addOptionPanelComponent(JComponent component, boolean label,
int row) {
GridBagConstraints c = new GridBagConstraints();
c.anchor = label ? GridBagConstraints.EAST : GridBagConstraints.WEST;
c.gridx = label ? 0 : 1;
c.gridy = row;
c.insets = new Insets(2, 2, 2, 2);
optionsPanel.add(component, c);
}
private void createColorSelectionPanel() {
colorSelectionPanel = new JPanel();
for (StoneColor color : StoneColor.values()) {
createColorButton(color);
}
}
private void createColorButton(final StoneColor color) {
JToggleButton button = new JToggleButton(ImageUtil.createColorIcon(
StonePainter.getColor(color), 12, 1));
button.setMargin(new Insets(3, 3, 3, 3));
button.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
emitColorChangeEvent();
}
});
colorSelectionPanel.add(button);
colorButtons.put(color, button);
}
private void emitColorChangeEvent() {
Set<StoneColor> colors = new HashSet<StoneColor>();
for (StoneColor color : StoneColor.values()) {
if (colorButtons.get(color).getModel().isSelected()) {
colors.add(color);
}
}
changeStoneColorsEvent.emit(colors);
}
private void makeVariantPanel() {
variantPanel = new JPanel(new GridLayout(1, 2, 5, 0));
setVariantDefaultButton = new JButton("Standard");
variantPanel.add(setVariantDefaultButton);
setVariantDefaultButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVariantDefaultEvent.emit();
}
});
setVariantChildrenButton = new JButton("Kinder");
variantPanel.add(setVariantChildrenButton);
setVariantChildrenButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVariantChildrenEvent.emit();
}
});
}
private JCheckBox createOptionCheckbox(final Event1<Boolean> targetEvent) {
final JCheckBox box = new JCheckBox();
box.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
targetEvent.emit(box.isSelected());
}
});
return box;
}
private JSpinner createOptionSpinner(int min, int max, int step,
final Event1<Integer> targetEvent) {
final JSpinner spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(min, min, max, step));
spinner
.setPreferredSize(new Dimension(60, spinner.getMinimumSize().height));
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
targetEvent.emit((Integer) spinner.getValue());
}
});
return spinner;
}
private JLabel makeOptionLabel(int row, String name) {
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.EAST;
c.gridx = 0;
c.gridy = row;
c.insets = new Insets(4, 4, 4, 4);
JLabel label = new JLabel(name);
optionsPanel.add(label, c);
return label;
}
SettingsPanel() {
setLayout(new GridBagLayout());
tabbedPane = new JTabbedPane();
createPlayerSetupPanel();
tabbedPane.addTab("Spieler", playerSetupPanel);
createOptionsPanel();
JScrollPane scrollPane = new JScrollPane(optionsPanel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
tabbedPane.addTab("Optionen", scrollPane);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1;
c.weighty = 1;
add(tabbedPane, c);
errorMessageLabel = new JLabel(" ");
c.weighty = 0;
add(errorMessageLabel, c);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridBagLayout());
add(buttonPanel, c);
startButton = createButton("Spiel starten", startGameEvent);
loadButton = createButton("Spiel laden...", loadGameEvent);
networkButton = createButton("Netzwerkspiel...", networkGameEvent);
offerButton = createButton("Spiel anbieten", offerGameEvent);
backButton = createButton("Zur\u00fcck", backEvent);
addDefaultButtons();
setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(
10, 10, 10, 10)));
}
void resetTabbedPane() {
tabbedPane.setSelectedIndex(0);
}
private void addDefaultButtons() {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridwidth = 1;
c.weightx = 1;
c.weighty = 1;
buttonPanel.add(startButton, c);
c.weightx = 0;
buttonPanel.add(Box.createHorizontalStrut(10), c);
c.weightx = 1;
buttonPanel.add(loadButton, c);
c.weightx = 0;
buttonPanel.add(Box.createHorizontalStrut(10), c);
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
buttonPanel.add(networkButton, c);
}
private void addNetworkSetupButtons() {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridwidth = 1;
c.weightx = 1;
c.weighty = 1;
buttonPanel.add(offerButton, c);
c.weightx = 0;
buttonPanel.add(Box.createHorizontalStrut(10), c);
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
buttonPanel.add(backButton, c);
}
private void addNetworkOfferButtons() {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridwidth = 1;
c.weightx = 1;
c.weighty = 1;
buttonPanel.add(startButton, c);
c.weightx = 0;
buttonPanel.add(Box.createHorizontalStrut(10), c);
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
buttonPanel.add(backButton, c);
}
private void addNetworkJoinButtons() {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1;
c.weighty = 1;
buttonPanel.add(backButton, c);
}
private JButton createButton(String title, final Event event) {
JButton button = new JButton(title);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
event.emit();
}
});
return button;
}
@Override
public void setSettingsMode(SettingsMode mode) {
settingsMode = mode;
while (!playerSettingsPanels.isEmpty()) {
removePlayerSettingsPanel();
}
buttonPanel.removeAll();
switch (mode) {
case DEFAULT:
addDefaultButtons();
enableOptions(true);
break;
case NETWORK_SETUP:
addNetworkSetupButtons();
enableOptions(true);
break;
case NETWORK_OFFER:
addNetworkOfferButtons();
enableOptions(false);
break;
case NETWORK_JOIN:
addNetworkJoinButtons();
enableOptions(false);
break;
}
}
private void enableOptions(boolean enable) {
if (enable) {
addOptionPanelComponents();
} else {
addOptionPanelLabels();
}
}
private class PlayerSettingsPanel extends JPanel {
private int playerNumber;
private JButton colorButton;
private JTextField nameField;
private JButton removeButton;
private JComboBox playerType;
private List<Type> playerTypeChoices;
private JLabel nameLabel;
private JLabel typeLabel;
public void setSettings(PlayerSettings settings) {
if (nameField != null && !nameField.getText().equals(settings.getName())) {
nameField.setText(settings.getName());
}
if (nameLabel != null) {
nameLabel.setText(settings.getName());
}
if (playerType != null) {
int index = playerTypeChoices.indexOf(settings.getType());
if (index != playerType.getSelectedIndex() && index >= 0
&& index < playerType.getModel().getSize()) {
playerType.setSelectedIndex(index);
}
}
if (typeLabel != null) {
typeLabel.setText(getTypeLabel(settings.getType()));
}
colorButton
.setIcon(ImageUtil.createColorIcon(settings.getColor(), 16, 2));
}
public void setPlayerNameEditable(boolean editable) {
if (nameField != null) {
nameField.setEditable(editable);
}
}
public void enableRemoveButton(boolean enable) {
if (removeButton != null) {
removeButton.setEnabled(enable);
}
}
class NameChangeListener implements DocumentListener {
@Override
public void insertUpdate(DocumentEvent e) {
changeName();
}
@Override
public void removeUpdate(DocumentEvent e) {
changeName();
}
@Override
public void changedUpdate(DocumentEvent e) {
changeName();
}
}
public PlayerSettingsPanel(int playerNumber, PlayerSettings settings,
List<Type> choices, boolean editable) {
setLayout(new GridBagLayout());
this.playerNumber = playerNumber;
if (editable) {
createControls(settings);
} else {
createLabels();
}
setChoices(choices);
setSettings(settings);
}
private String getTypeLabel(Type type) {
switch (type) {
case COMPUTER:
return "Computer";
case HUMAN:
return "Mensch";
case NETWORK:
case VACANT:
return "Netzwerk";
}
return null;
}
public void setChoices(List<Type> playerTypeChoices) {
this.playerTypeChoices = playerTypeChoices;
Vector<String> choices = new Vector<String>();
for (Type t : playerTypeChoices) {
choices.add(getTypeLabel(t));
}
if (playerType != null) {
playerType.setModel(new DefaultComboBoxModel(choices));
}
}
private void createControls(PlayerSettings settings) {
GridBagConstraints c = new GridBagConstraints();
GridBagConstraints c2 = new GridBagConstraints();
colorButton = new JButton();
nameField = new JTextField(settings.getName());
colorButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new ColorMenu();
}
});
c.gridy = 0;
add(colorButton, c);
nameField.getDocument().addDocumentListener(new NameChangeListener());
c2.gridy = 0;
c2.weightx = 1;
c2.fill = GridBagConstraints.HORIZONTAL;
add(nameField, c2);
playerType = new JComboBox();
playerType.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeType();
}
});
playerType.setPreferredSize(new Dimension(120, playerType
.getPreferredSize().height));
playerType.setMinimumSize(new Dimension(120,
playerType.getMinimumSize().height));
add(playerType, c);
removeButton = new JButton("\u00d7");
removeButton.setFont(removeButton.getFont().deriveFont(Font.BOLD));
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
remove();
}
});
add(removeButton, c);
}
private void createLabels() {
GridBagConstraints c = new GridBagConstraints();
GridBagConstraints c2 = new GridBagConstraints();
colorButton = new JButton();
nameLabel = new JLabel();
nameLabel.setBorder(new EmptyBorder(3, 7, 3, 7));
nameLabel.putClientProperty("html.disable", Boolean.TRUE);
colorButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new ColorMenu();
}
});
c.gridy = 0;
add(colorButton, c);
c2.gridy = 0;
c2.weightx = 1;
c2.fill = GridBagConstraints.HORIZONTAL;
add(nameLabel, c2);
typeLabel = new JLabel(" ");
typeLabel.setBorder(new EmptyBorder(3, 7, 3, 7));
typeLabel.setPreferredSize(new Dimension(120, typeLabel
.getPreferredSize().height));
typeLabel.setMinimumSize(new Dimension(120,
typeLabel.getMinimumSize().height));
add(typeLabel, c);
}
@Override
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
for (Component component : this.getComponents()) {
preferredSize
.setSize(preferredSize.width, Math.max(preferredSize.height,
component.getPreferredSize().height));
}
return preferredSize;
}
@Override
public Dimension getMaximumSize() {
Dimension preferredSize = super.getPreferredSize();
for (Component component : this.getComponents()) {
preferredSize
.setSize(Integer.MAX_VALUE, Math.max(preferredSize.height,
component.getPreferredSize().height));
}
return preferredSize;
}
private void changeName() {
changePlayerNameEvent.emit(playerNumber, nameField.getText());
}
private void changeColor(Color c) {
changePlayerColorEvent.emit(playerNumber, c);
}
private void changeType() {
changePlayerTypeEvent.emit(playerNumber,
playerTypeChoices.get(playerType.getSelectedIndex()));
}
private void remove() {
removePlayerEvent.emit(playerNumber);
}
private class ColorMenu extends JPanel {
ColorMenu() {
setLayout(new GridLayout(4, 4, 1, 1));
JPopupMenu menu = new JPopupMenu();
for (Color c : PLAYER_COLORS) {
add(new ColorButton(c, menu));
}
menu.setLayout(new BorderLayout());
menu.add(this);
menu.show(colorButton, 0, colorButton.getHeight());
}
private class ColorButton extends JLabel {
ColorButton(final Color c, final JPopupMenu menu) {
final Icon normalIcon = ImageUtil.createColorIcon(c, 16, 1);
final Icon hoverIcon = ImageUtil.createColorIcon(c, 16, 2);
setIcon(normalIcon);
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setIcon(hoverIcon);
}
@Override
public void mouseExited(MouseEvent e) {
setIcon(normalIcon);
}
@Override
public void mouseClicked(MouseEvent e) {
menu.setVisible(false);
changeColor(c);
}
});
}
}
}
}
}