Swing GUI客户端侦听器不响应远程RMI属性的更新

Swing GUI客户端侦听器不响应远程RMI属性的更新,swing,callback,listener,rmi,jtree,Swing,Callback,Listener,Rmi,Jtree,当对JTree的模型进行显式调用时,我在让JTree重新绘制时遇到了一些问题(我在向其添加了一些新节点后进行了调用) 该代码最初运行良好,但由于应用程序已导出到RMI,因此失败 我将DefaultTreeModel对象存储在控制器类中,它是一个远程对象 我使用tree.addModel(controller.getModel())将DefaultTreeModel对象添加到客户端的JTree中 我使用订阅客户端GUI上按钮的ActionListener调用控制器中执行“添加新节点”操作的方法 我

当对JTree的模型进行显式调用时,我在让JTree重新绘制时遇到了一些问题(我在向其添加了一些新节点后进行了调用)

该代码最初运行良好,但由于应用程序已导出到RMI,因此失败

我将DefaultTreeModel对象存储在控制器类中,它是一个远程对象

我使用tree.addModel(controller.getModel())将DefaultTreeModel对象添加到客户端的JTree中

我使用订阅客户端GUI上按钮的ActionListener调用控制器中执行“添加新节点”操作的方法

我使用TreeModelListener将消息打印到屏幕上,以证明模型侦听器已启动

客户端Swing侦听器不能在RMI上工作吗

我设法重现了这个问题。我包括完整的代码,但希望有人能够根据经验给出答案

服务器驱动程序类:

package server;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import client.controller.TestTreeControllerService;

import server.controller.TestTreeControllerImpl;


public class TestTreeServerStart {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new TestTreeServerStart();

    }

    public TestTreeServerStart() {

        try {

            LocateRegistry.createRegistry(1099);

            TestTreeControllerService c = new TestTreeControllerImpl();

             Registry registry = LocateRegistry.getRegistry();
             registry.rebind("TestTreeControllerService", c);

            System.out.println("Started the RMI Server");
        }
        catch (RemoteException e) {
            System.out.println(e.getMessage());
        }
    }

}
package server.controller;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import client.controller.TestTreeControllerService;



@SuppressWarnings("serial")
public class TestTreeControllerImpl extends UnicastRemoteObject implements TestTreeControllerService {

    /**
     * 
     */
    //private static final long serialVersionUID = -8137864611400855504L;
    private DefaultTreeModel m ;


    public DefaultTreeModel getModel() {

        return m;
    }


    public TestTreeControllerImpl() throws RemoteException {

        super();
        m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));

    }

    public void addNodeAction() throws RemoteException {
        DefaultTreeModel m = (DefaultTreeModel) getModel();
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
        root.add(newNode);
        //m.insertNodeInto(newNode, (DefaultMutableTreeNode) m.getRoot(), m.getChildCount(m.getRoot()));
        m.nodeStructureChanged(root);

    }

}
package client;
import java.rmi.Naming;
import java.rmi.RemoteException;

import client.controller.TestTreeControllerService;
import client.view.TreeTestClient;



public class TreeTestClientStart {

    /**
     * @param args
     */
    public static void main(String[] args) {


            try {
                TestTreeControllerService c = (TestTreeControllerService) Naming.lookup("rmi://localhost:1099/TestTreeControllerService");
                 new TreeTestClient(c);
            }
            catch(RemoteException e) {
                System.out.println("Remote service not found: " + e.getLocalizedMessage());
            }
            catch (Exception e) {
                System.out.println("Splat");
            }
    }

}
package client.controller;
import javax.swing.tree.DefaultTreeModel;


public interface TestTreeControllerService extends java.rmi.Remote {


    public DefaultTreeModel getModel() throws java.rmi.RemoteException;

    public void addNodeAction() throws java.rmi.RemoteException;
}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());


            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);


            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.Timer;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.GUIRefreshAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());

            //Try a listener that doesn't use the Remote object
            t.addTreeSelectionListener(new RefreshTreeAction(this));

            //Try a property change listener on the TreeModel   
            t.addPropertyChangeListener("treeModel", new RefreshTreeAction(this));

            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);

            //Add a GUI redraw timer
            Timer timer = new Timer(1000, new GUIRefreshAction(this));
            timer.setInitialDelay(1);
            timer.start();

            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
服务器控制器实现类:

package server;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import client.controller.TestTreeControllerService;

import server.controller.TestTreeControllerImpl;


public class TestTreeServerStart {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new TestTreeServerStart();

    }

    public TestTreeServerStart() {

        try {

            LocateRegistry.createRegistry(1099);

            TestTreeControllerService c = new TestTreeControllerImpl();

             Registry registry = LocateRegistry.getRegistry();
             registry.rebind("TestTreeControllerService", c);

            System.out.println("Started the RMI Server");
        }
        catch (RemoteException e) {
            System.out.println(e.getMessage());
        }
    }

}
package server.controller;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import client.controller.TestTreeControllerService;



