944,050 Members | Top Members by Rank

Ad:
  • Java Discussion Thread
  • Marked Solved
  • Views: 1060
  • Java RSS
You are currently viewing page 2 of this multi-page discussion thread; Jump to the first page
Nov 4th, 2009
0
Re: Issue with MouseListener
The error either has to do with memory consistency, or the fact that the InputStream class's read() method blocks while it waits for input (and the read() method gets called multiple times when you keep clicking on the Server's window when it is the client's turn). I'll figure it out soon enough. But if I don't, I think you should read about these avenues as well.

Update:

Ok, so this seems to be the issue: since read() blocks while it waits for input, when the client's receive() method is executed, all subsequent mouse clicks on the client "don't happen" until after the client finishes receiving the data via the read() method. So when you click out of order, you are putting an extra event on the thread which doesn't get executed until after read() is done. What you really want to do is "throw away" the click and pretend it didn't happen at all. But I think you need to multi-thread your application. Hopefully someone else on Daniweb will verify this so that I'm not unintentionally leading you astray, but as of now, I believe this to be accurate.
Last edited by BestJewSinceJC; Nov 4th, 2009 at 3:28 pm.
Reputation Points: 874
Solved Threads: 352
Posting Maven
BestJewSinceJC is offline Offline
2,758 posts
since Sep 2008
Nov 4th, 2009
0
Re: Issue with MouseListener
Okay, thanks!!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
chandini.david is offline Offline
14 posts
since Nov 2009
Nov 4th, 2009
1
Re: Issue with MouseListener
Sorry, took too long and couldn't edit my last post. Update:

Ok, so this seems to be the issue: since read() blocks while it waits for input, when the client's receive() method is executed, all subsequent mouse clicks on the client "don't happen" until after the client finishes receiving the data via the read() method. So when you click out of order, you are putting an extra event on the thread which doesn't get executed until after read() is done. What you really want to do is "throw away" the click and pretend it didn't happen at all. But I think you need to multi-thread your application. Hopefully someone else on Daniweb will verify this so that I'm not unintentionally leading you astray, but as of now, I believe this to be accurate.

This code will demonstrate to you what I'm talking about. If you look at the ClientTurn_flag variable, you'd expect that once you click (which calls receive() and sets ClientTurn_flag to false), the next time you clicked on the client's window, it should print out "wasn't client's turn". However, it doesn't do that, since the read() method is blocking the thread. In fact what *I think* happens is this. Lets say you run the program, then click:

1) Click client's window
-At this point ClientTurn_flag is true.
-client sends it's coordinates to the server.
-client calls receive method and waits for the server to take it's turn. The receive method calls read(), which blocks, so it just sits there waiting for the server to send it data. Now ClientTurn_flag is false, because it is set to false before read() is called.
-it is now the server's turn, and the server is sitting there waiting for you to click on it's window. ServerTurn_flag is true.

2) Click client's window again.
-Since the client is still sitting in the receive() method, which is blocking your thread, the mouse click doesn't happen yet. ClientTurn_flag is still false. Now you can basically think of your stack as looking like this:
first in line => receive() -> read()
next in line (behind both of the above) = mouse listener method.

3) Click server's window. Now you would wish that the client will receive the server's data and then ClientTurn_flag would be set to true. In fact, looking back at my logic, what I think is that after you click the server's window, the server calls its send method. Then the server calls receive() and waits for the client's turn and sets its ServerTurn_flag = false.
-Now, remember that read() was waiting on the client from part 2. Since the server just sent it's input, read() finishes in the client. At the end of read(), ClientTurn_flag = true. So now, in the client, since the next method call on the stack (from clicking on the window) was the mouse listener method, that mouse listener method gets called. But you never clicked anything while it was your turn! The click was done while it was the server's turn.
-After mouse listener method gets called, it calls send(), and it sends the coordinates of the mouse click from when you clicked earlier to the server. This may not cause a problem if the server happens to be waiting to receive, but I'm pretty sure that if you had clicked the client more times, or switched around the ordering of clicking on client and server, it would. You don't want this to happen because the server should always be ready to receive when the client wants to send and vice versa.

