Passing Swing classes (references) on network?
I want to know that is it possible to send major Swing classes event/actionlisteners, Events, components via RMI.
Possible scenario: If one client press the button or move the slider every client's button or slider move etc same for other swing elements.
I am expecting the answer in the context of RMI and swing MVC architecture, i want to call the swing component's models e.g ButtonModel and want to send swing ActionEvent on wire and register PropertyChangeListener/PropertyChangeSupport as remote objects for getting updates at client site.
typical examples : the server s开发者_JS百科hould call this method for each client, when ever some change occur in model
public void propertyChange(PropertyChangeEvent evt) {
for (AbstractViewPanel view: registeredViews) {
view.modelPropertyChange(evt);
}
}
in case of an event on one client, each client actionPerformed should be called from server:
@Override
public void actionPerformed(ActionEvent e) {
}
is it feasible? if not then why? where i could face the problems, i mean which classes are transferable (serialized) and which are not...
EDIT: here you see i m invoking Java Swing defaultbuttonmodel remotely, the only thing left when some of it's property or method change the other client's get updates, best would be following swing propertychangelistener if someone can just help me, realizing this, it would be great:
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();
}
}
I think it would be more efficient to send across something like a "scroll message" or "button pressed" message, utilizing the command pattern. This would allow different clients to act correctly with different implementations.
Edits:
the way I do it in my client/server applications (which is easily adapted to this peer-to-peer architecture you're doing) is with something like this (copy and pasted from my production code, mind you.)
abstract public class UserRequest implements Serializable {
public final String username;
private transient ServersideThread thread;
protected UserRequest(String username) {
this.username = username;
this.thread = null;
}
abstract public EngineMessage engineCallback(GenericEngine engine);
public void setThread(ServersideThread thread) {
if(this.thread == null) {
this.thread = thread;
return;
}
throw new IllegalStateException("Cannot set thread when already set:" + thread.getName());
}
public ServersideThread getThread() {
return this.thread;
}
}
So, with this approach, I would do something like...
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.
}
}
}
The Javadoc for every Swing class says that it should not be serialized.
More probably you should be transmitting the associated Model classes.
And event listening via RMI is an anti-pattern. Too much traffic, too many points of failure.
精彩评论