JTextArea实时输出 [英] JTextArea real time output

查看:124
本文介绍了JTextArea实时输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我创建了一个带有循环的等待队列模拟,并且还使GUI出现了问题,当用户单击运行按钮时,几秒钟都没有显示,例如10-15秒,然后整个输出显示在JTextArea中.我如何输出将添加到jtextarea的所有内容,例如在控制台中.我查找了一个名为SwingWorker的东西.但是不知道如何使用它.请帮忙.

Hi I have created a waiting queue simulation with loops and also I have made the GUI what the problem is when the user clicks the run button nothing shows up for couples of seconds like 10-15sec then the whole output shows in the JTextArea. How do I output everything that is being appending to the jtextarea like in the console. I looked up something called SwingWorker. But have not idea how to use it. any help please.

package Windows;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


public class Station implements  ActionListener 
{
    private JTextArea userinput, useroutput;
    private JScrollPane sbr_userinput, sbr_useroutput;
    private JButton runButton, clearButton, homeButton;

    //LinkedList Customer Queue created here.
    public static Queue<String> line = new  LinkedList<String> ();
    private static String time;   //time variable.
    private static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");   //DateFormat variable.

    private int intervals;
    private int cashiers;
    private int processing_time;

    public static void main(String[] args) 
    {
        new Station();
    }

    public Station()
    {
        JFrame frame = new JFrame("[=] Train Station Simulation [=]");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 400);

        frame.setContentPane(GUI());

        frame.setVisible(true);
    }

    public Container GUI() 
    {
        JPanel totalGUI = new JPanel();
        totalGUI.setLayout(new GridLayout(1, 2, 3, 3));

        JPanel lPanel = new JPanel();
        lPanel.setLayout(new GridLayout(2, 1, 3 , 3));
        totalGUI.add(lPanel);

        JPanel rPanel = new JPanel(new GridLayout(3, 1, 3 , 3));
        totalGUI.add(rPanel);

        userinput = new JTextArea("Welcome to Train Station Queue Simulation!!!" + "\n" + 
        "Enter the number of cashiers available HERE!!!!:" + "\n");
        userinput.setEditable(true);
        userinput.setLineWrap(true);
        userinput.setWrapStyleWord(true);
        lPanel.add(userinput);

        useroutput = new JTextArea();
        useroutput.setEditable(false);
        useroutput.setLineWrap(true);
        useroutput.setWrapStyleWord(true);
        lPanel.add(useroutput);

        sbr_userinput = new JScrollPane(userinput, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        sbr_userinput.setPreferredSize(new Dimension(300, 300));
        lPanel.add(sbr_userinput);

        sbr_useroutput = new JScrollPane(useroutput, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        sbr_useroutput.setPreferredSize(new Dimension(300, 300));
        lPanel.add(sbr_useroutput);

        runButton = new JButton("RUN");
        runButton.addActionListener(this);
        rPanel.add(runButton);

        clearButton = new JButton("CLEAR");
        clearButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                userinput.setText("");
                useroutput.setText("");
                System.out.println("cleared");
            }
        });
        rPanel.add(clearButton);

        homeButton = new JButton("HOME");
        rPanel.add(homeButton);

        totalGUI.setOpaque(true);
        return totalGUI;
    }

    public void actionPerformed(ActionEvent e)
    {
        cashiers = Integer.parseInt(userinput.getText());
        if (e.getSource() == this.runButton)
        {
            useroutput.append("CUSTOMERS ARE COMING !!!! !!!!" + "\n" + "\n");;

            //Array of all the customer that will enter the queue.
            String list[] = {"Naqi", "Monty", "Mohin", "Yasmin", "Maighjoo", "Ashish", "Paal", "Kevin", "Ruhail", "Tony"};
            //2nd ArrayList which customer are added to and removed later on so no duplicates arise.
            ArrayList<String> customer = new ArrayList<String>(Arrays.asList(list));

            int array_customer_list = list.length; //Recording the number of customers in the array.

            //While statement containing for loop add customers to the empty LinkedList object.
            while (line.isEmpty())
            {
                for (int x = 0; x < array_customer_list; x++ )
                {
                    try
                    {
                        Thread.sleep(ran_interval() * 1000);   //Sleep method to hold the arrival time by 1-2 seconds. 
                        int cus = (int) (Math.random() * customer.size());   //Random customer is picked here. 
                        String new_cus = customer.get(cus);   //New customer object is created ere.
                        line.add(new_cus);   //Customer objects are added to the empty LinkedList queue.
                        customer.remove(cus);

                        //For loop statement to outputting the queue.
                        for (String s : line)
                        {
                            useroutput.append("[" + s.toString() + " " + "]" + "\n");; //Outputting each customer and using the ".name" method so customers are readable.
                        }
                        //Outputting the whole queue and stating who has joined the queue.
                        useroutput.append("\n" + "The queue has " + line.size() + " customers so far" + "\n" + 
                        new_cus.toString() + " Has Joined the Queue " + " <=== WAITING" + "\n" + "\n");
                    }
                    catch(Exception a)   //ERROR handler for sleep method.
                    {
                        System.out.println("Intervals error: " + e);   //Outputting the ERROR message.
                        System.exit(0);   //If ERROR found exit system.
                    }

                }
            }

            userinput.append("\n");
            useroutput.append("CUSTOMERS ARE WAITING !!!! !!!!" + "\n" + "\n");
            useroutput.append("Processing START !!!!" + "\n" + "\n");

            while (!line.isEmpty())   //While statement with for loop to remove each customer from LinkedList queue.
            {
                try 
                {
                    String cus = line.remove(); //Method to remove customer from LinkedList queue.
                    String time = getTime();
                    Thread.sleep((processing_time() * 1000) / cashiers); //Sleep method to hold the processing by 1-3 seconds.
                    for (String s : line)
                    {
                        useroutput.append("[" + s.toString() + " " + "]" + "\n"); //Outputting each customer and using the ".name" method so customers are readable.
                    }
                    //Outputting the whole queue and stating who has joined the queue.
                    useroutput.append("\n" + "The queue has " + line.size() + " customers left" + "\n" + 
                    cus.toString()+ " waited for " + time + " <=== SERVED" + "\n" + "\n");
                }
                catch(Exception a)   //ERROR handler for sleep method.
                {
                    System.out.println("Cashiers_wait error: " + e);   //Outputting the ERROR message.
                    System.exit(0);   //If ERROR found exit system.
                }
            }
        }

        useroutput.append("Processing FINISHED !!!!" + "\n");
        System.out.println("working");
    }

    static String getTime()   //Time Constructor
    {
       Calendar cal = Calendar.getInstance();
       time = dateFormat.format(cal.getTime());   //Getting the current system time.
       return time;   //Return time.
    }

    public int ran_interval()
     {
         Random rand = new Random(); //Random object created here.
         int interval = this.intervals = rand.nextInt(2) + 1; //Random number between 1-2 is generated for customer arrival here.

         return interval;
     }

    public int processing_time()
     {
         Random ran = new Random();    //Random object created here.
         int time = this.processing_time = ran.nextInt(4) + 1;  //Random number between 1-3 is generated for customer arrival here.

         return time;
     }
}