Anyway, I spent a good bit of time attempting to figure out and then explain your problem, so I sincerely hope that it is correct. You can test my sample program to confirm that it appears to be correct.. for example, when you click the mouse over and over, you can tell that read() is blocking because the print statements get printed out much later in the program. I believe you can solve your problem by multi-threading your application so that every time a mouse is clicked, it checks (in a separate thread!) to see if it is that Client's/Server's turn, and if not, the method call just returns.

Java Syntax (Toggle Plain Text)
  1. package game;
  2.  
  3. import java.awt.*;
  4. import java.awt.event.*;
  5. import java.io.*;
  6. import java.net.*;
  7.  
  8. import javax.swing.*;
  9.  
  10. public class Clientms2 extends JFrame implements MouseListener
  11. {
  12. private static final long serialVersionUID = 1L;
  13.  
  14. JFrame container;
  15. static InetAddress address;
  16. static Socket s;
  17. static String host = "localhost";
  18. static BufferedOutputStream bos;
  19. static OutputStreamWriter osw;
  20. static BufferedInputStream bis;
  21. static InputStreamReader isr;
  22. static int port = 5656;
  23. static String message;
  24. static boolean ClientTurn_flag = true;
  25. //static MouseListener l;
  26.  
  27. static int tempx, tempy;
  28. static int mouseX, mouseY;
  29. static StringBuffer x, y;
  30.  
  31. public Clientms2()
  32. {
  33. super("Client 1: Player 1");
  34. setSize(400, 400);
  35. setDefaultCloseOperation(EXIT_ON_CLOSE);
  36. this.setResizable(false);
  37. addMouseListener(this);
  38. try {
  39. address = InetAddress.getByName(host);
  40. s = new Socket(address, port);
  41. } catch(Exception e){System.out.println("You fail at socket programs sucka!!!");}
  42. }
  43.  
  44. public static void main(String args[])
  45. {
  46. Clientms2 client = new Clientms2();
  47. client.setVisible(true);
  48.  
  49.  
  50. }
  51.  
  52. @Override
  53. public void mouseClicked(MouseEvent e)
  54. {
  55. if (ClientTurn_flag){
  56. mouseX = e.getX();
  57. mouseY = e.getY();
  58. send(mouseX, mouseY);
  59. System.out.println("End of client's turn, client waiting to receive.");
  60. receive();
  61. }else{
  62. System.out.println("Wasn't clients turn");
  63. }
  64.  
  65. }
  66.  
  67. public void receive()
  68. {
  69. System.out.println("Receive method called, all subsequent clicks on the client's window" +
  70. "should now result in seeing 'wasn't client's turn'");
  71. ClientTurn_flag = false;
  72. try
  73. {
  74. do
  75. {
  76. bis = new BufferedInputStream(s.getInputStream());
  77. isr = new InputStreamReader(bis, "US-ASCII");
  78. } while(isr.ready() == true);
  79. x = new StringBuffer();
  80. y = new StringBuffer();
  81. while((tempx = isr.read()) != 13)
  82. x.append((char) tempx);
  83. String str = x.toString();
  84. mouseX = Integer.parseInt(str);
  85.  
  86. while((tempy = isr.read()) != 13)
  87. y.append((char) tempy);
  88. str = y.toString();
  89. mouseY = Integer.parseInt(str);
  90. ClientTurn_flag=true;
  91.  
  92. } catch (IOException e) { System.out.println("Error in client received"); }
  93. System.out.println("Client finished receiving");
  94. ClientTurn_flag= true;
  95.  
  96. }
  97.  
  98.  
  99. private void send(int xcor, int ycor)
  100. {
  101. try
  102. {
  103. bos = new BufferedOutputStream(s.getOutputStream());
  104. osw = new OutputStreamWriter(bos, "US-ASCII");
  105. message = (Integer.toString(xcor)) + (char) 13;
  106. osw.write(message);
  107. osw.flush();
  108. message = (Integer.toString(ycor)) + (char) 13;
  109. osw.write(message);
  110. osw.flush();
  111. ClientTurn_flag = false;
  112. } catch (IOException e) { e.printStackTrace(); }
  113. System.out.println("Client finished sending");
  114.  
  115. }
  116.  
  117.  
  118. @Override
  119. public void mouseEntered(MouseEvent e) {
  120. // TODO Auto-generated method stub
  121.  
  122. }
  123.  
  124. @Override
  125. public void mouseExited(MouseEvent e) {
  126. // TODO Auto-generated method stub
  127.  
  128. }
  129.  
  130. @Override
  131. public void mousePressed(MouseEvent e) {
  132. // TODO Auto-generated method stub
  133.  
  134. }
  135.  
  136. @Override
  137. public void mouseReleased(MouseEvent e) {
  138. // TODO Auto-generated method stub
  139.  
  140. }
  141. }

