Java基础——解决JFrame.setBackground设置无效,mac系统IDEA编译器

本文详细介绍了在Java Swing中如何正确设置JFrame的背景颜色,包括两种有效的方法:一是使contentPane不可见并设置JFrame背景色;二是直接设置contentPane的背景色。文章通过实例代码展示了具体的实现步骤。

原理:

JFrame框架,一旦创建,在其中就已经包含一个内容面板。
一般我们在往JFrame中添加组件时,都加在了内容面板中,这个面板可以通过JFrame的成员方法getContentPane()取出来,所以如果设置JFrame的背景颜色,仍然会被内容面板盖住,不如设置内容面板的背景颜色,如果框架中还加有其他面板,内容面板的颜色也会被其他面板盖住,要注意一下面板的布局情况。

设置方法:

方法1:得到contentPane容器,设置为不可见;否则背景颜色被遮挡,setBackground()失效
jf.getContentPane().setVisible(false);
jf.setBackground(Color.BLACK);

方法2:直接设置contentPane容器,设置颜色
jf.getContentPane().setBackground(Color.BLACK);

例子:

    private void showUI() {
        JFrame jf = new JFrame();
        jf.setName("线程小球V1");
        jf.setSize(500,500);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(3);

        //方法1:得到contentPane容器,设置为不可见;否则背景颜色被遮挡,setBackground()失效
        jf.getContentPane().setVisible(false);
        jf.setBackground(Color.BLACK);
        
        //方法2:直接设置contentPane容器,设置颜色
        jf.getContentPane().setBackground(Color.BLACK);

        jf.setVisible(true);

    }

 

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> dateBiteComboBox; private JComboBox<String> stopBitsComboBox; private JComboBox<String> parityComboBox; private JComboBox<String> modeComboBox; private TemperatureController controller; // 输入组件 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; 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"); temperatureLabel.setFont(new Font("微软雅黑", Font.BOLD, 28)); temperatureLabel.setForeground(Color.WHITE); topPanel.add(temperatureLabel); 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.setSelectedIndex(0); inputPanel.add(baudRateComboBox, gbc); // 数据位 gbc.gridx = 0; gbc.gridy = row++; inputPanel.add(new JLabel("数据位"), gbc); gbc.gridx = 1; dateBiteComboBox = new JComboBox<>(new String[]{"6", "7", "8"}); dateBiteComboBox.setSelectedIndex(0); inputPanel.add(dateBiteComboBox, 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; JButton queryCurrentTempButton = new JButton("查询"); queryCurrentTempButton.setPreferredSize(new Dimension(80, 25)); queryCurrentTempButton.addActionListener(this::queryCurrentTemperature); inputPanel.add(queryCurrentTempButton, gbc); // 查询设定温度 gbc.gridx = 0; gbc.gridy = row++; inputPanel.add(new JLabel("设定温度:"), gbc); gbc.gridx = 1; JButton querySetTempButton = new JButton("查询"); querySetTempButton.setPreferredSize(new Dimension(80, 25)); querySetTempButton.addActionListener(this::querySetTemperature); inputPanel.add(querySetTempButton, 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; panel.add(new JLabel("过渡时间 (秒):"), gbc); gbc.gridx = 1; transitionTimeField = new JTextField(10); transitionTimeField.setText("30"); panel.add(transitionTimeField, gbc); // 添加说明标签 gbc.gridx = 0; gbc.gridy = 2; 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) + ":"); 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;'>点击 '+' 增加阶段,'-' 减少阶段。未填写或为 0 的阶段将被跳过</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]; curveTempFields[i].setVisible(visible); curveDurationFields[i].setVisible(visible); curveHoldFields[i].setVisible(visible); if (i < 3) { ((JLabel) ((JPanel) curveTempFields[i].getParent()).getComponent(0)).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]; curveTempFields[i].setVisible(visible); curveDurationFields[i].setVisible(visible); curveHoldFields[i].setVisible(visible); if (i < 3) { ((JLabel) ((JPanel) curveTempFields[i].getParent()).getComponent(0)).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 dateBite = Integer.parseInt((String) dateBiteComboBox.getSelectedItem()); int stopBits = getStopBitsValue(); int parity = getParityValue(); controller = new TemperatureController(this, selectedPort, baudRate, dateBite,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("请先连接串口"); } } public void startControl() { String selectedMode = (String) modeComboBox.getSelectedItem(); if ("恒温模式".equals(selectedMode)) { try { float targetTemp = Float.parseFloat(constantTempField.getText()); controller.setConstantTemperature(targetTemp); showInfo("恒温模式启动: " + targetTemp + "°C"); } catch (NumberFormatException ex) { showError("请输入有效的温度值"); } } else if ("曲线模式".equals(selectedMode)) { 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()); // ✅ 支持目标温度设为 0°C 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 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) ); } } 为什么一直报错呢
07-18
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) ); } } 为什么修改后,还是未被访问呢
最新发布
07-19
package useless; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Random; public class UselessButFunApp extends JFrame { private JButton targetButton; private JLabel scoreLabel; private JLabel timeLabel; private Timer timer; private int score = 0; private int timeLeft = 30; private Random random = new Random(); private Dimension screenSize; public UselessButFunApp() { setTitle("随机颜色按钮挑战"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setLayout(null); // 获取屏幕尺寸 screenSize = Toolkit.getDefaultToolkit().getScreenSize(); // 创建分数标签 scoreLabel = new JLabel("分数: 0"); scoreLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); scoreLabel.setBounds(20, 20, 200, 30); add(scoreLabel); // 创建时间标签 timeLabel = new JLabel("剩余时间: 30秒"); timeLabel.setFont(new Font("微软雅黑", Font.BOLD, 24)); timeLabel.setBounds(20, 60, 200, 30); add(timeLabel); // 创建目标按钮 targetButton = new JButton("点我!"); targetButton.setFont(new Font("微软雅黑", Font.BOLD, 20)); targetButton.setBounds(300, 250, 100, 60); targetButton.setOpaque(true); targetButton.setBorderPainted(false); targetButton.addActionListener(e -> { score++; scoreLabel.setText("分数: " + score); moveButton(); }); add(targetButton); // 设置初始按钮位置和颜色 moveButton(); // 创建计时器 timer = new Timer(1000, e -> { timeLeft--; timeLabel.setText("剩余时间: " + timeLeft + "秒"); if (timeLeft <= 0) { timer.stop(); targetButton.setEnabled(false); int option = JOptionPane.showConfirmDialog( this, "时间到!你的最终得分: " + score + "\n再玩一次?", "游戏结束", JOptionPane.YES_NO_OPTION ); if (option == JOptionPane.YES_OPTION) { restartGame(); } else { System.exit(0); } } }); // 添加开始按钮 JButton startButton = new JButton("开始游戏"); startButton.setFont(new Font("微软雅黑", Font.PLAIN, 18)); startButton.setBounds(320, 500, 150, 40); startButton.addActionListener(e -> { startButton.setVisible(false); timer.start(); }); add(startButton); setLocationRelativeTo(null); setVisible(true); } private void moveButton() { // 随机位置 int buttonWidth = targetButton.getWidth(); int buttonHeight = targetButton.getHeight(); int x = random.nextInt(getWidth() - buttonWidth - 20) + 10; int y = random.nextInt(getHeight() - buttonHeight - 80) + 70; // 随机颜色 Color buttonColor = new Color( random.nextInt(256), random.nextInt(256), random.nextInt(256) ); // 设置按钮位置和颜色 targetButton.setLocation(x, y); targetButton.setBackground(buttonColor); // 根据背景色调整文字颜色 int brightness = (buttonColor.getRed() * 299 + buttonColor.getGreen() * 587 + buttonColor.getBlue() * 114) / 1000; targetButton.setForeground(brightness > 128 ? Color.BLACK : Color.WHITE); } private void restartGame() { score = 0; timeLeft = 30; scoreLabel.setText("分数: 0"); timeLabel.setText("剩余时间: 30秒"); targetButton.setEnabled(true); moveButton(); timer.start(); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new UselessButFunApp()); } }纠错
06-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值