@SuppressWarnings("serial")
public class TestTreeControllerImpl extends UnicastRemoteObject implements TestTreeControllerService {

    /**
     * 
     */
    //private static final long serialVersionUID = -8137864611400855504L;
    private DefaultTreeModel m ;


    public DefaultTreeModel getModel() {

        return m;
    }


    public TestTreeControllerImpl() throws RemoteException {

        super();
        m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));

    }

    public void addNodeAction() throws RemoteException {
        DefaultTreeModel m = (DefaultTreeModel) getModel();
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
        root.add(newNode);
        //m.insertNodeInto(newNode, (DefaultMutableTreeNode) m.getRoot(), m.getChildCount(m.getRoot()));
        m.nodeStructureChanged(root);

    }

}
package client;
import java.rmi.Naming;
import java.rmi.RemoteException;

import client.controller.TestTreeControllerService;
import client.view.TreeTestClient;



public class TreeTestClientStart {

    /**
     * @param args
     */
    public static void main(String[] args) {


            try {
                TestTreeControllerService c = (TestTreeControllerService) Naming.lookup("rmi://localhost:1099/TestTreeControllerService");
                 new TreeTestClient(c);
            }
            catch(RemoteException e) {
                System.out.println("Remote service not found: " + e.getLocalizedMessage());
            }
            catch (Exception e) {
                System.out.println("Splat");
            }
    }

}
package client.controller;
import javax.swing.tree.DefaultTreeModel;


public interface TestTreeControllerService extends java.rmi.Remote {


    public DefaultTreeModel getModel() throws java.rmi.RemoteException;

    public void addNodeAction() throws java.rmi.RemoteException;
}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());


            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);


            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.Timer;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.GUIRefreshAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());

            //Try a listener that doesn't use the Remote object
            t.addTreeSelectionListener(new RefreshTreeAction(this));

            //Try a property change listener on the TreeModel   
            t.addPropertyChangeListener("treeModel", new RefreshTreeAction(this));

            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);

            //Add a GUI redraw timer
            Timer timer = new Timer(1000, new GUIRefreshAction(this));
            timer.setInitialDelay(1);
            timer.start();

            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
客户端驱动程序类:

package server;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import client.controller.TestTreeControllerService;

import server.controller.TestTreeControllerImpl;


public class TestTreeServerStart {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new TestTreeServerStart();

    }

    public TestTreeServerStart() {

        try {

            LocateRegistry.createRegistry(1099);

            TestTreeControllerService c = new TestTreeControllerImpl();

             Registry registry = LocateRegistry.getRegistry();
             registry.rebind("TestTreeControllerService", c);

            System.out.println("Started the RMI Server");
        }
        catch (RemoteException e) {
            System.out.println(e.getMessage());
        }
    }

}
package server.controller;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import client.controller.TestTreeControllerService;



@SuppressWarnings("serial")
public class TestTreeControllerImpl extends UnicastRemoteObject implements TestTreeControllerService {

    /**
     * 
     */
    //private static final long serialVersionUID = -8137864611400855504L;
    private DefaultTreeModel m ;


    public DefaultTreeModel getModel() {

        return m;
    }


    public TestTreeControllerImpl() throws RemoteException {

        super();
        m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));

    }

    public void addNodeAction() throws RemoteException {
        DefaultTreeModel m = (DefaultTreeModel) getModel();
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
        root.add(newNode);
        //m.insertNodeInto(newNode, (DefaultMutableTreeNode) m.getRoot(), m.getChildCount(m.getRoot()));
        m.nodeStructureChanged(root);

    }

}
package client;
import java.rmi.Naming;
import java.rmi.RemoteException;

import client.controller.TestTreeControllerService;
import client.view.TreeTestClient;



public class TreeTestClientStart {

    /**
     * @param args
     */
    public static void main(String[] args) {


            try {
                TestTreeControllerService c = (TestTreeControllerService) Naming.lookup("rmi://localhost:1099/TestTreeControllerService");
                 new TreeTestClient(c);
            }
            catch(RemoteException e) {
                System.out.println("Remote service not found: " + e.getLocalizedMessage());
            }
            catch (Exception e) {
                System.out.println("Splat");
            }
    }

}
package client.controller;
import javax.swing.tree.DefaultTreeModel;


public interface TestTreeControllerService extends java.rmi.Remote {


    public DefaultTreeModel getModel() throws java.rmi.RemoteException;

