/* * 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 mage.client.MageFrame; import mage.client.chat.ChatPanelBasic; import mage.client.util.GUISizeHelper; 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; import javax.swing.*; 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 java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.util.*; import java.util.List; 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; /** * * @author BetaSteward_at_googlemail.com, nantuko */ public class PlayersChatPanel extends javax.swing.JPanel { private final List<String> players = new ArrayList<>(); private final UserTableModel userTableModel; private static final int[] DEFAULT_COLUMNS_WIDTH = {20, 100, 40, 40, 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); jScrollPaneSystem.setViewportBorder(null); 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)); jScrollPanePlayers.setViewportBorder(null); } } 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() { jTablePlayers.getTableHeader().setFont(GUISizeHelper.tableFont); jTablePlayers.setFont(GUISizeHelper.tableFont); jTablePlayers.setRowHeight(GUISizeHelper.getTableRowHeight()); jScrollPanePlayers.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0)); jScrollPanePlayers.getHorizontalScrollBar().setPreferredSize(new Dimension(0, GUISizeHelper.scrollBarSize)); jScrollPaneSystem.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0)); jScrollPaneSystem.getHorizontalScrollBar().setPreferredSize(new Dimension(0, GUISizeHelper.scrollBarSize)); jTabbedPaneText.setFont(GUISizeHelper.getTabFont()); jSplitPane1.setDividerSize(GUISizeHelper.dividerBarSize); } 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", "Constructed Rating", "Limited Rating", "Matches", "MQP", "Tourneys", "TQP", "Games", "Connection"}; private UsersView[] players = new UsersView[0]; public void loadData(Collection<RoomUsersView> 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(8)).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].getConstructedRating(); case 3: return players[arg0].getLimitedRating(); case 4: return players[arg0].getMatchHistory(); case 5: return players[arg0].getMatchQuitRatio(); case 6: return players[arg0].getTourneyHistory(); case 7: return players[arg0].getTourneyQuitRatio(); case 8: return players[arg0].getInfoGames(); case 9: 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 = "<HTML><b>The flag the user has assigned to his profile</b>" + "<br>You can assign the flag in the connect to server dialog window"; break; case 1: tooltipText = "<HTML><b>Name of the user</b>" + "<br>(the number behind the header text is the number of currently connected users to the server)"; break; case 2: tooltipText = "<HTML><b>Constructed player rating</b>"; break; case 3: tooltipText = "<HTML><b>Limited player rating</b>"; break; case 4: tooltipText = "<HTML><b>Number of matches the user played so far</b>" + "<br>Q = number of matches quit" + "<br>I = number of matches lost because of idle timeout" + "<br>T = number of matches lost because of match timeout"; break; case 5: tooltipText = "<HTML><b>Percent-Ratio of matches played related to matches quit</b>" + "<br>this calculation does not include tournament matches"; break; case 6: tooltipText = "<HTML><b>Number of tournaments the user played so far</b>" + "<br>D = number of tournaments left during draft phase" + "<br>C = number of tournaments left during constructing phase" + "<br>R = number of tournaments left during rounds"; break; case 7: tooltipText = "<HTML><b>Percent-Ratio of tournament matches played related to tournament matches quit</b>" + "<br>this calculation does not include non tournament matches"; break; case 8: tooltipText = "<HTML><b>Current activities of the player</b>" + "<BR>the header itself shows the number of currently active games" + "<BR>T: = number of games threads " + "<BR><i>(that can vary from active games because of sideboarding or crashed games)</i>" + "<BR>limt: the maximum of games the server is configured to" + "<BR><i>(if the number of started games exceed that limit, the games have to wait" + "<BR>until active games end)</i>"; break; case 9: tooltipText = "<HTML><b>Latency of the user's connection to the server</b>"; 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 2: case 3: case 5: case 7: 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") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { 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.setOpaque(false); jTablePlayers.setRequestFocusEnabled(false); jTablePlayers.setRowSelectionAllowed(false); jTablePlayers.setShowHorizontalLines(false); jTablePlayers.setShowVerticalLines(false); jTablePlayers.setUpdateSelectionOnSort(false); jTablePlayers.setVerifyInputWhenFocusTarget(false); jScrollPanePlayers.setViewportView(jTablePlayers); jTablePlayers.getAccessibleContext().setAccessibleDescription(""); 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)) ); }// </editor-fold>//GEN-END:initComponents public void setRoomUserInfo(List<Collection<RoomUsersView>> 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 static class ColumnHeaderToolTips extends MouseMotionAdapter { int curCol; final Map<Integer, String> 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); JLabel content = new JLabel(tips.get(table.convertColumnIndexToModel(vColIndex))); content.setFont(GUISizeHelper.balloonTooltipFont); MageFrame.getInstance().getBalloonTip().setContents(content); ToolTipUtils.balloonToToolTip(MageFrame.getInstance().getBalloonTip(), 600, 10000); } else { MageFrame.getInstance().getBalloonTip().setTextContents(""); } curCol = table.convertColumnIndexToModel(vColIndex); } } } }