?
Solved

Any method that is remotely invoked will not interact with the GUI

Posted on 2009-02-18
21
Medium Priority
?
318 Views
Last Modified: 2012-05-06
Something very strange is happening (probably me doing something wrong). But when any method gets called remotely, it will ignore any interaction with the GUI.
For example:

public void recieveMessage(String message) throws RemoteException {
        System.out.println("HERE " + message); //prints out fine
        messageBox.setText("Message: "); //nothing displayed
        System.out.println("HERE " + message); //prints out fine
    }

I have also tried different method calls which would set a button to visible, but the code is ignored then aswell.
Any Ideas???
Regards
Joe
0
Comment
Question by:dajoebomb
  • 11
  • 8
  • 2
21 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 23668922
You need to update the GUI on the correct Thread. See EventQueue.invokeLater or use SwingWorker
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 600 total points
ID: 23668958
Best to use a utility class:
public void recieveMessage(String message) throws RemoteException {
     EventQueue.invokeLater(new MessageDisplayer(message));
}
 
private class MessageDisplayer implements Runnable {
	private String message;
 
	public MessageDisplayer(String message) {
		this.message = message;
	}
 
	public void run() {
		messageBox.setText(message);
	}
}

Open in new window

0
 

Author Comment

by:dajoebomb
ID: 23669716
Hi CEHJ,
Thanks for your very quick reply. Sorry for my very slow one.

I have implemented that utility class, but it still only works on the one client.
I added System.out.println("recieved message " + message);
and i got back :
recieved message a:  Hello
recieved message q:  Hello Back
But the text just didnt go into the jTextArea.
Do you have any other ideas?
I tried a swing worker too: but not sure if I did it correctly because that didnt work either



        SwingWorker sw = new SwingWorker() {
 
            @Override
            protected Object doInBackground() throws Exception {
                System.out.println("gets here" + un);
                    btnBut1.setVisible(true);
                }
                return "Done";
            }
        };
        sw.execute();

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 86

Expert Comment

by:CEHJ
ID: 23669738
>>btnBut1.setVisible(true);

should be in the done() method
0
 

Author Comment

by:dajoebomb
ID: 23669848
I put that code in done() and it still didn't work.
Well for some reason it only works on 1 client.
If Client A connectes first, messages will be displayed in the GUI fine, but Client B will not have anythng in the GUI. But both clients will recieve the message because it is displayed by System.out.println

Would it help to see my server code at all? or is that irrelivant because both clients are recieving the message?

public void recieveMessage(final String message) throws RemoteException {
        System.out.println("recieved message " + message);
        //EventQueue.invokeLater(new MessageDisplayer(message));
        
        SwingWorker sw = new SwingWorker() {
 
            @Override
            protected Object doInBackground() throws Exception {
                return "Done";
            }
            
            @Override
             public void done() {
                messageBox.setText(message);
            }
        };
        sw.execute();
    }

Open in new window

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 23669873
Firstly let's backtrack a little. Is the EventQueue version working OK?
0
 

Author Comment

by:dajoebomb
ID: 23669900
Partly. It only works on the first client that connects to the server.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 23669986
OK - but that goes for SwingWorker too, so the answer's effectively yes. Let's stick with that as SW is not appropriate - you don't need another worker thread.

So is the client code identical in each case?
0
 

Author Comment

by:dajoebomb
ID: 23670003
The same effect happens weather I use EventQueue, SwingWorker or do not have anything at all.
The first Client to connect will have all messages(including their own) put into the jTextArea called MessageBox.