Java Syntax (Toggle Plain Text)
  1. package game;
  2.  
  3. import java.awt.*;
  4. import java.awt.event.MouseEvent;
  5. import java.awt.event.MouseListener;
  6. import java.io.*;
  7. import java.net.*;
  8.  
  9. import javax.swing.*;
  10.  
  11. public class Serverms2 extends JFrame implements MouseListener
  12. {
  13. private static final long serialVersionUID = 1L;
  14.  
  15. JFrame container;
  16. static Socket s;
  17. static ServerSocket ss;
  18. static BufferedOutputStream bos;
  19. static OutputStreamWriter osw;
  20. static BufferedInputStream bis;
  21. static InputStreamReader isr;
  22. static StringBuffer x, y;
  23. static int port = 5656;
  24. static int ID, count = 0;
  25. static int tempx, tempy;
  26. static int mouseX, mouseY;
  27. static String message;
  28. static boolean ServerTurn_flag = false;
  29.  
  30. public Serverms2()
  31. {
  32. super("Server: Player 2");
  33. setSize(400, 400);
  34. setDefaultCloseOperation(EXIT_ON_CLOSE);
  35. this.setResizable(false);
  36. addMouseListener(this);
  37. try {
  38. ss = new ServerSocket(port);
  39. } catch (IOException e1) { e1.printStackTrace(); }
  40.  
  41. }
  42.  
  43.  
  44. public static void main(String args[])
  45. {
  46. Serverms2 server = new Serverms2();
  47. server.setVisible(true);
  48. try {
  49. s = ss.accept();
  50. } catch (IOException e) {
  51. // TODO Auto-generated catch block
  52. e.printStackTrace();
  53. }
  54.  
  55. server.receive();
  56.  
  57. }
  58.  
  59. @Override
  60. public void mouseClicked(MouseEvent e) {
  61. if (ServerTurn_flag){
  62. mouseX = e.getX();
  63. mouseY = e.getY();
  64. send(mouseX, mouseY);
  65. receive();
  66. } else{
  67.  
  68. System.out.println("Wasn't servers turn.");
  69. }
  70.  
  71. }
  72.  
  73. public void receive() {
  74. ServerTurn_flag = false;
  75. try
  76. {
  77. bis = new BufferedInputStream(s.getInputStream());
  78. isr = new InputStreamReader(bis, "US-ASCII");
  79.  
  80. x = new StringBuffer();
  81. y = new StringBuffer();
  82.  
  83. while((tempx = isr.read()) != 13)
  84. x.append((char) tempx);
  85.  
  86. String str = x.toString();
  87. mouseX = Integer.parseInt(str);
  88.  
  89. while((tempy = isr.read()) != 13)
  90. y.append((char) tempy);
  91. str = y.toString();
  92. mouseY = Integer.parseInt(str);
  93.  
  94. } catch (IOException e) {System.out.println("I hate it when this crap happens.."); }
  95. System.out.println("Server done receiving.");
  96. ServerTurn_flag = true;
  97.  
  98. }
  99.  
  100. private void send(int xcor, int ycor)
  101. {
  102. try
  103. {
  104. bos = new BufferedOutputStream(s.getOutputStream());
  105. osw = new OutputStreamWriter(bos, "US-ASCII");
  106. message = (Integer.toString(xcor)) + (char) 13;
  107. osw.write(message);
  108. osw.flush();
  109. //System.out.println(message);
  110. message = (Integer.toString(ycor)) + (char) 13;
  111. osw.write(message);
  112. osw.flush();
  113. bos.flush();
  114. //System.out.println(message);
  115. } catch (IOException e) { e.printStackTrace(); }
  116.  
  117. }
  118.  
  119. @Override
  120. public void mouseEntered(MouseEvent e) {
  121. // TODO Auto-generated method stub
  122.  
  123. }
  124.  
  125. @Override
  126. public void mouseExited(MouseEvent e) {
  127. // TODO Auto-generated method stub
  128.  
  129. }
  130.  
  131. @Override
  132. public void mousePressed(MouseEvent e) {
  133. // TODO Auto-generated method stub
  134.  
  135. }
  136.  
  137. @Override
  138. public void mouseReleased(MouseEvent e) {
  139. // TODO Auto-generated method stub
  140.  
  141. }
  142.  
  143. }