    public void addNodeAction() throws java.rmi.RemoteException;
}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());


            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);


            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.Timer;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.GUIRefreshAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());

            //Try a listener that doesn't use the Remote object
            t.addTreeSelectionListener(new RefreshTreeAction(this));

            //Try a property change listener on the TreeModel   
            t.addPropertyChangeListener("treeModel", new RefreshTreeAction(this));

            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);

            //Add a GUI redraw timer
            Timer timer = new Timer(1000, new GUIRefreshAction(this));
            timer.setInitialDelay(1);
            timer.start();

            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
客户端控制器界面:

package server;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import client.controller.TestTreeControllerService;

import server.controller.TestTreeControllerImpl;


public class TestTreeServerStart {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new TestTreeServerStart();

    }

    public TestTreeServerStart() {

        try {

            LocateRegistry.createRegistry(1099);

            TestTreeControllerService c = new TestTreeControllerImpl();

             Registry registry = LocateRegistry.getRegistry();
             registry.rebind("TestTreeControllerService", c);

            System.out.println("Started the RMI Server");
        }
        catch (RemoteException e) {
            System.out.println(e.getMessage());
        }
    }

}
package server.controller;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import client.controller.TestTreeControllerService;



@SuppressWarnings("serial")
public class TestTreeControllerImpl extends UnicastRemoteObject implements TestTreeControllerService {

    /**
     * 
     */
    //private static final long serialVersionUID = -8137864611400855504L;
    private DefaultTreeModel m ;


    public DefaultTreeModel getModel() {

        return m;
    }


    public TestTreeControllerImpl() throws RemoteException {

        super();
        m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));

    }

    public void addNodeAction() throws RemoteException {
        DefaultTreeModel m = (DefaultTreeModel) getModel();
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
        root.add(newNode);
        //m.insertNodeInto(newNode, (DefaultMutableTreeNode) m.getRoot(), m.getChildCount(m.getRoot()));
        m.nodeStructureChanged(root);

    }

}
package client;
import java.rmi.Naming;
import java.rmi.RemoteException;

import client.controller.TestTreeControllerService;
import client.view.TreeTestClient;



public class TreeTestClientStart {

    /**
     * @param args
     */
    public static void main(String[] args) {


            try {
                TestTreeControllerService c = (TestTreeControllerService) Naming.lookup("rmi://localhost:1099/TestTreeControllerService");
                 new TreeTestClient(c);
            }
            catch(RemoteException e) {
                System.out.println("Remote service not found: " + e.getLocalizedMessage());
            }
            catch (Exception e) {
                System.out.println("Splat");
            }
    }

}
package client.controller;
import javax.swing.tree.DefaultTreeModel;


public interface TestTreeControllerService extends java.rmi.Remote {


    public DefaultTreeModel getModel() throws java.rmi.RemoteException;

    public void addNodeAction() throws java.rmi.RemoteException;
}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());


            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);


            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.Timer;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.GUIRefreshAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());

            //Try a listener that doesn't use the Remote object
            t.addTreeSelectionListener(new RefreshTreeAction(this));

            //Try a property change listener on the TreeModel   
            t.addPropertyChangeListener("treeModel", new RefreshTreeAction(this));

            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);

            //Add a GUI redraw timer
            Timer timer = new Timer(1000, new GUIRefreshAction(this));
            timer.setInitialDelay(1);
            timer.start();

            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
客户端用户界面:

package server;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import client.controller.TestTreeControllerService;

import server.controller.TestTreeControllerImpl;


public class TestTreeServerStart {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new TestTreeServerStart();

    }

    public TestTreeServerStart() {

        try {

            LocateRegistry.createRegistry(1099);

            TestTreeControllerService c = new TestTreeControllerImpl();

             Registry registry = LocateRegistry.getRegistry();
             registry.rebind("TestTreeControllerService", c);

            System.out.println("Started the RMI Server");
        }
        catch (RemoteException e) {
            System.out.println(e.getMessage());
        }
    }

}
package server.controller;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import client.controller.TestTreeControllerService;



@SuppressWarnings("serial")
public class TestTreeControllerImpl extends UnicastRemoteObject implements TestTreeControllerService {

    /**
     * 
     */
    //private static final long serialVersionUID = -8137864611400855504L;
    private DefaultTreeModel m ;


    public DefaultTreeModel getModel() {

        return m;
    }


    public TestTreeControllerImpl() throws RemoteException {

        super();
        m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));

    }

    public void addNodeAction() throws RemoteException {
        DefaultTreeModel m = (DefaultTreeModel) getModel();
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
        root.add(newNode);
        //m.insertNodeInto(newNode, (DefaultMutableTreeNode) m.getRoot(), m.getChildCount(m.getRoot()));
        m.nodeStructureChanged(root);

    }

}
package client;
import java.rmi.Naming;
import java.rmi.RemoteException;

