Zipwhip Blog

Free Trial

Posts by Topic

see all

Tutorial: Using the Zipwhip API in Java to Popup Your Text Messages in a Bubble Window

I wrote a couple of posts about sending and receiving text messages via the Zipwhip API. Those posts culminated in console output showing you the results of sending or receiving. In this post I’m going to take things further and actually have a slick looking bubble popup on your desktop showing you your text message as it comes in to the Zipwhip Cloud in real-time. The results will look something like below.

image

Watch the video below to check out how cool the bubble looks as it fades in and out.

image

We are going to create a new Eclipse project from scratch. Let’s call it ZipwhipBubble. Go into Eclipse and start a new project.

image

Call the project ZipwhipBubble.

image

The source tab can be left with the defaults.

image

On the Libraries tab make sure to add the 3 JARs that we used in the previous posts including Log4j, SLF4j, and of course the most important library—the Zipwhip API JAR. The easiest way to do this is to just download the zip file below of this entire project.

ZipwhipBubble.zip 1.1 MB

The contents of the zip file are as follows:

image

After having downloaded the above zip file, you can add the libraries from the JARs folder into the Libraries tab. Your tab should look like the screenshot below.

image

Click Finish. You should now have a new project like the window below.

image

You need to add your first class to the project.

image

Give the class the name “Main” and give it a package like “com.yourcompany.zw”. Of course set yourcompany to your company.

image

You will see a code window that’s mostly empty like below.

image

Now paste the following code into your window so you get a full class ready to go without you having to do any of the hard work because I did it all for you. You can also download the full Zip file of this project from the top of this posting that contains all of the JARs, source code, and images for the project.

Main.java 4.8 KB

<span id="lnum1" style="color:#606060;"> 1:</span> <span style="color:#0000ff;">package</span> com.yourcompany.zw;
<span id="lnum2" style="color:#606060;"> 2:</span>
<span id="lnum3" style="color:#606060;"> 3:</span> <span style="color:#0000ff;">import</span> org.apache.log4j.BasicConfigurator;
<span id="lnum4" style="color:#606060;"> 4:</span> <span style="color:#0000ff;">import</span> org.apache.log4j.Level;
<span id="lnum5" style="color:#606060;"> 5:</span> <span style="color:#0000ff;">import</span> org.apache.log4j.Logger;
<span id="lnum6" style="color:#606060;"> 6:</span>
<span id="lnum7" style="color:#606060;"> 7:</span> <span style="color:#0000ff;">import</span> com.zipwhip.signals.dto.Message;
<span id="lnum8" style="color:#606060;"> 8:</span> <span style="color:#0000ff;">import</span> com.zipwhip.api.DefaultZipwhipSubscriptionClient;
<span id="lnum9" style="color:#606060;"> 9:</span> <span style="color:#0000ff;">import</span> com.zipwhip.api.HttpConnection;
<span id="lnum10" style="color:#606060;"> 10:</span> <span style="color:#0000ff;">import</span> com.zipwhip.api.signals.JsonSocketSignalClient;
<span id="lnum11" style="color:#606060;"> 11:</span> <span style="color:#0000ff;">import</span> com.zipwhip.signals.Signal;
<span id="lnum12" style="color:#606060;"> 12:</span> <span style="color:#0000ff;">import</span> com.zipwhip.signals.SignalObserver;
<span id="lnum13" style="color:#606060;"> 13:</span>
<span id="lnum14" style="color:#606060;"> 14:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Main {
<span id="lnum15" style="color:#606060;"> 15:</span>
<span id="lnum16" style="color:#606060;"> 16:</span>     <span style="color:#008000;">/**</span>
<span id="lnum17" style="color:#606060;"> 17:</span> <span style="color:#008000;"> * @param args</span>
<span id="lnum18" style="color:#606060;"> 18:</span> <span style="color:#008000;"> */</span>
<span id="lnum19" style="color:#606060;"> 19:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> main(String[] args) {
<span id="lnum20" style="color:#606060;"> 20:</span>         <span style="color:#008000;">// Setup logging</span>
<span id="lnum21" style="color:#606060;"> 21:</span>         <span style="color:#0000ff;">final</span> Logger log = Logger.getLogger(Main.<span style="color:#0000ff;">class</span>);
<span id="lnum22" style="color:#606060;"> 22:</span>         log.setLevel(Level.DEBUG);
<span id="lnum23" style="color:#606060;"> 23:</span>         BasicConfigurator.configure();
<span id="lnum24" style="color:#606060;"> 24:</span>
<span id="lnum25" style="color:#606060;"> 25:</span>         HttpConnection connection = <span style="color:#0000ff;">new</span> HttpConnection();
<span id="lnum26" style="color:#606060;"> 26:</span>         connection.setDebug(true);
<span id="lnum27" style="color:#606060;"> 27:</span>
<span id="lnum28" style="color:#606060;"> 28:</span>         String mobileNumber = <span style="color:#006080;">"3135551234"</span>;
<span id="lnum29" style="color:#606060;"> 29:</span>         String password = <span style="color:#006080;">"mypassword"</span>;
<span id="lnum30" style="color:#606060;"> 30:</span>
<span id="lnum31" style="color:#606060;"> 31:</span>         <span style="color:#0000ff;">try</span> {
<span id="lnum32" style="color:#606060;"> 32:</span>             <span style="color:#008000;">// This method will send a login request to the Zipwhip network and</span>
<span id="lnum33" style="color:#606060;"> 33:</span>             <span style="color:#008000;">// if succcessful you will get a sesionKey set in your connection object</span>
<span id="lnum34" style="color:#606060;"> 34:</span>             <span style="color:#008000;">// Watch out that you don't run "requestLogin()" too much because if you </span>
<span id="lnum35" style="color:#606060;"> 35:</span>             <span style="color:#008000;">// create more than 50 sessionKeys within 1 day you will no longer be able </span>
<span id="lnum36" style="color:#606060;"> 36:</span>             <span style="color:#008000;">// to get a key for 24 hours.</span>
<span id="lnum37" style="color:#606060;"> 37:</span>             <span style="color:#008000;">connection.requestLogin(mobileNumber, password);</span>
<span id="lnum38" style="color:#606060;"> 38:</span>             //connection.setSessionKey(<span style="color:#006080;">"2ecfd63-4c57-4aa6-64a0-b0f120a1677a:1"</span>);
<span id="lnum39" style="color:#606060;"> 39:</span>             connection.apiVersion = <span style="color:#006080;">"/"</span>;
<span id="lnum40" style="color:#606060;"> 40:</span>             log.info(<span style="color:#006080;">"Successfully authenticated. Your sessionKey is:"</span> + connection.getSessionKey());
<span id="lnum41" style="color:#606060;"> 41:</span>
<span id="lnum42" style="color:#606060;"> 42:</span>         } <span style="color:#0000ff;">catch</span> (Exception e) {
<span id="lnum43" style="color:#606060;"> 43:</span>             log.fatal(<span style="color:#006080;">"Failed to authenticate and get sessionKey to Zipwhip network."</span>);
<span id="lnum44" style="color:#606060;"> 44:</span>             log.fatal(e);
<span id="lnum45" style="color:#606060;"> 45:</span>             <span style="color:#0000ff;">return</span>;
<span id="lnum46" style="color:#606060;"> 46:</span>         }
<span id="lnum47" style="color:#606060;"> 47:</span>
<span id="lnum48" style="color:#606060;"> 48:</span>         DefaultZipwhipSubscriptionClient zipwhipSubscrClient;
<span id="lnum49" style="color:#606060;"> 49:</span>         JsonSocketSignalClient signalClient;
<span id="lnum50" style="color:#606060;"> 50:</span>
<span id="lnum51" style="color:#606060;"> 51:</span>         <span style="color:#008000;">// This will create a new client object that allows you to perform</span>
<span id="lnum52" style="color:#606060;"> 52:</span>         <span style="color:#008000;">// other tasks against the Zipwhip network once you have created </span>
<span id="lnum53" style="color:#606060;"> 53:</span>         <span style="color:#008000;">// an authenticated connection, i.e. have a sessionKey to communicate</span>
<span id="lnum54" style="color:#606060;"> 54:</span>         <span style="color:#008000;">// to the Zipwhip network over.</span>
<span id="lnum55" style="color:#606060;"> 55:</span>         zipwhipSubscrClient = <span style="color:#0000ff;">new</span> DefaultZipwhipSubscriptionClient(connection);
<span id="lnum56" style="color:#606060;"> 56:</span>         log.info(<span style="color:#006080;">"Just created our Default Client. Uses HTTP to connect to Zipwhip network."</span>);
<span id="lnum57" style="color:#606060;"> 57:</span>
<span id="lnum58" style="color:#606060;"> 58:</span>         <span style="color:#008000;">// We will create our socket connection as well. You still need an HTTP connection because</span>
<span id="lnum59" style="color:#606060;"> 59:</span>         <span style="color:#008000;">// the Zipwhip API uses HTTP calls to authenticate the socket connection.</span>
<span id="lnum60" style="color:#606060;"> 60:</span>         signalClient = <span style="color:#0000ff;">new</span> JsonSocketSignalClient(zipwhipSubscrClient);
<span id="lnum61" style="color:#606060;"> 61:</span>         log.info(<span style="color:#006080;">"Just created our Socket always-connected client. Uses TCP/IP sockets to connect to Zipwhip network."</span>);
<span id="lnum62" style="color:#606060;"> 62:</span>
<span id="lnum63" style="color:#606060;"> 63:</span>         signalClient.addSignalObserver(<span style="color:#0000ff;">new</span> SignalObserver() {
<span id="lnum64" style="color:#606060;"> 64:</span>             @Override
<span id="lnum65" style="color:#606060;"> 65:</span>             <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> notifySignalReceived(Signal signal) {
<span id="lnum66" style="color:#606060;"> 66:</span>                 log.debug(<span style="color:#006080;">"Signal received with uri "</span> + signal.uri);
<span id="lnum67" style="color:#606060;"> 67:</span>
<span id="lnum68" style="color:#606060;"> 68:</span>                 <span style="color:#0000ff;">switch</span> (SignalUri.toSignalUri(signal.uri)) {
<span id="lnum69" style="color:#606060;"> 69:</span>                 <span style="color:#0000ff;">case</span> SIGNAL_MESSAGE_RECEIVE:
<span id="lnum70" style="color:#606060;"> 70:</span>                     <span style="color:#008000;">// We got a message. Let's show it.</span>
<span id="lnum71" style="color:#606060;"> 71:</span>                     <span style="color:#008000;">// The Message object is contained in the signal.content object</span>
<span id="lnum72" style="color:#606060;"> 72:</span>                     <span style="color:#008000;">// but you need to cast it.</span>
<span id="lnum73" style="color:#606060;"> 73:</span>                     Message msg = (Message)signal.content;
<span id="lnum74" style="color:#606060;"> 74:</span>                     showIncomingMessageAlert(msg);
<span id="lnum75" style="color:#606060;"> 75:</span>                     <span style="color:#0000ff;">break</span>;
<span id="lnum76" style="color:#606060;"> 76:</span>                 <span style="color:#0000ff;">case</span> SIGNAL_CONVERSATION_CHANGE:
<span id="lnum77" style="color:#606060;"> 77:</span>                     <span style="color:#008000;">// Do nothing for now</span>
<span id="lnum78" style="color:#606060;"> 78:</span>                     <span style="color:#0000ff;">break</span>;
<span id="lnum79" style="color:#606060;"> 79:</span>                 <span style="color:#0000ff;">default</span>:
<span id="lnum80" style="color:#606060;"> 80:</span>                     <span style="color:#008000;">// Do nothing if we don't know the signal</span>
<span id="lnum81" style="color:#606060;"> 81:</span>                     <span style="color:#0000ff;">break</span>;
<span id="lnum82" style="color:#606060;"> 82:</span>                 }
<span id="lnum83" style="color:#606060;"> 83:</span>             }
<span id="lnum84" style="color:#606060;"> 84:</span>
<span id="lnum85" style="color:#606060;"> 85:</span>             @Override
<span id="lnum86" style="color:#606060;"> 86:</span>             <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> notifySignalProviderEvent(<span style="color:#0000ff;">boolean</span> isConnected, String message, <span style="color:#0000ff;">long</span> frameCount) {
<span id="lnum87" style="color:#606060;"> 87:</span>                 log.debug(<span style="color:#006080;">"Reporting SignalProvider event: isConnected "</span> + isConnected + <span style="color:#006080;">", message: "</span> + message + <span style="color:#006080;">", frames: "</span> + frameCount);
<span id="lnum88" style="color:#606060;"> 88:</span>             }
<span id="lnum89" style="color:#606060;"> 89:</span>         });
<span id="lnum90" style="color:#606060;"> 90:</span>
<span id="lnum91" style="color:#606060;"> 91:</span>         signalClient.connect(connection.getSessionKey());
<span id="lnum92" style="color:#606060;"> 92:</span>
<span id="lnum93" style="color:#606060;"> 93:</span>         log.info(<span style="color:#006080;">"Socket test will keep running on socket thread. Thanks for using Zipwhip."</span>);
<span id="lnum94" style="color:#606060;"> 94:</span>     }
<span id="lnum95" style="color:#606060;"> 95:</span>
<span id="lnum96" style="color:#606060;"> 96:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> showIncomingMessageAlert(Message message) {
<span id="lnum97" style="color:#606060;"> 97:</span>         Bubble bubble = <span style="color:#0000ff;">new</span> Bubble(message.sourceAddress, message.body, <span style="color:#006080;">"http://cloudtext.letsbobsled.com"</span>);
<span id="lnum98" style="color:#606060;"> 98:</span>     }
<span id="lnum99" style="color:#606060;"> 99:</span> }
<span id="lnum100" style="color:#606060;"> 100:</span>
<span id="lnum101" style="color:#606060;"> 101:</span> <span style="color:#0000ff;">enum</span> SignalUri
<span id="lnum102" style="color:#606060;"> 102:</span> {
<span id="lnum103" style="color:#606060;"> 103:</span>     <span style="color:#008000;">/*</span>
<span id="lnum104" style="color:#606060;"> 104:</span> <span style="color:#008000;"> * /signal/message/progress</span>
<span id="lnum105" style="color:#606060;"> 105:</span> <span style="color:#008000;"> * /signal/messageProgress/messageProgress</span>
<span id="lnum106" style="color:#606060;"> 106:</span> <span style="color:#008000;"> * /signal/message/send</span>
<span id="lnum107" style="color:#606060;"> 107:</span> <span style="color:#008000;"> * /signal/message/receive</span>
<span id="lnum108" style="color:#606060;"> 108:</span> <span style="color:#008000;"> * /signal/message/read</span>
<span id="lnum109" style="color:#606060;"> 109:</span> <span style="color:#008000;"> * /signal/message/delete</span>
<span id="lnum110" style="color:#606060;"> 110:</span> <span style="color:#008000;"> * /signal/conversation/change</span>
<span id="lnum111" style="color:#606060;"> 111:</span> <span style="color:#008000;"> */</span>
<span id="lnum112" style="color:#606060;"> 112:</span>     SIGNAL_MESSAGE_RECEIVE,
<span id="lnum113" style="color:#606060;"> 113:</span>     SIGNAL_MESSAGE_PROGRESS,
<span id="lnum114" style="color:#606060;"> 114:</span>     SIGNAL_MESSAGE_READ,
<span id="lnum115" style="color:#606060;"> 115:</span>     SIGNAL_MESSAGE_DELETE,
<span id="lnum116" style="color:#606060;"> 116:</span>     SIGNAL_MESSAGEPROGRESS_MESSAGEPROGRESS,
<span id="lnum117" style="color:#606060;"> 117:</span>     SIGNAL_CONVERSATION_CHANGE,
<span id="lnum118" style="color:#606060;"> 118:</span>     SIGNAL_CONTACT_NEW,
<span id="lnum119" style="color:#606060;"> 119:</span>     SIGNAL_CONTACT_SAVE,
<span id="lnum120" style="color:#606060;"> 120:</span>     SIGNAL_CONTACT_DELETE,
<span id="lnum121" style="color:#606060;"> 121:</span>     NOVALUE;
<span id="lnum122" style="color:#606060;"> 122:</span>
<span id="lnum123" style="color:#606060;"> 123:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> SignalUri toSignalUri(String str)
<span id="lnum124" style="color:#606060;"> 124:</span>     {
<span id="lnum125" style="color:#606060;"> 125:</span>         <span style="color:#008000;">// We are going to use Java's valueOf method, so</span>
<span id="lnum126" style="color:#606060;"> 126:</span>         <span style="color:#008000;">// we need to cleanup the URI string first</span>
<span id="lnum127" style="color:#606060;"> 127:</span>         <span style="color:#008000;">// Get rid of first slash</span>
<span id="lnum128" style="color:#606060;"> 128:</span>         String str2 = str.substring(1, str.length());
<span id="lnum129" style="color:#606060;"> 129:</span>         <span style="color:#008000;">// convert slashes to underscores</span>
<span id="lnum130" style="color:#606060;"> 130:</span>         str2 = str2.replaceAll(<span style="color:#006080;">"/"</span>, <span style="color:#006080;">"_"</span>);
<span id="lnum131" style="color:#606060;"> 131:</span>         <span style="color:#008000;">// go all upper case</span>
<span id="lnum132" style="color:#606060;"> 132:</span>         str2 = str2.toUpperCase();
<span id="lnum133" style="color:#606060;"> 133:</span>
<span id="lnum134" style="color:#606060;"> 134:</span>         <span style="color:#0000ff;">try</span> {
<span id="lnum135" style="color:#606060;"> 135:</span>             <span style="color:#0000ff;">return</span> valueOf(str2);
<span id="lnum136" style="color:#606060;"> 136:</span>         }
<span id="lnum137" style="color:#606060;"> 137:</span>         <span style="color:#0000ff;">catch</span> (Exception ex) {
<span id="lnum138" style="color:#606060;"> 138:</span>             System.out.println(<span style="color:#006080;">"Found no match for SignalURI:"</span> + str);
<span id="lnum139" style="color:#606060;"> 139:</span>             <span style="color:#0000ff;">return</span> NOVALUE;
<span id="lnum140" style="color:#606060;"> 140:</span>         }
<span id="lnum141" style="color:#606060;"> 141:</span>     }
<span id="lnum142" style="color:#606060;"> 142:</span> }

