0

Im making a java GUI on Netbeans to run on a computer that will be connecting to device through a serial port. This GUI is to show the user information that will be stored in the other device. Like a text file or to retrieve some data from the device's sensors. I just finished the outline of the interface and now it is the harder part as this is the first time dealing with serial ports. The other device is a beagleboard. I am a little unsure on where to even start, as I have looked in this forum but nothing seems to relate to my question exactly. I assume I should establish a connection through the port with the device and send the requests for the info as the user requests.

Any advices? Should the connection be established in a separate java class of the program? The gui is made up of a main JFrame and two auxiliary ones and I (plan) have a button to estabish the connection in the main frame basically.

Thanks in advance, Alex

MPelletier
  • 16,256
  • 15
  • 86
  • 137
alex91
  • 3
  • 1
  • 2
  • *"The gui is made up of a main JFrame and two auxiliary ones"* See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/a/9554657/418556) – Andrew Thompson Jun 12 '12 at 16:23
  • 1
    @Andrew Thompson: Someone out there is actively teaching people to use multiple JFrames. I feel like a salmon, swimming upstream, when I see you write or write myself about one and only one JFrame. – Gilbert Le Blanc Jun 12 '12 at 18:19
  • @GilbertLeBlanc *"when I see you write"* Oh, for me it is a copy/paste from my 'most used lines'. Couldn't be bothered typing it *every time* I use it. ;) – Andrew Thompson Jun 12 '12 at 18:25
  • 1
    @AndrewThompson: Thanks for the advice, I guess I will have to look into that. It really does not seem user-friendly just to start with. – alex91 Jun 12 '12 at 21:03

1 Answers1

1

Should the connection be established in a separate java class of the program?

Yes. One java class should be sufficient to establish the connection, send messages to the beagleboard, and receive responses.

I assume I should establish a connection through the port with the device and send the requests for the info as the user requests.

Yes. You would format the requests in whatever format the beagleboard requires.

Here's a class I put together to make sure a single instance of the Java application ran. You would modify this for your communications.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class ApplicationInstanceManager {

    private static final boolean DEBUG = false;

    private static ApplicationInstanceListener subListener;

    /** Randomly chosen, but static, high socket number */
    public static final int SINGLE_INSTANCE_NETWORK_SOCKET = 44331;

    /** Must end with newline */
    public static final String SINGLE_INSTANCE_SHARED_KEY = "$$RabidNewInstance$$\n";

    /**
     * Registers this instance of the application.
     * 
     * @return true if first instance, false if not.
     */
    public static boolean registerInstance() {
        // returnValueOnError should be true if lenient (allows app to run on
        // network error) or false if strict.
        boolean returnValueOnError = true;
        // try to open network socket
        // if success, listen to socket for new instance message, return true
        // if unable to open, connect to existing and send new instance message,
        // return false
        try {
            final ServerSocket socket = new ServerSocket(
                    SINGLE_INSTANCE_NETWORK_SOCKET, 10, InetAddress
                            .getLocalHost());
            if (DEBUG)
                System.out.println("Listening for application instances on socket "
                    + SINGLE_INSTANCE_NETWORK_SOCKET);
            Thread instanceListenerThread = new InstanceListenerThread(socket);
            instanceListenerThread.start();
            // listen
        } catch (UnknownHostException e) {
            EclipseLogging.logError(RabidPlugin.getDefault(),
                    RabidPlugin.PLUGIN_ID, e);
            return returnValueOnError;
        } catch (IOException e) {
            return portTaken(returnValueOnError, e);

        }
        return true;
    }

    private static boolean portTaken(boolean returnValueOnError, IOException e) {
        if (DEBUG)
            System.out.println("Port is already taken.  "
                    + "Notifying first instance.");
        try {
            Socket clientSocket = new Socket(InetAddress.getLocalHost(),
                    SINGLE_INSTANCE_NETWORK_SOCKET);
            OutputStream out = clientSocket.getOutputStream();
            out.write(SINGLE_INSTANCE_SHARED_KEY.getBytes());
            out.close();
            clientSocket.close();
            System.out.println("Successfully notified first instance.");
            return false;
        } catch (UnknownHostException e1) {
            EclipseLogging.logError(RabidPlugin.getDefault(),
                    RabidPlugin.PLUGIN_ID, e);
            return returnValueOnError;
        } catch (IOException e1) {
            EclipseLogging
                    .logError(
                            RabidPlugin.getDefault(),
                            RabidPlugin.PLUGIN_ID,
                            "Error connecting to local port for single instance notification",
                            e);
            return returnValueOnError;
        }
    }

    public static void setApplicationInstanceListener(
            ApplicationInstanceListener listener) {
        subListener = listener;
    }

    private static void fireNewInstance() {
        if (subListener != null) {
            subListener.newInstanceCreated();
        }
    }

    public static void main(String[] args) {
        if (!ApplicationInstanceManager.registerInstance()) {
            // instance already running.
            System.out.println("Another instance of this application " + 
                    "is already running.  Exiting.");
            System.exit(0);
        }
        ApplicationInstanceManager
                .setApplicationInstanceListener(new ApplicationInstanceListener() {
                    public void newInstanceCreated() {
                        System.out.println("New instance detected...");
                        // this is where your handler code goes...
                    }
                });
    }

    public static class InstanceListenerThread extends Thread {

        private ServerSocket socket;

        public InstanceListenerThread(ServerSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            boolean socketClosed = false;
            while (!socketClosed) {
                if (socket.isClosed()) {
                    socketClosed = true;
                } else {
                    try {
                        Socket client = socket.accept();
                        BufferedReader in = new BufferedReader(
                                new InputStreamReader(client.getInputStream()));
                        String message = in.readLine();
                        if (SINGLE_INSTANCE_SHARED_KEY.trim().equals(
                                message.trim())) {
                            if (DEBUG)
                                System.out.println("Shared key matched - "
                                        + "new application instance found");
                            fireNewInstance();
                        }
                        in.close();
                        client.close();
                    } catch (IOException e) {
                        socketClosed = true;
                    }
                }
            }
        }
    }
}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • Thank you, I will have to look into and see if works at all using sockets then, I had mostly seen people recommending the use of javax.comm or the clone RXTX. And it seems like I will also have to look into the multiple JFrames... – alex91 Jun 12 '12 at 21:01
  • Now that I had time to use the code and start understanding what you put together I have some extra questions. private static ApplicationInstanceListener subListener; this would be another class in the project that would be waiting for the instance to be made? and one more thing: EclipseLogging, where does that come from? Is that some kind of logfile to store errors? Thanks in advance, Alex – alex91 Jun 13 '12 at 09:22
  • @alex91: EclipseLogging is part of a Eclipse plugin I wrote specifically to display and log Eclipse plugin errors. ApplicationInstanceListener is a listener that I created with one method, newInstanceCreated(). The actual listener code I wrote is part of a different Eclipse plugin Application class, to force the current Eclipse window into focus. Your listener code would obviously be different. – Gilbert Le Blanc Jun 13 '12 at 12:05