1 package net.sourceforge.simplegamenet.framework.gui;
2
3 import java.awt.*;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.io.IOException;
7 import javax.swing.*;
8 import net.sourceforge.simplegamenet.framework.GameFactoryManager;
9 import net.sourceforge.simplegamenet.framework.transport.ClientLoginException;
10 import net.sourceforge.simplegamenet.specs.model.GameFactory;
11 import net.sourceforge.simplegamenet.util.proportionlayout.ProportionConstraints;
12 import net.sourceforge.simplegamenet.util.proportionlayout.ProportionLayout;
13
14 public class ConnectionWizardDialog extends JDialog implements ActionListener {
15
16 public static final int JOIN_OR_HOST_CONNECTION = 100;
17 public static final int JOIN_CONNECTION = 101;
18 public static final int HOST_CONNECTION = 111;
19
20 private static final int JOIN_HOST = 0;
21 private static final int JOIN_SETTINGS = 1;
22 private static final int HOST_SETTINGS = 2;
23 private static final int GAME_CHOICE = 3;
24 private static final int GAME_SETTINGS_CHOICE = 4;
25
26 private static final String[] stepTitles = {
27 "Choose connection type", "Join game",
28 "Host game", "Choose game",
29 "Choose game settings"
30 };
31 private static final String[] stepStrings = {
32 "Step 1:", "Step 2:", "Step 2:",
33 "Step 3:", "Step 4:"
34 };
35 private static final boolean[][] stepEnabledStates = {
36 {false, true, false, true},
37 {true, false, true, true},
38 {true, true, false, true},
39 {true, true, true, true},
40 {true, false, true, true}
41 };
42
43 private SimpleGameNetFrame simpleGameNetFrame;
44 private GameFactory[] gameFactories;
45
46 private JLabel stepLabel = new JLabel();
47 private JPanel stepPanel = new JPanel();
48 private CardLayout stepCardLayout = new CardLayout();
49 private JButton[] navigationButtons = new JButton[4];
50
51
52
53
54
55 private JoinHostGamePanel joinHostGamePanel;
56 private JoinSettingsPanel joinSettingsPanel;
57 private HostSettingsPanel hostSettingsPanel;
58 private GameChoicePanel gameChoicePanel;
59 private GameSettingsChoicePanel gameSettingsChoicePanel;
60
61 private ConnectionConfig connectionConfig;
62
63 private int hostGameInterfacesIndex = 0;
64
65 private int state;
66
67 public ConnectionWizardDialog(SimpleGameNetFrame simpleGameNetFrame) {
68 this(simpleGameNetFrame, JOIN_OR_HOST_CONNECTION);
69 }
70
71 public ConnectionWizardDialog(SimpleGameNetFrame simpleGameNetFrame,
72 int connectionType) {
73 super(simpleGameNetFrame, "", true);
74 this.simpleGameNetFrame = simpleGameNetFrame;
75 connectionConfig = ConnectionConfig.load();
76 gameFactories = GameFactoryManager.getInstance().getGameFactories();
77 Container contentPanel = getContentPane();
78 ProportionLayout layout = new ProportionLayout();
79 layout.appendColumn(10);
80 layout.appendColumn(0, 1.0);
81 layout.appendColumn(10);
82 layout.appendRow(10);
83 layout.appendRow(0, ProportionLayout.NO_PROPORTION);
84 layout.appendRow(10);
85 layout.appendRow(0, 1.0);
86 layout.appendRow(10);
87 layout.appendRow(0, ProportionLayout.NO_PROPORTION);
88 layout.appendRow(10);
89 contentPanel.setLayout(layout);
90
91 contentPanel.add(stepLabel, new ProportionConstraints(1, 1));
92 stepPanel.setLayout(stepCardLayout);
93 joinHostGamePanel = new JoinHostGamePanel(this);
94 joinSettingsPanel = new JoinSettingsPanel(this);
95 hostSettingsPanel = new HostSettingsPanel(this);
96 gameChoicePanel = new GameChoicePanel(this, gameFactories);
97 gameSettingsChoicePanel = new GameSettingsChoicePanel(this, gameFactories);
98 stepPanel.add(joinHostGamePanel, Integer.toString(JOIN_HOST));
99 stepPanel.add(joinSettingsPanel, Integer.toString(JOIN_SETTINGS));
100 stepPanel.add(hostSettingsPanel, Integer.toString(HOST_SETTINGS));
101 stepPanel.add(gameChoicePanel, Integer.toString(GAME_CHOICE));
102 stepPanel.add(gameSettingsChoicePanel, Integer.toString(GAME_SETTINGS_CHOICE));
103 contentPanel.add(stepPanel, new ProportionConstraints(1, 3));
104 ProportionLayout navigationLayout = new ProportionLayout();
105 navigationLayout.appendColumn(0, 1.0);
106 navigationLayout.appendColumn(10);
107 navigationLayout.appendColumn(0, 1.0);
108 navigationLayout.appendColumn(10);
109 navigationLayout.appendColumn(0, 1.0);
110 navigationLayout.appendColumn(10);
111 navigationLayout.appendColumn(0, 1.0);
112 navigationLayout.appendRow(0, ProportionLayout.NO_PROPORTION);
113 JPanel navigationPanel = new JPanel(navigationLayout);
114 navigationButtons[0] = new JButton("Previous");
115 navigationButtons[1] = new JButton("Next");
116 navigationButtons[2] = new JButton("Finish");
117 navigationButtons[3] = new JButton("Cancel");
118 for (int i = 0; i < navigationButtons.length; i++) {
119 navigationButtons[i].addActionListener(this);
120 navigationPanel.add(navigationButtons[i],
121 new ProportionConstraints(i * 2, 0));
122 }
123 contentPanel.add(navigationPanel, new ProportionConstraints(1, 5));
124 switch (connectionType) {
125 case JOIN_OR_HOST_CONNECTION:
126 switchToStep(JOIN_HOST);
127 break;
128 case JOIN_CONNECTION:
129 joinHostGamePanel.setConnectionType(JOIN_CONNECTION);
130 switchToStep(JOIN_SETTINGS);
131 break;
132 case HOST_CONNECTION:
133 joinHostGamePanel.setConnectionType(HOST_CONNECTION);
134 switchToStep(HOST_SETTINGS);
135 break;
136 }
137 pack();
138 Dimension frameSize = simpleGameNetFrame.getSize();
139 Dimension dialogSize = getSize();
140 setLocation((frameSize.width - dialogSize.width) / 2,
141 (frameSize.height - dialogSize.height) / 2);
142 setLocationRelativeTo(simpleGameNetFrame);
143 }
144
145 /***
146 * Invoked when an action occurs.
147 */
148 public void actionPerformed(ActionEvent actionEvent) {
149 if (actionEvent.getSource() == navigationButtons[0]) {
150 previous();
151 } else if (actionEvent.getSource() == navigationButtons[1]) {
152 next();
153 } else if (actionEvent.getSource() == navigationButtons[2]) {
154 finish();
155 } else if (actionEvent.getSource() == navigationButtons[3]) {
156 dispose();
157 }
158 }
159
160 private void previous() {
161 switch (state) {
162 case JOIN_SETTINGS:
163 switchToStep(JOIN_HOST);
164 break;
165 case HOST_SETTINGS:
166 switchToStep(JOIN_HOST);
167 break;
168 case GAME_CHOICE:
169 switchToStep(HOST_SETTINGS);
170 break;
171 case GAME_SETTINGS_CHOICE:
172 switchToStep(GAME_CHOICE);
173 break;
174 }
175 }
176
177 private void next() {
178 switch (state) {
179 case JOIN_HOST:
180 if (!joinHostGamePanel.areSettingsAcceptable()) {
181 return;
182 }
183 switch (joinHostGamePanel.getConnectionType()) {
184 case JOIN_CONNECTION:
185 switchToStep(JOIN_SETTINGS);
186 break;
187 case HOST_CONNECTION:
188 switchToStep(HOST_SETTINGS);
189 break;
190 }
191 break;
192 case HOST_SETTINGS:
193 if (!hostSettingsPanel.areSettingsAcceptable()) {
194 return;
195 }
196 switchToStep(GAME_CHOICE);
197 break;
198 case GAME_CHOICE:
199 if (!gameChoicePanel.areSettingsAcceptable()) {
200 return;
201 }
202 hostGameInterfacesIndex = gameChoicePanel.getGameFactoriesIndex();
203 gameSettingsChoicePanel.setGameFactoriesIndex(hostGameInterfacesIndex);
204 switchToStep(GAME_SETTINGS_CHOICE);
205 break;
206 }
207 }
208
209 private void finish() {
210 switch (state) {
211 case JOIN_SETTINGS:
212 if (!joinSettingsPanel.areSettingsAcceptable()) {
213 return;
214 }
215 try {
216 simpleGameNetFrame.joinGame(connectionConfig);
217 ConnectionConfig.store(connectionConfig);
218 dispose();
219 } catch (IOException exception) {
220 if (exception instanceof ClientLoginException) {
221 switch (((ClientLoginException) exception).getType()) {
222 case ClientLoginException.BANNED:
223 JOptionPane.showMessageDialog(this,
224 "You are banned from the server.",
225 "Login failed", JOptionPane.ERROR_MESSAGE);
226 break;
227 case ClientLoginException.PROTOCOL_VIOLATION:
228 JOptionPane.showMessageDialog(this,
229 "SimpleGameNet protocol violation occured.",
230 "Login failed", JOptionPane.ERROR_MESSAGE);
231 break;
232 case ClientLoginException.CLIENT_SGN_VERSION:
233 JOptionPane.showMessageDialog(this,
234 "Your SimpleGameNet version is older "
235 + "then the one of the host.",
236 "Login failed", JOptionPane.ERROR_MESSAGE);
237 break;
238 case ClientLoginException.SERVER_SGN_VERSION:
239 JOptionPane.showMessageDialog(this,
240 "The SimpleGameNet version of the host is older "
241 + "then yours.",
242 "Login failed", JOptionPane.ERROR_MESSAGE);
243 break;
244 case ClientLoginException.GAME_NOT_FOUND:
245 JOptionPane.showMessageDialog(this,
246 "You do not have the game being hosted.",
247 "Login failed", JOptionPane.ERROR_MESSAGE);
248 break;
249 case ClientLoginException.CLIENT_GAME_VERSION:
250 JOptionPane.showMessageDialog(this,
251 "Your game version is older "
252 + "then the one of the host.",
253 "Login failed", JOptionPane.ERROR_MESSAGE);
254 break;
255 case ClientLoginException.SERVER_GAME_VERSION:
256 JOptionPane.showMessageDialog(this,
257 "The game version of the host is older "
258 + "then yours.",
259 "Login failed", JOptionPane.ERROR_MESSAGE);
260 break;
261 case ClientLoginException.LOGIN_NOT_ACCEPTED:
262 JOptionPane.showMessageDialog(this,
263 "The game did not accept your connection.",
264 "Login failed", JOptionPane.ERROR_MESSAGE);
265 break;
266 default :
267 JOptionPane.showMessageDialog(this,
268 "Could not login.",
269 "Login failed", JOptionPane.ERROR_MESSAGE);
270 break;
271 }
272 } else {
273 JOptionPane.showMessageDialog(this,
274 "Could not connect to the host.",
275 "Connection failed", JOptionPane.ERROR_MESSAGE);
276 }
277 }
278 break;
279 case GAME_CHOICE:
280 if (!gameChoicePanel.areSettingsAcceptable()) {
281 return;
282 }
283 hostGameInterfacesIndex = gameChoicePanel.getGameFactoriesIndex();
284 gameSettingsChoicePanel.setGameFactoriesIndex(hostGameInterfacesIndex);
285 case GAME_SETTINGS_CHOICE:
286 if (!gameSettingsChoicePanel.areSettingsAcceptable()) {
287 return;
288 }
289 try {
290 simpleGameNetFrame.hostGame(connectionConfig,
291 gameFactories[hostGameInterfacesIndex]);
292 ConnectionConfig.store(connectionConfig);
293 dispose();
294 } catch (IOException exception) {
295 JOptionPane.showMessageDialog(this,
296 "The port " + connectionConfig.getPort()
297 + " is already taken by another application.",
298 "Hosting failed", JOptionPane.ERROR_MESSAGE);
299 }
300 break;
301 }
302 }
303
304 private void switchToStep(int state) {
305 this.state = state;
306 setTitle(stepTitles[state]);
307 stepLabel.setText(stepStrings[state]);
308 for (int i = 0; i < navigationButtons.length; i++) {
309 navigationButtons[i].setEnabled(stepEnabledStates[state][i]);
310 }
311 stepCardLayout.show(stepPanel, Integer.toString(state));
312 }
313
314 public ConnectionConfig getConnectionConfig() {
315 return connectionConfig;
316 }
317
318 }