/* * Copyright 2011 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. */ /* * ConsolePanel.java * * Created on 14-May-2011, 6:08:48 PM */ package mage.server.console; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import javax.swing.SwingWorker; import javax.swing.table.AbstractTableModel; import mage.remote.Session; import mage.view.TableView; import mage.view.UserView; import org.apache.log4j.Logger; /** * * @author BetaSteward_at_googlemail.com */ public class ConsolePanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(ConsolePanel.class); private final TableUserModel tableUserModel; private final TableTableModel tableTableModel; private UpdateUsersTask updateUsersTask; private UpdateTablesTask updateTablesTask; /** Creates new form ConsolePanel */ public ConsolePanel() { this.tableUserModel = new TableUserModel(); this.tableTableModel = new TableTableModel(); initComponents(); this.tblUsers.createDefaultColumnsFromModel(); this.tblTables.createDefaultColumnsFromModel(); } public void update(List users) { int row = this.tblUsers.getSelectedRow(); tableUserModel.loadData(users); this.tblUsers.repaint(); this.tblUsers.getSelectionModel().setSelectionInterval(row, row); } public void update(Collection tables) { int row = this.tblTables.getSelectedRow(); tableTableModel.loadData(tables); this.tblTables.repaint(); this.tblTables.getSelectionModel().setSelectionInterval(row, row); } public void start() { updateUsersTask = new UpdateUsersTask(ConsoleFrame.getSession(), this); updateTablesTask = new UpdateTablesTask(ConsoleFrame.getSession(), ConsoleFrame.getSession().getMainRoomId(), this); updateUsersTask.execute(); updateTablesTask.execute(); } public void stop() { if (updateUsersTask != null && !updateUsersTask.isDone()) { updateUsersTask.cancel(true); } if (updateTablesTask != null && !updateTablesTask.isDone()) { updateTablesTask.cancel(true); } } /** 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() { jSplitPane1 = new javax.swing.JSplitPane(); jPanel1 = new javax.swing.JPanel(); jPanel3 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); tblUsers = new javax.swing.JTable(); jPanel4 = new javax.swing.JPanel(); btnDisconnect = new javax.swing.JButton(); btnEndSession = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); jPanel5 = new javax.swing.JPanel(); jScrollPane2 = new javax.swing.JScrollPane(); tblTables = new javax.swing.JTable(); jPanel6 = new javax.swing.JPanel(); btnRemoveTable = new javax.swing.JButton(); jSplitPane1.setDividerLocation(250); jSplitPane1.setResizeWeight(0.5); tblUsers.setModel(tableUserModel); jScrollPane1.setViewportView(tblUsers); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE) ); jPanel4.setVerifyInputWhenFocusTarget(false); btnDisconnect.setText("Disconnect"); btnDisconnect.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnDisconnectActionPerformed(evt); } }); btnEndSession.setText("End session"); btnEndSession.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnEndSessionActionPerformed(evt); } }); javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addComponent(btnDisconnect, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(btnEndSession) .addContainerGap(8, Short.MAX_VALUE)) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnDisconnect) .addComponent(btnEndSession)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(0, 0, 0) .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)) ); jSplitPane1.setLeftComponent(jPanel1); tblTables.setModel(tableTableModel); jScrollPane2.setViewportView(tblTables); javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); jPanel5.setLayout(jPanel5Layout); jPanel5Layout.setHorizontalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 306, Short.MAX_VALUE) ); jPanel5Layout.setVerticalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 356, Short.MAX_VALUE) ); btnRemoveTable.setLabel("Remove Table"); btnRemoveTable.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnRemoveTableActionPerformed(evt); } }); javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); jPanel6.setLayout(jPanel6Layout); jPanel6Layout.setHorizontalGroup( jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel6Layout.createSequentialGroup() .addComponent(btnRemoveTable) .addContainerGap(170, Short.MAX_VALUE)) ); jPanel6Layout.setVerticalGroup( jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel6Layout.createSequentialGroup() .addComponent(btnRemoveTable) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, 301, Short.MAX_VALUE) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(0, 0, 0) .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); jSplitPane1.setRightComponent(jPanel2); 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.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 562, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING) ); }// //GEN-END:initComponents private void btnDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDisconnectActionPerformed int row = this.tblUsers.getSelectedRow(); ConsoleFrame.getSession().disconnectUser((String)tableUserModel.getValueAt(row, 3)); }//GEN-LAST:event_btnDisconnectActionPerformed private void btnRemoveTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveTableActionPerformed int row = this.tblTables.getSelectedRow(); ConsoleFrame.getSession().removeTable((UUID)tableTableModel.getValueAt(row, 7)); }//GEN-LAST:event_btnRemoveTableActionPerformed private void btnEndSessionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEndSessionActionPerformed int row = this.tblUsers.getSelectedRow(); ConsoleFrame.getSession().endUserSession((String) tableUserModel.getValueAt(row, 3)); }//GEN-LAST:event_btnEndSessionActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnDisconnect; private javax.swing.JButton btnEndSession; private javax.swing.JButton btnRemoveTable; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JPanel jPanel5; private javax.swing.JPanel jPanel6; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JTable tblTables; private javax.swing.JTable tblUsers; // End of variables declaration//GEN-END:variables } class TableUserModel extends AbstractTableModel { private final String[] columnNames = new String[]{"User Name", "Host", "Time Connected"}; private UserView[] users = new UserView[0]; private static final DateFormat formatter = new SimpleDateFormat("HH:mm:ss"); public void loadData(List users) { this.users = users.toArray(new UserView[0]); this.fireTableDataChanged(); } @Override public int getRowCount() { return users.length; } @Override public int getColumnCount() { return columnNames.length; } @Override public Object getValueAt(int arg0, int arg1) { switch (arg1) { case 0: return users[arg0].getUserName(); case 1: return users[arg0].getHost(); case 2: return formatter.format(users[arg0].getConnectionTime()); case 3: return users[arg0].getSessionId(); } return ""; } @Override public String getColumnName(int columnIndex) { String colName = ""; if (columnIndex <= getColumnCount()) { colName = columnNames[columnIndex]; } return colName; } @Override public Class getColumnClass(int columnIndex){ return String.class; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } } class TableTableModel extends AbstractTableModel { private final String[] columnNames = new String[]{"Table Name", "Owner", "Game Type", "Deck Type", "Status"}; private TableView[] tables = new TableView[0]; public void loadData(Collection tables) { this.tables = tables.toArray(new TableView[0]); this.fireTableDataChanged(); } @Override public int getRowCount() { return tables.length; } @Override public int getColumnCount() { return columnNames.length; } @Override public Object getValueAt(int arg0, int arg1) { switch (arg1) { case 0: return tables[arg0].getTableName(); case 1: return tables[arg0].getControllerName(); case 2: return tables[arg0].getGameType(); case 3: return tables[arg0].getDeckType(); case 4: return tables[arg0].getTableState().toString(); case 5: return tables[arg0].isTournament(); case 6: if (!tables[arg0].getGames().isEmpty()) { return tables[arg0].getGames().get(0); } return null; case 7: return tables[arg0].getTableId(); } return ""; } @Override public String getColumnName(int columnIndex) { String colName = ""; if (columnIndex <= getColumnCount()) { colName = columnNames[columnIndex]; } return colName; } @Override public Class getColumnClass(int columnIndex){ return String.class; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { if (columnIndex != 5) { return false; } return true; } } class UpdateUsersTask extends SwingWorker> { private final Session session; private final ConsolePanel panel; private List previousUsers; private static final Logger logger = Logger.getLogger(UpdateUsersTask.class); UpdateUsersTask(Session session, ConsolePanel panel) { this.session = session; this.panel = panel; } @Override protected Void doInBackground() throws Exception { while (!isCancelled()) { List users = session.getUsers(); if (previousUsers == null || checkUserListChanged(users)) { logger.debug("Need to update the user list"); this.publish(users); previousUsers = users; } Thread.sleep(1000); } return null; } private boolean checkUserListChanged(List usersToCheck) { if (previousUsers == null || usersToCheck == null) { return true; } if (previousUsers.size() != usersToCheck.size()) { // new user appeared return true; } for (UserView u1 : previousUsers) { boolean found = false; for (UserView u2 : usersToCheck) { if (u1.getUserName().equals(u2.getUserName())) { found = true; break; } } if (!found) { // some new user replaced old one return true; } } // seems nothing has been changed return false; } @Override protected void process(List> view) { panel.update(view.get(0)); } @Override protected void done() { try { get(); } catch (InterruptedException ex) { logger.fatal("Update Users Task error", ex); } catch (ExecutionException ex) { logger.fatal("Update Users Task error", ex); } catch (CancellationException ex) {} } } class UpdateTablesTask extends SwingWorker> { private final Session session; private final UUID roomId; private final ConsolePanel panel; private static final Logger logger = Logger.getLogger(UpdateTablesTask.class); UpdateTablesTask(Session session, UUID roomId, ConsolePanel panel) { this.session = session; this.roomId = roomId; this.panel = panel; } @Override protected Void doInBackground() throws Exception { while (!isCancelled()) { this.publish(session.getTables(roomId)); Thread.sleep(1000); } return null; } @Override protected void process(List> view) { panel.update(view.get(0)); } @Override protected void done() { try { get(); } catch (InterruptedException ex) { logger.fatal("Update Tables Task error", ex); } catch (ExecutionException ex) { logger.fatal("Update Tables Task error", ex); } catch (CancellationException ex) {} } }