Java多线程和串行读取:如何正确挂起和恢复?

Java多线程和串行读取:如何正确挂起和恢复?,java,multithreading,swing,serial-port,arduino,Java,Multithreading,Swing,Serial Port,Arduino,我正在尝试编写一个基本的JavaSwing应用程序,它的工作原理是这样的:Arduino每秒向COM端口写入两个CSV字符串,我读取并解析数据,然后在GUI中显示数据。在官方Arduino教程的帮助下,我可以读取和解析来自串行端口的数据,并显示它。但是,我可以使用键盘上的一个键暂停并恢复GUI(同时仍从串行文件读取)。我可以暂停程序,但不知道如何继续。我已经在网上找了一段时间了,但没有结果。如果有人能给我指出正确的方向,我将衷心感谢。我对线程和Arduino相当陌生,但有一些基本的Java经验。

我正在尝试编写一个基本的JavaSwing应用程序,它的工作原理是这样的:Arduino每秒向COM端口写入两个CSV字符串,我读取并解析数据,然后在GUI中显示数据。在官方Arduino教程的帮助下,我可以读取和解析来自串行端口的数据,并显示它。但是,我可以使用键盘上的一个键暂停并恢复GUI(同时仍从串行文件读取)。我可以暂停程序,但不知道如何继续。我已经在网上找了一段时间了,但没有结果。如果有人能给我指出正确的方向,我将衷心感谢。我对线程和Arduino相当陌生,但有一些基本的Java经验。下面是代码,分为三个类(一个用于从串行读取,一个用于GUI,一个用于运行所有内容的主类。谢谢

以下是“显示”类:

下面是“SerialReader”类:

最后,“主要”类:


请注意,这是静态的,因此
thisThread.sleep(1000);t.sleep(1000);
会导致当前线程睡眠两秒钟。这太愚蠢了,在我胡闹的时候忘了删除并注释掉一些内容。无论如何,感谢您指出它!请使用。
//Imports
import java.awt.*;
import javax.swing.*;
import java.util.Random;
import java.lang.Thread;
import java.awt.event.*;
import java.util.ArrayList;
import java.awt.Toolkit.*;

//Class Definition
public class Display extends JPanel implements Runnable {
//Variables
private volatile Thread t;
private volatile boolean threadSuspended;

//Data Strings
private String data;
private String carData;
private String gpsData;

//Car Data
private int event;
private int engineRPM;
private int cvtRPM;
private double kph;
private int brake;
private double accel_x;
private double accel_y;
private double accel_z;
private double gyro_x;
private double gyro_y;
private double gyro_z;

//GPS Data
private String sentence;
private int time;
private String status;
private double latitude;
private String latitudeDir;
private double longitude;
private String longitudeDir;
private double knots;
private double angle;
private int date;
private double magVar;
private char magVarDir;
private String checksum;

//Constructor
public Display() {
    super.setSize(800,800);
    setLayout(new BorderLayout());
    addKeyListener(new KeyHandler());
    setFocusable(true);

    start();
}

public void start() {
    t = new Thread(this);
    t.start();
    threadSuspended = false;
}

public synchronized void stop() {
    t = null;
    notify();
    threadSuspended = true;
}

@Override
public void run() {
    Thread thisThread = Thread.currentThread();
    while(t == thisThread) {
        try {
            Thread.sleep(1000);
            synchronized(this) {
                while (threadSuspended && t == thisThread) {
                    wait();
                }
            }
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
        repaint();
        save();
    }
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    kph = SerialReader.getKPH();
    System.out.println(kph);
    g.drawString("Speed of Car: " + kph, 35, 35);
}

//Writes values to a file and updates average values
public void save() {
    //Nothing here yet
}

private class KeyHandler extends KeyAdapter {
    @Override
    public synchronized void keyPressed(KeyEvent ke) {
        ke.consume();
        int key = ke.getKeyCode();
        if (key == KeyEvent.VK_SPACE) {
            threadSuspended = !threadSuspended;
            if (!threadSuspended) {
                notify();
            }
        }
    }
}
}
//Imports
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier; 
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent; 
import gnu.io.SerialPortEventListener; 
import java.util.Enumeration;

//Class definition
public class SerialReader implements SerialPortEventListener {

//Data Strings
private static String data;
private static String carData;
private static String gpsData;

//Car Data
private static int event;
private static int engineRPM;
private static int cvtRPM;
private static double kph;
private static int brake;
private static double accel_x;
private static double accel_y;
private static double accel_z;
private static double gyro_x;
private static double gyro_y;
private static double gyro_z;

//GPS Data
private static String sentence;
private static int time;
private static String status;
private static double latitude;
private static String latitudeDir;
private static double longitude;
private static String longitudeDir;
private static double knots;
private static double angle;
private static int date;
private static double magVar;
private static char magVarDir;
private static String checksum;

//Variables
SerialPort serialPort;
private static final String[] PORT_NAMES = {"/dev/tty.usbserial-A9007UX1", "/dev/ttyUSB0", "COM3"};
private BufferedReader input;
private OutputStream output;
private static final int TIME_OUT = 2000;
private static final int DATA_RATE = 9600;

//Constructor
public SerialReader() {}

//Opens port
public void initialize() {
    CommPortIdentifier portId = null;
    Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

    while (portEnum.hasMoreElements()) {
        CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
        for (String portName : PORT_NAMES) {
            if (currPortId.getName().equals(portName)) {
                portId = currPortId;
                break;
            }
        }
    }
    if (portId == null) {
        System.out.println("Could not find COM port.");
        return;
    }

    try {
        // open serial port, and use class name for the appName.
        serialPort = (SerialPort) portId.open(this.getClass().getName(),
                TIME_OUT);

        // set port parameters
        serialPort.setSerialPortParams(DATA_RATE,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);

        // open the streams
        input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
        output = serialPort.getOutputStream();

        // add event listeners
        serialPort.addEventListener(this);
        serialPort.notifyOnDataAvailable(true);
    } catch (Exception e) {
        //Do nothing
    }
}

//Called when port is no longer in use
public synchronized void close() {
    if (serialPort != null) {
        serialPort.removeEventListener();
        serialPort.close();
        System.out.println("Port Closed");
    }
}

//Reads data from serial port
public synchronized void serialEvent(SerialPortEvent spe) {
    if (spe.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            data = input.readLine();
            //System.out.println(data);
            if (data.charAt(0) == '$') {
                gpsData = data;
                parseGPSData(data);
            } else {
                carData = data;
                parseCarData(data);
            }
        } catch (Exception e) {
            //Do nothing
        }
    }
}

//Parse car data
public void parseCarData(String data) {
    String[] info = data.split(",");

    event = Integer.parseInt(info[0]);
    engineRPM = Integer.parseInt(info[1]);
    cvtRPM = Integer.parseInt(info[2]);
    kph = Double.parseDouble(info[3]);
    brake = Integer.parseInt(info[4]);
    accel_x = Double.parseDouble(info[5]);
    accel_y = Double.parseDouble(info[6]);
    accel_z = Double.parseDouble(info[7]);
    gyro_x = Double.parseDouble(info[8]);
    gyro_y = Double.parseDouble(info[9]);
    gyro_z = Double.parseDouble(info[10]);
}

//Parse GPS data
public void parseGPSData(String data) {
    String[] info = data.split(",");

    sentence = info[0];
    int time = Integer.parseInt(info[1]);
    status = info[2];
    latitude = Double.parseDouble(info[3]);
    latitudeDir = info[4];
    longitude = Double.parseDouble(info[5]);
    longitudeDir = info[6];
    knots = Double.parseDouble(info[7]);
    angle = Double.parseDouble(info[8]);
    date = Integer.parseInt(info[9]);
    magVar = Double.parseDouble(info[10]);
    magVarDir = info[11].charAt(0);
    checksum = info[11].substring(1);
}

//Accessor Methods
public static String getCarData() {
    return carData;
}

public static String getGPSData() {
    return gpsData;
}

public static int getEvent() {
    return event;
}

public static int getEngineRPM() {
    return engineRPM;
}

public static int getCvtRPM() {
    return cvtRPM;
}

public static double getKPH() {
    return kph;
}

public static int getBrake() {
    return brake;
}

public static double getAccel_X() {
    return accel_x;
}

public static double getAccel_Y() {
    return accel_y;
}

public static double getAccel_Z() {
    return accel_z;
}

public static double getGyro_X() {
    return gyro_x;
}

public static double getGyro_Y() {
    return gyro_y;
}

public static double getGyro_Z() {
    return gyro_z;
}

public static String getSentence() {
    return sentence;
}

public static int getTime() {
    return time;
}

public static String getStatus() {
    return status;
}

public static double getLatitude() {
    return latitude;
}

public static String getLatitudeDir() {
    return latitudeDir;
}

public static double getLongitude() {
    return longitude;
}

public static String getLongitudeDir() {
    return longitudeDir;
}

public static double getKnots() {
    return knots;
}

public static double getAngle() {
    return angle;
}

public static int getDate() {
    return date;
}

public static double getMagVar() {
    return magVar;
}

public static char getMagVarDir() {
    return magVarDir;
}

public static String getChecksum() {
    return checksum;
}
}
//Imports
import java.awt.*;
import javax.swing.*;

//Class Definition
public class Main {
//Variables
private static JFrame frame;
private static Display display;
private static Container pane;
private static Dimension dim;
private static SerialReader sr;
private static Thread t;

//Run the program
public static void main(String[] args) {
    sr = new SerialReader();
    sr.initialize();
    t = new Thread() {
        public void run() {
            try {
                Thread.sleep(1000000);
            } catch (InterruptedException ie) {
                //Do nothing
            }
        }
    };
    t.start();
    System.out.println("Started");

    //Set look and feel to that of OS
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }

    frame = new JFrame("Baja GUI, Version 0.1");
    frame.setSize(800,800);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    display = new Display();

    pane = frame.getContentPane();
    pane.add(display);

    //Place frame in the middle of the screen
    dim = Toolkit.getDefaultToolkit().getScreenSize();
    frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);

    frame.setVisible(true);
}
}