Reputation Points: 874
Solved Threads: 352
Posting Maven
BestJewSinceJC is offline Offline
2,758 posts
since Sep 2008
Nov 4th, 2009
1
Re: Issue with MouseListener
My example was pretty long, but try to grasp the concept and I think you'll be able to complete your program. Again, the basic idea I'm proposing is that you multi-thread your application so that the read() method doesn't block the main thread. I'm not sure of the best way to do this, but I'd first try to create a new Thread in which you'd run the receive() method. Hypothetically, you could also make sure that any time the mouse listener method was called it happened in a different thread, but I don't know how you'd do that (since it depends on an event). So if it was my program I'd try the first option. Anyway I really hope this works out for you. I'm no expert in Socket programming or in multithreaded programming, and everything I said here could be completely wrong. But I know the basic concepts of each, so hopefully that little knowledge will be helpful to you here. Good luck

Last edited by BestJewSinceJC; Nov 4th, 2009 at 4:05 pm.
Reputation Points: 874
Solved Threads: 352
Posting Maven
BestJewSinceJC is offline Offline
2,758 posts
since Sep 2008
Nov 4th, 2009
1
Re: Issue with MouseListener
I think you are correct that the behavior did stem from some blocking, but this can still be simplified a great deal to work without a separate listening thread.

