简介

对于 经常使用 printf or cout 的人来说 如果有这个日志系统的话,对于每次程序中的发生的错误可以了如职掌。 没必要 每次遇到问题 了解大致的逻辑然后 添加打印。后面章节中还提到一些技巧jconsole 的使用之类的。

java 日志代码

package cn;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.StreamHandler;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class LoggingImageViewer {
	public static void main(String[] args){
		if(System.getProperty("java.util.logging.config.class") == null && System.getProperty("java.util.logging.config.file") == null){
			try{
				Logger.getLogger("com.horstmann.corejava").setLevel(Level.ALL);
				final int LOG_ROTATION_COUNT = 10;
				Handler handler = new FileHandler("%h/LoggingImageViewer.log", 0, LOG_ROTATION_COUNT);
				Logger.getLogger("com.horstmann.corejava").addHandler(handler);
			}
			catch (IOException e){
				Logger.getLogger("com.horstmann.corejava").log(Level.SEVERE, "Can't create log file handler", e);
			}
		}
		EventQueue.invokeLater(()->{
			Handler windowHandler = new WindowHandler();
			windowHandler.setLevel(Level.ALL);
			Logger.getLogger("com.horstmann.corejava").addHandler(windowHandler);
			
			JFrame frame = new ImageViewerFrame();
			frame.setTitle("LoggingImageViewer");
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			
			Logger.getLogger("com.horstmann.corejava").fine("Showing frame");
			frame.setVisible(true);
		});
	}
	
	
}

class ImageViewerFrame extends JFrame{
	private static final int DEFAULT_WIDTH = 300;
	private static final int DEFAULT_HEIGHT = 400;
	private JLabel label;
	private static Logger logger = Logger.getLogger("com.horstmann.corejava");
	
	public ImageViewerFrame(){
		logger.entering("ImageViewerFrame", "<int>");
		setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		
		// set up menu bar
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		JMenu menu = new JMenu("File");
		menuBar.add(menu);
		
		JMenuItem openItem = new JMenuItem("Open");
		menu.add(openItem);
		
		openItem.addActionListener(new FileOpenListener());
		
		JMenuItem exitItem = new JMenuItem("Exit");
		menu.add(exitItem);
		exitItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){
				logger.fine("Exiting.");
				System.exit(0);
			}
		});
		
		// use a label to display the images
		label = new JLabel();
		add(label);
		logger.exiting("ImageViewerFrame", "<int>");
	}
	
	private class FileOpenListener implements ActionListener{
		public void actionPerformed(ActionEvent event){
			logger.entering("ImageViewerFrame.FileOpenListener", "actionPerformed", event);
			
			// set up file chooser
			JFileChooser chooser = new JFileChooser();
			chooser.setCurrentDirectory(new File("."));
			
			chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){
				public boolean accept(File f){
					return f.getName().toLowerCase().endsWith(".gif") || f.isDirectory();
				}
				
				public String getDescription(){
					return "GIF Images";
				}
			});
			
			// show file chooser dialog
			int r = chooser.showOpenDialog(ImageViewerFrame.this);
			
			// if image file accepted, set it as icon of the label
			if(r == JFileChooser.APPROVE_OPTION){
				String name = chooser.getSelectedFile().getPath();
				logger.log(Level.FINE, "Reading file {0}", name);
				label.setIcon(new ImageIcon(name));
			}
			else logger.fine("File open dialog canceled.");
			logger.exiting("ImageViewerFrame.FileOpenListener", "actionPerformed");
		}
	}
}

class WindowHandler extends StreamHandler{
	private JFrame frame;
	
	public WindowHandler(){
		frame = new JFrame();
		final JTextArea output = new JTextArea();
		output.setEditable(false);
		frame.setSize(200, 200);
		frame.add(new JScrollPane(output));
		frame.setFocusableWindowState(false);
		frame.setVisible(true);
		setOutputStream(new OutputStream(){
			public void write(int b){}
			
			public void write(byte[] b, int off, int len){
				output.append(new String(b, off, len));
			}
		});
	}
	public void publish(LogRecord record){
		if(!frame.isVisible()) return;
		super.publish(record);
		flush();
	}
}

Q&A

Q: 为什么要重写 publish 函数

publish 函数是因为数据流有缓冲区,当有数据过来的时候直接输出,而不是将其缓冲起来等待一定的时间再输出
public void publish(LogRecord record){
if(!frame.isVisible()) return;
super.publish(record);
flush();
}

Q: "%h/LoggingImageViewer.log" 是什么意思

%h 表示在用户主目录 user.home 在windows 中是 C:\Users\lee 目录下面 生成文件 LoggingImageViewer.log.0
Logger.getLogger("com.horstmann.corejava").addHandler(handler); // logger 都是要在某个处理器下工作的。

简单介绍 ImageViewerFrame 类的功能

就是现实图片,但是异常处理主要通过另外一个类来实现 FileOpenListener 。所有的关于读取文件的异常通过这个文件的接口实现。

posted on 2020-08-30 19:50  HDU李少帅  阅读(217)  评论(0编辑  收藏  举报