You will see that once you paste this code in you will have one error. You need to get the Bubble class that I created for this project.

image

The Bubble class takes care of all of the details of displaying a nice looking bubble on your desktop. All you have to do is create a bubble and pass it the mobile number, the text message, and a redirection URL to actually reply to the message. There are numerous web apps on the Internet that use the Zipwhip cloud so it is up to you to pick the URL that is appropriate.

Let’s go ahead and add our Bubble class to the project. Right click on the “com.yourcompany.zw” package name and choose New –> Class from the menu.

image

Call the class Bubble.

image

You will get a nice raw class like below.

image

Go ahead and paste in all of my hard work from my Bubble class. There’s a good deal of code in this class. The code is below. You can also download the file if you want. It’s below or it’s in the main Zip file linked to earlier in this posting.

Bubble.java 29.4 KB

<span id="lnum1" style="color:#606060;"> 1:</span> <span style="color:#0000ff;">package</span> com.yourcompany.zw;
<span id="lnum2" style="color:#606060;"> 2:</span>
<span id="lnum3" style="color:#606060;"> 3:</span> <span style="color:#0000ff;">import</span> java.awt.AlphaComposite;
<span id="lnum4" style="color:#606060;"> 4:</span> <span style="color:#0000ff;">import</span> java.awt.BorderLayout;
<span id="lnum5" style="color:#606060;"> 5:</span> <span style="color:#0000ff;">import</span> java.awt.Color;
<span id="lnum6" style="color:#606060;"> 6:</span> <span style="color:#0000ff;">import</span> java.awt.Container;
<span id="lnum7" style="color:#606060;"> 7:</span> <span style="color:#0000ff;">import</span> java.awt.Dimension;
<span id="lnum8" style="color:#606060;"> 8:</span> <span style="color:#0000ff;">import</span> java.awt.Font;
<span id="lnum9" style="color:#606060;"> 9:</span> <span style="color:#0000ff;">import</span> java.awt.GradientPaint;
<span id="lnum10" style="color:#606060;"> 10:</span> <span style="color:#0000ff;">import</span> java.awt.Graphics;
<span id="lnum11" style="color:#606060;"> 11:</span> <span style="color:#0000ff;">import</span> java.awt.Graphics2D;
<span id="lnum12" style="color:#606060;"> 12:</span> <span style="color:#0000ff;">import</span> java.awt.GraphicsConfiguration;
<span id="lnum13" style="color:#606060;"> 13:</span> <span style="color:#0000ff;">import</span> java.awt.Point;
<span id="lnum14" style="color:#606060;"> 14:</span> <span style="color:#0000ff;">import</span> java.awt.Toolkit;
<span id="lnum15" style="color:#606060;"> 15:</span> <span style="color:#0000ff;">import</span> java.awt.Transparency;
<span id="lnum16" style="color:#606060;"> 16:</span> <span style="color:#0000ff;">import</span> java.awt.event.ActionEvent;
<span id="lnum17" style="color:#606060;"> 17:</span> <span style="color:#0000ff;">import</span> java.awt.event.ActionListener;
<span id="lnum18" style="color:#606060;"> 18:</span> <span style="color:#0000ff;">import</span> java.awt.event.MouseAdapter;
<span id="lnum19" style="color:#606060;"> 19:</span> <span style="color:#0000ff;">import</span> java.awt.event.MouseEvent;
<span id="lnum20" style="color:#606060;"> 20:</span> <span style="color:#0000ff;">import</span> java.awt.event.MouseListener;
<span id="lnum21" style="color:#606060;"> 21:</span> <span style="color:#0000ff;">import</span> java.awt.event.MouseMotionAdapter;
<span id="lnum22" style="color:#606060;"> 22:</span> <span style="color:#0000ff;">import</span> java.awt.event.MouseMotionListener;
<span id="lnum23" style="color:#606060;"> 23:</span> <span style="color:#0000ff;">import</span> java.awt.geom.AffineTransform;
<span id="lnum24" style="color:#606060;"> 24:</span> <span style="color:#0000ff;">import</span> java.awt.geom.Rectangle2D;
<span id="lnum25" style="color:#606060;"> 25:</span> <span style="color:#0000ff;">import</span> java.awt.image.BufferedImage;
<span id="lnum26" style="color:#606060;"> 26:</span> <span style="color:#0000ff;">import</span> java.io.File;
<span id="lnum27" style="color:#606060;"> 27:</span> <span style="color:#0000ff;">import</span> java.io.IOException;
<span id="lnum28" style="color:#606060;"> 28:</span> <span style="color:#0000ff;">import</span> java.net.URI;
<span id="lnum29" style="color:#606060;"> 29:</span> <span style="color:#0000ff;">import</span> java.net.URISyntaxException;
<span id="lnum30" style="color:#606060;"> 30:</span> <span style="color:#0000ff;">import</span> java.net.URL;
<span id="lnum31" style="color:#606060;"> 31:</span> <span style="color:#0000ff;">import</span> java.util.ArrayList;
<span id="lnum32" style="color:#606060;"> 32:</span> <span style="color:#0000ff;">import</span> java.util.Arrays;
<span id="lnum33" style="color:#606060;"> 33:</span> <span style="color:#0000ff;">import</span> java.util.HashMap;
<span id="lnum34" style="color:#606060;"> 34:</span> <span style="color:#0000ff;">import</span> java.util.HashSet;
<span id="lnum35" style="color:#606060;"> 35:</span> <span style="color:#0000ff;">import</span> java.util.List;
<span id="lnum36" style="color:#606060;"> 36:</span> <span style="color:#0000ff;">import</span> java.util.Map;
<span id="lnum37" style="color:#606060;"> 37:</span> <span style="color:#0000ff;">import</span> java.util.Set;
<span id="lnum38" style="color:#606060;"> 38:</span> <span style="color:#0000ff;">import</span> java.util.regex.Pattern;
<span id="lnum39" style="color:#606060;"> 39:</span>
<span id="lnum40" style="color:#606060;"> 40:</span> <span style="color:#0000ff;">import</span> javax.imageio.ImageIO;
<span id="lnum41" style="color:#606060;"> 41:</span> <span style="color:#0000ff;">import</span> javax.swing.ImageIcon;
<span id="lnum42" style="color:#606060;"> 42:</span> <span style="color:#0000ff;">import</span> javax.swing.JButton;
<span id="lnum43" style="color:#606060;"> 43:</span> <span style="color:#0000ff;">import</span> javax.swing.JComponent;
<span id="lnum44" style="color:#606060;"> 44:</span> <span style="color:#0000ff;">import</span> javax.swing.JDialog;
<span id="lnum45" style="color:#606060;"> 45:</span> <span style="color:#0000ff;">import</span> javax.swing.JFrame;
<span id="lnum46" style="color:#606060;"> 46:</span> <span style="color:#0000ff;">import</span> javax.swing.JPanel;
<span id="lnum47" style="color:#606060;"> 47:</span> <span style="color:#0000ff;">import</span> javax.swing.Timer;
<span id="lnum48" style="color:#606060;"> 48:</span> <span style="color:#0000ff;">import</span> javax.swing.UIManager;
<span id="lnum49" style="color:#606060;"> 49:</span> <span style="color:#0000ff;">import</span> javax.swing.text.AbstractDocument;
<span id="lnum50" style="color:#606060;"> 50:</span>
<span id="lnum51" style="color:#606060;"> 51:</span> <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Bubble <span style="color:#0000ff;">extends</span> JDialog {
<span id="lnum52" style="color:#606060;"> 52:</span>
<span id="lnum53" style="color:#606060;"> 53:</span>     <span style="color:#008000;">// this code is static to manage the number of windows that are open</span>
<span id="lnum54" style="color:#606060;"> 54:</span>     <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">int</span> numOpen;
<span id="lnum55" style="color:#606060;"> 55:</span>     <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">int</span> getOpen() { <span style="color:#0000ff;">return</span> numOpen; }
<span id="lnum56" style="color:#606060;"> 56:</span>     <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> windowOpen() { numOpen++; }
<span id="lnum57" style="color:#606060;"> 57:</span>     <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> windowClose() { numOpen--; }
<span id="lnum58" style="color:#606060;"> 58:</span>
<span id="lnum59" style="color:#606060;"> 59:</span>     <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">int</span> X=0;
<span id="lnum60" style="color:#606060;"> 60:</span>     <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">int</span> Y=0;
<span id="lnum61" style="color:#606060;"> 61:</span>     <span style="color:#0000ff;">private</span> String fromMobileNumber;
<span id="lnum62" style="color:#606060;"> 62:</span>     <span style="color:#0000ff;">private</span> String message;
<span id="lnum63" style="color:#606060;"> 63:</span>     <span style="color:#0000ff;">private</span> String replyUrl;
<span id="lnum64" style="color:#606060;"> 64:</span>     <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">boolean</span> toFade = true;
<span id="lnum65" style="color:#606060;"> 65:</span>     <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">float</span> currOpacity;
<span id="lnum66" style="color:#606060;"> 66:</span>     <span style="color:#0000ff;">private</span> Timer fadeInTimer;
<span id="lnum67" style="color:#606060;"> 67:</span>     <span style="color:#0000ff;">private</span> Timer fadeOutTimer;
<span id="lnum68" style="color:#606060;"> 68:</span>
<span id="lnum69" style="color:#606060;"> 69:</span>     javax.swing.JTextPane jTextPaneTxtMsg;
<span id="lnum70" style="color:#606060;"> 70:</span>     AbstractDocument doc;
<span id="lnum71" style="color:#606060;"> 71:</span>
<span id="lnum72" style="color:#606060;"> 72:</span>     <span style="color:#0000ff;">public</span> Bubble(String fromMobileNumber, String message, String replyUrl) {
<span id="lnum73" style="color:#606060;"> 73:</span>         <span style="color:#0000ff;">this</span>(fromMobileNumber, message, replyUrl, true);
<span id="lnum74" style="color:#606060;"> 74:</span>     }
<span id="lnum75" style="color:#606060;"> 75:</span>
<span id="lnum76" style="color:#606060;"> 76:</span>     <span style="color:#0000ff;">public</span> Bubble(String fromMobileNumber, String message, String replyUrl, <span style="color:#0000ff;">boolean</span> toFade) {
<span id="lnum77" style="color:#606060;"> 77:</span>
<span id="lnum78" style="color:#606060;"> 78:</span>         <span style="color:#008000;">// initialize properties</span>
<span id="lnum79" style="color:#606060;"> 79:</span>         setFromMobileNumber(fromMobileNumber);
<span id="lnum80" style="color:#606060;"> 80:</span>         setMessage(message);
<span id="lnum81" style="color:#606060;"> 81:</span>         setReplyUrl(replyUrl);
<span id="lnum82" style="color:#606060;"> 82:</span>
<span id="lnum83" style="color:#606060;"> 83:</span>         <span style="color:#008000;">// initialize the UI of the bubble</span>
<span id="lnum84" style="color:#606060;"> 84:</span>         init();
<span id="lnum85" style="color:#606060;"> 85:</span>
<span id="lnum86" style="color:#606060;"> 86:</span>         <span style="color:#008000;">// set the location of where this bubble will be shown</span>
<span id="lnum87" style="color:#606060;"> 87:</span>         Dimension ourDim = Toolkit.getDefaultToolkit().getScreenSize();
<span id="lnum88" style="color:#606060;"> 88:</span>         <span style="color:#0000ff;">this</span>.setLocation(
<span id="lnum89" style="color:#606060;"> 89:</span>                 (<span style="color:#0000ff;">int</span>)ourDim.getWidth() - <span style="color:#0000ff;">this</span>.getWidth() - 10,
<span id="lnum90" style="color:#606060;"> 90:</span>                 0 + ((<span style="color:#0000ff;">this</span>.getHeight() + -20) * getOpen()));
<span id="lnum91" style="color:#606060;"> 91:</span>
<span id="lnum92" style="color:#606060;"> 92:</span>         <span style="color:#008000;">// increment how many bubbles are open</span>
<span id="lnum93" style="color:#606060;"> 93:</span>         windowOpen();
<span id="lnum94" style="color:#606060;"> 94:</span>
<span id="lnum95" style="color:#606060;"> 95:</span>         <span style="color:#008000;">// ok, show it finally</span>
<span id="lnum96" style="color:#606060;"> 96:</span>         <span style="color:#0000ff;">this</span>.setVisible(true);
<span id="lnum97" style="color:#606060;"> 97:</span>     }
<span id="lnum98" style="color:#606060;"> 98:</span>
<span id="lnum99" style="color:#606060;"> 99:</span>     <span style="color:#008000;">// Getters/setters</span>
<span id="lnum100" style="color:#606060;"> 100:</span>     <span style="color:#0000ff;">public</span> String getFromMobileNumber() {
<span id="lnum101" style="color:#606060;"> 101:</span>         <span style="color:#0000ff;">return</span> StringUtil.format(fromMobileNumber, <span style="color:#006080;">"(###) ###-####"</span>);
<span id="lnum102" style="color:#606060;"> 102:</span>     }
<span id="lnum103" style="color:#606060;"> 103:</span>
<span id="lnum104" style="color:#606060;"> 104:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> setFromMobileNumber(String fromMobileNumber) {
<span id="lnum105" style="color:#606060;"> 105:</span>         <span style="color:#0000ff;">this</span>.fromMobileNumber = fromMobileNumber;
<span id="lnum106" style="color:#606060;"> 106:</span>     }
<span id="lnum107" style="color:#606060;"> 107:</span>
<span id="lnum108" style="color:#606060;"> 108:</span>     <span style="color:#0000ff;">public</span> String getMessage() {
<span id="lnum109" style="color:#606060;"> 109:</span>         <span style="color:#0000ff;">return</span> message;
<span id="lnum110" style="color:#606060;"> 110:</span>     }
<span id="lnum111" style="color:#606060;"> 111:</span>
<span id="lnum112" style="color:#606060;"> 112:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> setMessage(String message) {
<span id="lnum113" style="color:#606060;"> 113:</span>         <span style="color:#0000ff;">this</span>.message = message;
<span id="lnum114" style="color:#606060;"> 114:</span>     }
<span id="lnum115" style="color:#606060;"> 115:</span>
<span id="lnum116" style="color:#606060;"> 116:</span>     <span style="color:#0000ff;">public</span> String getReplyUrl() {
<span id="lnum117" style="color:#606060;"> 117:</span>         <span style="color:#0000ff;">return</span> replyUrl;
<span id="lnum118" style="color:#606060;"> 118:</span>     }
<span id="lnum119" style="color:#606060;"> 119:</span>
<span id="lnum120" style="color:#606060;"> 120:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> setReplyUrl(String replyUrl) {
<span id="lnum121" style="color:#606060;"> 121:</span>         <span style="color:#0000ff;">this</span>.replyUrl = replyUrl;
<span id="lnum122" style="color:#606060;"> 122:</span>     }
<span id="lnum123" style="color:#606060;"> 123:</span>
<span id="lnum124" style="color:#606060;"> 124:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">boolean</span> isToFade() {
<span id="lnum125" style="color:#606060;"> 125:</span>         <span style="color:#0000ff;">return</span> toFade;
<span id="lnum126" style="color:#606060;"> 126:</span>     }
<span id="lnum127" style="color:#606060;"> 127:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> setToFade(<span style="color:#0000ff;">boolean</span> toFade) {
<span id="lnum128" style="color:#606060;"> 128:</span>         <span style="color:#0000ff;">this</span>.toFade = toFade;
<span id="lnum129" style="color:#606060;"> 129:</span>     }
<span id="lnum130" style="color:#606060;"> 130:</span>
<span id="lnum131" style="color:#606060;"> 131:</span>     <span style="color:#008000;">// Initialize the GUI</span>
<span id="lnum132" style="color:#606060;"> 132:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> init() {
<span id="lnum133" style="color:#606060;"> 133:</span>         <span style="color:#0000ff;">try</span> {
<span id="lnum134" style="color:#606060;"> 134:</span>
<span id="lnum135" style="color:#606060;"> 135:</span>             <span style="color:#008000;">// When JFrame or JDialog</span>
<span id="lnum136" style="color:#606060;"> 136:</span>             <span style="color:#0000ff;">this</span>.setUndecorated(true);
<span id="lnum137" style="color:#606060;"> 137:</span>             <span style="color:#0000ff;">this</span>.setModal(false);
<span id="lnum138" style="color:#606060;"> 138:</span>             <span style="color:#0000ff;">this</span>.setFocusableWindowState(false);
<span id="lnum139" style="color:#606060;"> 139:</span>             <span style="color:#0000ff;">this</span>.setAlwaysOnTop(true);
<span id="lnum140" style="color:#606060;"> 140:</span>
<span id="lnum141" style="color:#606060;"> 141:</span>             <span style="color:#0000ff;">try</span> {
<span id="lnum142" style="color:#606060;"> 142:</span>                 UIManager.setLookAndFeel(<span style="color:#006080;">"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"</span>);
<span id="lnum143" style="color:#606060;"> 143:</span>             } <span style="color:#0000ff;">catch</span> (Exception evt) {}
<span id="lnum144" style="color:#606060;"> 144:</span>
<span id="lnum145" style="color:#606060;"> 145:</span>             <span style="color:#008000;">// Get bg image</span>
<span id="lnum146" style="color:#606060;"> 146:</span>             <span style="color:#0000ff;">final</span> BufferedImage backgroundImg = ImageIO.read(getClass().getResource(<span style="color:#006080;">"/resources/riser_shd.png"</span>));
<span id="lnum147" style="color:#606060;"> 147:</span>
<span id="lnum148" style="color:#606060;"> 148:</span>             <span style="color:#008000;">// Set icon &amp; title</span>
<span id="lnum149" style="color:#606060;"> 149:</span>             <span style="color:#0000ff;">final</span> BufferedImage z = ImageIO.read(getClass().getResource(<span style="color:#006080;">"/resources/z.png"</span>));
<span id="lnum150" style="color:#606060;"> 150:</span>             ((java.awt.Frame)<span style="color:#0000ff;">this</span>.getOwner()).setIconImage(z);
<span id="lnum151" style="color:#606060;"> 151:</span>             <span style="color:#0000ff;">this</span>.setTitle(<span style="color:#0000ff;">this</span>.getFromMobileNumber() + <span style="color:#006080;">": "</span> + <span style="color:#0000ff;">this</span>.getMessage());
<span id="lnum152" style="color:#606060;"> 152:</span>
<span id="lnum153" style="color:#606060;"> 153:</span>             <span style="color:#008000;">// Set layout</span>
<span id="lnum154" style="color:#606060;"> 154:</span>             <span style="color:#0000ff;">this</span>.setLayout(<span style="color:#0000ff;">new</span> BorderLayout());
<span id="lnum155" style="color:#606060;"> 155:</span>             JPanel mainPanel = <span style="color:#0000ff;">new</span> JPanel(<span style="color:#0000ff;">new</span> BorderLayout()) {
<span id="lnum156" style="color:#606060;"> 156:</span>
<span id="lnum157" style="color:#606060;"> 157:</span>                 <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">final</span> <span style="color:#0000ff;">long</span> serialVersionUID = 1L;
<span id="lnum158" style="color:#606060;"> 158:</span>
<span id="lnum159" style="color:#606060;"> 159:</span>                 <span style="color:#008000;">// The paintComponent override let's us make the entire</span>
<span id="lnum160" style="color:#606060;"> 160:</span>                 <span style="color:#008000;">// window transparent on the desktop so we get a cool effect</span>
<span id="lnum161" style="color:#606060;"> 161:</span>                 @Override
<span id="lnum162" style="color:#606060;"> 162:</span>                 <span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">void</span> paintComponent(Graphics g) {
<span id="lnum163" style="color:#606060;"> 163:</span>                     Graphics2D g2d = (Graphics2D) g.create();
<span id="lnum164" style="color:#606060;"> 164:</span>
<span id="lnum165" style="color:#606060;"> 165:</span>                     <span style="color:#008000;">// code from</span>
<span id="lnum166" style="color:#606060;"> 166:</span>                     <span style="color:#008000;">// http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html</span>
<span id="lnum167" style="color:#606060;"> 167:</span>                     <span style="color:#0000ff;">int</span> width = backgroundImg.getWidth();
<span id="lnum168" style="color:#606060;"> 168:</span>                     <span style="color:#0000ff;">int</span> height = backgroundImg.getHeight();
<span id="lnum169" style="color:#606060;"> 169:</span>                     GraphicsConfiguration gc = g2d.getDeviceConfiguration();
<span id="lnum170" style="color:#606060;"> 170:</span>                     BufferedImage img = gc.createCompatibleImage(
<span id="lnum171" style="color:#606060;"> 171:</span>                         width,
<span id="lnum172" style="color:#606060;"> 172:</span>                         height,
<span id="lnum173" style="color:#606060;"> 173:</span>                         Transparency.TRANSLUCENT);
<span id="lnum174" style="color:#606060;"> 174:</span>                     Graphics2D g2 = img.createGraphics();
<span id="lnum175" style="color:#606060;"> 175:</span>                     g2.setComposite(AlphaComposite.Src);
<span id="lnum176" style="color:#606060;"> 176:</span>                     g2.drawImage(backgroundImg, 0, 0, null);
<span id="lnum177" style="color:#606060;"> 177:</span>                     g2.dispose();
<span id="lnum178" style="color:#606060;"> 178:</span>                     g2d.drawImage(img, 0, 0, <span style="color:#0000ff;">this</span>);
<span id="lnum179" style="color:#606060;"> 179:</span>                     g2d.dispose();
<span id="lnum180" style="color:#606060;"> 180:</span>                 }
<span id="lnum181" style="color:#606060;"> 181:</span>             };
<span id="lnum182" style="color:#606060;"> 182:</span>
<span id="lnum183" style="color:#606060;"> 183:</span>             <span style="color:#008000;">// Setup the window</span>
<span id="lnum184" style="color:#606060;"> 184:</span>             <span style="color:#0000ff;">final</span> JDialog wnd = <span style="color:#0000ff;">this</span>;
<span id="lnum185" style="color:#606060;"> 185:</span>
<span id="lnum186" style="color:#606060;"> 186:</span>             <span style="color:#008000;">// This is the phone number and textarea message panel</span>
<span id="lnum187" style="color:#606060;"> 187:</span>             javax.swing.JPanel jPanelAll = <span style="color:#0000ff;">new</span> javax.swing.JPanel();
<span id="lnum188" style="color:#606060;"> 188:</span>             javax.swing.JLabel jLabelMobileNum = <span style="color:#0000ff;">new</span> javax.swing.JLabel();
<span id="lnum189" style="color:#606060;"> 189:</span>             <span style="color:#0000ff;">this</span>.jTextPaneTxtMsg = <span style="color:#0000ff;">new</span> javax.swing.JTextPane();
<span id="lnum190" style="color:#606060;"> 190:</span>             JButton jButtonClose = <span style="color:#0000ff;">new</span> javax.swing.JButton();
<span id="lnum191" style="color:#606060;"> 191:</span>             JButton jButtonReply = <span style="color:#0000ff;">new</span> javax.swing.JButton();
<span id="lnum192" style="color:#606060;"> 192:</span>
<span id="lnum193" style="color:#606060;"> 193:</span>             jPanelAll.setOpaque(false);
<span id="lnum194" style="color:#606060;"> 194:</span>             jPanelAll.setDoubleBuffered(false);
<span id="lnum195" style="color:#606060;"> 195:</span>             jPanelAll.setName(<span style="color:#006080;">"jPanelAll"</span>); <span style="color:#008000;">// NOI18N</span>
<span id="lnum196" style="color:#606060;"> 196:</span>
<span id="lnum197" style="color:#606060;"> 197:</span>             jLabelMobileNum.setFont( <span style="color:#0000ff;">new</span> Font(null, Font.BOLD, 14));
<span id="lnum198" style="color:#606060;"> 198:</span>             jLabelMobileNum.setForeground(<span style="color:#0000ff;">new</span> Color(67, 74, 84));
<span id="lnum199" style="color:#606060;"> 199:</span>             jLabelMobileNum.setText(getFromMobileNumber());
<span id="lnum200" style="color:#606060;"> 200:</span>             jLabelMobileNum.setName(<span style="color:#006080;">"jLabelMobileNum"</span>); <span style="color:#008000;">// NOI18N</span>
<span id="lnum201" style="color:#606060;"> 201:</span>
<span id="lnum202" style="color:#606060;"> 202:</span>             jTextPaneTxtMsg.setBorder(null);
<span id="lnum203" style="color:#606060;"> 203:</span>             jTextPaneTxtMsg.setEditable(false);
<span id="lnum204" style="color:#606060;"> 204:</span>             jTextPaneTxtMsg.setFont( <span style="color:#0000ff;">new</span> Font(null, Font.PLAIN, 12));
<span id="lnum205" style="color:#606060;"> 205:</span>             jTextPaneTxtMsg.setOpaque(false);
<span id="lnum206" style="color:#606060;"> 206:</span>             jTextPaneTxtMsg.setDoubleBuffered(false);
<span id="lnum207" style="color:#606060;"> 207:</span>             jTextPaneTxtMsg.setText(getMessage());
<span id="lnum208" style="color:#606060;"> 208:</span>             jTextPaneTxtMsg.setName(<span style="color:#006080;">"jTextPane1"</span>); <span style="color:#008000;">// NOI18N</span>
<span id="lnum209" style="color:#606060;"> 209:</span>             jTextPaneTxtMsg.setCaretPosition(0);
<span id="lnum210" style="color:#606060;"> 210:</span>
<span id="lnum211" style="color:#606060;"> 211:</span>             javax.swing.JScrollPane jScrollPane1 = <span style="color:#0000ff;">new</span> javax.swing.JScrollPane(jTextPaneTxtMsg);
<span id="lnum212" style="color:#606060;"> 212:</span>             jScrollPane1.getViewport().setOpaque(false);
<span id="lnum213" style="color:#606060;"> 213:</span>             jScrollPane1.getViewport().setDoubleBuffered(false);
<span id="lnum214" style="color:#606060;"> 214:</span>
<span id="lnum215" style="color:#606060;"> 215:</span>             jScrollPane1.setBorder(null);
<span id="lnum216" style="color:#606060;"> 216:</span>             jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
<span id="lnum217" style="color:#606060;"> 217:</span>             jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
<span id="lnum218" style="color:#606060;"> 218:</span>             jScrollPane1.setOpaque(false);
<span id="lnum219" style="color:#606060;"> 219:</span>             jScrollPane1.setDoubleBuffered(false);
<span id="lnum220" style="color:#606060;"> 220:</span>             jScrollPane1.setWheelScrollingEnabled(true);
<span id="lnum221" style="color:#606060;"> 221:</span>
<span id="lnum222" style="color:#606060;"> 222:</span>             BufferedImage riserSpriteBtnImg = ImageIO.read(getClass().getResource(<span style="color:#006080;">"/resources/risergang.png"</span>));
<span id="lnum223" style="color:#606060;"> 223:</span>
<span id="lnum224" style="color:#606060;"> 224:</span>             <span style="color:#008000;">// Define the close button</span>
<span id="lnum225" style="color:#606060;"> 225:</span>             jButtonClose.setIcon(<span style="color:#0000ff;">new</span> ImageIcon(riserSpriteBtnImg.getSubimage(1,1,14,14)));
<span id="lnum226" style="color:#606060;"> 226:</span>             jButtonClose.setRolloverIcon(<span style="color:#0000ff;">new</span> ImageIcon(riserSpriteBtnImg.getSubimage(16,1,14,14)));
<span id="lnum227" style="color:#606060;"> 227:</span>             jButtonClose.setPressedIcon(<span style="color:#0000ff;">new</span> ImageIcon(riserSpriteBtnImg.getSubimage(31,1,14,14)));
<span id="lnum228" style="color:#606060;"> 228:</span>             jButtonClose.setBorder(null);
<span id="lnum229" style="color:#606060;"> 229:</span>             jButtonClose.setBorderPainted(false);
<span id="lnum230" style="color:#606060;"> 230:</span>             jButtonClose.setContentAreaFilled(false);
<span id="lnum231" style="color:#606060;"> 231:</span>             jButtonClose.addActionListener(<span style="color:#0000ff;">new</span> ActionListener() {
<span id="lnum232" style="color:#606060;"> 232:</span>                 @Override
<span id="lnum233" style="color:#606060;"> 233:</span>                 <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> actionPerformed(ActionEvent e) {
<span id="lnum234" style="color:#606060;"> 234:</span>                     wnd.setVisible(false);
<span id="lnum235" style="color:#606060;"> 235:</span>                 }
<span id="lnum236" style="color:#606060;"> 236:</span>             });
<span id="lnum237" style="color:#606060;"> 237:</span>
<span id="lnum238" style="color:#606060;"> 238:</span>             <span style="color:#008000;">// Define the reply button</span>
<span id="lnum239" style="color:#606060;"> 239:</span>             jButtonReply.setIcon(<span style="color:#0000ff;">new</span> ImageIcon(riserSpriteBtnImg.getSubimage(0,16,58,30)));
<span id="lnum240" style="color:#606060;"> 240:</span>             jButtonReply.setRolloverIcon(<span style="color:#0000ff;">new</span> ImageIcon(riserSpriteBtnImg.getSubimage(0,47,58,30)));
<span id="lnum241" style="color:#606060;"> 241:</span>             jButtonReply.setPressedIcon(<span style="color:#0000ff;">new</span> ImageIcon(riserSpriteBtnImg.getSubimage(0,78,58,30)));
<span id="lnum242" style="color:#606060;"> 242:</span>             jButtonReply.setBorder(null);
<span id="lnum243" style="color:#606060;"> 243:</span>             jButtonReply.setBorderPainted(false);
<span id="lnum244" style="color:#606060;"> 244:</span>             jButtonReply.setContentAreaFilled(false);
<span id="lnum245" style="color:#606060;"> 245:</span>             jButtonReply.addActionListener(<span style="color:#0000ff;">new</span> ActionListener() {
<span id="lnum246" style="color:#606060;"> 246:</span>                 @Override
<span id="lnum247" style="color:#606060;"> 247:</span>                 <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> actionPerformed(ActionEvent e) {
<span id="lnum248" style="color:#606060;"> 248:</span>                     openUri(getReplyUrl());
<span id="lnum249" style="color:#606060;"> 249:</span>                     wnd.setVisible(false);
<span id="lnum250" style="color:#606060;"> 250:</span>                 }
<span id="lnum251" style="color:#606060;"> 251:</span>             });
<span id="lnum252" style="color:#606060;"> 252:</span>
<span id="lnum253" style="color:#606060;"> 253:</span>             <span style="color:#008000;">// Do the layout positioning using horiz/vert groups </span>
<span id="lnum254" style="color:#606060;"> 254:</span>             javax.swing.GroupLayout jPanel2Layout = <span style="color:#0000ff;">new</span> javax.swing.GroupLayout(jPanelAll);
<span id="lnum255" style="color:#606060;"> 255:</span>             jPanelAll.setLayout(jPanel2Layout);
<span id="lnum256" style="color:#606060;"> 256:</span>
<span id="lnum257" style="color:#606060;"> 257:</span>             jPanel2Layout.setHorizontalGroup(
<span id="lnum258" style="color:#606060;"> 258:</span>                 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
<span id="lnum259" style="color:#606060;"> 259:</span>                 .addGroup(jPanel2Layout.createSequentialGroup()
<span id="lnum260" style="color:#606060;"> 260:</span>                     .addGap(32)
<span id="lnum261" style="color:#606060;"> 261:</span>                     .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
<span id="lnum262" style="color:#606060;"> 262:</span>                         .addComponent(jLabelMobileNum)
<span id="lnum263" style="color:#606060;"> 263:</span>                         .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
<span id="lnum264" style="color:#606060;"> 264:</span>                     )
<span id="lnum265" style="color:#606060;"> 265:</span>                     .addContainerGap(73, Short.MAX_VALUE))
<span id="lnum266" style="color:#606060;"> 266:</span>                 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
<span id="lnum267" style="color:#606060;"> 267:</span>                     .addGroup(jPanel2Layout.createSequentialGroup()
<span id="lnum268" style="color:#606060;"> 268:</span>                         .addGap(169)
<span id="lnum269" style="color:#606060;"> 269:</span>                         .addComponent(jButtonClose, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
<span id="lnum270" style="color:#606060;"> 270:</span>                         .addContainerGap(261, Short.MAX_VALUE)))
<span id="lnum271" style="color:#606060;"> 271:</span>                 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
<span id="lnum272" style="color:#606060;"> 272:</span>                     .addGroup(jPanel2Layout.createSequentialGroup()
<span id="lnum273" style="color:#606060;"> 273:</span>                         .addGap(128)
<span id="lnum274" style="color:#606060;"> 274:</span>                         .addComponent(jButtonReply, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
<span id="lnum275" style="color:#606060;"> 275:</span>                         .addContainerGap(251, Short.MAX_VALUE)))
<span id="lnum276" style="color:#606060;"> 276:</span>             );
<span id="lnum277" style="color:#606060;"> 277:</span>
<span id="lnum278" style="color:#606060;"> 278:</span>             jPanel2Layout.setVerticalGroup(
<span id="lnum279" style="color:#606060;"> 279:</span>                 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
<span id="lnum280" style="color:#606060;"> 280:</span>                 .addGroup(jPanel2Layout.createSequentialGroup()
<span id="lnum281" style="color:#606060;"> 281:</span>                     .addGap(32)
<span id="lnum282" style="color:#606060;"> 282:</span>                     .addComponent(jLabelMobileNum)
<span id="lnum283" style="color:#606060;"> 283:</span>                     .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
<span id="lnum284" style="color:#606060;"> 284:</span>                     .addComponent(false, jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
<span id="lnum285" style="color:#606060;"> 285:</span>                     .addContainerGap(64, Short.MAX_VALUE))
<span id="lnum286" style="color:#606060;"> 286:</span>                 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
<span id="lnum287" style="color:#606060;"> 287:</span>                     .addGroup(jPanel2Layout.createSequentialGroup()
<span id="lnum288" style="color:#606060;"> 288:</span>                         .addGap(28)
<span id="lnum289" style="color:#606060;"> 289:</span>                         .addComponent(jButtonClose, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
<span id="lnum290" style="color:#606060;"> 290:</span>                         .addContainerGap(300, Short.MAX_VALUE)))
<span id="lnum291" style="color:#606060;"> 291:</span>                 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
<span id="lnum292" style="color:#606060;"> 292:</span>                     .addGroup(jPanel2Layout.createSequentialGroup()
<span id="lnum293" style="color:#606060;"> 293:</span>                         .addGap(168)
<span id="lnum294" style="color:#606060;"> 294:</span>                         .addComponent(jButtonReply, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
<span id="lnum295" style="color:#606060;"> 295:</span>                         .addContainerGap(146, Short.MAX_VALUE)))
<span id="lnum296" style="color:#606060;"> 296:</span>             );
<span id="lnum297" style="color:#606060;"> 297:</span>
<span id="lnum298" style="color:#606060;"> 298:</span>             <span style="color:#008000;">// End phone/message panel</span>
<span id="lnum299" style="color:#606060;"> 299:</span>
<span id="lnum300" style="color:#606060;"> 300:</span>             <span style="color:#008000;">// Setup final main paenl</span>
<span id="lnum301" style="color:#606060;"> 301:</span>             mainPanel.add(jPanelAll, BorderLayout.WEST);
<span id="lnum302" style="color:#606060;"> 302:</span>             mainPanel.setDoubleBuffered(false);
<span id="lnum303" style="color:#606060;"> 303:</span>             mainPanel.setOpaque(true);
<span id="lnum304" style="color:#606060;"> 304:</span>             <span style="color:#0000ff;">this</span>.add(mainPanel, BorderLayout.CENTER);
<span id="lnum305" style="color:#606060;"> 305:</span>
<span id="lnum306" style="color:#606060;"> 306:</span>             <span style="color:#0000ff;">this</span>.setAlwaysOnTop(true);
<span id="lnum307" style="color:#606060;"> 307:</span>             <span style="color:#0000ff;">this</span>.setSize(216, 234);
<span id="lnum308" style="color:#606060;"> 308:</span>             <span style="color:#0000ff;">this</span>.setLocationRelativeTo(null);
<span id="lnum309" style="color:#606060;"> 309:</span>             com.sun.awt.AWTUtilities.setWindowOpaque(<span style="color:#0000ff;">this</span>, false);
<span id="lnum310" style="color:#606060;"> 310:</span>
<span id="lnum311" style="color:#606060;"> 311:</span>             <span style="color:#008000;">// Watch mouse movements and clicks to allow dragging of window</span>
<span id="lnum312" style="color:#606060;"> 312:</span>             addMouseListener(<span style="color:#0000ff;">new</span> MouseAdapter()
<span id="lnum313" style="color:#606060;"> 313:</span>             {
<span id="lnum314" style="color:#606060;"> 314:</span>                 <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mousePressed(MouseEvent e)
<span id="lnum315" style="color:#606060;"> 315:</span>                 {
<span id="lnum316" style="color:#606060;"> 316:</span>                     <span style="color:#008000;">// Check for double-click</span>
<span id="lnum317" style="color:#606060;"> 317:</span>                     <span style="color:#0000ff;">if</span> (e.getClickCount() &gt;= 2) {
<span id="lnum318" style="color:#606060;"> 318:</span>                         <span style="color:#008000;">// Open the website to let them reply</span>
<span id="lnum319" style="color:#606060;"> 319:</span>                         openUri(getReplyUrl());
<span id="lnum320" style="color:#606060;"> 320:</span>                         setVisible(false);
<span id="lnum321" style="color:#606060;"> 321:</span>                     } <span style="color:#0000ff;">else</span> {
<span id="lnum322" style="color:#606060;"> 322:</span>                         <span style="color:#008000;">// Do drag operation</span>
<span id="lnum323" style="color:#606060;"> 323:</span>                         X=e.getX();
<span id="lnum324" style="color:#606060;"> 324:</span>                         Y=e.getY();
<span id="lnum325" style="color:#606060;"> 325:</span>                     }
<span id="lnum326" style="color:#606060;"> 326:</span>                 }
<span id="lnum327" style="color:#606060;"> 327:</span>
<span id="lnum328" style="color:#606060;"> 328:</span>             });
<span id="lnum329" style="color:#606060;"> 329:</span>
<span id="lnum330" style="color:#606060;"> 330:</span>             addMouseMotionListener(<span style="color:#0000ff;">new</span> MouseMotionAdapter()
<span id="lnum331" style="color:#606060;"> 331:</span>             {
<span id="lnum332" style="color:#606060;"> 332:</span>                 <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mouseDragged(MouseEvent e)
<span id="lnum333" style="color:#606060;"> 333:</span>                 {
<span id="lnum334" style="color:#606060;"> 334:</span>                     setLocation(getLocation().x+(e.getX()-X),getLocation().y+(e.getY()-Y));
<span id="lnum335" style="color:#606060;"> 335:</span>                 }
<span id="lnum336" style="color:#606060;"> 336:</span>             });
<span id="lnum337" style="color:#606060;"> 337:</span>
<span id="lnum338" style="color:#606060;"> 338:</span>         } <span style="color:#0000ff;">catch</span> (IOException e) {
<span id="lnum339" style="color:#606060;"> 339:</span>             e.printStackTrace();
<span id="lnum340" style="color:#606060;"> 340:</span>         }
<span id="lnum341" style="color:#606060;"> 341:</span>     }
<span id="lnum342" style="color:#606060;"> 342:</span>
<span id="lnum343" style="color:#606060;"> 343:</span>     @Override
<span id="lnum344" style="color:#606060;"> 344:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> setVisible(<span style="color:#0000ff;">boolean</span> b) {
<span id="lnum345" style="color:#606060;"> 345:</span>
<span id="lnum346" style="color:#606060;"> 346:</span>         <span style="color:#008000;">// Handle fading in or fading out</span>
<span id="lnum347" style="color:#606060;"> 347:</span>
<span id="lnum348" style="color:#606060;"> 348:</span>         <span style="color:#008000;">// If setvisible is true</span>
<span id="lnum349" style="color:#606060;"> 349:</span>         <span style="color:#0000ff;">if</span> (b) {
<span id="lnum350" style="color:#606060;"> 350:</span>
<span id="lnum351" style="color:#606060;"> 351:</span>             <span style="color:#008000;">// See if we need to fade in</span>
<span id="lnum352" style="color:#606060;"> 352:</span>             <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.toFade) {
<span id="lnum353" style="color:#606060;"> 353:</span>                 <span style="color:#008000;">// mark the popup with 0% opacity</span>
<span id="lnum354" style="color:#606060;"> 354:</span>                 <span style="color:#0000ff;">this</span>.currOpacity = 0;
<span id="lnum355" style="color:#606060;"> 355:</span>                 com.sun.awt.AWTUtilities.setWindowOpacity(<span style="color:#0000ff;">this</span>, 0.0f);
<span id="lnum356" style="color:#606060;"> 356:</span>             }
<span id="lnum357" style="color:#606060;"> 357:</span>
<span id="lnum358" style="color:#606060;"> 358:</span>             <span style="color:#0000ff;">super</span>.setVisible(b);
<span id="lnum359" style="color:#606060;"> 359:</span>
<span id="lnum360" style="color:#606060;"> 360:</span>             <span style="color:#0000ff;">final</span> JDialog popupWindow = <span style="color:#0000ff;">this</span>;
<span id="lnum361" style="color:#606060;"> 361:</span>
<span id="lnum362" style="color:#606060;"> 362:</span>             <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.toFade) {
<span id="lnum363" style="color:#606060;"> 363:</span>                 <span style="color:#008000;">// start fading in</span>
<span id="lnum364" style="color:#606060;"> 364:</span>                 <span style="color:#0000ff;">this</span>.fadeInTimer = <span style="color:#0000ff;">new</span> Timer(50, <span style="color:#0000ff;">new</span> ActionListener() {
<span id="lnum365" style="color:#606060;"> 365:</span>                     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> actionPerformed(ActionEvent e) {
<span id="lnum366" style="color:#606060;"> 366:</span>                         currOpacity += 10;
<span id="lnum367" style="color:#606060;"> 367:</span>                         <span style="color:#0000ff;">if</span> (currOpacity &lt;= 100) {
<span id="lnum368" style="color:#606060;"> 368:</span>                             com.sun.awt.AWTUtilities.setWindowOpacity(popupWindow,
<span id="lnum369" style="color:#606060;"> 369:</span>                                     currOpacity / 100.0f);
<span id="lnum370" style="color:#606060;"> 370:</span>                             <span style="color:#008000;">// workaround bug 6670649 - should call</span>
<span id="lnum371" style="color:#606060;"> 371:</span>                             <span style="color:#008000;">// popupWindow.repaint() but that will not repaint the</span>
<span id="lnum372" style="color:#606060;"> 372:</span>                             <span style="color:#008000;">// panel</span>
<span id="lnum373" style="color:#606060;"> 373:</span>                             popupWindow.getContentPane().repaint();
<span id="lnum374" style="color:#606060;"> 374:</span>                         } <span style="color:#0000ff;">else</span> {
<span id="lnum375" style="color:#606060;"> 375:</span>                             currOpacity = 100;
<span id="lnum376" style="color:#606060;"> 376:</span>                             fadeInTimer.stop();
<span id="lnum377" style="color:#606060;"> 377:</span>                         }
<span id="lnum378" style="color:#606060;"> 378:</span>                     }
<span id="lnum379" style="color:#606060;"> 379:</span>                 });
<span id="lnum380" style="color:#606060;"> 380:</span>                 <span style="color:#0000ff;">this</span>.fadeInTimer.setRepeats(true);
<span id="lnum381" style="color:#606060;"> 381:</span>                 <span style="color:#0000ff;">this</span>.fadeInTimer.start();
<span id="lnum382" style="color:#606060;"> 382:</span>             }
<span id="lnum383" style="color:#606060;"> 383:</span>
<span id="lnum384" style="color:#606060;"> 384:</span>         } <span style="color:#0000ff;">else</span> {
<span id="lnum385" style="color:#606060;"> 385:</span>
<span id="lnum386" style="color:#606060;"> 386:</span>             <span style="color:#008000;">// If setvisible is false</span>
<span id="lnum387" style="color:#606060;"> 387:</span>
<span id="lnum388" style="color:#606060;"> 388:</span>             <span style="color:#008000;">// Handle fading out, if they want a fade</span>
<span id="lnum389" style="color:#606060;"> 389:</span>             <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.toFade) {
<span id="lnum390" style="color:#606060;"> 390:</span>
<span id="lnum391" style="color:#606060;"> 391:</span>                 <span style="color:#008000;">// cancel fade-in if it's running.</span>
<span id="lnum392" style="color:#606060;"> 392:</span>                 <span style="color:#0000ff;">if</span> (<span style="color:#0000ff;">this</span>.fadeInTimer.isRunning())
<span id="lnum393" style="color:#606060;"> 393:</span>                     <span style="color:#0000ff;">this</span>.fadeInTimer.stop();
<span id="lnum394" style="color:#606060;"> 394:</span>
<span id="lnum395" style="color:#606060;"> 395:</span>                 <span style="color:#0000ff;">final</span> Bubble popupWindow = <span style="color:#0000ff;">this</span>;
<span id="lnum396" style="color:#606060;"> 396:</span>
<span id="lnum397" style="color:#606060;"> 397:</span>                 <span style="color:#008000;">// start fading out</span>
<span id="lnum398" style="color:#606060;"> 398:</span>                 <span style="color:#0000ff;">this</span>.fadeOutTimer = <span style="color:#0000ff;">new</span> Timer(50, <span style="color:#0000ff;">new</span> ActionListener() {
<span id="lnum399" style="color:#606060;"> 399:</span>                     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> actionPerformed(ActionEvent e) {
<span id="lnum400" style="color:#606060;"> 400:</span>                         currOpacity -= 10;
<span id="lnum401" style="color:#606060;"> 401:</span>                         <span style="color:#0000ff;">if</span> (currOpacity &gt;= 0) {
<span id="lnum402" style="color:#606060;"> 402:</span>                             com.sun.awt.AWTUtilities.setWindowOpacity(popupWindow,
<span id="lnum403" style="color:#606060;"> 403:</span>                                     currOpacity / 100.0f);
<span id="lnum404" style="color:#606060;"> 404:</span>                             <span style="color:#008000;">// workaround bug 6670649 - should call</span>
<span id="lnum405" style="color:#606060;"> 405:</span>                             <span style="color:#008000;">// popupWindow.repaint() but that will not repaint the</span>
<span id="lnum406" style="color:#606060;"> 406:</span>                             <span style="color:#008000;">// panel</span>
<span id="lnum407" style="color:#606060;"> 407:</span>                             popupWindow.getContentPane().repaint();
<span id="lnum408" style="color:#606060;"> 408:</span>                         } <span style="color:#0000ff;">else</span> {
<span id="lnum409" style="color:#606060;"> 409:</span>                             fadeOutTimer.stop();
<span id="lnum410" style="color:#606060;"> 410:</span>                             popupWindow.setToFade(false);
<span id="lnum411" style="color:#606060;"> 411:</span>                             popupWindow.setVisible(false);
<span id="lnum412" style="color:#606060;"> 412:</span>                             currOpacity = 0;
<span id="lnum413" style="color:#606060;"> 413:</span>                         }
<span id="lnum414" style="color:#606060;"> 414:</span>                     }
<span id="lnum415" style="color:#606060;"> 415:</span>                 });
<span id="lnum416" style="color:#606060;"> 416:</span>                 <span style="color:#0000ff;">this</span>.fadeOutTimer.setRepeats(true);
<span id="lnum417" style="color:#606060;"> 417:</span>                 <span style="color:#0000ff;">this</span>.fadeOutTimer.start();
<span id="lnum418" style="color:#606060;"> 418:</span>
<span id="lnum419" style="color:#606060;"> 419:</span>             } <span style="color:#0000ff;">else</span> {
<span id="lnum420" style="color:#606060;"> 420:</span>
<span id="lnum421" style="color:#606060;"> 421:</span>                 <span style="color:#008000;">// setVisible is being set to false and we're not in fadeout mode,</span>
<span id="lnum422" style="color:#606060;"> 422:</span>                 <span style="color:#008000;">// so let's let the super handle</span>
<span id="lnum423" style="color:#606060;"> 423:</span>                 <span style="color:#008000;">// it cuz we don't want to interfere if there's no fading going on</span>
<span id="lnum424" style="color:#606060;"> 424:</span>                 windowClose();
<span id="lnum425" style="color:#606060;"> 425:</span>                 <span style="color:#0000ff;">super</span>.setVisible(false);
<span id="lnum426" style="color:#606060;"> 426:</span>                 <span style="color:#0000ff;">this</span>.removeAll();
<span id="lnum427" style="color:#606060;"> 427:</span>                 <span style="color:#0000ff;">this</span>.dispose();
<span id="lnum428" style="color:#606060;"> 428:</span>
<span id="lnum429" style="color:#606060;"> 429:</span>             }
<span id="lnum430" style="color:#606060;"> 430:</span>         }
<span id="lnum431" style="color:#606060;"> 431:</span>     }
<span id="lnum432" style="color:#606060;"> 432:</span>
<span id="lnum433" style="color:#606060;"> 433:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> openUri(String url) {
<span id="lnum434" style="color:#606060;"> 434:</span>
<span id="lnum435" style="color:#606060;"> 435:</span>         <span style="color:#0000ff;">if</span>( !java.awt.Desktop.isDesktopSupported() ) {
<span id="lnum436" style="color:#606060;"> 436:</span>
<span id="lnum437" style="color:#606060;"> 437:</span>             System.err.println( <span style="color:#006080;">"Desktop is not supported (fatal)"</span> );
<span id="lnum438" style="color:#606060;"> 438:</span>             <span style="color:#0000ff;">return</span>;
<span id="lnum439" style="color:#606060;"> 439:</span>         }
<span id="lnum440" style="color:#606060;"> 440:</span>
<span id="lnum441" style="color:#606060;"> 441:</span>         java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
<span id="lnum442" style="color:#606060;"> 442:</span>
<span id="lnum443" style="color:#606060;"> 443:</span>         <span style="color:#0000ff;">if</span>( !desktop.isSupported( java.awt.Desktop.Action.BROWSE ) ) {
<span id="lnum444" style="color:#606060;"> 444:</span>
<span id="lnum445" style="color:#606060;"> 445:</span>             System.err.println( <span style="color:#006080;">"Desktop doesn't support the browse action (fatal)"</span> );
<span id="lnum446" style="color:#606060;"> 446:</span>             <span style="color:#0000ff;">return</span>;
<span id="lnum447" style="color:#606060;"> 447:</span>         }
<span id="lnum448" style="color:#606060;"> 448:</span>
<span id="lnum449" style="color:#606060;"> 449:</span>         <span style="color:#0000ff;">try</span> {
<span id="lnum450" style="color:#606060;"> 450:</span>
<span id="lnum451" style="color:#606060;"> 451:</span>             java.net.URI uri = <span style="color:#0000ff;">new</span> java.net.URI( url );
<span id="lnum452" style="color:#606060;"> 452:</span>             desktop.browse( uri );
<span id="lnum453" style="color:#606060;"> 453:</span>         }
<span id="lnum454" style="color:#606060;"> 454:</span>         <span style="color:#0000ff;">catch</span> ( Exception e ) {
<span id="lnum455" style="color:#606060;"> 455:</span>
<span id="lnum456" style="color:#606060;"> 456:</span>             System.err.println( e.getMessage() );
<span id="lnum457" style="color:#606060;"> 457:</span>         }
<span id="lnum458" style="color:#606060;"> 458:</span>
<span id="lnum459" style="color:#606060;"> 459:</span>     }
<span id="lnum460" style="color:#606060;"> 460:</span>
<span id="lnum461" style="color:#606060;"> 461:</span> }
<span id="lnum462" style="color:#606060;"> 462:</span>
<span id="lnum463" style="color:#606060;"> 463:</span> <span style="color:#0000ff;">class</span> MoveMouseListener <span style="color:#0000ff;">implements</span> MouseListener, MouseMotionListener {
<span id="lnum464" style="color:#606060;"> 464:</span>     JComponent target;
<span id="lnum465" style="color:#606060;"> 465:</span>     Point start_drag;
<span id="lnum466" style="color:#606060;"> 466:</span>     Point start_loc;
<span id="lnum467" style="color:#606060;"> 467:</span>
<span id="lnum468" style="color:#606060;"> 468:</span>     <span style="color:#0000ff;">public</span> MoveMouseListener(JComponent target) {
<span id="lnum469" style="color:#606060;"> 469:</span>         <span style="color:#0000ff;">this</span>.target = target;
<span id="lnum470" style="color:#606060;"> 470:</span>     }
<span id="lnum471" style="color:#606060;"> 471:</span>
<span id="lnum472" style="color:#606060;"> 472:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> JFrame getFrame(Container target) {
<span id="lnum473" style="color:#606060;"> 473:</span>         <span style="color:#0000ff;">if</span> (target <span style="color:#0000ff;">instanceof</span> JFrame) {
<span id="lnum474" style="color:#606060;"> 474:</span>             <span style="color:#0000ff;">return</span> (JFrame) target;
<span id="lnum475" style="color:#606060;"> 475:</span>         }
<span id="lnum476" style="color:#606060;"> 476:</span>         <span style="color:#0000ff;">return</span> getFrame(target.getParent());
<span id="lnum477" style="color:#606060;"> 477:</span>     }
<span id="lnum478" style="color:#606060;"> 478:</span>
<span id="lnum479" style="color:#606060;"> 479:</span>     Point getScreenLocation(MouseEvent e) {
<span id="lnum480" style="color:#606060;"> 480:</span>         Point cursor = e.getPoint();
<span id="lnum481" style="color:#606060;"> 481:</span>         Point target_location = <span style="color:#0000ff;">this</span>.target.getLocationOnScreen();
<span id="lnum482" style="color:#606060;"> 482:</span>         <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> Point((<span style="color:#0000ff;">int</span>) (target_location.getX() + cursor.getX()),
<span id="lnum483" style="color:#606060;"> 483:</span>                 (<span style="color:#0000ff;">int</span>) (target_location.getY() + cursor.getY()));
<span id="lnum484" style="color:#606060;"> 484:</span>     }
<span id="lnum485" style="color:#606060;"> 485:</span>
<span id="lnum486" style="color:#606060;"> 486:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mouseClicked(MouseEvent e) {
<span id="lnum487" style="color:#606060;"> 487:</span>     }
<span id="lnum488" style="color:#606060;"> 488:</span>
<span id="lnum489" style="color:#606060;"> 489:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mouseEntered(MouseEvent e) {
<span id="lnum490" style="color:#606060;"> 490:</span>     }
<span id="lnum491" style="color:#606060;"> 491:</span>
<span id="lnum492" style="color:#606060;"> 492:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mouseExited(MouseEvent e) {
<span id="lnum493" style="color:#606060;"> 493:</span>     }
<span id="lnum494" style="color:#606060;"> 494:</span>
<span id="lnum495" style="color:#606060;"> 495:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mousePressed(MouseEvent e) {
<span id="lnum496" style="color:#606060;"> 496:</span>         <span style="color:#0000ff;">this</span>.start_drag = <span style="color:#0000ff;">this</span>.getScreenLocation(e);
<span id="lnum497" style="color:#606060;"> 497:</span>         <span style="color:#0000ff;">this</span>.start_loc = <span style="color:#0000ff;">this</span>.getFrame(<span style="color:#0000ff;">this</span>.target).getLocation();
<span id="lnum498" style="color:#606060;"> 498:</span>     }
<span id="lnum499" style="color:#606060;"> 499:</span>
<span id="lnum500" style="color:#606060;"> 500:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mouseReleased(MouseEvent e) {
<span id="lnum501" style="color:#606060;"> 501:</span>     }
<span id="lnum502" style="color:#606060;"> 502:</span>
<span id="lnum503" style="color:#606060;"> 503:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mouseDragged(MouseEvent e) {
<span id="lnum504" style="color:#606060;"> 504:</span>         Point current = <span style="color:#0000ff;">this</span>.getScreenLocation(e);
<span id="lnum505" style="color:#606060;"> 505:</span>         Point offset = <span style="color:#0000ff;">new</span> Point((<span style="color:#0000ff;">int</span>) current.getX() - (<span style="color:#0000ff;">int</span>) start_drag.getX(),
<span id="lnum506" style="color:#606060;"> 506:</span>                 (<span style="color:#0000ff;">int</span>) current.getY() - (<span style="color:#0000ff;">int</span>) start_drag.getY());
<span id="lnum507" style="color:#606060;"> 507:</span>         JFrame frame = <span style="color:#0000ff;">this</span>.getFrame(target);
<span id="lnum508" style="color:#606060;"> 508:</span>         Point new_location = <span style="color:#0000ff;">new</span> Point(
<span id="lnum509" style="color:#606060;"> 509:</span>                 (<span style="color:#0000ff;">int</span>) (<span style="color:#0000ff;">this</span>.start_loc.getX() + offset.getX()), (<span style="color:#0000ff;">int</span>) (<span style="color:#0000ff;">this</span>.start_loc
<span id="lnum510" style="color:#606060;"> 510:</span>                         .getY() + offset.getY()));
<span id="lnum511" style="color:#606060;"> 511:</span>         frame.setLocation(new_location);
<span id="lnum512" style="color:#606060;"> 512:</span>     }
<span id="lnum513" style="color:#606060;"> 513:</span>
<span id="lnum514" style="color:#606060;"> 514:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> mouseMoved(MouseEvent e) {
<span id="lnum515" style="color:#606060;"> 515:</span>     }
<span id="lnum516" style="color:#606060;"> 516:</span> }
<span id="lnum517" style="color:#606060;"> 517:</span>
<span id="lnum518" style="color:#606060;"> 518:</span> <span style="color:#0000ff;">class</span> StringUtil {
<span id="lnum519" style="color:#606060;"> 519:</span>
<span id="lnum520" style="color:#606060;"> 520:</span>     <span style="color:#008000;">//private static final Logger logger = LoggerFactory.getLogger(StringUtil.class);</span>
<span id="lnum521" style="color:#606060;"> 521:</span>
<span id="lnum522" style="color:#606060;"> 522:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">final</span> String EMPTY_STRING = <span style="color:#006080;">""</span>;
<span id="lnum523" style="color:#606060;"> 523:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">final</span> <span style="color:#0000ff;">int</span> MAX_MOBILE_NUMBER_DIGITS = 16; <span style="color:#008000;">// Finland being the longest we could find 99500-1-202-444-1212, plus a buffer...</span>
<span id="lnum524" style="color:#606060;"> 524:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">final</span> List&lt;Character&gt; VALID_NUMBERS;
<span id="lnum525" style="color:#606060;"> 525:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">final</span> List&lt;Character&gt; VALID_SPECIAL_CHARACTERS;
<span id="lnum526" style="color:#606060;"> 526:</span>
<span id="lnum527" style="color:#606060;"> 527:</span>     <span style="color:#0000ff;">static</span> {
<span id="lnum528" style="color:#606060;"> 528:</span>         VALID_NUMBERS = Arrays.asList(<span style="color:#0000ff;">new</span> Character[] { <span style="color:#006080;">'0'</span>, <span style="color:#006080;">'1'</span>, <span style="color:#006080;">'2'</span>, <span style="color:#006080;">'3'</span>, <span style="color:#006080;">'4'</span>, <span style="color:#006080;">'5'</span>, <span style="color:#006080;">'6'</span>, <span style="color:#006080;">'7'</span>, <span style="color:#006080;">'8'</span>, <span style="color:#006080;">'9'</span> });
<span id="lnum529" style="color:#606060;"> 529:</span>         VALID_SPECIAL_CHARACTERS = Arrays.asList(<span style="color:#0000ff;">new</span> Character[]{<span style="color:#006080;">'!'</span>, <span style="color:#006080;">'@'</span>, <span style="color:#006080;">'#'</span>, <span style="color:#006080;">'$'</span>, <span style="color:#006080;">'%'</span>, <span style="color:#006080;">'^'</span>, <span style="color:#006080;">'&amp;'</span>, <span style="color:#006080;">'*'</span>, <span style="color:#006080;">'('</span>, <span style="color:#006080;">')'</span>, <span style="color:#006080;">'`'</span>, <span style="color:#006080;">'['</span>, <span style="color:#006080;">']'</span>, <span style="color:#006080;">'\\', '</span>{<span style="color:#006080;">', '</span>}<span style="color:#006080;">', '</span>|<span style="color:#006080;">', '</span>&lt;<span style="color:#006080;">', '</span>&gt;<span style="color:#006080;">', '</span>?<span style="color:#006080;">', '</span>,<span style="color:#006080;">', '</span>.<span style="color:#006080;">', '</span>/<span style="color:#006080;">', '</span>:<span style="color:#006080;">', '</span>;<span style="color:#006080;">', '</span>\<span style="color:#006080;">''</span>, <span style="color:#006080;">'"'</span>, <span style="color:#006080;">'+'</span>, <span style="color:#006080;">'~'</span>, <span style="color:#006080;">'*'</span>, <span style="color:#006080;">'.'</span>});
<span id="lnum530" style="color:#606060;"> 530:</span>     }
<span id="lnum531" style="color:#606060;"> 531:</span>
<span id="lnum532" style="color:#606060;"> 532:</span>     <span style="color:#008000;">/**</span>
<span id="lnum533" style="color:#606060;"> 533:</span> <span style="color:#008000;"> * Strips all characters that are not numbers (0 - 9) and returns a new</span>
<span id="lnum534" style="color:#606060;"> 534:</span> <span style="color:#008000;"> * string. Returns and empty string if the mobile number is null or empty.</span>
<span id="lnum535" style="color:#606060;"> 535:</span> <span style="color:#008000;"> * </span>
<span id="lnum536" style="color:#606060;"> 536:</span> <span style="color:#008000;"> * @param mobileNumber - mobile number string to parse</span>
<span id="lnum537" style="color:#606060;"> 537:</span> <span style="color:#008000;"> * @return String - parsed mobile number</span>
<span id="lnum538" style="color:#606060;"> 538:</span> <span style="color:#008000;"> */</span>
<span id="lnum539" style="color:#606060;"> 539:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String safeCleanMobileNumber(String mobileNumber) {
<span id="lnum540" style="color:#606060;"> 540:</span>
<span id="lnum541" style="color:#606060;"> 541:</span>         <span style="color:#008000;">//logger.debug("getting clean for " + mobileNumber);</span>
<span id="lnum542" style="color:#606060;"> 542:</span>
<span id="lnum543" style="color:#606060;"> 543:</span>         <span style="color:#0000ff;">if</span> (isNullOrEmpty(mobileNumber)) {
<span id="lnum544" style="color:#606060;"> 544:</span>             <span style="color:#008000;">//logger.debug("was nullOrEmpty ");</span>
<span id="lnum545" style="color:#606060;"> 545:</span>             <span style="color:#0000ff;">return</span> null;
<span id="lnum546" style="color:#606060;"> 546:</span>         }
<span id="lnum547" style="color:#606060;"> 547:</span>
<span id="lnum548" style="color:#606060;"> 548:</span>         StringBuilder cleanMobileNumber = <span style="color:#0000ff;">new</span> StringBuilder();
<span id="lnum549" style="color:#606060;"> 549:</span>         <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = 0; i &lt; mobileNumber.length(); i++) {
<span id="lnum550" style="color:#606060;"> 550:</span>             <span style="color:#0000ff;">if</span> (VALID_NUMBERS.contains(mobileNumber.charAt(i))) {
<span id="lnum551" style="color:#606060;"> 551:</span>                 cleanMobileNumber.append(mobileNumber.charAt(i));
<span id="lnum552" style="color:#606060;"> 552:</span>             }
<span id="lnum553" style="color:#606060;"> 553:</span>         }
<span id="lnum554" style="color:#606060;"> 554:</span>
<span id="lnum555" style="color:#606060;"> 555:</span>         <span style="color:#008000;">// remove the first (1) at the beginning of the to match default us</span>
<span id="lnum556" style="color:#606060;"> 556:</span>         <span style="color:#008000;">// numbers</span>
<span id="lnum557" style="color:#606060;"> 557:</span>         <span style="color:#008000;">// 10 digits</span>
<span id="lnum558" style="color:#606060;"> 558:</span>         <span style="color:#0000ff;">if</span> (cleanMobileNumber.length() &gt; 10 &amp;&amp; startsWith(cleanMobileNumber.toString(), <span style="color:#006080;">"1"</span>)) {
<span id="lnum559" style="color:#606060;"> 559:</span>             <span style="color:#008000;">//logger.debug("clean 1 " + cleanMobileNumber.substring(1));</span>
<span id="lnum560" style="color:#606060;"> 560:</span>             <span style="color:#0000ff;">return</span> cleanMobileNumber.substring(1);
<span id="lnum561" style="color:#606060;"> 561:</span>         }
<span id="lnum562" style="color:#606060;"> 562:</span>         <span style="color:#0000ff;">if</span> (cleanMobileNumber.length() &gt; 10 &amp;&amp; startsWith(cleanMobileNumber.toString(), <span style="color:#006080;">"+1"</span>)) {
<span id="lnum563" style="color:#606060;"> 563:</span>             <span style="color:#008000;">//logger.debug("clean 2 " + cleanMobileNumber.substring(1));</span>
<span id="lnum564" style="color:#606060;"> 564:</span>             <span style="color:#0000ff;">return</span> cleanMobileNumber.substring(2);
<span id="lnum565" style="color:#606060;"> 565:</span>         }
<span id="lnum566" style="color:#606060;"> 566:</span>
<span id="lnum567" style="color:#606060;"> 567:</span>         <span style="color:#008000;">//logger.debug("clean " + cleanMobileNumber.toString());</span>
<span id="lnum568" style="color:#606060;"> 568:</span>         <span style="color:#0000ff;">return</span> cleanMobileNumber.toString();
<span id="lnum569" style="color:#606060;"> 569:</span>     }
<span id="lnum570" style="color:#606060;"> 570:</span>
<span id="lnum571" style="color:#606060;"> 571:</span>     <span style="color:#008000;">/**</span>
<span id="lnum572" style="color:#606060;"> 572:</span> <span style="color:#008000;"> * Same as safeCleanMobileNumber except for devices</span>
<span id="lnum573" style="color:#606060;"> 573:</span> <span style="color:#008000;"> * in which case the device number is removed first</span>
<span id="lnum574" style="color:#606060;"> 574:</span> <span style="color:#008000;"> *</span>
<span id="lnum575" style="color:#606060;"> 575:</span> <span style="color:#008000;"> * @param mobileNumber - mobile number string to parse</span>
<span id="lnum576" style="color:#606060;"> 576:</span> <span style="color:#008000;"> * @return String - parsed mobile number</span>
<span id="lnum577" style="color:#606060;"> 577:</span> <span style="color:#008000;"> */</span>
<span id="lnum578" style="color:#606060;"> 578:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String safeCleanMobileNumberRemoveDevice(String mobileNumber) {
<span id="lnum579" style="color:#606060;"> 579:</span>
<span id="lnum580" style="color:#606060;"> 580:</span>         <span style="color:#0000ff;">if</span> (startsWith(mobileNumber, <span style="color:#006080;">"device:/"</span>)) {
<span id="lnum581" style="color:#606060;"> 581:</span>
<span id="lnum582" style="color:#606060;"> 582:</span>             <span style="color:#0000ff;">int</span> index = mobileNumber.lastIndexOf(<span style="color:#006080;">'/'</span>);
<span id="lnum583" style="color:#606060;"> 583:</span>
<span id="lnum584" style="color:#606060;"> 584:</span>             <span style="color:#008000;">// If the last index of '/' is &gt; than the first</span>
<span id="lnum585" style="color:#606060;"> 585:</span>             <span style="color:#0000ff;">if</span> (index &gt; 7) {
<span id="lnum586" style="color:#606060;"> 586:</span>                 mobileNumber = mobileNumber.substring(0, index);
<span id="lnum587" style="color:#606060;"> 587:</span>             }
<span id="lnum588" style="color:#606060;"> 588:</span>         }
<span id="lnum589" style="color:#606060;"> 589:</span>
<span id="lnum590" style="color:#606060;"> 590:</span>         <span style="color:#0000ff;">return</span> safeCleanMobileNumber(mobileNumber);
<span id="lnum591" style="color:#606060;"> 591:</span>     }
<span id="lnum592" style="color:#606060;"> 592:</span>
<span id="lnum593" style="color:#606060;"> 593:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> isValidEmail(String email){
<span id="lnum594" style="color:#606060;"> 594:</span>         <span style="color:#008000;">// see http://www.mkyong.com/regular-expressions/how-to-validate-email-address-with-regular-expression/</span>
<span id="lnum595" style="color:#606060;"> 595:</span>         Pattern pattern ;
<span id="lnum596" style="color:#606060;"> 596:</span>         java.util.regex.Matcher matcher;
<span id="lnum597" style="color:#606060;"> 597:</span>         <span style="color:#0000ff;">final</span> String EMAIL_PATTERN = <span style="color:#006080;">"^[\\w\\-]+(\\.[\\w\\-]+)*@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"</span>;
<span id="lnum598" style="color:#606060;"> 598:</span>
<span id="lnum599" style="color:#606060;"> 599:</span>         pattern = Pattern.compile(EMAIL_PATTERN);
<span id="lnum600" style="color:#606060;"> 600:</span>         matcher = pattern.matcher(email);
<span id="lnum601" style="color:#606060;"> 601:</span>
<span id="lnum602" style="color:#606060;"> 602:</span>         <span style="color:#0000ff;">return</span> matcher.matches();
<span id="lnum603" style="color:#606060;"> 603:</span>     }
<span id="lnum604" style="color:#606060;"> 604:</span>
<span id="lnum605" style="color:#606060;"> 605:</span>
<span id="lnum606" style="color:#606060;"> 606:</span>     <span style="color:#008000;">/**</span>
<span id="lnum607" style="color:#606060;"> 607:</span> <span style="color:#008000;"> * The length is valid if it is between 3 and 6 or over</span>
<span id="lnum608" style="color:#606060;"> 608:</span> <span style="color:#008000;"> * 10 and up to and including 20</span>
<span id="lnum609" style="color:#606060;"> 609:</span> <span style="color:#008000;"> * 3-6 length means short codes</span>
<span id="lnum610" style="color:#606060;"> 610:</span> <span style="color:#008000;"> * 10 length 000-000-0000</span>
<span id="lnum611" style="color:#606060;"> 611:</span> <span style="color:#008000;"> * 10+ means international</span>
<span id="lnum612" style="color:#606060;"> 612:</span> <span style="color:#008000;"> *</span>
<span id="lnum613" style="color:#606060;"> 613:</span> <span style="color:#008000;"> * @param mobileNumber</span>
<span id="lnum614" style="color:#606060;"> 614:</span> <span style="color:#008000;"> * @return</span>
<span id="lnum615" style="color:#606060;"> 615:</span> <span style="color:#008000;"> */</span>
<span id="lnum616" style="color:#606060;"> 616:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> isValidLengthMobileNumber(String mobileNumber) {
<span id="lnum617" style="color:#606060;"> 617:</span>
<span id="lnum618" style="color:#606060;"> 618:</span>         <span style="color:#0000ff;">if</span> (isNullOrEmpty(mobileNumber))  {
<span id="lnum619" style="color:#606060;"> 619:</span>             <span style="color:#0000ff;">return</span> false;
<span id="lnum620" style="color:#606060;"> 620:</span>         }
<span id="lnum621" style="color:#606060;"> 621:</span>
<span id="lnum622" style="color:#606060;"> 622:</span>         <span style="color:#0000ff;">int</span> numberLength = mobileNumber.length();
<span id="lnum623" style="color:#606060;"> 623:</span>
<span id="lnum624" style="color:#606060;"> 624:</span>         <span style="color:#008000;">// Wrong if under 3 and between 7 and 9 digits long or longer than 20</span>
<span id="lnum625" style="color:#606060;"> 625:</span>         <span style="color:#0000ff;">if</span> (numberLength &lt; 3 || numberLength == 7 || numberLength == 8 || numberLength == 9 || numberLength &gt; MAX_MOBILE_NUMBER_DIGITS) {
<span id="lnum626" style="color:#606060;"> 626:</span>             <span style="color:#0000ff;">return</span> false;
<span id="lnum627" style="color:#606060;"> 627:</span>         }
<span id="lnum628" style="color:#606060;"> 628:</span>         <span style="color:#008000;">// Correct is 3 to 6 for short codes and 10 to 20 for long international</span>
<span id="lnum629" style="color:#606060;"> 629:</span>         <span style="color:#008000;">// numbers, including a buffer</span>
<span id="lnum630" style="color:#606060;"> 630:</span>         <span style="color:#0000ff;">return</span> true;
<span id="lnum631" style="color:#606060;"> 631:</span>     }
<span id="lnum632" style="color:#606060;"> 632:</span>
<span id="lnum633" style="color:#606060;"> 633:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> startsWith(String string1, String toFind) {
<span id="lnum634" style="color:#606060;"> 634:</span>         <span style="color:#0000ff;">if</span> (string1 == null &amp;&amp; toFind == null){
<span id="lnum635" style="color:#606060;"> 635:</span>             <span style="color:#008000;">// null contains null.</span>
<span id="lnum636" style="color:#606060;"> 636:</span>             <span style="color:#0000ff;">return</span> true;
<span id="lnum637" style="color:#606060;"> 637:</span>         } <span style="color:#0000ff;">else</span> <span style="color:#0000ff;">if</span> (string1 == null){
<span id="lnum638" style="color:#606060;"> 638:</span>             <span style="color:#0000ff;">return</span> false;
<span id="lnum639" style="color:#606060;"> 639:</span>         }
<span id="lnum640" style="color:#606060;"> 640:</span>
<span id="lnum641" style="color:#606060;"> 641:</span>         <span style="color:#0000ff;">if</span> (StringUtil.equalsIgnoreCase(string1, toFind)){
<span id="lnum642" style="color:#606060;"> 642:</span>             <span style="color:#0000ff;">return</span> true;
<span id="lnum643" style="color:#606060;"> 643:</span>         }
<span id="lnum644" style="color:#606060;"> 644:</span>
<span id="lnum645" style="color:#606060;"> 645:</span>         <span style="color:#0000ff;">return</span> string1.toLowerCase().startsWith(toFind.toLowerCase());
<span id="lnum646" style="color:#606060;"> 646:</span>     }
<span id="lnum647" style="color:#606060;"> 647:</span>
<span id="lnum648" style="color:#606060;"> 648:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> endsWith(String source, String toFind) {
<span id="lnum649" style="color:#606060;"> 649:</span>         <span style="color:#0000ff;">if</span> (source == null) {
<span id="lnum650" style="color:#606060;"> 650:</span>             <span style="color:#0000ff;">return</span> false;
<span id="lnum651" style="color:#606060;"> 651:</span>         }
<span id="lnum652" style="color:#606060;"> 652:</span>
<span id="lnum653" style="color:#606060;"> 653:</span>         <span style="color:#0000ff;">return</span> source.endsWith(toFind);
<span id="lnum654" style="color:#606060;"> 654:</span>     }
<span id="lnum655" style="color:#606060;"> 655:</span>
<span id="lnum656" style="color:#606060;"> 656:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String defaultValue(String string, String defaultValue) {
<span id="lnum657" style="color:#606060;"> 657:</span>         <span style="color:#0000ff;">if</span> (StringUtil.isNullOrEmpty(string)){
<span id="lnum658" style="color:#606060;"> 658:</span>             <span style="color:#0000ff;">return</span> defaultValue;
<span id="lnum659" style="color:#606060;"> 659:</span>         }
<span id="lnum660" style="color:#606060;"> 660:</span>         <span style="color:#0000ff;">return</span> string;
<span id="lnum661" style="color:#606060;"> 661:</span>     }
<span id="lnum662" style="color:#606060;"> 662:</span>
<span id="lnum663" style="color:#606060;"> 663:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">final</span> <span style="color:#0000ff;">class</span> Schema {
<span id="lnum664" style="color:#606060;"> 664:</span>
<span id="lnum665" style="color:#606060;"> 665:</span>         <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">final</span> String TEL = <span style="color:#006080;">"tel"</span>;
<span id="lnum666" style="color:#606060;"> 666:</span>     }
<span id="lnum667" style="color:#606060;"> 667:</span>
<span id="lnum668" style="color:#606060;"> 668:</span>     <span style="color:#008000;">/**</span>
<span id="lnum669" style="color:#606060;"> 669:</span> <span style="color:#008000;"> * Takes a string representing the display name and returns and array with</span>
<span id="lnum670" style="color:#606060;"> 670:</span> <span style="color:#008000;"> * first name and last name.</span>
<span id="lnum671" style="color:#606060;"> 671:</span> <span style="color:#008000;"> * </span>
<span id="lnum672" style="color:#606060;"> 672:</span> <span style="color:#008000;"> * Returns null if null or empty input</span>
<span id="lnum673" style="color:#606060;"> 673:</span> <span style="color:#008000;"> * </span>
<span id="lnum674" style="color:#606060;"> 674:</span> <span style="color:#008000;"> * @param displayName</span>
<span id="lnum675" style="color:#606060;"> 675:</span> <span style="color:#008000;"> * @return String[]</span>
<span id="lnum676" style="color:#606060;"> 676:</span> <span style="color:#008000;"> */</span>
<span id="lnum677" style="color:#606060;"> 677:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String[] splitDisplayName(String displayName) {
<span id="lnum678" style="color:#606060;"> 678:</span>         <span style="color:#0000ff;">if</span> (displayName == null || displayName.length() &lt; 1) {
<span id="lnum679" style="color:#606060;"> 679:</span>             <span style="color:#0000ff;">return</span> null;
<span id="lnum680" style="color:#606060;"> 680:</span>         }
<span id="lnum681" style="color:#606060;"> 681:</span>
<span id="lnum682" style="color:#606060;"> 682:</span>         String[] names = displayName.split(<span style="color:#006080;">" "</span>);
<span id="lnum683" style="color:#606060;"> 683:</span>
<span id="lnum684" style="color:#606060;"> 684:</span>         <span style="color:#0000ff;">return</span> names;
<span id="lnum685" style="color:#606060;"> 685:</span>     }
<span id="lnum686" style="color:#606060;"> 686:</span>
<span id="lnum687" style="color:#606060;"> 687:</span>     <span style="color:#008000;">/**</span>
<span id="lnum688" style="color:#606060;"> 688:</span> <span style="color:#008000;"> * Takes a string representing a list of mobile numbers as</span>
<span id="lnum689" style="color:#606060;"> 689:</span> <span style="color:#008000;"> * 5555551212, 5556667878 or</span>
<span id="lnum690" style="color:#606060;"> 690:</span> <span style="color:#008000;"> * 5555551212; 5556667878</span>
<span id="lnum691" style="color:#606060;"> 691:</span> <span style="color:#008000;"> *</span>
<span id="lnum692" style="color:#606060;"> 692:</span> <span style="color:#008000;"> * Returns null if null or empty input</span>
<span id="lnum693" style="color:#606060;"> 693:</span> <span style="color:#008000;"> *</span>
<span id="lnum694" style="color:#606060;"> 694:</span> <span style="color:#008000;"> * @param sourceNumber</span>
<span id="lnum695" style="color:#606060;"> 695:</span> <span style="color:#008000;"> * @return List&lt;String&gt;</span>
<span id="lnum696" style="color:#606060;"> 696:</span> <span style="color:#008000;"> */</span>
<span id="lnum697" style="color:#606060;"> 697:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> List&lt;String&gt; splitMobileNumbers(String sourceNumber) {
<span id="lnum698" style="color:#606060;"> 698:</span>
<span id="lnum699" style="color:#606060;"> 699:</span>         ArrayList&lt;String&gt; result = <span style="color:#0000ff;">new</span> ArrayList&lt;String&gt;();
<span id="lnum700" style="color:#606060;"> 700:</span>         <span style="color:#0000ff;">int</span> last = 0;
<span id="lnum701" style="color:#606060;"> 701:</span>
<span id="lnum702" style="color:#606060;"> 702:</span>         <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = 0; i &lt; sourceNumber.length(); i++) {
<span id="lnum703" style="color:#606060;"> 703:</span>             <span style="color:#0000ff;">if</span> (sourceNumber.charAt(i) == <span style="color:#006080;">';'</span> || sourceNumber.charAt(i) == <span style="color:#006080;">','</span>) {
<span id="lnum704" style="color:#606060;"> 704:</span>                 String number = sourceNumber.substring(last, i).trim();
<span id="lnum705" style="color:#606060;"> 705:</span>                 result.add(number);
<span id="lnum706" style="color:#606060;"> 706:</span>                 last = i + 1;
<span id="lnum707" style="color:#606060;"> 707:</span>             }
<span id="lnum708" style="color:#606060;"> 708:</span>         }
<span id="lnum709" style="color:#606060;"> 709:</span>         result.add(sourceNumber.substring(last).trim());
<span id="lnum710" style="color:#606060;"> 710:</span>         <span style="color:#0000ff;">return</span> result;
<span id="lnum711" style="color:#606060;"> 711:</span>     }
<span id="lnum712" style="color:#606060;"> 712:</span>
<span id="lnum713" style="color:#606060;"> 713:</span>     <span style="color:#008000;">/**</span>
<span id="lnum714" style="color:#606060;"> 714:</span> <span style="color:#008000;"> * Format the mobile number</span>
<span id="lnum715" style="color:#606060;"> 715:</span> <span style="color:#008000;"> * </span>
<span id="lnum716" style="color:#606060;"> 716:</span> <span style="color:#008000;"> * @param mobileNumber</span>
<span id="lnum717" style="color:#606060;"> 717:</span> <span style="color:#008000;"> * @param format</span>
<span id="lnum718" style="color:#606060;"> 718:</span> <span style="color:#008000;"> * - ###-###-####</span>
<span id="lnum719" style="color:#606060;"> 719:</span> <span style="color:#008000;"> * @return</span>
<span id="lnum720" style="color:#606060;"> 720:</span> <span style="color:#008000;"> */</span>
<span id="lnum721" style="color:#606060;"> 721:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String format(String mobileNumber, String format) {
<span id="lnum722" style="color:#606060;"> 722:</span>         <span style="color:#0000ff;">if</span> (mobileNumber == null || mobileNumber.length() &lt; 1 || format == null || format.length() &lt; 1) {
<span id="lnum723" style="color:#606060;"> 723:</span>             <span style="color:#0000ff;">return</span> mobileNumber;
<span id="lnum724" style="color:#606060;"> 724:</span>         }
<span id="lnum725" style="color:#606060;"> 725:</span>
<span id="lnum726" style="color:#606060;"> 726:</span>         <span style="color:#0000ff;">int</span> numberCount = 0;
<span id="lnum727" style="color:#606060;"> 727:</span>         <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = 0; i &lt; format.length(); i++) {
<span id="lnum728" style="color:#606060;"> 728:</span>             <span style="color:#0000ff;">if</span> (format.charAt(i) == <span style="color:#006080;">'#'</span>) {
<span id="lnum729" style="color:#606060;"> 729:</span>                 numberCount++;
<span id="lnum730" style="color:#606060;"> 730:</span>             }
<span id="lnum731" style="color:#606060;"> 731:</span>         }
<span id="lnum732" style="color:#606060;"> 732:</span>         String number = safeCleanMobileNumber(mobileNumber);
<span id="lnum733" style="color:#606060;"> 733:</span>         <span style="color:#0000ff;">if</span> (numberCount != number.length()) {
<span id="lnum734" style="color:#606060;"> 734:</span>             <span style="color:#0000ff;">return</span> mobileNumber;
<span id="lnum735" style="color:#606060;"> 735:</span>         }
<span id="lnum736" style="color:#606060;"> 736:</span>
<span id="lnum737" style="color:#606060;"> 737:</span>         List&lt;Character&gt; numberChars = <span style="color:#0000ff;">new</span> ArrayList&lt;Character&gt;();
<span id="lnum738" style="color:#606060;"> 738:</span>         <span style="color:#0000ff;">char</span>[] chars = <span style="color:#0000ff;">new</span> <span style="color:#0000ff;">char</span>[format.length()];
<span id="lnum739" style="color:#606060;"> 739:</span>         <span style="color:#0000ff;">int</span> count = 0;
<span id="lnum740" style="color:#606060;"> 740:</span>         <span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = 0; i &lt; format.length(); i++) {
<span id="lnum741" style="color:#606060;"> 741:</span>             <span style="color:#0000ff;">if</span> (format.charAt(i) == <span style="color:#006080;">'#'</span>) {
<span id="lnum742" style="color:#606060;"> 742:</span>                 numberChars.add(number.charAt(count));
<span id="lnum743" style="color:#606060;"> 743:</span>                 chars[i] = number.charAt(count);
<span id="lnum744" style="color:#606060;"> 744:</span>                 count++;
<span id="lnum745" style="color:#606060;"> 745:</span>             } <span style="color:#0000ff;">else</span> {
<span id="lnum746" style="color:#606060;"> 746:</span>                 numberChars.add(format.charAt(i));
<span id="lnum747" style="color:#606060;"> 747:</span>                 chars[i] = format.charAt(i);
<span id="lnum748" style="color:#606060;"> 748:</span>             }
<span id="lnum749" style="color:#606060;"> 749:</span>         }
<span id="lnum750" style="color:#606060;"> 750:</span>
<span id="lnum751" style="color:#606060;"> 751:</span>         <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">new</span> String(chars);
<span id="lnum752" style="color:#606060;"> 752:</span>     }
<span id="lnum753" style="color:#606060;"> 753:</span>
<span id="lnum754" style="color:#606060;"> 754:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String stringArrayToDelimittedString(String[] arrayString, String delimiter) {
<span id="lnum755" style="color:#606060;"> 755:</span>         <span style="color:#0000ff;">return</span> stringArrayToDelimittedString(arrayString, delimiter, null);
<span id="lnum756" style="color:#606060;"> 756:</span>     }
<span id="lnum757" style="color:#606060;"> 757:</span>
<span id="lnum758" style="color:#606060;"> 758:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String stringArrayToDelimittedString(String[] arrayString, String delimiter, String format) {
<span id="lnum759" style="color:#606060;"> 759:</span>
<span id="lnum760" style="color:#606060;"> 760:</span>         <span style="color:#0000ff;">if</span> (arrayString == null || delimiter == null) {
<span id="lnum761" style="color:#606060;"> 761:</span>             <span style="color:#0000ff;">return</span> null;
<span id="lnum762" style="color:#606060;"> 762:</span>         }
<span id="lnum763" style="color:#606060;"> 763:</span>
<span id="lnum764" style="color:#606060;"> 764:</span>         StringBuilder delimittedString = <span style="color:#0000ff;">new</span> StringBuilder();
<span id="lnum765" style="color:#606060;"> 765:</span>         <span style="color:#0000ff;">if</span> (format == null || format.length() &lt; 1) {
<span id="lnum766" style="color:#606060;"> 766:</span>             <span style="color:#0000ff;">for</span> (String number : arrayString) {
<span id="lnum767" style="color:#606060;"> 767:</span>                 delimittedString.append(number).append(delimiter);
<span id="lnum768" style="color:#606060;"> 768:</span>             }
<span id="lnum769" style="color:#606060;"> 769:</span>         } <span style="color:#0000ff;">else</span> {
<span id="lnum770" style="color:#606060;"> 770:</span>             <span style="color:#0000ff;">for</span> (String number : arrayString) {
<span id="lnum771" style="color:#606060;"> 771:</span>                 number = StringUtil.format(number, format);
<span id="lnum772" style="color:#606060;"> 772:</span>                 delimittedString.append(number).append(delimiter);
<span id="lnum773" style="color:#606060;"> 773:</span>             }
<span id="lnum774" style="color:#606060;"> 774:</span>         }
<span id="lnum775" style="color:#606060;"> 775:</span>
<span id="lnum776" style="color:#606060;"> 776:</span>         <span style="color:#0000ff;">return</span> delimittedString.toString();
<span id="lnum777" style="color:#606060;"> 777:</span>     }
<span id="lnum778" style="color:#606060;"> 778:</span>
<span id="lnum779" style="color:#606060;"> 779:</span>     <span style="color:#008000;">/**</span>
<span id="lnum780" style="color:#606060;"> 780:</span> <span style="color:#008000;"> * Takes a delimited values string and returns is as a set</span>
<span id="lnum781" style="color:#606060;"> 781:</span> <span style="color:#008000;"> * </span>
<span id="lnum782" style="color:#606060;"> 782:</span> <span style="color:#008000;"> * @param string</span>
<span id="lnum783" style="color:#606060;"> 783:</span> <span style="color:#008000;"> * @param delimiter</span>
<span id="lnum784" style="color:#606060;"> 784:</span> <span style="color:#008000;"> * @return Set&lt;String&gt;</span>
<span id="lnum785" style="color:#606060;"> 785:</span> <span style="color:#008000;"> */</span>
<span id="lnum786" style="color:#606060;"> 786:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> Set&lt;String&gt; stringToSet(String string, String delimiter) {
<span id="lnum787" style="color:#606060;"> 787:</span>         <span style="color:#0000ff;">if</span> (isNullOrEmpty(string) || isNullOrEmpty(delimiter)) {
<span id="lnum788" style="color:#606060;"> 788:</span>             <span style="color:#0000ff;">return</span> null;
<span id="lnum789" style="color:#606060;"> 789:</span>         }
<span id="lnum790" style="color:#606060;"> 790:</span>
<span id="lnum791" style="color:#606060;"> 791:</span>         String[] toArray = string.split(delimiter);
<span id="lnum792" style="color:#606060;"> 792:</span>         Set&lt;String&gt; toSet = null;
<span id="lnum793" style="color:#606060;"> 793:</span>         <span style="color:#0000ff;">if</span> (toArray != null &amp;&amp; toArray.length &gt; 0) {
<span id="lnum794" style="color:#606060;"> 794:</span>             toSet = <span style="color:#0000ff;">new</span> HashSet&lt;String&gt;();
<span id="lnum795" style="color:#606060;"> 795:</span>             <span style="color:#0000ff;">for</span> (String value : toArray) {
<span id="lnum796" style="color:#606060;"> 796:</span>                 <span style="color:#0000ff;">if</span> (!isNullOrEmpty(value)) toSet.add(value);
<span id="lnum797" style="color:#606060;"> 797:</span>             }
<span id="lnum798" style="color:#606060;"> 798:</span>         }
<span id="lnum799" style="color:#606060;"> 799:</span>         <span style="color:#0000ff;">return</span> toSet;
<span id="lnum800" style="color:#606060;"> 800:</span>     }
<span id="lnum801" style="color:#606060;"> 801:</span>
<span id="lnum802" style="color:#606060;"> 802:</span>     <span style="color:#008000;">/**</span>
<span id="lnum803" style="color:#606060;"> 803:</span> <span style="color:#008000;"> * Return true if the string is null. Trims the string and checks if it is</span>
<span id="lnum804" style="color:#606060;"> 804:</span> <span style="color:#008000;"> * an empty string</span>
<span id="lnum805" style="color:#606060;"> 805:</span> <span style="color:#008000;"> * </span>
<span id="lnum806" style="color:#606060;"> 806:</span> <span style="color:#008000;"> * @param string</span>
<span id="lnum807" style="color:#606060;"> 807:</span> <span style="color:#008000;"> * @return</span>
<span id="lnum808" style="color:#606060;"> 808:</span> <span style="color:#008000;"> */</span>
<span id="lnum809" style="color:#606060;"> 809:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> isNullOrEmpty(String string) {
<span id="lnum810" style="color:#606060;"> 810:</span>         <span style="color:#0000ff;">return</span> (string == null || string.trim().length() &lt; 1);
<span id="lnum811" style="color:#606060;"> 811:</span>     }
<span id="lnum812" style="color:#606060;"> 812:</span>
<span id="lnum813" style="color:#606060;"> 813:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> isNullOrEmpty(String... strings) {
<span id="lnum814" style="color:#606060;"> 814:</span>         <span style="color:#0000ff;">for</span> (String string : strings) {
<span id="lnum815" style="color:#606060;"> 815:</span>             <span style="color:#0000ff;">if</span> (isNullOrEmpty(string)) {
<span id="lnum816" style="color:#606060;"> 816:</span>                 <span style="color:#0000ff;">return</span> true;
<span id="lnum817" style="color:#606060;"> 817:</span>             }
<span id="lnum818" style="color:#606060;"> 818:</span>         }
<span id="lnum819" style="color:#606060;"> 819:</span>         <span style="color:#0000ff;">return</span> false;
<span id="lnum820" style="color:#606060;"> 820:</span>     }
<span id="lnum821" style="color:#606060;"> 821:</span>
<span id="lnum822" style="color:#606060;"> 822:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> exists(String string) {
<span id="lnum823" style="color:#606060;"> 823:</span>         <span style="color:#0000ff;">return</span> !isNullOrEmpty(string);
<span id="lnum824" style="color:#606060;"> 824:</span>     }
<span id="lnum825" style="color:#606060;"> 825:</span>
<span id="lnum826" style="color:#606060;"> 826:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> equals(String string1, String string2){
<span id="lnum827" style="color:#606060;"> 827:</span>         <span style="color:#0000ff;">if</span> (string1 == string2)
<span id="lnum828" style="color:#606060;"> 828:</span>             <span style="color:#0000ff;">return</span> true; <span style="color:#008000;">// covers both null, or both same instance</span>
<span id="lnum829" style="color:#606060;"> 829:</span>         <span style="color:#0000ff;">if</span> (string1 == null){
<span id="lnum830" style="color:#606060;"> 830:</span>             <span style="color:#0000ff;">return</span> false; <span style="color:#008000;">// covers 1 null, other not.</span>
<span id="lnum831" style="color:#606060;"> 831:</span>         }
<span id="lnum832" style="color:#606060;"> 832:</span>
<span id="lnum833" style="color:#606060;"> 833:</span>         <span style="color:#0000ff;">return</span> (string1.equals(string2)); <span style="color:#008000;">// covers equals</span>
<span id="lnum834" style="color:#606060;"> 834:</span>     }
<span id="lnum835" style="color:#606060;"> 835:</span>
<span id="lnum836" style="color:#606060;"> 836:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> equalsIgnoreCase(String string, String type) {
<span id="lnum837" style="color:#606060;"> 837:</span>         <span style="color:#0000ff;">boolean</span> oneEmpty = isNullOrEmpty(string);
<span id="lnum838" style="color:#606060;"> 838:</span>         <span style="color:#0000ff;">boolean</span> otherEmpty = isNullOrEmpty(type);
<span id="lnum839" style="color:#606060;"> 839:</span>         <span style="color:#0000ff;">if</span> (oneEmpty &amp;&amp; otherEmpty) {
<span id="lnum840" style="color:#606060;"> 840:</span>             <span style="color:#0000ff;">return</span> true;
<span id="lnum841" style="color:#606060;"> 841:</span>         }
<span id="lnum842" style="color:#606060;"> 842:</span>         <span style="color:#0000ff;">if</span> (oneEmpty || otherEmpty) {
<span id="lnum843" style="color:#606060;"> 843:</span>             <span style="color:#0000ff;">return</span> false;
<span id="lnum844" style="color:#606060;"> 844:</span>         }
<span id="lnum845" style="color:#606060;"> 845:</span>
<span id="lnum846" style="color:#606060;"> 846:</span>         <span style="color:#0000ff;">return</span> string.equalsIgnoreCase(type);
<span id="lnum847" style="color:#606060;"> 847:</span>     }
<span id="lnum848" style="color:#606060;"> 848:</span>
<span id="lnum849" style="color:#606060;"> 849:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> isIntegerParsable(String toCheck){
<span id="lnum850" style="color:#606060;"> 850:</span>         <span style="color:#0000ff;">if</span> (toCheck == null) <span style="color:#0000ff;">return</span> false;
<span id="lnum851" style="color:#606060;"> 851:</span>         <span style="color:#0000ff;">try</span> {
<span id="lnum852" style="color:#606060;"> 852:</span>             Integer.parseInt(toCheck);
<span id="lnum853" style="color:#606060;"> 853:</span>             <span style="color:#0000ff;">return</span> true;
<span id="lnum854" style="color:#606060;"> 854:</span>         } <span style="color:#0000ff;">catch</span> (NumberFormatException e){
<span id="lnum855" style="color:#606060;"> 855:</span>             <span style="color:#0000ff;">return</span> false;
<span id="lnum856" style="color:#606060;"> 856:</span>         }
<span id="lnum857" style="color:#606060;"> 857:</span>     }
<span id="lnum858" style="color:#606060;"> 858:</span>
<span id="lnum859" style="color:#606060;"> 859:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">boolean</span> isLongParsable(String toCheck){
<span id="lnum860" style="color:#606060;"> 860:</span>         <span style="color:#0000ff;">if</span> (toCheck == null) <span style="color:#0000ff;">return</span> false;
<span id="lnum861" style="color:#606060;"> 861:</span>         <span style="color:#0000ff;">try</span> {
<span id="lnum862" style="color:#606060;"> 862:</span>             Long.parseLong(toCheck);
<span id="lnum863" style="color:#606060;"> 863:</span>             <span style="color:#0000ff;">return</span> true;
<span id="lnum864" style="color:#606060;"> 864:</span>         } <span style="color:#0000ff;">catch</span> (NumberFormatException e){
<span id="lnum865" style="color:#606060;"> 865:</span>             <span style="color:#0000ff;">return</span> false;
<span id="lnum866" style="color:#606060;"> 866:</span>         }
<span id="lnum867" style="color:#606060;"> 867:</span>     }
<span id="lnum868" style="color:#606060;"> 868:</span>
<span id="lnum869" style="color:#606060;"> 869:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String[] convert(Object... parameters){
<span id="lnum870" style="color:#606060;"> 870:</span>         String[] args = <span style="color:#0000ff;">new</span> String[parameters.length];
<span id="lnum871" style="color:#606060;"> 871:</span>
<span id="lnum872" style="color:#606060;"> 872:</span>         <span style="color:#0000ff;">int</span> idx = 0;
<span id="lnum873" style="color:#606060;"> 873:</span>         <span style="color:#0000ff;">for</span>(Object object : parameters){
<span id="lnum874" style="color:#606060;"> 874:</span>             args[idx] = String.valueOf(object);
<span id="lnum875" style="color:#606060;"> 875:</span>             idx ++;
<span id="lnum876" style="color:#606060;"> 876:</span>         }
<span id="lnum877" style="color:#606060;"> 877:</span>
<span id="lnum878" style="color:#606060;"> 878:</span>         <span style="color:#0000ff;">return</span> args;
<span id="lnum879" style="color:#606060;"> 879:</span>     }
<span id="lnum880" style="color:#606060;"> 880:</span>
<span id="lnum881" style="color:#606060;"> 881:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String join(Object... parts) {
<span id="lnum882" style="color:#606060;"> 882:</span>         StringBuilder sb = <span style="color:#0000ff;">new</span> StringBuilder();
<span id="lnum883" style="color:#606060;"> 883:</span>         <span style="color:#0000ff;">for</span>(Object part : parts){
<span id="lnum884" style="color:#606060;"> 884:</span>             <span style="color:#0000ff;">if</span> (part == null){
<span id="lnum885" style="color:#606060;"> 885:</span>                 <span style="color:#0000ff;">continue</span>;
<span id="lnum886" style="color:#606060;"> 886:</span>             }
<span id="lnum887" style="color:#606060;"> 887:</span>             sb.append(String.valueOf(part));
<span id="lnum888" style="color:#606060;"> 888:</span>         }
<span id="lnum889" style="color:#606060;"> 889:</span>         <span style="color:#0000ff;">return</span> sb.toString();
<span id="lnum890" style="color:#606060;"> 890:</span>     }
<span id="lnum891" style="color:#606060;"> 891:</span>
<span id="lnum892" style="color:#606060;"> 892:</span>     <span style="color:#008000;">/**</span>
<span id="lnum893" style="color:#606060;"> 893:</span> <span style="color:#008000;"> * Check if the last character in the string matches the input character and</span>
<span id="lnum894" style="color:#606060;"> 894:</span> <span style="color:#008000;"> * removes. If the match fails, we return the string as it is.</span>
<span id="lnum895" style="color:#606060;"> 895:</span> <span style="color:#008000;"> * </span>
<span id="lnum896" style="color:#606060;"> 896:</span> <span style="color:#008000;"> * @param inputString</span>
<span id="lnum897" style="color:#606060;"> 897:</span> <span style="color:#008000;"> * @param c</span>
<span id="lnum898" style="color:#606060;"> 898:</span> <span style="color:#008000;"> * @return string</span>
<span id="lnum899" style="color:#606060;"> 899:</span> <span style="color:#008000;"> */</span>
<span id="lnum900" style="color:#606060;"> 900:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String removeLast(String inputString, <span style="color:#0000ff;">char</span> c) {
<span id="lnum901" style="color:#606060;"> 901:</span>
<span id="lnum902" style="color:#606060;"> 902:</span>         <span style="color:#0000ff;">if</span> (isNullOrEmpty(inputString)) {
<span id="lnum903" style="color:#606060;"> 903:</span>             <span style="color:#0000ff;">return</span> inputString;
<span id="lnum904" style="color:#606060;"> 904:</span>         }
<span id="lnum905" style="color:#606060;"> 905:</span>
<span id="lnum906" style="color:#606060;"> 906:</span>         <span style="color:#0000ff;">if</span> (inputString.charAt(inputString.length() - 1) == c) {
<span id="lnum907" style="color:#606060;"> 907:</span>             <span style="color:#0000ff;">return</span> inputString.substring(0, inputString.length() - 1);
<span id="lnum908" style="color:#606060;"> 908:</span>         }
<span id="lnum909" style="color:#606060;"> 909:</span>
<span id="lnum910" style="color:#606060;"> 910:</span>         <span style="color:#0000ff;">return</span> inputString;
<span id="lnum911" style="color:#606060;"> 911:</span>     }
<span id="lnum912" style="color:#606060;"> 912:</span>
<span id="lnum913" style="color:#606060;"> 913:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String stripStringNull(String param) {
<span id="lnum914" style="color:#606060;"> 914:</span>         <span style="color:#0000ff;">return</span> (StringUtil.isNullOrEmpty(param) || <span style="color:#006080;">"null"</span>.equalsIgnoreCase(param)) ? StringUtil.EMPTY_STRING : param;
<span id="lnum915" style="color:#606060;"> 915:</span>     }
<span id="lnum916" style="color:#606060;"> 916:</span>
<span id="lnum917" style="color:#606060;"> 917:</span>     <span style="color:#008000;">/**</span>
<span id="lnum918" style="color:#606060;"> 918:</span> <span style="color:#008000;"> * </span>
<span id="lnum919" style="color:#606060;"> 919:</span> <span style="color:#008000;"> * @param contents</span>
<span id="lnum920" style="color:#606060;"> 920:</span> <span style="color:#008000;"> * @param key</span>
<span id="lnum921" style="color:#606060;"> 921:</span> <span style="color:#008000;"> * @param value</span>
<span id="lnum922" style="color:#606060;"> 922:</span> <span style="color:#008000;"> * @return</span>
<span id="lnum923" style="color:#606060;"> 923:</span> <span style="color:#008000;"> */</span>
<span id="lnum924" style="color:#606060;"> 924:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String convertPatterns(String contents, Map&lt;String, String&gt; keyVals) {
<span id="lnum925" style="color:#606060;"> 925:</span>
<span id="lnum926" style="color:#606060;"> 926:</span>         <span style="color:#0000ff;">if</span> (contents == null) {
<span id="lnum927" style="color:#606060;"> 927:</span>             <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> NullPointerException(<span style="color:#006080;">"Cannot convert null pattern"</span>);
<span id="lnum928" style="color:#606060;"> 928:</span>         }
<span id="lnum929" style="color:#606060;"> 929:</span>
<span id="lnum930" style="color:#606060;"> 930:</span>         <span style="color:#0000ff;">for</span>(Map.Entry&lt;String, String&gt; entry : keyVals.entrySet()) {
<span id="lnum931" style="color:#606060;"> 931:</span>             contents = contents.replaceAll(entry.getKey(), entry.getValue());
<span id="lnum932" style="color:#606060;"> 932:</span>         }
<span id="lnum933" style="color:#606060;"> 933:</span>
<span id="lnum934" style="color:#606060;"> 934:</span>         <span style="color:#0000ff;">return</span> contents;
<span id="lnum935" style="color:#606060;"> 935:</span>     }
<span id="lnum936" style="color:#606060;"> 936:</span>
<span id="lnum937" style="color:#606060;"> 937:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> String convertPatterns(
<span id="lnum938" style="color:#606060;"> 938:</span>         <span style="color:#0000ff;">final</span> String contents,
<span id="lnum939" style="color:#606060;"> 939:</span>         <span style="color:#0000ff;">final</span> String hostnamePattern,
<span id="lnum940" style="color:#606060;"> 940:</span>         <span style="color:#0000ff;">final</span> String string
<span id="lnum941" style="color:#606060;"> 941:</span>     ) {
<span id="lnum942" style="color:#606060;"> 942:</span>
<span id="lnum943" style="color:#606060;"> 943:</span>         <span style="color:#0000ff;">final</span> Map&lt;String, String&gt; keyVals = <span style="color:#0000ff;">new</span> HashMap&lt;String, String&gt;();
<span id="lnum944" style="color:#606060;"> 944:</span>
<span id="lnum945" style="color:#606060;"> 945:</span>         <span style="color:#0000ff;">return</span> convertPatterns(contents, keyVals);
<span id="lnum946" style="color:#606060;"> 946:</span>
<span id="lnum947" style="color:#606060;"> 947:</span>     }
<span id="lnum948" style="color:#606060;"> 948:</span>
<span id="lnum949" style="color:#606060;"> 949:</span> }

