⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portframe.java

📁 用于串口通讯测试的工具软件。完全使用java语言编写。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

/** 电报发送面板 */
class SendPane extends JComponent
		implements ListSelectionListener, TextFieldGroup.Checker
{
	private static ResourceBundle res = JpscToolkit.getStringResourceBundle();
	/** 待发送数据 */
	private JTextField txtTelegram = new JTextField();
	/** 名称 */
	private JTextField txtName = new JTextField(6);
	/** 数据格式 */
	private JComboBox cbFormat = JpscToolkit.createFormatCompnent();
	/** 发送按钮 */
	private JButton cmdSendMsg = new UncapableButton(new SendA());
	/** 定时连续发送间隔,最长10分钟 */
	private JTextField txtResendInterval = new ZCIntTextField(1000, 1000 * 60 * 10, 4);
	/** 定时连续发送按钮 */
	private JToggleButton cmdResend = new JToggleButton();
	/** 连续发送的次数,0表示一直发送 */
	private int timesToResend = 0;
	/** 暂存发送项到表格中的按钮 */
	private JButton cmdAdd = new UncapableButton(new AddTelegramA());
	/** 历史发送数据表格 */
	private RWTableModel tm = new RWTableModel(new Object[]{
				res.getString("table.column.name")
				, res.getString("table.column.format")
				, res.getString("table.column.length")
				, res.getString("table.column.telegram")}, 0);
	private AutoAdaptColumnWidthTable table = new AutoAdaptColumnWidthTable(tm);
	/** 将存放在文件中的历史数据装入到表格中的按钮 */
	private JButton cmdLoadHistory = new UncapableButton(new LoadHistoryA());
	/** 保存表格中的内容到历史中的按钮 */
	private JButton cmdSaveTableData = new UncapableButton(new SaveA());
	/** 串口发送实现 */
	private SerialPortComm portCommunicator;
	/** 用于绑定发送按钮可用性的TextFieldGroup实例 */
	private TextFieldGroup tfgSend;
	private TextFieldGroup tfgResend;

	SendPane()
	{
		this.constructInterface();
		cmdResend.addItemListener(new ResendListener());
		cmdResend.addMouseListener(new RightClickListener());
		table.getSelectionModel().addListSelectionListener(this);
		SelectedRowDeleteAction.enableTable(table);
	}

	private void constructInterface()
	{
		ZCFixPanel fp = new ZCFixPanel();
		fp.addComToModel(JpscToolkit.createLabelForComp(("field.telegram.caption"), this.txtTelegram));
		fp.addComToModel(this.txtTelegram, 5, true);
		fp.newLine();
		fp.addComToModel(JpscToolkit.createLabelForComp(("field.name.caption"), this.txtName));
		fp.addComToModel(this.txtName, true);
		fp.addComToModel(JpscToolkit.createLabelForComp(("sendPane.field.format.caption"), this.cbFormat));
		fp.addComToModel(this.cbFormat);
		fp.addComToModel(this.cmdSendMsg);
		fp.newLine();
		fp.addComToModel(this.cmdAdd, 2);
		fp.addComToModel(JpscToolkit.createLabelForComp(("field.interval.caption"), this.txtResendInterval));
		fp.addComToModel(this.txtResendInterval);
		fp.addComToModel(this.cmdResend);
		fp.newLine();
		fp.addComToModel(new JScrollPane(table), 6, 1, GridBagConstraints.BOTH);
		fp.newLine();
		fp.addComToModel(this.cmdLoadHistory, 4);
		fp.addComToModel(this.cmdSaveTableData);

		this.setLayout(new BorderLayout());
		this.add(fp.getSubPane());

		table.setVisibleRowCount(15);
//		table.setOrderable(false);
		table.setShowHorizontalLines(false);
		JpscToolkit.setCommandPropterties(cmdResend, "command.resend");

		new TextFieldGroup(new JComponent[]{txtTelegram, txtName}, cmdAdd);
		tfgSend = new TextFieldGroup(txtTelegram, cmdSendMsg);
		tfgSend.addChecker(this);
		tfgResend = new TextFieldGroup(new JComponent[]{txtTelegram, txtResendInterval}, cmdResend);
		tfgResend.addChecker(this);

		this.cbFormat.addItemListener(new FormatItemListener());
	}

	void setPortCommunicator(SerialPortComm spc)
	{
		this.portCommunicator = spc;
	}

	/**
	 * 被通知串口已经被关闭
	 * 串口关闭时,如果"连续发送"按钮已经按下,则迫使它弹起。
	 */
	void notifyPortClosed()
	{
		if (cmdResend.isSelected())
		{
			cmdResend.setSelected(false);
		}
		tfgSend.check();
		tfgResend.check();
	}

	void notityPortOpened()
	{
		tfgSend.check();
		tfgResend.check();
	}

	/**
	 * TextFieldGroup.Checker接口实现
	 * 判定发送和连发按钮是否可以被设置为可用
	 */
	public boolean toSetEnabled()
	{
		return this.portCommunicator != null && this.portCommunicator.isOpened();
	}

	/**
	 * 获取存储发送电报的文件
	 * 注意:操作系统不能创建文件名串口或并口的文件,如COM1,LPT1,NUL
	 *
	 * @return
	 */
	private File getHistoryFile()
	{
		return new File(System.getProperty("work.dir")
							 + File.separator
							 + JpscToolkit.getFormatedString("file.message.history",
																		 portCommunicator.getName()));
	}

	/**
	 * 将用户选中行的数据填入“待发数据”、“名称”和“数据格式”输入组件中
	 * @param e 表格行选中事件
	 */
	public void valueChanged(ListSelectionEvent e)
	{
		if (!e.getValueIsAdjusting())
		{
			int selectedRow = table.getSelectedRow();
			if (selectedRow >= 0 && tm.getRowCount() > selectedRow)
			{
				this.txtName.setText((String)tm.getValueAt(selectedRow, 0));
				this.cbFormat.setSelectedItem(tm.getValueAt(selectedRow, 1));
				this.txtTelegram.setText((String)tm.getValueAt(selectedRow, 3));
			}
		}
	}

	/**
	 * @todo 发送一次按钮的事件处理
	 */
	private class SendA extends com.zcsoft.swing.ZCAction
	{
		private SendA()
		{
			super(res.getString("command.send.caption"));
		}

		/**
		 * 事件处理实现
		 * @param e 事件
		 */
		public void actionPerformed(java.awt.event.ActionEvent e)
		{
			try
			{
				portCommunicator.sendMessage(JpscToolkit.byteArrayOfTelegram(txtTelegram.getText(),
														JpscToolkit.getRadixForSelectedFormat(cbFormat)));
			}
			catch (Exception ex)
			{
				JpscToolkit.showMessageDialog((Component)e.getSource(), ex.toString());
			}
		}
	}

	/**
	 * @todo 连续发送电报按钮的事件处理
	 */
	private class ResendListener
			implements ItemListener, ActionListener
	{
		/** 实现连续发送的定时器 */
		private javax.swing.Timer resendTimer;
		/** 连续发送的电报 */
		private byte[] messageToResend;
		/** 已经发送的次数 */
		private int resentTimes = 0;
		/** 连续发送按钮的初始背景色。因为连续发送过程中,按钮的背景会改变。
		 * 连续发送停止时,需要复原连发按钮的背景色。
		 */
		private Color buttonBackground;

		private void stopResend()
		{
			if (resendTimer != null)
			{
				resendTimer.stop();
				cmdResend.setBackground(buttonBackground);
				this.setEditable(true);
				if (cmdResend.isSelected())
				{
					cmdResend.setSelected(false);
				}
			}
		}

		private void startResend()
		{
			int delay = Integer.parseInt(txtResendInterval.getText());
			if (resendTimer == null)
			{
				resendTimer = new javax.swing.Timer(delay, this);
				resendTimer.setRepeats(true);
			}
			else
			{
				resendTimer.setDelay(delay);
			}
			try
			{
				messageToResend = JpscToolkit.byteArrayOfTelegram(txtTelegram.getText(),
													JpscToolkit.getRadixForSelectedFormat(cbFormat));
				resendTimer.start();
				resentTimes = 0;
				buttonBackground = cmdResend.getBackground();
				this.setEditable(false);
			}
			catch (Exception ex)
			{
				JpscToolkit.showMessageDialog(cmdResend, ex.toString());
				stopResend();
			}
		}

		/**
		 * 设定“待发送数据”、“数据格式”和“发送间隔”组件是否可以被编辑。
		 * @param b true可以,false否
		 */
		private void setEditable(boolean b)
		{
			txtTelegram.setEditable(b);
			txtResendInterval.setEditable(b);
			cbFormat.setEnabled(b);
		}

		/**
		 * 按下时,开始重发
		 * 弹起时,停止重发
		 *
		 * @param e 事件
		 */
		public void itemStateChanged(ItemEvent e)
		{
			if(e.getStateChange() == ItemEvent.SELECTED)
			{
				this.startResend();
			}
			else
			{
				this.stopResend();
			}
		}

		/**
		 * 重发时钟执行事件实现
		 */
		public void actionPerformed(java.awt.event.ActionEvent e)
		{
			//如果发送次数达到用户指定的连发次数,就停止重发
			if (timesToResend > 0 && timesToResend < resentTimes)
			{
				stopResend();
				return;
			}
			//用一个明显的标记表示正在发送数据。
			//来回变更连发按钮的背景色
			cmdResend.setBackground(cmdResend.getBackground() == buttonBackground
											?buttonBackground.darker()
											:buttonBackground);
			try
			{
				portCommunicator.sendMessage(messageToResend);
				resentTimes ++;
			}
			catch (IllegalStateException ex)
			{

				JpscToolkit.showMessageDialog(cmdResend, ex.getMessage());
			}
		}
	}

	/** @todo 连发按钮上鼠标右键单击处理 */
	private class RightClickListener extends MouseAdapter
	{

		/**
		 * 事件处理实现
		 * 当用户在连续发送按钮上单击鼠标右键时,显示输入连发次数值的输入框
		 * @param e
		 */
		public void mouseReleased(MouseEvent e)
		{
			if (e.isPopupTrigger())
			{
				inputResendTimes(e);
			}
		}

		private void inputResendTimes(MouseEvent e) throws MissingResourceException
		{
			String times = (String)JOptionPane.showInputDialog((Component)e.getSource()
												, res.getString("resendTimes.dialog.message")
												, res.getString("input.dialog.title")
												, JOptionPane.QUESTION_MESSAGE, null
												, null, Integer.toString(timesToResend));
			if (times != null)
			{
				try
				{
					timesToResend = Integer.parseInt(times);
				}
				catch (NumberFormatException ex){}
			}
		}
	}

	/**
	 * @todo 将输入的电报放入界面表格的事件处理
	 */
	private class AddTelegramA extends com.zcsoft.swing.ZCAction
	{
		private AddTelegramA()
		{
			super(res.getString("command.storeIntoTable.caption"));
			this.setIcon(com.zcsoft.util.ResourceLoader.createImageIcon(this.getClass(), "addItem"));
		}

		/**
		 * 根据电报的名称查找表格是否存在有相同名称的电报,如果有,则覆盖它,否则将新的电报添加到表格
		 * 的后面。
		 * @param e 事件
		 */
		public void actionPerformed(java.awt.event.ActionEvent e)
		{
			String name = txtName.getText();
			Object format = cbFormat.getSelectedItem();
			String telegram = txtTelegram.getText();
			Integer length = new Integer(JpscToolkit.telegramLength(telegram, format));
			int maybeExistRow = indexRowOf(name);
			if (maybeExistRow >= 0)
			{
				tm.setValueAt(format, maybeExistRow, 1);
				tm.setValueAt(length, maybeExistRow, 2);
				tm.setValueAt(telegram, maybeExistRow, 3);
			}
			else
			{
				Vector rowData = new Vector(4);
				rowData.add(name);
				rowData.add(format);
				rowData.add(length);
				rowData.add(telegram);
				tm.addRow(rowData);
				maybeExistRow = tm.getRowCount() - 1;
			}
			table.changeSelection(maybeExistRow, 0, false, false);
		}

		/**
		 * 在界面表格中查找电报名称同指定名称相等的那一行的索引。
		 * 如果没有,则返回-1
		 */
		private int indexRowOf(String name)
		{
			for (int i = 0; i < tm.getRowCount(); i++)
			{
				if (name.equals(tm.getValueAt(i, 0)))
				{
					return i;
				}
			}
			return -1;
		}

	}

	/**
	 * @todo 保存表格中的电报到文件中的事件处理
	 */
	private class SaveA extends com.zcsoft.swing.ZCAction
	{
		private SaveA()
		{
			super(res.getString("command.save.caption"));
			this.setIcon(com.zcsoft.util.ResourceLoader.createImageIcon(this.getClass(), "save"));
		}

		/**
		 * 事件处理实现
		 * @param e 事件
		 */
		public void actionPerformed(java.awt.event.ActionEvent e)
		{
			File outputFile = getHistoryFile();
			if (outputFile.exists()
				 && tm.getRowCount() == 0
				 && false == ZCFixPanel.isSure((Component)e.getSource()
														, JpscToolkit.getFormatedString("sureToSave.dialog.message", outputFile.getAbsolutePath())
														, res.getString("sure.dialog.title")))
			{
				return;
			}
			ObjectOutputStream fos = null;
			try
			{
				if (!outputFile.exists())
				{
					outputFile.createNewFile();
				}
				fos = new ObjectOutputStream(new FileOutputStream(outputFile.getAbsolutePath(), false));
				fos.writeObject(tm.getDataVector());
				fos.flush();
			}
			catch (IOException ex)
			{
				JpscToolkit.showMessageDialog((Component)e.getSource(), ex.toString());
			}
			finally
			{
				if (fos != null)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -