Как добавить текст в JTextArea, используя данные из отдельного потока - PullRequest
0 голосов
/ 06 мая 2019

У меня есть класс 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.На данный момент вызов setProcess, сделанный в классе Scheduler, предоставляет классу MainFrame объект процесса, но только один раз.Как это можно обновлять каждый раз, когда создается новый процесс?

Я хочу, чтобы графический интерфейс пользователя заполнял processTextArea при создании новых процессов.В настоящий момент происходит всплывающее окно с графическим интерфейсом, однако в processTextArea ничего не добавляется.

1 Ответ

0 голосов
/ 06 мая 2019

Это класс планировщика. В основном, когда он создает Process p, мне нужно сообщить GUI о недавно созданном процессе, чтобы его можно было добавить к processTextArea

Я думаю, что MainFrame объект в Main и MainFrame в Scheduler - это две разные ссылки? Вы должны решить это в первую очередь.

Я хочу, чтобы графический интерфейс пользователя заполнял processTextArea по мере создания новых процессов. В данный момент происходит всплывающее окно с графическим интерфейсом, однако в processTextArea ничего не добавляется.

Извлеките processTextArea, чтобы стать членом MainFrame, и создайте метод, подобный:

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

Всякий раз, когда Process завершается, вызывайте mainFrame.onProcessComplete(this). Это должно удовлетворить ваши потребности.

...