package jrummikub.view.impl; import java.awt.Color; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Collections; import java.util.List; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListCellRenderer; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import jrummikub.model.PlayerSettings; import jrummikub.model.PlayerSettings.Type; import jrummikub.util.Event; import jrummikub.util.Event1; import jrummikub.util.GameData; import jrummikub.util.IEvent; import jrummikub.util.IEvent1; import jrummikub.util.Pair; import jrummikub.view.IGameListPanel; class GameListPanel extends JPanel implements IGameListPanel { private static final long serialVersionUID = 1L; private JLabel title; private JList gameList; private JButton joinButton; private JButton openNewGameButton; private JButton cancelButton; private Event1 joinEvent = new Event1(); private Event openNewGameEvent = new Event(); private Event cancelEvent = new Event(); private List games = Collections.emptyList(); /** * Creates new game list panel */ GameListPanel() { setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1; c.weighty = 0; title = new JLabel(); title.setFont(title.getFont().deriveFont(16.0f)); title.putClientProperty("html.disable", Boolean.TRUE); add(title, c); add(Box.createVerticalStrut(3), c); createGameList(); add(Box.createVerticalStrut(3), c); addButtons(c); setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10))); } /** * Creates the game list to be displayed in the panel */ private void createGameList() { GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1; c.weighty = 1; gameList = new JList(); gameList.setCellRenderer(new GameDataCellRenderer()); gameList.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { join(); } } }); gameList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { Object data = gameList.getSelectedValue(); if (data instanceof GameData) { GameData gameData = (GameData) data; Pair playerSlotCount = getPlayerSlotCount(gameData); joinButton.setEnabled(playerSlotCount.getFirst() < playerSlotCount .getSecond()); } else { joinButton.setEnabled(false); } } }); add(new JScrollPane(gameList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), c); } /** * Adds all three buttons to the panel * * @param c * constraints for button positioning */ private void addButtons(GridBagConstraints c) { joinButton = new JButton("Beitreten"); c.gridwidth = 1; joinButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { join(); } }); joinButton.setEnabled(false); add(joinButton, c); c.weightx = 0; add(Box.createHorizontalStrut(10), c); openNewGameButton = new JButton("Neues Spiel"); c.weightx = 1; add(openNewGameButton, c); openNewGameButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { openNewGameEvent.emit(); } }); c.weightx = 0; add(Box.createHorizontalStrut(10), c); cancelButton = new JButton("Abbrechen"); c.weightx = 1; c.weighty = 0; c.gridwidth = GridBagConstraints.REMAINDER; add(cancelButton, c); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { cancelEvent.emit(); } }); } /** * Resets panel if all games have been removed from list */ void reset() { games.clear(); } @Override public void setChannelName(String name) { title.setText("Spiele in " + name + ":"); } @Override public void setGameList(List games) { this.games = games; Object currentGame = gameList.getSelectedValue(); gameList.setListData(games.toArray()); if (games.contains(currentGame)) { gameList.setSelectedValue(currentGame, false); } else if (!games.isEmpty()) { gameList.setSelectedIndex(0); } } @Override public IEvent getOpenNewGameEvent() { return openNewGameEvent; } @Override public IEvent1 getJoinEvent() { return joinEvent; } @Override public IEvent getCancelEvent() { return cancelEvent; } /** * Emits a join event if a user selects a game and dedides to join it */ private void join() { Object data = gameList.getSelectedValue(); if (data instanceof GameData) { joinEvent.emit((GameData) data); } } /** * Counts the empty slots for network players in a game * * @param gameData * of the game * @return Pair of occupied spaces and vacant spaces */ private static Pair getPlayerSlotCount(GameData gameData) { int total = gameData.getGameSettings().getPlayerList().size(); int occupied = total; for (PlayerSettings player : gameData.getGameSettings().getPlayerList()) { if (player.getType() == Type.VACANT) { occupied--; } } return new Pair(occupied, total); } /** * Class presenting the game data in a readable way */ private static class GameDataCellRenderer extends JPanel implements ListCellRenderer { private static final long serialVersionUID = -892701906163443927L; JLabel hostLabel, playerCountLabel; /** * Create new game data cell renderer */ GameDataCellRenderer() { setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.gridwidth = 1; c.weightx = 1; c.weighty = 1; hostLabel = new JLabel(); hostLabel.setOpaque(true); hostLabel.setHorizontalAlignment(JLabel.LEFT); add(hostLabel, c); playerCountLabel = new JLabel(); playerCountLabel.setOpaque(true); playerCountLabel.setHorizontalAlignment(JLabel.RIGHT); c.gridwidth = GridBagConstraints.REMAINDER; add(playerCountLabel, c); } @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { String host = "", playerCount = ""; if (value instanceof GameData && ((GameData) value).getGameSettings() != null) { GameData gameData = (GameData) value; host = gameData.getHost(); Pair playerSlotCount = getPlayerSlotCount(gameData); playerCount = playerSlotCount.getFirst() + "/" + playerSlotCount.getSecond(); } else { host = String.valueOf(value); } hostLabel.setText(host); playerCountLabel.setText(playerCount); if (isSelected) { hostLabel.setBackground(list.getSelectionBackground()); hostLabel.setForeground(list.getSelectionForeground()); playerCountLabel.setBackground(list.getSelectionBackground()); playerCountLabel.setForeground(list.getSelectionForeground()); } else { hostLabel.setBackground(list.getBackground()); hostLabel.setForeground(list.getForeground()); playerCountLabel.setBackground(list.getBackground()); playerCountLabel.setForeground(list.getForeground()); } setEnabled(list.isEnabled()); setFont(list.getFont()); return this; } } }