Networked GUI handler for binary protocol - java

Alright, so I created a Client and Server that manipulates a Map via a GUI interface using a text based protocol. The handler below was used to create a "work order" to manipulate the GUI on a separate thread from the network communications.
class RemoteInputHandler implements Runnable,SharedVariables
{
#Override
public void run()
{
try
{
String input = netComm.reader.readLine();
while (input != null)
{
// Make a separate copy of the input string
String inputCopy = input;
// Post a work order to process the command on the GUI thread
Platform.runLater(() ->
{
handleRemote(inputCopy);
});
// Get the next remote input
input = netComm.reader.readLine();
}
} catch (IOException ex)
{
throw new RuntimeException(ex);
}
}
This pulls the next line of input from the server without freezing up the GUI. I then use the input in the handleRemote() method with a scanner to determine what is done with the input. The string retrieved from the reader looked something like "put key value". I'd then get the first word "put", using a scanner, to get the "command" and use a switch statement to determine how the GUI / Map should be updated on the client and server side respectively.
I'm doing another GUI based program that uses a binary protocol instead, but I'm having trouble figuring out how to handle the information in the same way as I did with the readLine() above. Is there a way to do this? Am i thinking about it the wrong way? I thought I could just get all of the bytes into an array, but I'm having trouble even figuring that out.
I could really use a hint! Thank you!

Related

Reading/Writing Objects using Serializable

so I have an object, a Hotel, which implements Serializable. I am using an FX application that has many buttons. The FX application has a hotel object, as a field, which is the object that I want to read/write.
Is it read before write? or write before read? and should it be in the start method?
Do you have the read/write methods right next to each other on startup? Or should I have a button to close/save the application, and have it write the object to a file (and read it on startup)?
Here's what I have so far, and I believe it's writing successfully, but it is not reading.
#Override
public void start(Stage primaryStage) {
try {
ObjectOutputStream oosoos = new ObjectOutputStream(new FileOutputStream("hotelRooms.dat"));
oosoos.writeObject(hotel);
}catch (IOException e) {
System.out.println(e.getMessage());
}
// Hotel tempHotel;
try {
ObjectInputStream iisiis = new ObjectInputStream(new FileInputStream("hotelRooms.dat"));
hotel = (Hotel)iisiis.readObject();
} catch (IOException | ClassNotFoundException ffe ) {
System.out.println(ffe.getMessage());
}
I've never used FX before, but I think I might be able to help, by making some assumptions...
I assume that your start() method is a lifecycle method defined by some FX class and you need to load the Hotel object when the application starts. Presumably you then have some sort of finish() method where you want to save the latest version of the Hotel object for later..?
If so, you need to 'read()' the object in the start() method and 'write()' the Hotel in the finish() method.
The problem in your code snippet is that you are trying to do both in the start() method. This has all manner of potential issues, not least of which is that your write() method needs to flush the stream (causing the data to actually be written to the file) and you probably then need to close the output stream before the input stream will be allowed to read.
Probably.
It might just be that if you call
oosoos.close(); // this will flush the stream
...after
oosoos.writeObject(hotel);
then the intput stream will successfully read the object.
However, you really need to split this code up as I mentioned previously - the code that you have posted is pointless; you write the Hotel object to the file and then read it back... you could just use the object that you wrote to file, without ever reading it back in...
Hope this helps and apologies if I have misunderstood, due to lack of knowledge of FX.
What I did was split up the read/write. I have it so it reads/inputs on startup, and when they click a button to create a reservation, it writes the current hotel object to the file.

error display in GUI [duplicate]

I have a query on handling error conditions with Java Swing.
I am using Netbeans to develop a simple Java Swing app. It is to load in a text file, then run calculation based on the numbers found in the text file. The main Swing class holds the JFrames and JPanels.
I have the file loading code as a separate class file. It returns the number of lines read and a List of numbers back to the main Swing app.
I realised that if the file reading fails (i.e. try -> catch (Exception ex)), the entire app will crash. What's the best way to handle errors resulting from my scenario above? That is to say, the file loading code crashes and I don't want the entire program to crash. I want the program to say the file is corrupted and wait for user to load new file.
Any thoughts?
Yakult
when you catch the exception, run:
JOptionPane.showMessageDialog("File is corrupted. Please select a new file.");
Then display the file dialog again.
It's probably best to do this as a loop that continues while the the file is not valid. If there is a corruption, then rather than throwing an exception, set a boolean flag and loop as long as the flag is set. That way, when a good file is found, the while loop will terminate.
Example:
public static void main(String[] args){
boolean goodFile = false;
while (!goodFile){
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog();
goodFile = processFile(chooser.getSelectedFile());
}
}
private boolean processFile(File file){
//do you stuff with the file
//return true if the processing works properly, and false otherwise
}
yeah
the problem is with your IO reading concept
the while loop is reading to the end of the file and so on..
to prevent that u can use a buffered reader
and use this code
String line = null
while((line = reader.readLine())!= null) {
// do stuf
}
if you are having this problem with processing the read line
all you need is to create a exception class of your own by extending Exception class and throw that exception in your catch block
after setting the message to your custom exception class you can set that message in to
JOptionPane.showMessageDialog(null,"message here"); //showMessageDialog is a static method
ok
You just catch the exception and put condition in the catch block. If the file contains other content that your application is intended to handle then you could call your method which will re-handle another file.
The main handling of your new process of the new file manipulation will start from your catch block. So in this way you are using java thrown exception to restart your application in a brand new way other than relaunching your app from the zero level.

Example on how to use TFileTransport in Thrift (Client/Server)

Is there anyone who managed to get TFileTransport as a transport layer, to work? I've tried but since there is no documentation (or have I not found it?) for this, I am not able to make it work.
If anyone have been more successful and could provide some sample code, it would be great.
edit:
What I've tried so far:
public class FileThriftServer {
public static void startThriftServer(
ThriftDataBenchmark.Processor<ThriftDataBenchmarkHandler> processor) {
try {
File input = new File("ThriftFile.in");
if(!input.exists()){
input.createNewFile();
}
File output = new File("ThriftFile.out");
if(!output.exists()){
output.createNewFile();
}
TFileTransport inputFileTransport = new TFileTransport(input.getAbsolutePath(), true);
TFileTransport outputFileTransport = new TFileTransport(output.getAbsolutePath(), false);
inputFileTransport.open();
outputFileTransport.open();
TFileProcessor fProcessor =
new TFileProcessor(processor, new TJSONProtocol.Factory(), inputFileTransport, outputFileTransport);
// this results in error in case I don't call those open methods above
fProcessor.processChunk();
System.out.println("File Thrift service started ...");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// ThriftDataBenchmarkHandler is an implementation of my test service
startThriftServer(new ThriftDataBenchmark.Processor<ThriftDataBenchmarkHandler>(
new ThriftDataBenchmarkHandler()));
}
}
Now I don't know if I am even on a good way, maybe I misunderstood the concept of this transport (again, it is not documented). I would expect I start the server by some method now which will listen on the input file. When clients put there something, it would process it and write the answer to output file (I didn't try to write client yet since this peace of code just executes and exists, it is obviously not right).
edit 2:
Ok, so if I understand it right, this code is ok and it should process one request of the client, if it's there. So I am moving to the client side, doing something like this:
File input = new File(THRIFT_INPUT_FILE_PATH);
if (!input.exists()) {
input.createNewFile();
}
TTransport transport = new TFileTransport(input.getAbsolutePath(),
false);
TProtocol protocol = new TJSONProtocol(transport);
ThriftDataBenchmark.Client client = new ThriftDataBenchmark.Client(
protocol);
// my testing service, the parameters are not important
SimpleCompany company = client.getSimpleCompanyData("token", 42);
Unfortunatelly calling getSimpleCompanyData results in:
org.apache.thrift.transport.TTransportException: Not Supported
at org.apache.thrift.transport.TFileTransport.write(TFileTransport.java:572)
at org.apache.thrift.transport.TTransport.write(TTransport.java:105)
at org.apache.thrift.protocol.TJSONProtocol.writeJSONArrayStart(TJSONProtocol.java:476)
at org.apache.thrift.protocol.TJSONProtocol.writeMessageBegin(TJSONProtocol.java:487)
at org.apache.thrift.TServiceClient.sendBase(TServiceClient.java:62)
It's a bit confusing that server side requires input and output transport but on the client side, it only accepts one. How does it read an answer and from where?
Let's not move into some extra logic of checking the file for changes, if it's not already part of Thrift. I'll be ok at this point by doing it manually in sense of: running the client first, then running the server side.
I would expect I start the server by some method now which will listen on the input file. When clients put there something, it would process it and write the answer to output file (I didn't try to write client yet since this peace of code just executes and exists, it is obviously not right).
That's exactly right. In particular, the fProcessor.processChunk() call you used will process exactly one chunk (the current one). The whole class looks as designed around the assumption that the file size is static and does not change over time. However, the underlying TFileTransport supports what's called a tailPolicy, used when a read call hits EOF:
public class TFileTransport extends TTransport {
public static enum tailPolicy {
NOWAIT(0, 0),
WAIT_FOREVER(500, -1);
/**
* Time in milliseconds to sleep before next read
* If 0, no sleep
*/
public final int timeout_;
/**
* Number of retries before giving up
* if 0, no retries
* if -1, retry forever
*/
public final int retries_;
// ... ctor ...
}
/**
* Current tailing policy
*/
tailPolicy currentPolicy_ = tailPolicy.NOWAIT;
Another option to get it to work could be calling fProcessor.processChunk(int chunkNum), watching the file contents separately and repeat the calls when new data come in. It's certainly not such a bad idea to use the TFileProcessor as a starting point and improve it as needed.
// this results in error in case I don't call those open methods above
fProcessor.processChunk();
Opening the transports before using is fine. I think that part is ok.
org.apache.thrift.transport.TTransportException: Not Supported
at org.apache.thrift.transport.TFileTransport.write(TFileTransport.java:572)
at org.apache.thrift.transport.TTransport.write(TTransport.java:105)
Unfortunately, that seems pretty correct yet. The only place where writing is implemented is the code in the C++ library. Both Java and D only support reading (yet).

Error messages with Java Swing

I have a query on handling error conditions with Java Swing.
I am using Netbeans to develop a simple Java Swing app. It is to load in a text file, then run calculation based on the numbers found in the text file. The main Swing class holds the JFrames and JPanels.
I have the file loading code as a separate class file. It returns the number of lines read and a List of numbers back to the main Swing app.
I realised that if the file reading fails (i.e. try -> catch (Exception ex)), the entire app will crash. What's the best way to handle errors resulting from my scenario above? That is to say, the file loading code crashes and I don't want the entire program to crash. I want the program to say the file is corrupted and wait for user to load new file.
Any thoughts?
Yakult
when you catch the exception, run:
JOptionPane.showMessageDialog("File is corrupted. Please select a new file.");
Then display the file dialog again.
It's probably best to do this as a loop that continues while the the file is not valid. If there is a corruption, then rather than throwing an exception, set a boolean flag and loop as long as the flag is set. That way, when a good file is found, the while loop will terminate.
Example:
public static void main(String[] args){
boolean goodFile = false;
while (!goodFile){
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog();
goodFile = processFile(chooser.getSelectedFile());
}
}
private boolean processFile(File file){
//do you stuff with the file
//return true if the processing works properly, and false otherwise
}
yeah
the problem is with your IO reading concept
the while loop is reading to the end of the file and so on..
to prevent that u can use a buffered reader
and use this code
String line = null
while((line = reader.readLine())!= null) {
// do stuf
}
if you are having this problem with processing the read line
all you need is to create a exception class of your own by extending Exception class and throw that exception in your catch block
after setting the message to your custom exception class you can set that message in to
JOptionPane.showMessageDialog(null,"message here"); //showMessageDialog is a static method
ok
You just catch the exception and put condition in the catch block. If the file contains other content that your application is intended to handle then you could call your method which will re-handle another file.
The main handling of your new process of the new file manipulation will start from your catch block. So in this way you are using java thrown exception to restart your application in a brand new way other than relaunching your app from the zero level.

Input Problem with Java Socket

I am trying to do a programming exercise here making a client and a server that work with sockets.For the communication between them i use PrintWriter and InputReader.What im stuck with is : How can i check if the Server is trying to send something to the client,while the client is waiting for input ? At this point the client loop is something like this :
do {
outToServer.println(inFromUser.readLine());
String fromServer=inFromServer.readLine();
if(fromServer.equals("OK")){
clientSocket.close();
}else{
System.out.println(fromServer);
}
} while (!clientSocket.isClosed());
The problem is that in some cases the server needs to print multiple lines ,before needed an input again.Instead it prints 1 line then ill have to type something,then another line comes etc . Is there a way to get around that problem ? Thanks .
So you're going to need to encapsulate the
outToServer.readLine();
in a while loop that has a boolean conditional similar to a hasNext() function. You may want to set it up as follows:
String x = outToServer.readLine();
//while x doesn't equal whatever readLine would return if there's nothing to read
//I'm not sure if this is a null String or not
while(x!=null){
System.out.print(x);//print it however you wish
String x = outToServer.readLine();
}
And then do something similar for inFromServer if needed.

Categories

Resources