我是靠谱客的博主 典雅指甲油,最近开发中收集的这篇文章主要介绍java中的outputarea_关于多线程:Java将系统输出重定向到jtextarea,直到计算完成才更新...,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我有将系统输出重定向到jtext区域的代码,但是直到代码运行完毕,该jtextarea才会更新。 如何在运行时实时修改代码以实时更新jtextarea?

private void updateTextArea(final String text) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

consoleTextAreaInner.append(text);

}

});

}

private void redirectSystemStreams() {

OutputStream out = new OutputStream() {

@Override

public void write(int b) throws IOException {

updateTextArea(String.valueOf((char) b));

}

@Override

public void write(byte[] b, int off, int len) throws IOException {

updateTextArea(new String(b, off, len));

}

@Override

public void write(byte[] b) throws IOException {

write(b, 0, b.length);

}

};

System.setOut(new PrintStream(out, true));

System.setErr(new PrintStream(out, true));

}

其余代码主要只是一个按钮的动作侦听器:

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

// TODO add your handling code here:

String shopRoot = this.shopRootDirTxtField.getText();

String updZipPath = this.updateZipTextField.getText();

this.mainUpdater = new ShopUpdater(new File(shopRoot), updZipPath);

this.mainUpdater.update();

}

该update()方法开始在文件系统上复制+粘贴文件的过程,在此过程中,使用system.out.println提供有关程序当前所在位置的最新状态,以参考有多少文件 它必须复制。

也许调用object(textare)repaint()方法?

举个例子

很难百分百肯定地说出出了什么问题,因为我们没有看到很多关键的相关代码,但是很有可能会遇到Swing线程问题。 您需要在后台线程中读取流,然后在Swing事件线程EDT上调用对文本区域的更新方法。 否则,您将在等待流读取的同时绑定EDT,从而完全冻结GUI。 SwingWorker会很好地工作。 考虑在每次遇到新行时发布到JTextArea。

例如:

import java.io.IOException;

import java.io.OutputStream;

import java.io.PrintStream;

import javax.swing.JTextArea;

import javax.swing.SwingUtilities;

public class MyRedirectStream {

private JTextArea textArea;

public MyRedirectStream(JTextArea gui) {

this.textArea = gui;

}

public void redirect() {

System.setOut(new PrintStream(new MyOutStream(), true));

System.setErr(new PrintStream(new MyOutStream(), true));

}

private class MyOutStream extends OutputStream {

private static final int MAX_LENGTH = 1600;

private StringBuilder sb = new StringBuilder(MAX_LENGTH + 100);

@Override

public void write(int b) throws IOException {

sb.append((char)b);

if (sb.length() > MAX_LENGTH) {

sendToTextArea(sb.toString());

sb = new StringBuilder();

}

}

@Override

public void flush() throws IOException {

sendToTextArea(sb.toString());

sb = new StringBuilder();

super.flush();

}

private void sendToTextArea(final String text) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

textArea.append(text);

}

});

}

}

}

和:

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.io.File;

import java.io.FileNotFoundException;

import java.util.Scanner;

import javax.swing.AbstractAction;

import javax.swing.JButton;

import javax.swing.JFileChooser;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.SwingUtilities;

public class StreamToTextArea2 {

public static void main(String[] args) {

final TextPanel gui = new TextPanel();

final MyRedirectStream myRedirectStream = new MyRedirectStream(

gui.getTextarea());

myRedirectStream.redirect();

SwingUtilities.invokeLater(new Runnable() {

public void run() {

final JFrame frame = new JFrame("Redirect");

JButton showTextBtn = new JButton(new AbstractAction("Show Text") {

@Override

public void actionPerformed(ActionEvent arg0) {

JFileChooser fileChooser = new JFileChooser();

int result = fileChooser.showOpenDialog(frame);

if (result == JFileChooser.APPROVE_OPTION) {

gui.clearText();

final File file = fileChooser.getSelectedFile();

new Thread(new Runnable() {

public void run() {

try {

Scanner scan = new Scanner(file);

while (scan.hasNextLine()) {

System.out.println(scan.nextLine());

}

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

}).start();

}

}

});

JButton clearTextBtn = new JButton(

new AbstractAction("Clear Text") {

@Override

public void actionPerformed(ActionEvent e) {

gui.clearText();

}

});

JPanel btnPanel = new JPanel();

btnPanel.add(clearTextBtn);

btnPanel.add(showTextBtn);

frame.getContentPane().add(gui);

frame.getContentPane().add(btnPanel, BorderLayout.SOUTH);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

}

});

}

}

import java.awt.BorderLayout;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

class TextPanel extends JPanel {

private JTextArea textarea = new JTextArea(20, 40);

public TextPanel() {

setLayout(new BorderLayout());

JScrollPane scrollPane = new JScrollPane(textarea);

scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

add(scrollPane);

}

public JTextArea getTextarea() {

return textarea;

}

public void clearText() {

textarea.setText("");

}

}

+1,对新的Runnable()感到好奇,您是否知道它将被缓存还是在每次读取字节时生成线程?

@arynaq:不,不会被缓存。这段代码不是很有效。最好建立一个缓冲区或StringBuilder,然后在缓冲区足够大时批处理数据。

@arynaq:现在它将被缓存一些。

@HovercraftFullOfEels我似乎无法导入TextPanel以及随后的.getTextArea()和.clearText()是TextPanel错误还是应该将其视为J软件包之一的一部分?在您的所有代码中,这些是唯一无法识别的显示。我已经安装了所有JGoodies库,并且正在使用IntelliJ Idea作为我的iDE。提前致谢。

@dbconfession:对不起,被遗漏了。

@HovercraftFullOfEelsahh好的,我现在看到它。谢谢。

@dbconfession:我添加了您正在询问的缺少的类TextPanel。

@HovercraftFullOfEels我不认为您的代码解决了OP的问题。这是他的问题的一个很好的例子。 Hes询问如何使控制台信息实时附加到JTextArea。您的代码获取文本文件的上下文,并将所有内容立即吐出到jTextArea。如果我理解正确的话,就像控制台显示正在发生的信息一样,JTextArea也应该实时显示,而不是仅仅一次转储控制台输出的最终结果。

您确实编写了invokeLater,并且稍后会调用它。 除非您执行一些有效的操作来使延迟确定,否则延迟的延迟是不确定的。 例如,您可以在文件之间插入Thread.sleep调用。

最后

以上就是典雅指甲油为你收集整理的java中的outputarea_关于多线程:Java将系统输出重定向到jtextarea,直到计算完成才更新...的全部内容,希望文章能够帮你解决java中的outputarea_关于多线程:Java将系统输出重定向到jtextarea,直到计算完成才更新...所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部