Skip to content
Sandny Blog
  • Home
  • Java
  • JavaScript
  • AWS
  • Embedded
  • About
Java RMI Slider Java

JAVA RMI Observer Slider

  • May 18, 2017July 26, 2021
  • by Coder Kai

How To Make A Slider With RMI Server

First of all, let’s take a look at the RMI structure.
RMI is can be used to run a server and to connect several clients to the given server. It can be loosely coupled with the design patterns to optimise scalability.

 

The thing is, for this architecture to work well, you should loosely couple all classes.

I have used MVC design pattern to design this project. So the client will have a Controller to get the slider position and a JFrame to view.

The controller will have two methods getValue and setValue to deal with slider value of clients. For RMI structure, controller should be implementing am interface to implement these methods

  • public int getValue();
  • public voidsetValue(int value);

So this will be the standalone structure of the client-side. So now we can add RMI Architecture to this

How to add RMI Observers

Observer design pattern can be used in any application with Observer and Observable classes in java.util package. But these cannot be used with RMI. So we have to create Observers with RMI Architecture.

Let’s see how to use RMI with observers. First, let’s create the RemoteObserver class the Here Remote class is found in java.rmi package.

REMOTEOBSERVER

 

package rmi; 
 
import java.rmi.Remote; 
import java.rmi.RemoteException; 
 
public interface RemoteObserver extends Remote { 
 
    public void update(RemoteObservable o, Object arg) throws RemoteException; 
}

 

REMOTEOBSERVERIMPL

public class RemoteObserverImpl extends UnicastRemoteObject implements RemoteObserver { 
 
    private RemoteObserver ob; 
 
    public RemoteObserverImpl(JFrame o) throws ClassCastException, RemoteException { 
        this.ob = (RemoteObserver) o; 
    } 
 
    @Override 
    public void update(RemoteObservable o, Object arg) throws RemoteException { 
        ob.update(o, arg); 
    } 
}

 

REMOTEOBSERVERIMPL

Note: Here we have used a bit different way to use observers. As swings cannot be casted for Remote, it cannot be used with RMI. So we use RemoteObserver implemented class . Observable class should be coded with extending UnicastRemoteObject in java.rmi. And also it must be implementing an interface throwing RemoteException. Therefore we will have to code a RemoteObservable class
Note: Here RemoteObservable is an interface extending Remote. Its code is below.

import java.rmi.Remote; 
import java.rmi.RemoteException; 
 
public interface RemoteObservable extends Remote { 
   public void addObserver (RemoteObserver o) throws RemoteException; 
    public  void deleteObserver(RemoteObserver o)throws RemoteException; 
    public void notifyObservers() throws RemoteException; 
    public void notifyObservers(Object arg)  throws RemoteException; 
    public  boolean hasChanged()throws RemoteException; 
    public  int countObservers()throws RemoteException; 
    public void deleteObservers() throws RemoteException; 
    public void setChanged() throws RemoteException; 
}

 

Note: Below is the RemoteObservableImpl class that implements and does the job.

import java.rmi.RemoteException; 
import java.rmi.server.UnicastRemoteObject; 
import java.util.ArrayList; 
import java.util.Observer; 
 
public class RemoteObservableImpl extends UnicastRemoteObject implements RemoteObservable{ 
    private boolean changed = false; 
    private ArrayList obs; 
 
 
    public RemoteObservableImpl() throws RemoteException { 
        obs = new ArrayList (); 
    } 
 
    @Override 
    public synchronized void addObserver(RemoteObserver o) throws RemoteException { 
        if (o == null) 
            throw new NullPointerException (); 
        if (!obs.contains(o)) { 
            obs.add(o); 
            System.out.println("Observer Added size "+obs.size()); 
        } 
    } 
 
    @Override 
    public synchronized void deleteObserver(RemoteObserver o) throws RemoteException { 
        obs.remove(o); 
    } 
 
    @Override 
    public void notifyObservers() throws RemoteException { 
        notifyObservers(null); 
    } 
 
    @Override 
    public void notifyObservers (Object arg) throws RemoteException { 
        Object[] arrLocal; 
 
        synchronized (this) { 
            if (!changed) 
                return; 
            arrLocal = obs.toArray(); 
            System.out.println ("obs arr size"+obs.size()); 
            clearChanged(); 
        } 
        System.out.println(""+arg+"  arrSize   "+ arrLocal.length ); 
        for  (int i = arrLocal.length-1; i>=0; i--){ 
            RemoteObservable impl=this; 
            ((RemoteObserver)arrLocal[i]).update (impl, arg); 
        } 
    } 
 
    @Override 
    public synchronized void deleteObservers() throws RemoteException { 
        obs.clear(); 
    } 
 
    @Override 
    public synchronized void setChanged() throws RemoteException { 
        changed = true; 
    } 
 
    protected synchronized void clearChanged() { 
        changed = false; 
    } 
 
    @Override 
    public synchronized boolean hasChanged() throws RemoteException { 
        return changed; 
    } 
 
