package demo1;
import com.fazecast.jSerialComm.SerialPort;
import static demo1.ModbusRequestBuilder.buildReadRequest;
import static demo1.ModbusRequestBuilder.buildWriteRequest;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TemperatureController {
private final TemperatureMonitorGUI gui;
private final String portName;
private final int baudRate;
private final int dateBit;
private final int stopBits;
private final int parity;
private SerialPort serialPort;
private volatile boolean running = false;
private final BlockingQueue<SerialRequest> requestQueue = new LinkedBlockingQueue<>();
private ScheduledExecutorService queueExecutor;
public final TemperatureProfileManager profileManager;
public TemperatureController(TemperatureMonitorGUI gui, String portName, int baudRate, int dateBit, int stopBits, int parity) {
this.gui = gui;
this.portName = portName;
this.baudRate = baudRate;
this.dateBit = dateBit;
this.stopBits = stopBits;
this.parity = parity;
this.profileManager = new TemperatureProfileManager(this);
}
public void start() {
new Thread(this::connectSerialPort).start();
}
public void stop() {
running = false;
if (queueExecutor != null) {
queueExecutor.shutdownNow();
}
if (serialPort != null && serialPort.isOpen()) {
serialPort.closePort();
}
}
private void connectSerialPort() {
serialPort = SerialPort.getCommPort(portName);
serialPort.setComPortParameters(baudRate, 8, stopBits, parity);
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1000, 0);
if (serialPort.openPort()) {
System.out.println("✅ 成功打开串口");
gui.setStatus("已连接到 " + portName);
serialPort.addDataListener(new SerialPortDataListenerImpl(serialPort, gui, this));
running = true;
startQueueConsumer();
startTemperaturePolling();
} else {
System.err.println("❌ 无法打开串口");
gui.setStatus("无法打开串口:" + portName);
}
}
private void startQueueConsumer() {
queueExecutor = new ScheduledThreadPoolExecutor(1);
queueExecutor.submit(() -> {
while (!Thread.interrupted() && running) {
try {
SerialRequest request = requestQueue.take();
sendRequest(request.data);
if (request.isManual) {
Thread.sleep(500);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
});
}
private void startTemperaturePolling() {
queueExecutor.scheduleAtFixedRate(() -> {
enqueueRequest(buildReadRequest((byte) 0x01, RegisterAddress.TEMP_MEASURED), false);
}, 0, 1, TimeUnit.SECONDS);
}
public void readRegister(byte slaveId, int registerAddr) {
enqueueRequest(buildReadRequest(slaveId, registerAddr), true);
}
public void writeRegister(byte slaveId, int registerAddr, int value) {
enqueueRequest(buildWriteRequest(slaveId, registerAddr, value), true);
}
private void enqueueRequest(byte[] data, boolean isManual) {
requestQueue.offer(new SerialRequest(data, isManual));
}
public void sendRequest(byte[] data) {
if (serialPort == null || !serialPort.isOpen()) {
System.err.println("串口未打开,无法发送数据");
return;
}
byte[] crc = ModbusRequestBuilder.calculateCRC(data);
byte[] fullRequest = new byte[data.length + 2];
System.arraycopy(data, 0, fullRequest, 0, data.length);
fullRequest[data.length] = crc[0]; // CRC低字节
fullRequest[data.length + 1] = crc[1]; // CRC高字节
serialPort.writeBytes(fullRequest, fullRequest.length);
System.out.println("发送请求: " + ModbusRequestBuilder.bytesToHex(fullRequest));
}
public void updateTemperature(double temperature) {
gui.updateTemperature(temperature);
}
public void updateSetTemperature(double temperature) {
gui.updateSetTemperature(temperature);
}
public void readActualTemperature(byte slaveId) {
enqueueRequest(buildReadRequest(slaveId, RegisterAddress.TEMP_MEASURED), true);
}
public void readSetTemperature(byte slaveId) {
enqueueRequest(buildReadRequest(slaveId, RegisterAddress.TEMP_SETPOINT), true);
}
public void setTargetTemperature(byte slaveId, float temp) {
int value = (int)(temp * 10);
enqueueRequest(buildWriteRequest(slaveId, RegisterAddress.TEMP_SETPOINT, value), true);
}
public void setConstantTemperature(float temp) {
byte slaveId = 0x01;
int value = (int)(temp * 10);
enqueueRequest(buildWriteRequest(slaveId, RegisterAddress.TEMP_SETPOINT, value), true);
}
public void stopControl() {
profileManager.stop();
}
/**
* 启动温控逻辑(定值模式)
*/
public void startControl(float targetTemp, int transitionTime) {
if (serialPort == null || !serialPort.isOpen()) return;
int registerValue = (int)(targetTemp * 10);
byte[] request = buildWriteRequest((byte) 0x01, RegisterAddress.TEMP_SETPOINT, registerValue);
sendRequest(request);
System.out.println("开始升温,目标温度:" + targetTemp + "°C,保持时间:" + transitionTime + "秒");
}
}
package demo1;
import com.fazecast.jSerialComm.SerialPort;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class TemperatureMonitorGUI extends JFrame {
private JLabel temperatureLabel;
private JLabel statusLabel;
private JButton connectButton;
private JButton readButton;
private JButton startControlButton;
private JButton refreshPortButton;
private JComboBox<String> portComboBox;
private JComboBox<String> baudRateComboBox;
private JComboBox<String> dateBitComboBox;
private JComboBox<String> stopBitsComboBox;
private JComboBox<String> parityComboBox;
private JComboBox<String> modeComboBox;
private TemperatureController controller;
// 输入组件
private JTextField waitTimeField;
private JLabel setTemperatureLabel;
private JTextField transitionTimeField;
private JTextField constantTempField;
private Map<String, Component> modeComponents = new HashMap<>();
// 曲线模式字段
private JTextField[] curveTempFields = new JTextField[3];
private JTextField[] curveDurationFields = new JTextField[3];
private JTextField[] curveHoldFields = new JTextField[3];
private JTextField finalTempField;
private JTextField finalTransitionField;
// 阶段标签
private JLabel[] stageLabels = new JLabel[3]; // 新增字段:保存阶段标签
public TemperatureMonitorGUI() {
setTitle("MODBUS RTU 温控系统");
setSize(1100, 700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(new Color(240, 245, 250));
JPanel mainPanel = new JPanel(new BorderLayout(15, 15));
mainPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
add(mainPanel);
JPanel topPanel = createTopPanel();
mainPanel.add(topPanel, BorderLayout.NORTH);
JPanel centerPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(8, 8, 8, 8);
gbc.fill = GridBagConstraints.BOTH;
JPanel inputPanel = createInputPanel();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.3;
gbc.weighty = 1.0;
centerPanel.add(inputPanel, gbc);
JPanel buttonPanel = createButtonPanel();
gbc.gridx = 1;
gbc.weightx = 0.2;
centerPanel.add(buttonPanel, gbc);
JPanel rightPanel = createRightPanel();
gbc.gridx = 2;
gbc.weightx = 0.4;
centerPanel.add(rightPanel, gbc);
mainPanel.add(centerPanel, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
bottomPanel.setBorder(BorderFactory.createEtchedBorder());
bottomPanel.setBackground(new Color(230, 240, 255));
statusLabel = new JLabel("状态: 未连接");
bottomPanel.add(statusLabel);
mainPanel.add(bottomPanel, BorderLayout.SOUTH);
}
private JPanel createTopPanel() {
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
topPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 15, 0));
topPanel.setBackground(new Color(70, 130, 180));
temperatureLabel = new JLabel("当前温度: -- °C");
setTemperatureLabel = new JLabel("当前设定温度: -- °C");
temperatureLabel.setFont(new Font("微软雅黑", Font.BOLD, 28));
temperatureLabel.setForeground(Color.WHITE);
setTemperatureLabel.setFont(new Font("微软雅黑", Font.BOLD, 28));
setTemperatureLabel.setForeground(Color.WHITE);
topPanel.add(temperatureLabel);
topPanel.add(Box.createRigidArea(new Dimension(30, 0)));
topPanel.add(setTemperatureLabel);
return topPanel;
}
private JPanel createInputPanel() {
JPanel inputPanel = new JPanel(new GridBagLayout());
inputPanel.setBorder(BorderFactory.createTitledBorder("通信配置"));
inputPanel.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
int row = 0;
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("串口:"), gbc);
gbc.gridx = 1;
JPanel portPanel = new JPanel(new BorderLayout(5, 0));
portComboBox = new JComboBox<>();
portComboBox.setPreferredSize(new Dimension(180, 25));
refreshPortList();
portPanel.add(portComboBox, BorderLayout.CENTER);
refreshPortButton = new JButton("刷新");
refreshPortButton.addActionListener(e -> refreshPortList());
portPanel.add(refreshPortButton, BorderLayout.EAST);
inputPanel.add(portPanel, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("波特率:"), gbc);
gbc.gridx = 1;
baudRateComboBox = new JComboBox<>(new String[]{"1200", "2400", "4800", "9600","19200"});
baudRateComboBox.setSelectedItem("9600"); // 默认选中 9600
inputPanel.add(baudRateComboBox, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("数据位"), gbc);
gbc.gridx = 1;
dateBitComboBox = new JComboBox<>(new String[]{"6", "7", "8"});
dateBitComboBox.setSelectedItem("8"); // 默认选中 8
inputPanel.add(dateBitComboBox, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("停止位:"), gbc);
gbc.gridx = 1;
stopBitsComboBox = new JComboBox<>(new String[]{"1", "1.5", "2"});
stopBitsComboBox.setSelectedIndex(0);
inputPanel.add(stopBitsComboBox, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("校验方式:"), gbc);
gbc.gridx = 1;
parityComboBox = new JComboBox<>(new String[]{"None", "Even", "Odd"});
parityComboBox.setSelectedIndex(0);
inputPanel.add(parityComboBox, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
gbc.gridwidth = 2;
inputPanel.add(new JSeparator(), gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("初始温度 (℃):"), gbc);
gbc.gridx = 1;
JTextField initialTempField = new JTextField("25.5", 10); // 新增输入框
inputPanel.add(initialTempField, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("等待时间 (秒):"), gbc);
gbc.gridx = 1;
JTextField waitTimeField = new JTextField("60", 10);
inputPanel.add(waitTimeField, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
gbc.gridwidth = 2;
inputPanel.add(new JSeparator(), gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("模式选择:"), gbc);
gbc.gridx = 1;
modeComboBox = new JComboBox<>(new String[]{"定值模式", "曲线模式"});
modeComboBox.setSelectedIndex(0);
inputPanel.add(modeComboBox, gbc);
gbc.gridx = 0;
gbc.gridy = row++;
inputPanel.add(new JLabel("启动控制:"), gbc);
gbc.gridx = 1;
startControlButton = new JButton("启动");
startControlButton.setPreferredSize(new Dimension(100, 30));
startControlButton.setBackground(new Color(50, 150, 50));
startControlButton.setForeground(Color.WHITE);
startControlButton.addActionListener(this::startControl);
inputPanel.add(startControlButton, gbc);
return inputPanel;
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel(new GridBagLayout());
buttonPanel.setBorder(BorderFactory.createTitledBorder("操作"));
buttonPanel.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(15, 10, 15, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
connectButton = new JButton("连接串口");
connectButton.setPreferredSize(new Dimension(150, 40));
connectButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
connectButton.setBackground(new Color(70, 130, 180));
connectButton.setForeground(Color.WHITE);
connectButton.addActionListener(this::connectSerialPort);
gbc.gridy = 0;
buttonPanel.add(connectButton, gbc);
readButton = new JButton("读取温度");
readButton.setPreferredSize(new Dimension(150, 40));
readButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
readButton.setBackground(new Color(60, 179, 113));
readButton.setForeground(Color.WHITE);
readButton.addActionListener(this::readTemperature);
gbc.gridy = 1;
buttonPanel.add(readButton, gbc);
return buttonPanel;
}
private JPanel createRightPanel() {
JPanel rightPanel = new JPanel(new BorderLayout());
rightPanel.setBorder(BorderFactory.createTitledBorder("模式配置"));
rightPanel.setBackground(Color.WHITE);
JPanel constantModePanel = createConstantModePanel();
modeComponents.put("定值模式", constantModePanel);
JPanel curveModePanel = createCurveModePanel();
modeComponents.put("曲线模式", curveModePanel);
rightPanel.add(modeComponents.get("定值模式"), BorderLayout.CENTER);
modeComboBox.addActionListener(e -> {
String selectedMode = (String) modeComboBox.getSelectedItem();
rightPanel.removeAll();
rightPanel.add(modeComponents.get(selectedMode), BorderLayout.CENTER);
rightPanel.revalidate();
rightPanel.repaint();
});
return rightPanel;
}
private JPanel createConstantModePanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBackground(Color.WHITE);
panel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(new JLabel("目标温度 (°C):"), gbc);
gbc.gridx = 1;
constantTempField = new JTextField(10);
constantTempField.setText("25.5");
panel.add(constantTempField, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
JLabel infoLabel = new JLabel("<html><div style='width:250px;'>定值模式将温度稳定在设定值</div></html>");
infoLabel.setForeground(new Color(100, 100, 100));
panel.add(infoLabel, gbc);
return panel;
}
private JPanel createCurveModePanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBackground(Color.WHITE);
panel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
panel.add(new JLabel("阶段"), gbc);
gbc.gridx = 1;
panel.add(new JLabel("目标温度 (°C)"), gbc);
gbc.gridx = 2;
panel.add(new JLabel("等待时间 (秒)"), gbc);
gbc.gridx = 3;
panel.add(new JLabel("保持时间 (秒)"), gbc);
for (int i = 0; i < 3; i++) {
gbc.gridx = 0;
gbc.gridy = i + 1;
gbc.anchor = GridBagConstraints.WEST;
JLabel stageLabel = new JLabel("阶段 " + (i + 1) + ":");
stageLabels[i] = stageLabel; // 保存引用
panel.add(stageLabel, gbc);
gbc.gridx = 1;
curveTempFields[i] = new JTextField("0.0");
curveTempFields[i].setColumns(8);
panel.add(curveTempFields[i], gbc);
gbc.gridx = 2;
curveDurationFields[i] = new JTextField("30");
curveDurationFields[i].setColumns(8);
panel.add(curveDurationFields[i], gbc);
gbc.gridx = 3;
curveHoldFields[i] = new JTextField("60");
curveHoldFields[i].setColumns(8);
panel.add(curveHoldFields[i], gbc);
if (i > 0) {
stageLabel.setVisible(false);
curveTempFields[i].setVisible(false);
curveDurationFields[i].setVisible(false);
curveHoldFields[i].setVisible(false);
}
}
gbc.gridy = 4;
gbc.gridx = 0;
gbc.gridwidth = 4;
gbc.anchor = GridBagConstraints.CENTER;
JPanel controlButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0));
JButton addStageButton = new JButton("+");
JButton removeStageButton = new JButton("-");
controlButtonPanel.add(addStageButton);
controlButtonPanel.add(removeStageButton);
panel.add(controlButtonPanel, gbc);
gbc.gridy = 5;
gbc.gridx = 0;
gbc.gridwidth = 1;
gbc.anchor = GridBagConstraints.WEST;
panel.add(new JLabel("最终目标:"), gbc);
gbc.gridx = 1;
finalTempField = new JTextField("30.0", 8);
panel.add(finalTempField, gbc);
gbc.gridx = 2;
finalTransitionField = new JTextField("30", 8);
panel.add(finalTransitionField, gbc);
gbc.gridy = 6;
gbc.gridx = 0;
gbc.gridwidth = 4;
gbc.anchor = GridBagConstraints.WEST;
JLabel infoLabel = new JLabel("<html><div style='width:350px;'>点击 '+' 增加阶段,'-' 减少阶段。未填写的阶段将被跳过</div></html>");
infoLabel.setForeground(new Color(100, 100, 100));
panel.add(infoLabel, gbc);
final int[] maxVisibleStages = {1};
addStageButton.addActionListener(e -> {
if (maxVisibleStages[0] < 3) {
maxVisibleStages[0]++;
for (int i = 0; i < 3; i++) {
boolean visible = i < maxVisibleStages[0];
stageLabels[i].setVisible(visible); // 使用引用设置可见性
curveTempFields[i].setVisible(visible);
curveDurationFields[i].setVisible(visible);
curveHoldFields[i].setVisible(visible);
}
panel.revalidate();
panel.repaint();
}
});
removeStageButton.addActionListener(e -> {
if (maxVisibleStages[0] > 1) {
maxVisibleStages[0]--;
for (int i = 0; i < 3; i++) {
boolean visible = i < maxVisibleStages[0];
stageLabels[i].setVisible(visible);
curveTempFields[i].setVisible(visible);
curveDurationFields[i].setVisible(visible);
curveHoldFields[i].setVisible(visible);
}
panel.revalidate();
panel.repaint();
}
});
return panel;
}
private void connectSerialPort(ActionEvent e) {
String selectedPort = (String) portComboBox.getSelectedItem();
if (selectedPort != null && controller == null) {
int baudRate = Integer.parseInt((String) baudRateComboBox.getSelectedItem());
int dateBit = Integer.parseInt((String) dateBitComboBox.getSelectedItem());
int stopBits = getStopBitsValue();
int parity = getParityValue();
controller = new TemperatureController(this, selectedPort, baudRate, dateBit, stopBits, parity);
controller.start();
connectButton.setText("断开连接");
connectButton.setBackground(new Color(246, 115, 115));
} else if (controller != null) {
controller.stop();
controller = null;
setStatus("已断开连接");
connectButton.setText("连接串口");
connectButton.setBackground(new Color(70, 130, 180));
}
}
private int getStopBitsValue() {
String stopBits = (String) stopBitsComboBox.getSelectedItem();
switch (stopBits) {
case "1": return SerialPort.ONE_STOP_BIT;
case "1.5": return SerialPort.ONE_POINT_FIVE_STOP_BITS;
case "2": return SerialPort.TWO_STOP_BITS;
default: return SerialPort.ONE_STOP_BIT;
}
}
private int getParityValue() {
String parity = (String) parityComboBox.getSelectedItem();
switch (parity) {
case "None": return SerialPort.NO_PARITY;
case "Even": return SerialPort.EVEN_PARITY;
case "Odd": return SerialPort.ODD_PARITY;
default: return SerialPort.NO_PARITY;
}
}
private void readTemperature(ActionEvent e) {
if (controller != null) {
try {
byte slaveId = 0x01;
controller.readActualTemperature(slaveId);
} catch (Exception ex) {
showError("读取温度时发生错误: " + ex.getMessage());
}
} else {
showError("请先连接串口");
}
}
private void queryCurrentTemperature(ActionEvent e) {
if (controller != null) {
try {
byte slaveId = 0x01;
controller.readActualTemperature(slaveId);
} catch (Exception ex) {
showError("查询当前温度时发生错误: " + ex.getMessage());
}
} else {
showError("请先连接串口");
}
}
private void querySetTemperature(ActionEvent e) {
if (controller != null) {
try {
byte slaveId = 0x01;
controller.readSetTemperature(slaveId);
} catch (Exception ex) {
showError("查询设定温度时发生错误: " + ex.getMessage());
}
} else {
showError("请先连接串口");
}
}
private void startControl(ActionEvent e) {
String selectedModeLabel = (String) modeComboBox.getSelectedItem();
ControlMode selectedMode = ControlMode.fromLabel(selectedModeLabel);
if (selectedMode == ControlMode.FIXED_VALUE_MODE) {
try {
float targetTemp = Float.parseFloat(constantTempField.getText());
controller.setConstantTemperature(targetTemp);
showInfo("定值模式启动: " + targetTemp + "°C");
} catch (NumberFormatException ex) {
showError("请输入有效的温度值");
}
} else if (selectedMode == ControlMode.CURVE_MODE) {
float[] temps = new float[4];
int[] durations = new int[4];
int[] holdTimes = new int[3];
int stageCount = 0;
for (int i = 0; i < 3; i++) {
try {
float temp = Float.parseFloat(curveTempFields[i].getText());
int duration = Integer.parseInt(curveDurationFields[i].getText());
int holdTime = Integer.parseInt(curveHoldFields[i].getText());
if (temp >= 0 && duration > 0 && holdTime >= 0) {
temps[stageCount] = temp;
durations[stageCount] = duration;
holdTimes[stageCount] = holdTime;
stageCount++;
}
} catch (NumberFormatException ignored) {}
}
try {
temps[stageCount] = Float.parseFloat(finalTempField.getText());
durations[stageCount] = Integer.parseInt(finalTransitionField.getText());
} catch (NumberFormatException ex) {
showError("请正确输入最终目标温度和保持时间");
return;
}
if (stageCount == 0) {
showError("至少需要一个有效阶段");
return;
}
controller.profileManager.startCurveControl(
Arrays.copyOf(temps, stageCount + 1),
Arrays.copyOf(durations, stageCount + 1),
Arrays.copyOf(holdTimes, stageCount)
);
showInfo("曲线模式启动: " + stageCount + "个阶段 + 最终目标");
}
}
public void refreshPortList() {
portComboBox.removeAllItems();
for (SerialPort port : SerialPort.getCommPorts()) {
portComboBox.addItem(port.getSystemPortName());
}
}
public void updateTemperature(double temperature) {
SwingUtilities.invokeLater(() -> {
temperatureLabel.setText(String.format("当前温度: %.1f°C", temperature));
if (temperature > 35) {
temperatureLabel.setForeground(new Color(220, 20, 60));
} else if (temperature < 10) {
temperatureLabel.setForeground(new Color(30, 144, 255));
} else {
temperatureLabel.setForeground(Color.WHITE);
}
});
}
public void updateSetTemperature(double temperature) {
SwingUtilities.invokeLater(() -> {
setTemperatureLabel.setText(String.format("当前设定温度: %.1f°C", temperature));
if (temperature > 35) {
setTemperatureLabel.setForeground(new Color(220, 20, 60));
} else if (temperature < 10) {
setTemperatureLabel.setForeground(new Color(30, 144, 255));
} else {
setTemperatureLabel.setForeground(Color.WHITE);
}
});
}
public void setStatus(String status) {
SwingUtilities.invokeLater(() ->
statusLabel.setText("状态: " + status)
);
}
private void showError(String message) {
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(this, message, "错误", JOptionPane.ERROR_MESSAGE)
);
}
private void showInfo(String message) {
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(this, message, "信息", JOptionPane.INFORMATION_MESSAGE)
);
}
}
为什么修改后,还是未被访问呢
最新发布