📄 portframe.java
字号:
package com.zcsoft.jpsc.gui;
import javax.swing.*;
import javax.swing.*;
import com.zcsoft.swing.*;
import com.zcsoft.comm.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.awt.datatransfer.*;
/**
* <p>Title: 串口通信</p>
* <p>Description: 串口通信实验</p>
* <p>Copyright: Copyright (c) 2004-2005</p>
* <p>Company: Zhicheng Software&Service Co. Ltd.</p>
* @author 蒋智湘
* @version 1.0
*/
/**
* 单个串口的控制窗口
* 用户可通过该面板发送接收数据、打开关闭串口、切换到另一个串口、设定串口配置参数等等
*/
class PortFrame extends JInternalFrame
{
private static ResourceBundle res = JpscToolkit.getStringResourceBundle();
/** 串口参数配置文件 */
private static final File portParamConfigureFile
= new File(System.getProperty("work.dir") + File.separator + res.getString("file.port.config"));
/** 所有串口的参数配置 */
private static Properties allPortsConfig;
/** 打开/关闭按钮 */
private JToggleButton cmdSwitch = new JToggleButton();
/** 改变串口 */
private JButton cmdChangePort = new UncapableButton(new ChangePortA());
/** 串口参数配置面板 */
private ConfigurePane configPane = new ConfigurePane();
/** 应用配置参数的按钮 */
private JButton cmdApply = new UncapableButton(new ApplyA());
/** 对应的串口 */
private SerialPortComm portID;
/** 串口配置 */
private SerialPortParam portParam;
/** 发送面板 */
private SendPane sp = new SendPane();
/** 接收面板 */
private ReceivePane rp = new ReceivePane();
/** 左右分隔发送面板和接收面板的面板 */
private JSplitPane centerPane;
/** 整个工具界面属性唯一存储 */
private Properties guiProperties;
PortFrame(SerialPortComm portID, Properties guiProperties)
{
super(null, true, true, true, true);
constructInterface(guiProperties);
installListeners();
this.setPortID(portID);
setGuiProperties(guiProperties);
}
/**
*
* @param guiProperties
*/
private void setGuiProperties(Properties guiProperties)
{
this.guiProperties = guiProperties;
String deviderLocation = guiProperties.getProperty(portID.getName() + ".devider.location");
if (deviderLocation != null)
{
try
{
centerPane.setDividerLocation(Integer.parseInt(deviderLocation));
}
catch (NumberFormatException ex){}
}
Rectangle thisBounds = JpscToolkit.rectValue(guiProperties.getProperty(portID.getName() + ".bounds"));
if (thisBounds != null)
{
this.setBounds(thisBounds);
}
else
{
this.setLocation(10, 10);
this.pack();
}
}
private void saveGuiProperties()
{
guiProperties.setProperty(portID.getName() + ".devider.location",
Integer.toString(centerPane.getDividerLocation()));
guiProperties.setProperty(portID.getName() + ".bounds",
JpscToolkit.stringValue(getBounds()));
}
private void constructInterface(Properties guiProperties)
{
cmdSwitch.setIcon(com.zcsoft.util.ResourceLoader.createImageIcon(this.getClass(), "off"));
cmdSwitch.setSelectedIcon(com.zcsoft.util.ResourceLoader.createImageIcon(this.getClass(), "on"));
cmdSwitch.setToolTipText(res.getString("command.switch.toolTip"));
cmdSwitch.setMnemonic(KeyEvent.VK_PAUSE);
Container c = this.getContentPane();
c.setLayout(new BorderLayout());
ZCFixPanel northPane = new ZCFixPanel();
northPane.addComToModel(cmdSwitch);
northPane.addComToModel(cmdChangePort);
northPane.addComToModel(JpscToolkit.createLabelForComp("config.component.caption", configPane));
northPane.addComToModel(configPane);
northPane.addComToModel(cmdApply);
centerPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
centerPane.setOneTouchExpandable(true);
centerPane.setDividerSize(10);
centerPane.setLeftComponent(this.sp);
centerPane.setRightComponent(this.rp);
c.add(northPane, BorderLayout.NORTH);
c.add(centerPane);
this.sp.setMinimumSize(new Dimension(0, 0));
this.rp.setMinimumSize(this.sp.getMinimumSize());
new TextFieldGroup(configPane.txtMethodParam, cmdApply);
}
private void installListeners()
{
this.cmdSwitch.addItemListener(new ItemListener()
{
/**
* 按下时,打开串口。如果打开失败,则
* 弹起时,关闭串口
* @param e
*/
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() == ItemEvent.SELECTED)
{
try
{
openPort();
}
catch (Exception ex)
{
cmdSwitch.setSelected(false);
JpscToolkit.showMessageDialog((Component)e.getSource(), ex.toString());
}
}
else
{
closePort();
}
}
});;
this.addInternalFrameListener(new InternalFrameAdapter()
{//窗口关闭时,关闭串口
public void internalFrameClosed(InternalFrameEvent e)
{
if (portID.isOpened())
{
closePort();
}
//还需存储发送面板和接收面板间分隔条的位置和串口操作界面窗体的位置和大小
saveGuiProperties();
}
});
}
/**
* 打开串口。
* (1)首先判定参数配置面板上的参数值是否有效,如果有效,则读取面板上的参数,
* 将其存储到SerialPortParam实例中。
* (2)随后判定SerialPortParam实例是否有效,如果无效,则读取当前串口上的参数值(波特率、数据位、停止位和校验方式)。
* (3)最后将SerialPortParam实例的属性值显示的参数配置面板上,并用该实例的属性值设定该串口。
*/
private void openPort()
{
this.portID.open();
if(this.configPane.isParamValueValid())
{
this.configPane.storeConfigValue(this.portParam);
}
if(!this.portParam.isParameterValueValid())
{
this.portID.storeDefaultPortParam(this.portParam);
}
this.portID.setSerialPortParams(this.portParam);
this.configPane.showConfigValue(this.portParam);
this.cmdChangePort.setEnabled(false);
this.sp.notityPortOpened();
}
/**
* 关闭串口
*/
private void closePort()
{
this.portID.close();
this.cmdChangePort.setEnabled(true);
this.sp.notifyPortClosed();
}
/**
* 设置串口时,
* (1)设定PortFrame的标题为串口的名称
* (2)读取配置文件portParam.txt,读入串口配置参数,
* (3)然后用这些参数值显示到属性配置面板上。
* @param port
*/
private void setPortID(SerialPortComm port)
{
this.portID = port;
this.setTitle(port.getName());
this.sp.setPortCommunicator(this.portID);
this.rp.setPortCommunicator(this.portID);
try
{
this.portParam = createPortParamWithPropertiesFile();
}
catch (NumberFormatException ex)
{
JpscToolkit.showMessageDialog(this, ex.toString());
}
if(portParam.isParameterValueValid())
{
this.configPane.showConfigValue(portParam);
}
}
SerialPortComm getPortID()
{
return this.portID;
}
/**
* 从配置文件portParam.txt中读取参数配置值。
* 每个参数项都以comN.开始
* @return
*/
private SerialPortParam createPortParamWithPropertiesFile()
{
SerialPortParam portParam = new SerialPortParam();
if (!this.portParamConfigureFile.exists())
{
return portParam;
}
Properties allPortsParam = this.loadPortParamFile();
if (allPortsParam.isEmpty())
{
return portParam;
}
String prefix = getStoreKeyPrefix();
String keyValue;
if ((keyValue = allPortsParam.getProperty(prefix + "baudRate")) != null)
{
portParam.setBaudRate(Integer.parseInt(keyValue));
}
if ((keyValue = allPortsParam.getProperty(prefix + "dataBits")) != null)
{
portParam.setDataBits(Integer.parseInt(keyValue));
}
if ((keyValue = allPortsParam.getProperty(prefix + "stopBits")) != null)
{
portParam.setStopBits(Integer.parseInt(keyValue));
}
if ((keyValue = allPortsParam.getProperty(prefix + "parity")) != null)
{
portParam.setParity(Integer.parseInt(keyValue));
}
if ((keyValue = allPortsParam.getProperty(prefix + "receiveMethod")) != null)
{
portParam.setReceiveMethod(Integer.valueOf(keyValue));
}
if ((keyValue = allPortsParam.getProperty(prefix + "methodParam")) != null)
{
portParam.setMethodParam(keyValue);
}
return portParam;
}
private String getStoreKeyPrefix()
{
return this.portID.getName()+".";
}
/** 从配置文件中读取串口参数配置哈希表 */
private Properties loadPortParamFile()
{
if (allPortsConfig != null)
{
return allPortsConfig;
}
Properties allPortsParam = new Properties();
FileInputStream is = null;
try
{
is = new FileInputStream(portParamConfigureFile);
allPortsParam.load(is);
is.close();
}
catch (IOException ex)
{
if (is != null)
{
try
{
is.close();
}
catch (IOException ex2){}
}
System.out.println(ex);
}
return (allPortsConfig = allPortsParam);
}
/**
* 将新的串口参数的配置值存入文件中
* @throws IOException 可能的文件操作异常
*/
private void storePortParamIntoFile(SerialPortParam portParam) throws IOException
{
Properties allPortsParam;
if (!portParamConfigureFile.exists())
{
portParamConfigureFile.createNewFile();
allPortsParam = new Properties();
}
else
{
allPortsParam = this.loadPortParamFile();
}
String prefix = getStoreKeyPrefix();
allPortsParam.setProperty(prefix + "baudRate", Integer.toString(portParam.getBaudRate()));
allPortsParam.setProperty(prefix + "dataBits", Integer.toString(portParam.getDataBits()));
allPortsParam.setProperty(prefix + "stopBits", Integer.toString(portParam.getStopBits()));
allPortsParam.setProperty(prefix + "parity", Integer.toString(portParam.getParity()));
allPortsParam.setProperty(prefix + "receiveMethod", portParam.getReceiveMethod().toString());
allPortsParam.setProperty(prefix + "methodParam", portParam.getMethodParam());
FileOutputStream out = null;
try
{
out = new FileOutputStream(portParamConfigureFile);
allPortsParam.store(out, null);
}
finally
{
if (out != null)
{
try
{
out.close();
}
catch (IOException ex){}
}
}
}
/**
* @todo 切换串口事件处理
*/
private class ChangePortA extends com.zcsoft.swing.ZCAction
{
private ChangePortA()
{
super(res.getString("command.change.caption"));
}
/**
* 事件处理实现
* 用JOptionPane显示可选的串口,用户选择串口后,调用PortFrame实例的setPort(CommPortIdentifier)
* 方法
*
* @param e 事件
*/
public void actionPerformed(java.awt.event.ActionEvent e)
{
java.util.List portNames = SerialPortComm.getAvailablePorts();
String selectedPort =
(String)JOptionPane.showInputDialog((Component)e.getSource()
, res.getString("switch.dialog.title"), this.getName()
, JOptionPane.QUESTION_MESSAGE, null
, portNames.toArray(), getPortID().getName());
if (selectedPort != null
&& !getPortID().getName().equals(selectedPort) )
{
setPortID(new SerialPortComm(selectedPort));
}
}
}
/**
* @todo 应用用户设定的串口配置的事件处理
*/
private class ApplyA extends com.zcsoft.swing.ZCAction
{
private ApplyA()
{
super(res.getString("command.apply.caption"));
}
/**
* 事件处理实现
* 读取配置面板上的当前内容,并设定当前串口的相应参数(如果串口已经被打开),
* 最后保存它到文件portParam.txt中
* @param e 事件
*/
public void actionPerformed(java.awt.event.ActionEvent e)
{
SerialPortParam newPortParam = new SerialPortParam();
configPane.storeConfigValue(newPortParam);
try
{
if (portID.isOpened())
{
portID.setSerialPortParams(newPortParam);
}
storePortParamIntoFile(newPortParam);
}
catch (Exception ex)
{
JpscToolkit.showMessageDialog((Component)e.getSource(), ex.toString());
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -