1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
|
package com.elkan1788.view;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.TextField;
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.List;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
import javax.imageio.ImageIO;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
public class JavaRs232 extends JFrame implements ActionListener, SerialPortEventListener {
/**
* JDK Serial Version UID
*/
private static final long serialVersionUID = -7270865686330790103L;
protected int WIN_WIDTH = 380;
protected int WIN_HEIGHT = 300;
private JComboBox<?> portCombox, rateCombox, dataCombox, stopCombox, parityCombox;
private Button openPortBtn, closePortBtn, sendMsgBtn;
private TextField sendTf;
private TextArea readTa;
private JLabel statusLb;
private String portname, rate, data, stop, parity;
protected CommPortIdentifier portId;
protected Enumeration<?> ports;
protected List<String> portList;
protected SerialPort serialPort;
protected OutputStream outputStream = null;
protected InputStream inputStream = null;
protected String mesg;
protected int sendCount, reciveCount;
/**
* 默认构造函数
*/
public JavaRs232() {
super("Java RS-232串口通信测试程序 凡梦星尘");
setSize(WIN_WIDTH, WIN_HEIGHT);
setLocationRelativeTo(null);
Image icon = null;
try {
icon = ImageIO.read(JavaRs232.class.getResourceAsStream("/res/rs232.png"));
} catch (IOException e) {
showErrMesgbox(e.getMessage());
}
setIconImage(icon);
setResizable(false);
scanPorts();
initComponents();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
/**
* 初始化各UI组件
* @since 2012-3-22 下午11:56:39
*/
public void initComponents() {
// 共用常量
Font lbFont = new Font("微软雅黑", Font.TRUETYPE_FONT, 14);
// 创建左边面板
JPanel northPane = new JPanel();
northPane.setLayout(new GridLayout(1, 1));
// 设置左边面板各组件
JPanel leftPane = new JPanel();
leftPane.setOpaque(false);
leftPane.setLayout(new GridLayout(3,2));
JLabel portnameLb = new JLabel("串口号:");
portnameLb.setFont(lbFont);
portnameLb.setHorizontalAlignment(SwingConstants.RIGHT);
portCombox = new JComboBox<String>((String [])portList.toArray(new String[0]));
portCombox.addActionListener(this);
JLabel databitsLb = new JLabel("数据位:");
databitsLb.setFont(lbFont);
databitsLb.setHorizontalAlignment(SwingConstants.RIGHT);
dataCombox = new JComboBox<Integer>(new Integer[]{5, 6, 7, 8});
dataCombox.setSelectedIndex(3);
dataCombox.addActionListener(this);
JLabel parityLb = new JLabel("校验位:");
parityLb.setFont(lbFont);
parityLb.setHorizontalAlignment(SwingConstants.RIGHT);
parityCombox = new JComboBox<String>(new String[]{"NONE","ODD","EVEN","MARK","SPACE"});
parityCombox.addActionListener(this);
// 添加组件至面板
leftPane.add(portnameLb);
leftPane.add(portCombox);
leftPane.add(databitsLb);
leftPane.add(dataCombox);
leftPane.add(parityLb);
leftPane.add(parityCombox);
//创建右边面板
JPanel rightPane = new JPanel();
rightPane.setLayout(new GridLayout(3,2));
// 设置右边面板各组件
JLabel baudrateLb = new JLabel("波特率:");
baudrateLb.setFont(lbFont);
baudrateLb.setHorizontalAlignment(SwingConstants.RIGHT);
rateCombox = new JComboBox<Integer>(new Integer[]{2400,4800,9600,14400,19200,38400,56000});
rateCombox.setSelectedIndex(2);
rateCombox.addActionListener(this);
JLabel stopbitsLb = new JLabel("停止位:");
stopbitsLb.setFont(lbFont);
stopbitsLb.setHorizontalAlignment(SwingConstants.RIGHT);
stopCombox = new JComboBox<String>(new String[]{"1","2","1.5"});
stopCombox.addActionListener(this);
openPortBtn = new Button("打开端口");
openPortBtn.addActionListener(this);
closePortBtn = new Button("关闭端口");
closePortBtn.addActionListener(this);
// 添加组件至面板
rightPane.add(baudrateLb);
rightPane.add(rateCombox);
rightPane.add(stopbitsLb);
rightPane.add(stopCombox);
rightPane.add(openPortBtn);
rightPane.add(closePortBtn);
// 将左右面板组合添加到北边的面板
northPane.add(leftPane);
northPane.add(rightPane);
// 创建中间面板
JPanel centerPane = new JPanel();
// 设置中间面板各组件
sendTf = new TextField(42);
readTa = new TextArea(8,50);
readTa.setEditable(false);
readTa.setBackground(new Color(225,242,250));
centerPane.add(sendTf);
sendMsgBtn = new Button(" 发送 ");
sendMsgBtn.addActionListener(this);
// 添加组件至面板
centerPane.add(sendTf);
centerPane.add(sendMsgBtn);
centerPane.add(readTa);
// 设置南边组件
statusLb = new JLabel();
statusLb.setText(initStatus());
statusLb.setOpaque(true);
// 获取主窗体的容器,并将以上三面板以北、中、南的布局整合
JPanel contentPane = (JPanel)getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.setBorder(new EmptyBorder(0, 0, 0, 0));
contentPane.setOpaque(false);
contentPane.add(northPane, BorderLayout.NORTH);
contentPane.add(centerPane, BorderLayout.CENTER);
contentPane.add(statusLb, BorderLayout.SOUTH);
}
/**
* 初始化状态标签显示文本
* @return String
* @since 2012-3-23 上午12:01:53
*/
public String initStatus() {
portname = portCombox.getSelectedItem().toString();
rate = rateCombox.getSelectedItem().toString();
data = dataCombox.getSelectedItem().toString();
stop = stopCombox.getSelectedItem().toString();
parity = parityCombox.getSelectedItem().toString();
StringBuffer str = new StringBuffer("当前串口号:");
str.append(portname).append(" 波特率:");
str.append(rate).append(" 数据位:");
str.append(data).append(" 停止位:");
str.append(stop).append(" 校验位:");
str.append(parity);
return str.toString();
}
/**
* 扫描本机的所有COM端口
* @since 2012-3-23 上午12:02:42
*/
public void scanPorts() {
portList = new ArrayList<String>();
Enumeration<?> en = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier portId;
while(en.hasMoreElements()){
portId = (CommPortIdentifier) en.nextElement();
if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
String name = portId.getName();
if(!portList.contains(name)) {
portList.add(name);
}
}
}
if(null == portList
|| portList.isEmpty()) {
showErrMesgbox("未找到可用的串行端口号,程序无法启动!");
System.exit(0);
}
}
/**
* 打开串行端口
* @since 2012-3-23 上午12:03:07
*/
public void openSerialPort() {
// 获取要打开的端口
try {
portId = CommPortIdentifier.getPortIdentifier(portname);
} catch (NoSuchPortException e) {
showErrMesgbox("抱歉,没有找到"+portname+"串行端口号!");
setComponentsEnabled(true);
return ;
}
// 打开端口
try {
serialPort = (SerialPort) portId.open("JavaRs232", 2000);
statusLb.setText(portname+"串口已经打开!");
} catch (PortInUseException e) {
showErrMesgbox(portname+"端口已被占用,请检查!");
setComponentsEnabled(true);
return ;
}
// 设置端口参数
try {
int rate = Integer.parseInt(this.rate);
int data = Integer.parseInt(this.data);
int stop = stopCombox.getSelectedIndex()+1;
int parity = parityCombox.getSelectedIndex();
serialPort.setSerialPortParams(rate,data,stop,parity);
} catch (UnsupportedCommOperationException e) {
showErrMesgbox(e.getMessage());
}
// 打开端口的IO流管道
try {
outputStream = serialPort.getOutputStream();
inputStream = serialPort.getInputStream();
} catch (IOException e) {
showErrMesgbox(e.getMessage());
}
// 给端口添加监听器
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
showErrMesgbox(e.getMessage());
}
serialPort.notifyOnDataAvailable(true);
}
/**
* 给串行端口发送数据
* @since 2012-3-23 上午12:05:00
*/
public void sendDataToSeriaPort() {
try {
sendCount++;
outputStream.write(mesg.getBytes());
outputStream.flush();
} catch (IOException e) {
showErrMesgbox(e.getMessage());
}
statusLb.setText(" 发送: "+sendCount+" 接收: "+reciveCount);
}
/**
* 关闭串行端口
* @since 2012-3-23 上午12:05:28
*/
public void closeSerialPort() {
try {
if(outputStream != null)
outputStream.close();
if(serialPort != null)
serialPort.close();
serialPort = null;
statusLb.setText(portname+"串口已经关闭!");
sendCount = 0;
reciveCount = 0;
sendTf.setText("");
readTa.setText("");
} catch (Exception e) {
showErrMesgbox(e.getMessage());
}
}
/**
* 显示错误或警告信息
* @param msg 信息
* @since 2012-3-23 上午12:05:47
*/
public void showErrMesgbox(String msg) {
JOptionPane.showMessageDialog(this, msg);
}
/**
* 各组件行为事件监听
*/
public void actionPerformed(ActionEvent e) {
if(e.getSource() == portCombox
|| e.getSource() == rateCombox
|| e.getSource() == dataCombox
|| e.getSource() == stopCombox
|| e.getSource() == parityCombox){
statusLb.setText(initStatus());
}
if(e.getSource() == openPortBtn){
setComponentsEnabled(false);
openSerialPort();
}
if(e.getSource() == closePortBtn){
if(serialPort != null){
closeSerialPort();
}
setComponentsEnabled(true);
}
if(e.getSource() == sendMsgBtn){
if(serialPort == null){
showErrMesgbox("请先打开串行端口!");
return ;
}
mesg = sendTf.getText();
if(null == mesg || mesg.isEmpty()){
showErrMesgbox("请输入你要发送的内容!");
return ;
}
sendDataToSeriaPort();
}
}
/**
* 端口事件监听
*/
public void serialEvent(SerialPortEvent event) {
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:
byte[] readBuffer = new byte[50];
try {
while (inputStream.available() > 0) {
inputStream.read(readBuffer);
}
StringBuilder receivedMsg = new StringBuilder("/-- ");
receivedMsg.append(new String(readBuffer).trim()).append(" --/\n");
readTa.append(receivedMsg.toString());
reciveCount++;
statusLb.setText(" 发送: "+sendCount+" 接收: "+reciveCount);
} catch (IOException e) {
showErrMesgbox(e.getMessage());
}
}
}
/**
* 设置各组件的开关状态
* @param enabled 状态
* @since 2012-3-23 上午12:06:24
*/
public void setComponentsEnabled(boolean enabled) {
openPortBtn.setEnabled(enabled);
openPortBtn.setEnabled(enabled);
portCombox.setEnabled(enabled);
rateCombox.setEnabled(enabled);
dataCombox.setEnabled(enabled);
stopCombox.setEnabled(enabled);
parityCombox.setEnabled(enabled);
}
/**
* 运行主函数
* @param args
* @since 2012-3-23 上午12:06:45
*/
public static void main(String[] args) {
new JavaRs232();
}
}
|