Added some tooltips to user table headers. History is shown in tournament player table now. Changed ratio column to numberic format.

This commit is contained in:
LevelX2 2016-02-06 21:22:51 +01:00
parent 82fed1ed87
commit 687ab7ec6b
18 changed files with 239 additions and 89 deletions

View file

@ -73,12 +73,12 @@
<artifactId>forms_rt</artifactId> <artifactId>forms_rt</artifactId>
<version>7.0.3</version> <version>7.0.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<type>jar</type> <type>jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>mage-counter-plugin</artifactId> <artifactId>mage-counter-plugin</artifactId>
@ -131,6 +131,11 @@
<artifactId>tritonus_share</artifactId> <artifactId>tritonus_share</artifactId>
<version>0.3.6</version> <version>0.3.6</version>
</dependency> </dependency>
<dependency>
<groupId>net.java.balloontip</groupId>
<artifactId>balloontip</artifactId>
<version>1.2.4.1</version>
</dependency>
</dependencies> </dependencies>
<!-- to get the reference to local repository with com\googlecode\jspf\jspf-core\0.9.1\ --> <!-- to get the reference to local repository with com\googlecode\jspf\jspf-core\0.9.1\ -->

View file

@ -128,6 +128,9 @@ import mage.remote.SessionImpl;
import mage.utils.MageVersion; import mage.utils.MageVersion;
import mage.view.GameEndView; import mage.view.GameEndView;
import mage.view.UserRequestMessage; import mage.view.UserRequestMessage;
import net.java.balloontip.BalloonTip;
import net.java.balloontip.positioners.LeftAbovePositioner;
import net.java.balloontip.styles.EdgedBalloonStyle;
import net.java.truevfs.access.TArchiveDetector; import net.java.truevfs.access.TArchiveDetector;
import net.java.truevfs.access.TConfig; import net.java.truevfs.access.TConfig;
import net.java.truevfs.kernel.spec.FsAccessOption; import net.java.truevfs.kernel.spec.FsAccessOption;
@ -176,6 +179,8 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static long startTime; private static long startTime;
private BalloonTip balloonTip;
/** /**
* @return the session * @return the session
*/ */
@ -298,6 +303,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
} }
}); });
// balloonTip = new BalloonTip(desktopPane, "", new ModernBalloonStyle(0, 0, Color.WHITE, Color.YELLOW, Color.BLUE), false);
balloonTip = new BalloonTip(desktopPane, "", new EdgedBalloonStyle(Color.WHITE, Color.BLUE), false);
balloonTip.setPositioner(new LeftAbovePositioner(0, 0));
mageToolbar.add(new javax.swing.JToolBar.Separator()); mageToolbar.add(new javax.swing.JToolBar.Separator());
mageToolbar.add(createWindowsButton()); mageToolbar.add(createWindowsButton());
@ -352,6 +361,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_CHECK, "false").equals("true")) { if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_CHECK, "false").equals("true")) {
checkForNewImages(); checkForNewImages();
} }
updateMemUsageTask.execute(); updateMemUsageTask.execute();
LOGGER.info("Client start up time: " + ((System.currentTimeMillis() - startTime) / 1000 + " seconds")); LOGGER.info("Client start up time: " + ((System.currentTimeMillis() - startTime) / 1000 + " seconds"));
if (autoConnect()) { if (autoConnect()) {
@ -360,6 +370,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
connectDialog.showDialog(); connectDialog.showDialog();
} }
setWindowTitle(); setWindowTitle();
} }
}); });
@ -1043,11 +1054,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (setActive) { if (setActive) {
setActive(tablesPane); setActive(tablesPane);
} else // if other panel was already shown, mamke sure it's topmost again } else // if other panel was already shown, mamke sure it's topmost again
{ if (topPanebefore != null) {
if (topPanebefore != null) {
setActive(topPanebefore); setActive(topPanebefore);
} }
}
} }
public void hideGames() { public void hideGames() {
@ -1291,6 +1300,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
DRAFTS.put(draftId, draftPanel); DRAFTS.put(draftId, draftPanel);
} }
public BalloonTip getBalloonTip() {
return balloonTip;
}
@Override @Override
public void connected(final String message) { public void connected(final String message) {
if (SwingUtilities.isEventDispatchThread()) { if (SwingUtilities.isEventDispatchThread()) {

View file

@ -1,4 +1,4 @@
<?xml version="1.1" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo"> <Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties> <Properties>

View file

@ -24,14 +24,13 @@
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
/* /*
* MagePane.java * MagePane.java
* *
* Created on 15-Dec-2009, 9:34:25 PM * Created on 15-Dec-2009, 9:34:25 PM
*/ */
package mage.client; package mage.client;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
@ -46,9 +45,11 @@ import org.apache.log4j.Logger;
*/ */
public abstract class MagePane extends javax.swing.JInternalFrame { public abstract class MagePane extends javax.swing.JInternalFrame {
private static final Logger logger = Logger.getLogger(MagePane.class); private static final Logger LOGGER = Logger.getLogger(MagePane.class);
/** Creates new form MagePane */ /**
* Creates new form MagePane
*/
public MagePane() { public MagePane() {
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
initComponents(); initComponents();
@ -90,10 +91,10 @@ public abstract class MagePane extends javax.swing.JInternalFrame {
} }
/** This method is called from within the constructor to /**
* initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is always
* always regenerated by the Form Editor. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -115,8 +116,6 @@ public abstract class MagePane extends javax.swing.JInternalFrame {
pack(); pack();
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View file

@ -60,7 +60,8 @@ import org.apache.log4j.Logger;
*/ */
public class TableWaitingDialog extends MageDialog { public class TableWaitingDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(TableWaitingDialog.class); private static final Logger LOGGER = Logger.getLogger(TableWaitingDialog.class);
private static final int[] DEFAULT_COLUMS_WIDTH = {20, 50, 100, 100, 100};
private UUID tableId; private UUID tableId;
private UUID roomId; private UUID roomId;
@ -68,7 +69,6 @@ public class TableWaitingDialog extends MageDialog {
private Session session; private Session session;
private final TableWaitModel tableWaitModel; private final TableWaitModel tableWaitModel;
private UpdateSeatsTask updateTask; private UpdateSeatsTask updateTask;
private static final int[] defaultColumnsWidth = {20, 50, 100, 100, 100};
/** /**
* Creates new form TableWaitingDialog * Creates new form TableWaitingDialog
@ -88,7 +88,7 @@ public class TableWaitingDialog extends MageDialog {
chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE);
tableSeats.createDefaultColumnsFromModel(); tableSeats.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tableSeats, defaultColumnsWidth, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); TableUtil.setColumnWidthAndOrder(tableSeats, DEFAULT_COLUMS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
tableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer()); tableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer());
MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart); MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart);
@ -280,7 +280,7 @@ public class TableWaitingDialog extends MageDialog {
} }
} catch (Exception e) { } catch (Exception e) {
//swallow exception //swallow exception
logger.error(e); LOGGER.error(e);
} }
closeDialog(); closeDialog();
}//GEN-LAST:event_btnCancelActionPerformed }//GEN-LAST:event_btnCancelActionPerformed

View file

@ -34,14 +34,21 @@
package mage.client.table; package mage.client.table;
import java.awt.Color; import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader; import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel; import javax.swing.table.TableColumnModel;
import mage.client.MageFrame;
import mage.client.chat.ChatPanelBasic; import mage.client.chat.ChatPanelBasic;
import static mage.client.chat.ChatPanelBasic.CHAT_ALPHA; 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_ORDER;
@ -52,6 +59,7 @@ import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.remote.MageRemoteException; import mage.remote.MageRemoteException;
import mage.view.RoomUsersView; import mage.view.RoomUsersView;
import mage.view.UsersView; import mage.view.UsersView;
import net.java.balloontip.utils.ToolTipUtils;
/** /**
* *
@ -79,6 +87,8 @@ public class PlayersChatPanel extends javax.swing.JPanel {
jTablePlayers.setRowSorter(new MageTableRowSorter(userTableModel)); jTablePlayers.setRowSorter(new MageTableRowSorter(userTableModel));
TableUtil.setColumnWidthAndOrder(jTablePlayers, DEFAULT_COLUMNS_WIDTH, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER); TableUtil.setColumnWidthAndOrder(jTablePlayers, DEFAULT_COLUMNS_WIDTH, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER);
userTableModel.initHeaderTooltips();
jTablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer()); jTablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer());
jScrollPaneTalk.setSystemMessagesPane(colorPaneSystem); jScrollPaneTalk.setSystemMessagesPane(colorPaneSystem);
@ -169,10 +179,61 @@ public class PlayersChatPanel extends javax.swing.JPanel {
return ""; 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>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 3:
tooltipText = "<HTML><b>%-Ratio of matches played to matches quit</b>"
+ "<br>this calculation does not include tournament matches";
break;
case 4:
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 5:
tooltipText = "<HTML><b>%-Ratio of tournament matches played to tournament matches quit</b>"
+ "<br>this calculation does not include non tournament matches";
break;
case 6:
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 7:
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 @Override
public String getColumnName(int columnIndex) { public String getColumnName(int columnIndex) {
String colName = ""; String colName = "";
if (columnIndex <= getColumnCount()) { if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex]; colName = columnNames[columnIndex];
} }
@ -185,6 +246,9 @@ public class PlayersChatPanel extends javax.swing.JPanel {
switch (columnIndex) { switch (columnIndex) {
case 0: case 0:
return Icon.class; return Icon.class;
case 3:
case 5:
return Integer.class;
default: default:
return String.class; return String.class;
} }
@ -290,4 +354,41 @@ public class PlayersChatPanel extends javax.swing.JPanel {
private javax.swing.JTabbedPane jTabbedPaneText; private javax.swing.JTabbedPane jTabbedPaneText;
private javax.swing.JTable jTablePlayers; private javax.swing.JTable jTablePlayers;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
class ColumnHeaderToolTips extends MouseMotionAdapter {
int curCol;
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);
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);
}
}
}
} }

View file

@ -100,7 +100,8 @@ import org.apache.log4j.Logger;
*/ */
public class TablesPanel extends javax.swing.JPanel { public class TablesPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(TablesPanel.class); private static final Logger LOGGER = Logger.getLogger(TablesPanel.class);
private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 60};
private TableTableModel tableModel; private TableTableModel tableModel;
private MatchesTableModel matchesModel; private MatchesTableModel matchesModel;
@ -119,8 +120,6 @@ public class TablesPanel extends javax.swing.JPanel {
JToggleButton[] filterButtons; JToggleButton[] filterButtons;
private static final int[] defaultColumnsWidth = {35, 150, 120, 180, 80, 120, 80, 60, 40, 60};
/** /**
* Creates new form TablesPanel * Creates new form TablesPanel
*/ */
@ -138,7 +137,7 @@ public class TablesPanel extends javax.swing.JPanel {
activeTablesSorter = new MageTableRowSorter(tableModel); activeTablesSorter = new MageTableRowSorter(tableModel);
tableTables.setRowSorter(activeTablesSorter); tableTables.setRowSorter(activeTablesSorter);
TableUtil.setColumnWidthAndOrder(tableTables, defaultColumnsWidth, TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH,
PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER); PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER);
tableCompleted.setRowSorter(new MageTableRowSorter(matchesModel)); tableCompleted.setRowSorter(new MageTableRowSorter(matchesModel));
@ -187,18 +186,18 @@ public class TablesPanel extends javax.swing.JPanel {
try { try {
frame.setSelected(true); frame.setSelected(true);
} catch (PropertyVetoException ve) { } catch (PropertyVetoException ve) {
logger.error(ve); LOGGER.error(ve);
} }
} }
} }
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
logger.error(ex); LOGGER.error(ex);
} }
return; return;
} }
if (isTournament) { if (isTournament) {
logger.info("Joining tournament " + tableId); LOGGER.info("Joining tournament " + tableId);
if (deckType.startsWith("Limited")) { if (deckType.startsWith("Limited")) {
if (!status.endsWith("PW")) { if (!status.endsWith("PW")) {
session.joinTournamentTable(roomId, tableId, session.getUserName(), "Human", 1, null, ""); session.joinTournamentTable(roomId, tableId, session.getUserName(), "Human", 1, null, "");
@ -209,7 +208,7 @@ public class TablesPanel extends javax.swing.JPanel {
joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited"));
} }
} else { } else {
logger.info("Joining table " + tableId); LOGGER.info("Joining table " + tableId);
joinTableDialog.showDialog(roomId, tableId, false, false); joinTableDialog.showDialog(roomId, tableId, false, false);
} }
break; break;
@ -220,18 +219,18 @@ public class TablesPanel extends javax.swing.JPanel {
break; break;
case "Show": case "Show":
if (isTournament) { if (isTournament) {
logger.info("Showing tournament table " + tableId); LOGGER.info("Showing tournament table " + tableId);
session.watchTable(roomId, tableId); session.watchTable(roomId, tableId);
} }
break; break;
case "Watch": case "Watch":
if (!isTournament) { if (!isTournament) {
logger.info("Watching table " + tableId); LOGGER.info("Watching table " + tableId);
session.watchTable(roomId, tableId); session.watchTable(roomId, tableId);
} }
break; break;
case "Replay": case "Replay":
logger.info("Replaying game " + gameId); LOGGER.info("Replaying game " + gameId);
session.replayGame(gameId); session.replayGame(gameId);
break; break;
} }
@ -258,7 +257,7 @@ public class TablesPanel extends javax.swing.JPanel {
break; break;
case "Show":; case "Show":;
if (matchesModel.isTournament(modelRow)) { if (matchesModel.isTournament(modelRow)) {
logger.info("Showing tournament table " + matchesModel.getTableId(modelRow)); LOGGER.info("Showing tournament table " + matchesModel.getTableId(modelRow));
session.watchTable(roomId, matchesModel.getTableId(modelRow)); session.watchTable(roomId, matchesModel.getTableId(modelRow));
} }
break; break;
@ -1177,7 +1176,7 @@ public class TablesPanel extends javax.swing.JPanel {
}//GEN-LAST:event_btnStateFinishedActionPerformed }//GEN-LAST:event_btnStateFinishedActionPerformed
private void handleError(Exception ex) { private void handleError(Exception ex) {
logger.fatal("Error loading deck: ", ex); LOGGER.fatal("Error loading deck: ", ex);
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE);
} }

View file

@ -26,7 +26,7 @@
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
/* /*
* TournamentPanel.java * TournamentPanel.java
* *
* Created on 20-Jan-2011, 9:18:30 PM * Created on 20-Jan-2011, 9:18:30 PM
@ -72,7 +72,10 @@ import org.apache.log4j.Logger;
*/ */
public class TournamentPanel extends javax.swing.JPanel { public class TournamentPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(TournamentPanel.class); private static final Logger LOGGER = Logger.getLogger(TournamentPanel.class);
private static final int[] DEFAULT_COLUMNS_WIDTH_PLAYERS = {30, 150, 150, 60, 400, 100};
private static final int[] DEFAULT_COLUMNS_WIDTH_MATCHES = {60, 140, 140, 400, 80};
private UUID tournamentId; private UUID tournamentId;
private boolean firstInitDone = false; private boolean firstInitDone = false;
@ -82,9 +85,6 @@ public class TournamentPanel extends javax.swing.JPanel {
private UpdateTournamentTask updateTask; private UpdateTournamentTask updateTask;
private final DateFormat df; private final DateFormat df;
private static final int[] defaultColumnsWidthPlayers = {30, 150, 150, 60, 400};
private static final int[] defaultColumnsWidthMatches = {60, 140, 140, 400, 80};
/** /**
* Creates new form TournamentPanel * Creates new form TournamentPanel
*/ */
@ -99,11 +99,11 @@ public class TournamentPanel extends javax.swing.JPanel {
df = DateFormat.getDateTimeInstance(); df = DateFormat.getDateTimeInstance();
tablePlayers.createDefaultColumnsFromModel(); tablePlayers.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tablePlayers, defaultColumnsWidthPlayers, KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH, KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER); TableUtil.setColumnWidthAndOrder(tablePlayers, DEFAULT_COLUMNS_WIDTH_PLAYERS, KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH, KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER);
tablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer()); tablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer());
tableMatches.createDefaultColumnsFromModel(); tableMatches.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tableMatches, defaultColumnsWidthMatches, KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH, KEY_TOURNAMENT_MATCH_COLUMNS_ORDER); TableUtil.setColumnWidthAndOrder(tableMatches, DEFAULT_COLUMNS_WIDTH_MATCHES, KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH, KEY_TOURNAMENT_MATCH_COLUMNS_ORDER);
chatPanel1.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); chatPanel1.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE);
chatPanel1.setChatType(ChatPanelBasic.ChatType.TOURNAMENT); chatPanel1.setChatType(ChatPanelBasic.ChatType.TOURNAMENT);
@ -123,7 +123,7 @@ public class TournamentPanel extends javax.swing.JPanel {
// session.replayGame(gameId); // session.replayGame(gameId);
// } // }
if (state.startsWith("Dueling") && actionText.equals("Watch")) { if (state.startsWith("Dueling") && actionText.equals("Watch")) {
logger.info("Watching game " + gameId); LOGGER.info("Watching game " + gameId);
session.watchTournamentTable(tableId); session.watchTournamentTable(tableId);
} }
} }
@ -545,7 +545,7 @@ public class TournamentPanel extends javax.swing.JPanel {
class TournamentPlayersTableModel extends AbstractTableModel { class TournamentPlayersTableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Loc", "Player Name", "State", "Points", "Results"}; private final String[] columnNames = new String[]{"Loc", "Player Name", "State", "Points", "Results", "History"};
private TournamentPlayerView[] players = new TournamentPlayerView[0]; private TournamentPlayerView[] players = new TournamentPlayerView[0];
public void loadData(TournamentView tournament) { public void loadData(TournamentView tournament) {
@ -576,6 +576,8 @@ class TournamentPlayersTableModel extends AbstractTableModel {
return Integer.toString(players[arg0].getPoints()); return Integer.toString(players[arg0].getPoints());
case 4: case 4:
return players[arg0].getResults(); return players[arg0].getResults();
case 5:
return players[arg0].getHistory();
} }
return ""; return "";
} }

View file

@ -42,6 +42,7 @@ public class TournamentPlayerView implements Serializable, Comparable {
private final String name; private final String name;
private final String state; private final String state;
private final String results; private final String results;
private final String history;
private final int points; private final int points;
private final boolean quit; private final boolean quit;
@ -57,6 +58,7 @@ public class TournamentPlayerView implements Serializable, Comparable {
this.points = tournamentPlayer.getPoints(); this.points = tournamentPlayer.getPoints();
this.results = tournamentPlayer.getResults(); this.results = tournamentPlayer.getResults();
this.quit = !tournamentPlayer.isInTournament(); this.quit = !tournamentPlayer.isInTournament();
this.history = tournamentPlayer.getPlayer().getUserData().getHistory();
this.flagName = tournamentPlayer.getPlayer().getUserData().getFlagName(); this.flagName = tournamentPlayer.getPlayer().getUserData().getFlagName();
} }
@ -88,4 +90,9 @@ public class TournamentPlayerView implements Serializable, Comparable {
public String getFlagName() { public String getFlagName() {
return flagName; return flagName;
} }
public String getHistory() {
return history;
}
} }

View file

@ -40,9 +40,9 @@ public class UsersView implements Serializable {
private final String flagName; private final String flagName;
private final String userName; private final String userName;
private final String matchHistory; private final String matchHistory;
private final String matchQuitRatio; private final int matchQuitRatio;
private final String tourneyHistory; private final String tourneyHistory;
private final String tourneyQuitRatio; private final int tourneyQuitRatio;
private final String infoGames; private final String infoGames;
private final String infoPing; private final String infoPing;
@ -50,9 +50,9 @@ public class UsersView implements Serializable {
String tourneyHistory, int tourneyQuitRatio, String infoGames, String infoPing) { String tourneyHistory, int tourneyQuitRatio, String infoGames, String infoPing) {
this.flagName = flagName; this.flagName = flagName;
this.matchHistory = matchHistory; this.matchHistory = matchHistory;
this.matchQuitRatio = Integer.toString(matchQuitRatio); this.matchQuitRatio = matchQuitRatio;
this.tourneyHistory = tourneyHistory; this.tourneyHistory = tourneyHistory;
this.tourneyQuitRatio = Integer.toString(tourneyQuitRatio); this.tourneyQuitRatio = tourneyQuitRatio;
this.userName = userName; this.userName = userName;
this.infoGames = infoGames; this.infoGames = infoGames;
this.infoPing = infoPing; this.infoPing = infoPing;
@ -70,7 +70,7 @@ public class UsersView implements Serializable {
return matchHistory; return matchHistory;
} }
public String getMatchQuitRatio() { public int getMatchQuitRatio() {
return matchQuitRatio; return matchQuitRatio;
} }
@ -78,7 +78,7 @@ public class UsersView implements Serializable {
return tourneyHistory; return tourneyHistory;
} }
public String getTourneyQuitRatio() { public int getTourneyQuitRatio() {
return tourneyQuitRatio; return tourneyQuitRatio;
} }

View file

@ -63,9 +63,9 @@ import org.apache.log4j.Logger;
*/ */
public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
private static final Logger logger = Logger.getLogger(GamesRoomImpl.class); private static final Logger LOGGER = Logger.getLogger(GamesRoomImpl.class);
private static final ScheduledExecutorService updateExecutor = Executors.newSingleThreadScheduledExecutor(); private static final ScheduledExecutorService UPDATE_EXECUTOR = Executors.newSingleThreadScheduledExecutor();
private static List<TableView> tableView = new ArrayList<>(); private static List<TableView> tableView = new ArrayList<>();
private static List<MatchView> matchView = new ArrayList<>(); private static List<MatchView> matchView = new ArrayList<>();
private static List<RoomUsersView> roomUsersView = new ArrayList<>(); private static List<RoomUsersView> roomUsersView = new ArrayList<>();
@ -73,13 +73,13 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
private final ConcurrentHashMap<UUID, Table> tables = new ConcurrentHashMap<>(); private final ConcurrentHashMap<UUID, Table> tables = new ConcurrentHashMap<>();
public GamesRoomImpl() { public GamesRoomImpl() {
updateExecutor.scheduleAtFixedRate(new Runnable() { UPDATE_EXECUTOR.scheduleAtFixedRate(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
update(); update();
} catch (Exception ex) { } catch (Exception ex) {
logger.fatal("Games room update exception! " + ex.toString(), ex); LOGGER.fatal("Games room update exception! " + ex.toString(), ex);
} }
} }
@ -118,7 +118,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
user.getMatchHistory(), user.getMatchQuitRatio(), user.getTourneyHistory(), user.getMatchHistory(), user.getMatchQuitRatio(), user.getTourneyHistory(),
user.getTourneyQuitRatio(), user.getGameInfo(), user.getPingInfo())); user.getTourneyQuitRatio(), user.getGameInfo(), user.getPingInfo()));
} catch (Exception ex) { } catch (Exception ex) {
logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex); LOGGER.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex);
users.add(new UsersView( users.add(new UsersView(
(user.getUserData() != null && user.getUserData().getFlagName() != null) ? user.getUserData().getFlagName() : "world", (user.getUserData() != null && user.getUserData().getFlagName() != null) ? user.getUserData().getFlagName() : "world",
user.getName() != null ? user.getName() : "<no name>", user.getName() != null ? user.getName() : "<no name>",
@ -197,8 +197,8 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
if (table != null) { if (table != null) {
table.cleanUp(); table.cleanUp();
tables.remove(tableId); tables.remove(tableId);
if (logger.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
logger.debug("Table removed: " + tableId); LOGGER.debug("Table removed: " + tableId);
} }
} }
} }

View file

@ -55,12 +55,12 @@ import mage.game.permanent.token.Token;
*/ */
public class WardenOfTheFirstTree extends CardImpl { public class WardenOfTheFirstTree extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); private static final FilterCreaturePermanent FILTER = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent(); private static final FilterCreaturePermanent FILTER2 = new FilterCreaturePermanent();
static { static {
filter.add(new SubtypePredicate("Warrior")); FILTER.add(new SubtypePredicate("Warrior"));
filter2.add(new SubtypePredicate("Spirit")); FILTER2.add(new SubtypePredicate("Spirit"));
} }
public WardenOfTheFirstTree(UUID ownerId) { public WardenOfTheFirstTree(UUID ownerId) {
@ -80,21 +80,21 @@ public class WardenOfTheFirstTree extends CardImpl {
this.addAbility(new SimpleActivatedAbility( this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD, Zone.BATTLEFIELD,
new ConditionalContinuousEffect( new ConditionalContinuousEffect(
new BecomesCreatureSourceEffect(new WardenOfTheFirstTree2(), "", Duration.Custom), new BecomesCreatureSourceEffect(new WardenOfTheFirstTree2(), "", Duration.Custom),
new LockedInCondition(new SourceMatchesFilterCondition(filter)), new LockedInCondition(new SourceMatchesFilterCondition(FILTER)),
"If {this} is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink"), "If {this} is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink"),
new ManaCostsImpl("{2}{W/B}{W/B}") new ManaCostsImpl("{2}{W/B}{W/B}")
)); ));
// {3}{W/B}{W/B}{W/B}: If Warden of the First Tree is a Spirit, put five +1/+1 counters on it. // {3}{W/B}{W/B}{W/B}: If Warden of the First Tree is a Spirit, put five +1/+1 counters on it.
this.addAbility(new SimpleActivatedAbility( this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD, Zone.BATTLEFIELD,
new ConditionalOneShotEffect( new ConditionalOneShotEffect(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)), new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)),
new SourceMatchesFilterCondition(filter2), new SourceMatchesFilterCondition(FILTER2),
"If {this} is a Spirit, put five +1/+1 counters on it"), "If {this} is a Spirit, put five +1/+1 counters on it"),
new ManaCostsImpl("{3}{W/B}{W/B}{W/B}") new ManaCostsImpl("{3}{W/B}{W/B}{W/B}")
)); ));
} }
public WardenOfTheFirstTree(final WardenOfTheFirstTree card) { public WardenOfTheFirstTree(final WardenOfTheFirstTree card) {

View file

@ -44,10 +44,10 @@ import mage.target.common.TargetCardInGraveyard;
*/ */
public class PulseOfMurasa extends CardImpl { public class PulseOfMurasa extends CardImpl {
private static final FilterCard filter = new FilterCard("creature or land card in a graveyard"); private static final FilterCard FILTER = new FilterCard("creature or land card in a graveyard");
static { static {
filter.add(Predicates.or( FILTER.add(Predicates.or(
new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.LAND))); new CardTypePredicate(CardType.LAND)));
} }
@ -58,9 +58,9 @@ public class PulseOfMurasa extends CardImpl {
// Return target creature or land card from a graveyard to its owner's hand. // Return target creature or land card from a graveyard to its owner's hand.
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInGraveyard(filter)); this.getSpellAbility().addTarget(new TargetCardInGraveyard(FILTER));
// You gain 6 life. // You gain 6 life.
getSpellAbility().addEffect(new GainLifeEffect(6)); this.getSpellAbility().addEffect(new GainLifeEffect(6));
} }
public PulseOfMurasa(final PulseOfMurasa card) { public PulseOfMurasa(final PulseOfMurasa card) {

View file

@ -120,4 +120,26 @@ public class WardenOfTheFirstTreeTest extends CardTestPlayerBase {
* power/toughness instead of 1/1. I have had it enter with both 2/2 and * power/toughness instead of 1/1. I have had it enter with both 2/2 and
* 4/4, neither of which are actual values the card can hold. * 4/4, neither of which are actual values the card can hold.
*/ */
@Test
public void testTwoWarden() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
// {1}{W/B}: Warden of the First Tree becomes a Human Warrior with base power and toughness 3/3.
// {2}{W/B}{W/B}: If Warden of the First Tree is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink.
// {3}{W/B}{W/B}{W/B}: If Warden of the First Tree is a Spirit, put five +1/+1 counters on it.
addCard(Zone.HAND, playerA, "Warden of the First Tree", 2); // {G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Warden of the First Tree");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/B}:");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{2}{W/B}{W/B}:");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Warden of the First Tree");
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Warden of the First Tree", 1, 1, Filter.ComparisonScope.Any);
assertPowerToughness(playerA, "Warden of the First Tree", 3, 3, Filter.ComparisonScope.Any);
}
} }

View file

@ -33,7 +33,6 @@ import mage.filter.FilterPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
/** /**
* Describes condition when source matches specified filter * Describes condition when source matches specified filter
* *
@ -41,17 +40,17 @@ import mage.game.permanent.Permanent;
*/ */
public class SourceMatchesFilterCondition implements Condition { public class SourceMatchesFilterCondition implements Condition {
private FilterPermanent filter; private FilterPermanent FILTER;
public SourceMatchesFilterCondition(FilterPermanent filter) { public SourceMatchesFilterCondition(FilterPermanent filter) {
this.filter = filter; this.FILTER = filter;
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId()); Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null) { if (permanent != null) {
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) { if (FILTER.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
return true; return true;
} }
} }

View file

@ -176,7 +176,10 @@ public class UserData implements Serializable {
} }
public String getHistory() { public String getHistory() {
return "Matches:" + this.matchHistory + " Tourneys:" + this.tourneyHistory; if (UserGroup.COMPUTER.equals(this.groupId)) {
return "";
}
return "Matches: " + this.matchHistory + " (" + this.matchQuitRatio + "%) Tourneys: " + this.tourneyHistory + " (" + this.tourneyQuitRatio + "%)";
} }
public void setMatchHistory(String history) { public void setMatchHistory(String history) {

View file

@ -12,7 +12,7 @@ public enum UserGroup {
ADMIN(7), ADMIN(7),
OWNER(15); OWNER(15);
private int groupId; private final int groupId;
UserGroup(int groupId) { UserGroup(int groupId) {
this.groupId = groupId; this.groupId = groupId;