Here's a re-wired version of the same that behaves itself. It's worth noting that these two versions only differ in what kind of socket is created to make one the "server". They could be coalesced to a single class. (It's also a quickly slapped together modification that doesn't properly handle exceptions or shut down properly and close io streams )
Java Syntax (Toggle Plain Text)
  1. package game;
  2.  
  3. import java.awt.*;
  4. import java.awt.event.*;
  5. import java.io.*;
  6. import java.net.*;
  7.  
  8. import javax.swing.*;
  9.  
  10. public class Clientms2 extends JFrame implements MouseListener {
  11.  
  12. private static final long serialVersionUID = 1L;
  13. JFrame container;
  14. InetAddress address;
  15. Socket s;
  16. String host = "localhost";
  17. PrintWriter out = null;
  18. BufferedReader in = null;
  19. int port = 5656;
  20. String message;
  21. int mouseX, mouseY;
  22.  
  23. boolean myTurn = true;
  24. JTextArea status = new JTextArea();
  25.  
  26. public Clientms2() {
  27. super("Client 1: Player 1");
  28. setDefaultCloseOperation(EXIT_ON_CLOSE);
  29. //this.setResizable(false);
  30. addMouseListener(this);
  31. status.addMouseListener(this);
  32. add(status);
  33. pack();
  34. setSize(400, 400);
  35. }
  36.  
  37. public static void main(String args[]) {
  38. Clientms2 client = new Clientms2();
  39. client.setVisible(true);
  40. client.run();
  41. }
  42.  
  43. public void run() {
  44. try {
  45. address = InetAddress.getByName(host);
  46. s = new Socket(address, port);
  47.  
  48. // establish streams one time
  49. out = new PrintWriter(s.getOutputStream(), true);
  50. in = new BufferedReader(new InputStreamReader(
  51. s.getInputStream()));
  52.  
  53. // start processing
  54. myTurn = true;
  55. String input = "";
  56. while ((input = in.readLine()) != null) {
  57. if (!myTurn) {
  58. process(input);
  59. }
  60. }
  61. } catch (Exception e) {
  62. e.printStackTrace();
  63. }
  64. }
  65.  
  66. @Override
  67. public void mouseClicked(MouseEvent e) {
  68. if (myTurn) {
  69. mouseX = e.getX();
  70. mouseY = e.getY();
  71. send(mouseX, mouseY);
  72. status.append("End of client's turn, client waiting to receive.\n");
  73. myTurn = false;
  74. }
  75. }
  76.  
  77. public void process(String input) {
  78. try {
  79. String[] coordStr = input.split(",");
  80. if (coordStr.length == 2) {
  81. mouseX = Integer.parseInt(coordStr[0]);
  82. mouseY = Integer.parseInt(coordStr[1]);
  83. status.append("received " + mouseX + " " + mouseY + "\n");
  84. myTurn = true;
  85. }
  86. } catch (Exception e) {
  87. e.printStackTrace();
  88. }
  89. }
  90.  
  91. private void send(int xcor, int ycor) {
  92. try {
  93. message = xcor + "," + ycor;
  94. out.println(message);
  95. } catch (Exception e) {
  96. e.printStackTrace();
  97. }
  98. }
  99.  
  100. @Override
  101. public void mouseEntered(MouseEvent e) {
  102. // TODO Auto-generated method stub
  103. }
  104.  
  105. @Override
  106. public void mouseExited(MouseEvent e) {
  107. // TODO Auto-generated method stub
  108. }
  109.  
  110. @Override
  111. public void mousePressed(MouseEvent e) {
  112. // TODO Auto-generated method stub
  113. }
  114.  
  115. @Override
  116. public void mouseReleased(MouseEvent e) {
  117. // TODO Auto-generated method stub
  118. }
  119. }
Java Syntax (Toggle Plain Text)
  1. package game;
  2.  
  3. import java.awt.*;
  4. import java.awt.event.MouseEvent;
  5. import java.awt.event.MouseListener;
  6. import java.io.*;
  7. import java.net.*;
  8.  
  9. import javax.swing.*;
  10.  
  11. public class Serverms2 extends JFrame implements MouseListener {
  12.  
  13. private static final long serialVersionUID = 1L;
  14. JFrame container;
  15. Socket s;
  16. ServerSocket ss;
  17. PrintWriter out = null;
  18. BufferedReader in = null;
  19. int port = 5656;
  20. int mouseX, mouseY;
  21. String message;
  22.  
  23. boolean myTurn = false;
  24. JTextArea status = new JTextArea();
  25.  
  26. public Serverms2() {
  27. super("Server: Player 2");
  28. setDefaultCloseOperation(EXIT_ON_CLOSE);
  29. //this.setResizable(false);
  30. addMouseListener(this);
  31. status.addMouseListener(this);
  32. add(status);
  33. pack();
  34. setSize(400, 400);
  35.  
  36. try {
  37. ss = new ServerSocket(port);
  38. } catch (IOException e1) {
  39. e1.printStackTrace();
  40. }
  41.  
  42. }
  43.  
  44. public void run() {
  45. try {
  46. s = ss.accept();
  47.  
  48. out = new PrintWriter(s.getOutputStream(), true);
  49. in = new BufferedReader(new InputStreamReader(
  50. s.getInputStream()));
  51.  
  52. myTurn = false;
  53. String input = "";
  54. while ((input = in.readLine()) != null) {
  55. if (!myTurn) {
  56. process(input);
  57. }
  58. }
  59.  
  60. } catch (IOException e) {
  61. // TODO Auto-generated catch block
  62. e.printStackTrace();
  63. }
  64.  
  65. }
  66.  
  67. public static void main(String args[]) {
  68. Serverms2 server = new Serverms2();
  69. server.setVisible(true);
  70. server.run();
  71. }
  72.  
  73. @Override
  74. public void mouseClicked(MouseEvent e) {
  75. if (myTurn) {
  76. mouseX = e.getX();
  77. mouseY = e.getY();
  78. send(mouseX, mouseY);
  79. status.append("End of server's turn, waiting to receive.\n");
  80. myTurn = false;
  81. }
  82. }
  83.  
  84. private void process(String input) {
  85. try {
  86. String[] coordStr = input.split(",");
  87. if (coordStr.length == 2) {
  88. mouseX = Integer.parseInt(coordStr[0]);
  89. mouseY = Integer.parseInt(coordStr[1]);
  90. myTurn = true;
  91. status.append("received " + mouseX + " " + mouseY + "\n");
  92. }
  93. } catch (Exception e) {
  94. e.printStackTrace();
  95. }
  96.  
  97. }
  98.  
  99. private void send(int xcor, int ycor) {
  100. try {
  101. message = xcor + "," + ycor;
  102. out.println(message);
  103. } catch (Exception e) {
  104. e.printStackTrace();
  105. }
  106. }
  107.  
  108. @Override
  109. public void mouseEntered(MouseEvent e) {
  110. // TODO Auto-generated method stub
  111. }
  112.  
  113. @Override
  114. public void mouseExited(MouseEvent e) {
  115. // TODO Auto-generated method stub
  116. }
  117.  
  118. @Override
  119. public void mousePressed(MouseEvent e) {
  120. // TODO Auto-generated method stub
  121. }
  122.  
  123. @Override
  124. public void mouseReleased(MouseEvent e) {
  125. // TODO Auto-generated method stub
  126. }
  127. }
