0

Jtextarea にコンソール出力を 1 つずつ表示する方法に問題がありました。システム コンソールの出力を JTextarea に正常にリダイレクトしました。しかし、問題は、実際のシステム コンソールでは、出力が 1 つずつ表示されることです (私は Thread.sleep() 関数を設定したので、結果はたとえば 0.5 秒ごとに表示されます)。しかし、JTextarea では、出力はループが終了したときに 1 回だけ表示され、実際のシステム コンソールのように 1 つずつ表示されるわけではありません。

ループは GUI ボタン​​によってトリガーされます。以下のサンプルコードをご覧ください。これはコードの一部です。

// Create a button.
but.setVerticalTextPosition(AbstractButton.CENTER);
but.setHorizontalTextPosition(AbstractButton.LEADING);
but.setActionCommand("publish");
but.addActionListener(this);

// Button action
public void actionPerformed(ActionEvent e) {
final JButton source = (JButton)e.getSource();
        if(source.equals(but)){
            for( int i = 0 ; i < 5 ; i++ ) {

                System.out.println( i );

                        // regular textarea output
                //JTextarea.append(Integer.toString(i));
                try {
                    Thread.sleep( 500 );
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

        }
}

ご覧のとおり、ループ内で System.out.println( i ) を使用しています。これは、システム コンソールの出力を JTextarea にリダイレクトしたため、出力が JTextarea にあるためです。

問題は、上で述べたように、実際のコンソールでは、出力が 500 ミリ秒ごとに 1 つずつ表示されることです。しかし、リダイレクトされた Jtextarea では、すべてのループが完了すると結果が 1 回表示されます。なぜこのようになっているのかわかりません。リダイレクトされた JTextarea にも出力を 1 つずつ表示する必要があります。

誰でも私を助けてください。どうもありがとう!

4

3 に答える 3

1

Swing何らかのイベントが発生したとき、または継続的な背景の変化に応じてGUI を動的に更新するには、 がSwingWorker提供する APIを使用できますSwing。このコードを試してください:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DynamicWrite implements ActionListener
{
    JFrame frame = new JFrame("TextArea");
    JTextArea tArea = new JTextArea(10,20);
    JButton button = new JButton("Click");
    JScrollPane pane = new JScrollPane(tArea);
    SwingWorker worker;
    String s= "Java is an Object Oriented Programming langauge...Java is static typed language...asbfldfjsdj";//some random String
    public void prepareAndShowGUI()
    {
        Container container = frame.getContentPane();
        container.add(pane);container.add(button,BorderLayout.NORTH);
        tArea.setLineWrap(true);
        tArea.setWrapStyleWord(true) ;
        button.addActionListener(this);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    public void actionPerformed(ActionEvent evt)
    {
        if(evt.getSource()==button)
        {
            tArea.setText("");
            if (worker!=null)
            {
                worker.cancel(true);
            }
            worker = new SwingWorker()
            {
                @Override
                protected Integer doInBackground()//Perform the required GUI update here.
                {
                    try
                    {
                        for(int i = 0;i<s.length();i++)
                        {
                            tArea.append(String.valueOf(s.charAt(i)));
                            Thread.sleep(5);
                        }
                    }catch(Exception ex){}
                    return 0;
                }       
            };
            worker.execute();//Schedules this SwingWorker for execution on a worker thread.
        }
    }   
    public static void main(String st[])
    {
        DynamicWrite dyna = new DynamicWrite();
        dyna.prepareAndShowGUI();
    }
}

これで問題が解決することを願っています。
SwingWorker API の詳細については、こちらをご覧ください

于 2013-01-16T20:07:12.553 に答える
0

を呼び出さないThread.sleepでくださいEDT。これにより、UI が「フリーズ」し、予想される視覚的な更新が遅れます。Swing には、非ビジュアル処理を Swing アプリケーションと並行して実行できるSwingWorkerなどの同時実行メカニズムがあります。

于 2013-01-16T11:42:23.490 に答える