首页 > 解决方案 > 如何使用来自单独线程的数据将文本附加到 JTextArea

问题描述

我有一个 Scheduler 类,其中有一个线程负责创建 Process 对象,我想在创建 Process 对象时获取它们并将有用的信息显示到 JTextArea。但是,当 Scheduler 类创建 Process 时,JTextArea 保持空白。每次创建新进程时如何通知或更新 JTextArea?还有一个 ArrayBlockingQueue 存储每个进程,直到 CPU 类执行它。

我尝试设置事件侦听器以尝试捕获创建进程的时间。

public class Main {

    public static void main(String[] args) {



            Scheduler scheduler = new Scheduler();
            scheduler.createProcesses();

            SwingUtilities.invokeLater(new Runnable(){

                public void run(){
                    JFrame frame = new MainFrame();
                    frame.setVisible(true);
                    frame.setSize(500,500);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                }
            });

    }
 }




Main 创建 Scheduler 对象,然后调用 createProcess()。然后它调用 SwingUtilities 可运行线程。

import java.awt.BorderLayout;
import java.awt.Container;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.lang.Math;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Scheduler {
    private static final int MAX_QUEUE_SIZE = 1001;
    private CPU cpu;
    private MainFrame frame;
    ArrayBlockingQueue<Process> readyQueue;
    int time = 0;
    int pid = 1000;



    public Scheduler()
    {
        readyQueue = new ArrayBlockingQueue<Process>(MAX_QUEUE_SIZE, true);
        this.cpu = new CPU(this);
        frame = new MainFrame();

        }//end of constructor


    public void createProcesses()  //populate ready queue
    {


        new Thread(new Runnable() {
            @Override
            public void run() {
                // Create 1002 processes
                Scheduler.this.cpu.start();
                while(pid < 2002) {
                    Random rand = new Random();
                    int meanRunTime = 10;
                    int sd = 2;
                    // Random number following a Normal distribution
                    int runTime = (int) Math.round(rand.nextGaussian()) * sd + meanRunTime;
                    int meanDelayTime = 5;
                    sd = 1;
                    int arrivalDelayTime = (int) Math.round(rand.nextGaussian()) * sd + meanDelayTime;
                    //System.out.println(Scheduler.this.time);
                    try {
                            // Wait for process to arrive
                            Thread.sleep(arrivalDelayTime);
                            Scheduler.this.time += arrivalDelayTime;
                        } catch (InterruptedException e) {
                            System.out.println("Queue waiting for arival interrupted");
                        }

                    Process p = new Process(Scheduler.this.pid, Process.WAITING, (time), runTime);    //constructs Process


                    System.out.println(p.toString());
                    frame.setProcess(p);   //This is where I am attempting to pass the process to the frame however this does not seem to work


                    Scheduler.this.pid++;
                    try {
                    Scheduler.this.readyQueue.put(p);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }

                }

            }

        }).start();

    }//end of create process

这是调度程序类。基本上,当它创建 Process pi 时,它需要它告诉 GUI 新创建的进程,以便它可以添加到 processTextArea

import java.awt.BorderLayout;
import java.awt.Container;
import java.util.concurrent.ArrayBlockingQueue;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;



public final class MainFrame extends JFrame{

    private Process process;





    public MainFrame(){

            //Layout of Frame
            setLayout(new BorderLayout());

            //Creation of Components that will go into the Frame
            JTextArea processTextArea = new JTextArea("Awaiting Completed Processes");

            while(process != null){
                processTextArea.setText(process.toString());
                process = null;
            }

            //Adds Compnents to the content frame
            Container c = getContentPane();
            c.add(processTextArea, BorderLayout.EAST);







    }



    public void setProcess(Process p){
        this.process = p;


    }

MainFrame 是 GUI 类。目前,在 Scheduler 类中进行的 setProcess 调用确实为 MainFrame 类提供了一个进程对象,但只有一次。每次创建新流程时如何更新?

我希望在创建新进程时让 GUI 填充 processTextArea。目前发生的情况是 GUI 框架弹出,但没有任何内容被添加到 processTextArea。

标签: javarunnableswingutilities

解决方案


这是调度程序类。基本上,当它创建 Process pi 时,它需要它告诉 GUI 新创建的进程,以便它可以添加到 processTextArea

我认为MainFrame对象 inMainMainFrameinScheduler是两个不同的引用?你应该先解决这个问题。

我希望在创建新进程时让 GUI 填充 processTextArea。目前发生的情况是 GUI 框架弹出,但没有任何内容被添加到 processTextArea。

提取processTextArea成为 的成员MainFrame,并创建如下方法:

public void onProcessComplete(Process P) {
    synchronized (processTextArea) {
        processTextArea.append(process.toString());
    }
}

每当 aProcess完成时,调用mainFrame.onProcessComplete(this). 这应该可以满足您的需求。


推荐阅读