source: src/main/java/genius/gui/tournament/MultiTournamentModel.java@ 87

Last change on this file since 87 was 87, checked in by Wouter Pasman, 7 years ago

#28 work around type checking issue with SpinnerModel.

File size: 8.0 KB
Line 
1package genius.gui.tournament;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.List;
6
7import javax.swing.event.ChangeEvent;
8import javax.swing.event.ChangeListener;
9import javax.swing.event.ListDataEvent;
10import javax.swing.event.ListDataListener;
11
12import genius.core.config.MultilateralTournamentConfiguration;
13import genius.core.listener.DefaultListenable;
14import genius.core.listener.Listener;
15import genius.core.persistent.PersistentDataType;
16import genius.core.repository.MultiPartyProtocolRepItem;
17import genius.core.repository.ParticipantRepItem;
18import genius.core.repository.PartyRepItem;
19import genius.core.repository.ProfileRepItem;
20import genius.gui.deadline.DeadlineModel;
21import genius.gui.negosession.ContentProxy;
22import genius.gui.panels.BooleanModel;
23import genius.gui.panels.SingleSelectionModel;
24import genius.gui.panels.SpinnerModel;
25import genius.gui.panels.SubsetSelectionModel;
26
27/**
28 * Contains the basic elements of MultilateralTournamentConfiguration, but
29 * mutable and the subcomponents are listenable so that we can use it for the
30 * MVC pattern. It listens to changes in the protocol and updates the model when
31 * necessary.
32 *
33 * <p>
34 * You can get notified when the multitournamentmodel is complete (as indicated
35 * by the user, he can press 'start' in the GUI). The data passed with the
36 * notification is the {@link MultilateralTournamentConfiguration}.
37 *
38 * @author W.Pasman
39 *
40 */
41public class MultiTournamentModel
42 extends DefaultListenable<MultilateralTournamentConfiguration> {
43
44 // models are all final, as they will be used to hook up the GUI.
45
46 private final SubsetSelectionModel<ProfileRepItem> profileModel;
47 private final SubsetSelectionModel<ParticipantRepItem> partyModel;
48 private final SingleSelectionModel<MultiPartyProtocolRepItem> protocolModel;
49 private final DeadlineModel deadlineModel = new DeadlineModel();
50 private final SingleSelectionModel<PartyRepItem> mediatorModel;
51 private final SpinnerModel<Integer> numTournamentsModel = new SpinnerModel<Integer>(
52 1, 1, 2000000000, 1);
53 private final SpinnerModel<Integer> numAgentsPerSessionModel = new SpinnerModel<Integer>(
54 1, 1, 2000000000, 1);
55 private final BooleanModel agentRepetitionModel = new BooleanModel(false);
56 private final BooleanModel randomSessionOrderModel = new BooleanModel(
57 false);
58 private final BooleanModel enablePrintModel = new BooleanModel(false);
59 private final BilateralOptionsModel bilateralOptionsModel;
60 private final SingleSelectionModel<PersistentDataType> persistentDatatypeModel = new SingleSelectionModel<PersistentDataType>(
61 Arrays.asList(PersistentDataType.values()));
62
63 public MultiTournamentModel() {
64 // load initial models.
65 protocolModel = new SingleSelectionModel<>(
66 ContentProxy.fetchProtocols());
67 profileModel = new SubsetSelectionModel<ProfileRepItem>(
68 ContentProxy.fetchProfiles());
69
70 // stubs for the partyModel and mediatorModel, will be set properly in
71 // updateSubmodels.
72 partyModel = new SubsetSelectionModel<ParticipantRepItem>(
73 new ArrayList<ParticipantRepItem>());
74 mediatorModel = new SingleSelectionModel<PartyRepItem>(
75 new ArrayList<PartyRepItem>());
76
77 bilateralOptionsModel = new BilateralOptionsModel(protocolModel);
78
79 updateSubmodels();
80 updateAgentRepetition();
81
82 addConstraints();
83
84 }
85
86 public SubsetSelectionModel<ProfileRepItem> getProfileModel() {
87 return profileModel;
88 }
89
90 /**
91 * @return model containing the deadline information
92 */
93 public DeadlineModel getDeadlineModel() {
94 return deadlineModel;
95 }
96
97 /**
98 * @return model containing the parties to use in the tournament
99 */
100 public SubsetSelectionModel<ParticipantRepItem> getPartyModel() {
101 return partyModel;
102 }
103
104 /**
105 * @return the model containing the number of tournaments to be run. This is
106 * also called "number of sessions" in some places. May be somethign
107 * historic.
108 */
109 public SpinnerModel getNumTournamentsModel() {
110 return numTournamentsModel;
111 }
112
113 /**
114 * @return the model containing the number of agents per session.
115 */
116 public SpinnerModel getNumAgentsPerSessionModel() {
117 return numAgentsPerSessionModel;
118 }
119
120 /**
121 * @return mediator model, or null if no mediator for this protocol
122 */
123 public SingleSelectionModel<PartyRepItem> getMediatorModel() {
124 return mediatorModel;
125 }
126
127 /**
128 * @return this model, converted in a
129 * {@link MultilateralTournamentConfiguration}.
130 */
131 public MultilateralTournamentConfiguration getConfiguration() {
132 List<ProfileRepItem> profilesB = new ArrayList<>();
133 List<ParticipantRepItem> partiesB = new ArrayList<>();
134
135 if (!bilateralOptionsModel.getPlayBothSides().getValue()) {
136 profilesB = bilateralOptionsModel.getProfileModelB()
137 .getSelectedItems();
138 partiesB = bilateralOptionsModel.getPartyModelB()
139 .getSelectedItems();
140 }
141 return new MultilateralTournamentConfiguration(
142 protocolModel.getSelection(), deadlineModel.getDeadline(),
143 mediatorModel.getSelection(), partyModel.getSelectedItems(),
144 profileModel.getSelectedItems(), partiesB, profilesB,
145 (int) numTournamentsModel.getValue(),
146 (int) numAgentsPerSessionModel.getValue(),
147 agentRepetitionModel.getValue(),
148 randomSessionOrderModel.getValue(),
149 persistentDatatypeModel.getSelection(),
150 enablePrintModel.getValue());
151
152 }
153
154 /**
155 * @return model containing the protocol
156 */
157 public SingleSelectionModel<MultiPartyProtocolRepItem> getProtocolModel() {
158 return protocolModel;
159 }
160
161 public BooleanModel getAgentRepetitionModel() {
162 return agentRepetitionModel;
163 }
164
165 public BooleanModel getRandomSessionOrderModel() {
166 return randomSessionOrderModel;
167 }
168
169 /**
170 * Call this when model is completed (user clicked 'start'). TODO check that
171 * the model is indeed complete.
172 */
173 public void modelIsComplete() {
174 notifyChange(getConfiguration());
175 }
176
177 public BilateralOptionsModel getBilateralOptionsModel() {
178 return bilateralOptionsModel;
179 }
180
181 public SingleSelectionModel<PersistentDataType> getPersistentDatatypeModel() {
182 return persistentDatatypeModel;
183 }
184
185 /******************* support funcs ***********************/
186 /**
187 * Update the repetition setting. Must go to "true, locked" mode if
188 * agentsPerSession is bigger than the number of available agents.
189 */
190 private void updateAgentRepetition() {
191 agentRepetitionModel.setLock(false);
192 if ((int) numAgentsPerSessionModel.getValue() > partyModel
193 .getSelectedItems().size()) {
194 agentRepetitionModel.setValue(true);
195 agentRepetitionModel.setLock(true);
196 }
197 }
198
199 /**
200 * connecting listeners that check the constraints between the fields in the
201 * model
202 */
203 private void addConstraints() {
204 // protocol has major impact on the submodels
205 protocolModel.addListDataListener(new ListDataListener() {
206
207 @Override
208 public void intervalRemoved(ListDataEvent e) {
209 }
210
211 @Override
212 public void intervalAdded(ListDataEvent e) {
213 }
214
215 @Override
216 public void contentsChanged(ListDataEvent e) {
217 updateSubmodels();
218 }
219 });
220
221 // The "Agents per session" field by default equals number of profiles;
222 // the agent repetition is depending on this too.
223 profileModel.addListener(new Listener<ProfileRepItem>() {
224 @Override
225 public void notifyChange(ProfileRepItem data) {
226 numAgentsPerSessionModel
227 .setValue(profileModel.getSelectedItems().size());
228 updateAgentRepetition();
229 }
230 });
231
232 // #parties and numAgentsPerSession -> repetition
233 partyModel.addListener(new Listener<ParticipantRepItem>() {
234 @Override
235 public void notifyChange(ParticipantRepItem data) {
236 updateAgentRepetition();
237 }
238 });
239 numAgentsPerSessionModel.addChangeListener(new ChangeListener() {
240 @Override
241 public void stateChanged(ChangeEvent e) {
242 updateAgentRepetition();
243 }
244 });
245 }
246
247 /**
248 * Update the models after a protocol change.
249 *
250 * @param protocol
251 * the new protocol.
252 */
253 private void updateSubmodels() {
254 MultiPartyProtocolRepItem protocol = protocolModel.getSelection();
255 partyModel.setAllItems(ContentProxy.fetchPartiesForProtocol(protocol));
256 mediatorModel
257 .setAllItems(ContentProxy.fetchMediatorsForProtocol(protocol));
258 }
259
260 public BooleanModel getEnablePrint() {
261 return enablePrintModel;
262 }
263
264}
Note: See TracBrowser for help on using the repository browser.