Eclipse plug-in development [Use eclipse RCP & ECF to implement Google Talk client]

Source: Internet
Author: User
Tags mail example
See: http://www.eclipseworld.org/bbs/read.php? Tid = 708

Have you ever used Google Talk? It is an im launched by Google, and the communication protocol is the jabber protocol we are familiar. Through this article, I will briefly introduce how to use ECF to implement a Google Talk client. Source code download: http://www.blogjava.net/Files/reloadcn/Chat.rar

1. Preparations
Download ECF first:
Www.eclipse.org/ecf

To test whether the client can run normally, we also need to download a goolge talk client: www.google.com/talk

However, to log on to the Google server, you must have a googlemail account. Because the current googlemail account is not applied for at will, you must recommend the googlemail user to apply, however, you can also enter the googlemail application page through some websites. You can search for it online. I will not talk about it here.

To build a Google Talk client, we need to know some ECF knowledge. You can go to the eclipse main site to get more information.

2. Create An RCP mail example

Select create plugin project and name it "chat". When you go to the second page of the Wizard Page, select "yes" in the "wocould you to create a rich client platform" option ", this ensures that you have created an RCP project. For details, see:

On the last page, select mail template:

After the Wizard is complete, we will get a simple RCP project.

3. login code

1) work before connection
ECF is an eclipse-based communication platform that implements the jabber protocol in part. ECF has a clientcontainer concept. In fact, it is equivalent to an object that maintains the client. It has connection and disconnection methods, and can add event listeners in communication. Therefore, to create a Google Talk client, we must first have such an object, which is unique throughout the life cycle of the program.
Let's modify the code in chatplugin:
First, we add a private variable clientcontainer to this class and add the getter and setter methods to it:

Xmppclientsocontainer clientcontainer;
? Public xmppclientsocontainer getclientcontainer (){
? ? Return clientcontainer;
? }

? Public void setclientcontainer (xmppclientsocontainer clientcontainer ){
? ? This. clientcontainer = clientcontainer;
? }

Okay. Think about it. When we log on to the Google server, we will use this clientcontainer to connect to the server, and the user information we log on to must be saved, for later code access, the clientcontainer generation method should be lazy, and we also need to create a variable for our Login Account:

?Private ID userid;

? Public ID getuserid (){
? ? Return userid;
? }

? Public void setuserid (ID userid ){
? ? This. userid = userid;
? }

In ECF, user information is represented by ID, which is an interface. ECF has implemented an xmppid, which is exactly what our jabber account needs.

Clientcontainer has a connect method to log on to the server, and there is no other action after the connection. Readers will ask: when will we be notified of successful connection? And how do users get friends on the server?

Clientcontainer is only responsible for connection. All the above operations are the information sent from the server to the client during or after connection to the server. This information needs to be captured by setting a listener for the clientcontainer.

One of the listeners is isharedobjectcontainerlistener, which can capture some events in the connection process and disconnection process, such as export dobjectconnectedevent (connection success event), export dobjectdisconnectedevent (disconnection success event ), if we need to do something after the client connects to the server, this listener is required.

Clientcontainer. addlistener (
? ? ? ? ? ? New isharedobjectcontainerlistener (){
? ? ? ? ? ? Public void handleevent (icontainerevent EVT)
? ? ? ? ? ? ? If (EVT instanceof isharedobjectcontainerconnectedevent ){
? ? ? ? ? ? ? ? ? ? ? // What do I do after the connection to the server is successful?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? If (EVT instanceof isharedobjectcontainerdisconnectedevent ){
? ? ? ? ? ? ? ? ? ? ? // What can I do after the server is disconnected successfully?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? ? ? }, Null );

2) start to connect to the server

Let's see that clientcontainer has a connect method.

This method requires two parameters: User ID and connection context.

We have already mentioned the user ID. It is a concept proposed by ECF. We can generate it through idfactory:

Userid = idfactory. getdefault (). makeid (
? ? ? ? ? ? ? ? ? ? ? ? ? Clientcontainer. getconnectnamespace (),
? ? ? ? ? ? ? ? ? ? ? ? ? GetUserName ());

Did you find out? The makeid method in the above Code requires two parameters. One parameter can be obtained from clientcontainer, which is a connection namespace. In my understanding, it is an agreement. The second is the user name. This parameter is a Google Talk account, that is, a Gmail account. However, we have no way to obtain it from the outside. I will mention it in the following content, then we can concatenate this program. Now we can regard it as having some values.

Well, we already have the ID. Now let's see how to create the context. The connection context is actually very simple. We can understand it as follows: When we connect, clientcontainer will obtain some relevant information from the client, such as nikename and password, which makes it easy to understand, in addition, in our Google Talk client, it will only ask for the password and username from us to see our code:

Clientcontainer. Connect (userid, new iconnectcontext (){

? ? ? Public callbackhandler getcallbackhandler (){
? ? ? ? ? Return new callbackhandler (){?
? ? ? ? ? ? ? Public void handle (callback [] callbacks) throws ioexception,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Unsupportedcallbackexception {
? ? ? ? ? ? ? ? ? If (callbacks = NULL) return;
? ? ? ? ? ? ? ? ? ? For (INT I = 0; I <Callbacks. length; I ++ ){
? ? ? ? ? ? ? ? ? ? ? ? If (callbacks [I] instanceof namecallback ){
? ? ? ? ? ? ? ? ? ? ? ? Namecallback NCB = (namecallback) callbacks [I]
? ? ? ? ? ? ? ? ? ? ? ? NCB. setname (GetUserName ());
? ? ? ? ? ? ? ? ? ? ? ? } Else
? ? ? ? ? ? ? ? ? ? If (callbacks [I] instanceof objectcallback ){
? ? ? ? ? ? ? ? ? ? ? Objectcallback OCB = (objectcallback) callbacks [I]
? ? ? ? ? ? ? ? ? ? ? OCB. setobject (password );
? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? });

So far, we have completed the connection process. We have encapsulated these codes into the login method of chatplugin, so that we can call them through external operations.

4. start logging in

We use SWT dialog to create a simple Login Dialog Box:

This class requires several attributes: User Account, user password, and dialog box return value.

After clicking login, the dialog box is closed and the value in the text is assigned to the account and password attributes. The returned value is set to SWT. OK. If it is cancel, we will close the dialog box and set the return value to SWT. cancel.

Go to the messagepopupaction class provided in mail RCP and modify its run method:

Public void run (){
? ? If (chatplugin. getdefault (). getclientcontainer ()! = NULL ){
? ? ? ? Messagedialog. openinformation (window. getshell (), "info", "logged in. Please log out first and then log in again ");
? ? ? ? Return;
? ? }
? ? Logindialog dialog = new logindialog (window. getshell (), SWT. None );
? ? Dialog. open ();
? ? If (dialog. getdialogresult () = SWT. OK ){
? ? ? ? Chatplugin. getdefault (). setpassword (dialog. GetPassword ());
? ? ? ? Chatplugin. getdefault (). setusername (dialog. getuser ());
? ? ? ? Chatplugin. getdefault (). login ();
? ? }
? }

The Code logic is clear. When we click this button, the Login Dialog Box will pop up, And we can log on normally after entering the information.

Pay attention to the following code. Set the username and password in chatplugin before calling the login method. If the login fails, the connection failure exception will be caught in the login method of chatplugin.

5. Get my friends

How can I get my friends?

As mentioned above, clientcontainer is only responsible for connection, and we need to add listeners to capture network events. The same is true for getting friends.

Clientcontainer can get an ipresencecontainer type object through getadapter. This object can be used to increase the listener for obtaining friend information. In addition, clientcontainer can also obtain the message sending object and the listening object of the message, this will be introduced later.
To obtain friend information, we should obtain the ipresencecontainer object through clientcontainer, and then add a listener for it to get friend events.

The question is, when should we get this object? Does this listener interface need to be implemented by some existing classes?

First, let's talk about the first question: when can we get this object and add listeners for it?

In general, we do not capture messages in our friend list before successful login, and we cannot. When the server does not verify our client, it won't be sent, so we need to get this object after successful login and add a listener for it. This object also needs to be stored as a private variable for access by other classes. Therefore, we need to mention in section 3rd that this code is written in the method of successful listening and login. Due to space issues, I will not provide code snippets here, So readers can look at the source code.

Let's look at the second question: Who needs to implement this listener?

In our common im, there is a list control that stores our current user information, so we need to add some content to some viewers after obtaining the friend list, this is our friend list.

In this client, I used a view as the control to display the friend list. The view name is simpleview, which has a tableviewer. I am not talking about the specific generation method of this class. You can look at the source code. I just want to talk about how this view monitors events that get friend information.

Let's implement the ipresencelistener interface and modify the handlesetrosterentry method:

Public void handlesetrosterentry (irosterentry entry ){
? ? Final irosterentry e1 = entry;
? ? Display. getdefault (). asyncexec (New runnable (){
? ? ? ? Public void run (){
? ? ? ? ? If (e1.getinteresttype () = interesttype. Both ){
? ? ? ? ? Roseters. Add (E1 );
? ? ? ? ? If (viewer. getinput ()! = Roseters) viewer. setinput (roseters );
? ? ? ? ? Viewer. Refresh ();
? ? ? ? ? }
? ? ? ? }
? ? });
? }

This method intercepts the interface functions used to obtain friend information. The entry indicates some information related to client friends obtained from the server, check whether this friend is in the list of friends of both parties. If not, do not add it. Otherwise, we will put this entry into a list object named roseters, then refresh the viewer. The viewer here is the tableviewer we mentioned just now. readers who have done SWT/jface know that this class requires us to add two interface implementations for it. One is the contentprovider interface, one is the labelprovier interface. The Code of these two interfaces can be viewed by readers. I will not write them here. It's okay if you are not familiar with SWT/jface.
Let's see what the list of friends is like after we log on:

6. Listen for messages

With the experience of adding friends, we can easily solve this problem now.
Similarly, the listener is intercepted by the added listener of the ipresencecontainer object.
However, I asked a class named view in our project to implement this listener, and the method to implement this interface is as follows:

Public void handlemessage (ID fromid, Id toid, type, string subject, string messagebody ){
? ? Final ID id = fromid;
? ? If (type = type. Chat ){
? ? Final string message = messagebody;
? ? Display. getdefault (). asyncexec (New runnable (){
? ? ? ? Public void run (){
? ? ? ? ? Try {
? ? ? ? ? ? If (Id. touri (). compareto (chaterid. touri () = 0 ){
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? String S = chaterid. touri (). getuserinfo (). tostring ();
? ? ? ? ? ? ? ? S + = "say:" + message + "/N ";
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? Showtext. append (s );
? ? ? ? ? ? ? ? View. This. getsite (). getworkbenchwindow ()
? ? ? ? ? ? ? ? . Getworkbench (). getactiveworkbenchwindow ()
? ? ? ? ? ? ? ? . Getactivepage (). Activate (
? ? ? ? ? ? (Iviewpart) chatplugin. getdefault (). getmessagedialogforid (chaterid ));
? ? ? ? ? ? }
? ? ? ? ? } Catch (urisyntaxexception e ){
? ? ? ? ? ? // Todo auto-generated Catch Block
? ? ? ? ? ? E. printstacktrace ();
? ? ? ? ? }
? ? ? ? }
? ? });}
? ?
? }

Readers may be confused by the above Code. Let me explain:
The chaterid variable is of the ID type. It is actually transmitted from the list of friends just now when the view object is generated when you double-click an item, let's take a look at the code of double-click action in simpleview:

Doubleclickaction = new action (){
? ? ? ? Public void run (){
? ? ? ? ? Iselection selection = viewer. getselection ();
? ? ? ? ? Irosterentry entry = (irosterentry) (structuredselection) Selection)
? ? ? ? ? ? ? ? . Getfirstelement ();
? ? ? ? ? View chatview = (View) chatplugin. getdefault ()
? ? ? ? ? ? ? ? . Getmessagedialogforid (entry. getuserid ());
? ? ? ? ? If (chatview! = NULL ){
? ? ? ? ? ? Sampleview. This. getsite (). getworkbenchwindow ()
? ? ? ? ? ? ? ? ? . Getworkbench (). getactiveworkbenchwindow ()
? ? ? ? ? ? ? ? ? . Getactivepage (). Activate (chatview );
? ? ? ? ? }
? ? ? ? }
? ? };

As you can see, when we double-click a friend, we will get its ID from the entry, generate a view, and send the ID to the view, so the chaterid of the view is the same.

The above explanation is as follows:
The showtext variable is actually a styletext object. It is responsible for displaying chat information. The readers of the following long code can ignore it. It is some work done to make a friend correspond to a view, for more information, see the source code.

7. Send messages

Let's take a look at a piece of code in the View class:

Messagetext. addkeylistener (New keylistener (){

? ? ? ? Public void keypressed (keyevent e ){
? ? ? ? ?
? ? ? ? }

? ? ? ? Public void keyreleased (keyevent e ){
? ? ? ? ? If (E. Character = '/R '){
? ? ? ? ? ? Sendmessage (messagetext. gettext ());
? ? ? ? ? ? Messagetext. settext ("");
? ? ? ? ? }
? ? ? ? }
? ? ? ?
? ? });

It is not difficult to see the meaning of this Code: when the input character is "enter", call the sendmessage method:

Public void sendmessage (string message ){
? ? If (this. getchaterid () = NULL) return;
? ? String S = "you said :";
? ? S + = message;
? ?
? ? Chatplugin. getdefault (). getpresencecontainer (). getmessagesender ()
? ? ? ? ? . Sendmessage (chatplugin. getdefault (). getuserid (), chaterid, null, null, message );
? ?
? ? Showtext. append (S + "/N ");
? }

The sendmessage method obtains the messagesender of ipresencecontainer from the chatplugin to send messages. The first parameter of the message sending function is the ID of the sender, the second is the receiver's ID (the chaterid has already talked about the obtained source). The last one is the sent message. The two parameters in the middle are the Message Type and title. They can be empty.

8. Conclusion
We have been able to create a Google Talk client by logging on to, getting a friend list, receiving and sending messages as described above, but there are still many functions that are not implemented, for example, you need to add friends and listen for changes in the status of friends. Here, we will see you next time.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.