I'll include the server code just encase you spot anything I have done wrong:

    public void sendMessage(String message){
        Collection c = clients.values();
        Iterator it = c.iterator();
        
        try {
            while (it.hasNext()) {
                System.out.println("MessageSent");
                ClientInterface ci = (ClientInterface)it.next();
                ci.recieveMessage(message);
            }
        } catch (RemoteException ex) {
            Logger.getLogger(PokerTable.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Open in new window

0
 

Author Comment

by:dajoebomb
ID: 23670008
Yes the client code is Identical.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 23670263
So in all cases:

System.out.println("HERE " + message); //prints out fine

is OK, but the GUI gets updated only once
0
 

Author Comment

by:dajoebomb
ID: 23671647
No, the GUI only gets updated on client A, it never gets update on client B, but on both clients
System.out.println("HERE " + message); //prints out fine
0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 600 total points
ID: 23671970
The only thing i can think of at this point is that something else occurs after the receipt of the first message that's blocking the EDT such that it won't update, even with invokeLater
0
 
LVL 92

Expert Comment

by:objects
ID: 23675367
can you post some more context. The code you already have in the question appears fine.
Are you sure messageBox is referencing the correct component?
0
 

Author Comment

by:dajoebomb
ID: 23679938
I couldn't think at all last night, thinking of the possibilities of what this could be. I came up with two possibilities.
1. Client A creates the Room, and Client B joins the room, so maybe there is something wrong with my code, maybe to do with pass-by-value and pass-by-reference.
2. I am using the server in a Virtual machine under Ubuntu. There is a problem with Linux under a VM where in the hosts file, it puts :
127.0.0.1      localhost
127.0.1.1      chatserver

where chatserver is the name of the machine. This causes errors with RMI. So i read that you had to change it to the IP address of your machine, so i changed it to :
127.0.0.1      localhost
192.168.1.4      chatserver

where 192.168.1.4 is the IP address of the machine. Things seemed to work then and connections happened, so i presumed it was fine, but could be a problem now.
private void joinTable() {
        try {
             Registry registry = LocateRegistry.getRegistry(Constants.SERVERIP, Constants.SERVERPORT);
            Constants.lobbyStub = (LobbyCommands) registry.lookup("Commands");
            String s = (String) availableTablestbl.getValueAt(availableRoomstbl.getSelectedRow(), availableRoomstbl.getColumnCount()-1);
            int roomNo = Integer.parseInt(s);
            RoomGUI rGUI = null;
            Room r = (Room) Constants.lobbyStub.getRoom(roomNo);
            Registry reg = LocateRegistry.createRegistry(1099);
            rGUI = new RoomGUI(r, user);
            Naming.rebind("CLIENT", rGUI);
            RoomGUI obj = new RoomGUI(r,user);
            ClientInterface stub = (ClientInterface) UnicastRemoteObject.exportObject(obj, 0);
            if(Constants.lobbyStub.joinRoom(user, roomNo, stub)){
                rGUI.setVisible(true);
                Constants.roomStub.addClient(username, stub);
            }
            else{
            JOptionPane.showMessageDialog(null, "Room is full, refresh  list and try to join again, or pick an alternative Room");
            }
        } catch (NotBoundException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (AccessException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MalformedURLException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RemoteException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
 
 
 
private void createRoombtnActionPerformed(java.awt.event.ActionEvent evt) {                                               
    try {
        Registry registry = LocateRegistry.getRegistry(Constants.SERVERIP, Constants.SERVERPORT);
        Constants.lobbyStub = (LobbyCommands) registry.lookup("Commands");
        Room response = null;
 
 
            response = Constants.lobbyStub.createRoom(user, roomNametxt.getText(), Integer.parseInt(maxChattersCombo.getSelectedItem().toString()));
 
        if (response != null) {
            this.setVisible(false);
            RoomGUI tableGUI = new RoomGUI(response, user);
            roomGUI.setVisible(true);
 
            Registry reg = LocateRegistry.createRegistry(1099);
            Naming.rebind("POKERCLIENT", roomGUI);
            RoomGUI obj = roomGUI;
            ClientInterface stub = (ClientInterface) UnicastRemoteObject.exportObject(obj, 0);
            Constants.roomStub.addClient(user.getUserName(), stub);
        } else {
            JOptionPane.showMessageDialog(null, "An error has occurred");
            }                                              
        } catch (MalformedURLException ex) {
            Logger.getLogger(CreateTableGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotBoundException ex) {
            Logger.getLogger(CreateTableGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (AccessException ex) {
            Logger.getLogger(CreateTableGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RemoteException ex) {
            Logger.getLogger(CreateTableGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Open in new window

0
 

Author Comment

by:dajoebomb
ID: 23679951
That should read "I couldn't sleep at all last night, thinking of..."
0
 
LVL 92

Expert Comment

by:objects
ID: 23680012
you need to be very careful with RMI and GUI's *Most* calls to your gui need to be done on the event dispatch thread, or the behaviour of your gui can become indeterminate.
But you also don't want any slow operations to be on the event dispatch thread as it will freeze your gui.
That means its important to have strong seperation between the gui and your business logic.

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 23680055
dajoebomb: that's quite a complex series of diagnoses since, according to you, the code is working, bar the gui message showing ...
0
 

Author Comment

by:dajoebomb
ID: 23680114
I think to rule out some of the diagnosis I will try and organise three computers and not have any VM's running.
I will post my results (hopefully later on today).
0
 

Author Comment

by:dajoebomb
ID: 23684266
Ahhhh finally sorted it out. It was problem number 1 in my diagnostics (although I thought it was going to be number 2).

The code just needed some rejigging. I think that the room object it was referencing was not the room object that i had on my GUI.

Just wanted to say a huge thank you to CEHJ. You really helped me with diagnosing the problem and also explained about SwingWorkers and EventQueue.
FROM:
private void joinTable() {
        try {
             Registry registry = LocateRegistry.getRegistry(Constants.SERVERIP, Constants.SERVERPORT);
            Constants.lobbyStub = (LobbyCommands) registry.lookup("Commands");
            String s = (String) availableTablestbl.getValueAt(availableRoomstbl.getSelectedRow(), availableRoomstbl.getColumnCount()-1);
            int roomNo = Integer.parseInt(s);
            RoomGUI rGUI = null;
            Room r = (Room) Constants.lobbyStub.getRoom(roomNo);
            Registry reg = LocateRegistry.createRegistry(1099);
            rGUI = new RoomGUI(r, user);
            Naming.rebind("CLIENT", rGUI);
            RoomGUI obj = new RoomGUI(r,user);
            ClientInterface stub = (ClientInterface) UnicastRemoteObject.exportObject(obj, 0);
            if(Constants.lobbyStub.joinRoom(user, roomNo, stub)){
                rGUI.setVisible(true);
                Constants.roomStub.addClient(username, stub);
            }
            else{
            JOptionPane.showMessageDialog(null, "Room is full, refresh  list and try to join again, or pick an alternative Room");
            }
        } catch (NotBoundException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (AccessException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MalformedURLException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RemoteException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
TO:
 
private void joinTable() {
        try {
             Registry registry = LocateRegistry.getRegistry(Constants.SERVERIP, Constants.SERVERPORT);
            Constants.lobbyStub = (LobbyCommands) registry.lookup("Commands");
            String s = (String) availableTablestbl.getValueAt(availableRoomstbl.getSelectedRow(), availableRoomstbl.getColumnCount()-1);
            int tableNo = Integer.parseInt(s);
            RoomGUI rGUI = null;
            Room r = (Room) Constants.lobbyStub.getRoom(roomNo);
            rGUI = new RoomGUI(r, user);
            
            Constants.roomStub = (RoomCommands) registry.lookup("Commands");
 
            Registry reg = LocateRegistry.createRegistry(1099);
            Naming.rebind("CLIENT", rGUI);
            RoomGUI obj = rGUI;
            ClientInterface stub = (ClientInterface) UnicastRemoteObject.exportObject(obj, 0);
            Constants.roomStub.addClient(user.getUserName(), stub);
 
            if(Constants.lobbyStub.joinRoom(user, roomNo, stub)){
                rGUI.setVisible(true);
                this.setVisible(false);
                Constants.roomStub.addClient(username, stub);
            }
            else{
            JOptionPane.showMessageDialog(null, "Room is full, refresh list and try to join again, or pick an alternative Room");
            }
        } catch (NotBoundException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (AccessException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MalformedURLException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RemoteException ex) {
            Logger.getLogger(LobbyGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Open in new window

0
 

Author Closing Comment

by:dajoebomb
ID: 31548194
Thanks!
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Most of the developers using Tomcat find it easy to configure the datasource in Server.xml and use the JNDI name in the code to get the connection.  So the default connection pool using DBCP (or any other framework) is made available and the life go…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Suggested Courses
Course of the Month15 days, 6 hours left to enroll

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question