I have a a GPS receptor. I create a class to retrieve all the GPS data on my Eclipse Console.
(This is the code of makia42)
public class COM implements Runnable{
static Thread myThread=null;
static BufferedReader br;
static BufferedWriter wr;
static InputStreamReader isr;
static OutputStreamWriter osw;
static java.io.RandomAccessFile port;
public COM(){ /**Constructeur*/
myThread=new Thread(this);
}
public void start(){
try {
port=new java.io.RandomAccessFile("COM3","rwd");
port.writeBytes("\r\n");
port.writeBytes("c,31,0,0,5\r\n");
port.writeBytes("T,1000,1\r\n");
}
catch (Exception e) {
System.out.println("start "+e.toString());
}
myThread.start();
}
public void run() {
System.out.println("lecture COM...");
for(;;){
String st = null;
try {
st=port.readLine();
} catch (IOException e) {System.out.println(e.getMessage());}
System.out.println(st);
}
}
public static void main(String[] args) {
COM temp= new COM();
temp.start();
}
}
I have another class which is a frame containing a button and a JTextArea. This class is in communication with my first class COM.
When i click the button, COM is starting and show me the data in my Eclipse Console.
But now, I'd like to show it on my JTextArea.
How can I do it ?
Best regards,
Tofuw
Take a moment to read about this pattern.
Make the Thread a Subject. Before starting register the instance of the class that contains the JTextArea as the Observer with the instance of the Thread. At the run() instead of printing on the console, use the notify(String);
public void run() {
System.out.println("lecture COM...");
for(;;){
String st = null;
try {
st=port.readLine();
} catch (IOException e) {System.out.println(e.getMessage());}
System.out.println(st);
}
}
Change to
public void run() {
System.out.println("lecture COM...");
for(;;){
String st = null;
try {
st=port.readLine();
} catch (IOException e) {System.out.println(e.getMessage());}
notifyObservers(st); //Pass the data to the observers.
}
}
EDIT:
I suppose you can rewrite the Thread to a simple class. It will render the program unresponsive while it reads, that's why you have a Thread. I suppose you can implement a cleaner way using Future<String>
public class GpsReader {
public class GenericGPSException extends Exception {
public GenericGPSException(String message, Throwable cause) {
super(message, cause);
}
}
public static void main(String[] args) {
// Example of usage
GpsReader gpsReader = new GpsReader();
String messageFromDevice;
try {
// Try read it
messageFromDevice = gpsReader.getCoordinate();
} catch (GenericGPSException e) {
// Error, what does it says?
messageFromDevice = e.getMessage();
}
JTextArea mockArea = new JTextArea();
// Show to user anything that comes to it.
mockArea.setText(messageFromDevice);
}
private boolean isReady;
private RandomAccessFile port;
public GpsReader() {
}
public String getCoordinate() throws GenericGPSException {
if (!isReady) {
try {
port = new RandomAccessFile("COM3", "rwd");
port.writeBytes("\r\n");
port.writeBytes("c,31,0,0,5\r\n");
port.writeBytes("T,1000,1\r\n");
isReady = true;
} catch (FileNotFoundException e) {
throw new GenericGPSException(
"Error at starting communication to Device ", e);
} catch (IOException e) {
throw new GenericGPSException(
"Error at starting communication to Device ", e);
}
}
try {
return port.readLine();
} catch (IOException e) {
throw new GenericGPSException("Error at reading the Device ", e);
}
}
}
Related
This question already has answers here:
Why are empty catch blocks a bad idea? [closed]
(20 answers)
Closed 5 years ago.
I have 3 very small classes.
The main class:
import java.io.*;
public class ConnectionManager {
public static void main(String argv[]) {
try {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout, true);
Receiver r = new Receiver(pin, true);
System.out.println("Starting threads");
s.start();
r.start();
} catch (Exception e) {}
}
}
The Sender class
import java.io.*;
import java.util.Random;
public class Sender extends Thread {
ObjectOutputStream oos;
boolean primitive;
public Sender(OutputStream os, boolean primitive) {
try {
oos = new ObjectOutputStream(os);
} catch (Exception e) {}
this.primitive = primitive;
}
public void run() {
Random rand = new Random();
while (true) {
try {
System.out.println("Integer is being sent");
oos.writeInt(10);
Thread.sleep(1000);
} catch (Exception e) {}
}
}
}
And the Receiver class
import java.io.*;
public class Receiver extends Thread {
ObjectInputStream ois;
boolean primitive;
public Receiver(InputStream is, boolean primitive) {
try {
ois = new ObjectInputStream(is);
} catch (Exception e) {}
this.primitive = primitive;
}
public void run() {
System.out.println("Receiver is starting");
while (true) {
try {
int x = ois.readInt();
System.out.print("An int was read: " + x);
} catch (Exception e) {}
}
}
}
Please ignore seemingly unused variables like primitive and rand. They're holdovers from slightly different versions that I was testing out earlier and I was too lazy to remove them.
Anyway, when I run the main method in ConnectionManager, I get this as output:
Starting threads
Receiver is starting
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
Integer is being sent
//... ad infinitum
Why is the receiver thread not getting the messages that are piped through? What am I missing here?
In your code, there is an exception like java.io.IOException: Read end dead.
You are NOT able to spot because you are suppressing them with empty catch blocks.
The main point is that you need to change Sender and Receiver classes to use PipedOutputStream and PipedInputStream as shown below :
Sender class:
public class Sender extends Thread {
PipedOutputStream oos;
public Sender(PipedOutputStream os) {
try {
this.oos = os;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
try {
System.out.println("Integer is being sent");
oos.write(10);
oos.close();
Thread.sleep(1000);
} catch (Exception e) {System.out.println(e);}
}
}
Receiver class:
public class Receiver extends Thread {
PipedInputStream ois;
public Receiver(PipedInputStream is) {
try {
this.ois = is;
} catch (Exception e) {System.out.println(e);}
}
public void run() {
System.out.println("Receiver is starting");
try {
int x = ois.read();
System.out.print("An int was read: " + x);
} catch (Exception e) {System.out.println(e);}
}
}
main() method:
public static void main(String[] args) throws Exception {
try {
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
Sender s = new Sender(pout);
Receiver r = new Receiver(pin);
System.out.println("Starting threads");
s.start();
r.start();
} catch (Exception e) {
System.out.println(e);
}
}
OUTPUT:
Starting threads
Receiver is starting
Integer is being sent
An int was read: 10
As a side note, remember that, empty catch blocks are very bad practice as they hide the exceptions, so I strongly suggest not to use them in the code.
I am trying to return the content of a text file on localhost (wamp server) as a string. I can read the text file but I cannot return a string because the function run of Runnable is a void. I'm working on Android Studio (that's why I'm using thread).
public String serverToString()
{
String str;
Thread t = new Thread(new Runnable() {
public void run() {
try {
URL url = new URL("http://myIP/test.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
str = in.readLine();
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Throwable th) {
th.printStackTrace();
}
}
});
t.start();
return str;
}
Advancing the the Cricket answer, I usually create an AsyncTask and inside it I define a callback interface.
The activity executing this task should implements this interface.
As an example of part of the code:
public class TeamUpdateTask extends AsyncTask, Object, TeamUpdateResponse> {
private TeamUpdateTaskCallback mListener;
#Override
public void onPostExecute (TeamUpdateResponse result) {
if (exception == null) {
mListener.OnTeamUpdateCompleted(result);
} else {
processException();
}
}
public void setListener (TeamUpdateTaskCallback listener) {
mListener = listener;
}
public interface TeamUpdateTaskCallback {
void OnTeamUpdateCompleted (TeamUpdateResponse response);
}
}
Hope it helps.
Generally, Volley library would be preferred over raw Thread. Or AsyncTask
but I cannot return a string because the function run of Runnable is a void
You can pass the result to a new method, though.
Define an interface
public interface ServerResponse {
void onResponse(String msg);
}
Add a parameter
public void serverToString(final ServerResponse callback)
{
String str;
Thread t = new Thread(new Runnable() {
public void run() {
try {
URL url = new URL("http://myIP/test.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
callback.onResponse(in.readLine()); // This is the 'return' now
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Throwable th) {
th.printStackTrace();
}
}
});
t.start();
}
And instead of this
String response = serverToString();
Do this
serverToString(new ServerResponse() {
#Override
public void onResponse(String response) {
// handle message
}
});
I am trying to create sample java application to implement the MultiUserChat of XMPP. Some how I can able to create user and make it online in openfire. Can any one suggest how to join all the users to the created chatRoom?
Here is my sample code inside the class SampleMultiUserChat Where I invite all the users to join the group but it is not getting joined. What I am missing?
SampleMultiUserChat(){
oConnectionConfiguration = new ConnectionConfiguration("10.10.1.105",5223);
createChatRoom();
}
/**
* #param args
*/
public static void main(String[] args) {
SampleMultiUserChat oSampleMultiUserChat = new SampleMultiUserChat();
for(int i = 2; i < 4; i++){
oSampleMultiUserChat.openXMPPConnection("user"+i);
oSampleMultiUserChat.createAcceptInvitationListener("user"+i);
oSampleMultiUserChat.inviteToJoinRoom("user"+i);
}
Thread mainThread = Thread.currentThread();
while(true){
try {
mainThread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void openXMPPConnection(String user){
XMPPConnection oXmppConnection = new XMPPConnection(oConnectionConfiguration);
try {
oXmppConnection.connect();
oXmppConnection.login(user, "60474c9c10d7142b7508ce7a50acf414");
userConnection.put(user, oXmppConnection);
} catch (XMPPException e) {
System.out.println("Exception occured in login in user : "+user);
}
}
private void createChatRoom(){
XMPPConnection oXmppConnection = new XMPPConnection(oConnectionConfiguration);
try {
oXmppConnection.connect();
oXmppConnection.login("user1", "60474c9c10d7142b7508ce7a50acf414");
myChattingRoom = new MultiUserChat(oXmppConnection, "mychattingroom#conference.10.10.1.105");
myChattingRoom.create("roomNickName");
myChattingRoom.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
} catch (XMPPException e) {
e.printStackTrace();
}
}
private void inviteToJoinRoom(String user){
myChattingRoom.invite(user+"#10.10.1.105", "Please join my chatting room");
System.out.println("sent invitation by "+user);
}
private void sendMessage(String msg){
try {
myChattingRoom.sendMessage(msg);
} catch (XMPPException e) {
System.out.println("Exception occured while sending msg to chat room"+e);
}
}
private void createAcceptInvitationListener(String user){
MultiUserChat.addInvitationListener(userConnection.get(user), new InvitationListener() {
public void invitationReceived(Connection connection, String room, String inviter,
String reason, String password, Message msg) {
try {
myChattingRoom.join(connection.getUser().substring(0, connection.getUser().indexOf("#")));
} catch (XMPPException e) {
e.printStackTrace();
}
}
});
}
Thanks in advance.
I solved my above problem by creating new instance of MultiUserChat.
Here is my edited method 'createAcceptInvitationListener'
private void createAcceptInvitationListener(String user){
System.out.println("inside create accept invitation listener");
final XMPPConnection oXmppConnection = userConnection.get(user);
MultiUserChat.addInvitationListener(oXmppConnection, new InvitationListener() {
public void invitationReceived(Connection connection, String room, String inviter,
String reason, String password, Message msg) {
System.out.println("inside invitation received method");
try {
System.out.println(connection.getUser().substring(0, connection.getUser().indexOf("#")));
MultiUserChat myChattingRoom = new MultiUserChat(oXmppConnection, "mychattingroom#conference.10.10.1.105");
myChattingRoom.join(connection.getUser().substring(0, connection.getUser().indexOf("#")));
} catch (Exception e) {
e.printStackTrace();
System.out.println("Exception occured while joining the chat room : "+e);
}
}
});
}
private void reservedRoomsCreation(MultiUserChat myChattingRoom) throws XMPPException{
Form form = myChattingRoom.getConfigurationForm();
Form submitForm = form.createAnswerForm();
for(Iterator fields = form.getFields(); fields.hasNext();){
FormField formFields = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(formFields.getType()) && formFields.getVariable() != null) {
submitForm.setDefaultAnswer(formFields.getVariable());
}
}
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
myChattingRoom.sendConfigurationForm(submitForm);
}
My program is set & ready, the problem is within the server. When I clients send the message, where should it be stored at ? I tried using queue but didn't work, also tried to use a usual string register but it worked partially. I made a thread for the sending & a thread for storing, using "Read/write UTF". I would be more than grateful if somebody provided me with an algorithm , or at a least a better idea. Code :
class clientThread extends Thread {
DataInputStream fromClient;
int counter = 0;
public clientThread(Socket cs) throws IOException
{
fromClient = new DataInputStream(cs.getInputStream());
}
public void run()
{
while (true)
{
try {
toall=Integer.toString(counter)+fromClient.readUTF();
} catch (IOException ex) {
Logger.getLogger(ChatTerminalS.class.getName()).log(Level.SEVERE, null, ex);
}
counter++;
}
}
}
class SendingThread extends Thread
{
DataOutputStream toClient;
String s = "";int counter=0;
public SendingThread(Socket cs) throws IOException
{
toClient = new DataOutputStream(cs.getOutputStream());
}
public void run()
{
while (true)
{
if(toall.charAt(0)+""==Integer.toString(counter))
{}
else
{
try {
toClient.writeUTF(toall);
} catch (IOException ex) {
Logger.getLogger(ChatTerminalS.class.getName()).log(Level.SEVERE, null, ex);
}
counter++;
}
}
}
Here is the code:
public static void main(String[] args) {
SocketWorker worker = null;
MyIOConsole mio = null;
try {
portNumber = 2012;
worker = new SocketWorker();
worker.assignPort(portNumber);
mio = new MyIOConsole();
mio.assignObject(worker);
Thread b = new Thread(mio);
b.start();
worker.run();
} catch (IOException e) {
e.printStackTrace();
}finally{
mio.applicationQuit();
}
}
The SocketWorker is simply a socket, listening the port 2012, and the MyIOConsole, will accept user command,
public class MyConsoleIO implements Runnable {
SocketWorker o;
static BufferedReader reader;
public void assignObject(Object o) {
reader = new BufferedReader(new InputStreamReader(System.in));
this.o = (SocketWorker) o;
}
#Override
public void run() {
String inputString = null;
System.out.println("Press 'q' to kill to program");
try {
inputString = reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (inputString.equalsIgnoreCase("q")) {
this.applicationQuit();
}
}
public void applicationQuit(){
this.o.stopWorking();
System.exit(0);
}
}
But when the Socket got the exception, even I catch them, the code
mio.applicationQuit();
keep run. I don't want that, I just want when the user close or crashed the application, the socket will close and quit. How can I solve it?
Add the following. The run method will be called as the JVM is exiting.
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run(){
// cleanup code before JVM exit goes here.
}
});