import client.controller.TestTreeControllerService;
import client.view.TreeTestClient;



public class TreeTestClientStart {

    /**
     * @param args
     */
    public static void main(String[] args) {


            try {
                TestTreeControllerService c = (TestTreeControllerService) Naming.lookup("rmi://localhost:1099/TestTreeControllerService");
                 new TreeTestClient(c);
            }
            catch(RemoteException e) {
                System.out.println("Remote service not found: " + e.getLocalizedMessage());
            }
            catch (Exception e) {
                System.out.println("Splat");
            }
    }

}
package client.controller;
import javax.swing.tree.DefaultTreeModel;


public interface TestTreeControllerService extends java.rmi.Remote {


    public DefaultTreeModel getModel() throws java.rmi.RemoteException;

    public void addNodeAction() throws java.rmi.RemoteException;
}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());


            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);


            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
package client.view;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.Timer;

import client.controller.TestTreeControllerService;
import client.view.action.AddNodeAction;
import client.view.action.GUIRefreshAction;
import client.view.action.RefreshTreeAction;



public class TreeTestClient {

    private JTree t;
    private TestTreeControllerService c;

    public JTree getTree() {
        return t;
    }

    public TestTreeControllerService getController() {
        return c;
    }

    public void setTree(JTree tIn) {
        t = tIn;
    }

    public TreeTestClient(TestTreeControllerService cIn) {

        //Add controller
        try {
            c = cIn;

            //Draw Frame & Panel  - set dimensions
            JFrame f = new JFrame();
            f.setSize(new Dimension(800,600));
            JPanel p = new JPanel();
            p.setSize(new Dimension(800,600));

            //Create a tree and add the Model from the Controller to it
            t = new JTree();
            t.setModel(c.getModel());

            //Try a listener that doesn't use the Remote object
            t.addTreeSelectionListener(new RefreshTreeAction(this));

            //Try a property change listener on the TreeModel   
            t.addPropertyChangeListener("treeModel", new RefreshTreeAction(this));

            //Try a Tree Model Listener
            t.getModel().addTreeModelListener(new RefreshTreeAction(this));

            //Add listener to a button which adds nodes to the tree when clicked
            JButton addNode = new JButton("Add node");
            addNode.addActionListener(new AddNodeAction(this));

            JScrollPane s = new JScrollPane(t);

            //Add a GUI redraw timer
            Timer timer = new Timer(1000, new GUIRefreshAction(this));
            timer.setInitialDelay(1);
            timer.start();

            p.add(s);
            p.add(addNode);

            p.setVisible(true);
            f.add(p);
            f.setVisible(true);
    }
    catch(Exception e) {
        System.out.println("Splat");
    }
    }

}
*客户端“添加节点”操作侦听器(在控制器中调用添加操作)*

客户端“刷新操作”树侦听器(打印到屏幕以证明侦听器已启动)


服务器导出的TreeModel作为客户端自己的副本序列化到客户端。服务器不知道客户端副本发生了什么,客户端也不知道服务器副本发生了什么。它们不是同一个对象。

通过向订阅GUI上新按钮的ActionListener添加以下代码,我可以在单击按钮时检查模型的内容:

                //Loop contents of model attached to Client Tree
                for (int i=0; i<t.getModel().getChildCount(t.getModel().getRoot()); i++) {
                        System.out.println("From Tree: Row #" + i + ": " + t.getModel().getChild(t.getModel().getRoot(), i));
                }

                //Loop contents of model object stored in Controller
                try {
                    for (int i=0; i<c.getModel().getChildCount(c.getModel().getRoot()); i++) {
                        System.out.println("From Controller: Row #" + i + ": " + c.getModel().getChild(c.getModel().getRoot(), i));
                    }
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
GUI刷新侦听器类

package client.view.action;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;

import client.view.TreeTestClient;

public class GUIRefreshAction implements ActionListener {

    private TreeTestClient client;

    public GUIRefreshAction(TreeTestClient clientIn) {
        client = clientIn;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        //Update the Tree's Model to match latest on Server
        try {
            client.getTree().setModel(client.getController().getModel());
        } catch (RemoteException e1) {
            e1.printStackTrace();
        }

    }

}

我希望这有助于对RMI客户端Swing GUI有相同要求的人根据服务器上的更改进行更新。

根据RMI跟踪:“远程对象基本上是通过引用传递的。远程对象引用是存根,它是实现远程对象实现的完整远程接口集的客户端代理“。如果远程对象通过引用传递给存根,那么当它们的状态发生变化时,任何与存根交互的客户端类都可以观察到它。@7SpecialGems树模型不是远程对象;它不是通过引用传递的;正如我在上面写的那样,它被序列化,即通过值传递。它们不是同一个对象。