在 GUI 面板内创建 Java 控制台
2022-09-01 00:24:18
如何在 GUI 面板中创建 Java 控制台的实例?
如何在 GUI 面板中创建 Java 控制台的实例?
下面是一个函数类。您可以使用以下命令将此实例安装到系统中并出错:
PrintStream con=new PrintStream(new TextAreaOutputStream(...));
System.setOut(con);
System.setErr(con);
2014-02-19 更新:使用 EventQueue.invokeLater() 以避免 GUI 线程问题,这些问题在原始版本中很少出现。
更新 2014-02-27:更好的实施
更新 2014-03-25:更正记录和删除文本区域中的行,使其在方法范围内,以避免在控制台被输出淹没时可能发生的追加和删除之间的争用条件。最终结果对我来说似乎也更干净。run()
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
public class TextAreaOutputStream
extends OutputStream
{
// *************************************************************************************************
// INSTANCE MEMBERS
// *************************************************************************************************
private byte[] oneByte; // array for write(int val);
private Appender appender; // most recent action
public TextAreaOutputStream(JTextArea txtara) {
this(txtara,1000);
}
public TextAreaOutputStream(JTextArea txtara, int maxlin) {
if(maxlin<1) { throw new IllegalArgumentException("TextAreaOutputStream maximum lines must be positive (value="+maxlin+")"); }
oneByte=new byte[1];
appender=new Appender(txtara,maxlin);
}
/** Clear the current console text area. */
public synchronized void clear() {
if(appender!=null) { appender.clear(); }
}
public synchronized void close() {
appender=null;
}
public synchronized void flush() {
}
public synchronized void write(int val) {
oneByte[0]=(byte)val;
write(oneByte,0,1);
}
public synchronized void write(byte[] ba) {
write(ba,0,ba.length);
}
public synchronized void write(byte[] ba,int str,int len) {
if(appender!=null) { appender.append(bytesToString(ba,str,len)); }
}
@edu.umd.cs.findbugs.annotations.SuppressWarnings("DM_DEFAULT_ENCODING")
static private String bytesToString(byte[] ba, int str, int len) {
try { return new String(ba,str,len,"UTF-8"); } catch(UnsupportedEncodingException thr) { return new String(ba,str,len); } // all JVMs are required to support UTF-8
}
// *************************************************************************************************
// STATIC MEMBERS
// *************************************************************************************************
static class Appender
implements Runnable
{
private final JTextArea textArea;
private final int maxLines; // maximum lines allowed in text area
private final LinkedList<Integer> lengths; // length of lines within text area
private final List<String> values; // values waiting to be appended
private int curLength; // length of current line
private boolean clear;
private boolean queue;
Appender(JTextArea txtara, int maxlin) {
textArea =txtara;
maxLines =maxlin;
lengths =new LinkedList<Integer>();
values =new ArrayList<String>();
curLength=0;
clear =false;
queue =true;
}
synchronized void append(String val) {
values.add(val);
if(queue) { queue=false; EventQueue.invokeLater(this); }
}
synchronized void clear() {
clear=true;
curLength=0;
lengths.clear();
values.clear();
if(queue) { queue=false; EventQueue.invokeLater(this); }
}
// MUST BE THE ONLY METHOD THAT TOUCHES textArea!
public synchronized void run() {
if(clear) { textArea.setText(""); }
for(String val: values) {
curLength+=val.length();
if(val.endsWith(EOL1) || val.endsWith(EOL2)) {
if(lengths.size()>=maxLines) { textArea.replaceRange("",0,lengths.removeFirst()); }
lengths.addLast(curLength);
curLength=0;
}
textArea.append(val);
}
values.clear();
clear =false;
queue =true;
}
static private final String EOL1="\n";
static private final String EOL2=System.getProperty("line.separator",EOL1);
}
} /* END PUBLIC CLASS */
这是它的实际截图:
@Sofware猴子:
它的工作原理!:)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class Main{
public static void main( String [] args ) throws InterruptedException {
JFrame frame = new JFrame();
frame.add( new JLabel(" Outout" ), BorderLayout.NORTH );
JTextArea ta = new JTextArea();
TextAreaOutputStream taos = new TextAreaOutputStream( ta, 60 );
PrintStream ps = new PrintStream( taos );
System.setOut( ps );
System.setErr( ps );
frame.add( new JScrollPane( ta ) );
frame.pack();
frame.setVisible( true );
frame.setSize(800,600);
for( int i = 0 ; i < 100 ; i++ ) {
System.out.println( i );
Thread.sleep( 500 );
}
}
}