/*******************************************************************************
* Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://robocode.sourceforge.net/license/epl-v10.html
*
* Contributors:
* Luis Crespo & Mathew A. Nelson
* - Original implementation
* Flemming N. Larsen
* - Totally rewritten to contain the functionality for both the
* RankingDialog and ResultsDialog (code reuse)
* - Changed to be a independent frame instead of a dialog
* - Changed to pack the dialog to fit the table with the rankings
* Nathaniel Troutman
* - Bugfix: Added cleanup to prevent memory leaks with the battle object in
* okButtonActionPerformed()
*******************************************************************************/
package net.sf.robocode.ui.dialog;
import net.sf.robocode.battle.BattleRankingTableModel;
import net.sf.robocode.settings.ISettingsManager;
import net.sf.robocode.ui.IWindowManager;
import robocode.control.events.BattleAdaptor;
import robocode.control.events.BattleFinishedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.snapshot.ITurnSnapshot;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicReference;
/**
* Frame to display the battle results or ranking during battles.
*
* @author Mathew A. Nelson (original)
* @author Luis Crespo (original)
* @author Flemming N. Larsen (contributor)
* @author Nathaniel Troutman (contributor)
*/
@SuppressWarnings("serial")
public class RankingDialog extends BaseScoreDialog {
private final BattleRankingTableModel tableModel;
private final Timer timerTask;
private final BattleObserver battleObserver;
private final AtomicReference<ITurnSnapshot> snapshot;
private ITurnSnapshot lastSnapshot;
private int lastRows;
private final MenuBar menu;
private final IWindowManager windowManager;
public RankingDialog(IWindowManager windowManager, ISettingsManager settingsManager, MenuBar menu) {
super(settingsManager.getOptionsCommonDontHideRankings() ? null : windowManager, false);
initialize();
this.windowManager = windowManager;
battleObserver = new BattleObserver();
timerTask = new Timer(1000 / 2, new TimerTask());
snapshot = new AtomicReference<ITurnSnapshot>();
lastRows = 0;
tableModel = new BattleRankingTableModel();
this.menu = menu;
setTitle("Ranking");
}
@Override
protected AbstractTableModel getTableModel() {
return tableModel;
}
private void update() {
final ITurnSnapshot current = snapshot.get();
if (lastSnapshot != current) {
setResultsData();
lastSnapshot = current;
tableModel.updateSource(lastSnapshot);
if (table.getModel().getRowCount() != lastRows) {
lastRows = table.getModel().getRowCount();
table.setPreferredSize(
new Dimension(table.getColumnModel().getTotalColumnWidth(),
table.getModel().getRowCount() * table.getRowHeight()));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
pack();
}
repaint();
}
}
protected void onDialogShown() {
windowManager.addBattleListener(battleObserver);
timerTask.start();
}
protected void onDialogHidden() {
menu.getOptionsShowRankingCheckBoxMenuItem().setState(false);
timerTask.stop();
windowManager.removeBattleListener(battleObserver);
dispose();
}
private class BattleObserver extends BattleAdaptor {
@Override
public void onBattleFinished(BattleFinishedEvent event) {
snapshot.set(null);
}
@Override
public void onTurnEnded(TurnEndedEvent event) {
snapshot.set(event.getTurnSnapshot());
}
}
private class TimerTask implements ActionListener {
public void actionPerformed(ActionEvent e) {
update();
}
}
}