最近看了JavaEye中一些有关使用RxTxComm.jar扩展包开发串口监听的代码,正好有个朋友让我做一个这方面的小软件,就把别人的代码整合了一下,做了一个小Demo。
项目结构其他的都是网上的代码,或我自己扩展的未完成的类:
软件可以接收串口传送的数据,显示在state标签后,并将数据返回给发送端。只是在本本上测试通过了,没有在真正的串口设备上测试。
使用了一个串口模拟的软件,模拟了一对串口设备com1,和com2,
使用串口调试助手发送模拟数据。
界面布局使用了GridBagLayout,相关代码在前一篇的博客中。
好了,贴代码了:
package gui;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import javax.swing.DefaultComboBoxModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class SerialPortMoniterPanel extends JPanel implements SerialPortEventListener{
static final String STATE = "STATE: ";
static final String COUNT = "COUNT: ";
static final String ERROR = "ERROR, PLEASE RETRY !";
static int count = 0;
JPanel panel;
JLabel commLabel; //端口号
JComboBox commComboBox;
JLabel BPSLabel; //波特率
JComboBox BPSComboBox; //BPS
JLabel flowInLabel; //Flow Control In 输入流控制
JComboBox flowInBox;
JLabel flowOutLabel; //Flow Control Out 输出流控制
JComboBox flowOutBox;
JLabel dataBitsLabel; //Data Bits 数据位数
JComboBox dataBitsBox;
JLabel stopBitsLabel; //Stop Bits 停止位
JComboBox stopBitsBox;
JLabel parityLabel; //Parity 奇偶校验
JComboBox parityBox;
JLabel logoLabel;
JLabel stateLabel;
JLabel countLabel;
JButton connButton;
static CommPortIdentifier portId;
static Enumeration portList;
InputStream inputStream; //由串口读入的流
OutputStream outputStream;// 向串口输出的流
SerialPort serialPort;
ConnectAction action;
Thread buttonThread;
public SerialPortMoniterPanel(){
super(new BorderLayout());
initPanel();
add(panel,BorderLayout.CENTER);
}
public void initPanel(){
GridBagLayout layout = new GridBagLayout();
panel = new JPanel(layout);
connButton = new JButton("CONNECTION");
action = new ConnectAction();
connButton.addActionListener(action);
stateLabel = new JLabel(STATE);
stateLabel.setHorizontalAlignment(JLabel.LEFT);
countLabel = new JLabel(COUNT+String.valueOf(count));
countLabel.setHorizontalAlignment(JLabel.LEFT);
logoLabel = new JLabel();
Image image = Toolkit.getDefaultToolkit().getImage("logo/logo.png");
Icon icon = new ImageIcon(image);
logoLabel.setIcon(icon);
commLabel = new JLabel("Port Name");
commComboBox = new JComboBox(getCOMArray().toArray());
BPSLabel = new JLabel("Baud Rate");
Object[] bpsArray = {300,600,1200,2400,4800,9600, 19200,38400,43000,56000, 57600, 115200 };
DefaultComboBoxModel model = new DefaultComboBoxModel(bpsArray);
BPSComboBox = new JComboBox(model);
flowInLabel = new JLabel("Flow Control In");
flowInBox = new JComboBox();
flowOutLabel = new JLabel("Flow Control Out");
flowOutBox = new JComboBox();
dataBitsLabel = new JLabel("Data Bits");
Object[] dataBitsArray = {8,7,6};
dataBitsBox = new JComboBox(dataBitsArray);
stopBitsLabel = new JLabel("Stop Bits");
Object[] stopBitsArray = {1,2};
stopBitsBox = new JComboBox(stopBitsArray);
parityLabel = new JLabel("Parity");
Object[] parityArray = {"NONE", "ODD", "EVEN"};
parityBox = new JComboBox(parityArray);
GridBagHelper.addComponent(panel, stateLabel, 0, 1, 2, 1, 2, 0, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, countLabel, 0, 2, 2, 1, 2, 0, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, commLabel, 0, 4, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, commComboBox, 1, 4, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, BPSLabel, 2, 4, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, BPSComboBox, 3, 4, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, flowInLabel, 0, 5, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, flowInBox, 1, 5, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, flowOutLabel, 2, 5, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, flowOutBox, 3, 5, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, dataBitsLabel, 0, 6, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, dataBitsBox, 1, 6, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, stopBitsLabel, 2, 6, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, stopBitsBox, 3, 6, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, parityLabel, 0, 7, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, parityBox, 1, 7, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, logoLabel, 4, 4, 1, 4, 1, 0, 0.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.EAST);
GridBagHelper.addComponent(panel, connButton, 4, 8, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.BOTH, GridBagConstraints.WEST);
}
public static ArrayList<String> getCOMArray(){
ArrayList<String> comList = new ArrayList<String>();
portList = CommPortIdentifier.getPortIdentifiers();
//System.out.println(portList.toString());
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
//System.out.println(portId.getName());
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
comList.add(portId.getName());
}
}
return comList;
}
@Override
public void serialEvent(SerialPortEvent event) {
// TODO Auto-generated method stub
switch (event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
//声明一个20个字节的缓冲区。
byte[] readBuffer = new byte[20];
try {
stateLabel.setText(STATE);
int numBytes = 0;
while (inputStream.available() > 0) {
//将数据读入readBuffer中。
numBytes = inputStream.read(readBuffer);
}
stateLabel.setText(STATE+(new String(readBuffer)).trim());
System.out.println(new String(readBuffer).trim());
outputStream.write(readBuffer);
//计数
count++;
countLabel.setText(COUNT+String.valueOf(count));
} catch (IOException e) {
System.out.println(e);
}
break;
}
}
public void initConnect(){
try {
serialPort = (SerialPort) portId.open("myapp", 2000);// 打开串口名字为myapp,延迟为2毫秒
} catch (PortInUseException e) {
JOptionPane.showMessageDialog(null, ERROR);
System.exit(0);
}
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, ERROR);
System.exit(0);
}
try {
serialPort.addEventListener(this); // 给当前串口天加一个监听器
} catch (TooManyListenersException e) {
JOptionPane.showMessageDialog(null, ERROR);
System.exit(0);
}
serialPort.notifyOnDataAvailable(true); // 当有数据时通知
try {
int bps = Integer.parseInt(String.valueOf(BPSComboBox.getSelectedItem()));
//System.out.println(bps);
serialPort.setSerialPortParams(bps, SerialPort.DATABITS_8, // 设置串口读写参数
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
//serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN|SerialPort.FLOWCONTROL_RTSCTS_OUT);
} catch (UnsupportedCommOperationException e) {
JOptionPane.showMessageDialog(null, ERROR);
System.exit(0);
}
JOptionPane.showMessageDialog(null, "CONNECTION SUCCESS");
}
//联接事件
class ConnectAction implements Runnable, ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if(null != buttonThread){
return;
}else{
buttonThread = new Thread(this);
buttonThread.start();//开启线程
}
}
@Override
public void run() {
// TODO Auto-generated method stub
if(null != serialPort){
serialPort.close();
}
String comString = String.valueOf(commComboBox.getSelectedItem());
try {
portList = CommPortIdentifier.getPortIdentifiers(); // 得到当前连接上的端口
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {// 判断如果端口类型是串口
if (portId.getName().equals(comString)) { // 判断如果COM3端口已经启动就连接
initConnect();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
buttonThread = null;
}
}
}
对话框类:
package gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CurrentStatePanel extends JPanel{
static int LENGTH = 16;
JPanel panel;
JLabel nameLabel;
JLabel countLabel;
JLabel stateLabel;
StatusMessage message ;
StatusMessage oldMessage;
ArrayList<Integer>countList;
public CurrentStatePanel(StatusMessage message){
super(new BorderLayout());
countList = new ArrayList<Integer>();
for(int i=0; i<LENGTH; i++){
countList.add(0);
}
this.message = message;
this.oldMessage = message;
refreshPanel(message);
}
public void refreshPanel(StatusMessage message){
this.removeAll();
initPanel(message);
}
public void initPanel(StatusMessage message){
GridBagLayout layout = new GridBagLayout();
panel = new JPanel(layout);
panel.setBorder(BorderFactory.createTitledBorder("Current Status"));
Image image = Toolkit.getDefaultToolkit().getImage("logo/on.png");
Icon onIcon = new ImageIcon(image);
image = Toolkit.getDefaultToolkit().getImage("logo/off.png");
Icon offIcon = new ImageIcon(image);
if(message.statusList.size()==0){
for(int i=0; i<LENGTH; i++){
message.statusList.add((byte)1);
}
}
for(int i=0; i<LENGTH; i++){
if(message.statusList.get(i) != oldMessage.statusList.get(i)){
int temp = countList.get(i);
countList.set(i, ++temp);
//System.out.print(temp);
}
nameLabel = new JLabel(String.valueOf(i));
stateLabel = new JLabel();
stateLabel.setBorder(BorderFactory.createLoweredBevelBorder());
stateLabel.setIcon(message.statusList.get(i).byteValue()==1?onIcon:offIcon);
countLabel = new JLabel(String.valueOf(countList.get(i)));
GridBagHelper.addComponent(panel, nameLabel, i, 1, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.CENTER);
GridBagHelper.addComponent(panel, stateLabel, i, 2, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.WEST);
GridBagHelper.addComponent(panel, countLabel, i, 3, 1, 1, 1, 0, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.CENTER);
}
add(panel,BorderLayout.CENTER);
panel.repaint();
panel.revalidate();
oldMessage = message;
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(new Dimension(300,300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final StatusMessage message = new StatusMessage();
final CurrentStatePanel panel = new CurrentStatePanel(message);
frame.add(panel);
frame.setVisible(true);
JButton button = new JButton("change");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
StatusMessage message2 = new StatusMessage();
message2.statusList.clear();
for(int i=0; i<16; i++){
Random random = new Random();
message2.statusList.add((byte)(random.nextInt(2)));
}
panel.refreshPanel(message2);
}
});
frame.add(button,BorderLayout.NORTH);
}
}
本来还想写一些对ModBus的协议分析,处理得代码,但老板认为我不务正业,只能以后再私下研究了。