package dell_system; import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import dell_targets.Dell_tag; import publicsWay.Languages; import udptcp.UDPPortAReceiver; import udptcp.UDPPortBReceiver; public class MessageViewPanel extends JPanel { private static final long serialVersionUID = 1L; private ResourceBundle messages; private JButton btnStart, btnPause, btnClear, btnSend; private static JComboBox cbDataType; private static JComboBox cbProtocol; private static JComboBox cbDeviceId; private static JComboBox cbRemoteDevice; private static JCheckBox chkAutoSave; private static JCheckBox chkShowSource; private static JTextArea txtDataView; private JScrollPane scrollPane; private JTextField txtSendData; private JRadioButton rdoSendHex; private JRadioButton rdoSendAscii; private JCheckBox chkAppendNewline; private static final ThreadLocal SB = ThreadLocal.withInitial(() -> new StringBuilder(256)); private static final char[] DIGITS = "0123456789".toCharArray(); private static final String COLON = ":"; private static final String PREFIX = "["; private static final String SUFFIX = "]"; public static volatile boolean isWindowVisible = false; private static boolean isCapturing = false; private static boolean isStarted = false; // ÐÂÔö£º¸ú×Ù¿ªÊ¼°´Å¥×´Ì¬ private static Map remoteDeviceLocalPortMap = new HashMap<>(); public MessageViewPanel(ResourceBundle messages) { this.messages = messages; initializeUI(); } public void addNotify() { super.addNotify(); Window window = SwingUtilities.getWindowAncestor(this); if (window != null) { isWindowVisible = true; window.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { isWindowVisible = false; } @Override public void windowClosed(WindowEvent e) { isWindowVisible = false; } }); } } private void initializeUI() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(5, 10, 5, 10); gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; setBackground(new Color(240, 245, 249)); // ÏÂÀ­¿òÇøÓò gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 1; gbc.weightx = 0.25; JPanel dataTypePanel = new JPanel(new BorderLayout(5, 0)); dataTypePanel.setBackground(new Color(240, 245, 249)); dataTypePanel.add(createLabel(messages.getString("MESSAGE_VIEW_DATA_TYPE")), BorderLayout.WEST); cbDataType = new JComboBox<>(); loadtyps(); dataTypePanel.add(cbDataType, BorderLayout.CENTER); add(dataTypePanel, gbc); gbc.gridx++; JPanel protocolPanel = new JPanel(new BorderLayout(5, 0)); protocolPanel.setBackground(new Color(240, 245, 249)); protocolPanel.add(createLabel(messages.getString("MESSAGE_VIEW_PROTOCOL")), BorderLayout.WEST); cbProtocol = new JComboBox<>(new String[]{ "ALL", "55AA01", "55AA02", "55AA03", "55AA05", "55AA07", "55AA0A", "55AA0C", "55AA12", "55AA14", "55AA20", "GNGGA", "XTB" }); protocolPanel.add(cbProtocol, BorderLayout.CENTER); add(protocolPanel, gbc); gbc.gridx++; JPanel devicePanel = new JPanel(new BorderLayout(5, 0)); devicePanel.setBackground(new Color(240, 245, 249)); devicePanel.add(createLabel(messages.getString("MESSAGE_VIEW_DEVICE_ID")), BorderLayout.WEST); cbDeviceId = new JComboBox<>(); cbDeviceId.setEditable(true); cbDeviceId.addItem("ALL"); loadDeviceIds(); devicePanel.add(cbDeviceId, BorderLayout.CENTER); add(devicePanel, gbc); gbc.gridx++; JPanel remoteDevicePanel = new JPanel(new BorderLayout(5, 0)); remoteDevicePanel.setBackground(new Color(240, 245, 249)); remoteDevicePanel.add(createLabel(messages.getString("MESSAGE_VIEW_REMOTE_DEVICE")), BorderLayout.WEST); cbRemoteDevice = new JComboBox<>(); cbRemoteDevice.setEditable(true); cbRemoteDevice.addItem(messages.getString("MESSAGE_VIEW_ALL_DEVICES")); remoteDevicePanel.add(cbRemoteDevice, BorderLayout.CENTER); add(remoteDevicePanel, gbc); // ¸´Ñ¡¿òÇøÓò - ¼ò»¯ÎªÁ½¸ö¸´Ñ¡¿ò gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 4; gbc.weightx = 1.0; JPanel checkboxPanel = new JPanel(new GridLayout(1, 2, 6, 0)); // ÐÞ¸ÄΪ2ÁÐ checkboxPanel.setBackground(new Color(240, 245, 249)); chkAutoSave = createStyledCheckbox(messages.getString("MESSAGE_VIEW_AUTO_SAVE")); chkShowSource = createStyledCheckbox(messages.getString("MESSAGE_VIEW_SHOW_SOURCE")); // ÒÆ³ýÁËÊ®Áù½øÖƺÍASCIIÏÔʾ¸´Ñ¡¿ò checkboxPanel.add(chkAutoSave); checkboxPanel.add(chkShowSource); add(checkboxPanel, gbc); // Êý¾ÝÏÔÊ¾ÇøÓò gbc.gridy++; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; txtDataView = new JTextArea(); txtDataView.setFont(new Font("Monospaced", Font.PLAIN, 14)); txtDataView.setEditable(false); scrollPane = new JScrollPane(txtDataView); scrollPane.setPreferredSize(new Dimension(800, 400)); scrollPane.setBorder(BorderFactory.createTitledBorder( BorderFactory.createLineBorder(new Color(180, 180, 220)), messages.getString("MESSAGE_VIEW_DATA_PANEL"), TitledBorder.LEFT, TitledBorder.TOP, new Font("΢ÈíÑźÚ", Font.BOLD, 12), new Color(70, 130, 180) )); add(scrollPane, gbc); // °´Å¥Ãæ°åÇøÓò gbc.gridy++; gbc.weighty = 0; gbc.fill = GridBagConstraints.HORIZONTAL; JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5)); buttonPanel.setBackground(new Color(240, 245, 249)); btnStart = createStyledButton(messages.getString("MESSAGE_VIEW_START"), new Color(70, 130, 180)); btnPause = createStyledButton(messages.getString("MESSAGE_VIEW_PAUSE"), new Color(218, 165, 32)); btnClear = createStyledButton(messages.getString("MESSAGE_VIEW_CLEAR"), new Color(205, 92, 92)); txtSendData = new JTextField(30); txtSendData.setFont(new Font("΢ÈíÑźÚ", Font.PLAIN, 12)); btnSend = createStyledButton(messages.getString("MESSAGE_VIEW_SEND"), new Color(60, 179, 113)); JPanel sendOptionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); sendOptionsPanel.setBackground(new Color(240, 245, 249)); ButtonGroup sendFormatGroup = new ButtonGroup(); rdoSendHex = createStyledRadioButton(messages.getString("MESSAGE_VIEW_SEND_HEX")); rdoSendAscii = createStyledRadioButton(messages.getString("MESSAGE_VIEW_SEND_ASCII")); sendFormatGroup.add(rdoSendHex); sendFormatGroup.add(rdoSendAscii); rdoSendAscii.setSelected(true); chkAppendNewline = createStyledCheckbox(messages.getString("MESSAGE_VIEW_APPEND_NEWLINE")); sendOptionsPanel.add(rdoSendHex); sendOptionsPanel.add(rdoSendAscii); sendOptionsPanel.add(chkAppendNewline); buttonPanel.add(btnStart); buttonPanel.add(btnPause); buttonPanel.add(btnClear); buttonPanel.add(txtSendData); buttonPanel.add(btnSend); buttonPanel.add(sendOptionsPanel); add(buttonPanel, gbc); setupActions(); } private JLabel createLabel(String text) { JLabel label = new JLabel(text); label.setFont(new Font("΢ÈíÑźÚ", Font.BOLD, 12)); label.setForeground(new Color(70, 70, 70)); return label; } private JButton createStyledButton(String text, Color bgColor) { JButton button = new JButton(text); button.setFont(new Font("΢ÈíÑźÚ", Font.BOLD, 12)); button.setBackground(bgColor); button.setForeground(Color.WHITE); button.setFocusPainted(false); button.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(bgColor.darker(), 1), BorderFactory.createEmptyBorder(5, 15, 5, 15) )); return button; } private JCheckBox createStyledCheckbox(String text) { JCheckBox checkBox = new JCheckBox(text); checkBox.setFont(new Font("΢ÈíÑźÚ", Font.PLAIN, 12)); checkBox.setBackground(new Color(240, 245, 249)); checkBox.setForeground(new Color(70, 70, 70)); return checkBox; } private JRadioButton createStyledRadioButton(String text) { JRadioButton radioButton = new JRadioButton(text); radioButton.setFont(new Font("΢ÈíÑźÚ", Font.PLAIN, 12)); radioButton.setBackground(new Color(240, 245, 249)); radioButton.setForeground(new Color(70, 70, 70)); radioButton.setIcon(new RadioButtonIcon(false)); radioButton.setSelectedIcon(new RadioButtonIcon(true)); radioButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { radioButton.setForeground(new Color(30, 144, 255)); } public void mouseExited(java.awt.event.MouseEvent evt) { radioButton.setForeground(new Color(70, 70, 70)); } }); return radioButton; } private static class RadioButtonIcon implements Icon { private static final int SIZE = 14; private final boolean selected; public RadioButtonIcon(boolean selected) { this.selected = selected; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (selected) { g2d.setColor(new Color(70, 130, 180)); g2d.fillOval(x, y, SIZE, SIZE); g2d.setColor(Color.WHITE); g2d.fillOval(x + SIZE/4, y + SIZE/4, SIZE/2, SIZE/2); } else { g2d.setColor(new Color(150, 150, 150)); g2d.drawOval(x, y, SIZE-1, SIZE-1); } g2d.dispose(); } @Override public int getIconWidth() { return SIZE; } @Override public int getIconHeight() { return SIZE; } } private void loadtyps() { cbDataType.removeAllItems(); cbDataType.addItem("UDPA"); cbDataType.addItem("UDPB"); cbDataType.addItem("TCP"); } private void setupActions() { btnStart.addActionListener(e -> startCapture()); btnPause.addActionListener(e -> pauseCapture()); btnClear.addActionListener(e -> clearDisplay()); btnSend.addActionListener(e -> sendData()); } private void startCapture() { if (!isCapturing) { isStarted = true; // ÉèÖÿªÊ¼±êÖ¾ isCapturing = true; btnStart.setEnabled(false); btnPause.setEnabled(true); } } private void pauseCapture() { isStarted = false; // Çå³ý¿ªÊ¼±êÖ¾ isCapturing = false; btnStart.setEnabled(true); btnPause.setEnabled(false); } private void clearDisplay() { txtDataView.setText(""); } private void sendData() { ResourceBundle currentMessages = Languages.getCurrentMessages(); String selectedDevice = (String) cbRemoteDevice.getSelectedItem(); if (selectedDevice == null || selectedDevice.equals(currentMessages.getString("MESSAGE_VIEW_ALL_DEVICES"))) { JOptionPane.showMessageDialog(this, currentMessages.getString("MESSAGE_VIEW_SELECT_DEVICE"), currentMessages.getString("WARNING"), JOptionPane.WARNING_MESSAGE); return; } Integer localPort = remoteDeviceLocalPortMap.get(selectedDevice); if (localPort == null) { JOptionPane.showMessageDialog(this, "ÎÞ·¨È·¶¨É豸µÄ½ÓÊÕ¶Ë¿Ú", currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } String[] parts = selectedDevice.split(":"); if (parts.length != 2) { JOptionPane.showMessageDialog(this, currentMessages.getString("MESSAGE_VIEW_INVALID_DEVICE"), currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } String ip = parts[0]; int port; try { port = Integer.parseInt(parts[1]); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(this, currentMessages.getString("MESSAGE_VIEW_INVALID_PORT"), currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } String dataToSend = txtSendData.getText(); if (dataToSend.isEmpty()) { JOptionPane.showMessageDialog(this, currentMessages.getString("MESSAGE_VIEW_EMPTY_DATA"), currentMessages.getString("WARNING"), JOptionPane.WARNING_MESSAGE); return; } if (chkAppendNewline.isSelected()) { dataToSend += "\r\n"; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String timestamp = sdf.format(new Date()); StringBuilder displayData = new StringBuilder(); displayData.append("[SEND][").append(timestamp).append("][").append(ip).append(":").append(port).append("] "); if (rdoSendHex.isSelected()) { String hexData = toHexString(dataToSend); displayData.append(hexData); if (localPort == UDPPortAReceiver.PORT) { UDPPortAReceiver.sendData(ip, port, dataToSend, true); } else if (localPort == UDPPortBReceiver.PORT) { UDPPortBReceiver.sendData(ip, port, dataToSend, true); } } else { displayData.append(dataToSend); if (localPort == UDPPortAReceiver.PORT) { UDPPortAReceiver.sendData(ip, port, dataToSend, false); } else if (localPort == UDPPortBReceiver.PORT) { UDPPortBReceiver.sendData(ip, port, dataToSend, false); } } SwingUtilities.invokeLater(() -> { txtDataView.append(displayData.toString() + "\n"); txtDataView.setCaretPosition(txtDataView.getDocument().getLength()); }); } public static void addRemoteDevice(String ip, int port, int localPort) { String device = ip + ":" + port; if (!remoteDeviceLocalPortMap.containsKey(device)) { remoteDeviceLocalPortMap.put(device, localPort); SwingUtilities.invokeLater(() -> { boolean exists = false; ComboBoxModel model = cbRemoteDevice.getModel(); for (int i = 0; i < model.getSize(); i++) { if (device.equals(model.getElementAt(i))) { exists = true; break; } } if (!exists) { cbRemoteDevice.addItem(device); } }); } } public static void showData(String rawData, String ip, int port, int localPort, String DataType, String Protocol, String Id) { // Ë«ÖØ¼ì²é£º´°¿Ú¿É¼ûÇÒÒѵã»÷¿ªÊ¼°´Å¥ if (!isWindowVisible || !isStarted) { return; } if (cbDataType == null || cbProtocol == null || cbDeviceId == null) { return; } String selectedDataType = (String) cbDataType.getSelectedItem(); String selectedProtocol = (String) cbProtocol.getSelectedItem(); String selectedDeviceId = (String) cbDeviceId.getSelectedItem(); boolean DataTypeboolean = "ALL".equals(selectedDataType) || selectedDataType.equals(DataType); boolean Protocolboolean = "ALL".equals(selectedProtocol) || selectedProtocol.equals(Protocol); boolean DeviceIdboolean = "ALL".equals(selectedDeviceId) || selectedDeviceId.equals(Id); if (DataTypeboolean && Protocolboolean && DeviceIdboolean) { StringBuilder sb = SB.get(); sb.setLength(0); if (chkShowSource.isSelected()) { sb.append(PREFIX); formatTime(sb); sb.append(',').append(ip).append(COLON).append(port).append(SUFFIX); } sb.append(rawData); final String finalText = sb.toString(); SwingUtilities.invokeLater(() -> { txtDataView.append(finalText); txtDataView.append("\n"); txtDataView.setCaretPosition(txtDataView.getDocument().getLength()); }); if (isCapturing && localPort != 0) { addRemoteDevice(ip, port, localPort); } if (chkAutoSave.isSelected()) { saveToFile(finalText); } } } private void loadDeviceIds() { cbDeviceId.removeAllItems(); cbDeviceId.addItem("ALL"); List tags = Dell_tag.getAlldeviceIds(); for (String tag : tags) { cbDeviceId.addItem(tag); } } private static String toHexString(String input) { StringBuilder hex = new StringBuilder(); for (char c : input.toCharArray()) { hex.append(String.format("%02X ", (int) c)); } return hex.toString().trim(); } private static void saveToFile(String data) { SimpleDateFormat fileFormat = new SimpleDateFormat("yyyyMMdd"); String fileName = "systemfile/baowen/messages_" + fileFormat.format(new Date()) + ".txt"; try (java.io.FileWriter writer = new java.io.FileWriter(fileName, true)) { writer.write(data + "\n"); } catch (java.io.IOException ex) { ex.printStackTrace(); } } public static String getSelectedDataType() { return cbDataType == null ? "" : String.valueOf(cbDataType.getSelectedItem()); } public static String getSelectedProtocol() { return cbProtocol == null ? "" : String.valueOf(cbProtocol.getSelectedItem()); } public static String getSelectedDeviceId() { return cbDeviceId == null ? "" : String.valueOf(cbDeviceId.getSelectedItem()); } private static void formatTime(StringBuilder sb) { long now = System.currentTimeMillis(); long sec = (now / 1000) % 86400; int ms = (int) (now % 1000); int h = (int) (sec / 3600); int m = (int) ((sec % 3600) / 60); int s = (int) (sec % 60); sb.append((char) ('0' + (h / 10))) .append((char) ('0' + (h % 10))).append(':'); sb.append((char) ('0' + (m / 10))) .append((char) ('0' + (m % 10))).append(':'); sb.append((char) ('0' + (s / 10))) .append((char) ('0' + (s % 10))).append('.'); sb.append(DIGITS[ms / 100]) .append(DIGITS[(ms / 10) % 10]) .append(DIGITS[ms % 10]); } }