[英]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? 我认为
Main
的MainFrame
对象和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.