Java 在网络上传递Swing类(引用)?

Java 在网络上传递Swing类(引用)?,java,model-view-controller,swing,user-interface,rmi,Java,Model View Controller,Swing,User Interface,Rmi,我想知道是否可以通过RMI发送主要的Swing类事件/动作监听器、事件和组件 可能的场景:如果一个客户端按下按钮或移动滑块,则每个客户端的按钮或滑块移动等与其他swing元素相同 我希望在RMI和swing MVC架构的上下文中得到答案,我希望调用swing组件的模型,例如ButtonModel,并希望在线发送swing ActionEvent,并将PropertyChangeListener/PropertyChangeSupport注册为远程对象,以便在客户端站点获取更新 典型例子: 当模型

我想知道是否可以通过RMI发送主要的Swing类事件/动作监听器、事件和组件

可能的场景:如果一个客户端按下按钮或移动滑块,则每个客户端的按钮或滑块移动等与其他swing元素相同

我希望在RMI和swing MVC架构的上下文中得到答案,我希望调用swing组件的模型,例如ButtonModel,并希望在线发送swing ActionEvent,并将PropertyChangeListener/PropertyChangeSupport注册为远程对象,以便在客户端站点获取更新

典型例子: 当模型发生变化时,服务器应该为每个客户机调用此方法

 public void propertyChange(PropertyChangeEvent evt) {
        for (AbstractViewPanel view: registeredViews) {
            view.modelPropertyChange(evt);
        }
    }
在一个客户端上发生事件的情况下,应从服务器调用执行的每个客户端操作:

@Override
public void actionPerformed(ActionEvent e)  {
}
可行吗?若否,原因为何?在我可能面临的问题中,我指的是哪些类是可转移的(序列化的),哪些不是

编辑:在这里,您可以看到我正在远程调用Java Swing defaultbuttonmodel,当它的某些属性或方法更改其他客户端的get更新时,剩下的唯一一件事就是跟随Swing propertychangelistener如果有人能帮我,认识到这一点,那将非常好:

public class RemoteButtonModel extends UnicastRemoteObject implements Model {

    private ButtonModel model = new DefaultButtonModel() ;

    protected myModel() throws RemoteException {
        super();
    }


    @Override
    public void setEnabled(boolean b) throws RemoteException {
        if (isEnabled())
            model.setEnabled(false);
        else{
            model.setEnabled(true);   
           }
    }

    @Override
    public boolean isEnabled() throws RemoteException {
        return model.isEnabled();

    }
}

我认为使用命令模式,通过“滚动消息”或“按下按钮”消息发送消息会更有效。这将允许不同的客户机使用不同的实现正确操作

编辑: 我在我的客户机/服务器应用程序中执行此操作的方式(很容易适应您正在执行的对等体系结构)是这样的(请注意,从我的生产代码复制并粘贴)

所以,用这种方法,我会做一些像

public class SliderMoveNotification extends UserRequest {

    // need some way to say what slider moved
    public final int sliderId;
    public final int slideDistance;

    public SliderMoveNotification(String username) {
        super(username);
        sliderId = 0;
        sliderDistance = 0;
        throw new UnsupportedOperationException("Must supply a slider and a distance");
    }

    public SliderMoveNotification(String username, int sliderID, int slideDistance) {
        super(username);
        this.sliderId = sliderId;
        this.slideDistance = slideDistance;
    }

    public EngineMessage engineCallback(GenericEngine engine) {
        if(engine instanceof WindowEngine) {
            WindowEngine manager = (WindowEngine)engine;
            manager.slideWindow(sliderId,slideDistance);
            // you wouldn't need engine messages like I do in my client/server
            // relationship, but the idea stands.
        }

    }

}

每个Swing类的Javadoc都说不应该序列化它

更可能的情况是,您应该传输关联的模型类


通过RMI进行事件监听是一种反模式。太多的流量,太多的故障点。

更好的是,只发送事件。它有更多的信息,可以避免发明语义事件,例如“按下按钮”。(外部化可以处理可序列化的低效率。)@alphazero不同意。它将有一些可能不兼容的数据。我当然赞成发送消息对象(比某些字符串可靠得多…),但事件将特定于生成它的任何对象。没有太多的“烤”进去。源代码显然是特定于JVM的,但请注意最后一个括号。外部化可以简单地获取事件的类名。@glowcoder:您是说在接收字符串消息时触发其他客户端上的事件,可能是通过客户端回调。附言:如果您的网站有一些具体的实现,我将非常感激,因为我想了解不同解决方案的实现复杂性,所以我可以更进一步。@alphazero:您说的是将事件发送到服务器,然后将该事件作为参数发送到所有客户端的服务器回调…已经定义的侦听器方法是否足以处理回调,或者我需要单独的方法来处理这些事件的回调。这样做的目的是保持服务器上的JComponent模型类和仅发送的更改,以及客户端上的controller/view。我想使用Swing默认MVC支持,请参阅我的其他问题以了解详细信息。@Static Void Main:您询问过如何通过RMI发送Swing组件。我回答了。如果你不这么做,那很好。如果你的问题没有包含足够的上下文,也许你可以编辑它。
public class SliderMoveNotification extends UserRequest {

    // need some way to say what slider moved
    public final int sliderId;
    public final int slideDistance;

    public SliderMoveNotification(String username) {
        super(username);
        sliderId = 0;
        sliderDistance = 0;
        throw new UnsupportedOperationException("Must supply a slider and a distance");
    }

    public SliderMoveNotification(String username, int sliderID, int slideDistance) {
        super(username);
        this.sliderId = sliderId;
        this.slideDistance = slideDistance;
    }

    public EngineMessage engineCallback(GenericEngine engine) {
        if(engine instanceof WindowEngine) {
            WindowEngine manager = (WindowEngine)engine;
            manager.slideWindow(sliderId,slideDistance);
            // you wouldn't need engine messages like I do in my client/server
            // relationship, but the idea stands.
        }

    }

}