Your Eclipse window package explorer should have two files in it now: Bubble.java and Main.java.

image

Now, you can go ahead and run your code but you will get errors because you don’t have the pictures required by the Bubble.java class to render out the nice looking bubble. So, you need to go create a resources folder and place the pictures inside it.

image

Then paste in the 3 pictures into the folder. These pictures are also in the main zip file for the entire project at the start of this posting. Or you can download them here.

resources.zip 23 KB

image

Ok, now go to your Main.java file and run the program. The best way to do this is to move your cursor into the static void main() method and right-click. Choose Run As –> Java Application. This will execute the static void main() and actually run your app. You will see a lot of output in the console window. This is the Zipwhip API giving you lots of debugging feedback.

image

Now, here’s the big moment. Go ahead and send yourself a text message to the phone you are logged in as. You will get a slick popup window fading in on your desktop in the upper right corner. You can double-click the bubble to jump to the configured URL to reply to your message. You can also hit the reply button or close the bubble.

image

The key extra chunk of code for this example vs. the previous posting is that we are now listening to signals and parsing them so we can perform a switch. I created an ENUM of some of the standard signals from the Zipwhip API so that I could perform a switch since Java still does not let you do a switch on strings.

Here is the signal observer code and the switch statement.

<span id="lnum1" style="color:#606060;"> 1:</span> signalClient.addSignalObserver(<span style="color:#0000ff;">new</span> SignalObserver() {
<span id="lnum2" style="color:#606060;"> 2:</span>     @Override
<span id="lnum3" style="color:#606060;"> 3:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> notifySignalReceived(Signal signal) {
<span id="lnum4" style="color:#606060;"> 4:</span>         log.debug(<span style="color:#006080;">"Signal received with uri "</span> + signal.uri);
<span id="lnum5" style="color:#606060;"> 5:</span>
<span id="lnum6" style="color:#606060;"> 6:</span>         <span style="color:#0000ff;">switch</span> (SignalUri.toSignalUri(signal.uri)) {
<span id="lnum7" style="color:#606060;"> 7:</span>         <span style="color:#0000ff;">case</span> SIGNAL_MESSAGE_RECEIVE:
<span id="lnum8" style="color:#606060;"> 8:</span>             <span style="color:#008000;">// We got a message. Let's show it.</span>
<span id="lnum9" style="color:#606060;"> 9:</span>             <span style="color:#008000;">// The Message object is contained in the signal.content object</span>
<span id="lnum10" style="color:#606060;"> 10:</span>             <span style="color:#008000;">// but you need to cast it.</span>
<span id="lnum11" style="color:#606060;"> 11:</span>             Message msg = (Message)signal.content;
<span id="lnum12" style="color:#606060;"> 12:</span>             showIncomingMessageAlert(msg);
<span id="lnum13" style="color:#606060;"> 13:</span>             <span style="color:#0000ff;">break</span>;
<span id="lnum14" style="color:#606060;"> 14:</span>         <span style="color:#0000ff;">case</span> SIGNAL_CONVERSATION_CHANGE:
<span id="lnum15" style="color:#606060;"> 15:</span>             <span style="color:#008000;">// Do nothing for now</span>
<span id="lnum16" style="color:#606060;"> 16:</span>             <span style="color:#0000ff;">break</span>;
<span id="lnum17" style="color:#606060;"> 17:</span>         <span style="color:#0000ff;">default</span>:
<span id="lnum18" style="color:#606060;"> 18:</span>             <span style="color:#008000;">// Do nothing if we don't know the signal</span>
<span id="lnum19" style="color:#606060;"> 19:</span>             <span style="color:#0000ff;">break</span>;
<span id="lnum20" style="color:#606060;"> 20:</span>         }
<span id="lnum21" style="color:#606060;"> 21:</span>     }
<span id="lnum22" style="color:#606060;"> 22:</span>
<span id="lnum23" style="color:#606060;"> 23:</span>  });

