前回はとりあえず表示は行ったものの、キャレットの位置が変なところにいったり、スクロールバーがなかったりだったが今回追加した。キャレットの位置はキャレット用のクラスを作り、そこで制御している。そのため、1行に表示する文字数を指定する必要がある。またスクロールバーは今のところテスト用のクラスであるMainクラスでJScrollPaneを使っているだけである。以下ソース、まずはCaretクラスから
public class Caret{ private int row; private int column; private int width; private boolean isHigh; public Caret(int width){ row = 0; column = 0; this.width = width; isHigh = true; } public void nextRow(){ row++; } public void beforeRow(){ if(row > 0) row--; } public void nextColumn(){ column++; if(column >= width){ column = 0; nextRow(); } } public void beforeColumn(){ column--; if(column < 0){ if(row == 0) column = 0; else column = width - 1; beforeRow(); } } public int getRow(){ return row; } public void setRow(int row){ this.row = row; } public int getColumn(){ return column; } public void setColumn(int column){ this.column = column; isHigh = true; } public boolean isHigh(){ return isHigh; } public void setHigh(boolean isHigh){ isHigh = isHigh; } }
public class BinaryDocument{ private int size; private int capacity; private byte[] contents; public BinaryDocument(){ this(0); } public BinaryDocument(int size){ this.size = size; this.capacity = (size * 13 / 10) + 10; this.contents = new byte[capacity]; } public void set(byte data, int index){ if(index >= capacity) reallocate(index); if(index > size) size = index; contents[index] = data; } public byte get(int index){ if(index >= size) return (byte)0; return contents[index]; } public byte[] gets(int index, int length){ byte[] data = new byte[length]; for(int i = 0; i < length; i++){ data[i] = get(index + i); } return data; } private void reallocate(int newSize){ capacity = (newSize * 13 / 10) + 10; byte[] newContents = new byte[capacity]; for(int i = 0; i < size; i++){ newContents[i] = contents[i]; } contents = newContents; size = newSize; } public int getSize(){ return size; } }
import javax.swing.JComponent; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Point; import java.awt.Dimension; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; public class HexEditor extends JComponent implements KeyListener{ private BinaryDocument document; private Caret caret; private static final String[] DATA_TABLE = new String[]{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; public HexEditor(){ this(new BinaryDocument()); } public HexEditor(BinaryDocument document){ this.document = document; caret = new Caret(16); int requireColumn = (document.getSize() / 16) + 10; setPreferredSize(new Dimension(16 * 26 + 8, requireColumn * 20)); setFocusable(true); addKeyListener(this); } public void paintComponent(Graphics g){ g.setFont(new Font("Monospaced", Font.PLAIN, 16)); g.setColor(Color.BLACK); int row = 128; int column = 16; for(int y = 0; y < row; y++){ for(int x = 0; x < column; x++){ int index = (y * column) + x; byte data = document.get(index); byte high = (byte)((data >> 4) & 0x0F); byte low = (byte)(data & 0x0F); g.drawString(DATA_TABLE[high], x * 26 + 8, (y + 1) * 20); g.drawString(DATA_TABLE[low], (x * 26) + 8 + 8, (y + 1) * 20); } } g.setColor(new Color(0x6080CCFF, true)); g.fillRect(caret.getColumn() * 26 + 6, caret.getRow() * 20 + 4, 22, 20); } public void keyPressed(KeyEvent e){ switch(e.getKeyCode()){ case KeyEvent.VK_UP: caret.beforeRow(); break; case KeyEvent.VK_DOWN: caret.nextRow(); break; case KeyEvent.VK_LEFT: caret.beforeColumn(); break; case KeyEvent.VK_RIGHT: caret.nextColumn(); break; default: break; } repaint(); } public void keyTyped(KeyEvent e){} public void keyReleased(KeyEvent e){} }
import javax.swing.JFrame; import javax.swing.JScrollPane; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.IOException; public class Main{ public static void main(String[] args) throws IOException{ BinaryDocument document = new BinaryDocument(10); int index = 0; int n; byte[] data = new byte[1024]; BufferedInputStream in = new BufferedInputStream(new FileInputStream("./Main.java")); while((n = in.read(data, 0, 1024)) > 0){ for(int i = 0; i < n; i++){ document.set(data[i], index++); } } HexEditor editor = new HexEditor(document); JFrame frame = new JFrame(); frame.add(new JScrollPane(editor)); frame.setSize(600, 500); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }