有什么方法可以在JTextArea
后台进程中写入文本。我在屏幕上有一个按钮。当用户单击该按钮时,将启动一些过程。我想在文本区域的屏幕上显示该进程的持续状态。做完之后textArea.append("Some status")
我会打电话textArea.repaint()
,但这对我不起作用。
我是否需要为此实现自己的线程?
您只需使用SwingWorker,您就不必担心在Event Dispatcher Thread
. 您只需调用publish()
insidedoInBackground()
方法将指定的文本附加到JTextArea
,这将自动调用process()
并执行整个任务Event Dispatcher Thread
。
看看这个工作示例:
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);
}
}
这个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();
单击按钮时应运行此代码。