You will need to also have the class for the Enum. I got lazy and just placed it into the Main.java file. Technically you should likely place this in its own class file.

<span id="lnum1" style="color:#606060;"> 1:</span> <span style="color:#0000ff;">enum</span> SignalUri
<span id="lnum2" style="color:#606060;"> 2:</span> {
<span id="lnum3" style="color:#606060;"> 3:</span>     <span style="color:#008000;">/*</span>
<span id="lnum4" style="color:#606060;"> 4:</span> <span style="color:#008000;"> * /signal/message/progress</span>
<span id="lnum5" style="color:#606060;"> 5:</span> <span style="color:#008000;"> * /signal/messageProgress/messageProgress</span>
<span id="lnum6" style="color:#606060;"> 6:</span> <span style="color:#008000;"> * /signal/message/send</span>
<span id="lnum7" style="color:#606060;"> 7:</span> <span style="color:#008000;"> * /signal/message/receive</span>
<span id="lnum8" style="color:#606060;"> 8:</span> <span style="color:#008000;"> * /signal/message/read</span>
<span id="lnum9" style="color:#606060;"> 9:</span> <span style="color:#008000;"> * /signal/message/delete</span>
<span id="lnum10" style="color:#606060;"> 10:</span> <span style="color:#008000;"> * /signal/conversation/change</span>
<span id="lnum11" style="color:#606060;"> 11:</span> <span style="color:#008000;"> */</span>
<span id="lnum12" style="color:#606060;"> 12:</span>     SIGNAL_MESSAGE_RECEIVE,
<span id="lnum13" style="color:#606060;"> 13:</span>     SIGNAL_MESSAGE_PROGRESS,
<span id="lnum14" style="color:#606060;"> 14:</span>     SIGNAL_MESSAGE_READ,
<span id="lnum15" style="color:#606060;"> 15:</span>     SIGNAL_MESSAGE_DELETE,
<span id="lnum16" style="color:#606060;"> 16:</span>     SIGNAL_MESSAGEPROGRESS_MESSAGEPROGRESS,
<span id="lnum17" style="color:#606060;"> 17:</span>     SIGNAL_CONVERSATION_CHANGE,
<span id="lnum18" style="color:#606060;"> 18:</span>     SIGNAL_CONTACT_NEW,
<span id="lnum19" style="color:#606060;"> 19:</span>     SIGNAL_CONTACT_SAVE,
<span id="lnum20" style="color:#606060;"> 20:</span>     SIGNAL_CONTACT_DELETE,
<span id="lnum21" style="color:#606060;"> 21:</span>     NOVALUE;
<span id="lnum22" style="color:#606060;"> 22:</span>
<span id="lnum23" style="color:#606060;"> 23:</span>     <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> SignalUri toSignalUri(String str)
<span id="lnum24" style="color:#606060;"> 24:</span>     {
<span id="lnum25" style="color:#606060;"> 25:</span>         <span style="color:#008000;">// We are going to use Java's valueOf method, so</span>
<span id="lnum26" style="color:#606060;"> 26:</span>         <span style="color:#008000;">// we need to cleanup the URI string first</span>
<span id="lnum27" style="color:#606060;"> 27:</span>         <span style="color:#008000;">// Get rid of first slash</span>
<span id="lnum28" style="color:#606060;"> 28:</span>         String str2 = str.substring(1, str.length());
<span id="lnum29" style="color:#606060;"> 29:</span>         <span style="color:#008000;">// convert slashes to underscores</span>
<span id="lnum30" style="color:#606060;"> 30:</span>         str2 = str2.replaceAll(<span style="color:#006080;">"/"</span>, <span style="color:#006080;">"_"</span>);
<span id="lnum31" style="color:#606060;"> 31:</span>         <span style="color:#008000;">// go all upper case</span>
<span id="lnum32" style="color:#606060;"> 32:</span>         str2 = str2.toUpperCase();
<span id="lnum33" style="color:#606060;"> 33:</span>
<span id="lnum34" style="color:#606060;"> 34:</span>         <span style="color:#0000ff;">try</span> {
<span id="lnum35" style="color:#606060;"> 35:</span>             <span style="color:#0000ff;">return</span> valueOf(str2);
<span id="lnum36" style="color:#606060;"> 36:</span>         }
<span id="lnum37" style="color:#606060;"> 37:</span>         <span style="color:#0000ff;">catch</span> (Exception ex) {
<span id="lnum38" style="color:#606060;"> 38:</span>             System.out.println(<span style="color:#006080;">"Found no match for SignalURI:"</span> + str);
<span id="lnum39" style="color:#606060;"> 39:</span>             <span style="color:#0000ff;">return</span> NOVALUE;
<span id="lnum40" style="color:#606060;"> 40:</span>         }
<span id="lnum41" style="color:#606060;"> 41:</span>     }
<span id="lnum42" style="color:#606060;"> 42:</span> }

