[virtualcommons-svn] SF.net SVN: virtualcommons:[416] foraging/trunk
Status: Beta
Brought to you by:
alllee
From: <al...@us...> - 2009-12-25 05:17:30
|
Revision: 416 http://virtualcommons.svn.sourceforge.net/virtualcommons/?rev=416&view=rev Author: alllee Date: 2009-12-25 05:17:14 +0000 (Fri, 25 Dec 2009) Log Message: ----------- merging r385:r415 into trunk Modified Paths: -------------- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/Circle.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ClientDataModel.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EmbeddedChatPanel.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow3D.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GridView.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/SubjectView.java foraging/trunk/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java foraging/trunk/src/main/java/edu/asu/commons/foraging/facilitator/FacilitatorWindow.java foraging/trunk/src/main/java/edu/asu/commons/foraging/model/ClientData.java foraging/trunk/src/main/java/edu/asu/commons/foraging/model/GroupDataModel.java foraging/trunk/src/main/java/edu/asu/commons/foraging/model/ServerDataModel.java foraging/trunk/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java foraging/trunk/src/main/java/edu/asu/commons/foraging/util/ForagingSaveFileConverter.java Added Paths: ----------- foraging/trunk/src/main/java/TestEnforcement.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EnforcementPanel.java foraging/trunk/src/main/java/edu/asu/commons/foraging/client/RegulationPanel.java foraging/trunk/src/main/java/edu/asu/commons/foraging/event/EnforcementMechanismUpdateEvent.java foraging/trunk/src/main/java/edu/asu/commons/foraging/event/EnforcementRankingRequest.java foraging/trunk/src/main/java/edu/asu/commons/foraging/event/MonitorTaxEvent.java foraging/trunk/src/main/java/edu/asu/commons/foraging/event/RegulationRankingRequest.java foraging/trunk/src/main/java/edu/asu/commons/foraging/event/RegulationSubmissionUpdateEvent.java foraging/trunk/src/main/java/edu/asu/commons/foraging/event/RegulationUpdateEvent.java foraging/trunk/src/main/java/edu/asu/commons/foraging/event/SubmitRegulationRequest.java foraging/trunk/src/main/java/edu/asu/commons/foraging/model/EnforcementMechanism.java foraging/trunk/src/main/java/edu/asu/commons/foraging/model/ForagingRole.java foraging/trunk/src/main/java/edu/asu/commons/foraging/model/RegulationData.java foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/ foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round0.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round1.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round2.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round3.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round4.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round5.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round6.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round7.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/server.xml Removed Paths: ------------- foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round0.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round1.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round2.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round3.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round4.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round5.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round6.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/round7.xml foraging/trunk/src/main/resources/configuration/asu-experiments/voting-regulation-enforcement/server.xml Property Changed: ---------------- foraging/trunk/ Property changes on: foraging/trunk ___________________________________________________________________ Added: svn:mergeinfo + /foraging/branches/deepak-branch-fall-09:386-415 Copied: foraging/trunk/src/main/java/TestEnforcement.java (from rev 415, foraging/branches/deepak-branch-fall-09/src/main/java/TestEnforcement.java) =================================================================== --- foraging/trunk/src/main/java/TestEnforcement.java (rev 0) +++ foraging/trunk/src/main/java/TestEnforcement.java 2009-12-25 05:17:14 UTC (rev 416) @@ -0,0 +1,33 @@ +import java.awt.Color; +import java.awt.Container; +import java.awt.FlowLayout; + +import javax.swing.JFrame; + +import edu.asu.commons.foraging.client.EnforcementPanel; + + +public class TestEnforcement { + + /** + * @param args + */ + public static void main(String[] args) { + // TODO Auto-generated method stub + //ForagingClient client = new ForagingClient(); + + EnforcementPanel testEnforcement = new EnforcementPanel(); + testEnforcement.initialize(); + JFrame f = new JFrame("This is a test"); + f.setSize(1000, 1000); + Container content = f.getContentPane(); + content.setBackground(Color.white); + content.setLayout(new FlowLayout()); + content.add(testEnforcement); + //f.setDefaultCloseOperation(0); + f.setVisible(true); + + + } + +} Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java 2009-12-24 22:42:09 UTC (rev 415) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java 2009-12-25 05:17:14 UTC (rev 416) @@ -102,7 +102,7 @@ add(targetHandlePanel, BorderLayout.NORTH); add(chatField, BorderLayout.CENTER); - add(sendButton, BorderLayout.SOUTH); +// add(sendButton, BorderLayout.SOUTH); setChatFieldFocus(); } @@ -199,6 +199,7 @@ setName("Chat panel"); messageWindow = new JTextPane(); messageWindow.setEditable(false); + messageWindow.setBackground(Color.WHITE); messageScrollPane = new JScrollPane(messageWindow); addStylesToMessageWindow(); @@ -249,13 +250,12 @@ chatInstructionsPane.setContentType("text/html"); chatInstructionsPane.setEditorKit(new HTMLEditorKit()); chatInstructionsPane.setEditable(false); + chatInstructionsPane.setBackground(Color.WHITE); JScrollPane chatInstructionsScrollPane = new JScrollPane(chatInstructionsPane); chatInstructionsPane.setText(client.getDataModel().getRoundConfiguration().getChatInstructions()); add(chatInstructionsScrollPane, BorderLayout.NORTH); add(messageScrollPane, BorderLayout.CENTER); - // if (client.getDataModel().getRoundConfiguration().shouldD - // add(participantButtonPanel, BorderLayout.EAST); add(textEntryPanel, BorderLayout.SOUTH); textEntryPanel.setChatFieldFocus(); } Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/Circle.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/Circle.java 2009-12-24 22:42:09 UTC (rev 415) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/Circle.java 2009-12-25 05:17:14 UTC (rev 416) @@ -16,6 +16,8 @@ private static final long serialVersionUID = 6400834001276229287L; + private static final double FUDGE_FACTOR = 0.1d; + private Point center; private final double radius; @@ -28,7 +30,7 @@ if (point == null) { throw new IllegalArgumentException("Null point passed to Circle.contains()"); } - return center.distance(point) <= radius; + return center.distance(point) <= (radius + FUDGE_FACTOR); } public void setCenter(Point center) { Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ClientDataModel.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ClientDataModel.java 2009-12-24 22:42:09 UTC (rev 415) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ClientDataModel.java 2009-12-25 05:17:14 UTC (rev 416) @@ -14,8 +14,10 @@ import edu.asu.commons.foraging.event.RealTimeSanctionRequest; import edu.asu.commons.foraging.event.SynchronizeClientEvent; import edu.asu.commons.foraging.model.ClientData; +import edu.asu.commons.foraging.model.EnforcementMechanism; import edu.asu.commons.foraging.model.ForagingDataModel; import edu.asu.commons.foraging.model.GroupDataModel; +import edu.asu.commons.foraging.model.RegulationData; import edu.asu.commons.foraging.model.Resource; import edu.asu.commons.net.Identifier; import edu.asu.commons.util.Duration; @@ -39,7 +41,7 @@ // FIXME: can obtain tokensConsumed from the clientDataMap now. private int currentTokens; - + // these are the subjects whom we have sanctioned private Map<Identifier, Duration> sanctioned = new HashMap<Identifier, Duration>(); @@ -57,9 +59,27 @@ public void toggleExplicitCollectionMode() { explicitCollectionMode = !explicitCollectionMode; - client.transmit(new ExplicitCollectionModeRequest(client.getId(), - explicitCollectionMode)); + client.transmit(new ExplicitCollectionModeRequest(client.getId(), explicitCollectionMode)); } + + public Identifier getMonitorId() { + if (groupDataModel.getActiveMonitor() != null) { + return groupDataModel.getActiveMonitor().getId(); + } + return Identifier.NULL; + } + + public boolean isSanctioningAllowed() { + return getClientData().isSanctioningAllowed() || isSanctioningEnabled(); + } + + public boolean isHarvestingAllowed() { + return getClientData().isHarvestingAllowed(); + } + + public boolean isMonitor() { + return getClientData().getForagingRole().isMonitor(); + } /* * public Map<Identifier, Duration> getSanctioned() { return sanctioned; } @@ -101,7 +121,17 @@ groupDataModel = null; } } - + + public List<RegulationData> getSubmittedRegulations() { + return groupDataModel.getSubmittedRegulations(); + } + + public EnforcementMechanism getActiveEnforcementMechanism() { + return groupDataModel.getActiveEnforcementMechanism(); + } + + + public void initialize(GroupDataModel groupDataModel) { clear(); this.groupDataModel = groupDataModel; @@ -257,4 +287,12 @@ public Set<Resource> getRemovedResources() { return groupDataModel.getRemovedResources(); } + + public void setActiveRegulation(RegulationData regulationData) { + groupDataModel.setActiveRegulation(regulationData); + } + + public RegulationData getActiveRegulation() { + return groupDataModel.getActiveRegulation(); + } } Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EmbeddedChatPanel.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EmbeddedChatPanel.java 2009-12-24 22:42:09 UTC (rev 415) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EmbeddedChatPanel.java 2009-12-25 05:17:14 UTC (rev 416) @@ -34,7 +34,7 @@ /** * $Id$ * - * Chat panel used to communicate with other players. + * Chat panel used to communicate with other players within the 3D foraging visualization. * * FIXME: randomize mappings from handle (e.g., A -> 1, B -> 2, C -> 3 ...) so that it's * not linear. Copied: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EnforcementPanel.java (from rev 415, foraging/branches/deepak-branch-fall-09/src/main/java/edu/asu/commons/foraging/client/EnforcementPanel.java) =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EnforcementPanel.java (rev 0) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/EnforcementPanel.java 2009-12-25 05:17:14 UTC (rev 416) @@ -0,0 +1,363 @@ +package edu.asu.commons.foraging.client; + + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.ScrollPaneConstants; + +import edu.asu.commons.foraging.event.EnforcementRankingRequest; +import edu.asu.commons.foraging.model.EnforcementMechanism; +import edu.asu.commons.net.Identifier; + +/** + * $Id: EnforcementPanel.java 45 2008-08-21 00:47:39Z dbarge $ + * + * Enforcement panel is used to vote enforcement mechanism + * + * @author dbarge + * @version $Revision: 45 $ + */ + +@SuppressWarnings("serial") +public class EnforcementPanel extends JPanel { + + private ForagingClient client; + + + private String[] votes = { "1", "2", "3","4"}; + private EnforcementMechanism[] enforcementOptions = EnforcementMechanism.values(); + // private String[] enforcementOptions = { + // "No Enforcement - Click here for more info ", + // "Everyone sanctions - Click here for more info ", + // "Randomly picked monitering - Click here for more info", + // "Random sanctioning - Click here for more info " + // }; + + private String[] enforcementText = { + "Everybody can harvest. Nobody can subtract tokens<br>" + + "from others<br>", + + "Each participant can reduce the token amount of<br>" + + "another participant by two tokens at a cost of <br>" + + "one by pressing the numeric key that identifies<br>" + + "the other participant.<br>", + + "Randomly one of the participants is selected to<br>" + + "be the monitoring participant. This participant<br>" + + "can not harvest, but can force another particip<br>" + + "ant to pay a token to the monitoring participan<br>" + + "by pressing the responding numeric key. At the <br>" + + "end of the round each participant who could har<br>" + + "vest pays 25% of the earning to the monitoring <br>" + + "participant.<br>", + + "Same as two, but now each participant takes turns<br>" + + "of 48 seconds randomly assigned by the computer.<br>" + }; + + public EnforcementPanel (ForagingClient client) { + this(); + this.client = client; + this.clientId = client.getId(); + } + + private Identifier clientId; + private JPanel votingPanel; +// private JButton reset; +// private JButton sendMyVotes; + private JPanel instructionsPanel; + private SixChoicePanel[] newPanel; + + private int noOfEnforcements = EnforcementMechanism.values().length; + + private int currentRankingInformation[]; + + private JPanel buttonPanel; + + public EnforcementPanel () + { + newPanel = new SixChoicePanel[4]; + } + + public String getVotedEnforcementOptions(int index){ + return this.enforcementText[index]; + } + + private JPanel getInstructionPanel() + { + JPanel instructionPanel = new JPanel(); + + //instructionPanel.setBackground(color); + instructionPanel.setLayout(new BoxLayout(instructionPanel, BoxLayout.X_AXIS)); + instructionPanel.setBorder(BorderFactory.createTitledBorder("Enforcement Instructions")); + + //create Text area and JSCroll pane for it + String instructions = client.getDataModel().getRoundConfiguration().getVotingInstructions(); + + JTextArea instructionText = new JTextArea(instructions,3,50); + instructionText.setWrapStyleWord(true); + JScrollPane scrollForRegulationText = new JScrollPane(instructionText); + instructionPanel.add(scrollForRegulationText); + + return instructionPanel; + + } + + private Color getColor(int i) + { + Color color = null; + if(i==0) color = new Color(153,153,204); + if(i==1) color = new Color(204,153,153); + if(i==2) color = new Color(153,204,102); + if(i==3) color = new Color(204,204,102); + if(i==4) color = new Color(255,255,153); + return color; + } + + // FIXME: this is extremely inefficient, reimplement later + private void updateVotingPanel(int currentActive){ + int r,c,i; + SixChoicePanel temp = null; +// boolean enableSendButton = true; + + + for(r = 0; r < noOfEnforcements; r++) + { + +// if(newPanel[r].currentRanking == -1)enableSendButton = false; + + if((newPanel[currentActive].currentRanking == newPanel[r].currentRanking) && (r != currentActive)) + { + newPanel[r].currentRanking = -1; + newPanel[r].group.clearSelection(); + } + } + + + for(r = 0; r < noOfEnforcements-1; r++) + { + for(c = 0; c < noOfEnforcements-1; c++) + { + if((newPanel[c].currentRanking > newPanel[c+1].currentRanking)&&(newPanel[c+1].currentRanking != -1)) + { + temp = newPanel[c]; + newPanel[c] = newPanel[c+1]; + newPanel[c+1] = temp; + } + if((newPanel[c].currentRanking < newPanel[c+1].currentRanking)&&(newPanel[c].currentRanking == -1)) + { + temp = newPanel[c]; + newPanel[c] = newPanel[c+1]; + newPanel[c+1] = temp; + } + } + } + for(c = 0; c < noOfEnforcements; c++) + { + // System.out.print(newPanel[c].getCurrentRanking() +" "); + } + + votingPanel.setVisible(false); + remove(votingPanel); + votingPanel = new JPanel(); + votingPanel.setLayout(new BoxLayout(votingPanel, BoxLayout.Y_AXIS)); + + votingPanel.add(getInstructionPanel()); + + + for(i=0; i < noOfEnforcements; i++) { + votingPanel.add(newPanel[i].enforcementPanel); + } + + votingPanel.setVisible(true); + add(votingPanel, BorderLayout.CENTER); + +// if(enableSendButton) { +// sendMyVotes.setEnabled(true); +// buttonPanel.setVisible(true); +// add(buttonPanel, BorderLayout.SOUTH); +// } + revalidate(); + } + + private String getVoteString(){ + + StringBuilder sb = new StringBuilder(); + + for(int c = 0; c < noOfEnforcements; c++) + { + sb.append("\nEnforcement "+(newPanel[c].getCurrentRanking()+1)); + } + return(sb.toString()); + } + + public void sendEnforcementVotes() { + int i; + for(i=0; i < noOfEnforcements; i++) { + if(newPanel[i].currentRanking == -1) + this.currentRankingInformation[i] = -1; + else + this.currentRankingInformation[i] = newPanel[i].getCurrentRanking(); + } + client.transmit(new EnforcementRankingRequest(clientId, currentRankingInformation)); + } + + public void initGuiComponents(){ + + // remove(enforcementInstructionsScrollPane); + // remove(messageScrollPane); + this.currentRankingInformation = new int[4]; + this.newPanel = new SixChoicePanel[4]; + setBackground(Color.lightGray); + setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + + votingPanel = new JPanel(); + votingPanel.setLayout(new BoxLayout(votingPanel, BoxLayout.Y_AXIS)); + + //add the instruction panel as the first panel in voting panel. + instructionsPanel = getInstructionPanel(); + votingPanel.add(instructionsPanel); + + + + + for(int i=0; i<noOfEnforcements; i++) { + + //newPanel[i] = new SixChoicePanel(s, votes, enforcementData.getEnforcementID(), getColor(i)); + //newPanel[i] = new SixChoicePanel(s, votes, client.getEnforcementID(), getColor(i)); + newPanel[i] = new SixChoicePanel(enforcementOptions[i], votes, i, getColor(i)); + votingPanel.add(newPanel[i].getEnforcementPanel(i)); + } + + add(votingPanel, BorderLayout.CENTER); +// reset = new JButton("Reset All Ranks"); +// reset.setAlignmentX(Component.CENTER_ALIGNMENT); +// reset.addActionListener(new ActionListener() { +// public void actionPerformed(ActionEvent e) { +// for(int i=0; i<noOfEnforcements; i++) { +// for(int j=0; j<noOfEnforcements; j++) { +// newPanel[i].option[j].setEnabled(true); +// newPanel[i].group.clearSelection(); +// newPanel[i].currentRanking = -1; +// } +// } +// } +// }); +// sendMyVotes = new JButton("Send votes"); +// sendMyVotes.setAlignmentX(Component.CENTER_ALIGNMENT); +// sendMyVotes.setEnabled(false); +// sendMyVotes.addActionListener(new ActionListener() { +// public void actionPerformed(ActionEvent e) { +// +// int n = JOptionPane.showConfirmDialog( +// null, "Are you sure to submit your votes ?"+ +// "\nBelow is order of your voting" + +// getVoteString(), +// "Confirm and send votes", +// JOptionPane.YES_NO_OPTION); +// +// if (n == JOptionPane.YES_OPTION) { +// GameWindow2D.duration.expire(); +// } +// if (n == JOptionPane.NO_OPTION) { +// +// } +// +// } +// }); +// buttonPanel = new JPanel(); +// //buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); +// buttonPanel.setLayout(new GridLayout(1,2)); +// buttonPanel.add(reset); +// buttonPanel.add(sendMyVotes); +// buttonPanel.setVisible(true); +// buttonPanel.repaint(); +// add(buttonPanel, BorderLayout.SOUTH); + } + + public void initialize() { + initGuiComponents(); + } + + private class SixChoicePanel implements ActionListener{ + String title; + String description; + String [] buttonLabels; + int enforcementID; + int currentRanking; + JPanel enforcementPanel; + JPanel rankPanel; + ButtonGroup group; + JRadioButton option []; + Color color; + + + public SixChoicePanel(EnforcementMechanism enforcementMechanism, String[] buttonLabels, int enforcementID, Color color ) { + this.title = enforcementMechanism.getTitle(); + this.description = enforcementMechanism.getDescription(); + this.buttonLabels = buttonLabels; + this.enforcementID = enforcementID; + this.color = color; + this.currentRanking = -1; + this.option = new JRadioButton[4]; + } + public int getCurrentRanking(){ + return enforcementID; + } + + public void actionPerformed(ActionEvent e) { + String choice = group.getSelection().getActionCommand(); + int buttonNo = Integer.parseInt(choice); + System.out.println("ACTION Choice Selected: " + choice); + System.out.println("Bno: " + buttonNo); + System.out.println("CurrentActive : "+this.enforcementID); + this.currentRanking = buttonNo; + updateVotingPanel(this.enforcementID); + } + + + public JPanel getEnforcementPanel(int i){ + enforcementPanel = new JPanel(); + enforcementPanel.setBackground(color); + enforcementPanel.setLayout(new BoxLayout(enforcementPanel, BoxLayout.Y_AXIS)); + enforcementPanel.setBorder(BorderFactory.createTitledBorder(title)); + + //create Text area and JSCroll pane for it + + JTextArea regulationText = new JTextArea(title,3,50); + regulationText.setText(description); + regulationText.setWrapStyleWord(true); + JScrollPane scrollForRegulationText = new JScrollPane(regulationText); + enforcementPanel.add(scrollForRegulationText); + + rankPanel = new JPanel(); + rankPanel.setBackground(color); + rankPanel.setLayout(new BoxLayout(rankPanel, BoxLayout.X_AXIS)); + rankPanel.setBorder(BorderFactory.createTitledBorder("Rank")); + group = new ButtonGroup(); + int length = buttonLabels.length; // Assumes even length + + for(int j=0; j<length; j++) { + option[j] = new JRadioButton(buttonLabels[j]); + option[j].setActionCommand(buttonLabels[j]); + group.add(option[j]); + option[j].addActionListener(this); + rankPanel.add(option[j]); + } + enforcementPanel.add(rankPanel); + return enforcementPanel; + } + + } + +} Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java 2009-12-24 22:42:09 UTC (rev 415) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java 2009-12-25 05:17:14 UTC (rev 416) @@ -8,6 +8,7 @@ import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; +import javax.swing.UIManager; import edu.asu.commons.client.BaseClient; import edu.asu.commons.event.ClientMessageEvent; @@ -23,10 +24,13 @@ import edu.asu.commons.foraging.event.ClientPositionUpdateEvent; import edu.asu.commons.foraging.event.CollectTokenRequest; import edu.asu.commons.foraging.event.EndRoundEvent; +import edu.asu.commons.foraging.event.EnforcementMechanismUpdateEvent; import edu.asu.commons.foraging.event.LockResourceEvent; import edu.asu.commons.foraging.event.PostRoundSanctionRequest; import edu.asu.commons.foraging.event.PostRoundSanctionUpdateEvent; import edu.asu.commons.foraging.event.RealTimeSanctionRequest; +import edu.asu.commons.foraging.event.RegulationSubmissionUpdateEvent; +import edu.asu.commons.foraging.event.RegulationUpdateEvent; import edu.asu.commons.foraging.event.ResetTokenDistributionRequest; import edu.asu.commons.foraging.event.RoundStartedEvent; import edu.asu.commons.foraging.event.ShowInstructionsRequest; @@ -65,8 +69,9 @@ private ClientDataModel dataModel; private MessageQueue messageQueue; - private JPanel panel = new JPanel(); + private JPanel clientPanel = new JPanel(); + public ForagingClient(ServerConfiguration configuration) { this(configuration, new Dimension(800, 600)); } @@ -77,12 +82,11 @@ if (configuration.shouldInitialize2D()) { gameWindow2D = new GameWindow2D(this, screenSize); } - if (configuration.shouldInitialize3D()) { + else if (configuration.shouldInitialize3D()) { gameWindow3D = new GameWindow3D(this); } - panel.setLayout(new BorderLayout()); - panel.add(configuration.getCurrentParameters().is2dExperiment() - ? gameWindow2D : gameWindow3D.getPanel(), + clientPanel.setLayout(new BorderLayout()); + clientPanel.add(configuration.getCurrentParameters().is2dExperiment() ? gameWindow2D : gameWindow3D.getPanel(), BorderLayout.CENTER); } @@ -108,7 +112,7 @@ return gameWindow3D; } } - + public void sendAvatarInfo(boolean male, Color hairColor, Color skinColor, Color shirtColor, Color trouserColor, Color shoesColor) { transmit(new AgentInfoRequest(getId(), male, hairColor, skinColor, shirtColor, trouserColor, shoesColor)); gameWindow3D.removeAgentDesigner(); @@ -128,19 +132,19 @@ dataModel.setRoundConfiguration(configuration); SwingUtilities.invokeLater(new Runnable() { public void run() { - panel.removeAll(); - panel.invalidate(); + clientPanel.removeAll(); + clientPanel.invalidate(); if (dataModel.is2dExperiment()) { - panel.add(gameWindow2D, BorderLayout.CENTER); + clientPanel.add(gameWindow2D, BorderLayout.CENTER); if (gameWindow3D != null) { gameWindow3D.dispose(); } } else { - panel.add(gameWindow3D.getPanel(), BorderLayout.CENTER); + clientPanel.add(gameWindow3D.getPanel(), BorderLayout.CENTER); } - panel.validate(); - panel.repaint(); + clientPanel.validate(); + clientPanel.repaint(); getGameWindow().init(); } }); @@ -163,11 +167,13 @@ state = ClientState.RUNNING; } }); + addEventProcessor(new EventTypeProcessor<EndRoundEvent>(EndRoundEvent.class) { public void handle(final EndRoundEvent event) { if (state == ClientState.RUNNING) { dataModel.setGroupDataModel(event.getGroupDataModel()); getGameWindow().endRound(event); + getGameWindow().resetPanels(); if (dataModel.is2dExperiment()) { messageQueue.stop(); } @@ -221,17 +227,37 @@ addEventProcessor(new EventTypeProcessor<ClientMessageEvent>(ClientMessageEvent.class) { public void handle(ClientMessageEvent event) { - gameWindow2D.displayErrorMessage(event.toString()); + gameWindow2D.displayErrorMessage(event.toString(),0); } }); + addEventProcessor(new EventTypeProcessor<EnforcementMechanismUpdateEvent>(EnforcementMechanismUpdateEvent.class) { + public void handle(final EnforcementMechanismUpdateEvent event) { + dataModel.setGroupDataModel(event.getGroupDataModel()); + gameWindow2D.displayActiveEnforcementMechanism(); + } + }); + addEventProcessor(new EventTypeProcessor<RegulationSubmissionUpdateEvent>(RegulationSubmissionUpdateEvent.class) { + public void handle(final RegulationSubmissionUpdateEvent event) { + dataModel.setGroupDataModel(event.getGroupDataModel()); + gameWindow2D.initializeRegulationVotingPanel(); + } + }); + addEventProcessor(new EventTypeProcessor<RegulationUpdateEvent>(RegulationUpdateEvent.class) { + public void handle(final RegulationUpdateEvent event) { + dataModel.setActiveRegulation(event.getRegulationData()); + gameWindow2D.displayActiveRegulation(); + } + }); } public boolean canPerformRealTimeSanction() { - return dataModel.getRoundConfiguration().isRealTimeSanctioningEnabled() && dataModel.getCurrentTokens() > 0; + return dataModel.isMonitor() + || (dataModel.isSanctioningAllowed() && dataModel.getCurrentTokens() > 0); } public void transmit(PostRoundSanctionRequest request) { if (state == ClientState.WAITING) { + //System.out.println("Sending post round sanction request"); gameWindow2D.switchInstructionsPane(); super.transmit(request); } @@ -255,7 +281,7 @@ private int messagesSent; // samples are collected over 3 seconds. - private final static int SAMPLE_TIME = 3; +// private final static int SAMPLE_TIME = 3; private int totalMessagesPerSample; private int averageMessagesPerSecond; @@ -304,10 +330,6 @@ System.err.println("Discarding event: " + request + " - already sent " + messagesSent); } } - - public void clear() { - stop(); - } public void start() { running = true; @@ -346,10 +368,6 @@ // } // } - public int size() { - return actions.size(); - } - private void tick() { if (secondTick.hasExpired()) { secondTick.restart(); @@ -389,15 +407,25 @@ public static void main(String[] args) { Runnable createGuiRunnable = new Runnable() { public void run() { - Dimension defaultDimension = new Dimension(800, 600); - JFrame frame = new JFrame(); + //System.out.println("inside client"); + //Dimension defaultDimension = new Dimension(600, 600); + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch(Exception e) { + e.printStackTrace(); + System.err.println("Couldn't set native look and feel: "+ e); + } + Dimension defaultDimension = new Dimension(600, 600); + JFrame frame = new JFrame(); ForagingClient client = new ForagingClient(new ServerConfiguration(), defaultDimension); client.connect(); frame.setTitle("Client Window: " + client.getId()); frame.setSize(defaultDimension); - frame.add(client.panel); + frame.add(client.clientPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); + } }; SwingUtilities.invokeLater(createGuiRunnable); Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow.java 2009-12-24 22:42:09 UTC (rev 415) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow.java 2009-12-25 05:17:14 UTC (rev 416) @@ -17,5 +17,6 @@ public void init(); public void update(long millisecondsLeft); public void showInstructions(); + public void resetPanels(); } Modified: foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java =================================================================== --- foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java 2009-12-24 22:42:09 UTC (rev 415) +++ foraging/trunk/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java 2009-12-25 05:17:14 UTC (rev 416) @@ -1,5 +1,6 @@ package edu.asu.commons.foraging.client; + import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; @@ -21,11 +22,13 @@ import java.util.Map; import java.util.Properties; +import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JTextArea; import javax.swing.JTextPane; import javax.swing.SwingUtilities; import javax.swing.Timer; @@ -45,6 +48,7 @@ import edu.asu.commons.foraging.event.QuizCompletedEvent; import edu.asu.commons.foraging.event.RealTimeSanctionRequest; import edu.asu.commons.foraging.event.ResetTokenDistributionRequest; +import edu.asu.commons.foraging.event.SubmitRegulationRequest; import edu.asu.commons.foraging.model.ClientData; import edu.asu.commons.foraging.model.Direction; import edu.asu.commons.net.Identifier; @@ -70,21 +74,39 @@ // the data model private final ClientDataModel dataModel; - // instructions components. - + // instructions components. + private Component currentCenterComponent; - + private JScrollPane instructionsScrollPane; - private HtmlEditorPane instructionsEditorPane; - + private HtmlEditorPane instructionsEditorPane; + private JPanel messagePanel; private JScrollPane errorMessageScrollPane; private JTextPane errorMessageTextPane; private JPanel labelPanel; + + // FIXME: this shouldn't be public + public static Duration duration; + private ChatPanel chatPanel; + public final static String[] roleDescription = { + "Monitor: You cannot harvest but can sanction other participants\n" + + "To sanction press numbers from 1-5. At the end of the round you\n" + + "will receive 25% tokens from every other participant", + "Harvest: You can collect tokens as in earlier rounds. But you \n" + + "cannot sanction", + "Sanction: You cannot harvest but only sanction \n", + "Harvest and Sanction: You can collect tokens and at the same & \n" + + "at the same time sanction other participants"}; + + private RegulationPanel regulationPanel; + + private EnforcementPanel enforcementPanel; + private JLabel informationLabel; private JLabel timeLeftLabel; @@ -92,17 +114,26 @@ private JPanel subjectWindow; private ForagingClient client; - + private SubjectView subjectView; - private Timer timer; + public Timer timer; + public static final Object regulationSignal = new Object(); + + public static final Object enforcementVotesSignal = new Object(); + + public static final Object regulationVotesSignal = new Object(); + + public static final Object clientRoleSignal = new Object(); + private final StringBuilder instructionsBuilder = new StringBuilder(); - + private EventChannel channel; - + + private CardLayout cardLayout; - + // private EnergyLevel energyLevel; public GameWindow2D(ForagingClient client, Dimension size) { @@ -110,11 +141,12 @@ this.dataModel = client.getDataModel(); // FIXME: set the actual screen size dimensions after this JPanel has been initialized... this.channel = client.getEventChannel(); - // feed subject view the avaiable screen size so that + // feed subject view the available screen size so that // it can adjust appropriately when given a board size Dimension subjectViewSize = new Dimension((int) Math.floor(size.getWidth()), (int) Math.floor(size.getHeight() * 0.85)); subjectView = new SubjectView(subjectViewSize, dataModel); + // subjectView.addKeyListener(this); initGuiComponents(); } @@ -136,6 +168,8 @@ }); } + + /** * In certain cases, init() _can_ be called before endRound() is finished. Need to lock * access! @@ -148,22 +182,22 @@ } // don't display next round time, instead wait for the // facilitator signal. - + timeLeftLabel.setText("Waiting for facilitator's signal."); informationLabel.setText("Waiting for facilitator's signal."); // add the next round instructions to the existing debriefing text set by the previous // EndRoundEvent. } - - - + + + private ActionListener createQuizListener(final RoundConfiguration configuration) { return new ActionListener() { public void actionPerformed(ActionEvent e) { // System.err.println("In action performed with event: " + e); HtmlEditorPane.FormActionEvent formEvent = (HtmlEditorPane.FormActionEvent) e; Properties actualAnswers = formEvent.getData(); -// actualAnswers.list(System.err); + // actualAnswers.list(System.err); List<String> incorrectAnswers = new ArrayList<String>(); // iterate through expected answers for (Map.Entry<String, String> entry : configuration.getQuizAnswers().entrySet()) { @@ -200,16 +234,112 @@ subjectView.collectToken(position); } + private void startRegulationDisplayTimer(){ + if (timer == null) { + final Duration duration = Duration.create(dataModel.getRoundConfiguration().getRegulationDisplayDuration()); + timer = new Timer(1000, new ActionListener() { + public void actionPerformed(ActionEvent event) { + if (duration.hasExpired()) { + timeLeftLabel.setText("Regulation voting will start soon."); + timer.stop(); + timer = null; + initializeEnforcementVotingPanel(); + } + else { + timeLeftLabel.setText( String.format("Voting for the enforcement mechanism will start in %d seconds.", duration.getTimeLeft() / 1000L) ); + } + } + }); + timer.start(); + } + } + + private void startEnforcementVotingTimer() { + + if (timer == null) { + //FIXME: Need to fetch this value from the round4.xml + duration = Duration.create(dataModel.getRoundConfiguration().getEnforcementVotingDuration()); + timer = new Timer(1000, new ActionListener() { + public void actionPerformed(ActionEvent event) { + if (duration.hasExpired()) { + timeLeftLabel.setText("Voting is now disabled."); + timer.stop(); + timer = null; + getEnforcementPanel().sendEnforcementVotes(); + displayVotingWaitMessage(); + } + else { + timeLeftLabel.setText( String.format("Voting period will end in %d seconds.", duration.getTimeLeft() / 1000L) ); + } + } + }); + timer.start(); + } + } + + + private void startRegulationVotingTimer() { + + if (timer == null) { + duration = Duration.create(dataModel.getRoundConfiguration().getRegulationVotingDuration()); + + timer = new Timer(1000, new ActionListener() { + public void actionPerformed(ActionEvent event) { + if (duration.hasExpired()) { + timeLeftLabel.setText("Voting is now disabled. Next round begins shortly."); + + //new code + //Need to add the enforcementVotingPane over here + //instead of the instructionsScrollPane + timer.stop(); + timer = null; + //remove(sanctioningPanel); + //getSanctioningPanel().stopTimer(); + getRegulationPanel().sendRegulationVotes(); + displayVotingWaitMessage(); + } + else { + timeLeftLabel.setText( String.format("Voting period will end in %d seconds.", duration.getTimeLeft() / 1000L) ); + } + } + }); + timer.start(); + } + } + + + private void startRegulationSubmissionTimer() { + if (timer == null) { + duration = Duration.create(dataModel.getRoundConfiguration().getRegulationSubmissionDuration()); + timer = new Timer(1000, new ActionListener() { + public void actionPerformed(ActionEvent event) { + if (duration.hasExpired()) { + timeLeftLabel.setText("Time's up."); + timer.stop(); + timer = null; + String regulation = regulationTextArea.getText(); + client.transmit(new SubmitRegulationRequest(client.getId(), regulation)); + displayVotingWaitMessage(); + } + else { + timeLeftLabel.setText( String.format("You have %d second(s) left to write your regulation.", duration.getTimeLeft() / 1000L) ); + } + } + }); + timer.start(); + } + } private void startChatTimer() { - if (timer == null) { - final Duration duration = Duration.create(dataModel.getRoundConfiguration().getChatDuration()); + if (timer == null) { + // final Duration duration = Duration.create(dataModel.getRoundConfiguration().getChatDuration()); + final Duration duration = Duration.create(dataModel.getRoundConfiguration().getChatDuration()); timer = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent event) { if (duration.hasExpired()) { - timeLeftLabel.setText("Chat is now disabled. The next round will begin shortly."); - addCenterComponent(instructionsScrollPane); - timer.stop(); + timeLeftLabel.setText("Chat is now disabled."); + timer.stop(); timer = null; + initializeRegulationPanel(); } else { timeLeftLabel.setText( String.format("Chat will end in %d seconds.", duration.getTimeLeft() / 1000L) ); @@ -217,7 +347,7 @@ } }); timer.start(); - } + } } private String getInformationLabelText() { @@ -250,7 +380,7 @@ long secondsLeft = roundTimeLeft / 1000L; return "Time left: " + secondsLeft + " second(s)"; } - + private void setInstructions(String s) { instructionsEditorPane.setText(s); instructionsEditorPane.setCaretPosition(0); @@ -262,18 +392,25 @@ private HtmlEditorPane createInstructionsEditorPane() { // JEditorPane pane = new JEditorPane("text/html", - // "Costly Sanctioning Experiment"); + // "Costly Sanctioning Experiment"); final HtmlEditorPane htmlPane = new HtmlEditorPane(); htmlPane.setPreferredSize(new Dimension(400, 400)); htmlPane.setEditable(false); + htmlPane.setBackground(Color.WHITE); htmlPane.setFont(new Font("sansserif", Font.PLAIN, 12)); return htmlPane; } + private RegulationPanel updateRegulationVotingPanel(){ + RegulationPanel regulationPanel = getRegulationPanel(); + regulationPanel.initRegulationVotingComponents(); + return regulationPanel; + } + private void initGuiComponents() { // FIXME: replace with CardLayout for easier switching between panels -// cardLayout = new CardLayout(); - + // cardLayout = new CardLayout(); + setLayout(new BorderLayout(4, 4)); instructionsEditorPane = createInstructionsEditorPane(); instructionsScrollPane = new JScrollPane(instructionsEditorPane); @@ -284,6 +421,7 @@ subjectWindow.setBackground(Color.WHITE); subjectWindow.setForeground(Color.BLACK); subjectWindow.add(subjectView, BorderLayout.CENTER); + // setBackground(SubjectView.FIELD_OF_VISION_COLOR); setBackground(Color.WHITE); // replace with progress bar. timeLeftLabel = new JLabel("Connecting ..."); @@ -291,7 +429,20 @@ // latencyLabel = new JLabel("Latency: 0"); informationLabel.setBackground(Color.YELLOW); informationLabel.setForeground(Color.BLUE); - + + // getSanctioningPanel().initializeVotingPaneWithRegulations(); + + // regulationVotingPane = new JPanel(); + // //regulationVotingPane.setLayout(new BoxLayout(regulationVotingPane, BoxLayout.LINE_AXIS)); + // regulationVotingPane.setLayout(new BorderLayout(4,4)); + // + // regulationVotingIntructions = new JEditorPane(); + // regulationVotingIntructions.setContentType("text/html"); + // regulationVotingIntructions.setEditorKit(new HTMLEditorKit()); + // regulationVotingIntructions.setEditable(false); + // regulationVotingIntructions.setBorder(BorderFactory.createTitledBorder("Regulation voting instructions")); + // regulationVotingIntructionsScrollPane = new JScrollPane(regulationVotingIntructions); + labelPanel = new JPanel(); labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.LINE_AXIS)); labelPanel.setBackground(Color.WHITE); @@ -299,14 +450,17 @@ labelPanel.add(Box.createHorizontalGlue()); labelPanel.add(informationLabel); add(labelPanel, BorderLayout.NORTH); - + // add message window. messagePanel = new JPanel(new BorderLayout()); -// messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); + // messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); messagePanel.add(new JLabel("System Messages"), BorderLayout.NORTH); errorMessageTextPane = new JTextPane(); errorMessageTextPane.setEditable(false); errorMessageTextPane.setFont(new Font("arial", Font.BOLD, 12)); + errorMessageTextPane.setBackground(Color.WHITE); + + addStyles(errorMessageTextPane.getStyledDocument()); errorMessageScrollPane = new JScrollPane(errorMessageTextPane); Dimension scrollPaneSize = new Dimension(getPreferredSize().width, 50); @@ -315,15 +469,16 @@ errorMessageScrollPane.setMaximumSize(scrollPaneSize); messagePanel.add(errorMessageScrollPane, BorderLayout.CENTER); add(messagePanel, BorderLayout.SOUTH); - - + + addKeyListener( createGameWindowKeyListener() ); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { requestFocusInWindow(); } }); - + + // resize listener addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent event) { Component component = event.getComponent(); @@ -331,12 +486,13 @@ Dimension size = new Dimension(component.getWidth(), subjectViewHeight); subjectView.setScreenSize(size); subjectView.setImageSizes(); - repaint(); + GameWindow2D.this.revalidate(); + GameWindow2D.this.repaint(); } }); // add component listeners, chat panel, and sanctioning window IF chat/sanctioning are enabled, and after the end of the round... } - + /** * IMPORTANT: this method handles client keyboard inputs within the game. * @return @@ -351,6 +507,7 @@ public void keyReleased(KeyEvent keyEvent) { keyReleased = true; } + // FIXME: refactor this method if possible. @Override public void keyPressed(KeyEvent keyEvent) { int keyChar = (int) keyEvent.getKeyChar(); @@ -363,13 +520,24 @@ switch (keyCode) { // token request handling case KeyEvent.VK_SPACE: - event = new CollectTokenRequest(client.getId()); + if(dataModel.isHarvestingAllowed()) { + event = new CollectTokenRequest(client.getId()); + } + else { + displayErrorMessage("You cannot harvest at this time.", 1); + } break; // real-time sanctioning keycode handling - case KeyEvent.VK_1: case KeyEvent.VK_2: case KeyEvent.VK_3: case KeyEvent.VK_4: - case KeyEvent.VK_5: case KeyEvent.VK_6: case KeyEvent.VK_7: case KeyEvent.VK_8: - case KeyEvent.VK_9: + case KeyEvent.VK_1: case KeyEvent.VK_2: case KeyEvent.VK_3: + case KeyEvent.VK_4: case KeyEvent.VK_5: case KeyEvent.VK_6: + case KeyEvent.VK_7: case KeyEvent.VK_8: case KeyEvent.VK_9: + if (! dataModel.isSanctioningAllowed()) { + // get rid of magic constants + displayErrorMessage("You aren't allowed to reduce other participants tokens at this time.", 1); + return; + } if (client.canPerformRealTimeSanction()) { + //System.out.println("Can do sanctioning"); int assignedNumber = keyChar - 48; Identifier sanctionee = dataModel.getClientId(assignedNumber); if (sanctionee == null || sanctionee.equals(dataModel.getId())) { @@ -379,11 +547,16 @@ // only allow sanctions for subjects within this subject's field of vision Point subjectPosition = dataModel.getClientDataMap().get(sanctionee).getPoint(); if (dataModel.getClientData().isSubjectInFieldOfVision(subjectPosition)) { + // System.out.println("sanctioning event sent"); event = new RealTimeSanctionRequest(dataModel.getId(), sanctionee); + // below function must be used for enforcement type4 dataModel.sanction(dataModel.getId(), sanctionee); + } + else { + displayErrorMessage("The participant is out of range ", 1); + return; } } - else return; break; // reset token distribution request handling case KeyEvent.VK_R: @@ -410,11 +583,11 @@ dataModel.getClientData().setPosition(newPosition); subjectView.repaint(); } - */ + */ } if (keyReleased) { // FIXME: have client directly render these requests? Would - // make the app more "responsive" and less tied to server latency. + // make the app more "responsive" and less tied to server latency. channel.handle(event); keyReleased = false; } @@ -422,7 +595,7 @@ }; } - + private boolean canResetTokenDistribution() { RoundConfiguration configuration = dataModel.getRoundConfiguration(); return configuration.isPracticeRound() && configuration.isPrivateProperty(); @@ -434,17 +607,17 @@ remove(currentCenterComponent); add(newCenterComponent, BorderLayout.CENTER); newCenterComponent.setVisible(true); - revalidate(); } currentCenterComponent = newCenterComponent; + revalidate(); } public void startRound() { final RoundConfiguration configuration = dataModel.getRoundConfiguration(); - if (timer != null) { - timer.stop(); - timer = null; - } + if (timer != null) { + timer.stop(); + timer = null; + } // currentExperimentConfiguration = configuration; Runnable runnable = new Runnable() { public void run() { @@ -462,11 +635,14 @@ }; SwingUtilities.invokeLater(runnable); } - - public void displayErrorMessage(String errorMessage) { + + public void displayErrorMessage(String errorMessage, int par) { // String chatHandle = getChatHandle(source); + if(par==1)errorMessageTextPane.setForeground(Color.RED); + else errorMessageTextPane.setForeground(Color.BLACK); + StyledDocument document = errorMessageTextPane.getStyledDocument(); - try { + try { document.insertString(document.getLength(), errorMessage + "\n", document.getStyle("bold")); errorMessageTextPane.setCaretPosition(document.getLength()); } @@ -475,7 +651,7 @@ throw new RuntimeException(e); } } - + // FIXME: add to some common GUI package? private void addStyles(StyledDocument styledDocument) { // and why not have something like... StyleContext.getDefaultStyle() to @@ -490,25 +666,26 @@ StyleConstants.setItalic(styledDocument .addStyle("italic", defaultStyle), true); } - + + private double getIncome(float numTokens) { if (dataModel.getRoundConfiguration().isPracticeRound()) { return 0.0f; } return dataModel.getRoundConfiguration().getDollarsPerToken() * numTokens; } - + private void addDebriefingText(EndRoundEvent event) { instructionsBuilder.delete(0, instructionsBuilder.length()); instructionsBuilder.append( String.format("<h3>Your stats in this round:</h3>" + - "<ul>" + - "<li>Tokens collected: %d</li>" + - "<li>Income: $%3.2f</li>" + + "<ul>" + + "<li>Tokens collected: %d</li>" + + "<li>Income: $%3.2f</li>" + "</ul>", event.getCurrentTokens(), getIncome(event.getCurrentTokens())) - ); + ); double showUpFee = dataModel.getRoundConfiguration().getParentConfiguration().getShowUpFee(); instructionsBuilder.append(String.format("Your <b>total income</b> so far (including a $%3.2f bonus for showing up) is : $%3.2f<hr>", showUpFee, dataModel.getTotalIncome() + showUpFee)); @@ -518,7 +695,7 @@ } setInstructions(instructionsBuilder.toString()); } - + private void postSanctionDebriefingText(final PostRoundSanctionUpdateEvent event) { instructionsBuilder.delete(0, instructionsBuilder.length()); ClientData clientData = event.getClientData(); @@ -538,7 +715,7 @... [truncated message content] |