Last edited by Ezzaral; Nov 4th, 2009 at 6:23 pm.
Moderator
Featured Poster
Reputation Points: 3239
Solved Threads: 839
Posting Genius
Ezzaral is offline Offline
6,761 posts
since May 2007
Nov 4th, 2009
0
Re: Issue with MouseListener
Well, thank god that somebody else stepped up, because I was getting quite frustrated and it isn't even my program. Haha. Although after a quick look I don't see why your version is any different than mine was, but I suppose it is those two while loops that truly make the difference. But no need to explain unless the OP is curious - I'll take a look at it when I get up the effort to look at this thing without getting frustrated again.
Last edited by BestJewSinceJC; Nov 4th, 2009 at 8:27 pm.
Reputation Points: 874
Solved Threads: 352
Posting Maven
BestJewSinceJC is offline Offline
2,758 posts
since Sep 2008
Nov 4th, 2009
0
Re: Issue with MouseListener
OMG!! You guys are awesome!!!!

Java Syntax (Toggle Plain Text)
  1. while(true)
  2. System.out.println("Thaaaaaaaaaank you!!!");

Looll! I did sorta suspect that the mouselistener kept getting called, and that out-of-turn co-ords were stored somewhere, but just weren't sent until receive() completed. That was why I added the removeMouseListener method. I thought that would disable the mouselistener after one set of co-ords were sent out, and since I didn't add it again until after the receive() method, I figured that the intermediate out-of-turn clicks would effectively be "thrown away". But, I guess I was mistaken. Anyways, thanks again!! I can now finally move on with the rest of my program.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
chandini.david is offline Offline
14 posts
since Nov 2009
Nov 4th, 2009
0
Re: Issue with MouseListener
That is actually good logic - but it assumes that the MouseListener wouldn't get re-added due to the method calls being blocked/having to wait for receive, so it probably runs into the same problem as the variable does. Although I'm not sure and honestly don't feel like investigating. But I'm glad you have it working now, wish I could've been of better assistance.

PS mark solved

Last edited by BestJewSinceJC; Nov 4th, 2009 at 9:01 pm.
Reputation Points: 874
Solved Threads: 352
Posting Maven
BestJewSinceJC is offline Offline
2,758 posts
since Sep 2008
Nov 5th, 2009
0
Re: Issue with MouseListener
Reputation Points: 10
Solved Threads: 0
Newbie Poster
chandini.david is offline Offline
14 posts
since Nov 2009

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Java Forum Timeline: Taking too long to print out 500x500 2D Array
Next Thread in Java Forum Timeline: Java object persistance





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC