Метод, кажется, не работает, когда он вызывается - PullRequest
2 голосов
/ 09 августа 2010

У меня есть два класса, которые должны общаться, но это не так. Один называется Chatter, и когда слушатель получает сообщение в Chatter, он должен вызвать метод во втором классе, который называется ClassView. Но я не думаю, что метод вызывается.

Вот код для Chatter:

package instantmessengerplugin;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TableItem;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;

public class Chatter {

    public XMPPConnection connection;
    public String user;
    public ClassView classView;
    public Chat chat;
    public PacketFilter packetFilter;
    public PacketListener listener;




    public Chatter(XMPPConnection connection1,String user1, Display dist)
    {
        connection  = connection1;
        user = user1;

        openChat();
        classView = new ClassView(dist,chat);
    }

    public void  openChat()
    {
        ChatManager cm = connection.getChatManager();
        chat = cm.createChat(user, new MessageListener()
        {
            public void processMessage(Chat chat ,Message message)
            {
                if(message.getType().equals(Message.Type.chat))
                {
                    //TableItem item = new TableItem(classView.chatViewer,SWT.NONE);
                    //item.setText("Them: " + message.getBody());
                    System.out.println(message.getBody());
                    classView.updateChat(message);
                }


            }
        }




        );


    }





}

А вот код для ClassView:

package instantmessengerplugin;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;


public class ClassView {

    public Display displayChat;
    public Shell shellChat;
    final Table chatViewer;
    public Chat chat;

    public ClassView(Display dist,Chat chat1){

        chat = chat1;

        displayChat = dist;
        shellChat = new Shell(displayChat);
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 2;
        shellChat.setLayout(gridLayout);

        Label contact = new Label(shellChat,SWT.NONE);
        GridData data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.horizontalSpan = 2;
        data.grabExcessHorizontalSpace = true;
        data.grabExcessVerticalSpace = true;

        chatViewer = new Table(shellChat,SWT.NONE); 
        data = new GridData();
        data.horizontalSpan = 2;
        data.horizontalAlignment = GridData.FILL;
        data.verticalAlignment = GridData.FILL;
        data.grabExcessHorizontalSpace = true;
        chatViewer.setLayoutData(data);

        final Text chatBox = new Text(shellChat,SWT.SINGLE);
        data = new GridData();
        data.verticalAlignment = GridData.FILL;
        data.horizontalAlignment = GridData.FILL;
        data.grabExcessHorizontalSpace = true;
        chatBox.setLayoutData(data);

        Button send = new Button(shellChat,SWT.PUSH);
        send.setText("Send");

        send.addSelectionListener(new SelectionAdapter(){

            public void widgetSelected(SelectionEvent e)
            {

                String s = chatBox.getText();
                TableItem item = new TableItem(chatViewer, SWT.NONE);
                item.setText("Me: " + s);
                try {
                    chat.sendMessage(s);
                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                chatBox.setText("");
            }

        });










        shellChat.pack();
        shellChat.open();

        while(!shellChat.isDisposed())
        {
            if(!displayChat.readAndDispatch())
            {
                displayChat.sleep();
            }
        } 



    }


    public void updateChat(Message message)
    {
        TableItem item = new TableItem(chatViewer,SWT.NONE);
        item.setText("Them: " + message.getBody());
    }



}

Когда вызывается метод processMessage в Chatter, он должен обращаться к ClassView, который будет вызывать updateChat, который затем изменяет объект таблицы в ClassView. Кажется, этого не происходит. Таблица не изменилась и не было сгенерировано исключение. Я знаю, что болтовня работает правильно, потому что она выводит сообщение на консоль просто отлично.

Кто-нибудь знает, почему updateChat не вызывается?

Обновление:

Я запустил отладчик с указанным кодом. Вот отладочный стек того, что вызывается при выполнении:

FutureTask $ Sync.innerRun () строка: недоступно [локальные переменные недоступны]

Строка FutureTask.run (): недоступно
ThreadPoolExecutor $ Worker.runTask (Runnable) строка: недоступно
ThreadPoolExecutor $ Worker.run () строка: недоступно
Thread.run () строка: недоступно [локальные переменные недоступны]

Я не уверен, что именно это означает. Упоминание о потоках - это то, что заставило меня подумать, что вызов метода не синхронизирован с другим потоком.

Ответы [ 3 ]

0 голосов
/ 09 августа 2010

Вы должны отлаживать код с помощью eclipse (возможно, вы используете эту IDE, так же как и SWT). Установите точку останова внутри processMessage и пройдитесь по коду. Тогда вы увидите, называется ли updateChat или нет.

0 голосов
/ 06 октября 2010

У меня была похожая ошибка с Smack, в моем случае уловка была в том, что настоящей ошибкой было исключение NullPointer. Вот мой код:

for(PartnerMessageCallback callback : callbacks) {
   callback.processMessage(null, message);
}

Исключение NullPointer возникло из processMessage, но я вижу следующее в StackTrace:

FutureTask $ Sync.innerRun () строка: недоступно [локальные переменные недоступны]

В моем случае, простой try-catch решил проблему:

for(PartnerMessageCallback callback : callbacks) {
  try {
    callback.processMessage(null, message);
  } catch (Exception ex) {
    ex.printStackTrace();
  }
}

Надеюсь, это поможет вам.

0 голосов
/ 09 августа 2010

Это предположение, но, похоже, ваше сообщение updateChat просто создает TableItem, не добавляя его в какую-либо таблицу.

    public void updateChat(Message message)
{
    TableItem item = new TableItem(chatViewer,SWT.NONE);
    item.setText("Them: " + message.getBody());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...