java 刷新jtextarea,如何刷新Java的JTextArea?

I am writing a GUI with a button. When the user clicks the button, I would like a "Beginning work..." message to appear in a JTextArea immediately, and a "Finished." message to appear when the work is done. The GUI contains some code of the form

private void buttonActionPerformed(java.awt.event.ActionEvent evt) {

myJTextArea.append("Beginning work...\n");

myJTextArea.append("Finished.\n");

}

Unfortunately, neither message appears until the end. Is there a way to flush messages to JTextArea? On another forum, I saw people mention running a separate thread for the JTextArea output. Would some solution based on that be possible?

Thanks

解决方案

Unfortunately, neither message appears until the end. Is there a way to flush messages to JTextArea? On another forum, I saw mention running a separate thread for the JTextArea output. Would some solution based on that be possible?

This has nothing to do with "flushing" the JTextArea, and all to do with making sure that your code follows Swing threading rules. The long running code that is outputting to the JTextArea should be called in a background thread such as with a SwingWorker. Then it would intermittently output its results to the JTextArea, but making sure to do so carefully on the Swing event thread. If you use a SwingWorker, this could be done using the publish/process method pair.

For example:

import java.util.List;

import javax.swing.*;

public class SwingThreadingEg extends JPanel implements MyAppendable {

private JTextArea area = new JTextArea(30, 50);

public SwingThreadingEg() {

JScrollPane scrollPane = new JScrollPane(area);

scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

add(scrollPane);

}

@Override

public void append(String text) {

area.append(text);

}

private static void createAndShowGui() {

SwingThreadingEg mainPanel = new SwingThreadingEg();

MyWorker myWorker = new MyWorker(mainPanel);

// add a Prop Change listener here to listen for

// DONE state then call get() on myWorker

myWorker.execute();

JFrame frame = new JFrame("SwingThreadingEg");

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

frame.getContentPane().add(mainPanel);

frame.pack();

frame.setLocationByPlatform(true);

frame.setVisible(true);

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGui();

}

});

}

}

class MyWorker extends SwingWorker {

private static final long SLEEP_TIME = 500;

private MyAppendable myAppendable;

public MyWorker(MyAppendable myAppendable) {

this.myAppendable = myAppendable;

}

@Override

protected Void doInBackground() throws Exception {

publish("Beginning Work");

// simulate some long-running task:

for (int i = 0; i < 20; i++) {

publish("From SwingWorker: " + i);

Thread.sleep(SLEEP_TIME);

}

publish("Finished!");

return null;

}

@Override

protected void process(List chunks) {

for (String text : chunks) {

myAppendable.append(text + "\n");

}

}

}

interface MyAppendable {

public void append(String text);

}

Code adapted from my code from an answer to a previous similar question.

Note, if you're going to use a standard Runnable and a background Thread without a SwingWorker, as Lars recommends, you'll first of all want to implement a Runnable and not extend Thread, and you must take care that most all Swing calls are queued onto the event thread, thus something like:

@Override

public void actionPerformed(ActionEvent e) {

textarea.append("Start...");

new Thread(new Runnable(){

@Override

public void run() {

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

SwingUtilities.invokeLater(new Runnable() {

@Override

public void run() {

textarea.append("End");

}

});

}

}).start();

}

This looks a bit complicated what with all the nested anonymous inner classes, and in fact this is one of the main reasons why a SwingWorker may work better in this situation, since the code used is simpler, reducing the chances of creating unseen bugs.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值