如何使用来自单独线程的数据将文本追加到JTextArea

时间:2019-05-06 01:43:34

标签: java runnable swingutilities

我有一个带有线程的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 p时,我需要它告诉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添加任何内容。

1 个答案:

答案 0 :(得分:0)

  

这是调度程序类。基本上,当它创建Process p时,我需要它告诉GUI有关新创建的进程的信息,以便可以将其添加到processTextArea

我认为MainFrame中的Main对象和MainFrame中的Scheduler是两个不同的引用?您应该先解决这个问题。

  

我希望在创建新流程时让GUI填充processTextArea。目前发生的是GUI框架弹出,但是未向processTextArea添加任何内容。

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

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

只要完成Process,就调用mainFrame.onProcessComplete(this)。这应该可以满足您的需求。