Swing應用開發實戰系列之五:後臺日誌信息前臺監控器

 

做爲一個程序設計人員,咱們深知日誌的重要性,對於日誌的監控,咱們一般不外乎採用如下兩種方式:日誌文件方式和後臺打印方式,常規狀況下,這兩種日誌監控方式徹底能夠知足咱們對日誌監控的須要。可是,當咱們用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

dailog_log_generator

dialog_log_monitor

 

運行程序打包下載 hnepri-log-monitor.jarthis

 


做者:商兵兵spa

單位:河南省電力科學研究院智能電網所設計

QQ:52190634日誌

主頁:http://www.cnblogs.com/shangbingbingcode

空間:http://shangbingbing.qzone.qq.com

相關文章
相關標籤/搜索