《Java 核心技术 卷1》 笔记 第11章 异常、日志、断言和调试(9)自制控制台窗口与窗口事件抓取
11.6.1 使用控制台窗口
调试时,因为信息较多,比起机器捕捉关键词,有时人眼直接捕捉会更有效率。此时就需要滚动的窗口,而非 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(){ @Override public 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(){ @Override public 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 = new Main(); ConsoleWindow.init(); for(int i = 0; i < 10; i++){ System.out.println("out "+i); System.err.println("err "+i); } }}
?????????????????????
11.6.2 跟踪 AWT 事件
我们希望当 AWT 组件和用户交互过程中,能显示提示信息,应该捕获信息,并将状态信息进行输出。
这部分挺有意思的,大致就是作者通过事件描述符,拦截到事件,然后交给代理类去处理,然后代理类完成了输出工作。为了和前面的内容结合,又把刚刚的控制台利用上了。这个控制台不会自动换行,内容一长看的头疼。找了好久,终于让我找到一个设置自动换行的工具,MyHTMLEditorKit:
MyHTMLEditorKit.class
?????????????????????
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 = 3632670469611941371L; @Override public ViewFactory getViewFactory() { return new HTMLFactory() { public View create(Element e) { View v = 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 == View.X_AXIS) { checkPainter(); int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len); if (p0 == getStartOffset() && p1 == 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 == null) { r = new SizeRequirements();}float pref = layoutPool.getPreferredSpan(axis);float min = layoutPool.getMinimumSpan(axis);r.minimum = (int) min;r.preferred = Math.max(r.minimum, (int) pref);r.maximum = Integer.MAX_VALUE;return r; }}; } return v; } }; }}
?????????????????????
ConsoleWindow.class
?????????????????????
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 = 800; private static final int H = 500; private static final int L = 200; private static final int T = 200; public static void init(){ EventTracer tracer = new EventTracer(); JFrame frame = new JFrame(); tracer.add(frame); frame.setTitle("ConsoleWindow"); final JTextPane output = 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 = output.getStyledDocument(); SimpleAttributeSet attr = new SimpleAttributeSet(); PrintStream consoleStream = new PrintStream( new OutputStream(){ @Override public 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(){ @Override public 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 = new Main(); ConsoleWindow.init(); }}
?????????????????????
然后发现书的作者还有第二段代码。。。嗯~ o(* ̄▽ ̄*)o,跑偏了。那就再试下呗。
给了个滚动条,还有个按钮,咱把刚刚的控制台再加进来,来个三级运载火箭合体:
?????????????????????
import javax.swing.*;import java.awt.*; public class EventTracerTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new EventTracerFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); }} class EventTracerFrame extends JFrame{ private static final int W = 400; private static final int H = 400; public EventTracerFrame(){ setTitle("EventTracerTest"); setSize(W,H); add(new JSlider(),BorderLayout.NORTH); add(new JButton("Test"),BorderLayout.SOUTH); ConsoleWindow.init(); EventTracer tracer = new EventTracer(); tracer.add(this); }}
?????????????????????
控制台代码的这两行屏蔽一下:
相关内容:选择 《Java核心技术 卷1》查找相关笔记
评论?点赞?收藏✨关注?,是送给作者最好的礼物,愿我们共同学习,一起进步
如果对作者发布的内容感兴趣,可点击下方关注公众号 钰娘娘知识汇总 查看更多作者文章哦!