推荐答案

Swing是一个单线程框架.也就是说,所有与UI的交互都应在事件调度线程的上下文内执行.

Swing is a single threaded framework. That is, all interactions with the UI are intended to performed from within the context of the Event Dispatching Thread.

EDT的职责之一是处理重涂请求.

One of the responsibilities of the EDT is to process repaint requests.

任何阻止此线程的进程都将阻止其更新UI.

Any process that blocks this thread will prevent it from updating the UI.

在您的actionPerformed方法中,您正在EDT中运行一个耗时的过程,这就是为什么要花一些时间才能看到结果

In your actionPerformed method, you are running a time consuming process within the EDT which is why it takes time before you see the results

Yu可以启动第二个线程并在那里处理数据,从而使EDT继续响应更新请求.问题是,Swing还要求对UI的任何修改也必须在EDT内部执行.

Yu could start a second thread and process the data there, allowing the EDT to continue responding to update requests. The problem is, Swing also requires that any modifications to the UI be executed from within the EDT as well.

幸运的是,有一个简单的解决方案.

Luckily for you, there is a simple solution.

最好的选择是使用SwingWorker.它具有doInBackground方法,允许您在EDT之外进行处理; publish方法,允许您将结果发送回EDT; process方法,用于处理正在发布的内容,该方法在EDT和done方法,当doInBackground方法存在时在EDT上下文中调用

The best option is to use a SwingWorker. It has a doInBackground method, which allows you to do processing off the EDT, a publish method to allow you to send results back to the EDT, a process method to process what's being published, which is executed in the EDT and a done method which is called within the context of the EDT when the doInBackground method exists

有关更多详细信息,请参见 Swing中的并发

Take a look at Concurrency in Swing for more details

这篇关于JTextArea实时输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