Source Code Cross Referenced for StockMIDlet.java in  » IDE-Netbeans » mobility » example » stock » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » mobility » example.stock 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *
0003:         * Copyright (c) 2007, Sun Microsystems, Inc.
0004:         *
0005:         * All rights reserved.
0006:         *
0007:         * Redistribution and use in source and binary forms, with or without
0008:         * modification, are permitted provided that the following conditions
0009:         * are met:
0010:         *
0011:         *  * Redistributions of source code must retain the above copyright
0012:         *    notice, this list of conditions and the following disclaimer.
0013:         *  * Redistributions in binary form must reproduce the above copyright
0014:         *    notice, this list of conditions and the following disclaimer in the
0015:         *    documentation and/or other materials provided with the distribution.
0016:         *  * Neither the name of Sun Microsystems nor the names of its contributors
0017:         *    may be used to endorse or promote products derived from this software
0018:         *    without specific prior written permission.
0019:         *
0020:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0021:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0022:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0023:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
0024:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0025:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0026:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0027:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0028:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0029:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0030:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0031:         */
0032:        package example.stock;
0033:
0034:        import java.io.*;
0035:
0036:        import java.util.Timer;
0037:        import java.util.TimerTask;
0038:
0039:        import javax.microedition.io.*;
0040:        import javax.microedition.lcdui.*;
0041:        import javax.microedition.midlet.*;
0042:        import javax.microedition.rms.*;
0043:
0044:        /**
0045:         * <p>The MIDlet application class that we'll run for the Stock Demo.</p>
0046:         *
0047:         */
0048:        public class StockMIDlet extends MIDlet {
0049:            /**
0050:             * Since there is no support in MIDP/CLDC for floating point numbers,
0051:             * and all of the stock data comes in the form ##.### (usually) then we
0052:             * have to find a way to store the decimals as well as the integer part
0053:             * of the quote data.  Multiplying by the OFFSET will shift the decimal
0054:             * place far enough over to make the number an integer which we can
0055:             * store.  Every time we retrieve quote data from our
0056:             * <code>RecordStore</code> we
0057:             * must make sure that we divide by the OFFSET to correctly display and
0058:             * use the value we actually want.
0059:             */
0060:            private static int OFFSET = 10000; // each 0 is one decimal place
0061:
0062:            /**
0063:             * Back <code>Command</code>
0064:             */
0065:            private static final Command BACK_COMMAND = new Command("Back",
0066:                    Command.BACK, 0);
0067:
0068:            /**
0069:             * Main Menu <code>Command</code>
0070:             */
0071:            private static final Command MAIN_MENU_COMMAND = new Command(
0072:                    "Main", Command.SCREEN, 1);
0073:
0074:            /**
0075:             * Done <code>Command</code>
0076:             */
0077:            private static final Command DONE_COMMAND = new Command("Done",
0078:                    Command.OK, 2);
0079:
0080:            /**
0081:             * Set <code>Command</code>
0082:             */
0083:            private static final Command SET_COMMAND = new Command("Set",
0084:                    Command.OK, 4);
0085:
0086:            /**
0087:             * Exit <code>Command</code>
0088:             */
0089:            private static final Command EXIT_COMMAND = new Command("Exit",
0090:                    Command.STOP, 5);
0091:
0092:            /**
0093:             * Calc <code>Command</code>
0094:             */
0095:            private static final Command CALC_COMMAND = new Command("Calc",
0096:                    Command.OK, 6);
0097:
0098:            /**
0099:             * The <code>MIDlet</code>'s display object
0100:             */
0101:            Display display = null;
0102:
0103:            /**
0104:             * The <code>Ticker</code> that scrolls along the top of the screen
0105:             */
0106:            private Ticker stockTicker = null;
0107:
0108:            /**
0109:             * A <code>List</code> of stocks
0110:             */
0111:            private List choose = null;
0112:
0113:            /**
0114:             * The Stock Tracker menu
0115:             */
0116:            private List view = null;
0117:
0118:            /**
0119:             * The Main menu
0120:             */
0121:            private List menu = null;
0122:
0123:            /**
0124:             * The Alert menu
0125:             */
0126:            private List alertList = null;
0127:
0128:            /**
0129:             * The Settings menu
0130:             */
0131:            private List settingsList = null;
0132:
0133:            /**
0134:             * The 'What If?' <code>Form</code> upon which we enter our query data
0135:             */
0136:            private Form whatif = null;
0137:
0138:            /**
0139:             * The <code>Form</code> to display the different update intervals settings
0140:             */
0141:            private Form updatesForm = null;
0142:
0143:            /**
0144:             * Used to input a stock symbol
0145:             */
0146:            private TextBox stockSymbolBox = null;
0147:
0148:            /**
0149:             * Used to enter the price at which the user wishes to be alerted to the
0150:             * stocks's value
0151:             */
0152:            private TextBox alertPriceBox = null;
0153:
0154:            /**
0155:             * The original price the user purchased the stock at, used on the What If?
0156:             * <code>Form</code>
0157:             */
0158:            private TextField origPurchPriceField = null;
0159:
0160:            /**
0161:             * The number of shares the users wishes to sell, used on the What If?
0162:             * <code>Form</code>
0163:             */
0164:            private TextField numSharesField = null;
0165:
0166:            /**
0167:             * The radio buttons for the update interval time
0168:             */
0169:            private ChoiceGroup updatesChoices = null;
0170:
0171:            /**
0172:             * A textual reference to the current menu that is displayed
0173:             * onscreen to
0174:             * allow the <code>StockCommandListener</code> to decide what
0175:             * action to perform upon
0176:             * execution of a command
0177:             */
0178:            private String currentMenu = null;
0179:
0180:            /**
0181:             * A reference to the stock that has been chosen from a list of stocks
0182:             * onscreen.  Using this we can extract the correct stock's data from
0183:             * the <code>StockDatabase</code>
0184:             */
0185:            private String stockSymbol = null;
0186:
0187:            /**
0188:             * The reference to the <code>StockDatabase</code> that stores
0189:             * the stock data
0190:             */
0191:            private StockDatabase stocks = null;
0192:
0193:            /**
0194:             * The reference to the <code>AlertDatabase</code> that stores the alerts
0195:             */
0196:            private AlertDatabase alerts = null;
0197:
0198:            /**
0199:             * The server from which the quotes are downloaded
0200:             *
0201:             * NOTE: Currently, only the quote.yahoo.com server is supported
0202:             */
0203:            private String quoteServerURL = "http://quote.yahoo.com/d/quotes.csv?s=";
0204:
0205:            /**
0206:             * The format parameter for the quote server to retrieve stock data
0207:             *
0208:             * NOTE: Currently, only this format is supported
0209:             */
0210:            private String quoteFormat = "&f=slc1wop";
0211:
0212:            /**
0213:             * The proxy server that must be negotiated
0214:             *
0215:             * NOTE: Proxy server is optional and a blank string indicates that
0216:             *       no proxy should be used
0217:             */
0218:
0219:            // Initial default but read from settings file on subsequent runs
0220:            private String proxyURL = null;
0221:
0222:            /**
0223:             * The <code>Timer</code> object that refreshes the stock
0224:             * quotes periodically
0225:             */
0226:            private Timer stockRefresh = null;
0227:
0228:            /**
0229:             * The <code>TimerTask</code> that the <code>Timer</code>
0230:             * performs periodically.
0231:             * It refreshes the stock quotes
0232:             */
0233:            private StockRefreshTask stockRefreshTask = null;
0234:
0235:            /**
0236:             * How often are the stocks' data updated off of the server?
0237:             */
0238:
0239:            // Initial default but read from settings file on subsequent runs
0240:            private int refresh_interval = 900000; // 1000 = 1 second
0241:            private boolean firstTime;
0242:
0243:            /**
0244:             * <p>Default constructor that is called by the application
0245:             * manager to create a new instance of this <code>MIDlet</code> after
0246:             * which the <code>MIDlet</code> enters the <code>Paused</code> state.</p>
0247:             */
0248:            public StockMIDlet() throws MIDletStateChangeException {
0249:                synchronized (this ) {
0250:                    // Open the Stocks file
0251:                    stocks = new StockDatabase();
0252:
0253:                    try {
0254:                        stocks.open("Stocks");
0255:                    } catch (Exception e) {
0256:                        try {
0257:                            stocks.cleanUp("Stocks");
0258:                        } catch (Exception e2) {
0259:                        }
0260:                    }
0261:
0262:                    // Open the Alerts file
0263:                    alerts = new AlertDatabase();
0264:
0265:                    try {
0266:                        alerts.open("Alerts");
0267:                    } catch (Exception e) {
0268:                        try {
0269:                            alerts.cleanUp("Alerts");
0270:                        } catch (Exception e2) {
0271:                        }
0272:                    }
0273:
0274:                    // Create all the menus and forms
0275:                    origPurchPriceField = new TextField(
0276:                            "Original Purchase Price:", "", 5,
0277:                            TextField.NUMERIC);
0278:                    numSharesField = new TextField("Number Of Shares:", "", 9,
0279:                            TextField.NUMERIC);
0280:
0281:                    menu = new List("Stock Menu", Choice.IMPLICIT);
0282:                    menu.append("Stock Tracker", null);
0283:                    menu.append("What If?", null);
0284:                    menu.append("Alerts", null);
0285:                    menu.append("Settings", null);
0286:                    menu.addCommand(EXIT_COMMAND);
0287:                    menu.setCommandListener(new StockCommandListener());
0288:                    //menu.setTicker(stockTicker);
0289:                    whatif = new Form("What If?");
0290:                    //whatif.setTicker(stockTicker);
0291:                    whatif.append(origPurchPriceField);
0292:                    whatif.append(numSharesField);
0293:                    whatif.addCommand(BACK_COMMAND);
0294:                    whatif.addCommand(CALC_COMMAND);
0295:                    whatif.setCommandListener(new StockCommandListener());
0296:
0297:                    alertList = new List("Alert Menu", Choice.IMPLICIT);
0298:                    //alertList.setTicker(stockTicker);
0299:                    alertList.append("Add", null);
0300:                    alertList.append("Remove", null);
0301:                    alertList.addCommand(BACK_COMMAND);
0302:                    alertList.setCommandListener(new StockCommandListener());
0303:
0304:                    settingsList = new List("Settings", Choice.IMPLICIT);
0305:                    //settingsList.setTicker(stockTicker);
0306:                    settingsList.append("Updates", null);
0307:                    settingsList.append("Add Stock", null);
0308:                    settingsList.append("Remove Stock", null);
0309:                    settingsList.addCommand(BACK_COMMAND);
0310:                    settingsList.setCommandListener(new StockCommandListener());
0311:
0312:                    alertPriceBox = new TextBox("Alert me when stock reaches:",
0313:                            "", 9, TextField.NUMERIC);
0314:                    //alertPriceBox.setTicker(stockTicker);
0315:                    alertPriceBox.addCommand(DONE_COMMAND);
0316:                    alertPriceBox.addCommand(BACK_COMMAND);
0317:                    alertPriceBox
0318:                            .setCommandListener(new StockCommandListener());
0319:
0320:                    updatesForm = new Form("Updates");
0321:                    updatesChoices = new ChoiceGroup("Update Interval:",
0322:                            Choice.EXCLUSIVE);
0323:                    updatesChoices.append("Continuous", null); // will be 30 seconds
0324:                    updatesChoices.append("15 minutes", null); // default for JavaONE
0325:                    updatesChoices.append("30 minutes", null);
0326:                    updatesChoices.append("1 hour", null);
0327:                    updatesChoices.append("3 hours", null);
0328:
0329:                    switch (refresh_interval) {
0330:                    case 30000:
0331:                        updatesChoices.setSelectedIndex(0, true);
0332:
0333:                        break;
0334:
0335:                    case 1800000:
0336:                        updatesChoices.setSelectedIndex(2, true);
0337:
0338:                        break;
0339:
0340:                    case 3600000:
0341:                        updatesChoices.setSelectedIndex(3, true);
0342:
0343:                        break;
0344:
0345:                    case 10800000:
0346:                        updatesChoices.setSelectedIndex(4, true);
0347:
0348:                        break;
0349:
0350:                    case 900000:
0351:                    default:
0352:                        updatesChoices.setSelectedIndex(1, true);
0353:
0354:                        break;
0355:                    }
0356:
0357:                    //updatesForm.setTicker(stockTicker);
0358:                    updatesForm.append(updatesChoices);
0359:                    updatesForm.addCommand(BACK_COMMAND);
0360:                    updatesForm.addCommand(DONE_COMMAND);
0361:                    updatesForm.setCommandListener(new StockCommandListener());
0362:
0363:                    stockSymbolBox = new TextBox("Enter a Stock Symbol:", "",
0364:                            5, TextField.ANY);
0365:                    //stockSymbolBox.setTicker(stockTicker);
0366:                    stockSymbolBox.addCommand(DONE_COMMAND);
0367:                    stockSymbolBox.addCommand(BACK_COMMAND);
0368:                    stockSymbolBox
0369:                            .setCommandListener(new StockCommandListener());
0370:
0371:                    // Open the Settings file
0372:                    try {
0373:                        RecordStore settings = RecordStore.openRecordStore(
0374:                                "Settings", true);
0375:                        refresh_interval = Integer.valueOf(
0376:                                new String(settings.getRecord(1))).intValue();
0377:                        settings.closeRecordStore();
0378:
0379:                        // No settings file existed
0380:                    } catch (Exception e) {
0381:                        refresh_interval = 900000;
0382:                    }
0383:                } // synchronized
0384:
0385:                firstTime = true;
0386:            }
0387:
0388:            /**
0389:             * <p>This method is invoked when the <code>MIDlet</code>
0390:             * is ready to run and
0391:             * starts/resumes execution after being in the <code>Paused</code>
0392:             * state. The
0393:             * <code>MIDlet</code> acquires any resources it needs,
0394:             * enters the
0395:             * <code>Active</code> state and begins to perform its service,
0396:             * which in this
0397:             * case means it displays the main menu on the screen.</p>
0398:             *
0399:             * <p>The method proceeds like so:</p>
0400:             *  <li> open the <code>StockDatabase</code> and the
0401:             * <code>AlertDatabase</code></li>
0402:             *  <li> read the settings data from the settings
0403:             * <code>RecordStore</code></li>
0404:             *  <li> create the string to be scrolled across the <code>Ticker</code> on
0405:             *       the top of the screens and instantiate the Ticker object using that
0406:             *       string.  That string will be constructed of the names and prices of
0407:             *       the stocks in our database</li>
0408:             *  <li> get and store the <code>MIDlet</code>'s
0409:             *  <code>Display</code> object</li>
0410:             *  <li> create and show the main menu</li>
0411:             *  <li> instantiate the <code>TimerTask</code> and <code>Timer</code> and
0412:             *       associate the two setting the refresh interval to the value of
0413:             *       the refresh_interval variable</li>
0414:             *
0415:             * @throws <code>MIDletStateChangeException</code> is thrown if the
0416:             *         <code>MIDlet</code> cannot start now but might be able to
0417:             *         start at a later time.
0418:             * @see javax.microedition.midlet.MIDlet
0419:             */
0420:            public void startApp() {
0421:                // Make the ticker
0422:                stockTicker = new Ticker(makeTickerString());
0423:                // set the ticker to all forms
0424:                menu.setTicker(stockTicker);
0425:                whatif.setTicker(stockTicker);
0426:                alertList.setTicker(stockTicker);
0427:                settingsList.setTicker(stockTicker);
0428:                alertPriceBox.setTicker(stockTicker);
0429:                updatesForm.setTicker(stockTicker);
0430:                stockSymbolBox.setTicker(stockTicker);
0431:
0432:                display = Display.getDisplay(this );
0433:
0434:                if (firstTime) {
0435:                    mainMenu();
0436:                    firstTime = false;
0437:                }
0438:
0439:                // Set up and start the timer to refresh the stock quotes
0440:                stockRefreshTask = new StockRefreshTask();
0441:                stockRefresh = new Timer();
0442:                stockRefresh.schedule(stockRefreshTask, 0, refresh_interval);
0443:            }
0444:
0445:            /**
0446:             * <p>This method is invoked by the application management software when
0447:             * the <code>MIDlet</code> no longer needs to be active.  It is a stop
0448:             * signal for the <code>MIDlet</code> upon which the <code>MIDlet</code>
0449:             * should release any resources which can be re-acquired through the
0450:             * <code>startApp<code> method which will be called upon re-activation of
0451:             * the <code>MIDlet</code>. The <code>MIDlet</code> enters
0452:             * the <code>Paused</code>
0453:             * state upon completion of this method.</p>
0454:             *
0455:             * @see javax.microedition.midlet.MIDlet
0456:             */
0457:            public void pauseApp() {
0458:                synchronized (this ) {
0459:                    // free memory used by these objects
0460:                    display = null;
0461:                    stockTicker = null;
0462:                    stockRefresh.cancel();
0463:                    stockRefresh = null;
0464:                    stockRefreshTask = null;
0465:                } // synchronized
0466:            }
0467:
0468:            /**
0469:             * <p>When the application management software has determined that the
0470:             * <code>MIDlet</code> is no longer needed, or perhaps needs to make room
0471:             * for a higher priority application in memory, is signals
0472:             * the <code>MIDlet</code>
0473:             * that it is a candidate to be destroyed by invoking the
0474:             * <code>destroyApp(boolean)</code> method. In this case, we need to destroy
0475:             * the <code>RecordEnumeration</code>s so that we don't waste their memory
0476:             * and close the open <code>RecordStore</code>s.  If the
0477:             * <code>RecordStore</code>s
0478:             * are empty, then we do not need them to be stored as
0479:             * they will be recreated
0480:             * on the next invokation of the <code>MIDlet</code> so
0481:             * we should delete them.
0482:             * At the end of our clean up, we must call <code>notifyDestroyed</code>
0483:             * which will inform the application management software that we are done
0484:             * cleaning up and have finished our execution and can
0485:             * now be safely terminated and
0486:             * enters the <code>Destroyed</code> state.</p>
0487:             *
0488:             * @param unconditional If true when this method is called,
0489:             * the <code>MIDlet</code> must
0490:             * cleanup and release all resources. If false the <code>MIDlet</code>
0491:             * may throw <code>MIDletStateChangeException</code> to indicate it
0492:             * does not want to be destroyed at this time.
0493:             * @throws <code>MIDletStateChangeException</code>
0494:             *         is thrown if the <code>MIDlet</code> wishes to continue to
0495:             *         execute (Not enter the <code>Destroyed</code> state). This
0496:             *         exception is ignored if <code>unconditional</code> is equal
0497:             *         to true.
0498:             * @see javax.microedition.midlet.MIDlet
0499:             */
0500:            public void destroyApp(boolean unconditional)
0501:                    throws MIDletStateChangeException {
0502:                // If there is no criteria that will keep us from terminating
0503:                if (unconditional) {
0504:                    synchronized (this ) {
0505:                        if (display == null) {
0506:                            // If display == null, we are not initialized and
0507:                            // we have nothing to destroy
0508:                            return;
0509:                        }
0510:
0511:                        stockRefresh.cancel();
0512:
0513:                        try {
0514:                            stocks.close();
0515:                            alerts.close();
0516:
0517:                            RecordStore settings = RecordStore.openRecordStore(
0518:                                    "Settings", true);
0519:
0520:                            try {
0521:                                settings.setRecord(1, String.valueOf(
0522:                                        refresh_interval).getBytes(), 0, String
0523:                                        .valueOf(refresh_interval).length());
0524:
0525:                                // First time writing to the settings file
0526:                            } catch (RecordStoreException rse) {
0527:                                settings.addRecord(String.valueOf(
0528:                                        refresh_interval).getBytes(), 0, String
0529:                                        .valueOf(refresh_interval).length());
0530:                            }
0531:
0532:                            settings.closeRecordStore();
0533:                        } catch (Exception e) {
0534:                            // Ignore exception there is no place to report it
0535:                        }
0536:
0537:                        notifyDestroyed();
0538:
0539:                        // Something might make us not want to exit so check it
0540:                        // here before terminating
0541:                    } // synchronized
0542:                }
0543:            }
0544:
0545:            /**
0546:             * <p>Calculate the profits in a What If? scenario by the formula:</p>
0547:             * <p><type>  Profit = (CurrentPrice - OriginalPurchasePrice)
0548:             * * NumberOfShares</type></p>
0549:             * <p>First we retrieve the current price of the stock. Then parse the
0550:             * original purchase price that the user enters to format it to an
0551:             * integer.  Next, retrieve the number of shares from the form that
0552:             * the user filled in and then calculate the profits and display a nice
0553:             * message (with the result) to the user onscreen.</p>
0554:             */
0555:            private void calc() {
0556:                try {
0557:                    String s = stocks.search(stockSymbol);
0558:                    int currPrice = Stock.getPrice(s);
0559:                    int opp = Stock.makeInt(origPurchPriceField.getString());
0560:                    int numShares = Integer.valueOf(numSharesField.getString())
0561:                            .intValue();
0562:                    int profit = ((currPrice - opp) * numShares);
0563:
0564:                    Form answerForm = new Form(Stock.getName(s) + " "
0565:                            + Stock.getStringPrice(s));
0566:                    StringBuffer sb = new StringBuffer().append(
0567:                            "Net profit (loss) is ").append(
0568:                            (profit >= 0) ? "$" : "($").append(
0569:                            (profit >= 0) ? Stock.convert(profit)
0570:                                    : ("-" + Stock.convert(profit))).append(
0571:                            (profit >= 0) ? "" : ")").append(" when selling ")
0572:                            .append(String.valueOf(numShares)).append(
0573:                                    " shares at $").append(
0574:                                    Stock.convert(currPrice)).append(
0575:                                    " per share.");
0576:                    answerForm.append(sb.toString());
0577:                    answerForm.addCommand(BACK_COMMAND);
0578:                    answerForm.addCommand(MAIN_MENU_COMMAND);
0579:                    answerForm.setCommandListener(new StockCommandListener());
0580:                    display.setCurrent(answerForm);
0581:                    currentMenu = "AnswerForm";
0582:                } catch (Exception e) {
0583:                    error("Calculation Failed", 2000);
0584:                }
0585:            }
0586:
0587:            /**
0588:             * <p>Set an alert for the selected stock at the specified price</p>
0589:             *
0590:             * @param Sprice String representation of the price of the stock that
0591:             *               the user would like an alert for
0592:             */
0593:            private void setAlert(String Sprice) {
0594:                try {
0595:                    alerts.add((new StringBuffer().append(
0596:                            Stock.getName(stocks.search(stockSymbol))).append(
0597:                            ';').append(Stock.makeInt(Sprice))).toString());
0598:                } catch (Exception e) {
0599:                    error("Failed to add alert", 2000);
0600:                }
0601:            }
0602:
0603:            /**
0604:             * <p>Generate a string (which concatenates all of the stock names and
0605:             * prices) which will be used for the <code>Ticker</code>.</p>
0606:             *
0607:             * @return The ticker string which concatenates all of the stock symbols
0608:             *         and prices
0609:             */
0610:            private String makeTickerString() {
0611:                // the ticker tape string
0612:                StringBuffer tickerTape = new StringBuffer();
0613:
0614:                try {
0615:                    RecordEnumeration re = stocks.enumerateRecords();
0616:
0617:                    while (re.hasNextElement()) {
0618:                        String theStock = new String(re.nextRecord());
0619:                        tickerTape.append(Stock.getName(theStock))
0620:                                .append(" @ ").append(
0621:                                        Stock.getStringPrice(theStock)).append(
0622:                                        "   ");
0623:                    }
0624:                } catch (Exception e) {
0625:                    return "Error Accessing Database";
0626:                }
0627:
0628:                return tickerTape.toString();
0629:            }
0630:
0631:            /**
0632:             * <p>Display a message onscreen for a specified period of time</p>
0633:             *
0634:             * @param message The message to be displayed
0635:             * @param time The delay before the message disappears
0636:             */
0637:            private void error(String message, int time) {
0638:                if (!(display.getCurrent() instanceof  Alert)) {
0639:                    Alert a = new Alert("Error", message, null, AlertType.ERROR);
0640:                    a.setTimeout(time);
0641:                    display.setCurrent(a, display.getCurrent());
0642:                }
0643:            }
0644:
0645:            /**
0646:             * <p>Check the alerts to see if any are registered for tkrSymbol at the
0647:             * tkrSymbol's current price</p>
0648:             *
0649:             * @param tkrSymbol The name of the stock to check for alerts on
0650:             */
0651:            private void checkAlerts(String tkrSymbol) {
0652:                try {
0653:                    int current_price = Stock
0654:                            .getPrice(stocks.search(tkrSymbol));
0655:                    RecordEnumeration re = alerts.enumerateRecords(tkrSymbol,
0656:                            current_price);
0657:
0658:                    while (re.hasNextElement()) {
0659:                        String alert_string = new String(re.nextRecord());
0660:                        int my_price = Integer.valueOf(
0661:                                alert_string.substring(alert_string
0662:                                        .indexOf(';') + 1, alert_string
0663:                                        .length())).intValue();
0664:                        Alert a = new Alert(tkrSymbol, "", null,
0665:                                AlertType.ALARM);
0666:                        StringBuffer sb = new StringBuffer().append(tkrSymbol)
0667:                                .append(" has reached your price point of $")
0668:                                .append(Stock.convert(my_price)).append(
0669:                                        " and currently is trading at $")
0670:                                .append(
0671:                                        Stock.getStringPrice(stocks
0672:                                                .search(tkrSymbol)));
0673:                        a.setString(sb.toString());
0674:                        a.setTimeout(Alert.FOREVER);
0675:                        display.setCurrent(a);
0676:                        alerts.delete(alert_string);
0677:                    }
0678:                } catch (RecordStoreNotOpenException rsno) {
0679:                } catch (RecordStoreException rs) {
0680:                }
0681:            }
0682:
0683:            /**
0684:             * <p>Display the main menu of the program</p>
0685:             */
0686:            private void mainMenu() {
0687:                display.setCurrent(menu);
0688:                currentMenu = "Main";
0689:            }
0690:
0691:            /**
0692:             * <p>Show the list of stocks to pick from and set the menu type to indicate
0693:             * to the Listener what to do with the list choice</p>
0694:             *
0695:             * @param reload   Indicates whether the list should be reloaded
0696:             * which should
0697:             * only happen if it is possible that the stocks have changed
0698:             * since it was last shown
0699:             * @param menuType Which menu is this list representing
0700:             * @param type     Type of Choice to display
0701:             * @param prices   Indicates whether or not to show prices on the list
0702:             */
0703:            private void chooseStock(boolean reload, String menuType, int type,
0704:                    boolean prices) {
0705:                if (reload) {
0706:                    choose = new List("Choose Stocks", type);
0707:                    choose.setTicker(stockTicker);
0708:                    choose.addCommand(BACK_COMMAND);
0709:
0710:                    if (menuType.equals("RemoveStock")) {
0711:                        choose.addCommand(DONE_COMMAND);
0712:                    } else if (menuType.equals("WhatChoose")
0713:                            || menuType.equals("AddAlert")) {
0714:                        choose.addCommand(MAIN_MENU_COMMAND);
0715:                    }
0716:
0717:                    choose.setCommandListener(new StockCommandListener());
0718:
0719:                    try {
0720:                        RecordEnumeration re = stocks.enumerateRecords();
0721:
0722:                        while (re.hasNextElement()) {
0723:                            String theStock = new String(re.nextRecord());
0724:
0725:                            if (prices) {
0726:                                choose.append(Stock.getName(theStock) + " @ "
0727:                                        + Stock.getStringPrice(theStock), null);
0728:                            } else {
0729:                                choose.append(Stock.getName(theStock), null);
0730:                            }
0731:                        }
0732:                    } catch (RecordStoreNotOpenException rsno) {
0733:                    } catch (RecordStoreException rs) {
0734:                    }
0735:                }
0736:
0737:                display.setCurrent(choose);
0738:                currentMenu = menuType;
0739:            }
0740:
0741:            /**
0742:             * <p>Display the stock selected on the View menu with all its
0743:             * attributes shown (ie. Name, Price, etc.)</p>
0744:             *
0745:             * @param tkrSymbol The name of the stock to be deleted
0746:             */
0747:            private void displayStock(String tkrSymbol) {
0748:                try {
0749:                    String theStock = stocks.search(tkrSymbol);
0750:                    Form stockInfo = new Form(Stock.getName(theStock));
0751:                    stockInfo.setTicker(stockTicker);
0752:
0753:                    StringBuffer sb = new StringBuffer().append(
0754:                            "Last Trade:\n         ").append(
0755:                            Stock.getTime(theStock)).append("\n         ")
0756:                            .append(Stock.getStringPrice(theStock)).append(
0757:                                    "\nChange:  ").append(
0758:                                    Stock.getStringChange(theStock)).append(
0759:                                    "\nHigh:  ").append(
0760:                                    Stock.getStringHigh(theStock)).append(
0761:                                    "\nLow:  ").append(
0762:                                    Stock.getStringLow(theStock)).append(
0763:                                    "\nOpen:  ").append(
0764:                                    Stock.getStringOpen(theStock)).append(
0765:                                    "\nPrev:  ").append(
0766:                                    Stock.getStringPrevious(theStock));
0767:                    stockInfo.append(sb.toString());
0768:                    stockInfo.addCommand(BACK_COMMAND);
0769:                    stockInfo.addCommand(MAIN_MENU_COMMAND);
0770:                    stockInfo.setCommandListener(new StockCommandListener());
0771:                    display.setCurrent(stockInfo);
0772:                    currentMenu = "stockInfo";
0773:                } catch (RecordStoreNotOpenException rsno) {
0774:                    error("Could not display stock.  ", 2000);
0775:                } catch (RecordStoreException rs) {
0776:                    error("Could not display stock.  ", 2000);
0777:                } catch (NullPointerException npe) {
0778:                    error("Could not display stock.  ", 2000);
0779:                }
0780:            }
0781:
0782:            /**
0783:             * <p>Show the What If? form to investigate a hypothetical stock deal</p>
0784:             *
0785:             * @param tkrSymbol The name of the stock to perform the query with
0786:             */
0787:            private void whatIfForm(String tkrSymbol) {
0788:                display.setCurrent(whatif);
0789:                currentMenu = "WhatIfForm";
0790:                stockSymbol = tkrSymbol;
0791:            }
0792:
0793:            /**
0794:             * <p>Show the alert management menu</p>
0795:             *
0796:             * @param showAlert Indicate whether we should show an alert to indicate
0797:             *                  that we have just successfully added an alert
0798:             */
0799:            private void alertMenu(boolean showAlert) {
0800:                display.setCurrent(alertList);
0801:                currentMenu = "AlertMenu";
0802:
0803:                if (showAlert) {
0804:                    Alert a = new Alert("", "\n\n\n   Saved!", null, null);
0805:                    a.setTimeout(2000);
0806:                    display.setCurrent(a, alertList);
0807:                }
0808:            }
0809:
0810:            /**
0811:             * <p>Show a list of all active alerts</p>
0812:             */
0813:            private void viewAlerts() {
0814:                choose = new List("Current Alerts", Choice.MULTIPLE);
0815:                choose.setTicker(stockTicker);
0816:
0817:                try {
0818:                    // Get all the Alert records
0819:                    RecordEnumeration re = alerts.enumerateRecords("", 0);
0820:
0821:                    while (re.hasNextElement()) {
0822:                        String a = new String(re.nextRecord());
0823:                        String price = Stock.convert(Integer.valueOf(
0824:                                a.substring(a.indexOf(';') + 1, a.length()))
0825:                                .intValue());
0826:                        choose.append(a.substring(0, a.indexOf(';')) + " @ $"
0827:                                + price, null);
0828:                    }
0829:                } catch (Exception e) {
0830:                    error("Error reading alerts", 2500);
0831:                }
0832:
0833:                choose.addCommand(BACK_COMMAND);
0834:                choose.addCommand(DONE_COMMAND);
0835:                choose.setCommandListener(new StockCommandListener());
0836:                display.setCurrent(choose);
0837:                currentMenu = "RemoveAlert";
0838:            }
0839:
0840:            /**
0841:             * <p>Show the form to add an alert</p>
0842:             *
0843:             * @param tkrSymbol The ticker symbol of the stock we're adding an alert to
0844:             */
0845:            private void alertForm(String tkrSymbol) {
0846:                display.setCurrent(alertPriceBox);
0847:                currentMenu = "AlertForm";
0848:                stockSymbol = tkrSymbol;
0849:            }
0850:
0851:            /**
0852:             * <p>Remove the alert from our RecordStore referenced by index</p>
0853:             *
0854:             * @param choose_data A string with the symbol and price of the alert
0855:             *                    to remove in it
0856:             */
0857:            private void removeAlert(String choose_data) {
0858:                try {
0859:                    // Separate the symbol and price from the data
0860:                    String symbol = choose_data.substring(0, choose_data
0861:                            .indexOf('@') - 1);
0862:                    int sPrice = Stock
0863:                            .makeInt(choose_data.substring(choose_data
0864:                                    .indexOf('@') + 3, choose_data.length()));
0865:                    System.out
0866:                            .println("Remove Alert: " + symbol + ";" + sPrice);
0867:                    // Remove the alert
0868:                    alerts.delete(symbol + ";" + sPrice);
0869:                } catch (Exception e) {
0870:                    error("Failed to remove alert", 2000);
0871:                }
0872:            }
0873:
0874:            /**
0875:             * <p>Show the settings menu</p>
0876:             *
0877:             * @param showAlert Indicate whether we should show an alert to indicate
0878:             *                  that we have just successfully saved changes to the
0879:             *                  settings
0880:             */
0881:            private void settings(boolean showAlert) {
0882:                display.setCurrent(settingsList);
0883:                currentMenu = "Settings";
0884:
0885:                if (showAlert) {
0886:                    Alert a = new Alert("", "\n\n\n   Saved!", null, null);
0887:                    a.setTimeout(1500);
0888:                    display.setCurrent(a, settingsList);
0889:                }
0890:            }
0891:
0892:            /**
0893:             * <p>Show the updates choices</p>
0894:             */
0895:            private void updates() {
0896:                display.setCurrent(updatesForm);
0897:                currentMenu = "Updates";
0898:            }
0899:
0900:            /**
0901:             * <p>Show the screen to add a stock</p>
0902:             */
0903:            private void addStock() {
0904:                stockSymbolBox.setString("");
0905:                display.setCurrent(stockSymbolBox);
0906:                currentMenu = "AddStock";
0907:            }
0908:
0909:            /**
0910:             * <p>Add the stock to the database</p>
0911:             *  <li> first contact the quote server to get the stock quote</li>
0912:             *  <li> if the stock doesn't not exist, alert the user and return to
0913:             *       the add screen</li>
0914:             *  <li> if the stock exists then add it to our list</li>
0915:             *  <li> if the addition of the stock was successful, return true
0916:             *       otherwise, return false</li>
0917:             * <BR>
0918:             * <p>This is the format returned by the quote.yahoo.com server in
0919:             * the format
0920:             * specified in the instance variable:</p>
0921:             * <pre>
0922:             * NAME    TIME         PRICE        CHANGE   LOW       HIGH    OPEN PREV
0923:             * "SUNW","11:24AM - <b>79.0625</b>",-3.0625,"26.9375 - 106.75",80.5,82.125
0924:             * </pre>
0925:             * <BR>
0926:             * <p>This is what is returned if the stock is not found:</p>
0927:             * <pre>
0928:             * "NAME" ,"N/A - <b>0.00</b>"       ,N/A    ,"N/A - N/A"       ,N/A ,N/A
0929:             * </pre>
0930:             *
0931:             * @return whether or not the addition of the stock was successful
0932:             * @param tkrSymbol The ticker symbol of the stock to add
0933:             */
0934:            private boolean addNewStock(String tkrSymbol) {
0935:                try {
0936:                    // When stocks.search() returns null, the stock doesn't yet exist
0937:                    if (stocks.search(tkrSymbol) == null) {
0938:                        try {
0939:                            stocks.add(getStockQuote(tkrSymbol));
0940:                            stockTicker.setString(makeTickerString());
0941:                        } catch (RecordStoreFullException rsf) {
0942:                            error("Database is full.", 2000);
0943:
0944:                            return false;
0945:                        } catch (RecordStoreException rs) {
0946:                            error("Failed to add " + tkrSymbol, 2000);
0947:
0948:                            return false;
0949:                        } catch (IOException ioe) {
0950:                            error("Failed to download stock quote for \""
0951:                                    + tkrSymbol + "\"", 2000);
0952:
0953:                            return false;
0954:                        } catch (NumberFormatException nfe) {
0955:                            error(
0956:                                    "\""
0957:                                            + tkrSymbol
0958:                                            + "\" not found on server, or invalid data "
0959:                                            + "received from server", 2000);
0960:
0961:                            return false;
0962:                        } catch (Exception e) {
0963:                            error(e.toString(), 2000);
0964:
0965:                            return false;
0966:                        }
0967:
0968:                        // The stock already exists so we'll just update it
0969:                    } else {
0970:                        try {
0971:                            stocks.update(tkrSymbol, getStockQuote(tkrSymbol)
0972:                                    .getBytes());
0973:                            stockTicker.setString(makeTickerString());
0974:                        } catch (RecordStoreFullException rsf) {
0975:                            error("Database is full.", 2000);
0976:
0977:                            return false;
0978:                        } catch (RecordStoreException rs) {
0979:                            error("Failed to update " + tkrSymbol, 2000);
0980:
0981:                            return false;
0982:                        } catch (IOException ioe) {
0983:                            error("Failed to download stock quote for "
0984:                                    + tkrSymbol, 2000);
0985:
0986:                            return false;
0987:                        } catch (Exception e) {
0988:                            error(e.toString(), 2000);
0989:
0990:                            return false;
0991:                        }
0992:                    }
0993:                } catch (RecordStoreException rs) {
0994:                    error("Error accessing database.", 2000);
0995:
0996:                    return false;
0997:                }
0998:
0999:                return true;
1000:            }
1001:
1002:            /**
1003:             * <p>This method actually contacts the server, downloads and returns
1004:             * the stock quote.</p>
1005:             *
1006:             * NOTE: If PROXY support is added to HttpConnection then switch the code
1007:             *       over to that as it will be pure MIDP.
1008:             *
1009:             * @return the stock quote
1010:             * @param tkrSymbol The Stock to be requested from the server
1011:             * @throws <code>IOException</code> is thrown if there is a problem
1012:             *         negotiating a connection with the server
1013:             * @throws <code>NumberFormatException</code> is thrown if trashed data
1014:             *         is received from the server (or the Stock could not be found)
1015:             */
1016:            private String getStockQuote(String tkrSymbol) throws IOException,
1017:                    NumberFormatException {
1018:                String quoteURL = quoteServerURL + tkrSymbol + quoteFormat;
1019:
1020:                StreamConnection c = (StreamConnection) Connector.open(
1021:                        quoteURL, Connector.READ_WRITE);
1022:                InputStream is = c.openInputStream();
1023:                int ch;
1024:                StringBuffer sb = new StringBuffer();
1025:
1026:                while ((ch = is.read()) != -1) {
1027:                    sb.append((char) ch);
1028:                }
1029:
1030:                Stock.parse(sb.toString());
1031:                is.close();
1032:                c.close();
1033:
1034:                return sb.toString();
1035:            }
1036:
1037:            /**
1038:             * <p>Remove the stock from the <code>StockDatabase</code></p>
1039:             *
1040:             * @param tkrSymbol The ticker symbol of the stock to delete
1041:             */
1042:            private void deleteStock(String tkrSymbol) {
1043:                try {
1044:                    stocks.delete(tkrSymbol);
1045:                    alerts.removeUselessAlerts(tkrSymbol);
1046:                    stockTicker.setString(makeTickerString());
1047:                } catch (RecordStoreException rs) {
1048:                    error("Failed to delete " + tkrSymbol, 2000);
1049:                }
1050:            }
1051:
1052:            /**
1053:             * <p>This class is the Listener for ALL of the events that
1054:             * take place during
1055:             * life span of the <code>MIDlet</code>.  It handles <code>Command</code>
1056:             * events and list selections which are the only events that this
1057:             * <code>MIDlet</code> will generate.  In order to determine what to do,
1058:             * the Listener checks the name of the command and the currently displayed
1059:             * menu/list and matches them up to execute the appropriate action.</p>
1060:             * <BR>
1061:             * NOTE: The parseCommandString(String) is only there because the getXXX
1062:             *       methods are missing from the Command class.  When they are added,
1063:             *       this method can be removed and the Command.getLabel() can be used
1064:             */
1065:            private class StockCommandListener implements  CommandListener,
1066:                    Runnable {
1067:                /** Current command to process. */
1068:                private Command currentCommand;
1069:
1070:                /** Displayable of the current command to process. */
1071:                private Displayable currentDisplayable;
1072:
1073:                /** The current command processing thread. */
1074:                private Thread commandThread;
1075:
1076:                /**
1077:                 * <p>The method to determine what action to take</p>
1078:                 *
1079:                 * @param c The <code>Command</code> object that has been activated
1080:                 * @param d The <code>Displayable</code> object that the command was
1081:                 *          associated with
1082:                 */
1083:                public void commandAction(Command c, Displayable d) {
1084:                    synchronized (this ) {
1085:                        if (commandThread != null) {
1086:                            // process only one command at a time
1087:                            return;
1088:                        }
1089:
1090:                        currentCommand = c;
1091:                        currentDisplayable = d;
1092:                        commandThread = new Thread(this );
1093:                        commandThread.start();
1094:                    }
1095:                }
1096:
1097:                /**
1098:                 * Perform the current command set by the method commandAction.
1099:                 */
1100:                public void run() {
1101:                    String type = currentCommand.getLabel();
1102:
1103:                    // Main command executed, always show Main Menu regardless of
1104:                    // which screen is showing
1105:                    if (type.equals("Main")) {
1106:                        mainMenu();
1107:
1108:                        // Back command executed, check which screen is and move to
1109:                        // the previous one
1110:                    } else if (type.equals("Back")) {
1111:                        // Screens off the Main Menu
1112:                        if (currentMenu.equals("View")
1113:                                || currentMenu.equals("WhatChoose")
1114:                                || currentMenu.equals("AlertMenu")
1115:                                || currentMenu.equals("Settings")) {
1116:                            mainMenu();
1117:
1118:                            // Screens off the Settings menu
1119:                        } else if (currentMenu.equals("Add")
1120:                                || currentMenu.equals("Updates")
1121:                                || currentMenu.equals("RemoveStock")) {
1122:                            settings(false);
1123:                        } else if (currentMenu.equals("stockInfo")) {
1124:                            chooseStock(false, "View", Choice.IMPLICIT, true);
1125:                        } else if (currentMenu.equals("WhatIfForm")) {
1126:                            chooseStock(false, "WhatChoose", Choice.IMPLICIT,
1127:                                    false);
1128:                        } else if (currentMenu.equals("AlertForm")) {
1129:                            chooseStock(false, "AddAlert", Choice.IMPLICIT,
1130:                                    false);
1131:                        } else if (currentMenu.equals("AnswerForm")) {
1132:                            whatIfForm(stockSymbol);
1133:
1134:                            // Screens off the Alerts menu
1135:                        } else if (currentMenu.equals("RemoveAlert")
1136:                                || currentMenu.equals("AddAlert")) {
1137:                            alertMenu(false);
1138:                        } else if (currentMenu.equals("AddStock")) {
1139:                            settings(false);
1140:                        }
1141:
1142:                        /*
1143:                         * OK command executed, perform different actions
1144:                         * depending on which screen is showing
1145:                         */
1146:                    } else if (type.equals("Done")) {
1147:                        if (currentMenu.equals("AddStock")) {
1148:                            if ((!stockSymbolBox.getString().trim().equals(""))
1149:                                    && (addNewStock(stockSymbolBox.getString()
1150:                                            .trim()))) {
1151:                                settings(true);
1152:                            }
1153:                        } else if (currentMenu.equals("AlertForm")) {
1154:                            setAlert(((TextBox) currentDisplayable).getString());
1155:                            alertMenu(true);
1156:
1157:                            // Remove an alert
1158:                        } else if (currentMenu.equals("RemoveAlert")) {
1159:                            boolean[] chosen = new boolean[choose.size()];
1160:                            choose.getSelectedFlags(chosen);
1161:
1162:                            for (int i = 0; i < chosen.length; i++) {
1163:                                if (chosen[i]) {
1164:                                    removeAlert(choose.getString(i));
1165:                                }
1166:                            }
1167:
1168:                            alertMenu(true);
1169:
1170:                            // Remove a Stock
1171:                        } else if (currentMenu.equals("RemoveStock")) {
1172:                            boolean[] chosen = new boolean[choose.size()];
1173:                            choose.getSelectedFlags(chosen);
1174:
1175:                            for (int i = 0; i < chosen.length; i++) {
1176:                                if (chosen[i]) {
1177:                                    deleteStock(choose.getString(i));
1178:                                }
1179:                            }
1180:
1181:                            chosen = null;
1182:                            settings(true);
1183:
1184:                            // Set the quote update interval
1185:                        } else if (currentMenu.equals("Updates")) {
1186:                            switch (updatesChoices.getSelectedIndex()) {
1187:                            case 0:
1188:                                refresh_interval = 30000;
1189:
1190:                                break;
1191:
1192:                            case 1:
1193:                                refresh_interval = 900000;
1194:
1195:                                break;
1196:
1197:                            case 2:
1198:                                refresh_interval = 1800000;
1199:
1200:                                break;
1201:
1202:                            case 3:
1203:                                refresh_interval = 3600000;
1204:
1205:                                break;
1206:
1207:                            case 4:
1208:                                refresh_interval = 10800000;
1209:
1210:                                break;
1211:
1212:                            default:
1213:                                break;
1214:                            }
1215:
1216:                            stockRefreshTask.cancel();
1217:                            stockRefreshTask = new StockRefreshTask();
1218:                            stockRefresh.schedule(stockRefreshTask, 0,
1219:                                    refresh_interval);
1220:                            settings(true);
1221:                        }
1222:
1223:                        // Exit command executed
1224:                    } else if (type.equals("Exit")) {
1225:                        try {
1226:                            destroyApp(true);
1227:                        } catch (MIDletStateChangeException msce) {
1228:                            mainMenu();
1229:                        }
1230:
1231:                        // Calc command executed
1232:                    } else if (type.equals("Calc")) {
1233:                        if (origPurchPriceField.size() == 0) {
1234:                            error("You must enter the price you originally "
1235:                                    + "purchased the stock at.", 2000);
1236:                        } else {
1237:                            if (numSharesField.size() == 0) {
1238:                                error("You must specify the number of shares"
1239:                                        + " to calculate with.", 2000);
1240:                            } else {
1241:                                calc();
1242:                            }
1243:                        }
1244:
1245:                        /*
1246:                         * No command button was pressed but a list selection
1247:                         * was made
1248:                         */
1249:                    } else {
1250:                        List shown = (List) display.getCurrent();
1251:
1252:                        /*
1253:                         * if it's a menu not a list of stocks then we'll
1254:                         * use a switch to select which action to perform
1255:                         */
1256:                        if (currentMenu.equals("Main")
1257:                                || currentMenu.equals("Settings")
1258:                                || currentMenu.equals("AlertMenu")) {
1259:                            switch (shown.getSelectedIndex()) {
1260:                            case 0:
1261:
1262:                                // View Stocks
1263:                                if (currentMenu.equals("Main")) {
1264:                                    chooseStock(true, "View", Choice.IMPLICIT,
1265:                                            true);
1266:
1267:                                    // Updates
1268:                                } else if (currentMenu.equals("Settings")) {
1269:                                    updates();
1270:
1271:                                    // Add Alert
1272:                                } else {
1273:                                    chooseStock(true, "AddAlert",
1274:                                            Choice.IMPLICIT, false);
1275:                                }
1276:
1277:                                break;
1278:
1279:                            case 1:
1280:
1281:                                // What If?
1282:                                if (currentMenu.equals("Main")) {
1283:                                    chooseStock(true, "WhatChoose",
1284:                                            Choice.IMPLICIT, false);
1285:
1286:                                    // Add Stock
1287:                                } else if (currentMenu.equals("Settings")) {
1288:                                    addStock();
1289:
1290:                                    // Remove Alert
1291:                                } else {
1292:                                    viewAlerts();
1293:                                }
1294:
1295:                                break;
1296:
1297:                            case 2:
1298:
1299:                                // Alerts
1300:                                if (currentMenu.equals("Main")) {
1301:                                    alertMenu(false);
1302:
1303:                                    // Remove Stock
1304:                                } else if (currentMenu.equals("Settings")) {
1305:                                    chooseStock(true, "RemoveStock",
1306:                                            Choice.MULTIPLE, false);
1307:                                }
1308:
1309:                                break;
1310:
1311:                            case 3:
1312:
1313:                                // Settings
1314:                                if (currentMenu.equals("Main")) {
1315:                                    settings(false);
1316:                                }
1317:
1318:                                break;
1319:
1320:                            default:
1321:                                break;
1322:                            }
1323:
1324:                            /*
1325:                             * we've now determined that it is a menu of stocks
1326:                             * so we have to either show the stock info (from the
1327:                             * View menu), add an alert (if Alert Choose screen is
1328:                             * showing) or perform a What If? (if the What If?
1329:                             * Choose screen is showing)
1330:                             */
1331:                        } else {
1332:                            if (currentMenu.equals("View")) {
1333:                                displayStock(choose.getString(
1334:                                        choose.getSelectedIndex()).substring(
1335:                                        0,
1336:                                        choose.getString(
1337:                                                choose.getSelectedIndex())
1338:                                                .indexOf('@') - 1));
1339:                            } else if (currentMenu.equals("WhatChoose")) {
1340:                                if (choose.getSelectedIndex() >= 0) {
1341:                                    whatIfForm(choose.getString(choose
1342:                                            .getSelectedIndex()));
1343:                                }
1344:                            } else if (currentMenu.equals("AddAlert")) {
1345:                                if (choose.getSelectedIndex() >= 0) {
1346:                                    alertForm(choose.getString(choose
1347:                                            .getSelectedIndex()));
1348:                                }
1349:                            }
1350:                        }
1351:                    }
1352:
1353:                    synchronized (this ) {
1354:                        // signal that another command can be processed
1355:                        commandThread = null;
1356:                    }
1357:                }
1358:            }
1359:
1360:            /**
1361:             * <p>This is an extension of the <code>TimerTask</code> class which runs
1362:             * when called by <code>Timer</code>.  It refreshes the stock info for
1363:             * each stock from the quote server and checks to see if any of the alerts
1364:             * should be fired.</p>
1365:             *
1366:             * @see java.util.TimerTask
1367:             */
1368:            private class StockRefreshTask extends TimerTask {
1369:                /**
1370:                 * <p>Execute the Timer's Task</p>
1371:                 */
1372:                public void run() {
1373:                    try {
1374:                        // Just return if the database is empty
1375:                        if (stocks.getNumRecords() == 0) {
1376:                            return;
1377:                        }
1378:
1379:                        // Get all the records
1380:                        RecordEnumeration re = stocks.enumerateRecords();
1381:
1382:                        while (re.hasNextElement()) {
1383:                            String tkrSymbol = Stock.getName(new String(re
1384:                                    .nextRecord()));
1385:
1386:                            try {
1387:                                byte[] rec = getStockQuote(tkrSymbol)
1388:                                        .getBytes();
1389:
1390:                                // Update the record and check for any alerts that
1391:                                // may need to be executed
1392:                                stocks.update(tkrSymbol, rec);
1393:                                checkAlerts(tkrSymbol);
1394:                            } catch (NumberFormatException nfe) {
1395:                                error(
1396:                                        "\""
1397:                                                + tkrSymbol
1398:                                                + "\" not found on server, or invalid data "
1399:                                                + "received from server", 2000);
1400:                            }
1401:                        }
1402:                    } catch (Exception e) {
1403:                        error("Update Failed\n\nStocks were not updated", 2000);
1404:                    }
1405:                }
1406:            }
1407:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.