如何在 JFrame/JPanel 中可视化控制台 java
Posted
技术标签:
【中文标题】如何在 JFrame/JPanel 中可视化控制台 java【英文标题】:how to visualize console java in JFrame/JPanel 【发布时间】:2012-04-04 07:26:19 【问题描述】:我使用 Swing 库制作了一个 Java 程序。 现在我想将我的控制台输出重定向到 JFrame 或 JPanel。
【问题讨论】:
那么你的问题到底是什么? 也许将所有内容附加到另一个 Swing 组件(例如JTextArea
)?
【参考方案1】:
我知道我迟到了,但是对于正在寻找更好、更紧凑的答案的人,我让这个女巫结合了两个自定义类。
控制台.java
public class Console
final JFrame frame = new JFrame("CONSOLE");
ColorPane textPane;
JScrollPane scroll;
public Console() throws Exception
textPane = new ColorPane();
textPane.setPreferredSize(new Dimension(525, 600));
textPane.setFont(new Font("Lucida Console", Font.BOLD, 12));
scroll = new JScrollPane(textPane);
textPane.setBackground(Color.BLACK);
scroll.setVerticalScrollBarPolicy ( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS );
textPane.getDocument().addDocumentListener(new DocumentListener()
@Override
public void insertUpdate(DocumentEvent e)
scrollToBottom(scroll);
@Override
public void removeUpdate(DocumentEvent e)
@Override
public void changedUpdate(DocumentEvent e)
);
//Add textPane in to middle panel
frame.add(scroll);
frame.setSize(100, 600);
frame.pack();
frame.setVisible(false);
redirectOut();
public PrintStream redirectOut()
OutputStream out = new OutputStream()
@Override
public void write(int b) throws IOException
textPane.append(Color.WHITE, String.valueOf((char) b));
;
OutputStream errOut = new OutputStream()
@Override
public void write(int b) throws IOException
textPane.append(Color.RED, String.valueOf((char) b));
;
PrintStream ps = new PrintStream(out);
PrintStream err = new PrintStream(errOut);
System.setOut(ps);
System.setErr(err);
scrollToBottom(scroll);
return ps;
public JFrame getFrame()
return frame;
private void scrollToBottom(JScrollPane scrollPane)
JScrollBar verticalBar = scrollPane.getVerticalScrollBar();
AdjustmentListener downScroller = new AdjustmentListener()
@Override
public void adjustmentValueChanged(AdjustmentEvent e)
Adjustable adjustable = e.getAdjustable();
adjustable.setValue(adjustable.getMaximum());
verticalBar.removeAdjustmentListener(this);
;
verticalBar.addAdjustmentListener(downScroller);
和 ColorPane.java
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
public class ColorPane extends JTextPane
public void appendNaive(Color c, String s) // naive implementation
// bad: instiantiates a new AttributeSet object on each call
SimpleAttributeSet aset = new SimpleAttributeSet();
StyleConstants.setForeground(aset, c);
int len = getText().length();
setCaretPosition(len); // place caret at the end (with no selection)
setCharacterAttributes(aset, false);
replaceSelection(s); // there is no selection, so inserts at caret
public void append(Color c, String s) // better implementation--uses
// StyleContext
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,
StyleConstants.Foreground, c);
int len = getDocument().getLength(); // same value as
// getText().length();
setCaretPosition(len); // place caret at the end (with no selection)
setCharacterAttributes(aset, false);
replaceSelection(s); // there is no selection, so inserts at caret
public static boolean isPrime(int n)
if (n < 2)
return false;
double max = Math.sqrt(n);
for (int j = 2; j <= max; j += 1)
if (n % j == 0)
return false; // j is a factor
return true;
public static boolean isPerfectSquare(int n)
int j = 1;
while (j * j < n && j * j > 0)
j += 1;
return (j * j == n);
这是我一直在使用的解决方案,它甚至有彩色输出。 PS:顺便说一句,对不起英语不好(我只有 11 岁)
【讨论】:
【参考方案2】:您需要创建一个将输出重定向到文本区域并实现 OutputStream 接口的所有必要方法的 OutputStream,然后在您的主程序中,将您的标准输出重定向到此流。我在我的一个程序中使用了类似的东西:
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class TextAreaOutputStream extends OutputStream
private final JTextArea textArea;
private final StringBuilder sb = new StringBuilder();
private String title;
public TextAreaOutputStream(final JTextArea textArea, String title)
this.textArea = textArea;
this.title = title;
sb.append(title + "> ");
@Override
public void flush()
@Override
public void close()
@Override
public void write(int b) throws IOException
if (b == '\r')
return;
if (b == '\n')
final String text = sb.toString() + "\n";
SwingUtilities.invokeLater(new Runnable()
public void run()
textArea.append(text);
);
sb.setLength(0);
sb.append(title + "> ");
return;
sb.append((char) b);
你可以用这个来演示它:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintStream;
import javax.swing.*;
@SuppressWarnings("serial")
public class TextAreaOutputStreamTest extends JPanel
private JTextArea textArea = new JTextArea(15, 30);
private TextAreaOutputStream taOutputStream = new TextAreaOutputStream(
textArea, "Test");
public TextAreaOutputStreamTest()
setLayout(new BorderLayout());
add(new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
System.setOut(new PrintStream(taOutputStream));
int timerDelay = 1000;
new Timer(timerDelay , new ActionListener()
int count = 0;
@Override
public void actionPerformed(ActionEvent arg0)
// though this outputs via System.out.println, it actually displays
// in the JTextArea:
System.out.println("Count is now: " + count + " seconds");
count++;
).start();
private static void createAndShowGui()
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TextAreaOutputStreamTest());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
public static void main(String[] args)
SwingUtilities.invokeLater(new Runnable()
public void run()
createAndShowGui();
);
【讨论】:
【参考方案3】:获得JFrame
或JPanel
后,向其中添加一个文本字段。
JTextArea
是一个不错的选择,因为它是多行。
添加后,您可以.append('text');
给它,而不是写System.out.print();
JFrame jFrame = new JFrame();
JTextArea jTextArea = new JTextArea();
jTextArea.append( "Hello World." );
jFrame.add( jTextArea );
【讨论】:
好的,我读到了。我认为还有其他事情可以做到这一点。因为已经有 println 我不想添加新的 textarea 并附加它们以上是关于如何在 JFrame/JPanel 中可视化控制台 java的主要内容,如果未能解决你的问题,请参考以下文章