zsh_root
2025-12-10 8d662de2fd262b3a485f16e197cb4d0ca2a61cdf
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
package home;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
 
public class ExtensionPanel extends JDialog {
    private static final long serialVersionUID = 1L;
    private MainFrame mainFrame;
    private JPanel commandPanel;
    private JScrollPane scrollPane;
    private JButton saveButton;
    private File commandFile;
    
    public ExtensionPanel(MainFrame parent) {
        super(parent, getString(parent, "extension"), false); // 设置为非模态对话框
        this.mainFrame = parent;
        initializeUI();
        loadCommands();
    }
    
    private void initializeUI() {
        setSize(800, 500); // 修改默认打开窗口为800*500
        setLocationRelativeTo(mainFrame);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        setLayout(new BorderLayout());
        
        // 创建命令面板
        commandPanel = new JPanel();
        commandPanel.setLayout(new BoxLayout(commandPanel, BoxLayout.Y_AXIS));
        
        scrollPane = new JScrollPane(commandPanel);
        scrollPane.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), 
            getString(mainFrame, "common.commands"), 
            TitledBorder.LEFT, 
            TitledBorder.TOP
        ));
        
        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        
        // 使用ButtonUtils创建样式按钮
        saveButton = ButtonUtils.createBlueButton(getString(mainFrame, "save.common.commands"), 25);
        saveButton.setPreferredSize(new Dimension(120, 25));
        
        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                saveCommands();
            }
        });
        
        buttonPanel.add(saveButton);
        
        add(scrollPane, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);
        
        // 初始化指令文件
        String rootPath = System.getProperty("user.dir");
        File systemFileDir = new File(rootPath + File.separator + "systemfile");
        if (!systemFileDir.exists()) {
            systemFileDir.mkdirs();
        }
        commandFile = new File(systemFileDir, "zhiling.txt");
    }
    
    private void loadCommands() {
        commandPanel.removeAll(); // 清空面板
        
        if (commandFile.exists()) {
            try (BufferedReader reader = new BufferedReader(new FileReader(commandFile))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    if (!line.trim().isEmpty()) {
                        // 每行格式:是否HEX:指令内容
                        String[] parts = line.split(":", 2);
                        boolean isHex = false;
                        String command = "";
                        
                        if (parts.length == 2) {
                            isHex = Boolean.parseBoolean(parts[0]);
                            command = parts[1];
                        } else {
                            command = line;
                        }
                        
                        addCommandRow(isHex, command);
                    }
                }
            } catch (IOException e) {
                JOptionPane.showMessageDialog(this, 
                    getString(mainFrame, "load.commands.failed") + e.getMessage(), 
                    getString(mainFrame, "error"), 
                    JOptionPane.ERROR_MESSAGE);
            }
        }
        
        // 添加一个空行用于新增命令
        addCommandRow(false, "");
        
        commandPanel.revalidate();
        commandPanel.repaint();
    }
    
    private void addCommandRow(boolean isHex, String command) {
        JPanel rowPanel = new JPanel();
        rowPanel.setLayout(new BoxLayout(rowPanel, BoxLayout.X_AXIS));
        rowPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // 设置行间距
        
        // HEX复选框
        JCheckBox hexCheckBox = new JCheckBox(getString(mainFrame, "hex.send"));
        hexCheckBox.setSelected(isHex);
        hexCheckBox.setAlignmentY(Component.CENTER_ALIGNMENT);
        
        // 命令文本框
        JTextField commandField = new JTextField(command);
        commandField.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30)); // 限制高度,宽度自适应
        
        // 发送按钮
        JButton sendButton = createSendButton();
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                sendCommand(hexCheckBox.isSelected(), commandField.getText());
            }
        });
        
        // 添加组件到行面板
        rowPanel.add(hexCheckBox);
        rowPanel.add(Box.createHorizontalStrut(5)); // HEX复选框与文本框间隔5像素
        rowPanel.add(commandField);
        rowPanel.add(Box.createHorizontalStrut(10)); // 文本框与按钮间隔10像素
        rowPanel.add(sendButton);
        
        commandPanel.add(rowPanel);
    }
    
    private JButton createSendButton() {
        JButton button = new JButton(getString(mainFrame, "send"));
        
        // 设置按钮大小为60×20(宽×高)
        button.setPreferredSize(new Dimension(80, 20));
        button.setMinimumSize(new Dimension(80, 20));
        button.setMaximumSize(new Dimension(80, 20));
        
        // 设置按钮样式
        button.setBackground(new Color(0, 120, 215));
        button.setForeground(Color.WHITE);
        button.setFocusPainted(false);
        button.setBorderPainted(false);
        button.setFont(button.getFont().deriveFont(Font.BOLD, 12f));
        
        // 添加鼠标交互效果
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                button.setBackground(new Color(0, 150, 255)); // 悬停时变亮
                button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            }
            
            public void mouseExited(java.awt.event.MouseEvent evt) {
                button.setBackground(new Color(0, 120, 215)); // 恢复正常颜色
                button.setCursor(Cursor.getDefaultCursor());
            }
            
            public void mousePressed(java.awt.event.MouseEvent evt) {
                // 点击效果 - 颜色变深并有轻微缩小效果
                button.setBackground(new Color(0, 80, 160));
                button.setBounds(button.getX() + 1, button.getY() + 1, 58, 18);
            }
            
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                // 恢复原状
                button.setBackground(new Color(0, 150, 255));
                button.setBounds(button.getX() - 1, button.getY() - 1, 60, 20);
            }
        });
        
        return button;
    }
    
    private void saveCommands() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(commandFile))) {
            Component[] components = commandPanel.getComponents();
            for (Component comp : components) {
                if (comp instanceof JPanel) {
                    JPanel rowPanel = (JPanel) comp;
                    Component[] rowComponents = rowPanel.getComponents();
                    
                    boolean isHex = false;
                    String command = "";
                    
                    for (Component rowComp : rowComponents) {
                        if (rowComp instanceof JCheckBox) {
                            isHex = ((JCheckBox) rowComp).isSelected();
                        } else if (rowComp instanceof JTextField) {
                            command = ((JTextField) rowComp).getText().trim();
                        }
                    }
                    
                    if (!command.isEmpty()) {
                        writer.write(isHex + ":" + command);
                        writer.newLine();
                    }
                }
            }
            JOptionPane.showMessageDialog(this, 
                getString(mainFrame, "save.commands.success"), 
                getString(mainFrame, "prompt"), 
                JOptionPane.INFORMATION_MESSAGE);
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, 
                getString(mainFrame, "save.commands.failed") + e.getMessage(), 
                getString(mainFrame, "error"), 
                JOptionPane.ERROR_MESSAGE);
        }
    }
    
    private void sendCommand(boolean isHex, String command) {
        if (command == null || command.trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, 
                getString(mainFrame, "command.cannot.empty"), 
                getString(mainFrame, "error"), 
                JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        // 获取当前时间
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentTime = dateFormat.format(new Date());
        
        // 构建日志信息
        StringBuilder logMessage = new StringBuilder();
        logMessage.append("[").append(currentTime).append("] ");
        logMessage.append(getString(mainFrame, "send")).append(": ");
        
        // 根据HEX发送选项格式化内容
        if (isHex) {
            logMessage.append("HEX ");
            logMessage.append(command);
        } else {
            logMessage.append("ASCII ");
            logMessage.append(command);
        }
        
        logMessage.append(" [").append(getString(mainFrame, "extension.command")).append("]");
        logMessage.append("\n");
        
        // 将发送信息添加到数据日志面板
        addLogToDataLogPanel(logMessage.toString());
        
        // 调用主框架的发送方法
        if (mainFrame != null) {
            mainFrame.sendDataFromExtension(command, isHex);
        }
    }
    
    /**
     * 将日志信息添加到数据日志面板
     * @param logMessage 日志信息
     */
    private void addLogToDataLogPanel(String logMessage) {
        try {
            // 通过主框架获取DataLogPanel实例
            if (mainFrame != null) {
                // 直接调用MainFrame的日志添加方法,避免使用反射
                mainFrame.addToDataLog(logMessage);
            }
        } catch (Exception ex) {
            // 备用方案:尝试使用反射
            try {
                DataLogPanel dataLogPanel = mainFrame.getDataLogPanel();
                if (dataLogPanel != null) {
                    java.lang.reflect.Field logAreaField = DataLogPanel.class.getDeclaredField("logArea");
                    logAreaField.setAccessible(true);
                    JTextArea logArea = (JTextArea) logAreaField.get(dataLogPanel);
                    
                    if (logArea != null) {
                        logArea.append(logMessage);
                        // 自动滚动到最后
                        logArea.setCaretPosition(logArea.getDocument().getLength());
                    }
                }
            } catch (Exception e) {
                System.err.println("无法访问数据日志区域: " + e.getMessage());
                // 显示错误信息
                JOptionPane.showMessageDialog(this,
                    getString(mainFrame, "cannot.display.in.data.log") + ": " + e.getMessage(),
                    getString(mainFrame, "error"),
                    JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    
    private static String getString(MainFrame mainFrame, String key) {
        return mainFrame != null ? mainFrame.getString(key) : key;
    }
}