package cn.mutils.app.ext; import java.awt.Color; import java.awt.Dialog; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; import java.awt.Rectangle; import java.awt.Window; import java.awt.event.WindowEvent; import javax.swing.JDialog; import javax.swing.JScrollPane; import javax.swing.JTextPane; import javax.swing.ScrollPaneConstants; import javax.swing.text.Document; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import cn.mutils.core.graphics.Bounds; import cn.mutils.core.io.ISystemPrinter; /** * Desktop pinter to print system stream to desktop UI. */ @SuppressWarnings("serial") public class DesktopPrinter extends JDialog implements ISystemPrinter { /** Console buffer size of default like eclipse */ public static final int BUFFER_SIZE = 80000; protected int mBufferSize = BUFFER_SIZE; protected LogText mTextPane; protected JScrollPane mScrollPane; protected Style mStyleSysout; protected Style mStyleSyserr; /** * Create the dialog. */ public DesktopPrinter(Window owner) { super(owner); setBounds(100, 100, 550, 200); mScrollPane = new JScrollPane(); mScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); mScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); getContentPane().add(mScrollPane); mTextPane = new LogText(); mTextPane.setFont(new Font("微软雅黑", Font.PLAIN, 14)); mScrollPane.setViewportView(mTextPane); String appTitle = null; DesktopApp app = DesktopApp.getApp(); if (app != null) { Window w = app.getMainWindow(); if (w instanceof Frame) { appTitle = ((Frame) w).getTitle(); } else if (w instanceof Dialog) { appTitle = ((Dialog) w).getTitle(); } } if (appTitle != null && !appTitle.isEmpty()) { this.setTitle("日志 - " + appTitle); } else { this.setTitle("日志"); } mStyleSysout = mTextPane.getStyledDocument().addStyle(null, null); mStyleSyserr = mTextPane.addStyle("syserr", mStyleSysout); StyleConstants.setForeground(mStyleSyserr, Color.RED); this.setLocationRelativeTo(null); } @Override protected void processWindowEvent(WindowEvent e) { if (e.getID() == WindowEvent.WINDOW_CLOSING) { DesktopApp app = DesktopApp.getApp(); if (app != null) { if (app.getMainWindow() == null) { // Main window startup happens exception System.exit(0); } } } super.processWindowEvent(e); } public void log(String text) { this.log(text, false); } public void log(String text, boolean err) { synchronized (this) { Document doc = mTextPane.getDocument(); try { int docLength = doc.getLength(); if (docLength >= mBufferSize) { if (text != null && text.equals("\r\n")) { if (docLength >= mBufferSize * 1.5) { doc.remove(0, docLength); docLength = 0; } } else { doc.remove(0, docLength); docLength = 0; } } doc.insertString(docLength, text, err ? mStyleSyserr : mStyleSysout); } catch (Exception e) { } } EventQueue.invokeLater(new UpdateRunnable()); } @Override public void systemOut(String str) { log(str, false); } @Override public void systemErr(String str) { log(str, true); } public static class LogText extends JTextPane { @Override public boolean getScrollableTracksViewportWidth() { return getUI().getPreferredSize(this).width <= getParent().getSize().width; } } class UpdateRunnable implements Runnable { @Override public void run() { mTextPane.scrollRectToVisible(new Rectangle(mScrollPane.getHorizontalScrollBar().getValue(), mTextPane.getPreferredSize().height, 0, 0)); if (!isVisible()) { Bounds max = DesktopUtil.getMaxWindowBounds(); int x = max.intX() + max.intWidth() - getWidth(); int y = max.intY() + max.intHeight() - getHeight(); if (x != getX() || y != getY()) { setLocation(x, y); } setVisible(true); } } } }