Java 在JTextArea中显示后台进程状态

Java 在JTextArea中显示后台进程状态,java,swing,jtextarea,Java,Swing,Jtextarea,有没有办法在JTextArea中编写关于后台进程的文本。我在屏幕上有一个按钮。当用户单击该按钮时,某些进程启动。我想在文本区的屏幕上显示该过程的持续状态。在执行textArea.appendSome状态后,我使用调用textArea.repaint,但这对我不起作用 我需要为此实现自己的线程吗?textArea.repaint调用完全是多余的。在调用append之后,会自动调用repaint,所以您不需要调用它 下面是一个例子: Process p = ...; // start the pro

有没有办法在JTextArea中编写关于后台进程的文本。我在屏幕上有一个按钮。当用户单击该按钮时,某些进程启动。我想在文本区的屏幕上显示该过程的持续状态。在执行textArea.appendSome状态后,我使用调用textArea.repaint,但这对我不起作用

我需要为此实现自己的线程吗?

textArea.repaint调用完全是多余的。在调用append之后,会自动调用repaint,所以您不需要调用它

下面是一个例子:

Process p = ...; // start the process somehow
final BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
new Thread() {
    private String line;
    public void run() {
        while ((line = br.readLine()) != null) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    textArea.append(line);
                }
            });
        }
    }
}.start();
单击按钮时应运行此代码。

textArea.repaint调用完全是多余的。在调用append之后,会自动调用repaint,所以您不需要调用它

下面是一个例子:

Process p = ...; // start the process somehow
final BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
new Thread() {
    private String line;
    public void run() {
        while ((line = br.readLine()) != null) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    textArea.append(line);
                }
            });
        }
    }
}.start();
此代码应该在单击按钮时运行。

您只需使用,就不必担心在事件调度程序线程上执行定期任务。您只需调用publish inside doInBackground方法将指定的文本附加到JTextArea,它将调用进程并自动在事件调度程序线程上执行整个任务

