1 package net.sourceforge.simplegamenet.framework.gui;
2
3 import java.awt.*;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.KeyEvent;
6 import java.awt.event.WindowAdapter;
7 import java.awt.event.WindowEvent;
8 import java.awt.event.WindowListener;
9 import java.io.IOException;
10 import javax.swing.*;
11 import javax.swing.event.ChangeEvent;
12 import javax.swing.event.ChangeListener;
13 import net.sourceforge.simplegamenet.framework.model.SimpleGameNetSettings;
14 import net.sourceforge.simplegamenet.specs.model.GameFactory;
15 import net.sourceforge.simplegamenet.util.proportionlayout.ProportionConstraints;
16 import net.sourceforge.simplegamenet.util.proportionlayout.ProportionLayout;
17
18 /***
19 * The main class of the executable jar which is responsible for initializing the entire
20 * SimpleGameNet framework.
21 * <p/>
22 * All game modules are dynamically loaded from the executable jar file path's subdirectory "games".
23 * A game module is required to be jarred into one jar file with it's "Main-Class" attribute set to
24 * its {@link net.sourceforge.simplegamenet.specs.model.GameFactory}.
25 *
26 * @author Geoffrey De Smet
27 * @version 1.0, 2003-06-18
28 * @see GameFactory
29 * @see net.sourceforge.simplegamenet.specs.model.GamePlayerClient
30 * @see net.sourceforge.simplegamenet.specs.model.GameServer
31 */
32 public class SimpleGameNetFrame extends JFrame {
33
34 private static final int NOT_CONNECTED = 0;
35 private static final int HOSTED_GAME = 11;
36 private static final int JOINED_GAME = 21;
37
38 public static void createSimpleGameNetFrame() {
39 System.out.println("SimpleGameNet "
40 + SimpleGameNetSettings.getInstance().getVersion().toString());
41 SimpleGameNetFrame currentFrame = new SimpleGameNetFrame();
42 currentFrame.pack();
43 currentFrame.setLocationRelativeTo(null);
44 currentFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
45 currentFrame.setVisible(true);
46 }
47
48 private Action connectAction;
49 private Action disconnectAction;
50 private Action joinAction;
51 private Action hostAction;
52 private Action exitAction;
53 private Action optionsAction;
54 private Action aboutAction;
55
56 private JTabbedPane tabbedPane;
57
58
59
60
61
62 private StatusTabPanel statusTabPanel = new StatusTabPanel();
63 private ChatTabPanel chatTabPanel = new ChatTabPanel();
64 private GameTabPanel gameTabPanel = new GameTabPanel();
65 private GameSettingsTabPanel gameSettingsTabPanel = new GameSettingsTabPanel();
66
67 private JTextArea logTextArea;
68
69 private ServerGUIFacade serverGUIFacade = null;
70 private ClientGUIFacade clientGUIFacade = null;
71
72 private int appState;
73
74 private SimpleGameNetFrame() {
75 super();
76 initActions();
77 initFrame();
78 initMenuBar();
79 initContent();
80 logTextArea = statusTabPanel.getLogTextArea();
81 updateAppState(NOT_CONNECTED, "Not connected");
82 }
83
84 private void initFrame() {
85 ImageIcon simpleGameNetIcon = new ImageIcon(
86 getClass().getResource("SimpleGameNetIcon.png"),
87 "SimpleGameNet icon");
88 setIconImage(simpleGameNetIcon.getImage());
89 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
90 WindowListener windowListener = new WindowAdapter() {
91 public void windowClosing(WindowEvent windowEvent) {
92 exit();
93 }
94
95 public void windowClosed(WindowEvent windowEvent) {
96 System.exit(0);
97 }
98 };
99 addWindowListener(windowListener);
100 }
101
102 private void initActions() {
103 Icon connectIcon = new ImageIcon(getClass().getResource("ConnectIcon.png"));
104 connectAction = new AbstractAction("Connect...", connectIcon) {
105 public void actionPerformed(ActionEvent event) {
106 ConnectionWizardDialog connectionWizardDialog
107 = new ConnectionWizardDialog(SimpleGameNetFrame.this);
108 connectionWizardDialog.show();
109 }
110 };
111 connectAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_C));
112 connectAction.putValue(Action.SHORT_DESCRIPTION, "Join or host a game...");
113
114 Icon disconnectIcon = new ImageIcon(getClass().getResource("DisconnectIcon.png"));
115 disconnectAction = new AbstractAction("Disconnect", disconnectIcon) {
116 public void actionPerformed(ActionEvent event) {
117 disconnect();
118 }
119 };
120 disconnectAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_D));
121 disconnectAction.putValue(Action.SHORT_DESCRIPTION, "Disconnect from the game");
122
123 Icon joinIcon = new ImageIcon(getClass().getResource("JoinIcon.png"));
124 joinAction = new AbstractAction("Join...", joinIcon) {
125 public void actionPerformed(ActionEvent event) {
126 ConnectionWizardDialog connectionWizardDialog
127 = new ConnectionWizardDialog(SimpleGameNetFrame.this,
128 ConnectionWizardDialog.JOIN_CONNECTION);
129 connectionWizardDialog.show();
130 }
131 };
132 joinAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_J));
133 joinAction.putValue(Action.SHORT_DESCRIPTION, "Join a game...");
134
135 Icon hostIcon = new ImageIcon(getClass().getResource("HostIcon.png"));
136 hostAction = new AbstractAction("Host...", hostIcon) {
137 public void actionPerformed(ActionEvent event) {
138 ConnectionWizardDialog connectionWizardDialog
139 = new ConnectionWizardDialog(SimpleGameNetFrame.this,
140 ConnectionWizardDialog.HOST_CONNECTION);
141 connectionWizardDialog.show();
142 }
143 };
144 hostAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_H));
145 hostAction.putValue(Action.SHORT_DESCRIPTION, "Host a game...");
146
147 Icon optionsIcon = new ImageIcon(getClass().getResource("OptionsIcon.png"));
148 optionsAction = new AbstractAction("Options", optionsIcon) {
149 public void actionPerformed(ActionEvent event) {
150 OptionsDialog optionsDialog = new OptionsDialog(SimpleGameNetFrame.this);
151 optionsDialog.show();
152 }
153 };
154 optionsAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_O));
155 optionsAction.putValue(Action.SHORT_DESCRIPTION, "Options and settings");
156
157 Icon exitIcon = new ImageIcon(getClass().getResource("ExitIcon.png"));
158 exitAction = new AbstractAction("Exit", exitIcon) {
159 public void actionPerformed(ActionEvent event) {
160 exit();
161 }
162 };
163 exitAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_X));
164 exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit");
165
166 Icon aboutIcon = new ImageIcon(getClass().getResource("AboutIcon.png"));
167 aboutAction = new AbstractAction("About", aboutIcon) {
168 public void actionPerformed(ActionEvent event) {
169 AboutDialog aboutDialog = new AboutDialog(SimpleGameNetFrame.this);
170 aboutDialog.show();
171 }
172 };
173 aboutAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_A));
174 aboutAction.putValue(Action.SHORT_DESCRIPTION, "About SimpleGameNet");
175 }
176
177 private void initMenuBar() {
178 JMenuBar menuBar = new JMenuBar();
179 JMenu gameMenu = new JMenu("Game");
180 gameMenu.setMnemonic(KeyEvent.VK_G);
181 gameMenu.add(connectAction);
182 gameMenu.add(disconnectAction);
183 gameMenu.addSeparator();
184 gameMenu.add(joinAction);
185 gameMenu.add(hostAction);
186 gameMenu.addSeparator();
187 gameMenu.add(optionsAction);
188 gameMenu.addSeparator();
189 gameMenu.add(exitAction);
190 menuBar.add(gameMenu);
191 JMenu helpMenu = new JMenu("Help");
192 helpMenu.setMnemonic(KeyEvent.VK_H);
193 helpMenu.add(aboutAction);
194 menuBar.add(helpMenu);
195 setJMenuBar(menuBar);
196 }
197
198 private void initContent() {
199 Container contentPanel = getContentPane();
200 ProportionLayout layout = new ProportionLayout();
201 layout.appendColumn(10);
202 layout.appendColumn(0, 1.0);
203 layout.appendColumn(10);
204 layout.appendRow(10);
205 layout.appendRow(0, 1.0);
206 layout.appendRow(10);
207 contentPanel.setLayout(layout);
208
209 tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);
210 tabbedPane.add("Status", statusTabPanel);
211 tabbedPane.add("Chat", chatTabPanel);
212 tabbedPane.add("Game", gameTabPanel);
213 tabbedPane.add("Game settings", gameSettingsTabPanel);
214 tabbedPane.addChangeListener(new ChangeListener() {
215 public void stateChanged(ChangeEvent changeEvent) {
216 switch (tabbedPane.getSelectedIndex()) {
217 case 0:
218 statusTabPanel.requestFocusInWindow();
219 break;
220 case 1:
221 chatTabPanel.requestFocusInWindow();
222 break;
223 case 2:
224 gameTabPanel.requestFocusInWindow();
225 break;
226 case 3:
227 gameSettingsTabPanel.requestFocusInWindow();
228 break;
229 }
230 }
231 });
232 contentPanel.add(tabbedPane, new ProportionConstraints(1, 1));
233 }
234
235 private void updateAppState(int newAppState, String statusTitle) {
236 appState = newAppState;
237 boolean connected = appState != NOT_CONNECTED;
238
239 connectAction.setEnabled(!connected);
240 disconnectAction.setEnabled(connected);
241 joinAction.setEnabled(!connected);
242 hostAction.setEnabled(!connected);
243
244 if (!connected) {
245 if (tabbedPane.getSelectedIndex() > 1) {
246 tabbedPane.setSelectedIndex(1);
247 }
248 }
249 tabbedPane.setEnabledAt(2, connected);
250 tabbedPane.setEnabledAt(3, connected);
251
252 setTitle(statusTitle + " - SimpleGameNet "
253 + SimpleGameNetSettings.getInstance().getVersion().toString());
254 }
255
256 public void hostGame(ConnectionConfig connectionConfig, GameFactory gameFactory)
257 throws IOException {
258 if (appState != NOT_CONNECTED) {
259 return;
260 }
261 serverGUIFacade = new ServerGUIFacade(this, logTextArea);
262 serverGUIFacade.hostGame(connectionConfig, gameFactory);
263
264 clientGUIFacade = new ClientGUIFacade(this, statusTabPanel, chatTabPanel, gameTabPanel,
265 gameSettingsTabPanel, logTextArea, true);
266 clientGUIFacade.joinGame(connectionConfig);
267
268 updateAppState(HOSTED_GAME, "Hosting " + gameFactory.getName());
269 }
270
271 public void joinGame(ConnectionConfig connectionConfig)
272 throws IOException {
273 if (appState != NOT_CONNECTED) {
274 return;
275 }
276 clientGUIFacade = new ClientGUIFacade(this, statusTabPanel, chatTabPanel,
277 gameTabPanel, gameSettingsTabPanel,
278 logTextArea, false);
279 GameFactory gameFactory = clientGUIFacade.joinGame(connectionConfig);
280 updateAppState(JOINED_GAME, "Joined " + gameFactory.getName());
281 }
282
283 private void disconnect() {
284 switch (appState) {
285 case HOSTED_GAME:
286 serverGUIFacade.closeServer();
287 break;
288 case JOINED_GAME:
289 clientGUIFacade.leaveServer();
290 break;
291 }
292 }
293
294 public void disconnected() {
295 updateAppState(NOT_CONNECTED, "Not connected");
296 }
297
298 private void exit() {
299 if (appState == NOT_CONNECTED) {
300 dispose();
301 } else {
302 if (JOptionPane.showConfirmDialog(this,
303 "Do you want to disconnect?", "You are still connected.",
304 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
305 == JOptionPane.YES_OPTION) {
306 disconnect();
307 dispose();
308 }
309 }
310 }
311
312 }