You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing开发:实现单按钮控制10个功能按钮停止功能

解决方案

核心实现要点

  • 避免在Swing事件线程中执行耗时操作,所有按钮的运行逻辑都放在后台线程中
  • 通过volatile修饰的布尔变量控制所有任务的启停,保证线程间的状态可见性
  • 用集合统一管理所有后台线程,方便停止时批量处理

修改后的完整代码

package dc.android.doctor.v3;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class DCJFrame extends javax.swing.JFrame {

    // 全局停止标志,volatile保证线程可见性
    private volatile boolean isRunning = false;
    // 存储所有后台任务线程
    private List<Thread> taskThreads = new ArrayList<>();

    public DCJFrame() {
        initComponents();
        // 给10个按钮绑定各自的功能监听器
        initButtonActions();
    }

    private void initButtonActions() {
        // 按钮1:正向更新进度条
        jButton1.addActionListener(e -> runTask(() -> {
            for (int i = 0; i <= 100 && isRunning; i++) {
                int finalI = i;
                SwingUtilities.invokeLater(() -> jProgressBar1.setValue(finalI));
                try {
                    Thread.sleep(50);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
            }
        }));

        // 按钮2:弹出消息对话框
        jButton2.addActionListener(e -> runTask(() -> {
            SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(this, "按钮2任务执行中"));
            try {
                Thread.sleep(2000);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(this, "按钮2任务完成"));
        }));

        // 按钮3:循环修改自身文本计数
        jButton3.addActionListener(e -> runTask(() -> {
            int count = 0;
            while (isRunning) {
                String text = "按钮3计数:" + count++;
                SwingUtilities.invokeLater(() -> jButton3.setText(text));
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
            SwingUtilities.invokeLater(() -> jButton3.setText("jButton3"));
        }));

        // 按钮4:控制台循环计数输出
        jButton4.addActionListener(e -> runTask(() -> {
            int count = 0;
            while (isRunning) {
                System.out.println("按钮4计数:" + count++);
                try {
                    Thread.sleep(800);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }));

        // 按钮5:循环修改窗口标题
        jButton5.addActionListener(e -> runTask(() -> {
            int count = 0;
            while (isRunning) {
                String title = "动态标题-" + count++;
                SwingUtilities.invokeLater(() -> setTitle(title));
                try {
                    Thread.sleep(1200);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
            SwingUtilities.invokeLater(() -> setTitle("DCJFrame"));
        }));

        // 按钮6:循环切换自身背景色
        jButton6.addActionListener(e -> runTask(() -> {
            Color[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW};
            int index = 0;
            while (isRunning) {
                Color color = colors[index++ % colors.length];
                SwingUtilities.invokeLater(() -> jButton6.setBackground(color));
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
            SwingUtilities.invokeLater(() -> jButton6.setBackground(UIManager.getColor("Button.background")));
        }));

        // 按钮7:打开新窗口,5秒后自动关闭
        jButton7.addActionListener(e -> runTask(() -> {
            SwingUtilities.invokeLater(() -> {
                JFrame newFrame = new JFrame("按钮7的新窗口");
                newFrame.setSize(300, 200);
                newFrame.setLocationRelativeTo(this);
                newFrame.add(new JLabel("这是按钮7触发的新窗口"));
                newFrame.setVisible(true);
            });
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            SwingUtilities.invokeLater(() -> {
                for (Window window : Window.getWindows()) {
                    if (window != this && window instanceof JFrame) {
                        window.dispose();
                    }
                }
            });
        }));

        // 按钮8:控制台输出随机数
        jButton8.addActionListener(e -> runTask(() -> {
            while (isRunning) {
                int random = (int) (Math.random() * 1000);
                System.out.println("按钮8生成随机数:" + random);
                try {
                    Thread.sleep(600);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }));

        // 按钮9:反向更新进度条
        jButton9.addActionListener(e -> runTask(() -> {
            for (int i = 100; i >= 0 && isRunning; i--) {
                int finalI = i;
                SwingUtilities.invokeLater(() -> jProgressBar1.setValue(finalI));
                try {
                    Thread.sleep(50);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
            }
        }));

        // 按钮10:循环切换前3个按钮的启用状态
        jButton10.addActionListener(e -> runTask(() -> {
            boolean enabled = true;
            while (isRunning) {
                boolean finalEnabled = enabled;
                SwingUtilities.invokeLater(() -> {
                    jButton1.setEnabled(finalEnabled);
                    jButton2.setEnabled(finalEnabled);
                    jButton3.setEnabled(finalEnabled);
                });
                enabled = !enabled;
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
            SwingUtilities.invokeLater(() -> {
                jButton1.setEnabled(true);
                jButton2.setEnabled(true);
                jButton3.setEnabled(true);
            });
        }));
    }

    // 通用任务启动方法
    private void runTask(Runnable task) {
        if (isRunning) {
            Thread thread = new Thread(task);
            taskThreads.add(thread);
            thread.start();
        }
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();
        jButton7 = new javax.swing.JButton();
        jButton8 = new javax.swing.JButton();
        jButton9 = new javax.swing.JButton();
        jButton10 = new javax.swing.JButton();
        jProgressBar1 = new javax.swing.JProgressBar();
        start = new javax.swing.JButton();
        stop = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");

        jButton2.setText("jButton2");

        jButton3.setText("jButton3");

        jButton4.setText("jButton4");

        jButton5.setText("jButton5");

        jButton6.setText("jButton6");

        jButton7.setText("jButton7");

        jButton8.setText("jButton8");

        jButton9.setText("jButton9");

        jButton10.setText("jButton10");

        start.setText("START");
        start.addActionListener(e -> startActionPerformed(e));

        stop.setText("STOP");
        stop.addActionListener(e -> stopActionPerformed(e));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jProgressBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton6)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton8)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton9)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton10)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(start)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(stop)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(25, 25, 25)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton2)
                    .addComponent(jButton3)
                    .addComponent(jButton4)
                    .addComponent(jButton5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton6)
                    .addComponent(jButton7)
                    .addComponent(jButton8)
                    .addComponent(jButton9)
                    .addComponent(jButton10))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 146, Short.MAX_VALUE)
                .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(start)
                    .addComponent(stop))
                .addGap(17, 17, 17))
        );

        pack();
    }

    private void startActionPerformed(java.awt.event.ActionEvent evt) {
        isRunning = true;
        taskThreads.clear();
        // 重置进度条
        SwingUtilities.invokeLater(() -> jProgressBar1.setValue(0));
        JOptionPane.showMessageDialog(this, "已启动所有任务,点击按钮开始执行");
    }

    private void stopActionPerformed(java.awt.event.ActionEvent evt) {
        isRunning = false;
        // 中断所有线程
        for (Thread thread : taskThreads) {
            thread.interrupt();
        }
        taskThreads.clear();
        // 恢复界面状态
        SwingUtilities.invokeLater(() -> {
            jProgressBar1.setValue(0);
            setTitle("DCJFrame");
            jButton3.setText("jButton3");
            jButton6.setBackground(UIManager.getColor("Button.background"));
            jButton1.setEnabled(true);
            jButton2.setEnabled(true);
            jButton3.setEnabled(true);
            // 关闭所有打开的新窗口
            for (Window window : Window.getWindows()) {
                if (window != this && window instanceof JFrame) {
                    window.dispose();
                }
            }
        });
        JOptionPane.showMessageDialog(this, "已停止所有任务");
    }

    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(DCJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }

        java.awt.EventQueue.invokeLater(() -> new DCJFrame().setVisible(true));
    }

    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton10;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JButton jButton7;
    private javax.swing.JButton jButton8;
    private javax.swing.JButton jButton9;
    private javax.swing.JProgressBar jProgressBar1;
    private javax.swing.JButton start;
    private javax.swing.JButton stop;
}

关键代码说明

  1. 线程安全控制:用volatile boolean isRunning作为全局开关,所有后台任务都会循环检查这个变量,一旦变为false就终止执行
  2. 任务管理:taskThreads集合存储所有启动的后台线程,停止时批量中断并清空
  3. Swing线程规则:所有修改UI的操作必须通过SwingUtilities.invokeLater()提交到事件线程执行,避免线程安全问题
  4. 按钮功能:10个按钮分别实现了进度条更新、弹窗、文本修改、控制台输出、窗口标题变化、背景色切换、新窗口打开、随机数生成、反向进度条、按钮状态切换等不同功能
  5. 启停逻辑:
    • START按钮:设置isRunning=true,清空线程列表,重置界面状态
    • STOP按钮:设置isRunning=false,中断所有线程,恢复所有界面元素到初始状态

内容的提问来源于stack exchange,提问作者DISCOUNT CENTRE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:07:04