package jrummikub.view.impl; import java.awt.BorderLayout; import java.awt.Color; 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.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.LinkedList; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import jrummikub.model.GameSettings; import jrummikub.model.PlayerSettings; import jrummikub.util.Event1; import jrummikub.util.IEvent1; import jrummikub.view.ISettingsPanel; @SuppressWarnings("serial") class SettingsPanel extends JPanel implements ISettingsPanel { private final static Color[] PLAYER_COLORS = { new Color(1.0f, 0, 0), // red new Color(0, 1.0f, 0), // lime new Color(1.0f, 1.0f, 0), // yellow new Color(0, 0, 1.0f), // blue new Color(1.0f, 0, 1.0f), // fuchsia new Color(0, 1.0f, 1.0f), // aqua new Color(0.5f, 0, 0), // maroon new Color(0, 0.5f, 0), // green new Color(0.5f, 0.5f, 0), // olive new Color(0, 0, 0.5f), // navy new Color(0.5f, 0, 0.5f), // purple new Color(0, 0.5f, 0.5f), // teal new Color(0, 0, 0), // black new Color(0.5f, 0.5f, 0.5f), // gray new Color(0.75f, 0.75f, 0.75f), // silver new Color(1.0f, 1.0f, 1.0f), // white }; private JPanel playerSetupPanel; private JPanel playerSettingsViewport; private JPanel ruleSetupPanel; private GameSettings gameSettings = new GameSettings(); private LinkedList playerSettingsPanels = new LinkedList(); private Event1 settingsChangeEvent = new Event1(); private Event1 startGameEvent = new Event1(); @Override public IEvent1 getSettingsChangeEvent() { return settingsChangeEvent; } @Override public IEvent1 getStartGameEvent() { return startGameEvent; } private void addPlayerSettings() { // Find unused player name int num = playerSettingsPanels.size(); nameLoop: while (true) { num++; String playerName = "Spieler " + num; for (PlayerSettings player : gameSettings.getPlayerList()) { if (playerName.equals(player.getName())) { continue nameLoop; } } break; } // Next, find unused color Color color = null; colorLoop: for (Color c : PLAYER_COLORS) { color = c; for (PlayerSettings player : gameSettings.getPlayerList()) { if (c == player.getColor()) { continue colorLoop; } } break; } PlayerSettingsPanel panel = new PlayerSettingsPanel("Spieler " + num, color); playerSettingsPanels.add(panel); playerSettingsViewport.add(panel, playerSettingsViewport.getComponentCount() - 1); settingsChangeEvent.emit(gameSettings); } 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); JButton addPlayerButton = new JButton("+"); addPlayerButton.setFont(addPlayerButton.getFont().deriveFont(Font.BOLD)); addPlayerButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { addPlayerSettings(); playerSettingsViewport.revalidate(); } }); addPlayerPanel.add(addPlayerButton); addPlayerSettings(); addPlayerSettings(); } private void createRuleSetupPanel() { ruleSetupPanel = new JPanel(); } SettingsPanel() { setLayout(new GridBagLayout()); final JTabbedPane tabbedPane = new JTabbedPane(); createPlayerSetupPanel(); tabbedPane.addTab("Spieler", playerSetupPanel); createRuleSetupPanel(); tabbedPane.addTab("Regeln", ruleSetupPanel); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1; c.weighty = 1; add(tabbedPane, c); JLabel errorMessageLabel = new JLabel(" "); errorMessageLabel.setForeground(Color.RED); c.weighty = 0; add(errorMessageLabel, c); JButton startButton = new JButton("Spiel starten"); startButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { startGameEvent.emit(gameSettings); } }); add(startButton, c); setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder( 10, 10, 10, 10))); } private class PlayerSettingsPanel extends JPanel { private JTextField nameField; private JButton colorButton; private PlayerSettings settings; private void remove() { playerSettingsPanels.remove(PlayerSettingsPanel.this); playerSettingsViewport.remove(PlayerSettingsPanel.this); playerSettingsViewport.revalidate(); gameSettings.getPlayerList().remove(settings); settingsChangeEvent.emit(gameSettings); } private void updateColor() { colorButton .setIcon(ImageUtil.createColorIcon(settings.getColor(), 16, 2)); } private void setName() { if (nameField.getText() == settings.getName()) { return; } settings.setName(nameField.getText()); settingsChangeEvent.emit(gameSettings); } private void setColor(Color c) { if (c == settings.getColor()) { return; } // Exchange colors if the color is already used for (PlayerSettingsPanel other : playerSettingsPanels) { if (other.settings.getColor() == c) { other.settings.setColor(settings.getColor()); other.updateColor(); break; } } settings.setColor(c); updateColor(); settingsChangeEvent.emit(gameSettings); } PlayerSettingsPanel(String name, Color color) { settings = new PlayerSettings(name, color); setLayout(new BorderLayout()); colorButton = new JButton(); updateColor(); colorButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new ColorMenu(); } }); add(colorButton, BorderLayout.WEST); nameField = new JTextField(settings.getName()); nameField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { setName(); } @Override public void removeUpdate(DocumentEvent e) { setName(); } @Override public void changedUpdate(DocumentEvent e) { setName(); } }); add(nameField); JButton removeButton = new JButton("\u00d7"); removeButton.setFont(removeButton.getFont().deriveFont(Font.BOLD)); removeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { remove(); } }); add(removeButton, BorderLayout.EAST); gameSettings.getPlayerList().add(settings); } @Override public Dimension getPreferredSize() { return getComponent(1).getPreferredSize(); } @Override public Dimension getMaximumSize() { return new Dimension(Integer.MAX_VALUE, getPreferredSize().height); } 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); setColor(c); } }); } } } } }