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