This posting is about the Zipwhip API so I don’t want to get into the details of the cool looking bubble being generated from the Bubble() class, but it’s worth noting that we are using some of the features only available in later versions of Java that let you create transparent windows. We are doing some fade in/out tricks. We are manually adding mouse listeners to let you drag the window around. We are doing some sprite tricks with getSubImage() so we can repurpose some web PNGs as well. It was quite a lot of work to get that Bubble class setup, but it was well worth it because you can run this app non-stop and actually start using it to get real-time popups.

image

If you want to try some tricks with the Bubble to see if there are things you like better than the settings I picked, one of the things I recommend is to allow the window focus to be set. If you do this, you will be able to select the text from the message to copy it to the clipboard. Go into the code and change the this.setFocusableWindowState() line:

image

Notice that you can now select text, hit Ctrl-C to copy it to the clipboard, hit tab to choose Reply, hit the spacebar to choose the button, etc. The reason I didn’t pick allowing focus is that if a bubble pops in while you’re doing something like writing an email, I don’t think it’s a good idea to steal the focus. The user could consider that rude. However, it’s up to you how you want to setup your app.

image imageimage

Ok, thanks for reading the tutorial. Enjoy playing with your popup bubbles on your desktop when your friends text you on your phone.


Jul 17, 2011 1:10:00 PM

0 comments

0 comments

Comment