简体   繁体   English

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

[英]How to append text to a JTextArea using data from a separate thread

I have a Scheduler class with a thread in charge of creating Process objects and I want to take the Process object as they are created and display the useful information to a JTextArea. 我有一个Scheduler类,其中一个线程负责创建Process对象,我想在创建它们时获取Process对象,并将有用信息显示给JTextArea。 However, when the Scheduler class creates the Process the JTextArea remains blank. 但是,当Scheduler类创建Process时,JTextArea保持空白。 How can i notify or update the JTextArea everytime a new Process is created? 每次创建新进程时,如何通知或更新JTextArea? There is also an ArrayBlockingQueue that stores every Process until the CPU class executes it. 还有一个ArrayBlockingQueue存储每个进程,直到CPU类执行它。

I have tried setting up Event listeners to try to capture when a process has been created. 我已经尝试设置事件侦听器以尝试捕获创建进程的时间。

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 creates the Scheduler object and then calls createProcess(). Main创建Scheduler对象,然后调用createProcess()。 Then it calls the SwingUtilities runnable thread. 然后它调用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

This is the scheduler class. 这是调度程序类。 Basically when it creates Process pi need it to tell the GUI about the newly created process so that it can be added to processTextArea 基本上当它创建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;


    }

The MainFrame is the GUI class. MainFrame是GUI类。 At the moment the setProcess call made in the Scheduler class does give the MainFrame class a process object but only once. 目前,在Scheduler类中进行的setProcess调用确实为MainFrame类提供了一个进程对象但只有一次。 How can this be updated everytime a new Process is created? 每次创建新流程时如何更新?

I Wish to have the GUI fill up the processTextArea as new Process's are being created. 我希望在创建新进程时让GUI填充processTextArea。 What happens at the moment is The GUI frame pops up however nothing is being added to the processTextArea. 目前发生的是GUI框架弹出但是没有任何东西被添加到processTextArea。

This is the scheduler class. 这是调度程序类。 Basically when it creates Process pi need it to tell the GUI about the newly created process so that it can be added to processTextArea 基本上当它创建Process pi需要它告诉GUI关于新创建的进程,以便它可以添加到processTextArea

I think the MainFrame object in Main and the MainFrame in Scheduler are two different reference? 我认为MainMainFrame对象和Scheduler中的MainFrame是两个不同的引用? You should solve this first. 你应该先解决这个问题。

I Wish to have the GUI fill up the processTextArea as new Process's are being created. 我希望在创建新进程时让GUI填充processTextArea。 What happens at the moment is The GUI frame pops up however nothing is being added to the processTextArea. 目前发生的是GUI框架弹出但是没有任何东西被添加到processTextArea。

Extract processTextArea to become the member of MainFrame , and to create a method like: 提取processTextArea成为MainFrame的成员,并创建一个方法,如:

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

Whenever a Process is completed, invoke mainFrame.onProcessComplete(this) . 每当Process完成时,调用mainFrame.onProcessComplete(this) This should meet your needs. 这应该符合您的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM