前回までは表示しかしてなかったので、今回は編集できるようにしてみた。そして、今までスクリーンショットを載せてなかったことに気づいたので、載せておく
それで編集機能を加えるにあたって修正したのはCaretクラスとHexEditorクラス。今の方法だと、キャレットは同じ位置にあっても、上位4bitを修正するか下位4bitを修正するかにわかれる。そのための状態を表す変数は持っていたのだが、状態の切り替えをうまくできていなかった。キャレットの移動時には上位4bit修正するモードにしようと思っていたのだが、Caretクラスの移動に関わるいくつかのメソッドでモードの切り替えが行われていなかった。なので修正した。あとHexEditorは、押されたキーが0〜9またはA〜FならBinaryDocumentに変更を加えるようにした。以下ソース。
まずはCaretクラス
package hexedit.caret; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Color; public class Caret{ private int row; private int column; private int width; private boolean isHigh; private Highlighter highlighter; public Caret(int width){ row = 0; column = 0; this.width = width; isHigh = true; highlighter = new DefaultHighlighter(); highlighter.setBackgroundColor(new Color(0x60ffCC80, true)); highlighter.setRoundColor(new Color(0x60ffCC80, true)); } public void nextRow(){ row++; isHigh = true; } public void beforeRow(){ if(row > 0) row--; isHigh = true; } public void nextColumn(){ column++; if(column >= width){ column = 0; nextRow(); } isHigh = true; } public void beforeColumn(){ column--; if(column < 0){ if(row == 0) column = 0; else column = width - 1; beforeRow(); } isHigh = true; } public int getRow(){ return row; } public void setRow(int row){ this.row = row; isHigh = true; } 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){ this.isHigh = isHigh; } public void setBackgroundColor(Color color){ highlighter.setBackgroundColor(color); } public void setRoundColor(Color color){ highlighter.setRoundColor(color); } public void draw(Graphics g, Rectangle rect){ highlighter.draw(g, rect); } }
次にHexEditorクラス
package hexedit.editor; 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.Rectangle; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import hexedit.document.BinaryDocument; import hexedit.caret.Caret; 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); } } Rectangle caretRectangle = new Rectangle(caret.getColumn() * 26 + 6, caret.getRow() * 20 + 4, 22, 20); caret.draw(g, caretRectangle); } public void setCaretBackground(Color color){ caret.setBackgroundColor(color); } public void setCaretRoundColor(Color color){ caret.setRoundColor(color); } 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; } char c = e.getKeyChar(); int index = caret.getRow() * 16 + caret.getColumn(); if(c >= '0' && c <= '9'){ byte data = document.get(index); if(caret.isHigh()){ byte high = (byte)((c - '0') << 4); data = (byte)(high + (byte)(data & 0x0F)); caret.setHigh(false); }else{ byte low = (byte)((c - '0') & 0x0F); data = (byte)((byte)(data & 0xF0) + low); caret.nextColumn(); } document.set(data, index); } if(c >= 'a' && c <= 'f'){ byte data = document.get(index); if(caret.isHigh()){ byte high = (byte)((c - 'a' + 10) << 4); data = (byte)(high + (byte)(data & 0x0F)); caret.setHigh(false); }else{ byte low = (byte)((c - 'a' + 10) & 0x0F); data = (byte)((byte)(data & 0xF0) + low); caret.nextColumn(); } document.set(data, index); } if(c >= 'A' && c <= 'F'){ byte data = document.get(index); if(caret.isHigh()){ byte high = (byte)((c - 'A' + 10) << 4); data = (byte)(high + (byte)(data & 0x0F)); caret.setHigh(false); }else{ byte low = (byte)((c - 'A' + 10) & 0x0F); data = (byte)((byte)(data & 0xF0) + low); caret.nextColumn(); } document.set(data, index); } repaint(); } public void keyTyped(KeyEvent e){} public void keyReleased(KeyEvent e){} }