选用教材:《Java核心技术卷一》
第七章 异常、断言和日志
一、日志的8个级别
1、按照优先级顺序,分别为:SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST、ALL。
2、默认情况下,系统只会记录前三个级别。
3、当你将级别更改至INFO之后的某个等级时,系统会记录该等级及以上的日志记录。
二、日志记录的全过程
1、日志记录器将记录一层层发送给处理器:
日志记录器→处理器→父处理器→祖先处理器
2、日志记录器或处理器中可以安装若干个过滤器;
3、处理器中还可以安装若干个格式化器。
三、一道日志例题
将日志记录消息显示在一个日志窗口,代码如下:
package logging; import java.awt.EventQueue; import java.awt.event.*; import java.io.*; import java.util.logging.*; import javax.swing.*; 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); //将日志记录器设置为ALL级别 final int LOG_ROTATION_COUNT=10; var 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(()-> { var windowHandler=new WindowHandler(); windowHandler.setLevel(Level.ALL); Logger.getLogger("com.horstmann.corejava").addHandler(windowHandler); var 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","<init>"); setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); var menuBar=new JMenuBar(); setJMenuBar(menuBar); var menu=new JMenu("File"); menuBar.add(menu); var openItem=new JMenuItem("Open"); menu.add(openItem); openItem.addActionListener(new FileOpenListener()); var exitItem=new JMenuItem("Exit"); menu.add(exitItem); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { logger.fine("Exiting."); System.exit(0); } }); label=new JLabel(); add(label); logger.exiting("ImageViewerFrame", "<init>"); } private class FileOpenListener implements ActionListener { public void actionPerformed(ActionEvent event) { logger.entering("ImageViewerFrame.FileOpenListener","actionPerformed",event); var chooser=new JFileChooser(); chooser.setCurrentDirectory(new File(".")); chooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { return f.getName().toLowerCase().endsWith(".jpg") || f.isDirectory(); } public String getDescription() { return "JPG Images"; } }); int r=chooser.showOpenDialog(ImageViewerFrame.this); 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(); var 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(); //覆盖publish方法,以便在处理器获得每条记录之后刷新缓冲区。 } }
程序倒是能跑起来,就是不能将图片信息显示在窗口。
原文:https://www.cnblogs.com/yizhinailu/p/12636274.html