source: java/client_3D/src/com/framsticks/net/client3D/App.java @ 66

Last change on this file since 66 was 66, checked in by Maciej Komosinski, 13 years ago

set 'eol-style' to 'native'

  • Property svn:eol-style set to native
File size: 13.6 KB
Line 
1package com.framsticks.net.client3D;
2
3import java.awt.BorderLayout;
4import java.awt.Color;
5import java.awt.event.ActionEvent;
6import java.awt.event.ActionListener;
7import java.io.IOException;
8import java.util.ArrayList;
9
10import javax.swing.JCheckBoxMenuItem;
11import javax.swing.JFrame;
12import javax.swing.JMenu;
13import javax.swing.JMenuBar;
14import javax.swing.JMenuItem;
15import javax.swing.JOptionPane;
16import javax.swing.JScrollPane;
17import javax.swing.JTextField;
18import javax.swing.JTextPane;
19import javax.swing.SwingUtilities;
20import javax.swing.text.BadLocationException;
21import javax.swing.text.Style;
22import javax.swing.text.StyleConstants;
23import javax.swing.text.StyleContext;
24import javax.swing.text.StyledDocument;
25
26import foxtrot.Task;
27import foxtrot.Worker;
28
29/**
30 * The main application class.
31 *
32 * Since formerly the main interface of the program was the command line,
33 * all the actions are executed via text commands. Menu options simply execute
34 * the parseCommand method with the command specified.
35 */
36// TODO: console scrollLock
37public class App extends JFrame {
38        static final long serialVersionUID = 1;
39
40        private Client client;
41        private Viewer viewer;
42        private StyledDocument styledDocument;
43        private ArrayList<String> commandHistory;
44        private JTextPane textPane;
45        private JTextField inputLine;
46        private boolean lockScroll = false;
47        private JMenu viewMenu;
48        private JMenuBar menuBar;
49        private JMenuItem connectItem;
50        private JMenuItem disconnectItem;
51        private JCheckBoxMenuItem loggingItem;
52        private JCheckBoxMenuItem autorefreshItem;
53        private JMenu styleMenu;
54
55        private final String DEFAULT_HOST = "127.0.0.1"; // "192.168.10.3";
56                                                                                                                // //192.168.1.102
57        private final String DEFAULT_PORT = "9009";
58
59        private class SwitchCreatureAction implements ActionListener {
60                private App console;
61                private int group;
62                private int index;
63
64                public SwitchCreatureAction(App console, int group, int index) {
65                        this.console = console;
66                        this.group = group;
67                        this.index = index;
68                }
69
70                public void actionPerformed(ActionEvent e) {
71                        console.parseCommand("viewcreature " + group + " " + index);
72                }
73        }
74
75        /**
76         * Constructor.
77         */
78        public App() {
79                super("Framsticks 3D Client");
80                init();
81        }
82
83        private void init() {
84                JFrame.setDefaultLookAndFeelDecorated(true);
85                commandHistory = new ArrayList<String>();
86                createChildren();
87                createMenuBar();
88                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
89                setVisible(true);
90
91                client = new Client();
92                try
93                {
94                        viewer = new Viewer(this);
95                        viewer.showInFrame();
96                }
97                // An exception thrown by Viewer's constructor.
98                catch (IOException e)
99                {
100                        Log.getInstance().log("err", "Couldn't initialize the viewer window: " + e.toString());
101                        e.printStackTrace();
102                }
103        }
104
105        private void createChildren() {
106                JFrame.setDefaultLookAndFeelDecorated(true);
107                setSize(500, 500);
108                setLocationRelativeTo(null);
109                setLocation(this.getX() + 255, this.getY());
110                setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
111
112                getContentPane().setLayout(new BorderLayout());
113                createTextArea();
114                // since all options are now available in the menu,
115                // the textual input line for commands has been hidden:
116                // createInputLine();
117
118                Log.getInstance().addLoggerListener(new ILogListener() {
119                        public void onMesssage(String category, String text) {
120                                try {
121                                        styledDocument.insertString(styledDocument.getLength(),
122                                                        text + "\n", styledDocument.getStyle(category));
123                                        if (!lockScroll)
124                                                textPane.scrollRectToVisible(textPane.getVisibleRect());
125                                } catch (BadLocationException ble) {
126                                        System.err
127                                                        .println("Couldn't insert initial text into text pane.");
128                                }
129                        }
130                });
131
132        }
133
134        public void setInputLineText(String text) {
135                inputLine.setText(text);
136        }
137
138        private void createTextArea() {
139                textPane = new JTextPane();
140                textPane.setEditable(false);
141                styledDocument = textPane.getStyledDocument();
142                addStylesToDocument(styledDocument);
143
144                JScrollPane paneScrollPane = new JScrollPane(textPane);
145                paneScrollPane
146                                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
147
148                getContentPane().add(paneScrollPane, BorderLayout.CENTER);
149        }
150
151        class StyleListener implements ActionListener {
152                String styleName;
153
154                StyleListener(String name) {
155                        styleName = name;
156                }
157
158                public void actionPerformed(ActionEvent event) {
159                        parseCommand("style " + styleName);
160                }
161        }
162
163        /**
164         * Adds a new style.
165         *
166         * @param name
167         *            Name of the new style.
168         */
169        public void AddStyle(String name) {
170                JMenuItem item = new JMenuItem(name);
171                styleMenu.add(item);
172                item.addActionListener(new StyleListener(name));
173        }
174
175        private void createMenuBar() {
176                menuBar = new JMenuBar();
177
178                JMenu serverItem = new JMenu("Server");
179                menuBar.add(serverItem);
180
181                JMenuItem testModeItem = new JMenuItem("Test mode");
182                serverItem.add(testModeItem);
183
184                testModeItem.addActionListener(new ActionListener() {
185                        public void actionPerformed(ActionEvent event) {
186                                parseCommand("connect mock");
187                        }
188                });
189
190                connectItem = new JMenuItem("Connect");
191                serverItem.add(connectItem);
192
193                final App window = this;
194                connectItem.addActionListener(new ActionListener() {
195                        public void actionPerformed(ActionEvent event) {
196                                String params = (String) JOptionPane.showInputDialog(window,
197                                                "Enter server address (IP:port)\n", "Connect",
198                                                JOptionPane.PLAIN_MESSAGE, null, null, DEFAULT_HOST
199                                                                + ":" + DEFAULT_PORT);
200                                if (params != null) {
201                                        params = params.replaceAll(":", " ");
202                                        parseCommand("connect " + params);
203                                }
204                        }
205                });
206
207                disconnectItem = new JMenuItem("Disonnect");
208                serverItem.add(disconnectItem);
209                disconnectItem.addActionListener(new ActionListener() {
210                        public void actionPerformed(ActionEvent event) {
211                                parseCommand("disconnect");
212                        }
213                });
214
215                JMenu simulationItem = new JMenu("Simulation");
216                menuBar.add(simulationItem);
217
218                JMenuItem initItem = new JMenuItem("Init");
219                simulationItem.add(initItem);
220                initItem.addActionListener(new ActionListener() {
221                        public void actionPerformed(ActionEvent event) {
222                                parseCommand("> call /simulator init");
223                        }
224                });
225
226                JMenuItem startItem = new JMenuItem("Start");
227                simulationItem.add(startItem);
228                startItem.addActionListener(new ActionListener() {
229                        public void actionPerformed(ActionEvent event) {
230                                parseCommand("> set /simulator running 1");
231                        }
232                });
233
234                JMenuItem stopItem = new JMenuItem("Stop");
235                simulationItem.add(stopItem);
236                stopItem.addActionListener(new ActionListener() {
237                        public void actionPerformed(ActionEvent event) {
238                                parseCommand("> set /simulator running 0");
239                        }
240                });
241
242                JMenuItem refreshCreaturesItem = new JMenuItem("Refresh creatures");
243                simulationItem.add(refreshCreaturesItem);
244                refreshCreaturesItem.addActionListener(new ActionListener() {
245                        public void actionPerformed(ActionEvent event) {
246                                parseCommand("refreshcreatures");
247                        }
248                });
249
250                JMenuItem refreshWorldItem = new JMenuItem("Refresh world");
251                simulationItem.add(refreshWorldItem);
252                refreshWorldItem.addActionListener(new ActionListener() {
253                        public void actionPerformed(ActionEvent event) {
254                                parseCommand("refreshworld");
255                        }
256                });
257
258                styleMenu = new JMenu("Style");
259                menuBar.add(styleMenu);
260
261                viewMenu = new JMenu("View");
262                menuBar.add(viewMenu);
263                rebuildViewMenu(null);
264
265                JMenu optionsMenu = new JMenu("Options");
266                menuBar.add(optionsMenu);
267
268                autorefreshItem = new JCheckBoxMenuItem("Autorefresh");
269                autorefreshItem.addActionListener(new ActionListener() {
270                        public void actionPerformed(ActionEvent e) {
271                                switchAutorefresh();
272                        }
273                });
274                optionsMenu.add(autorefreshItem);
275
276                loggingItem = new JCheckBoxMenuItem("Logging");
277                loggingItem.addActionListener(new ActionListener() {
278                        public void actionPerformed(ActionEvent e) {
279                                switchLogging();
280                        }
281                });
282                optionsMenu.add(loggingItem);
283                loggingItem.setSelected(true);
284
285                setJMenuBar(menuBar);
286        }
287
288        /**
289         * Turns logging on and off.
290         */
291        public void switchLogging() {
292                Log.getInstance().setEnabled(!Log.getInstance().isEnabled());
293        }
294
295        /**
296         * Turns autorefreshing on and off.
297         */
298        public void switchAutorefresh() {
299                if (autorefreshItem.isSelected()) {
300                        parseCommand("refreshcreatures");
301                }
302        }
303
304        /**
305         * Rebuilds the 'View' menu with a specified list of creatures.
306         *
307         * @param creatures
308         *            Creatures to include in the 'View' menu.
309         */
310        public void rebuildViewMenu(Creature[] creatures) {
311                viewMenu.removeAll();
312                JMenuItem allMenuItem = new JMenuItem("World");
313                allMenuItem.addActionListener(new SwitchCreatureAction(this, -1, -1));
314                viewMenu.add(allMenuItem);
315                if (creatures != null) {
316                        for (Creature creature : creatures) {
317                                JMenuItem item = new JMenuItem("Creature "
318                                                + creature.toString());
319                                item.addActionListener(new SwitchCreatureAction(this, creature
320                                                .getGroup(), creature.getIndex()));
321                                viewMenu.add(item);
322                        }
323                }
324        }
325
326        /**
327         * Sets font styles in a specified document.
328         *
329         * @param doc
330         *            A document object.
331         */
332        protected void addStylesToDocument(StyledDocument doc) {
333                // Initialize some styles
334                Style def = StyleContext.getDefaultStyleContext().getStyle(
335                                StyleContext.DEFAULT_STYLE);
336
337                Style s = doc.addStyle("dbg", def);
338                StyleConstants.setForeground(s, new Color(150, 150, 150));
339
340                s = doc.addStyle("wrn", def);
341                StyleConstants.setForeground(s, new Color(255, 150, 0));
342
343                s = doc.addStyle("err", def);
344                StyleConstants.setForeground(s, new Color(255, 0, 0));
345
346                s = doc.addStyle("cmd", def);
347                StyleConstants.setForeground(s, new Color(0, 150, 0));
348
349                s = doc.addStyle("<<<", def);
350                StyleConstants.setForeground(s, new Color(100, 40, 200));
351                // StyleConstants.setFontFamily(s, "Courier New");
352
353                s = doc.addStyle(">>>", def);
354                StyleConstants.setForeground(s, new Color(30, 100, 200));
355                // StyleConstants.setFontFamily(s, "Courier New");
356        }
357
358        private void parseCommand(String line) {
359                commandHistory.add(line);
360                commandHistory.size();
361
362                int endIndex;
363                if (line.contains(" "))
364                        endIndex = line.indexOf(" ");
365                else
366                        endIndex = line.length();
367
368                String command = line.substring(0, endIndex).trim();
369                String params = line.substring(endIndex).trim();
370
371                handleCommand(command, params);
372        }
373
374        private void handleCommand(String command, String params) {
375                Log.getInstance().log("cmd", command + " " + params);
376                if (command.equals("connect") || command.equals("c")) {
377                        if (params.equals("mock")) {
378                                connectMockAction();
379                        } else {
380                                String[] paramList = params.split(" ");
381                                String host = "";
382                                int port = 9009;
383                                if (paramList.length > 0)
384                                        host = paramList[0];
385                                try {
386                                        if (paramList.length > 1)
387                                                port = Integer.parseInt(paramList[1]);
388                                } catch (NumberFormatException e) {
389                                        Log.getInstance().log("err",
390                                                        "Invalid port, setting default value 9009");
391                                }
392                                connectHostAction(host, port);
393                        }
394                } else if (command.equals("disconnect")) {
395                        viewer.setCreatures(null);
396                        viewer.setWorld(null);
397                        client.closeConnection();
398                } else if (command.equals("refreshcreatures") || command.equals("rc")) {
399                        refreshCreaturesAction();
400                } else if (command.equals("viewcreature")) {
401                        viewCreatureAction(params);
402                } else if (command.equals("refreshworld") || command.equals("rw")) {
403                        refreshWorldAction();
404                } else if (command.equals("style") || command.equals("s")) {
405                        styleAction(params);
406                } else if (command.equals(">")) {
407                        serverRequestAction(params);
408                } else if (command.equals("quit") || command.equals("q")) {
409                        // TODO: quit command
410                }
411        }
412
413        private void connectMockAction() {
414                client.initConnectionMock();
415                refreshWorldAction();
416                refreshCreaturesAction();
417        }
418
419        private void connectHostAction(String host, int port) {
420                client.initConnection(host, port);
421                if (client.isConnected()) {
422                        refreshWorldAction();
423                        refreshCreaturesAction();
424                }
425        }
426
427        private void refreshCreaturesAction() {
428                Log.getInstance().log("dbg", "refreshCreaturesAction");
429                try {
430                        Creature[] creatures = (Creature[]) Worker.post(new Task() {
431                                public Object run() throws Exception {
432                                        return client.readCreatures();
433                                }
434                        });
435                        viewer.setCreatures(creatures);
436                        rebuildViewMenu(creatures);
437                } catch (Exception e) {
438                        Log.getInstance().log("err", e.toString());
439                        e.printStackTrace();
440                }
441                Log.getInstance().log(
442                                "autorefresh " + autorefreshItem.isSelected() + " "
443                                                + client.isConnected());
444                if (autorefreshItem.isSelected() && client.isConnected()) {
445                        SwingUtilities.invokeLater(new Runnable() {
446                                public void run() {
447                                        refreshCreaturesAction();
448                                }
449                        });
450                }
451        }
452
453        private void refreshWorldAction() {
454                Log.getInstance().log("dbg", "refreshWorldAction");
455                try {
456                        World world = (World) Worker.post(new Task() {
457                                public Object run() throws Exception {
458                                        return client.readWorld();
459                                }
460                        });
461                        viewer.setWorld(world);
462                } catch (Exception e) {
463                        Log.getInstance().log("err", e.toString());
464                        e.printStackTrace();
465                }
466        }
467
468        private void styleAction(String styleName) {
469                Log.getInstance().log("dbg", "SetStyle " + styleName);
470                viewer.setStyle(styleName);
471        }
472
473        private void viewCreatureAction(String params) {
474                int group = -1;
475                int index = -1;
476                try {
477                        String[] arr = params.split(" ");
478                        if (arr.length > 0) {
479                                group = Integer.parseInt(arr[0]);
480                        }
481                        if (arr.length > 1) {
482                                index = Integer.parseInt(arr[1]);
483                        }
484                } catch (Exception e) {
485                        e.printStackTrace();
486                }
487
488                viewer.setView(group, index);
489        }
490
491        private void serverRequestAction(String request) {
492                Log.getInstance().log("dbg", "serverRequestAction \"" + request + "\"");
493                final String finalRequest = request;
494                try {
495                        Worker.post(new Task() {
496                                public Object run() throws Exception {
497                                        client.send(finalRequest);
498                                        return null;
499                                }
500                        });
501                } catch (Exception e) {
502                        e.printStackTrace();
503                }
504                Log.getInstance().log("dbg",
505                                "serverRequestAction finished \"" + request + "\"");
506        }
507
508        /**
509         * The application entry-point.
510         *
511         * @param args
512         *            Command-line argument.
513         */
514        public static void main(String[] args) {
515                new App();
516        }
517}
Note: See TracBrowser for help on using the repository browser.