    @Override 
    public synchronized int countObservers() throws RemoteException{ 
        return obs.size(); 
    } 
}

 

This is basically the original Remote Observer just edited to be Remote.
Let’s see how to make use of them in our project.

What we have to do is making our controller class extending RemoteObservableImpl overriding methods that we want to use to invoke observers.

package controller; 
import java.rmi.RemoteException; 
import rmi.RemoteObservableImpl; 
import rmi.RemoteObserver; 
 
public class Controller extends RemoteObservableImpl { 
    private int value; 
 
    public Controller()  throws RemoteException { 
    } 
 
    public int getValue()   throws RemoteException{ 
        return value; 
    } 
 
    public void setValue (int value)  throws RemoteException{ 
        this.value = value; 
    } 
 
    @Override 
    public synchronized void setChanged() throws RemoteException{ 
        super.setChanged(); 
    } 
 
    @Override 
    public void notifyObservers ()  throws RemoteException{ 
        super.notifyObservers(); 
    } 
 
    @Override 
    public void notifyObservers (Object arg)  throws RemoteException{ 
        super.notifyObservers(arg); 
    } 
 
    @Override 
    public synchronized void addObserver(RemoteObserver o)   throws RemoteException{ 
        super.addObserver(o); 
    } 
}

Now make a RemoteController that have UnicastRemoteObject. We can do this by keeping an object in a RemoteControllerImpl class.
The classes are as follows

REMOTECONTROLLER

What we do here is make an interface to cast RemoteContollerImpl class from the registry. Don’t forget to throw RemoteException unless it will cause a runtime error.

import java.rmi.Remote; 
import java.rmi.RemoteException; 
import rmi.RemoteObserver; 
 
public interface RemoteController extends Remote{ 
    public int getValue() throws RemoteException; 
    public void setValue(int value) throws RemoteException; 
    public void setChanged() throws RemoteException; 
    public void notifyObservers() throws RemoteException; 
    public void notifyObservers(Object arg)  throws RemoteException; 
    public void addObserver (RemoteObserver o) throws RemoteException; 
}

 

REMOTECONTROLLERIMPL

package rmi.controller; 
 
import controller.RemoteController; 
import controller.Controller; 
import java.rmi.RemoteException; 
import java.rmi.server.UnicastRemoteObject; 
import rmi.RemoteObserver; 
 
public class RemoteControllerImpl extends UnicastRemoteObject implements RemoteController{ 
 
    private Controller controller; 
    public RemoteControllerImpl()  throws RemoteException { 
        controller=new Controller(); 
    } 
 
    @Override 
    public int getValue()  throws RemoteException{ 
        return controller.getValue(); 
    } 
 
    @Override 
    public void setValue (int value)  throws RemoteException{ 
        controller.setValue(value); 
    } 
 
    @Override 
    public void setChanged()   throws RemoteException{ 
        controller.setChanged(); 
    } 
 
    @Override 
    public void notifyObservers ()  throws RemoteException{ 
        controller.notifyObservers(); 
    } 
 
    @Override 
    public void notifyObservers (Object arg)  throws RemoteException{ 
        controller.notifyObservers(arg); 
    } 
 
    @Override 
    public void addObserver (RemoteObserver o)  throws RemoteException{ 
        controller.addObserver(o); 
    } 
}

 

 

 

REMOTEFACTORY

import controller.RemoteController; 
import java.rmi.Remote; 
import java.rmi.RemoteException; 
 
public interface RemoteFactory  extends Remote{ 
    public RemoteController getController()  throws RemoteException; 
}

 

REMOTEFACTORYIMPL

 

import controller.RemoteController; 
import java.rmi.RemoteException; 
import java.rmi.server.UnicastRemoteObject; 
import rmi.controller.RemoteControllerImpl; 
 
public class RemoteFactoryImpl extends UnicastRemoteObject implements RemoteFactory { 
    private RemoteController c; 
 
    public RemoteFactoryImpl() throws RemoteException  { 
        c=new RemoteControllerImpl(); 
    } 
    @Override 
    public RemoteController getController() throws RemoteException{ 
        return c; 
    } 
}

 

Right. Now we have to make a server to bind this factory object to the Registry. Here I’m going to use just a main method to start the server.

REMOTESERVER

 

  
package rmi.server; 
 
import java.rmi.RemoteException; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import rmi.factory.RemoteFactory; 
import rmi.factory.RemoteFactoryImpl; 
 
public class RemoteServer { 
    public static void startServer(){ 
        try { 
            RemoteFactory rf=new RemoteFactoryImpl (); 
            Registry createRegistry = LocateRegistry.createRe gistry(5050); 
            createRegistry.rebind("server", rf); 
            System.out.println("server started.... "); 
        } catch (RemoteException ex)  { 
            Logger.getLogger (RemoteServer.class.getName()).log(Level.SEVERE, null, ex); 
        } 
    } 
    public static void main(String[] args)  { 
        startServer(); 
    } 
}

The Server is over.

Now let’s make the slider frame. Use NetBeans to make this easily. I just wanted to show how it is done.

