//總共有3個類 commF.java SendComm.java ReadComm.java
//總窗體。commF.java
package youknow;
import java.awt.*;
import java.awt.event.*;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import javax.comm.*;
public class commF extends JFrame implements ActionListener,Runnable,SerialPortEventListener{
private static final long serialVersionUID = 1L;
public JButton 軟件說明,SD,QFS,QJS,Quit,Clo,QD,Open;
public JLabel L1,L2,L3,L4,L5,L6,ms,Fs,Js,xs;//缺多選下拉框。
public JComboBox X1,X2,X3,X4,X5;
public JCheckBox F16,J16,Zd; //打鉤框
public JTextArea F1,J1,subL;
public JTextField Te1,io_message;
InputStream inputStream;
int i = 0;
//public String j = new String();//定義標籤
static CommPortIdentifier portId;
/*Enumeration 爲枚舉型類,在util中 */
@SuppressWarnings("rawtypes")
static Enumeration portList = CommPortIdentifier.getPortIdentifiers();
OutputStream outputStream;
/*RS-232的串行口 */
SerialPort serialPort;
Thread readThread;
byte data[]=new byte[10240];
/*設置判斷要是否關閉串口的標誌*/
boolean mark;
public commF(){
super("java串口調試助理");
軟件說明 = new JButton("調試");
xs = new JLabel("顯示發接情況:");
io_message = new JTextField(25);
L1 = new JLabel("串口號");
L2 = new JLabel("波特率");
L3 = new JLabel("校驗位");
L4 = new JLabel("數據位");
L5 = new JLabel("停止位");
X1 = new JComboBox();
//獲得計算機的串口號並添加到窗體。
while(portList.hasMoreElements()){
portId = (CommPortIdentifier)portList.nextElement();
if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
X1.addItem(portId.getName());
}
}
//X1.setSelectedIndex(0);//JComboBox設置默認值,
//0代表第一項。-1指示沒有做出選擇。
X1.setMaximumRowCount(3);
X2 = new JComboBox();
X2.addItem("300");
X2.addItem("600");
X2.addItem("1200");
X2.addItem("2400");
X2.addItem("4800");
X2.addItem("9600");
X2.addItem("14400");
X2.addItem("19200");
X2.addItem("28800");
X2.addItem("38400");
X2.addItem("57600");
X2.addItem("115200");
X2.setSelectedIndex(5);
X2.setMaximumRowCount(3);
X3 = new JComboBox();
X3.addItem("NONE");
X3.addItem("ODD");
X3.addItem("EVEN");
X3.addItem("MARK");
X3.addItem("SPACE");
X3.setMaximumRowCount(3);
X4 = new JComboBox();
X4.addItem("8");
X4.addItem("7");
X4.addItem("6");
X5 = new JComboBox();
X5.addItem("1");
X5.addItem("1.5");
X5.addItem("2");
Container contentPane1 = getContentPane();//定義容器1
contentPane1.setLayout(new BorderLayout());
JPanel pt1 = new JPanel(new GridLayout(5,2));
pt1.add(L1);
pt1.add(X1);
pt1.add(L2);
pt1.add(X2);
pt1.add(L3);
pt1.add(X3);
pt1.add(L4);
pt1.add(X4);
pt1.add(L5);
pt1.add(X5);
SD = new JButton("手動發送");
QFS = new JButton("清空發送區");
F16 = new JCheckBox("16進制發送",false);
JPanel pt2 = new JPanel(new GridLayout(3,1));
pt2.add(SD);
pt2.add(QFS);
pt2.add(F16);
JPanel pt3 = new JPanel(new GridLayout(2,2));
Clo = new JButton("關閉串口");
//Open = new JButton("打開串口");
QJS = new JButton("清空接收區");
Quit = new JButton("退出程序");
J16 = new JCheckBox("16進制接收");
pt3.add(Clo);
//pt3.add(Open);
pt3.add(QJS);
pt3.add(Quit);
pt3.add(J16);
Fs = new JLabel("發送區");
Zd = new JCheckBox("自動發送",false);
L6 = new JLabel("自動發送週期:");
Te1 = new JTextField("1000");
ms = new JLabel("ms");
Js = new JLabel("接收區");
JPanel pt5 = new JPanel(new FlowLayout());
pt5.add(Zd);
pt5.add(L6);
pt5.add(Te1);
pt5.add(ms);
F1 = new JTextArea();
JScrollPane jp1=new JScrollPane(F1);//設置文本框邊框
F1.setColumns(30);
F1.setRows(5);
F1.setLineWrap(true);
F1.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));//設置邊框。
F1.setText("java調試軟件"); //setText 方法指定 JTextField 中的文本內容。
//textArea = new JTextArea(5, 15);)。
//rows 爲 JTextArea 的高度,以行爲單位;
//columns 爲 JTextArea 的寬度,以字符爲單位。
J1 = new JTextArea();
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //窗口隱藏動作
JScrollPane jp2=new JScrollPane(J1);
J1.setColumns(30);
J1.setRows(5);
J1.setLineWrap(true);
J1.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));//顯示文本邊框
JPanel pt7 = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//j = F1.getText();
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 2;
c.gridheight = 1;
pt7.add(xs,c);
c.gridx = 2;
c.gridy = 0;
c.gridwidth = 4;
c.gridheight = 1;
pt7.add(io_message,c);//打開、關閉串口提示標籤(0,0,1,1)
c.gridx = 8;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
pt7.add(軟件說明,c);//唯康電子(0,0,1,1)
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 2;
c.gridheight = 5;
pt7.add(pt1,c); //串口號、波特率等等(0,1,3,5)
c.gridx = 3;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 5;
pt7.add(pt2,c); //手動發送
c.gridx = 1;
c.gridy = 8;
c.gridwidth = 2;
c.gridheight = 4;
pt7.add(pt3,c); //關閉串口、清空接收區等。(0,8,2,2)
c.gridx = 4;
c.gridy = 1;
c.gridwidth = 5;
c.gridheight = 1;
pt7.add(pt5,c);//自動發送部分。(3,1,5,5)
c.gridx = 4;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
pt7.add(Fs,c);//發送區。(3,2,1,1)
c.gridx = 4;
c.gridy = 2;
c.gridwidth = 5;
c.gridheight = 4;
pt7.add(jp1,c); //發送區文本域。(3,2,5,4)
c.gridx = 4;
c.gridy = 6;
c.gridwidth = 1;
c.gridheight = 1;
pt7.add(Js,c); //接收區標籤。(3,6,1,1)
c.gridx = 4;
c.gridy = 8;
c.gridwidth = 5;
c.gridheight = 4;
pt7.add(jp2,c); //接收區文本域。(3,8,5,4)
contentPane1.add(pt7,BorderLayout.CENTER);
//contentPane1.add(in_message,BorderLayout.SOUTH);
pack();
this.setBounds(300,250,680,350);//setBounds(int x,int y,int width,int height)
setVisible(true);
setResizable(false);//設置窗體大小固定。即不可以改變窗體大小。
QFS.addActionListener(this);
QJS.addActionListener(this);
SD.addActionListener(this);
Quit.addActionListener(this);
軟件說明.addActionListener(this);
Clo.addActionListener(this);
//Zd.addActionListener(this);
QD = new JButton("確定");
//QD.addActionListener(this);
}
public static void main(String args[]){
new commF();
}
@Override
public void actionPerformed(ActionEvent e)
{
JButton but = (JButton) e.getSource();
JFrame subW =new JFrame("調試");
SendComm sc = new SendComm();
ReadComm rc = new ReadComm();
if(but==QFS)
F1.setText(null);
if(but == QJS)
J1.setText(null);
if(but == SD)
//J1.setText(F1.getText()); //僅僅輸入一次的時候。
J1.append(F1.getText()); //連續輸入N多次。
if(but == Quit)
System.exit(0);
if(but ==QD)
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
dispose();
}
});
if(but == 軟件說明)
{
this.setVisible(false);
subL = new JTextArea();
subL.setText(" 調試代表着一切。");
subL.setColumns(17);
subL.setRows(5);
subL.setLineWrap(true);
JPanel subJ = new JPanel();
subJ.add(subL);
subJ.add(QD);
subW.add(subJ);
subW.setBounds(550,300,300,150);
subW.setResizable(false);
this.setVisible(true);
軟件說明.setEnabled(false);
subW.setVisible(true);
//this.getParent().setVisible(false);獲得父級容器並設置爲不可見。
}
if (e.getSource()==Clo)
{
serialPort.close(); //關閉串口
Clo.setActionCommand("關閉串口");
Clo.setText("打開串口");
mark=true; //用於中止線程的run()方法
io_message.setText("串口COM1已經關閉,停止發送數據.");
}
else
sc.clopen();
if(X1.getSelectedItem().toString().equals("COM1"))
rc.acc();
}
@Override
public void serialEvent(SerialPortEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void run() {
//TODO Auto-generated method stub
}
}
//此類爲SendComm類。爲串口發送
package youknow;
import java.io.IOException;
import javax.comm.*;
public class SendComm extends commF
{
private static final long serialVersionUID = 1L;
Thread readThread;
public void clopen()
{
Clo.setActionCommand("打開串口");
Clo.setText("關閉串口");
mark=false;
/*從文本區按字節讀取數據*/
data=F1.getText().getBytes();
Clo.setText("關閉串口");
/*打開串口*/
start();
io_message.setText("串口COM1已經打開,正在每2秒鐘發送一次數據.....");
}//SendComm() end
/*打開串口,並調用線程發送數據*/
public void start()
{
/*獲取系統中所有的通訊端口 */
/* 用循環結構找出串口 */
while (portList.hasMoreElements()){
/*強制轉換爲通訊端口類型*/
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
if (X1.getSelectedItem().toString().equals("COM1")) {
/*打開串口 */
try {
serialPort = (SerialPort) portId.open("ReadComm", 2000);
}
catch (PortInUseException e) {
//this.theApp.getMessageDlg().MessageLabel.setText(PortName+"串口已被佔用");
}
/*設置串口輸出流*/
try {
outputStream = serialPort.getOutputStream();
}
catch (IOException e) {}
} //if end
} //if end
} //while end
/*調用線程發送數據*/
try{
readThread = new Thread(this);
//線程負責每發送一次數據,休眠2秒鐘
readThread.start();
}
catch (Exception e) { }
} //start() end
/*發送數據,休眠2秒鐘後重發*/
public void run() {
/*設置串口通訊參數*/
try {serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e) { }
/*發送數據流(將數組data[]中的數據發送出去)*/
try {
outputStream.write(data);
}
catch (IOException e) { }
/*發送數據後休眠2秒鐘,然後再重發*/
try {
Thread.sleep(2000);
if (mark){
return; //結束run方法,導致線程死亡
}
start();
}
catch (InterruptedException e) { }
//SendComm()
}
}
//以下類爲ReadComm類。爲串口的接收數據類
package youknow;
import java.io.IOException;
import java.util.TooManyListenersException;
import javax.comm.*;
public class ReadComm extends commF
{
private static final long serialVersionUID = 1L;
Thread readThread;
public void acc(){
/*獲取系統中所有的通訊端口 */
portList=CommPortIdentifier.getPortIdentifiers();
/* 用循環結構找出串口 */
while (portList.hasMoreElements()){
/*強制轉換爲通訊端口類型*/
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
if (X1.getSelectedItem().toString().equals("COM1")) {
try {
serialPort = (SerialPort) portId.open("ReadComm", 2000);
io_message.setText("已打開端口COM1 ,正在接收數據..... ");
}
catch (PortInUseException e) { }
/*設置串口監聽器*/
try {
serialPort.addEventListener(this);
}
catch (TooManyListenersException e) { }
/* 偵聽到串口有數據,觸發串口事件*/
serialPort.notifyOnDataAvailable(true);
} //if end
} //if end
} //while end
readThread = new Thread(this);
readThread.start(); //線程負責每接收一次數據休眠20秒鐘
} //actionPerformed() end
/*接收數據後休眠20秒鐘*/
public void run() {
try {
Thread.sleep(20000);
}
catch (InterruptedException e) { }
} //run() end
/*串口監聽器觸發的事件,設置串口通訊參數,讀取數據並寫到文本區中*/
public void serialEvent(SerialPortEvent event) {
/*設置串口通訊參數:波特率、數據位、停止位、奇偶校驗*/
try {
serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e) {}
byte[] readBuffer = new byte[20];
try {
inputStream = serialPort.getInputStream();
}
catch (IOException e) {}
try {
/* 從線路上讀取數據流 */
while (inputStream.available() > 0) {
//int numBytes = inputStream.read(readBuffer);
} //while end
String str = new String(readBuffer);
/*接收到的數據存放到文本區中*/
J1.append(str+"\n");
}
catch (IOException e) { }
} //serialEvent() end
//類R_Frame end
}
我知道SendComm.java跟ReadComm.java中的extended commF是錯誤的。但是,如果不繼承commF的話,兩個類中的控件又要自己定義。這樣就跟commF中的控件連接不起來。
問題是:如何運行commF.java,使得觸碰了commF中的控件,可以觸發SendComm跟ReadComm中的事件。?????