📄 hexviewer.java
字号:
/*** $Id: HexViewer.java,v 1.3 2001/05/07 12:37:22 kunugi Exp $**** Copyright (c) 2000-2001 Jeff Gay** on behalf of ICEMail.org <http://www.icemail.org>** Copyright (c) 1998-2000 by Timothy Gerard Endres** ** This program is free software.** ** You may redistribute it and/or modify it under the terms of the GNU** General Public License as published by the Free Software Foundation.** Version 2 of the license should be included with this distribution in** the file LICENSE, as well as License.html. If the license is not** included with this distribution, you may find a copy at the FSF web** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.**** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR** REDISTRIBUTION OF THIS SOFTWARE. ** */package org.icemail.mail;import java.awt.Color;import java.awt.Cursor;import java.awt.Dimension;import java.awt.Font;import java.awt.FontMetrics;import java.awt.Frame;import java.awt.Graphics;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.io.InputStream;import java.io.IOException;import java.util.Vector;import java.text.FieldPosition;import javax.activation.CommandObject;import javax.activation.DataHandler;import javax.swing.JComponent;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollBar;import javax.swing.JTextField;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;import javax.swing.border.EmptyBorder;import org.icemail.util.AWTUtilities;import org.icemail.text.HexNumberFormat;/** * Class ImageViewer implements a CommandObject for the Java Activation Framework. * HexViewer displays the bytes of a data stream in a readable form. * <p> * The only verb supported is "view", converting the contents into a series of hex * words laid out onto a JPanel for display. */public class HexViewer extends JComponent implements CommandObject{ private static final int BLOCKSIZE = 256; private static final int HEXBYTES = 16; private static final int HEXLINES = 16; private static final int PAGEINCR = 8; private boolean hitEOF = false; private int dataLength; private InputStream dataStream = null; private int currentBlkIdx; private Vector blockCache = new Vector(); private HexNumberFormat hexFmt; private HexCanvas hexCanvas; private JScrollBar scrollBar; private JTextField blkHexField; private JTextField blkDecField; private JTextField offHexField; private JTextField offDecField; private Cursor saveCursor = null; /** * Construct an empty viewer, which can be loaded later. */ public HexViewer() { super(); setDoubleBuffered( true ); establishContents(); } public void finalize() { checkClose(); } /** * Initialize the command object from the data handler as described by the verb. * <p> * Implements CommandObject.setCommandContext(). * <p> * @param verb the command from the activation framework * @param dh the datahandler containing the data contents and type * @see javax.activation.CommandObject */ public void setCommandContext( String verb, DataHandler dh ) throws IOException { if ( verb == null || dh == null ) throw new IOException( "Invalid parameters to HexViewer.setCommandContext()" ); if ( ! verb.equalsIgnoreCase( "view" ) ) throw new IOException( "Only 'view' accepted to HexViewer.setCommandContext()" ); InputStream content = dh.getInputStream(); this.dataStream = content; this.dataLength = -1; adjustScroller(); if ( content != null ) { setCurrentBlock( 0 ); } invalidate(); validate(); content.close(); } private void checkClose() { if ( this.dataStream != null ) { try { this.dataStream.close(); } catch ( IOException ex ) { } this.dataStream = null; } } private void adjustScroller() { if ( this.dataLength < 0 ) { this.scrollBar.setMaximum( HexViewer.PAGEINCR ); } else { this.scrollBar.setMaximum( (this.dataLength + (HexViewer.BLOCKSIZE - 1)) / HexViewer.BLOCKSIZE ); } } private void setCurrentBlock( int offset ) { setWaitCursor(); int blkNum = offset / HexViewer.BLOCKSIZE; if ( blkNum >= this.blockCache.size() ) { try { if ( readBlock( blkNum ) == -1 ) { checkClose(); this.hitEOF = true; blkNum = this.blockCache.size() - 1; this.scrollBar.setValue( blkNum ); this.scrollBar.setMaximum( blkNum + 1 ); } } catch ( IOException ex ) { ex.printStackTrace( System.err ); blkNum = this.blockCache.size() - 1; } } this.currentBlkIdx = blkNum; if ( this.currentBlkIdx < this.blockCache.size() ) { byte[] dispData = (byte[])this.blockCache.elementAt( blkNum ); if ( this.hitEOF && this.dataLength >= 0 && this.currentBlkIdx == (this.blockCache.size() - 1) ) { int rem = this.dataLength - (this.currentBlkIdx * HexViewer.BLOCKSIZE); if ( rem != HexViewer.BLOCKSIZE ) { byte[] remData = new byte[ rem ]; System.arraycopy( dispData, 0, remData, 0, rem ); dispData = remData; } } this.hexCanvas.displayData( dispData ); } else { this.hexCanvas.displayEOF(); } if ( this.dataLength < 0 ) { if ( this.currentBlkIdx > ( this.scrollBar.getMaximum() - HexViewer.PAGEINCR ) ) { this.scrollBar.setMaximum( this.currentBlkIdx + HexViewer.PAGEINCR ); } } int hexVal = this.currentBlkIdx; String fldStr = this.hexFmt.format(hexVal); this.blkHexField.setText( fldStr ); fldStr = "" + hexVal; this.blkDecField.setText( fldStr ); hexVal = (this.currentBlkIdx * HexViewer.BLOCKSIZE); fldStr = this.hexFmt.format(hexVal); this.offHexField.setText( fldStr ); fldStr = "" + hexVal; this.offDecField.setText( fldStr ); this.scrollBar.setValue( this.currentBlkIdx ); setWaitCursor(); } private int readBlock( int blkNum ) throws IOException { int result = 0; int curBlk = this.blockCache.size(); for ( ; curBlk <= blkNum ; ++curBlk ) { byte[] buf = new byte[ HexViewer.BLOCKSIZE ]; int off = 0; int need = buf.length; for ( ; need > 0 ; ) { int numRead = this.dataStream.read( buf, off, need ); if ( numRead < 0 ) { result = -1; if ( this.dataLength < 0 ) { this.dataLength = (curBlk * HexViewer.BLOCKSIZE) + off; } break; } off += numRead; need -= numRead; } if ( off > 0 ) this.blockCache.addElement( buf ); } return result; } private void establishContents() { int row = 0; setLayout( new GridBagLayout() ); this.hexFmt = new HexNumberFormat( "XXXXXXXX" ); JPanel ctlPanel = new JPanel(); ctlPanel.setLayout( new GridBagLayout() ); ctlPanel.setBorder( new EmptyBorder( 2, 2, 2, 2 ) ); AWTUtilities.constrain( this, ctlPanel, GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER, 0, row++, 1, 1, 1.0, 0.0 ); int ctlRow = 0; int ctlCol = 0; JLabel label = new JLabel( "Block:" ); label.setHorizontalAlignment( JLabel.RIGHT );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -