调试时,因为信息较多,比起机器捕捉关键词,有时人眼直接捕捉会更有效率。此时就需要滚动的窗口,而非 cmd,terminal 之类的简易控制台。就可带滚动条继续打印 System.out/System.err的内容。
修订版(作者弄得白背景黑字感觉不像,自己调了一下):
ConsoleWindow.java
🧡💛💚💙💜🖤🤎🧡💛💚💙💜🖤🤎🧡💛💚💙💜🖤🤎
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.*;
import java.io.OutputStream;
import java.io.PrintStream;public class ConsoleWindow {private static final int W = 800;private static final int H = 500;private static final int L = 200;private static final int T = 200;public static void init(){JFrame frame = new JFrame();frame.setTitle("ConsoleWindow");final JTextPane output = new JTextPane();output.setEditable(false);frame.add(new JScrollPane(output));frame.setSize(W,H);frame.setLocation(L,T);frame.setFocusableWindowState(false);frame.setVisible(true);output.setBackground(Color.BLACK);output.setFont(new Font("DIALOG",Font.BOLD,20));StyledDocument d = output.getStyledDocument();SimpleAttributeSet attr = new SimpleAttributeSet();PrintStream consoleStream = new PrintStream(new OutputStream(){@Overridepublic void write(int b) {}public void write(byte[] b, int off, int len) {StyleConstants.setForeground(attr,Color.WHITE);try {d.insertString(d.getLength(),new String(b,off,len),attr);} catch (BadLocationException e) {e.printStackTrace();}}});new Font("",Font.BOLD,5);PrintStream consoleStream2 = new PrintStream(new OutputStream(){@Overridepublic void write(int b) {}public void write(byte[] b, int off, int len){StyleConstants.setForeground(attr,Color.RED);try {d.insertString(d.getLength(),new String(b,off,len),attr);} catch (BadLocationException e) {e.printStackTrace();}}});System.setOut(consoleStream);System.setErr(consoleStream2);}
}
🧡💛💚💙💜🖤🤎🧡💛💚💙💜🖤🤎🧡💛💚💙💜🖤🤎
Main.java
🧡💛💚💙💜🖤🤎🧡💛💚💙💜🖤🤎🧡💛💚💙💜🖤🤎
public class Main {public static void main(String[] args) {Main solution &#61; new Main();ConsoleWindow.init();for(int i &#61; 0; i <10; i&#43;&#43;){System.out.println("out "&#43;i);System.err.println("err "&#43;i);}}
}
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
我们希望当 AWT 组件和用户交互过程中&#xff0c;能显示提示信息&#xff0c;应该捕获信息&#xff0c;并将状态信息进行输出。
这部分挺有意思的&#xff0c;大致就是作者通过事件描述符&#xff0c;拦截到事件&#xff0c;然后交给代理类去处理&#xff0c;然后代理类完成了输出工作。为了和前面的内容结合&#xff0c;又把刚刚的控制台利用上了。这个控制台不会自动换行&#xff0c;内容一长看的头疼。找了好久&#xff0c;终于让我找到一个设置自动换行的工具&#xff0c;MyHTMLEditorKit&#xff1a;
MyHTMLEditorKit.class
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
import javax.swing.*;
import javax.swing.text.Element;
import javax.swing.text.ParagraphView;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.InlineView;public class MyHTMLEditorKit extends HTMLEditorKit {private static final long serialVersionUID &#61; 3632670469611941371L;&#64;Overridepublic ViewFactory getViewFactory() {return new HTMLFactory() {public View create(Element e) {View v &#61; super.create(e);if (v instanceof InlineView) {return new InlineView(e) {public int getBreakWeight(int axis, float pos, float len) {return GoodBreakWeight;}public View breakView(int axis, int p0, float pos, float len) {if (axis &#61;&#61; View.X_AXIS) {checkPainter();int p1 &#61; getGlyphPainter().getBoundedPosition(this, p0, pos, len);if (p0 &#61;&#61; getStartOffset() && p1 &#61;&#61; getEndOffset()) {return this;}return createFragment(p0, p1);}return this;}};} else if (v instanceof ParagraphView) {return new ParagraphView(e) {protected SizeRequirements calculateMinorAxisRequirements(int axis,SizeRequirements r) {if (r &#61;&#61; null) {r &#61; new SizeRequirements();}float pref &#61; layoutPool.getPreferredSpan(axis);float min &#61; layoutPool.getMinimumSpan(axis);r.minimum &#61; (int) min;r.preferred &#61; Math.max(r.minimum, (int) pref);r.maximum &#61; Integer.MAX_VALUE;return r;}};}return v;}};}
}
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
ConsoleWindow.class
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.io.OutputStream;
import java.io.PrintStream;public class ConsoleWindow {private static final int W &#61; 800;private static final int H &#61; 500;private static final int L &#61; 200;private static final int T &#61; 200;public static void init(){EventTracer tracer &#61; new EventTracer();JFrame frame &#61; new JFrame();tracer.add(frame);frame.setTitle("ConsoleWindow");final JTextPane output &#61; new JTextPane();output.setEditorKit(new MyHTMLEditorKit());output.setEditable(false);output.setSize(W,H);frame.add(new JScrollPane(output));frame.setSize(W,H);frame.setLocation(L,T);frame.setFocusableWindowState(false);frame.setVisible(true);output.setBackground(Color.BLACK);output.setFont(new Font("DIALOG",Font.BOLD,20));StyledDocument d &#61; output.getStyledDocument();SimpleAttributeSet attr &#61; new SimpleAttributeSet();PrintStream consoleStream &#61; new PrintStream(new OutputStream(){&#64;Overridepublic void write(int b) {}public void write(byte[] b, int off, int len) {StyleConstants.setForeground(attr,Color.WHITE);try {d.insertString(d.getLength(),new String(b,off,len),attr);} catch (BadLocationException e) {e.printStackTrace();}}});new Font("",Font.BOLD,5);PrintStream consoleStream2 &#61; new PrintStream(new OutputStream(){&#64;Overridepublic void write(int b) {}public void write(byte[] b, int off, int len){StyleConstants.setForeground(attr,Color.RED);try {d.insertString(d.getLength(),new String(b,off,len),attr);} catch (BadLocationException e) {e.printStackTrace();}}});System.setOut(consoleStream);System.setErr(consoleStream2);}
}
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
Main.java
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
public class Main {public static void main(String[] args) {Main solution &#61; new Main();ConsoleWindow.init();}}
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
然后发现书的作者还有第二段代码。。。嗯~ o(*&#xffe3;▽&#xffe3;*)o&#xff0c;跑偏了。那就再试下呗。
给了个滚动条&#xff0c;还有个按钮&#xff0c;咱把刚刚的控制台再加进来&#xff0c;来个三级运载火箭合体&#xff1a;
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
import javax.swing.*;
import java.awt.*;public class EventTracerTest {public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {&#64;Overridepublic void run() {JFrame frame &#61; new EventTracerFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}});}
}class EventTracerFrame extends JFrame{private static final int W &#61; 400;private static final int H &#61; 400;public EventTracerFrame(){setTitle("EventTracerTest");setSize(W,H);add(new JSlider(),BorderLayout.NORTH);add(new JButton("Test"),BorderLayout.SOUTH);ConsoleWindow.init();EventTracer tracer &#61; new EventTracer();tracer.add(this);}
}
&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;&#x1f9e1;&#x1f49b;&#x1f49a;&#x1f499;&#x1f49c;&#x1f5a4;&#x1f90e;
控制台代码的这两行屏蔽一下&#xff1a;
相关内容&#xff1a;选择 《Java核心技术 卷1》查找相关笔记
评论&#x1f339;点赞&#x1f44d;收藏✨关注&#x1f440;&#xff0c;是送给作者最好的礼物&#xff0c;愿我们共同学习&#xff0c;一起进步
如果对作者发布的内容感兴趣&#xff0c;可点击下方关注公众号 钰娘娘知识汇总 查看更多作者文章哦&#xff01;