【问题标题】:pass JFrame to a thread将 JFrame 传递给线程
【发布时间】:2015-03-19 18:59:23
【问题描述】:

我有一个创建 JFrame 的类。单击开始按钮时,它会调用我的 CoinCounterMechanism 类。该类包含以下线程:

Thread consumer = new Thread("CONSUMER"){
    public void run ()
    {
        Integer coin;
        while (producerFlag)
        try 
        {
            coin = queue.take();
            System.out.println("Coin received: " + coin);
        } catch (InterruptedException e)  
        {
            e.printStackTrace();
        }
    }
};

当从我的其他类调用此线程时,我需要将 JFrame 传递给它,以便我可以修改 JFrame 内容。我怎样才能做到这一点?这是一个入门级的java课程,所以老师给了我们大部分代码。下面是调用线程的代码:

Button btnStart = new JButton("Start");
    btnStart.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            cm = new CoinCounterMechanism();
            cm.setConsumerFlag();
            cm.setProducerFlag();

            cm.producer.start();
            cm.consumer.start();
        }
    });

【问题讨论】:

  • 唯一应该对JFrame 做任何事情的线程是 UI 线程。
  • 请记住,swing 不是线程安全的。最好使用回调与可用于将线程与 EDT 同步或使用 SwingWorker
  • 考虑为这个问题和您之前的问题投票赞成有用的答案并接受最佳答案。否则,你是在要求志愿者付出努力,而不是奖励他们的努力。

标签: java multithreading swing


【解决方案1】:

您创建了一个实际的 Runnable 类,而不是匿名线程。您使用构造函数来传递您的 JFrame 和其他字段。

public class Consumer implements Runnable {

    private boolean producerFlag;

    private JFrame frame;

    private Queue<Integer> queue;

    public Consumer(JFrame frame, Queue<Integer> queue, boolean producerFlag) {
        this.frame = frame;
        this.queue = queue;
        this.producerFlag = producerFlag;
    }

    @Override
    public void run() {
        Integer coin;
        while (producerFlag)
            try {
                coin = queue.take();
                System.out.println("Coin received: " + coin);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }

}

您的 JButton 代码包含比实际启动线程的代码更高级别的代码。一般来说,你会用上面的 Runnable 类启动一个线程:

new Thread(new Consumer(frame, queue, true)).start();

【讨论】:

    【解决方案2】:

    应该在 JFrame 上修改任何内容的唯一线程是事件调度线程。

    为了让另一个线程修改像 JFrame 这样的 Swing 组件,它需要在事件调度线程上提交更改,例如让工作线程使用 SwingUtilities#invokeLater

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // modify your JFrame here
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2018-10-02
      • 2015-06-08
      • 2011-02-18
      • 2011-06-01
      • 2019-05-27
      • 2015-03-08
      • 2014-01-05
      • 1970-01-01
      相关资源
      最近更新 更多