做爲一個程序設計人員,咱們深知日誌的重要性,對於日誌的監控,咱們一般不外乎採用如下兩種方式:日誌文件方式和後臺打印方式,常規狀況下,這兩種日誌監控方式徹底能夠知足咱們對日誌監控的須要。可是,當咱們用Swing進行前臺開發時,經常想能不能把後臺服務運行日誌實時地顯示在前臺窗口中,或者只是將某類咱們比較關心的日誌信息(譬如異常日誌等)實時動態地顯示在前臺窗口中,這樣方便咱們及時監控和處理。這個設想咱們稱之爲「後臺日誌信息前臺監控器」。java
設計這樣一個「後臺日誌信息前臺監控器」,有兩個難點,第一個是,當咱們捕捉到後臺日誌信息時,如何將日誌信息傳遞給前臺監控器,實現實時傳遞。第二個是,當前臺監控器收到日誌信息後,如何實時顯示。總結起來,就是一個「實時」的問題:實時傳遞和顯示日誌信息。app
對於如何將後臺日誌信息實時傳遞到前臺進行監控顯示,咱們採用了自定義事件機制,經過事件觸發機制,監控日誌內容的變動。思路是這樣的,在LogMonitor類中,用StringBuilder實例化一個變量logs,用來存儲日誌信息,經過addLog和clearLogs方法來添加和刪除日誌信息,並在這兩個方法體內監控日誌信息的變動,當日志信息發生變動時,觸發事件變動事件,最後在此事件內實時刷新前臺監控區域。ide
/** * Description:日誌信息事件<br> * Copyright: Copyright (c) 2015<br> * Company: 河南電力科學研究院智能電網所<br> * * @author shangbingbing 2015-01-01編寫 * @version 1.0 */ public class LogChangedEvent extends java.util.EventObject { private static final long serialVersionUID = 7573194493258326711L; public LogChangedEvent(Object source) { super(source); } }
/** * Description:日誌信息變動監聽器<br> * Copyright: Copyright (c) 2015<br> * Company: 河南電力科學研究院智能電網所<br> * * @author shangbingbing 2015-01-01編寫 * @version 1.0 */ public class LogChangedListener implements java.util.EventListener { public void EventActivated(LogChangedEvent me) { } }
/** * Description:日誌信息監聽器類<br> * Copyright: Copyright (c) 2015<br> * Company: 河南電力科學研究院智能電網所<br> * @author shangbingbing 2015-01-01編寫 * @version 1.0 */ public class LogMonitor implements Serializable { private static final long serialVersionUID = 1L; private static StringBuilder logs = new StringBuilder(); /** * 獲取日誌信息 * @return */ public static StringBuilder getLogs() { return logs; } /** * 新增日誌信息 * @param log */ public static void addLog(String log) { if(StringUtils.isBlank(log)) { logs.append("\r\n"); } else { log = String.format("%s %s\r\n", new Date().toString(), log); logs.append(log); } activateLogChangedEvent(); } /** * 清除日誌信息 */ public static void clearLogs() { logs = new StringBuilder(); activateLogChangedEvent(); } private static Vector<LogChangedListener> vectorListeners = new Vector<LogChangedListener>(); public static synchronized void addLogChangedListener(LogChangedListener listener) { vectorListeners.addElement(listener); } public static synchronized void removeLogChangedListener(LogChangedListener listener) { vectorListeners.removeElement(listener); } public static void activateLogChangedEvent() { Vector<LogChangedListener> tempVector = null; LogChangedEvent e = new LogChangedEvent(LogMonitor.class); synchronized(LogMonitor.class) { tempVector = (Vector<LogChangedListener>)vectorListeners.clone(); for(int i=0;i<tempVector.size();i++) { LogChangedListener listener = tempVector.elementAt(i); listener.EventActivated(e); } } } }
import javax.swing.JDialog; import javax.swing.UIManager; import javax.swing.GroupLayout; import javax.swing.GroupLayout.Alignment; import javax.swing.JScrollPane; import javax.swing.JTextArea; /** * Description:日誌信息監聽窗口<br> * Copyright: Copyright (c) 2015<br> * Company: 河南電力科學研究院智能電網所<br> * @author shangbingbing 2015-01-01編寫 * @version 1.0 */ public class DialogLogMonitor extends JDialog { private static final long serialVersionUID = 1L; private JTextArea txtLogInfo; public static void main(String[] args) { try { //設置系統觀感器 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); DialogLogMonitor dialog = new DialogLogMonitor(); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } /** * 日誌信息變動監聽處理(關鍵點) */ private void init() { LogMonitor.addLogChangedListener(new LogChangedListener() { @Override public void EventActivated(LogChangedEvent me) { txtLogInfo.setText(LogMonitor.getLogs().toString()); txtLogInfo.setCaretPosition(txtLogInfo.getText().length()); txtLogInfo.paintImmediately(txtLogInfo.getBounds()); } }); } public DialogLogMonitor() { setResizable(false); setTitle("\u540E\u53F0\u65E5\u5FD7\u76D1\u63A7\u5668"); setBounds(100, 100, 439, 274); JScrollPane scrollPane = new JScrollPane(); GroupLayout groupLayout = new GroupLayout(getContentPane()); groupLayout.setHorizontalGroup( groupLayout.createParallelGroup(Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane) .addContainerGap()) ); groupLayout.setVerticalGroup( groupLayout.createParallelGroup(Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 230, Short.MAX_VALUE) .addContainerGap()) ); txtLogInfo = new JTextArea(); txtLogInfo.setEditable(false); txtLogInfo.setLineWrap(true); scrollPane.setViewportView(txtLogInfo); getContentPane().setLayout(groupLayout); this.init(); } }
咱們設計了一個後臺日誌模擬生成窗口,來測試日誌信息的監控效果。窗口源代碼以下:測試
import javax.swing.JDialog; import javax.swing.UIManager; import javax.swing.GroupLayout; import javax.swing.GroupLayout.Alignment; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JLabel; import javax.swing.LayoutStyle.ComponentPlacement; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; /** * Description:後臺日誌信息模擬生成窗口<br> * Copyright: Copyright (c) 2015<br> * Company: 河南電力科學研究院智能電網所<br> * @author shangbingbing 2015-01-01編寫 * @version 1.0 */ public class DialogLogGenerator extends JDialog { private static final long serialVersionUID = 1L; private JTextArea txtLogInfo; public static void main(String[] args) { try { //設置系統觀感器 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); DialogLogGenerator dialog = new DialogLogGenerator(); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setVisible(true); DialogLogMonitor dialogLogMonitor = new DialogLogMonitor(); dialogLogMonitor.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialogLogMonitor.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } private void generatorLog() { LogMonitor.addLog(this.txtLogInfo.getText()); this.txtLogInfo.setText(""); } public DialogLogGenerator() { setResizable(false); setTitle("\u540E\u53F0\u65E5\u5FD7\u6A21\u62DF\u751F\u6210\u6D4B\u8BD5\u7A97\u53E3"); setBounds(100, 100, 439, 278); JLabel lblNewLabel = new JLabel("\u8BF7\u8F93\u5165\u6A21\u62DF\u65E5\u5FD7\u4FE1\u606F\uFF1A"); JScrollPane scrollPane = new JScrollPane(); JButton btnCreateLog = new JButton("\u4F20\u9012\u6A21\u62DF\u65E5\u5FD7"); btnCreateLog.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { generatorLog(); } }); GroupLayout groupLayout = new GroupLayout(getContentPane()); groupLayout.setHorizontalGroup( groupLayout.createParallelGroup(Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addContainerGap() .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE) .addContainerGap()) .addGroup(groupLayout.createSequentialGroup() .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) .addComponent(btnCreateLog, GroupLayout.PREFERRED_SIZE, 131, GroupLayout.PREFERRED_SIZE) .addComponent(lblNewLabel, GroupLayout.PREFERRED_SIZE, 170, GroupLayout.PREFERRED_SIZE)) .addGap(253)))) ); groupLayout.setVerticalGroup( groupLayout.createParallelGroup(Alignment.LEADING) .addGroup(groupLayout.createSequentialGroup() .addGap(18) .addComponent(lblNewLabel) .addPreferredGap(ComponentPlacement.UNRELATED) .addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 131, GroupLayout.PREFERRED_SIZE) .addGap(18) .addComponent(btnCreateLog, GroupLayout.PREFERRED_SIZE, 41, GroupLayout.PREFERRED_SIZE) .addContainerGap(17, Short.MAX_VALUE)) ); txtLogInfo = new JTextArea(); scrollPane.setViewportView(txtLogInfo); getContentPane().setLayout(groupLayout); } }
啓動運行DialogLogGenerator窗口,會同時顯示DialogLogMonitor窗口,在日誌模擬窗口輸入一些日誌信息,而後點擊「傳遞模擬日誌」按鈕,你將能夠在DialogLogMonitor監控區域看到模擬的日誌信息。運行效果圖以下所示:ui
運行程序打包下載 hnepri-log-monitor.jarthis
做者:商兵兵spa
單位:河南省電力科學研究院智能電網所設計
QQ:52190634日誌