import java.awt.event.*;
import jdsl.core.api.*;
import jdsl.core.ref.*;
/**
* Simulates an auction in a GUI.
* @author Robert Cohen (rfc)
* @version JDSL 2
*/
public class AuctionSimulator implements CountDownTimerListener, ActionListener
{
private AuctionFrame frame;
private CountDownTimer clock;
private String item[]={"Car","Watch","Elvis Painting","Computer","Chair"};
private Position myPos;
private Auction auction;
private java.util.Random rnd = new java.util.Random();
private boolean closed;
private Sequence participants;
// running this class just creates a visible AuctionSimulator window
static public void main(String args[]) {
(new AuctionSimulator()).frame.setVisible(true);
}
// open a window and start things running
AuctionSimulator(){
frame = new AuctionFrame(this);
clock = frame.clock;
reset();
}
// refresh everything, but don't start the countdown
private void reset(){
frame.startBtn.setEnabled(true);
frame.withdrawBtn.setEnabled(false);
frame.setBid("");
auction = new Auction();
clock.reset();
frame.clear();
chooseItem();
closed = false;
myPos=null;
participants=new ArraySequence();
}
// start the timed auction
private void start(){
if (closed)
frame.setMsg("Auction closed.");
else {
frame.startBtn.setEnabled(false);
myBid();
updateFrame();
clock.start();
}
}
// action when the Withdraw button is clicked
private void withdraw(){
frame.withdrawBtn.setEnabled(false);
auction.quit(myPos);
myPos=null;
updateFrame();
frame.setMsg("");
}
// finish the auction
private void close() {
closed=true;
Position winner = auction.close();
if (winner == null)
frame.setMsg("Closed with no bidders.");
else if (winner == myPos)
frame.setMsg("You win!!");
else
frame.setMsg("Auction closed.");
}
// receive AWT events and dispatch them to other methods
public void actionPerformed(java.awt.event.ActionEvent event)
{
Object object = event.getSource();
if (object == frame.startBtn) {
start();
}
else if (object == frame.withdrawBtn){
withdraw();
}
else if (object == frame.resetBtn) {
reset();
}
else if (object == frame.bidField) {
if (closed) {
frame.setMsg("Bids have closed.");
} else if (clock.isRunning()) {
myBid();
} else {
start();
}
}
}
// on clock ticks, possibly end the auction or call a new bid
public void timerTicked(CountDownTimerEvent e) {
int timeLeft = e.timeLeft();
if (timeLeft==0)
close();
else if (timeLeft%5==0)
newBid();
}
// generate a new bid from a "participant"
private void newBid() {
Position newPos;
int size=participants.size();
int choice=rnd.nextInt(size+2)-1;
if (choice < 0) return;
double bidAmount = auction.highBid()+rnd.nextInt(50);
if (choice == size)
newPos = bid(null,"",bidAmount);
else {
Position pos = (Position)participants.atRank(choice);
Position bidder = (Position)pos.element();
Position newBidder = bid(bidder,"",bidAmount);
participants.replaceElement(pos,newBidder);
}
}
// enter the user's bid
private void myBid() {
double bid = frame.getBid();
String name = frame.getName();
myPos=bid(myPos,name,bid);
if (myPos != null)
frame.withdrawBtn.setEnabled(true);
}
// enter a bid
private Position bid(Position pos, String name, double bid) {
Position ret=pos;
String msg = "";
if (bid>0) {
if (pos == null) {
try {
ret=auction.initial(name,bid);
} catch (InvalidBidException e){
msg=e.getMessage();
}
} else {
try {
ret=auction.top(myPos,bid);
} catch (InvalidBidException e){
msg=e.getMessage();
}
}
}
updateFrame();
frame.setMsg(msg);
return ret;
}
private void updateFrame() {
frame.setHighBid(auction.highBid());
frame.setNumBidders(auction.numBidders());
}
private void chooseItem(){
int i = rnd.nextInt(item.length);
frame.setItem(item[i]);
}
}