请看这个工作示例:

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class LoadingImage {

    private JPanel contentPane;
    private JTextArea logArea;
    private JLabel imageLabel;
    private ImageIcon[] images;
    private JButton startStopButton;
    private String[] path;
    private int counter;

    private Timer timer;

    private ActionListener timerAction = 
                            new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            counter %= path.length;
            imageLabel.setIcon(images[counter++]);
        }
    };

    private ActionListener buttonAction = 
                            new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            if (timer.isRunning()) {
                startStopButton.setText("Start");
                timer.stop();
            }
            else {
                startStopButton.setText("Stop");
                timer.start();
            }
        }
    };

    public LoadingImage() {
        imageLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
        images = new ImageIcon[5];
        path = new String[] {
            "http://i.imgur.com/922oehL.gif",
            "http://i.imgur.com/2Fim5t4.gif",
            "http://i.imgur.com/jJKlCiI.gif",
            "http://i.imgur.com/0KuZuGl.gif",
            "http://i.imgur.com/evuKoI5.gif"
        };
        counter = 0;
    }

    private void displayGUI() {
        JFrame frame = new JFrame("Loading Image Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        contentPane = new JPanel(new BorderLayout(5, 5));
        JPanel centerPanel = new JPanel(new GridLayout(1, 2, 5, 5));
        logArea = new JTextArea(10, 10);
        JScrollPane logScroller = new JScrollPane();
        logScroller.setViewportView(logArea);

        centerPanel.add(logScroller);
        centerPanel.add(imageLabel);
        contentPane.add(centerPanel, BorderLayout.CENTER);

        startStopButton = new JButton("Stop");
        startStopButton.addActionListener(buttonAction);
        contentPane.add(startStopButton, BorderLayout.PAGE_END);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        new BackgroundTask().execute();
        timer = new Timer(1000, timerAction);
        timer.start();
    }

    private class BackgroundTask extends SwingWorker<ImageIcon[], String> {
        @Override
        protected ImageIcon[] doInBackground() {
            ImageIcon[] images = new ImageIcon[path.length];
            for (int i = 0; i < path.length; i++)
            {
                try {
                images[i] = new ImageIcon(ImageIO.read(new URL(path[i])));
                }catch(Exception e) {e.printStackTrace();}
                publish(String.format("Loaded : %s%n", path[i]));
            }

            return images;
        }

        @Override
        protected void process(java.util.List<String> messages) {
            for (String message : messages)
                logArea.append(message);
        }

        @Override
        protected void done() {
            try {
                images = get();             
            } catch(Exception e) {e.printStackTrace();}
        }
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new LoadingImage().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}
您可以简单地使用,在这里您实际上不必担心在事件调度程序线程上执行定期任务。您只需调用publish inside doInBackground方法将指定的文本附加到JTextArea,它将调用进程并自动在事件调度程序线程上执行整个任务

请看这个工作示例:

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class LoadingImage {

    private JPanel contentPane;
    private JTextArea logArea;
    private JLabel imageLabel;
    private ImageIcon[] images;
    private JButton startStopButton;
    private String[] path;
    private int counter;

    private Timer timer;

    private ActionListener timerAction = 
                            new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            counter %= path.length;
            imageLabel.setIcon(images[counter++]);
        }
    };

    private ActionListener buttonAction = 
                            new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            if (timer.isRunning()) {
                startStopButton.setText("Start");
                timer.stop();
            }
            else {
                startStopButton.setText("Stop");
                timer.start();
            }
        }
    };

    public LoadingImage() {
        imageLabel = new JLabel("Nothing to display yet...", JLabel.CENTER);
        images = new ImageIcon[5];
        path = new String[] {
            "http://i.imgur.com/922oehL.gif",
            "http://i.imgur.com/2Fim5t4.gif",
            "http://i.imgur.com/jJKlCiI.gif",
            "http://i.imgur.com/0KuZuGl.gif",
            "http://i.imgur.com/evuKoI5.gif"
        };
        counter = 0;
    }

    private void displayGUI() {
        JFrame frame = new JFrame("Loading Image Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        contentPane = new JPanel(new BorderLayout(5, 5));
        JPanel centerPanel = new JPanel(new GridLayout(1, 2, 5, 5));
        logArea = new JTextArea(10, 10);
        JScrollPane logScroller = new JScrollPane();
        logScroller.setViewportView(logArea);

        centerPanel.add(logScroller);
        centerPanel.add(imageLabel);
        contentPane.add(centerPanel, BorderLayout.CENTER);

        startStopButton = new JButton("Stop");
        startStopButton.addActionListener(buttonAction);
        contentPane.add(startStopButton, BorderLayout.PAGE_END);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        new BackgroundTask().execute();
        timer = new Timer(1000, timerAction);
        timer.start();
    }

    private class BackgroundTask extends SwingWorker<ImageIcon[], String> {
        @Override
        protected ImageIcon[] doInBackground() {
            ImageIcon[] images = new ImageIcon[path.length];
            for (int i = 0; i < path.length; i++)
            {
                try {
                images[i] = new ImageIcon(ImageIO.read(new URL(path[i])));
                }catch(Exception e) {e.printStackTrace();}
                publish(String.format("Loaded : %s%n", path[i]));
            }

            return images;
        }

        @Override
        protected void process(java.util.List<String> messages) {
            for (String message : messages)
                logArea.append(message);
        }

        @Override
        protected void done() {
            try {
                images = get();             
            } catch(Exception e) {e.printStackTrace();}
        }
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new LoadingImage().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

在我的例子中,Process并不完全是Process类的对象。它只是调用一些功能。你能解释一下我如何使用上面的spinet吗?要点是:如果你使用Java 7,你启动一个线程来检查功能的进度并定期调用JTextArea.append.append不是线程安全的。正如@bellabax所指出的,OP必须使用SwingWorker删除他/她的答案的人也可以使用SwingUtilities.invokeLater,我将在答案中提供一个例子。我也是如此,直到kleopatra和trashgod最近告诉我这件事:-在我的情况下,流程并不完全是流程类的对象。它只是调用一些功能。你能解释一下我如何使用上面的spinet吗?要点是:如果你使用Java 7,你启动一个线程来检查功能的进度并定期调用JTextArea.append.append不是线程安全的。正如@bellabax所指出的,OP必须使用SwingWorker删除他/她的答案的人也可以使用SwingUtilities.invokeLater,我将在答案中提供一个例子。我也是如此,直到kleopatra和垃圾神最近告诉我这件事:-