package cryodex.widget; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.event.*; import cryodex.CryodexController; import cryodex.Player; import cryodex.modules.Module; /** * Panel for the creation of players. Also contains the donation link. * * @author cbrown * */ public class RegisterPanel extends JPanel { private static final long serialVersionUID = 1L; private static final String filterHint = "Filter Player List"; private JButton saveButton; private JButton deleteButton; private JButton cancelButton; private JList<Player> playerList; private JTextField nameField; private DefaultListModel<Player> userModel; private JLabel counterLabel; private JLabel donationLabel; private JTextField groupField; private JTextField emailField; private JPanel playerInfoPanel; private JPanel playerPanel; private JTextField playerSearchField; private JButton clearFilter; private boolean filtering = false; public RegisterPanel() { super(new BorderLayout()); this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // Panel set up to push everything to the top this.add(getPlayerPanel(), BorderLayout.NORTH); this.add(new JPanel(), BorderLayout.CENTER); } /** * Main panel layout * * @return */ private JPanel getPlayerPanel() { if (playerPanel == null) { playerPanel = new JPanel(new BorderLayout()); JLabel playersTitle = new JLabel("<html><b>Player Info</b></html>"); playersTitle.setFont(new Font(playersTitle.getFont().getName(), playersTitle.getFont().getStyle(), 20)); JScrollPane listScroller = new JScrollPane(getPlayerList()); listScroller.setPreferredSize(new Dimension(150, 250)); JPanel labelPanel = ComponentUtils.addToVerticalBorderLayout(getCounterLabel(), getDonationLabel(), null); JPanel southPanel = ComponentUtils.addToVerticalBorderLayout(null, listScroller, labelPanel); playerPanel.add(playersTitle, BorderLayout.NORTH); playerPanel.add(getPlayerInfoPanel(), BorderLayout.CENTER); playerPanel.add(southPanel, BorderLayout.SOUTH); } return playerPanel; } /** * Information input * * @return */ private JPanel getPlayerInfoPanel() { if (playerInfoPanel == null) { playerInfoPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.anchor = GridBagConstraints.WEST; playerInfoPanel.add(new JLabel("Name"), gbc); gbc.gridy++; gbc.anchor = GridBagConstraints.EAST; playerInfoPanel.add(getNameField(), gbc); gbc.gridy++; playerInfoPanel.add(new JLabel("Group Name"), gbc); gbc.gridy++; playerInfoPanel.add(getGroupNameField(), gbc); gbc.gridy++; playerInfoPanel.add(new JLabel("Email Address"), gbc); gbc.gridy++; playerInfoPanel.add(getEmailField(), gbc); for (Module m : CryodexController.getModules()) { gbc.gridy++; playerInfoPanel.add(m.getRegistration().getPanel(), gbc); } gbc.gridy++; playerInfoPanel.add(ComponentUtils.addToHorizontalBorderLayout(getSaveButton(), getCancelButton(), getDeleteButton()), gbc); gbc.gridy++; playerInfoPanel.add(ComponentUtils.addToHorizontalBorderLayout(getPlayerFilterTextField(), null, getClearFilterButton()), gbc); } return playerInfoPanel; } private JTextField getNameField() { if (nameField == null) { nameField = new JTextField(); } return nameField; } private JTextField getGroupNameField() { if (groupField == null) { groupField = new JTextField(); } return groupField; } private JTextField getEmailField() { if (emailField == null) { emailField = new JTextField(); } return emailField; } private JButton getSaveButton() { if (saveButton == null) { saveButton = new JButton("Save"); saveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // ///////////////////////////// // Update general information // ///////////////////////////// String name = getNameField().getText(); String groupName = getGroupNameField().getText(); String email = getEmailField().getText(); if (name == null || name.isEmpty()) { JOptionPane.showMessageDialog((Component) null, "Name is required", "Error", JOptionPane.ERROR_MESSAGE); return; } // Create new player or get previous player instance Player player; if (getPlayerList().getSelectedIndex() == -1) { for (Player p : CryodexController.getPlayers()) { if (p.getName().equals(name)) { JOptionPane.showMessageDialog((Component) null, "This player name already exists.", "Error", JOptionPane.ERROR_MESSAGE); return; } } player = new Player(); CryodexController.getPlayers().add(player); getUserModel().addElement(player); sortPlayer(); } else { player = getPlayerList().getSelectedValue(); } player.setName(name); if (groupName != null) { player.setGroupName(groupName); } player.setEmail(email); for (Module m : CryodexController.getModules()) { m.getRegistration().save(player); } clearFields(); CryodexController.saveData(); EventQueue.invokeLater(new Runnable() { @Override public void run() { getNameField().grabFocus(); getNameField().requestFocus(); } }); updateCounterLabel(); } }); } return saveButton; } private JButton getDeleteButton() { if (deleteButton == null) { deleteButton = new JButton("Delete"); deleteButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { CryodexController.getPlayers().remove(getPlayerList().getSelectedValue()); getUserModel().removeElement(getPlayerList().getSelectedValue()); clearFields(); CryodexController.saveData(); updateCounterLabel(); // Fix to prevent the filter textbox from stealing focus after a delete playerSearchField.transferFocus(); } }); deleteButton.setEnabled(false); } return deleteButton; } private JButton getCancelButton() { if (cancelButton == null) { cancelButton = new JButton("Cancel"); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { clearFields(); updateCounterLabel(); } }); } return cancelButton; } private void clearFields() { getNameField().setText(""); getPlayerList().clearSelection(); getDeleteButton().setEnabled(false); getNameField().setRequestFocusEnabled(true); getGroupNameField().setText(""); getEmailField().setText(""); for (Module m : CryodexController.getModules()) { m.getRegistration().clearFields(); } } public void addPlayers(List<Player> players) { for (Player p : players) { getUserModel().addElement(p); } sortPlayer(); } public void removeAllPlayers(){ getUserModel().removeAllElements(); } public void sortPlayer() { List<Player> players = Collections.list(getUserModel().elements()); Collections.sort(players); getUserModel().removeAllElements(); for (Player p : players) { getUserModel().addElement(p); } } private DefaultListModel<Player> getUserModel() { if (userModel == null) { userModel = new DefaultListModel<Player>(); userModel.addListDataListener(new ListDataListener() { @Override public void intervalRemoved(ListDataEvent e) { updateCounterLabel(); } @Override public void intervalAdded(ListDataEvent e) { updateCounterLabel(); } @Override public void contentsChanged(ListDataEvent e) { updateCounterLabel(); } }); } return userModel; } private JList<Player> getPlayerList() { if (playerList == null) { playerList = new JList<Player>(getUserModel()); playerList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); playerList.setLayoutOrientation(JList.VERTICAL); playerList.setVisibleRowCount(-1); playerList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent arg0) { Player player = playerList.getSelectedValue(); if (player == null) { getDeleteButton().setEnabled(false); } else { getDeleteButton().setEnabled(true); getNameField().setText(player.getName()); getGroupNameField().setText(player.getGroupName()); getEmailField().setText(player.getEmail()); for (Module m : CryodexController.getModules()) { m.getRegistration().load(player); } } updateCounterLabel(); } }); } return playerList; } public void updateCounterLabel() { getCounterLabel().setText("Player Count: " + getUserModel().getSize()); } public JLabel getCounterLabel() { if (counterLabel == null) { counterLabel = new JLabel(); } return counterLabel; } public JLabel getDonationLabel() { if (donationLabel == null) { donationLabel = new JLabel("<html><a href=\"\">Donate To Cryodex</a></html>"); donationLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); donationLabel.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent arg0) { CryodexController.sendDonation(); } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent arg0) { } @Override public void mouseReleased(MouseEvent arg0) { } }); } return donationLabel; } public void registerButton() { this.getRootPane().setDefaultButton(getSaveButton()); } public void importPlayers(List<Player> players) { for (Player p : players) { CryodexController.getPlayers().add(p); getUserModel().addElement(p); } sortPlayer(); CryodexController.saveData(); } public JTextField getPlayerFilterTextField() { if (playerSearchField == null) { playerSearchField = new JTextField(filterHint, 10); playerSearchField.addFocusListener(new FocusListener() { @Override public void focusGained(FocusEvent e) { if (playerSearchField.getText().equals(filterHint)) { playerSearchField.setText(""); } } @Override public void focusLost(FocusEvent e) { if (playerSearchField.getText().trim().equals("")) { playerSearchField.setText(filterHint); } } }); playerSearchField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { filterPlayerList(playerSearchField.getText().trim().toLowerCase()); } @Override public void removeUpdate(DocumentEvent e) { filterPlayerList(playerSearchField.getText().trim().toLowerCase()); } @Override public void changedUpdate(DocumentEvent e) { filterPlayerList(playerSearchField.getText().trim().toLowerCase()); } }); } return playerSearchField; } /** * Filter list to only include elements whose toString function contains the filterText. Elements that have a word * that starts with the filter text are given priority. */ private void filterPlayerList(String filterText) { // Prevent the function from multiple simultaneous executions if (!filtering) { filtering = true; List<Player> preFilteredPlayerList = new ArrayList<Player>(CryodexController.getPlayers()); Collections.sort(preFilteredPlayerList); List<Player> filteredPlayerList = new ArrayList<>(); getUserModel().removeAllElements(); // Reset list for blank filter if (filterText.equals("") || filterText.equalsIgnoreCase(filterHint)) { for (Player element : preFilteredPlayerList) { getUserModel().addElement(element); } updateCounterLabel(); } else { filteredPlayerList.clear(); // Check the beginning of each word for (Player element : preFilteredPlayerList) { String[] name = element.toString().toLowerCase().split(" "); for (String s : name) { if (s.startsWith(filterText)) { filteredPlayerList.add(element); break; } } } // Check if the element contains the text for (Player element : preFilteredPlayerList) { if (element.toString().contains(filterText) && !filteredPlayerList.contains(element)) { filteredPlayerList.add(element); } } // Add all matching elements to the list for (Player element : filteredPlayerList) { getUserModel().addElement(element); } updateCounterLabel(); } filtering = false; } } public JButton getClearFilterButton() { if (clearFilter == null) { clearFilter = new JButton("Clear Filter"); clearFilter.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { playerSearchField.setText(filterHint); filterPlayerList(filterHint); } }); } return clearFilter; } }