From 91a3328907bd268834ab89484d4958eba6c34baa Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 21 Jan 2019 01:10:01 +0400 Subject: [PATCH] * UI: added cell hints to player's list in lobby, fixed header hints; --- .../java/mage/client/table/ColumnInfo.java | 41 ++++ .../java/mage/client/table/MageTable.java | 57 +++++ .../mage/client/table/PlayersChatPanel.java | 225 +++++------------- .../java/mage/client/table/TableInfo.java | 47 ++++ .../java/mage/client/util/GUISizeHelper.java | 8 + .../src/main/java/mage/server/Main.java | 2 +- 6 files changed, 217 insertions(+), 163 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/table/ColumnInfo.java create mode 100644 Mage.Client/src/main/java/mage/client/table/MageTable.java create mode 100644 Mage.Client/src/main/java/mage/client/table/TableInfo.java diff --git a/Mage.Client/src/main/java/mage/client/table/ColumnInfo.java b/Mage.Client/src/main/java/mage/client/table/ColumnInfo.java new file mode 100644 index 0000000000..d8a3a9ebba --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/table/ColumnInfo.java @@ -0,0 +1,41 @@ +package mage.client.table; + +/** + * @author JayDi85 + */ +public class ColumnInfo { + private Integer index; + private Integer width; + private String headerName; + private String headerHint; + private Class colClass; + + public ColumnInfo(Integer index, Integer width, Class colClass, String headerName, String headerHint) { + this.index = index; + this.width = width; + this.colClass = colClass; + this.headerName = headerName; + this.headerHint = headerHint; + } + + + public Integer getIndex() { + return index; + } + + public Integer getWidth() { + return width; + } + + public String getHeaderName() { + return headerName; + } + + public String getHeaderHint() { + return headerHint; + } + + public Class getColClass() { + return colClass; + } +} diff --git a/Mage.Client/src/main/java/mage/client/table/MageTable.java b/Mage.Client/src/main/java/mage/client/table/MageTable.java new file mode 100644 index 0000000000..8edce11662 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/table/MageTable.java @@ -0,0 +1,57 @@ +package mage.client.table; + +import mage.client.util.GUISizeHelper; + +import javax.swing.*; +import javax.swing.table.JTableHeader; +import java.awt.event.MouseEvent; + +/** + * @author JayDi85 + */ +public class MageTable extends JTable { + + private TableInfo tableInfo; + + public MageTable(TableInfo tableInfo) { + this.tableInfo = tableInfo; + } + + @Override + public String getToolTipText(MouseEvent e) { + // default tooltip for cells + String tip = null; + java.awt.Point p = e.getPoint(); + int rowIndex = rowAtPoint(p); + rowIndex = getRowSorter().convertRowIndexToModel(rowIndex); + int colIndex = columnAtPoint(p); + + try { + tip = getValueAt(rowIndex, colIndex).toString(); + } catch (RuntimeException e1) { + //catch null pointer exception if mouse is over an empty line + } + + return GUISizeHelper.textToHtmlWithSize(tip, GUISizeHelper.tableFont); + } + + @Override + protected JTableHeader createDefaultTableHeader() { + // default tooltip for headers + return new JTableHeader(columnModel) { + public String getToolTipText(MouseEvent e) { + // html tooltip + java.awt.Point p = e.getPoint(); + int index = columnModel.getColumnIndexAtX(p.x); + int realIndex = columnModel.getColumn(index).getModelIndex(); + + String tip = tableInfo.getColumnByIndex(realIndex).getHeaderHint(); + if (tip == null) { + tip = tableInfo.getColumnByIndex(realIndex).getHeaderName(); + } + + return GUISizeHelper.textToHtmlWithSize(tip, GUISizeHelper.tableFont); + } + }; + } +} diff --git a/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java b/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java index 732e6f21a1..6bf3e0d156 100644 --- a/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/PlayersChatPanel.java @@ -1,13 +1,5 @@ - - - /* - * 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; @@ -16,18 +8,15 @@ 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.ArrayList; +import java.util.Collection; import java.util.List; import static mage.client.chat.ChatPanelBasic.CHAT_ALPHA; @@ -35,20 +24,45 @@ 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 + * @author BetaSteward_at_googlemail.com, nantuko, JayDi85 */ 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, 40, 40, 100, 40, 100, 80, 80}; + private static final TableInfo tableInfo = new TableInfo() + .addColumn(0, 20, Icon.class, "Flag", null) + .addColumn(1, 100, String.class, "Players", + "User name" + + "
(the number behind the header text is the number of users online)") + .addColumn(2, 40, Integer.class, "Constructed Rating", null) + .addColumn(3, 40, Integer.class, "Limited Rating", null) + .addColumn(4, 40, String.class, "Matches", + "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") + .addColumn(5, 100, Integer.class, "MQP", + "Percent-Ratio of matches played related to matches quit" + + "
this calculation does not include tournament matches") + .addColumn(6, 40, String.class, "Tourneys", + "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") + .addColumn(7, 100, Integer.class, "TQP", + "Percent-Ratio of tournament matches played related to tournament matches quit" + + "
this calculation does not include non tournament matches") + .addColumn(8, 80, String.class, "Games", + "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)
") + .addColumn(9, 80, String.class, "Ping", null); - - /* - * Creates new form ChatPanel - * - */ public PlayersChatPanel() { userTableModel = new UserTableModel(); // needs to be set before initComponents(); @@ -60,8 +74,7 @@ public class PlayersChatPanel extends javax.swing.JPanel { jTablePlayers.setRowSorter(new MageTableRowSorter(userTableModel)); setGUISize(); - TableUtil.setColumnWidthAndOrder(jTablePlayers, DEFAULT_COLUMNS_WIDTH, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER); - userTableModel.initHeaderTooltips(); + TableUtil.setColumnWidthAndOrder(jTablePlayers, tableInfo.getColumnsWidth(), KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER); jTablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer()); @@ -122,7 +135,6 @@ public class PlayersChatPanel extends javax.swing.JPanel { 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 roomUserInfoList) throws MageRemoteException { @@ -131,9 +143,9 @@ public class PlayersChatPanel extends javax.swing.JPanel { 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() + tcm.getColumn(jTablePlayers.convertColumnIndexToView(tableInfo.getColumnByName("Players").getIndex())).setHeaderValue("Players (" + this.players.length + ')'); + tcm.getColumn(jTablePlayers.convertColumnIndexToView(tableInfo.getColumnByName("Games").getIndex())).setHeaderValue("Games " + + roomUserInfo.getNumberActiveGames() + (roomUserInfo.getNumberActiveGames() != roomUserInfo.getNumberGameThreads() ? " (T:" + roomUserInfo.getNumberGameThreads() : " (") + " limit: " + roomUserInfo.getNumberMaxGames() + ')'); th.repaint(); @@ -147,117 +159,44 @@ public class PlayersChatPanel extends javax.swing.JPanel { @Override public int getColumnCount() { - return columnNames.length; + return tableInfo.getColumns().size(); } @Override - public Object getValueAt(int arg0, int arg1) { - switch (arg1) { + public Object getValueAt(int rowIndex, int colIndex) { + switch (colIndex) { case 0: - return players[arg0].getFlagName(); + return players[rowIndex].getFlagName(); case 1: - return players[arg0].getUserName(); + return players[rowIndex].getUserName(); case 2: - return players[arg0].getConstructedRating(); + return players[rowIndex].getConstructedRating(); case 3: - return players[arg0].getLimitedRating(); + return players[rowIndex].getLimitedRating(); case 4: - return players[arg0].getMatchHistory(); + return players[rowIndex].getMatchHistory(); case 5: - return players[arg0].getMatchQuitRatio(); + return players[rowIndex].getMatchQuitRatio(); case 6: - return players[arg0].getTourneyHistory(); + return players[rowIndex].getTourneyHistory(); case 7: - return players[arg0].getTourneyQuitRatio(); + return players[rowIndex].getTourneyQuitRatio(); case 8: - return players[arg0].getInfoGames(); + return players[rowIndex].getInfoGames(); case 9: - return players[arg0].getInfoPing(); + return players[rowIndex].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 = "Constructed player rating"; - break; - case 3: - tooltipText = "Limited player rating"; - break; - case 4: - 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 5: - tooltipText = "Percent-Ratio of matches played related to matches quit" - + "
this calculation does not include tournament matches"; - break; - case 6: - 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 7: - tooltipText = "Percent-Ratio of tournament matches played related to tournament matches quit" - + "
this calculation does not include non tournament matches"; - break; - case 8: - 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 9: - 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; + return tableInfo.getColumnByIndex(columnIndex).getHeaderName(); } @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; - } + return tableInfo.getColumnByIndex(columnIndex).getColClass(); } @Override @@ -279,7 +218,7 @@ public class PlayersChatPanel extends javax.swing.JPanel { jSpinner1 = new javax.swing.JSpinner(); jSplitPane1 = new javax.swing.JSplitPane(); jScrollPanePlayers = new javax.swing.JScrollPane(); - jTablePlayers = new javax.swing.JTable(); + jTablePlayers = new MageTable(tableInfo); jTabbedPaneText = new javax.swing.JTabbedPane(); jScrollPaneTalk = new mage.client.chat.ChatPanelSeparated(); jScrollPaneSystem = new javax.swing.JScrollPane(); @@ -332,14 +271,14 @@ public class PlayersChatPanel extends javax.swing.JPanel { 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.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)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jSplitPane1) + .addGap(0, 0, 0)) ); }// //GEN-END:initComponents @@ -350,6 +289,7 @@ public class PlayersChatPanel extends javax.swing.JPanel { this.players.clear(); } } + // Variables declaration - do not modify//GEN-BEGIN:variables private mage.client.components.ColorPane colorPaneSystem; private javax.swing.JScrollPane jScrollPanePlayers; @@ -358,45 +298,6 @@ public class PlayersChatPanel extends javax.swing.JPanel { private javax.swing.JSpinner jSpinner1; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JTabbedPane jTabbedPaneText; - private javax.swing.JTable jTablePlayers; + private MageTable jTablePlayers; // End of variables declaration//GEN-END:variables - - static class ColumnHeaderToolTips extends MouseMotionAdapter { - - int curCol; - final 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); - 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); - } - } - } - } diff --git a/Mage.Client/src/main/java/mage/client/table/TableInfo.java b/Mage.Client/src/main/java/mage/client/table/TableInfo.java new file mode 100644 index 0000000000..4839dbbc1c --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/table/TableInfo.java @@ -0,0 +1,47 @@ +package mage.client.table; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author JayDi85 + */ +public class TableInfo { + + private List columns = new ArrayList<>(); + + public TableInfo() { + + } + + public TableInfo addColumn(Integer index, Integer width, Class colClass, String headerName, String headerHint) { + this.columns.add(new ColumnInfo(index, width, colClass, headerName, headerHint)); + return this; + } + + public int[] getColumnsWidth() { + return this.columns.stream().mapToInt(ColumnInfo::getIndex).toArray(); + } + + public List getColumns() { + return this.columns; + } + + public ColumnInfo getColumnByIndex(int index) { + for (ColumnInfo col : this.columns) { + if (col.getIndex().equals(index)) { + return col; + } + } + return null; + } + + public ColumnInfo getColumnByName(String name) { + for (ColumnInfo col : this.columns) { + if (col.getHeaderName().equals(name)) { + return col; + } + } + return null; + } +} diff --git a/Mage.Client/src/main/java/mage/client/util/GUISizeHelper.java b/Mage.Client/src/main/java/mage/client/util/GUISizeHelper.java index 790fe34e03..6ea1424acc 100644 --- a/Mage.Client/src/main/java/mage/client/util/GUISizeHelper.java +++ b/Mage.Client/src/main/java/mage/client/util/GUISizeHelper.java @@ -8,6 +8,7 @@ package mage.client.util; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; +import java.util.Locale; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; @@ -178,4 +179,11 @@ public final class GUISizeHelper { } } } + + public static String textToHtmlWithSize(String text, Font font) { + if (text != null && !text.toLowerCase(Locale.ENGLISH).startsWith("")) { + return "

" + text + "

"; + } + return text; + } } diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java index 06dc38db0f..531d2736c9 100644 --- a/Mage.Server/src/main/java/mage/server/Main.java +++ b/Mage.Server/src/main/java/mage/server/Main.java @@ -418,7 +418,7 @@ public final class Main { File[] files = directory.listFiles( (dir, name) -> name.endsWith(".game") ); - if(files != null) { + if (files != null) { for (File file : files) { file.delete(); }