/* * LobbyWindow.java * * Created on Apr 5, 2009, 12:47:25 PM * * This file is a part of Shoddy Battle. * Copyright (C) 2009 Catherine Fitzpatrick and Benjamin Gwin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, visit the Free Software Foundation, Inc. * online at http://gnu.org. */ package shoddybattleclient; import java.awt.Color; import java.awt.Component; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.net.URL; import java.text.SimpleDateFormat; import javax.swing.*; import java.util.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import shoddybattleclient.forms.AdminPanel; import shoddybattleclient.forms.AdminPanel.ChannelLookup; import shoddybattleclient.forms.BattlePanel; import shoddybattleclient.forms.FindPanel; import shoddybattleclient.forms.UserPanel; import shoddybattleclient.network.ServerLink; import shoddybattleclient.network.ServerLink.BanElement; import shoddybattleclient.network.ServerLink.ChallengeMediator; import shoddybattleclient.shoddybattle.Generation; import shoddybattleclient.shoddybattle.Generation.RuleSet; import shoddybattleclient.utils.*; import shoddybattleclient.utils.ClauseList.Clause; import shoddybattleclient.utils.CloseableTabbedPane.TabCloseListener; /** * * @author ben */ public class LobbyWindow extends javax.swing.JFrame implements TabCloseListener, ChannelLookup { public static class Channel { //User flags public static final int PROTECTED = 1; // +a public static final int OP = 2; // +o public static final int VOICE = 4; // +v public static final int MUTE = 8; // +b public static final int IDLE = 16; // inactive public static final int BUSY = 32; // ("ignoring challenges") //Channel flags public static final int MUTED = 1; // +m muted room public static final int INVITE = 2; // +i invite only public static final String[] MODES = { "a", "o", "v", "b"}; public static final String[] CHANNEL_MODES = {"m", "i"}; public static final int TYPE_ORDINARY = 0; public static final int TYPE_BATTLE = 1; public static final int TYPE_PRIVATE_MESSAGE = 2; public static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("dd/MM/yyyy kk:mm:ss"); private int m_id; private int m_type; private String m_name; private String m_topic; private int m_flags; private ChatPane m_chat; // TOOD: Do not assume the background is white. public static ColourMap COLOUR_MAP = new ColourMap(Color.WHITE); private UserListModel m_users = new UserListModel(); public void setChatPane(ChatPane c) { m_chat = c; } public ChatPane getChatPane() { return m_chat; } public UserListModel getModel() { return m_users; } public static int getLevel(int flags) { if ((flags & PROTECTED) != 0) return 3; if ((flags & OP) != 0) return 2; if ((flags & VOICE) != 0) return 1; if ((flags & MUTE) != 0) return -1; return 0; } public Channel(int id, int type, String name, String topic, int flags) { m_id = id; m_type = type; m_name = name; m_topic = topic; m_flags = flags; } public void addUser(String name, int flags) { m_users.addUser(new User(name, flags)); } public void removeUser(String name) { m_users.removeUser(name); } private String getModeString(int oldflags, int newflags, boolean channel) { String[] modeNames = channel ? CHANNEL_MODES : MODES; int diff = oldflags ^ newflags; if (diff == 0) return null; StringBuilder modes = new StringBuilder(); String last = null; for (int i = 0; i < modeNames.length; ++i) { int bit = 1 << i; if ((diff & bit) != 0) { String prefix = ((oldflags & bit) != 0) ? "-" : "+"; if (!prefix.equals(last)) { modes.append(prefix); } last = prefix; modes.append(modeNames[i]); } } return modes.toString(); } //sets the flags for this channel public void setFlags(String setter, int flags) { String modes = getModeString(m_flags, flags, true); if (modes == null) return; m_flags = flags; String msg = Text.getText(27, 0, new String[] {setter, modes, ""}); msg = "<font class='mode'>" + msg + "</font>"; m_chat.getLobby().showChannelMessage(this, null, msg, false); } public void updateUser(String setter, String name, int flags) { User user = getUser(name); int old = user.getFlags(); String modes = getModeString(old, flags, false); if (modes == null) return; String msg; if (setter.length() > 0) { msg = Text.getText(27, 0, new String[] { setter, modes, name }); } else { msg = Text.getText(27, 1, new String[] { modes, name }); } msg = "<font class='mode'>" + msg + "</font>"; m_chat.getLobby().showChannelMessage(this, null, msg, false); m_users.setLevel(user, flags); } public boolean isMuted() { if ((m_flags & MUTED) != 0) { return true; } return false; } public boolean isInviteOnly() { if ((m_flags & INVITE) != 0) { return true; } return false; } public void informBan(String mod, String user, int date) { if (date == 0) { //kick String msg = Text.getText(27, 2, new String[] {user, mod}); m_chat.addMessage(null, "<b class='kick'>" + msg + "</b>", false); } else if (date == -1) { //unban String msg = Text.getText(27, 4, new String[] {user}); m_chat.addMessage(null, "<b class='unban'>" + msg + "</b>", false); } else if (date > 0) { String dateStr = Text.formatDateDifference(date); String msg = Text.getText(27, 3, new String[] {user, mod, dateStr}); m_chat.addMessage(null, "<b class='ban'>" + msg + "</b>", false); } } public static String getUserHtml(User user, Color color) { return user.getHtml(color); } public static String getUserHtml(User user) { return getUserHtml(user, COLOUR_MAP.getColour(user.getName())); } public String getTopic() { return m_topic; } public void setTopic(String topic) { m_topic = topic; } public String getName() { return m_name; } int getId() { return m_id; } public User getUser(String name) { for (int i = 0; i < m_users.getSize(); i++) { User u = (User)m_users.getElementAt(i); if (u.m_name.equalsIgnoreCase(name)) { return u; } } return null; } public int getType() { return m_type; } } public static class UserCellRenderer extends JLabel implements ListCellRenderer { private static final ImageIcon[] STATUS_ICONS = new ImageIcon[3]; static { STATUS_ICONS[0] = getModeIcon("voice.png"); STATUS_ICONS[1] = getModeIcon("operator.png"); STATUS_ICONS[2] = getModeIcon("protected.png"); } public static ImageIcon getModeIcon(String file) { return new ImageIcon(Toolkit.getDefaultToolkit() .createImage(GameVisualisation.class.getResource( "resources/modes/" + file))); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { User user = (User)value; int level = user.getLevel(); if (level > 0) { setIcon(STATUS_ICONS[level - 1]); } else { setIcon(null); } if (isSelected) { setText("<html>" + Channel.getUserHtml( user, list.getSelectionForeground()) + "</html>"); setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setText("<html>" + Channel.getUserHtml(user) + "</html>"); setBackground(list.getBackground()); setForeground(list.getForeground()); } setEnabled(list.isEnabled()); setFont(list.getFont()); setOpaque(true); return this; } } /** * Algorithm for assigning to each string a colour that contrasts well with * the background */ public static class ColourMap { private static final int BRIGHTNESS_DELTA = 40000;//100000; private static final int COLOUR_DELTA = 500; private static final Random m_random = new Random(2718281); private static final Color[] m_colours = new Color[255]; private static int getBrightness(Color c) { return c.getRed() * 299 + c.getGreen() * 587 + c.getBlue() * 114; } private static int getDifference(Color c1, Color c2) { int r1 = c1.getRed(); int g1 = c1.getGreen(); int b1 = c1.getBlue(); int r2 = c2.getRed(); int g2 = c2.getGreen(); int b2 = c2.getBlue(); return Math.max(r1, r2) - Math.min(r1, r2) + Math.max(g1, g2) - Math.min(g1, g2) + Math.max(b1, b2) - Math.min(b1, b2); } private static Color getColour() { int r = m_random.nextInt(256); int g = m_random.nextInt(256); int b = m_random.nextInt(256); return new Color(r, g, b); } private static Color getVisibleColour(Color background) { while (true) { Color c = getColour(); int b = getBrightness(c); int delta = Math.abs(b - getBrightness(background)); if ((delta > BRIGHTNESS_DELTA) && (getDifference(c, background) > COLOUR_DELTA)) return c; } } public ColourMap(Color background) { Set<Color> set = new HashSet<Color>(); for (int i = 0; i < m_colours.length; ++i) { Color c = getVisibleColour(background); while (set.contains(c)) { c = getVisibleColour(background); } set.add(c); } set.toArray(m_colours); } public Color getColour(Object key) { return m_colours[Math.abs(key.hashCode() % m_colours.length)]; } } public static class User implements Comparable { private String m_name; private int m_status = 0; private int m_flags, m_level; private Map<Integer, String> m_battles = new HashMap<Integer, String>(); public User(String name, int flags) { m_name = name; m_flags = flags; m_level = Channel.getLevel(flags); } public int getFlags() { return m_flags; } public void setLevel(int flags) { m_flags = flags; m_level = Channel.getLevel(flags); } public int getLevel() { return m_level; } public void setStatus(int status) { m_status = status; } public String getName() { return m_name; } public boolean hasMute() { return ((m_flags & Channel.MUTE) != 0); } @Override public int compareTo(Object o2) { User u2 = ((User)o2); if (m_level > u2.m_level) return -1; if (m_level < u2.m_level) return 1; if (m_status < u2.m_status) return -1; if (m_status > u2.m_status) return 1; String s2 = u2.m_name; return m_name.compareToIgnoreCase(s2); } public String getPrefix() { String[] prefixes = { "", "+", "@", "&" }; return prefixes[m_level]; } public void addBattle(int id, String opponent) { m_battles.put(id, opponent); } public void removeBattle(int id) { m_battles.remove(id); } @Override public boolean equals(Object o2) { if(o2 == null) return false; if(!this.getClass().equals(o2.getClass())) return false; return ((User)o2).m_name.equalsIgnoreCase(m_name); } @Override public int hashCode() { return m_name.toUpperCase().hashCode(); } @Override public String toString() { return m_name; } public String getHtml(Color c) { if (m_level != -1) { int r = c.getRed(); int g = c.getGreen(); int b = c.getBlue(); String colour = "rgb(" + r + "," + g + "," + b + ")"; String style = (m_battles.size() > 0) ? "font-style: italic;" : ""; return "<font class='name' style='color: " + colour + style + "'>" + m_name + "</font>"; } return "<font class='muted'>" + m_name + "</font>"; } } private class PopupListener extends MouseAdapter { int m_level = 0; public void setLevel(int level) { m_level = level; } public void mouseReleased(MouseEvent e) { triggerPopup(e); } public void mousePressed(MouseEvent e) { triggerPopup(e); } private void triggerPopup(MouseEvent e) { if (e.isPopupTrigger()) { //If the source is an HTMLPane then it is the chat if (e.getSource().getClass().getSimpleName().equals("HTMLPane")) { // This menu annoys me (Cathy), so I'm disabling it for now. //new ChatPopupMenu(LobbyWindow.this, m_level) // .show(e.getComponent(), e.getX(), e.getY()); } else { int idx = listUsers.locationToIndex(e.getPoint()); if (idx < 0) return; listUsers.setSelectedIndex(idx); User u = (User)((UserListModel)listUsers.getModel()).getElementAt(idx); new UserPopupMenu(LobbyWindow.this, u, m_level) .show(e.getComponent(), e.getX(), e.getY()); } } } }; private String m_name; private ServerLink m_link; private Map<Integer, Channel> m_channels = new HashMap<Integer, Channel>(); private Map<String, UserPanel> m_userPanels = new HashMap<String, UserPanel>(); private Map<String, Channel> m_privateMessages = new HashMap<String, Channel>(); final private BattlePanel m_battlePanel; final private FindPanel m_findPanel; final private AdminPanel m_adminPanel; //The most recent channel that was focused private Channel m_recentChannel = null; final private PopupListener m_popupListener = new PopupListener(); public void setChatChannels(String[] chats) { mnuJoinChannel.removeAll(); for (final String i : chats) { JMenuItem item = new JMenuItem("#" + i); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { m_link.joinChannel(i); } }); mnuJoinChannel.add(item); } } public BattlePanel getBattlePanel() { return m_battlePanel; } public Channel getChannel(String name) { for (Channel i : m_channels.values()) { if (name.equals(i.getName())) { return i; } } return null; } public void addChannel(Channel channel) { String name = "#" + channel.getName(); Channel previous = m_channels.get(channel.m_id); m_channels.put(channel.m_id, channel); if (tabChats.indexOfTab(name) == -1) { previous = null; } ChatPane c = (previous == null) ? new ChatPane(channel, this, m_name) : previous.getChatPane(); channel.setChatPane(c); c.setName(name); if (channel.getType() == Channel.TYPE_BATTLE) { return; } c.addMessage(null, "<b>The topic for " + name + " is: " + channel.getTopic() + "</b>", false); if (previous == null) { tabChats.addTab(name, c); tabChats.setSelectedComponent(c); } listUsers.setModel(channel.getModel()); } public Channel getChannel(int id) { return m_channels.get(id); } public void handleJoinPart(int id, String user, boolean join) { Channel channel = m_channels.get(id); if (channel != null) { if (join) { channel.addUser(user, 0); } else { channel.removeUser(user); } } if (channel.getType() == Channel.TYPE_BATTLE) { BattleWindow wnd = m_link.getBattle(channel.getId()); if (wnd != null) wnd.refreshUsers(); } } public FindPanel getFindPanel() { return m_findPanel; } private void openBattleTab() { if (tabChats.indexOfComponent(m_battlePanel) == -1) { tabChats.add("Battles", m_battlePanel); } } private void openFindTab() { if (tabChats.indexOfComponent(m_findPanel) == -1) { tabChats.add("Find", m_findPanel); } } /** Creates new form LobbyWindow */ public LobbyWindow(ServerLink link, String userName) { initComponents(); m_link = link; m_link.setLobbyWindow(this); m_battlePanel = new BattlePanel(m_link); m_findPanel = new FindPanel(m_link); m_adminPanel = new AdminPanel(m_link); m_name = userName; openBattleTab(); openFindTab(); listUsers.setCellRenderer(new UserCellRenderer()); tabChats.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (tabChats.getSelectedIndex() == -1) { listUsers.setModel(new UserListModel()); return; } ((CloseableTabbedPane)tabChats).setFlashingAt(tabChats.getSelectedIndex(), false); Component comp = tabChats.getSelectedComponent(); if (comp instanceof ChatPane) { ChatPane c = (ChatPane)comp; Channel channel = c.getChannel(); c.getChat().addMouseListener(m_popupListener); m_recentChannel = channel; listUsers.setModel(channel.getModel()); User u = channel.getUser(m_name); if (u != null) { m_popupListener.setLevel(u.getLevel()); } } else if (comp instanceof BattlePanel) { m_link.requestChannelList(); } } }); ((CloseableTabbedPane)tabChats).addTabCloseListener(this); setTitle("Pokemon Lab - " + userName); mnuPreferences.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); mnuQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); mnuLeaveServer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); listUsers.addMouseListener(m_popupListener); } public ServerLink getLink() { return m_link; } public static void viewWebPage(URL page) { try { BareBonesBrowserLaunch.openURL(page); } catch (Exception e) { System.out.println("Failed to open url " + page); } } /** * Takes some letters and returns a list of matching usernames */ public List<String> autocompleteUser(String str) { str = str.toLowerCase(); UserListModel model = (UserListModel)listUsers.getModel(); List<String> list = model.getNames(); List<String> ret = new ArrayList<String>(); for (String name : list) { if (name.toLowerCase().startsWith(str)) { ret.add(name); } } return ret; } public void addChallenge(String name, boolean incoming, int gen, int n, int teamLength, int metagame, RuleSet rules) { if (Preference.ignoring(name)) { m_link.resolveChallenge(name, false, null); return; } UserPanel panel = openUserPanel(name, gen, n, teamLength, metagame, rules); CloseableTabbedPane closeable = (CloseableTabbedPane)tabChats; int idx = closeable.indexOfComponent(panel); closeable.setFlashingAt(idx, true); } public ChallengeMediator getChallengeMediator(String name) { UserPanel panel = m_userPanels.get(name); if (panel != null) { return panel.getMediator(); } else { return null; } } public void cancelChallenge(String name) { } public ChatPane getChat() { return (ChatPane)tabChats.getSelectedComponent(); } public String getUserName() { return m_name; } private void updateBattleUsers(int id) { BattleWindow wnd = m_link.getBattle(id); if (wnd != null) wnd.refreshUsers(); } public void handleUpdateStatus(int id, String setter, String user, int flags) { Channel channel = m_channels.get(id); if (channel != null) { if ("".equals(user)) { channel.setFlags(setter, flags); return; } channel.updateUser(setter, user, flags); if (user.equalsIgnoreCase(m_name)) { m_popupListener.setLevel(channel.getUser(m_name).getLevel()); } if (channel.getType() == Channel.TYPE_BATTLE) { updateBattleUsers(channel.getId()); } } } public void showChannelMessage(Channel channel, String user, String message, boolean encode) { if (channel.getType() == Channel.TYPE_ORDINARY) { channel.getChatPane().addMessage(user, message, encode); } else { // battle chat message BattleWindow wnd = m_link.getBattle(channel.getId()); if (wnd != null) wnd.addMessage(user, message, encode); } } public void handleChannelMessage(int id, String user, String message) { if (Preference.ignoring(user) && !user.equals(m_name)) return; Channel channel = m_channels.get(id); if (channel != null) { User u = channel.getUser(user); String userString = user; if (u != null) { String prefix = u.getPrefix(); userString = prefix + Channel.getUserHtml(u); } showChannelMessage(channel, userString, message, true); } } public void closeTab(int index) { tabChats.removeTabAt(index); } public UserPanel openUserPanel(String user, boolean incoming, int generation, int n, int teamLength, int metagame, RuleSet rules) { UserPanel panel = m_userPanels.get(user); if (panel == null) { int index = tabChats.getTabCount(); panel = new UserPanel(user, m_link, index); tabChats.add(user, panel); m_userPanels.put(user, panel); } if (incoming) { panel.setIncoming(); panel.setOptions(n, teamLength, generation, metagame, rules); } else { tabChats.setSelectedComponent(panel); } return panel; } public boolean isUserPanelSelected(String user) { UserPanel panel = m_userPanels.get(user); Component selected = tabChats.getSelectedComponent(); if (panel == selected) return true; return false; } public void removeUserPanel(String user) { UserPanel panel = m_userPanels.get(user); this.closeTab(tabChats.indexOfComponent(panel)); m_userPanels.remove(user); } public void openUserPanel(String user) { openUserPanel(user, false, 0, 0, 0, -1, null); } public UserPanel openUserPanel(String user, int generation, int n, int teamLength, int metagame, RuleSet rules) { return openUserPanel(user, true, generation, n, teamLength, metagame, rules); } @Override public void tabClosed(Component c) { if (c instanceof UserPanel) { UserPanel panel = (UserPanel)c; m_userPanels.remove(panel.getOpponent()); } } public void handleBanMessage(int id, String mod, String user, int date) { if (id == -1) { for (Channel c : m_channels.values()) { if (c.getType() == Channel.TYPE_ORDINARY) { c.informBan(mod, user, date); } } } else { Channel c = m_channels.get(id); if (c != null) c.informBan(mod, user, date); } } public Channel openPrivateMessage(String user, boolean select) { if (user.equals(m_name)) { return null; } if (Preference.ignoring(user)) { // Sending messages to ignored users but not getting any replies // may be perceived as a bug. JOptionPane.showMessageDialog(this, "This user is ignored", "Error", JOptionPane.ERROR_MESSAGE); return null; } String name = "PM: " + user; Channel channel = m_privateMessages.get(user); if (channel == null) { channel = new Channel(-2, Channel.TYPE_PRIVATE_MESSAGE, user, "", 0); ChatPane chat = new ChatPane(channel, this, m_name); channel.setChatPane(chat); channel.addUser(user, 0); channel.addUser(m_name, 0); m_privateMessages.put(user, channel); tabChats.add(name, chat); } if (select) { tabChats.setSelectedComponent(channel.getChatPane()); } else { if (tabChats.getSelectedComponent() != channel.getChatPane()) { ((CloseableTabbedPane)tabChats).setFlashingAt( tabChats.indexOfComponent(channel.getChatPane()), true); } } return channel; } public void handleInvalidPrivateMessage(String user) { Channel chat = openPrivateMessage(user, false); String msg = user + " is not online."; msg = Text.addClass(msg, "important"); chat.getChatPane().addMessage(null, msg, false); } public void handlePrivateMessage(String user, String sender, String message) { if (Preference.ignoring(user)) { return; } Channel chat = openPrivateMessage(user, false); User u = chat.getUser(sender); chat.getChatPane().addMessage(Channel.getUserHtml(u), message, true); } public void closePrivateMessage(String user) { m_privateMessages.remove(user); } public void handleImportantMessage(int channel, String sender, String message) { message += " ~ " + sender; message = Text.addClass(message, "important"); if (channel == -1) { for (Channel c : m_channels.values()) { this.showChannelMessage(c, null, message, false); } } else { Channel c = m_channels.get(channel); if (c != null) { this.showChannelMessage(c, null, message, false); } } } public void informBadLookup() { m_adminPanel.setErrorText("No such user"); } public void showLookupResults(String user, String ip, List<String> aliases, List<BanElement> bans) { m_adminPanel.updateDetails(user, ip, aliases, bans); tabChats.add("Admin", m_adminPanel); tabChats.setSelectedComponent(m_adminPanel); } public String getChannelName(int id) { if (id == -1) { return "[global]"; } Channel c = m_channels.get(id); if (c == null) { return null; } else { return c.getName(); } } public int getActiveChannel() { if (m_recentChannel == null) return -1; return m_recentChannel.getId(); } public void informInvalidTeam(String user, int teamSize, int[] clauses) { boolean[] invalidTraits = new boolean[9]; StringBuilder clauseList = new StringBuilder(); List<Clause> cl = m_link.getClauseList(); for (int i = 0; i < clauses.length; i++) { if (clauses[i] < 0) { int problem = (-clauses[i]-1) / teamSize; invalidTraits[problem] = true; } else { clauseList.append(" -"); clauseList.append(cl.get(clauses[i]).name); clauseList.append("\n"); } } StringBuilder sb = new StringBuilder(); sb.append("The supplied team does not conform to:\n"); if (invalidTraits[8]) sb.append(" -Unbanned Pokemon\n"); if (invalidTraits[0]) sb.append(" -1 to 4 Unique Moves\n"); if (invalidTraits[1]) sb.append(" -Legal Learnsets\n"); if (invalidTraits[2]) sb.append(" -Legal Move Combinations\n"); if (invalidTraits[3]) sb.append(" -Valid PP ups\n"); if (invalidTraits[4]) sb.append(" -Legal Items\n"); if (invalidTraits[5]) sb.append(" -Legal Ability\n"); if (invalidTraits[6]) sb.append(" -Correct Genders\n"); if (invalidTraits[7]) sb.append(" -Legal Stats\n"); sb.append(clauseList.toString()); if (!"".equals(user)) { UserPanel panel = m_userPanels.get(user); if (panel != null) { panel.unsetTeam(); } } else { m_findPanel.unsetTeam(); } JOptionPane.showMessageDialog(this, sb.toString()); } public void addImportantMessage(String msg) { msg = Text.addClass(msg, "important"); for (Component c : tabChats.getComponents()) { if (c instanceof ChatPane) { ((ChatPane)c).addMessage(null, msg, false); } } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); jMenu2 = new javax.swing.JMenu(); btnChallenge = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); listUsers = new javax.swing.JList(); tabChats = new shoddybattleclient.utils.CloseableTabbedPane(); jMenuBar2 = new javax.swing.JMenuBar(); jMenu3 = new javax.swing.JMenu(); mnuTeamBuilder = new javax.swing.JMenuItem(); jSeparator3 = new javax.swing.JSeparator(); mnuJoinChannel = new javax.swing.JMenu(); mnuBattleList = new javax.swing.JMenuItem(); mnuFind = new javax.swing.JMenuItem(); jSeparator2 = new javax.swing.JSeparator(); mnuPreferences = new javax.swing.JMenuItem(); mnuLeaveServer = new javax.swing.JMenuItem(); mnuQuit = new javax.swing.JMenuItem(); jMenu4 = new javax.swing.JMenu(); chkAway = new javax.swing.JCheckBoxMenuItem(); chkIgnoreChallenge = new javax.swing.JCheckBoxMenuItem(); jSeparator1 = new javax.swing.JSeparator(); mnuPersonalMessage = new javax.swing.JMenuItem(); jMenu1.setText("File"); jMenuBar1.add(jMenu1); jMenu2.setText("Edit"); jMenuBar1.add(jMenu2); setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); setLocationByPlatform(true); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { formWindowClosing(evt); } }); btnChallenge.setText("Challenge"); btnChallenge.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnChallengeActionPerformed(evt); } }); listUsers.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jScrollPane1.setViewportView(listUsers); jMenu3.setText("File"); mnuTeamBuilder.setText("Team Builder"); mnuTeamBuilder.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mnuTeamBuilderActionPerformed(evt); } }); jMenu3.add(mnuTeamBuilder); jMenu3.add(jSeparator3); mnuJoinChannel.setText("Join Channel"); jMenu3.add(mnuJoinChannel); mnuBattleList.setText("Battle List"); mnuBattleList.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mnuBattleListActionPerformed(evt); } }); jMenu3.add(mnuBattleList); mnuFind.setText("Find"); mnuFind.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mnuFindActionPerformed(evt); } }); jMenu3.add(mnuFind); jMenu3.add(jSeparator2); mnuPreferences.setText("Preferences"); mnuPreferences.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mnuPreferencesActionPerformed(evt); } }); jMenu3.add(mnuPreferences); mnuLeaveServer.setText("Leave Server"); mnuLeaveServer.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mnuLeaveServerActionPerformed(evt); } }); jMenu3.add(mnuLeaveServer); mnuQuit.setText("Quit"); mnuQuit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mnuQuitActionPerformed(evt); } }); jMenu3.add(mnuQuit); jMenuBar2.add(jMenu3); jMenu4.setText("Status"); chkAway.setText("Away"); jMenu4.add(chkAway); chkIgnoreChallenge.setText("Ignoring Challenges"); jMenu4.add(chkIgnoreChallenge); jMenu4.add(jSeparator1); mnuPersonalMessage.setText("Personal Message"); mnuPersonalMessage.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mnuPersonalMessageActionPerformed(evt); } }); jMenu4.add(mnuPersonalMessage); jMenuBar2.add(jMenu4); setJMenuBar(jMenuBar2); org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() .addContainerGap() .add(tabChats, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 108, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(btnChallenge, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 110, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(tabChats, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE) .add(layout.createSequentialGroup() .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE) .add(9, 9, 9) .add(btnChallenge))) .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing if (confirmLeave()) { this.dispose(); m_link.close(); new WelcomeWindow().setVisible(true); } }//GEN-LAST:event_formWindowClosing private void btnChallengeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChallengeActionPerformed User user = (User)listUsers.getSelectedValue(); if (user == null) return; String opponent = user.getName(); if (opponent.equals(m_name) && false) { // todo: internationalisation JOptionPane.showMessageDialog(this, "You cannot challenge yourself."); } else { openUserPanel(opponent); } }//GEN-LAST:event_btnChallengeActionPerformed private void mnuPersonalMessageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuPersonalMessageActionPerformed new PersonalMessageDialog(m_link).setVisible(true); }//GEN-LAST:event_mnuPersonalMessageActionPerformed private void mnuQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuQuitActionPerformed if (confirmLeave()) { System.exit(0); } }//GEN-LAST:event_mnuQuitActionPerformed private void mnuLeaveServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuLeaveServerActionPerformed formWindowClosing(null); }//GEN-LAST:event_mnuLeaveServerActionPerformed private void mnuPreferencesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuPreferencesActionPerformed new PreferencePane().setVisible(true); }//GEN-LAST:event_mnuPreferencesActionPerformed private void mnuBattleListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuBattleListActionPerformed openBattleTab(); tabChats.setSelectedComponent(m_battlePanel); m_link.requestChannelList(); }//GEN-LAST:event_mnuBattleListActionPerformed private void mnuFindActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuFindActionPerformed openFindTab(); tabChats.setSelectedComponent(m_findPanel); }//GEN-LAST:event_mnuFindActionPerformed private void mnuTeamBuilderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuTeamBuilderActionPerformed List<String> items = Generation.loadItems(); Generation generation = m_link.getGenerations()[0]; new TeamBuilder(generation).setVisible(true); }//GEN-LAST:event_mnuTeamBuilderActionPerformed // prompts the user to confirm that they wish to leave the server private boolean confirmLeave() { if (!m_link.isAlive()) return true; int response = JOptionPane.showConfirmDialog(this, "Are you sure you " + "want to leave this server?", "Disconnecting...", JOptionPane.YES_NO_OPTION); return (response == JOptionPane.YES_OPTION); } /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { LobbyWindow lw = new LobbyWindow(null, "Ben"); lw.setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnChallenge; private javax.swing.JCheckBoxMenuItem chkAway; private javax.swing.JCheckBoxMenuItem chkIgnoreChallenge; private javax.swing.JMenu jMenu1; private javax.swing.JMenu jMenu2; private javax.swing.JMenu jMenu3; private javax.swing.JMenu jMenu4; private javax.swing.JMenuBar jMenuBar1; private javax.swing.JMenuBar jMenuBar2; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator2; private javax.swing.JSeparator jSeparator3; private javax.swing.JList listUsers; private javax.swing.JMenuItem mnuBattleList; private javax.swing.JMenuItem mnuFind; private javax.swing.JMenu mnuJoinChannel; private javax.swing.JMenuItem mnuLeaveServer; private javax.swing.JMenuItem mnuPersonalMessage; private javax.swing.JMenuItem mnuPreferences; private javax.swing.JMenuItem mnuQuit; private javax.swing.JMenuItem mnuTeamBuilder; private shoddybattleclient.utils.CloseableTabbedPane tabChats; // End of variables declaration//GEN-END:variables }