【问题标题】:Method doesn't seem to be running when it is called方法在被调用时似乎没有运行
【发布时间】:2011-03-27 06:02:46
【问题描述】:

我有两个班级应该进行交流,但他们没有。一个称为 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());
    }



}

当调用 Chatter 中的 processMessage 方法时,它应该与 ClassView 对话,后者将调用 updateChat,然后更改 ClassView 中的表对象。它似乎没有发生。表没有改变,也没有抛出异常。我知道 chatter 工作正常,因为它可以很好地将消息打印到控制台。

有谁知道为什么 updateChat 似乎没有被调用?

更新:

我已经在有问题的代码上运行了调试器。这是执行时调用的调试堆栈:

FutureTask$Sync.innerRun() 行:不可用 [局部变量不可用]

FutureTask.run() 行:不可用
ThreadPoolExecutor$Worker.runTask(Runnable) 行:不可用
ThreadPoolExecutor$Worker.run() 行:不可用
Thread.run() 行:不可用 [局部变量不可用]

我不确定这到底是什么意思。提到线程让我觉得方法调用不与另一个线程同步是什么。

【问题讨论】:

标签: java swt


【解决方案1】:

这是推测,但您的 updateChat 消息似乎只是创建了一个 TableItem 而不将其添加到任何表中。

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

【讨论】:

  • chatViewer 是表对象。表项是在该表“上”创建的,包括将项添加到表中。但是表可能需要刷新(在某处有一个refresh 方法,可能在chatViewer 上,可能在其父级上)
【解决方案2】:

您应该使用 eclipse 调试代码(猜想您使用这个 IDE 就像使用 SWT 一样)。在processMessage 中设置断点并单步执行代码。然后你会看到updateChat是否被调用。

【讨论】:

  • 我使用了你说的调试器。事实证明 updateChat 没有被调用。但是,如果您从它自己的类中调用 updateChat,它就可以正常工作。我认为 Chatter 类中的代码必须与 ClassView 类中的 UI 线程同步。但我不知道该怎么做。是syncExec方法吗?
  • 但是 - 在classView.updateChat(message); 行调用的,程序必须在某个地方继续,你说,上一行得到 执行.
  • 我已经更新了问题,详细说明了在 classView.updateChat(message) 中调用的内容。
【解决方案3】:

我在 Smack 中遇到过类似的错误,在我的情况下,诀窍在于真正的错误是 NullPointer 异常。这是我的代码:

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

从 processMessage 中引发了 NullPointer 异常,但我在 StackTrace 中看到以下内容:

FutureTask$Sync.innerRun() 行:不可用 [局部变量不可用]

在我的例子中,一个简单的 try-catch 解决了这个问题:

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

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 2018-07-05
    • 2013-09-11
    • 1970-01-01
    相关资源
    最近更新 更多