0

我正在使用 smack 和 javafx 开发聊天客户端。所以我有一个表格视图,它列出了登录用户的联系人,它实时获取联系人的状态,但是当需要更新表格视图时它不会这样做(即使我的 system.out 也很困难。 println 表明它应该这样做)。奇怪的是它只在第一次加载 tableview 时加载数据。这是我的代码:

package login;

import java.util.Collection;
import java.util.Iterator;

import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Presence;

import dto.RosterDTO;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.*;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;

/** Controls the main application screen */
public class MainViewController {
    @FXML
    private Button logoutButton;
    @FXML
    private Label sessionLabel;

    @FXML
    private TableView<RosterDTO> rosterTable;
    @FXML
    private TableColumn<RosterDTO, String> grupoColumn;
    @FXML
    private TableColumn<RosterDTO, String> usuarioColumn;
    @FXML
    private TableColumn<RosterDTO, String> estatusColumn;

    ObservableList<RosterDTO> rosterList;

    private LoginManager loginManager;

    @FXML
    private void initialize() {
        // Initialize the person table
        grupoColumn
                .setCellValueFactory(new PropertyValueFactory<RosterDTO, String>(
                        "grupo"));
        usuarioColumn
                .setCellValueFactory(new PropertyValueFactory<RosterDTO, String>(
                        "usuario"));
        estatusColumn
        .setCellValueFactory(new PropertyValueFactory<RosterDTO, String>(
                "estatus"));        
        rosterTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    }

    public void initSessionID(final LoginManager loginManager, String sessionID) {
        this.loginManager = loginManager;
        XMPPConnection connection = this.loginManager.getXmppManager().getConnection(); 
        Roster roster = connection.getRoster();
        Collection<RosterEntry> entries = roster.getEntries();
        Presence p = roster.getPresence("testUser1");
        System.out.println("Estatus: " + p.getStatus());
        System.out.println("\n\n" + entries.size() + " buddy(ies):");
        rosterList = FXCollections.observableArrayList();
        for (RosterEntry r : entries) {
            RosterDTO rosterDTO = new RosterDTO();
            rosterDTO.setUsuario(r.getUser() + "/Smack");
            System.out.println("user: " + r.getUser());
            System.out.println(r.getName()); 
            System.out.println("group: " + r.getGroups());
            for (Iterator<?> i = r.getGroups().iterator(); i.hasNext();) {
                RosterGroup rosterObject = (RosterGroup) i.next();
                rosterDTO.setGrupo(rosterObject.getName());
            } 
            rosterList.add(rosterDTO); 
        }
        rosterTable.setItems(rosterList);
        roster.addRosterListener(new RosterListener() {
            public void entriesDeleted(Collection<String> addresses) {
                System.out.println("deleted: " + addresses.size());
            }

            public void entriesUpdated(Collection<String> addresses) {
                System.out.println("updated: " + addresses.size());
            }

            public void entriesAdded(Collection<String> addresses) {
                System.out.println("added: " + addresses.size());
            }

            public void presenceChanged(Presence presence) {
                System.out.println("Presence changed: " + presence.getFrom()
                        + " " + presence + " " + presence.getStatus());
                System.out.println(presence.getProperty("key")); 
                rosterList.get(0).setUsuario(presence.getStatus()); 
                rosterList.get(0).setEstatus(presence.getStatus());
                //rosterTable.setUserData(rosterList);
                rosterTable.layout();
                rosterTable.setItems(rosterList);
            }
        });     

    }
}

为什么它第一次加载数据而不是稍后?我应该使用除了 tableview 之外的其他东西吗?提前致谢。

4

1 回答 1

0

我已经设法通过使用我的可观察列表中的方法“set”来解决它,所以我留下了这样的方法:

public final void displayBuddyList(final TableView<RosterDTO> rosterTable) {
        Roster roster = connection.getRoster();  
        Collection<RosterEntry> entries = roster.getEntries();
        System.out.println("\n\n" + entries.size() + " buddy(ies):");
        final ObservableList<RosterDTO> rosterList = FXCollections.observableArrayList();
        for (RosterEntry r : entries) {
            RosterDTO rosterDTO = new RosterDTO();
            rosterDTO.setUsuario(r.getUser() + "/Smack");
            System.out.println("user: " + r.getUser());
            System.out.println(r.getName()); 
            System.out.println("group: " + r.getGroups());
            for (Iterator<?> i = r.getGroups().iterator(); i.hasNext(); ) {
                RosterGroup rosterObject = (RosterGroup) i.next();
                rosterDTO.setGrupo(rosterObject.getName());
            } 
            rosterList.add(rosterDTO); 
        }
        rosterTable.setItems(rosterList);
        roster.addRosterListener(new RosterListener() {
            // Ignored events public void entriesAdded(Collection<String>
            // addresses) {}
            public void entriesDeleted(Collection<String> addresses) {
                System.out.println("deleted: " + addresses.size());
            }

            public void entriesUpdated(Collection<String> addresses) {
                System.out.println("updated: " + addresses.size());
            }

            public void entriesAdded(Collection<String> addresses) {
                System.out.println("added: " + addresses.size());
            }

            public void presenceChanged(Presence presence) {
                int i = 0;
                for(RosterDTO rdto : rosterList) {
                    if (rdto.getUsuario().equals(presence.getFrom())) {
                        RosterDTO element = new RosterDTO();
                        element.setEstatus("" + presence); 
                        element.setUsuario(rosterList.get(i).getUsuario()); 
                        rosterList.set(i, element);
                    }
                    i++;
                }
                System.out.println("ch: " + rosterList.toString());  
            }
        }); 
    }
于 2013-07-20T01:54:44.670 回答