【问题标题】:Run and pause a GUI background thread by clicking a button通过单击按钮运行和暂停 GUI 后台线程
【发布时间】:2013-04-23 20:52:39
【问题描述】:

我需要在我的 Java GUI 中运行一个后台线程,该线程仅在我单击一个按钮时运行,并在我再次单击该按钮时暂停。我不确定如何设置它,但是我在构造函数中放置了一个线程,并且当我将特定布尔值设置为 TRUE 时,其中的 while 循环设置为通过。一键切换设置此布尔值 TRUE 或 FALSE。

我在这个 GUI 中的所有其他东西都可以正常工作。当我尝试调试线程时,它实际上在我单步执行线程时工作,但当我尝试完全运行 GUI 时却没有。 GUI 相当大,所以我将放置一部分构造函数和按钮的动作侦听器。其余的代码是不必要的,因为它工作得很好。我需要知道我在这里做错了什么:

public BasketballGUI() {
    // certain labels and buttons
    Thread runningSim = new Thread() {
        public void run() {
            while(simRun) {
                // do stuff here
            }
        }
    };
    runningSim.start();
}

// other GUI stuff

// actionListener that should run the thread.
class SimButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent arg0) {
        if(!simRun) {
            simRun = true;
            sim.setText("Pause Simulator");
        }
        else if(simRun) {
            simRun = false;
            sim.setText("Run Simulator");
        }
        // other stuff in this actionListener
    }
}

【问题讨论】:

  • @LittleChild 不,它们不能 Thread#suspendThread#resume 已弃用并被视为不稳定...
  • @原始发帖者,请展示一些代码,请告诉我们您正在尝试做什么。
  • No code example,没有答案
  • 如需尽快获得更好的帮助,请发帖 SSCCE。我不会像@MadProgrammer 那样说“没有SSCCE,没有答案”,但这确实暗示了许多人会忽略没有SSCCE 的问题。
  • @AndrewThompson 那只是因为我是一个脾气暴躁、懒惰的老草;)

标签: java swing user-interface


【解决方案1】:
  1. 建立一个基于 Swing 的 Timer 和一个将被重复调用的 ActionListener
  2. actionPerformed(ActionEvent)方法中调用repaint()
  3. 当用户点击 Start 时启动计时器 (Timer.start())
  4. 当用户点击 Stop 时停止计时器 (Timer.stop())

如果您无法从该描述中得到它,我建议您发布您的最佳尝试的 SSCCE。


我以为我有一个“躺着”。试试这个working SSCCE,它使用在this SSCCE 创建的图像。

【讨论】:

    【解决方案2】:

    在处理按钮事件以影响文本区域或进度条等内容时,我可以看到这个后台线程对 Java GUI 很有用。

    为了争论,我将为您构建一个影响文本区域的小型 GUI。希望对您有所帮助。

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.concurrent.atomic.AtomicBoolean;
    import javax.swing.*;
    
    public class TestClass extends JPanel {
    
        super("TestClass - Title");
        private AtomicBoolean paused;
        private JTextArea jta;
        private JButton btn;
        private Thread thread;
    
        public TestClass() {
    
            paused = new AtomicBoolean(false);
            jta = new JTextArea(100, 100);
            btn = new JButton();
    
            initialize();
        }
    
        public void initialize() {
    
            jta.setLineWrap(true);
            jta.setWrapStyleWord(true);
            add(new JScrollPane(jta));
            btn.setPreferredSize(new Dimension(100, 100));
            btn.setText("Pause");
            btn.addActionListener(new ButtonListener());
            add(btn);
    
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    while(true) {
    
                        for(int i = 0; i < Integer.MAX_VALUE; i++) {
    
                            if(paused.get()) {
                                synchronized(thread) {
                                    try {
    
                                        thread.wait();
    
                                    } catch(InterruptedException e) {
                                    }
                                }
                            }
                        }
    
                        jta.append(Integer.toString(i) + ", ");
    
                   try {
    
                       Thread.sleep(500);
    
                   } catch (InterruptedException e) {
                    }
                    }
                }
            };
            thread = new Thread(runnable);
            thread.start();
        }
    
        @Override
        public Dimension getPreferredSize() {
    
            return new Dimension(100, 30);
    
        }
    
                class ButtonListener implements ActionListener {
    
                    @Override
                    public void actionPerformed(ActionEvent event) {
    
                        if(!paused.get()) {
                            btn.setText("Start");
                            paused.set(true);
                        } else {
                            btn.setText("Pause");
                            paused.set(false);
    
                            synchronized(thread) {
                                thread.notify();
                            }
                        }
                    }
                }
    }
    

    调用一切的主类。

    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    public class MainClass {
    
        public static void main(final String[] arg) {
    
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestClass());
                    frame.pack();
                    frame.setVisible(true);
                    frame.setLocationRelativeTo(null);
                }
            });
        }
    }
    

    我没有测试这段代码是否能正常工作,它的主要目标是打破你的编码障碍并使用我的组件来解决你的问题。希望这有帮助。需要其他任何东西给我发电子邮件到 DesignatedSoftware@gmail.com

    【讨论】:

    • 你的建议是非常危险的,它告诉原始发帖人拨打 Swing 电话,特别是在 Swing 事件调度线程之外的 jta.append(Integer.toString(i) + ", ");。请修改。
    • 您的代码有效,这正是我希望完成的。看来我的语法有点不对劲,但如果我能做出调整,我应该可以让它工作。
    • @PatchGuru 你知道我是否可以确保 TextArea 始终位于滚动窗格的底部?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    相关资源
    最近更新 更多