/* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ /* * ChatPanel.java * * Created on 15-Dec-2009, 11:04:31 PM */ package mage.client.table; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.Icon; import javax.swing.JTable; import javax.swing.border.EmptyBorder; import javax.swing.table.AbstractTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import mage.client.MageFrame; import mage.client.chat.ChatPanelBasic; import static mage.client.chat.ChatPanelBasic.CHAT_ALPHA; import static mage.client.dialog.PreferencesDialog.KEY_USERS_COLUMNS_ORDER; import static mage.client.dialog.PreferencesDialog.KEY_USERS_COLUMNS_WIDTH; import mage.client.util.FontSizeHelper; import mage.client.util.MageTableRowSorter; import mage.client.util.gui.TableUtil; import mage.client.util.gui.countryBox.CountryCellRenderer; import mage.remote.MageRemoteException; import mage.view.RoomUsersView; import mage.view.UsersView; import net.java.balloontip.utils.ToolTipUtils; /** * * @author BetaSteward_at_googlemail.com, nantuko */ public class PlayersChatPanel extends javax.swing.JPanel { private final List players = new ArrayList<>(); private final UserTableModel userTableModel; private static final int[] DEFAULT_COLUMNS_WIDTH = {20, 100, 40, 100, 40, 100, 80, 80}; /* * Creates new form ChatPanel * */ public PlayersChatPanel() { userTableModel = new UserTableModel(); // needs to be set before initComponents(); initComponents(); setBackground(new Color(0, 0, 0, CHAT_ALPHA)); jTablePlayers.setBackground(new Color(0, 0, 0, CHAT_ALPHA)); jTablePlayers.setForeground(Color.white); jTablePlayers.setRowSorter(new MageTableRowSorter(userTableModel)); setGUISize(); TableUtil.setColumnWidthAndOrder(jTablePlayers, DEFAULT_COLUMNS_WIDTH, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER); userTableModel.initHeaderTooltips(); jTablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer()); jScrollPaneTalk.setSystemMessagesPane(colorPaneSystem); jScrollPaneTalk.setOpaque(false); jScrollPaneSystem.getViewport().setOpaque(false); colorPaneSystem.setExtBackgroundColor(new Color(0, 0, 0, CHAT_ALPHA)); // Alpha = 255 not transparent colorPaneSystem.setBorder(new EmptyBorder(5, 5, 5, 5)); if (jScrollPanePlayers != null) { jScrollPanePlayers.setBackground(new Color(0, 0, 0, CHAT_ALPHA)); jScrollPanePlayers.getViewport().setBackground(new Color(0, 0, 0, CHAT_ALPHA)); } } public ChatPanelBasic getUserChatPanel() { return jScrollPaneTalk; } public void cleanUp() { TableUtil.saveColumnWidthAndOrderToPrefs(jTablePlayers, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER); jScrollPaneTalk.cleanUp(); } public void changeGUISize() { setGUISize(); } private void setGUISize() { Font font = FontSizeHelper.getTableFont(); jTablePlayers.getTableHeader().setFont(font); jTablePlayers.getTableHeader().setPreferredSize(new Dimension(FontSizeHelper.tableHeaderHeight, FontSizeHelper.tableHeaderHeight)); font = FontSizeHelper.getTabFont(); jTabbedPaneText.setFont(font); this.revalidate(); this.repaint(); } public void setSplitDividerLocation(int location) { if (jSplitPane1 != null) { jSplitPane1.setDividerLocation(location); } } public int getSplitDividerLocation() { if (jSplitPane1 == null) { return 0; } return this.jSplitPane1.getDividerLocation(); } class UserTableModel extends AbstractTableModel { private final String[] columnNames = new String[]{"Loc", "Players", "Matches", "MQ%", "Tourneys", "TQ%", "Games", "Connection"}; private UsersView[] players = new UsersView[0]; public void loadData(Collection roomUserInfoList) throws MageRemoteException { RoomUsersView roomUserInfo = roomUserInfoList.iterator().next(); this.players = roomUserInfo.getUsersView().toArray(new UsersView[0]); JTableHeader th = jTablePlayers.getTableHeader(); TableColumnModel tcm = th.getColumnModel(); tcm.getColumn(jTablePlayers.convertColumnIndexToView(1)).setHeaderValue("Players (" + this.players.length + ")"); tcm.getColumn(jTablePlayers.convertColumnIndexToView(6)).setHeaderValue( "Games " + roomUserInfo.getNumberActiveGames() + (roomUserInfo.getNumberActiveGames() != roomUserInfo.getNumberGameThreads() ? " (T:" + roomUserInfo.getNumberGameThreads() : " (") + " limit: " + roomUserInfo.getNumberMaxGames() + ")"); th.repaint(); this.fireTableDataChanged(); } @Override public int getRowCount() { return players.length; } @Override public int getColumnCount() { return columnNames.length; } @Override public Object getValueAt(int arg0, int arg1) { switch (arg1) { case 0: return players[arg0].getFlagName(); case 1: return players[arg0].getUserName(); case 2: return players[arg0].getMatchHistory(); case 3: return players[arg0].getMatchQuitRatio(); case 4: return players[arg0].getTourneyHistory(); case 5: return players[arg0].getTourneyQuitRatio(); case 6: return players[arg0].getInfoGames(); case 7: return players[arg0].getInfoPing(); } return ""; } public void initHeaderTooltips() { ColumnHeaderToolTips tips = new ColumnHeaderToolTips(); for (int c = 0; c < jTablePlayers.getColumnCount(); c++) { String tooltipText = ""; switch (c) { case 0: tooltipText = "The flag the user has assigned to his profile" + "
You can assign the flag in the connect to server dialog window"; break; case 1: tooltipText = "Name of the user" + "
(the number behind the header text is the number of currently connected users to the server)"; break; case 2: tooltipText = "Number of matches the user played so far" + "
Q = number of matches quit" + "
I = number of matches lost because of idle timeout" + "
T = number of matches lost because of match timeout"; break; case 3: tooltipText = "%-Ratio of matches played to matches quit" + "
this calculation does not include tournament matches"; break; case 4: tooltipText = "Number of tournaments the user played so far" + "
D = number of tournaments left during draft phase" + "
C = number of tournaments left during constructing phase" + "
R = number of tournaments left during rounds"; break; case 5: tooltipText = "%-Ratio of tournament matches played to tournament matches quit" + "
this calculation does not include non tournament matches"; break; case 6: tooltipText = "Current activities of the player" + "
the header itself shows the number of currently active games" + "
T: = number of games threads " + "
(that can vary from active games because of sideboarding or crashed games)" + "
limt: the maximum of games the server is configured to" + "
(if the number of started games exceed that limit, the games have to wait" + "
until active games end)
"; break; case 7: tooltipText = "Latency of the user's connection to the server"; break; } tips.setToolTip(c, tooltipText); } JTableHeader header = jTablePlayers.getTableHeader(); header.addMouseMotionListener(tips); } @Override public String getColumnName(int columnIndex) { String colName = ""; if (columnIndex <= getColumnCount()) { colName = columnNames[columnIndex]; } return colName; } @Override public Class getColumnClass(int columnIndex) { switch (columnIndex) { case 0: return Icon.class; case 3: case 5: return Integer.class; default: return String.class; } } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return 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") // //GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; jSpinner1 = new javax.swing.JSpinner(); jSplitPane1 = new javax.swing.JSplitPane(); jScrollPanePlayers = new javax.swing.JScrollPane(); jTablePlayers = new javax.swing.JTable(); jTabbedPaneText = new javax.swing.JTabbedPane(); jScrollPaneTalk = new mage.client.chat.ChatPanelSeparated(); jScrollPaneSystem = new javax.swing.JScrollPane(); colorPaneSystem = new mage.client.components.ColorPane(); jSplitPane1.setBorder(null); jSplitPane1.setDividerSize(10); jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); jSplitPane1.setResizeWeight(0.25); jScrollPanePlayers.setBorder(null); jTablePlayers.setModel(this.userTableModel); jTablePlayers.setToolTipText("Connected players"); jTablePlayers.setAutoscrolls(false); jTablePlayers.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); jTablePlayers.setFocusable(false); jTablePlayers.setGridColor(new java.awt.Color(255, 255, 255)); jTablePlayers.setOpaque(false); jTablePlayers.setRequestFocusEnabled(false); jTablePlayers.setRowSelectionAllowed(false); jTablePlayers.setUpdateSelectionOnSort(false); jTablePlayers.setVerifyInputWhenFocusTarget(false); jScrollPanePlayers.setViewportView(jTablePlayers); jSplitPane1.setTopComponent(jScrollPanePlayers); jTabbedPaneText.setTabPlacement(javax.swing.JTabbedPane.BOTTOM); jTabbedPaneText.addTab("Talk", jScrollPaneTalk); jScrollPaneSystem.setBorder(null); jScrollPaneSystem.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); jScrollPaneSystem.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); jScrollPaneSystem.setFocusable(false); jScrollPaneSystem.setOpaque(false); colorPaneSystem.setEditable(false); colorPaneSystem.setBackground(new java.awt.Color(0, 0, 0)); colorPaneSystem.setBorder(null); colorPaneSystem.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N colorPaneSystem.setMargin(new java.awt.Insets(0, 0, 0, 0)); colorPaneSystem.setOpaque(false); jScrollPaneSystem.setViewportView(colorPaneSystem); jTabbedPaneText.addTab("System", jScrollPaneSystem); jSplitPane1.setRightComponent(jTabbedPaneText); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 350, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jSplitPane1) .addGap(0, 0, 0)) ); }// //GEN-END:initComponents public void setRoomUserInfo(List> view) { try { userTableModel.loadData(view.get(0)); } catch (Exception ex) { this.players.clear(); } } // Variables declaration - do not modify//GEN-BEGIN:variables private mage.client.components.ColorPane colorPaneSystem; private javax.swing.JScrollPane jScrollPanePlayers; private javax.swing.JScrollPane jScrollPaneSystem; private mage.client.chat.ChatPanelSeparated jScrollPaneTalk; private javax.swing.JSpinner jSpinner1; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JTabbedPane jTabbedPaneText; private javax.swing.JTable jTablePlayers; // End of variables declaration//GEN-END:variables class ColumnHeaderToolTips extends MouseMotionAdapter { int curCol; Map tips = new HashMap<>(); public void setToolTip(Integer mCol, String tooltip) { if (tooltip == null) { tips.remove(mCol); } else { tips.put(mCol, tooltip); } } @Override public void mouseMoved(MouseEvent evt) { JTableHeader header = (JTableHeader) evt.getSource(); JTable table = header.getTable(); TableColumnModel colModel = table.getColumnModel(); int vColIndex = colModel.getColumnIndexAtX(evt.getX()); TableColumn col = null; if (vColIndex >= 0) { col = colModel.getColumn(table.convertColumnIndexToModel(vColIndex)); } if (table.convertColumnIndexToModel(vColIndex) != curCol) { if (col != null) { MageFrame.getInstance().getBalloonTip().setAttachedComponent(header); MageFrame.getInstance().getBalloonTip().setTextContents(tips.get(table.convertColumnIndexToModel(vColIndex))); ToolTipUtils.balloonToToolTip(MageFrame.getInstance().getBalloonTip(), 600, 10000); } else { MageFrame.getInstance().getBalloonTip().setTextContents(""); } curCol = table.convertColumnIndexToModel(vColIndex); } } } }