package view; 
 
import java.awt.BorderLayout; 
import java.rmi.RemoteException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JFrame; 
import javax.swing.JSlider; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import rmi.RemoteObservable; 
import rmi.RemoteObserver; 
import rmi.RemoteObserverImpl; 
import rmi.connector.RemoteConnector; 
import rmi.controller.RemoteController; 
 
public class Main extends JFrame implements RemoteObserver{ 
 
    private RemoteController controller; 
    private JSlider sldMain; 
 
    public Main() { 
        setSize(400, 100); 
        setLayout(new BorderLayout()); 
        sldMain=new JSlider(0,100); 
        setDefaultCloseOperation(EXIT_ON_CLOSE); 
        try { 
            controller=(RemoteController) RemoteConnector.getRf ().getController(); 
 
            controller.addObserver(new RemoteObserverImpl (this)); 
        } catch  (RemoteException ex) { 
            Logger.getLogger(Slider.class.getName()).log (Level.SEVERE, null, ex); 
        } 
        this.add("North", sldMain); 
        sldMain.addChangeListener(new ChangeListener() { 
 
            @Override 
            public void stateChanged(ChangeEvent e)  { 
                try { 
                    if(controller! = null){ 
                         int value=sldMain.getValue(); 
                         controller.setValue(value); 
                         controller.setChanged(); 
                         controller.notifyObservers("changed"); 
                    } 
                } catch  (RemoteException ex) { 
                    Logger.getLo gger(Slider.class.getName()).log(Level.SEVERE, null, ex); 
                } 
            } 
        }); 
    } 
    @Override 
    public void update(RemoteObservable o, Object arg)  throws RemoteException { 
        try { 
            int value = controller.getValue(); 
            sldMain.setValue(value); 
        } catch (RemoteException ex)  { 
            Logger.getLogger (Main.class.getName()).log(Level.SEVERE, null, ex); 
        } 
    } 
    public static void main(String[] args)  { 
        new Main().setVisible (true); 
    } 
}

 

Now it’s over. Just make sure you run the projects correctly. To work this properly you have to make a Common Project with all classes needed for both Server and the Client.
Start the server.
Start any number of clients.
Move the slider and see how others change the position.

All you must remember when using RMI is,

  1. Always throw RemoteException in interfaces and override them correctly.
  2. Always use the reference type of the interface to bind to the registry.
  3. Objects should be cast to the interface for objects that are looked up in the registry.

That’s all I think. This is just an example how to use RMI Observers. Can be a crap. But develop this for server-client architecture or for a chat system.

Jasper Subreporting for a CV generator
Servlet File Upload
Coder Kai
A humble developer
java remote remote method invocation rmi rmi slider

Related articles

String.lines()
How to convert a string…
How to avoid NullPointerException in Java
How to avoid NullPointerException in…
The new features in Java 14
JDK 14 – The new…
Java 13 features
Java 13 (JDK 13) -The…
Java 13 Switch Expressions
How to enable preview feature in Java 13 with maven.
Enable the Preview Feature in…
create a Vertx Eventbus js client
How to create a Vertx…
neo4j boltdriver
How to create a neo4j…
Servlet File Upload
Servlet File Upload

Categories

  • android 3
  • Apollo Client 1
  • AWS 8
    • AppSync 5
    • EC2 1
    • EKS 1
    • Route53 1
    • S3 1
  • AWS Amplify 1
  • Chakra UI 1
  • Docker 1
  • Embedded 1
  • EmberJS 1
  • FCM 1
  • Godaddy 1
  • GraphQL 3
  • ios 1
  • Jasper 1
  • Java 10
    • Java 11 1
    • Java 14 1
  • JavaEE 2
  • JavaScript 39
    • Express.js 4
    • Javascript Guide 7
    • Node.js 3
    • react-native 4
    • React.js 17
    • Typescript 1
  • Kubernetes 1
  • machine learning 1
  • Maven 2
  • OCaml 3
  • PostgreSQL 1
  • Python 2
  • react-native 4
  • ReactJS 3
  • sass 1
  • Server 6
  • spark 1
  • Terraform 2
  • Ubuntu 4
  • Uncategorized 1
  • webpack 2

Recent Comments

  • Michaelpex on Why did Facebook pick OCaml?
  • Dang k'y binance us on 03. Javascript Guide – Strings
  • Registrati on Use AWS GraphQL for React Native Message App

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Archives

  • October 2022 3
  • September 2022 7
  • May 2022 1
  • December 2021 1
  • August 2021 1
  • July 2021 6
  • June 2021 3
  • February 2021 1
  • July 2020 1
  • December 2019 5
  • November 2019 6
  • October 2019 3
  • August 2019 1
  • March 2019 1
  • February 2019 1
  • January 2019 2
  • December 2018 1
  • September 2018 2
  • August 2018 1
  • June 2018 1
  • February 2018 1
  • November 2017 2
  • October 2017 5
  • September 2017 1
  • June 2017 1
  • May 2017 10
Sandny Blog space
Theme by Colorlib Powered by WordPress