Subtrees hinzugefügt

This commit is contained in:
Thomas Schaller 2024-12-29 13:43:45 +01:00
parent 6e9f2223d2
commit a6d1e09ddb
15 changed files with 2338 additions and 0 deletions

View file

@ -0,0 +1,5 @@
*.class
*.ctxt
*.sh
repo.adoc
*.~lock

Binary file not shown.

View file

@ -0,0 +1,354 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import java.io.*;
/**
*
* Beschreibung
*
* @version 1.0 vom 6.12.2009
* @author
*/
public class BMPHexEditor extends JFrame {
// Anfang Attribute
private JMenuBar mb = new JMenuBar();
private JMenu fileMenu = new JMenu("Datei");
private JMenu editMenu = new JMenu("Bearbeiten");
private JMenu viewMenu = new JMenu("Ansicht");
private JMenu bildMenu = new JMenu("Zoom");
private JMenu infoMenu = new JMenu("Info");
private static JFileChooser dateiauswahldialog = new JFileChooser(System.getProperty("user.dir"));
private Edit eingabe = new Edit(this);
private JScrollPane scrollPane = new JScrollPane(eingabe);
private Bild bmpBild = new Bild(this);
private JScrollPane bmpscrollPane = new JScrollPane(bmpBild);
private JPanel infoPane = new JPanel();
private JLabel binLabel = new JLabel(" ");
private JLabel hexLabel = new JLabel(" ");
private JLabel ascLabel = new JLabel(" ");
private JLabel infoLabel = new JLabel(" ");
private JLabel binTitle = new JLabel("Binär:");
private JLabel hexTitle = new JLabel("Hexadezimal:");
private JLabel ascTitle = new JLabel("ASCII-Code:");
private JLabel infoTitle = new JLabel("Bedeutung:");
private JPanel titelPane = new JPanel();
private JLabel dateiname = new JLabel("");
private JLabel modus = new JLabel("Überschreibmodus");
private JMenuItem modeAction = new JMenuItem("Einfügemodus wählen");
// Ende Attribute
public BMPHexEditor(String title) {
// Frame-Initialisierung
super(title);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) { System.exit(0); }
});
int frameWidth = 800;
int frameHeight = 500;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
Container cp = getContentPane();
// Anfang Komponenten
setLayout(new BorderLayout());
setJMenuBar(mb);
mb.add(fileMenu);
mb.add(editMenu);
mb.add(viewMenu);
mb.add(bildMenu);
mb.add(infoMenu);
// Create and add simple menu item to one of the drop down menu
JMenuItem newAction = new JMenuItem("Neu");
JMenuItem openAction = new JMenuItem("Öffnen");
JMenuItem saveAction = new JMenuItem("Speichern");
JMenuItem saveasAction = new JMenuItem("Speichern unter");
JMenuItem exitAction = new JMenuItem("Beenden");
JMenuItem searchAction = new JMenuItem("Suchen");
JMenuItem compareAction = new JMenuItem("Dateivergleich");
JMenuItem binAction = new JMenuItem("Binärdarstellung");
JMenuItem hexAction = new JMenuItem("Hexadezimaldarstellung");
JMenuItem ascAction = new JMenuItem("ASCII-Darstellung");
JMenuItem zoom100 = new JMenuItem("Zoom 100%");
JMenuItem zoom200 = new JMenuItem("Zoom 200%");
JMenuItem zoom400 = new JMenuItem("Zoom 400%");
JMenuItem zoom800 = new JMenuItem("Zoom 800%");
JMenuItem zoom1600 = new JMenuItem("Zoom 1600%");
JMenuItem infoAction = new JMenuItem("Info");
fileMenu.add(newAction);
fileMenu.add(openAction);
fileMenu.add(saveAction);
fileMenu.addSeparator();
fileMenu.add(exitAction);
editMenu.add(searchAction);
editMenu.add(compareAction);
editMenu.addSeparator();
editMenu.add(modeAction);
viewMenu.add(binAction);
viewMenu.add(hexAction);
viewMenu.add(ascAction);
bildMenu.add(zoom100);
bildMenu.add(zoom200);
bildMenu.add(zoom400);
bildMenu.add(zoom800);
bildMenu.add(zoom1600);
infoMenu.add(infoAction);
newAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
eingabe.setDatei(new Datei());
dateiname.setText("unbenannt.txt");
pack();
repaint();
}
});
openAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
openFile();
}
});
saveAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
saveFile();
}
});
exitAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { System.exit(0); }
});
searchAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { suchen();}
});
compareAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { vergleiche();}
});
modeAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { changeUeberschreiben();}
});
binAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { eingabe.setMode(1);
scrollPane.getViewport().setView(eingabe);
}
});
hexAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { eingabe.setMode(2);
scrollPane.getViewport().setView(eingabe);
}
});
ascAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { eingabe.setMode(3);
scrollPane.getViewport().setView(eingabe);
}
});
zoom100.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
bmpBild.setZoom(100);
bmpscrollPane.getViewport().setView(bmpBild);
}
});
zoom200.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
bmpBild.setZoom(200);
bmpscrollPane.getViewport().setView(bmpBild);
}
});
zoom400.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
bmpBild.setZoom(400);
bmpscrollPane.getViewport().setView(bmpBild);
}
});
zoom800.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
bmpBild.setZoom(800);
bmpscrollPane.getViewport().setView(bmpBild);
}
});
zoom1600.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
bmpBild.setZoom(1600);
bmpscrollPane.getViewport().setView(bmpBild);
}
});
infoAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
JOptionPane.showMessageDialog(null, "Autor: T. Schaller Version: April 2013", "Information", JOptionPane.INFORMATION_MESSAGE);
}
});
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(600,450));
scrollPane.setBorder(BorderFactory.createEtchedBorder());
cp.add(scrollPane,BorderLayout.CENTER);
bmpscrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
bmpscrollPane.setPreferredSize(new Dimension(200,450));
bmpscrollPane.setBorder(BorderFactory.createEtchedBorder());
cp.add(bmpscrollPane,BorderLayout.LINE_END);
infoPane.setLayout(new BoxLayout(infoPane, BoxLayout.LINE_AXIS));
infoPane.setBorder(BorderFactory.createEmptyBorder(0,5,3,5));
/* infoPane.add(binTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(binLabel);
infoPane.add(Box.createRigidArea(new Dimension(30, 0)));
infoPane.add(hexTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(hexLabel);
infoPane.add(Box.createRigidArea(new Dimension(30, 0)));
infoPane.add(ascTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(ascLabel);
infoPane.add(Box.createRigidArea(new Dimension(30, 0)));
*/ infoPane.add(infoTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(infoLabel);
cp.add(infoPane, BorderLayout.PAGE_END);
titelPane.setLayout(new BoxLayout(titelPane, BoxLayout.LINE_AXIS));
titelPane.setBorder(BorderFactory.createEmptyBorder(3,5,0,5));
titelPane.add(dateiname);
titelPane.add(Box.createHorizontalGlue());
titelPane.add(modus);
cp.add(titelPane, BorderLayout.PAGE_START);
// Ende Komponenten
setResizable(true);
setVisible(true);
pack();
eingabe.requestFocus();
}
// Anfang Methoden
public void showLabels(String bin, String hex, String asc, String info)
{
binLabel.setText(bin);
hexLabel.setText(hex);
ascLabel.setText(asc);
infoLabel.setText(info);
}
public void openFile() {
int ergebnis = dateiauswahldialog.showOpenDialog(this);
if(ergebnis != JFileChooser.APPROVE_OPTION) { // abgebrochen
return;
}
Datei file = new Datei(dateiauswahldialog.getSelectedFile());
eingabe.setDatei(file);
bmpBild.setDatei(file);
dateiname.setText(file.getFileName());
scrollPane.getViewport().setView(eingabe);
bmpscrollPane.getViewport().setView(bmpBild);
repaint();
}
public void saveFile() {
Datei file = eingabe.getDatei();
if (file != null) {
file = eingabe.getDatei();
dateiauswahldialog.setSelectedFile(new File(file.getPathName()));
int ergebnis = dateiauswahldialog.showSaveDialog(this);
if(ergebnis != JFileChooser.APPROVE_OPTION) { // abgebrochen
return;
}
file.saveFile(dateiauswahldialog.getSelectedFile());
dateiname.setText(file.getFileName());
repaint();
}
}
public void fileChanged() {
bmpBild.setDatei(eingabe.getDatei());
repaint();
}
public void posChanged(int x, int y) {
bmpBild.setPos(x,y);
}
public void posClicked(int x, int y) {
eingabe.moveToPos(x,y);
}
public void scrollTo(int x, int y) {
scrollPane.getVerticalScrollBar().setValue(y);
}
public void changeUeberschreiben() {
if (eingabe.getUeberschreiben()==1) {
eingabe.setUeberschreiben(0);
modeAction.setText("Überschreibemodus wählen");
modus.setText("Einfügemodus");
}
else {
eingabe.setUeberschreiben(1);
modeAction.setText("Einfügemodus wählen");
modus.setText("Überschreibemodus");
}
}
public void suchen() {
String s = JOptionPane.showInputDialog("Geben Sie bitte die gesuchten Bytes ein.");
if (s!=null) {
int erg = eingabe.search(s);
if (erg==-1)
JOptionPane.showMessageDialog(this,"Fehler bei der Suche. Es muss eine Datei geöffnet sein und es können immer nur ganze Bytes gesucht werden.");
if (erg==0)
JOptionPane.showMessageDialog(this,"Gesuchte Bytes wurden nicht gefunden.");
if (erg>0)
JOptionPane.showMessageDialog(this,"Gesuchte Bytes wurden "+erg+" mal gefunden.");
}
}
public void vergleiche() {
int ergebnis = dateiauswahldialog.showOpenDialog(this);
if(ergebnis != JFileChooser.APPROVE_OPTION) { // abgebrochen
return;
}
int erg = eingabe.compare(dateiauswahldialog.getSelectedFile());
repaint();
if (erg==-1)
JOptionPane.showMessageDialog(this,"Fehler beim Vergleich. Es muss eine Datei geöffnet sein.");
if (erg==0)
JOptionPane.showMessageDialog(this,"Keine Unterschiede gefunden.");
if (erg>0)
JOptionPane.showMessageDialog(this,""+erg+" Bytes unterscheiden sich.");
}
// Ende Methoden
public static void main(String[] args) {
new BMPHexEditor("BMPHexEditor");
}
}

View file

@ -0,0 +1,43 @@
object HexEditor: TFGUIFormular
Left = 4
Top = 6
BorderIcons = [biSystemMenu, biMinimize]
Caption = 'd:\tom\Informatik\Java\HexEditor\HexEditor.jfm'
ClientHeight = 205
ClientWidth = 392
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'MS Sans Serif'
Font.Style = []
FormStyle = fsMDIChild
OldCreateOrder = True
Position = poDesigned
Visible = True
WindowState = wsMaximized
OnClose = FormClose
OnCloseQuery = FormCloseQuery
OnResize = FormResize
PixelsPerInch = 96
TextHeight = 16
object button1: TButton
Tag = 3
Left = 224
Top = 128
Width = 75
Height = 25
Caption = 'button1'
TabOrder = 0
end
object textArea1: TMemo
Tag = 2
Left = 0
Top = 24
Width = 569
Height = 81
Lines.Strings = (
'textArea1')
TabOrder = 1
end
end

View file

@ -0,0 +1,160 @@
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;
class Bild extends JComponent {
Datei file;
BMPHexEditor parent;
Image image;
int zoom=100;
int posx =2;
int posy =2;
/*
class myKeyListener implements KeyListener
{
public void keyPressed( KeyEvent k )
{
int iHeight = getSize().height;
if (k.getKeyCode()==8) delete(-1);
if (k.getKeyCode()==127) delete(0);
if (k.getKeyCode()==37) movePos(-1);
if (k.getKeyCode()==39) movePos(1);
if (k.getKeyCode()==38) movePos(-proZeile);
if (k.getKeyCode()==40) movePos(proZeile);
if (k.getKeyCode()==33) movePos(-proZeile*(iHeight/hoehe));
if (k.getKeyCode()==34) movePos(proZeile*(iHeight/hoehe));
}
public void keyReleased(KeyEvent k){}
public void keyTyped(KeyEvent k){
// System.out.println( "Typed:"+k.getKeyCode()+"|"+k.getKeyChar() );
switch(modus) {
case 1: {
if (k.getKeyChar()>='0' && k.getKeyChar()<='1') modifyByte(k.getKeyChar());
break;
}
case 2: {
if (k.getKeyChar()>='0' && k.getKeyChar()<='9') modifyByte(k.getKeyChar());
if (k.getKeyChar()>='a' && k.getKeyChar()<='f') modifyByte(k.getKeyChar());
if (k.getKeyChar()>='A' && k.getKeyChar()<='F') modifyByte(k.getKeyChar());
break;
}
default: {
if (k.getKeyCode()!= 127) modifyByte(k.getKeyChar());
}
}
}
} */
class myMouseListener implements MouseListener
{
public void mouseClicked( MouseEvent e )
{
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
setPos((e.getX()-10)*100/zoom+1,(e.getY()-10)*100/zoom+1 );
parent.posClicked(posx, posy);
}
public void mouseReleased(MouseEvent e) {
}
}
public Bild(BMPHexEditor p){
super();
parent = p;
file = null;
image = null;
// addKeyListener(new myKeyListener());
addMouseListener(new myMouseListener());
}
public void paint(Graphics g){
int iWidth = getSize().width;
int iHeight = getSize().height;
if (file != null && image != null) {
g.drawImage(image,10,10, this);
g.drawRect(9,9,image.getWidth(this)+2,image.getHeight(this)+2);
if (posx >=0 && posy >= 0) {
g.setColor(Color.red);
g.fillRect((posx+1)*zoom/100+10,(posy-1)*zoom/100+10,4*zoom/100,zoom/100);
g.fillRect((posx-1)*zoom/100+10,(posy+1)*zoom/100+10,zoom/100,4*zoom/100);
g.fillRect((posx-6)*zoom/100+10,(posy-1)*zoom/100+10,4*zoom/100,zoom/100);
g.fillRect((posx-1)*zoom/100+10,(posy-6)*zoom/100+10,zoom/100,4*zoom/100);
}
}
}
public void setDatei(Datei file) {
this.file = file;
try {
image = ImageIO.read(new ByteArrayInputStream(file.getByteArray()));
image = image.getScaledInstance(image.getWidth(this)*zoom/100,image.getHeight(this)*zoom/100,Image.SCALE_DEFAULT);
} catch (Exception e) {
// TODO Auto-generated catch block
// System.out.println("Bild kann nicht geladen werden oder ist nicht korrekt");
image = null;
}
}
public void setZoom(int z) {
zoom = z;
setDatei(file);
}
public void setPos(int x, int y) {
posx = x;
posy = y;
repaint();
}
public Dimension getPreferredSize()
{
if (file == null || image == null)
{
return new Dimension( 300, 200 );
}
else
{
return new Dimension( image.getWidth(this)+20,image.getHeight(this)+20);
}
}
public Dimension getMinimumSize()
{
return getPreferredSize();
}
public void keyPressed ( KeyEvent e){
}
public void keyReleased ( KeyEvent e ){
}
public boolean isFocusable() {
return true;
}
}

View file

@ -0,0 +1,291 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.*;
import java.io.*;
import java.util.*;
public class Datei {
int ib = 0;
int iLength = 0;
byte buffer[] = new byte[10000000];
byte searchBuffer[] = new byte[10000000];
String dateiname = "";
String pfad= "";
public Datei () {
dateiname = "unbenannt.txt";
}
public Datei (File file) {
try {
FileInputStream inFile = new FileInputStream(file);
//BufferedReader inData = new BufferedReader(new InputStreamReader(inFile));
//if (inData.ready()) {
iLength = inFile.read(buffer);
for (int i=0; i< iLength; i++) searchBuffer[i]=0;
//inData.close();
inFile.close();
dateiname = file.getName();
pfad = file.getAbsolutePath();
//} else {
//System.out.println("Fehler beim Dateiöffnen");
//}
}
catch (Exception ex) {
System.out.println("Fehler beim Dateiöffnen");
}
}
public void saveFile(File file) {
try {
FileOutputStream outFile = new FileOutputStream(file);
//BufferedReader inData = new BufferedReader(new InputStreamReader(inFile));
//if (inData.ready()) {
outFile.write(buffer,0,iLength);
//inData.close();
outFile.close();
dateiname = file.getName();
pfad = file.getAbsolutePath();
//} else {
//System.out.println("Fehler beim Dateiöffnen");
//}
}
catch (Exception ex) {
System.out.println("Fehler beim Dateiöffnen");
}
}
public String getFileName()
{
return dateiname;
}
public String getPathName()
{
return dateiname;
}
public byte[] getByteArray()
{
return buffer;
}
public String getByteBinary(int i)
{
String s = "";
if (i<this.iLength) {
byte c = buffer[i];
s = Integer.toBinaryString(c);
String p = "00000000";
if (s.length()==32) {
s = s.substring(24);
}
s = p.substring(0,8-s.length())+s;
}
return s;
}
public void setByteBinary(int i, String s)
{
if(i<iLength) buffer[i]=(byte) Integer.parseInt(s,2);
}
public String getByteHex(int i)
{
String s = "";
if (i<this.iLength) {
byte c = buffer[i];
s = Integer.toHexString(c);
s = s.toUpperCase();
if (s.length()<2) {
s = "0"+s;
}
if (s.length()==8) {
s = s.substring(6);
}
}
return s;
}
public void setByteHex(int i, String s)
{
if (i<this.iLength) {
buffer[i]=(byte) Integer.parseInt(s,16);
}
}
public String getByteChar(int i)
{
String s="";
if (i<this.iLength) {
int j = (0x000000FF & ((int)buffer[i]));
s = ""+(char) j;
}
return s;
}
public void setByteChar(int i, char c)
{
if (i<this.iLength) {
buffer[i] = (byte) c;
}
}
public byte getByte(int i)
{
if (i<this.iLength) {
return buffer[i];
} else {
return 0;
} // end of if-else
}
public int getUnsignedInt(int i)
{
return (buffer[i] & 0x7F) + (buffer[i] < 0 ? 128 : 0);
}
public int getDWORD(int i)
{
return getUnsignedInt(i)+256*(getUnsignedInt(i+1)+256*(getUnsignedInt(i+2)+256*getUnsignedInt(i+3)));
}
public int getWORD(int i)
{
return getUnsignedInt(i)+256*(getUnsignedInt(i+1));
}
public byte getSearchByte(int i)
{
return searchBuffer[i];
}
public String getBinary()
{
String s = "";
for (int i = 0; i< iLength; i++)
{
s = s + getByteBinary(i);
}
return s;
}
public String getHex()
{
String s = "";
for (int i = 0; i< iLength; i++)
{
s = s + getByteHex(i);
}
return s;
}
public int getLength()
{
return iLength;
}
public void insertByte(int pos) {
for (int i=iLength; i>= pos; i--) buffer[i+1]=buffer[i];
buffer[pos]=0;
iLength++;
}
public void deleteByte(int pos) {
for (int i=pos; i< iLength; i++) buffer[i]=buffer[i+1];
buffer[iLength]=0;
iLength--;
}
public int search(String s, int modus) {
byte searchBytes[] = new byte[50];
int searchLength = 0;
int i, treffer, laenge=0;
for (i=0; i< iLength;i++) searchBuffer[i]=0;
i = 0;
if (modus==1) laenge = 8;
if (modus==2) laenge = 2;
if (modus==3) laenge = 1;
while(s.length() >= laenge) {
if (modus==1) {
searchBytes[i] = (byte) Integer.parseInt(s.substring(0,8),2);
}
if (modus==2) {
searchBytes[i] = (byte) Integer.parseInt(s.substring(0,2),16);
}
if (modus==3) {
searchBytes[i] = (byte) s.charAt(0);
}
if (s.length()>laenge) {
s = s.substring(laenge);
} else s = "";
i++;
}
searchLength = i;
if (s.length()==0) {
treffer=0;
for(int j = 0; j< iLength-searchLength; j++)
{
int gefunden = 1;
for (i = 0; (i < searchLength) && (gefunden==1); i++)
{
if (buffer[j+i]!= searchBytes[i]) gefunden = 0;
}
if (gefunden==1) {
for (i=0; i<searchLength; i++) searchBuffer[j+i] = 1;
treffer++;
}
}
}
else treffer = -1;
return treffer;
}
public int compare (File file) {
int cLength = 0;
byte cbuffer[] = new byte[10000000];
int unterschiede=0;
for (int i=0; i< iLength;i++) searchBuffer[i]=0;
try {
FileInputStream inFile = new FileInputStream(file);
cLength = inFile.read(cbuffer);
inFile.close();
if (iLength < cLength) cLength = iLength;
for (int i=0; i <cLength; i++) {
if (buffer[i] != cbuffer[i]) {
searchBuffer[i] = 1;
unterschiede++;
}
}
}
catch (Exception ex) {
System.out.println("Fehler beim Dateiöffnen");
unterschiede = -1;
}
return unterschiede;
}
}

View file

@ -0,0 +1,520 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
class Edit extends JComponent {
Datei file;
int pos, subpos, modus;
int ueberschreiben=1;
int breite, hoehe, proZeile, luecke, anzahl;
String searchString="";
int searchPos = -1;
BMPHexEditor parent;
class myKeyListener implements KeyListener
{
public void keyPressed( KeyEvent k )
{
int iHeight = getSize().height;
if (k.getKeyCode()==8) delete(-1);
if (k.getKeyCode()==127) delete(0);
if (k.getKeyCode()==37) movePos(-1);
if (k.getKeyCode()==39) movePos(1);
if (k.getKeyCode()==38) movePos(-proZeile);
if (k.getKeyCode()==40) movePos(proZeile);
if (k.getKeyCode()==33) movePos(-proZeile*(iHeight/hoehe));
if (k.getKeyCode()==34) movePos(proZeile*(iHeight/hoehe));
}
public void keyReleased(KeyEvent k){}
public void keyTyped(KeyEvent k){
// System.out.println( "Typed:"+k.getKeyCode()+"|"+k.getKeyChar() );
switch(modus) {
case 1: {
if (k.getKeyChar()>='0' && k.getKeyChar()<='1') modifyByte(k.getKeyChar());
break;
}
case 2: {
if (k.getKeyChar()>='0' && k.getKeyChar()<='9') modifyByte(k.getKeyChar());
if (k.getKeyChar()>='a' && k.getKeyChar()<='f') modifyByte(k.getKeyChar());
if (k.getKeyChar()>='A' && k.getKeyChar()<='F') modifyByte(k.getKeyChar());
break;
}
default: {
if (k.getKeyCode()!= 127) modifyByte(k.getKeyChar());
}
}
}
}
class myMouseListener implements MouseListener
{
public void mouseClicked( MouseEvent m )
{
moveToMousePos(m.getX(),m.getY() );
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
// System.out.println("Test");
}
public void mouseReleased(MouseEvent e) {
}
}
public Edit(BMPHexEditor p){
super();
parent = p;
file = null;
pos = 0;
subpos = 0;
addKeyListener(new myKeyListener());
addMouseListener(new myMouseListener());
modus = 1;
}
public void adjustTextMetrics()
{
int iWidth = getSize().width;
int iHeight = getSize().height;
Graphics g = getGraphics();
g.setFont(new Font("Monospaced",Font.PLAIN,12));
FontMetrics fm = g.getFontMetrics( g.getFont() );
hoehe = fm.getHeight();
switch (modus) {
case 1: breite = fm.stringWidth("01010101")+4; luecke = 4; anzahl = 8;
break;
case 2: breite = fm.stringWidth("FF")+4; luecke = 4; anzahl = 2;
break;
default : breite = fm.stringWidth("F"); luecke = 0; anzahl = 1;
}
proZeile = iWidth / breite;
}
public void paint(Graphics g){
String s;
int iWidth = getSize().width;
int iHeight = getSize().height;
Rectangle r = getVisibleRect();
adjustTextMetrics();
g.setFont(new Font("Monospaced",Font.PLAIN,12));
g.setColor( Color.black );
int zeile, spalte;
if (file != null) {
// BMP-Bild interpretieren
String info;
int bilddaten = file.getDWORD(10);
int bbreite = file.getDWORD(18);
int bhoehe = file.getDWORD(22);
int farbtiefe = file.getWORD(28);
int compression = 0;
int min = 0; int max = -1;
int xx = -1; int yy = -1;
switch (pos) {
case 0: case 1:
info = "Byte 1+2 immer 'BM' zur Kennzeichnung eines BMP-Bildes";
min = 0; max = 1;
break;
case 2: case 3: case 4: case 5:
int i = file.getDWORD(2);
info = "Byte 3-6 Dateigröße: "+i+" Bytes (unsicher)";
min = 2; max = 5;
break;
case 6: case 7: case 8: case 9:
info = "Byte 7-10 reservierte Bytes (keine Bedeutung)";
min = 6; max = 9;
break;
case 10: case 11: case 12: case 13:
info = "Byte 11-14 Bilddaten beginnen bei Byte Nr. "+bilddaten;
min = 10; max = 13;
break;
case 14: case 15: case 16: case 17:
i = file.getDWORD(14);
info = "Byte 15-18 Größe des Headers: "+i+" Byte";
min = 14; max = 17;
break;
case 18: case 19: case 20: case 21:
info = "Byte 19-22 Breite des Bildes: "+bbreite+" Pixel";
min = 18; max = 21;
break;
case 22: case 23: case 24: case 25:
if (bhoehe<0) {
info = "Byte 23-26 Höhe des Bildes: "+(-bhoehe)+" Pixel und Top-Down-Bitmap";
} else {
info = "Byte 23-26 Höhe des Bildes: "+bhoehe+" Pixel und Bottum-Up-Bitmap";
}
min = 22; max = 25;
break;
case 28: case 29:
if (farbtiefe<=8) {
info = "Byte 29+30: Farbtiefe "+farbtiefe+" Bit pro Pixel mit Farbpalette";
}
else {
info = "Byte 29+30: Farbtiefe "+farbtiefe+" Bit pro Pixel ohne Farbpalette";
}
min = 28; max = 29;
break;
case 30: case 31: case 32: case 33:
compression = file.getDWORD(30);
if (compression == 0) {
info = "Byte 31-34: Komprimierung: Die Bilddaten sind unkomprimiert";
}
else {
info = "Byte 31-34: Komprimierung: Die Bilddaten sind RunLength komprimiert";
}
min = 30; max = 33;
break;
case 34: case 35: case 36: case 37:
i = file.getDWORD(34);
info = "Byte 35-38 Größe der Bilddaten: "+i+" Byte (kann auch 0 sein)";
min = 34; max = 37;
break;
case 38: case 39: case 40: case 41:
i = file.getDWORD(38);
info = "Byte 39-42 Horizontale Auflösung "+i+" Pixel pro Meter (meist 0 gesetzt)";
min = 38; max = 41;
break;
case 42: case 43: case 44: case 45:
i = file.getDWORD(42);
info = "Byte 43-46 Vertikale Auflösung "+i+" Pixel pro Meter (meist 0 gesetzt)";
min = 42; max = 45;
break;
case 46: case 47: case 48: case 49:
i = file.getDWORD(38);
info = "Byte 47-50 Anzahl der Farben in der Palette "+i+" (0 = maximale Anzahl)";
min = 46; max = 49;
break;
case 50: case 51: case 52: case 53:
i = file.getDWORD(38);
info = "Byte 51-54 Anzahl der benutzten Farben im Bild "+i+" (0 = alle Farben)";
min = 50; max = 53;
break;
default:
info = "sonstige Daten";
if (pos >= 54 && pos < bilddaten) {
min = max = pos;
min = min -(pos-54) % 4;
max = max + 3-(pos-54) % 4;
info = "Byte "+(pos+1)+" Farbe Nr. "+(pos-54)/4+" der Palette ";
if ((pos-54) % 4==0) {
info = info + " (Blauanteil)";
}
if ((pos-54) % 4==1) {
info = info + " (Grünanteil)";
}
if ((pos-54) % 4==2) {
info = info + " (Rotanteil)";
}
if ((pos-54) % 4==3) {
info = info + " (immer 0)";
}
}
if (pos >= bilddaten) {
min = max = pos;
// immer auf 4 Byte mit Nullen aufgefüllt
int bbreite_angepasst = bbreite*farbtiefe/8+3;
bbreite_angepasst = bbreite_angepasst - bbreite_angepasst % 4;
yy = (pos-bilddaten) / bbreite_angepasst +1;
int pos_in_zeile = ((pos-bilddaten) - (yy-1)*bbreite_angepasst);
xx = pos_in_zeile*8 / farbtiefe +1;
if (bhoehe > 0) {
yy = bhoehe - yy +1;
}
if (farbtiefe == 1) {
info = "Byte "+(pos+1)+" Farbenummer des Pixels an Pos ("+xx+"/"+yy+") und der nächsten 7 Pixel";
}
if (farbtiefe == 2) {
info = "Byte "+(pos+1)+" Farbenummer des Pixels an Pos ("+xx+"/"+yy+") und der nächsten 3 Pixel";
}
if (farbtiefe == 4) {
info = "Byte "+(pos+1)+" Farbnummer des Pixels an Pos ("+xx+"/"+yy+") und des nächsten Pixels";
}
if (farbtiefe == 8) {
info = "Byte "+(pos+1)+" Farbnummer des Pixels an Pos ("+xx+"/"+yy+")";
}
if (farbtiefe > 8) {
info = "Byte "+(pos+1)+" Farbe des Pixels an Pos ("+xx+"/"+yy+")";
if ((pos_in_zeile) % 3==0) {
info = info + " (Blauanteil)";
}
if ((pos_in_zeile) % 3==1) {
info = info + " (Grünanteil)";
}
if ((pos_in_zeile) % 3==2) {
info = info + " (Rotanteil)";
}
min = min -(pos_in_zeile) % 3;
max = max + 2-(pos_in_zeile) % 3;
}
if (xx > bbreite) { // Dummybytes
info = "Byte "+(pos+1)+" keine Bedeutung";
min = max = pos;
}
parent.posChanged(xx,yy);
}
}
int laenge = file.getLength();
zeile = 0;
spalte = 0;
int start = (int)(r.getY() / hoehe) * proZeile;
int ende = ((int) ((r.getY()+r.getHeight()) / hoehe)+1)*proZeile;
zeile = (int) (r.getY() / hoehe);
spalte = 0;
for (int i=start; i<ende && i<laenge; i++){
if (file.getSearchByte(i) == 1) {
g.setColor( Color.red);
g.fillRect((spalte)*breite+luecke/2-1,4+(zeile)*hoehe-1,breite-luecke/2+1,hoehe+2);
g.setColor( Color.black);
}
if (i>=min && i<=max) {
g.setColor( Color.lightGray);
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
g.setColor( Color.black);
}
if (i==pos) {
g.setColor( Color.yellow);
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
if (subpos != 0) {
g.setColor( Color.red);
g.fillRect((spalte)*breite+subpos*(breite-luecke)/anzahl+luecke/2,4+(zeile)*hoehe,(breite-luecke/2)/anzahl-1,hoehe);
}
g.setColor( Color.black);
}
switch (modus) {
case 1: s = file.getByteBinary(i);
break;
case 2: s = file.getByteHex(i);
break;
default : s = file.getByteChar(i);
}
g.drawString(s,(spalte)*breite+luecke/2,hoehe+(zeile)*hoehe);
spalte++;
if (spalte >= proZeile) {
zeile++;
spalte = 0;
}
}
if (pos<ende && pos==laenge) { // Cursor steht hinter dem letzten Zeichen => leeres Rechteck zeichnen
g.setColor( Color.lightGray);
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
g.setColor( Color.black);
}
parent.showLabels(file.getByteBinary(pos), file.getByteHex(pos), file.getByteChar(pos),info);
}
}
public void setDatei(Datei file) {
this.file = file;
pos = 0;
subpos = 0;
}
public Datei getDatei(){
return file;
}
public Dimension getPreferredSize()
{
adjustTextMetrics();
if (file == null)
{
return new Dimension( 300, 200 );
}
else
{
int laenge = file.getLength();
int komponentenhoehe = hoehe+(laenge/proZeile)*hoehe+5;
if (komponentenhoehe < 200) {
komponentenhoehe = 200;
}
return new Dimension( 300, komponentenhoehe);
}
}
public Dimension getMinimumSize()
{
return getPreferredSize();
}
public void setMode( int i) {
modus = i;
subpos = 0;
repaint();
}
public void setUeberschreiben(int i) {
ueberschreiben = i;
}
public int getUeberschreiben() {
return ueberschreiben;
}
public void movePos ( int i ){
if (file!=null) {
subpos = 0;
pos += i;
if (pos < 0) pos = 0;
if (pos > file.getLength()) pos = file.getLength();
repaint();
}
}
public void moveToMousePos(int x, int y) {
if (file!=null) {
pos = (y / hoehe)*proZeile + (x / breite);
subpos = 0;
if (pos < 0) pos = 0;
if (pos > file.getLength()) pos = file.getLength();
repaint();
}
}
public void moveToPos(int x, int y) {
int bilddaten = file.getDWORD(10);
int bbreite = file.getDWORD(18);
int bhoehe = file.getDWORD(22);
int farbtiefe = file.getWORD(28);
if (bhoehe > 0) {
pos = (bhoehe - y)*bbreite +x-1;
}
else {
pos = (y-1)*bbreite + x-1;
}
pos = pos * farbtiefe / 8;
pos += bilddaten;
parent.scrollTo(0, pos / proZeile * hoehe - 100);
repaint();
}
public int compare(File vergleichDatei) {
int gefunden = -1;
if (file!=null)
{
gefunden = file.compare(vergleichDatei);
}
repaint();
return gefunden;
}
public int search(String s) {
int gefunden = -1;
if (file!=null)
{
String s2="";
char b;
for (int i = 0; i < s.length(); i++)
{
b = s.charAt(i);
if (modus==1 && (b == '0' || b == '1')) s2 = s2 + b;
if (modus==2 && ((b >= '0' && b <= '9')|| (b>='A' && b <='F') || (b>='a' && b<='f'))) s2 = s2+b;
if (modus==3) s2 = s2+b;
}
if (modus==2) s2 = s2.toUpperCase();
if (s2.length()>0) gefunden = file.search(s2,modus);
}
repaint();
return gefunden;
}
public void delete( int i) {
if (file != null && pos+i>0 && pos+i<file.getLength()) {
file.deleteByte(pos+i);
subpos = 0;
pos += i;
if (pos > file.getLength()) pos--;
}
repaint();
}
public void modifyByte( char c ) {
String s;
if (file != null) {
if (pos == file.getLength() || (subpos == 0 && !(ueberschreiben==1))) file.insertByte(pos);
switch (modus) {
case 1: s = file.getByteBinary(pos);
break;
case 2: s = file.getByteHex(pos);
break;
default : s = file.getByteChar(pos);
}
s = s.substring(0,subpos)+c+s.substring(subpos+1);
subpos++;
int maxSubpos;
switch (modus) {
case 1: maxSubpos = 7;
file.setByteBinary(pos,s);
break;
case 2: maxSubpos = 1;
file.setByteHex(pos,s);
break;
default : maxSubpos = 0;
file.setByteChar(pos,c);
}
if (subpos > maxSubpos)
{
subpos = 0;
movePos(1);
}
repaint();
parent.fileChanged();
}
}
public void keyPressed ( KeyEvent e){
}
public void keyReleased ( KeyEvent e ){
}
public boolean isFocusable() {
return true;
}
}

View file

@ -0,0 +1,12 @@
= Material : Hexeditor
|===
|Zuordnung| Daten und Codierung
|Klassenstufe| ab Klasse 7
|Bildungsplanbezug | Codierung von Bildern
|Werkzeug| Hexeditor-Quellcodes
|Autoren| Thomas Schaller
|===
== Inhalt
Dieses Programm stellt BMP-Dateien in Form von Bits dar. Es kann genutzt werden, um deutlich zu machen, dass auch Bilder aus Bits bestehen. Beim Anklicken einzelner Pixel werden die dazugehörigen Bits markiert. Werden die Bits verändert, ändert sich das Bild synchron. Im Gegensatz zu üblichen Hexeditoren werden die Daten binär dargestellt (Hexadezimal oder als Text ist aber auch verfügbar.)

View file

@ -0,0 +1,5 @@
*.class
*.ctxt
*.sh
repo.adoc
*.~lock

View file

@ -0,0 +1,274 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.*;
import java.io.*;
import java.util.*;
public class Datei {
int ib = 0;
int iLength = 0;
byte buffer[] = new byte[1000000];
byte searchBuffer[] = new byte[1000000];
String dateiname = "";
String pfad= "";
public Datei () {
dateiname = "unbenannt.txt";
}
public Datei (File file) {
try {
buffer = new byte[(int) file.length()+100000];
searchBuffer = new byte[(int) file.length()+100000];
FileInputStream inFile = new FileInputStream(file);
//BufferedReader inData = new BufferedReader(new InputStreamReader(inFile));
//if (inData.ready()) {
iLength = inFile.read(buffer);
for (int i=0; i< iLength; i++) searchBuffer[i]=0;
//inData.close();
inFile.close();
dateiname = file.getName();
pfad = file.getAbsolutePath();
//} else {
//System.out.println("Fehler beim Dateiöffnen");
//}
}
catch (Exception ex) {
System.out.println("Fehler beim Dateiöffnen");
}
}
public void saveFile(File file) {
try {
FileOutputStream outFile = new FileOutputStream(file);
//BufferedReader inData = new BufferedReader(new InputStreamReader(inFile));
//if (inData.ready()) {
outFile.write(buffer,0,iLength);
//inData.close();
outFile.close();
dateiname = file.getName();
pfad = file.getAbsolutePath();
//} else {
//System.out.println("Fehler beim Dateiöffnen");
//}
}
catch (Exception ex) {
System.out.println("Fehler beim Dateiöffnen");
}
}
public String getFileName()
{
return dateiname;
}
public String getPathName()
{
return dateiname;
}
public String getByteBinary(int i)
{
String s = "";
if (i<this.iLength) {
byte c = buffer[i];
String p = "00000000";
s = Integer.toBinaryString(c);
if (s.length()==32) {
s = s.substring(24);
}
s = p.substring(0,8-s.length())+s;
}
return s;
}
public void setByteBinary(int i, String s)
{
if(i<iLength) buffer[i]=(byte) Integer.parseInt(s,2);
}
public String getByteHex(int i)
{
String s = "";
if (i<this.iLength) {
byte c = buffer[i];
s = Integer.toHexString(c);
s = s.toUpperCase();
if (s.length()<2) {
s = "0"+s;
}
if (s.length()==8) {
s = s.substring(6);
}
}
return s;
}
public void setByteHex(int i, String s)
{
if (i<this.iLength) {
buffer[i]=(byte) Integer.parseInt(s,16);
}
}
public String getByteChar(int i)
{
String s="";
if (i<this.iLength) {
int j = (0x000000FF & ((int)buffer[i]));
s = ""+(char) j;
}
return s;
}
public void setByteChar(int i, char c)
{
if (i<this.iLength) {
buffer[i] = (byte) c;
}
}
public byte getByte(int i)
{
if (i<this.iLength) {
return buffer[i];
} else {
return 0;
} // end of if-else
}
public byte getSearchByte(int i)
{
return searchBuffer[i];
}
public String getBinary()
{
String s = "";
for (int i = 0; i< iLength; i++)
{
s = s + getByteBinary(i);
}
return s;
}
public String getHex()
{
String s = "";
for (int i = 0; i< iLength; i++)
{
s = s + getByteHex(i);
}
return s;
}
public int getLength()
{
return iLength;
}
public void insertByte(int pos) {
for (int i=iLength; i>= pos; i--) buffer[i+1]=buffer[i];
buffer[pos]=0;
iLength++;
}
public void deleteByte(int pos) {
for (int i=pos; i< iLength; i++) buffer[i]=buffer[i+1];
buffer[iLength]=0;
iLength--;
}
public int search(String s, int modus) {
byte searchBytes[] = new byte[50];
int searchLength = 0;
int i, treffer, laenge=0;
for (i=0; i< iLength;i++) searchBuffer[i]=0;
i = 0;
if (modus==1) laenge = 8;
if (modus==2) laenge = 2;
if (modus==3) laenge = 1;
while(s.length() >= laenge) {
if (modus==1) {
searchBytes[i] = (byte) Integer.parseInt(s.substring(0,8),2);
}
if (modus==2) {
searchBytes[i] = (byte) Integer.parseInt(s.substring(0,2),16);
}
if (modus==3) {
searchBytes[i] = (byte) s.charAt(0);
}
if (s.length()>laenge) {
s = s.substring(laenge);
} else s = "";
i++;
}
searchLength = i;
if (s.length()==0) {
treffer=0;
for(int j = 0; j< iLength-searchLength; j++)
{
int gefunden = 1;
for (i = 0; (i < searchLength) && (gefunden==1); i++)
{
if (buffer[j+i]!= searchBytes[i]) gefunden = 0;
}
if (gefunden==1) {
for (i=0; i<searchLength; i++) searchBuffer[j+i] = 1;
treffer++;
}
}
}
else treffer = -1;
return treffer;
}
public int compare (File file) {
int cLength = 0;
byte cbuffer[];
int unterschiede=0;
for (int i=0; i< iLength;i++) searchBuffer[i]=0;
try {
FileInputStream inFile = new FileInputStream(file);
cbuffer = new byte[(int) file.length()];
cLength = inFile.read(cbuffer);
inFile.close();
if (iLength < cLength) cLength = iLength;
for (int i=0; i <cLength; i++) {
if (buffer[i] != cbuffer[i]) {
searchBuffer[i] = 1;
unterschiede++;
}
}
}
catch (Exception ex) {
System.out.println("Fehler beim Dateiöffnen");
unterschiede = -1;
}
return unterschiede;
}
}

View file

@ -0,0 +1,332 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
class Edit extends JComponent {
Datei file;
int pos, subpos, modus;
int ueberschreiben=1;
int breite, hoehe, proZeile, luecke, anzahl;
String searchString="";
int searchPos = -1;
HexEditor parent;
class myKeyListener implements KeyListener
{
public void keyPressed( KeyEvent k )
{
int iHeight = getSize().height;
if (k.getKeyCode()==8) delete(-1);
if (k.getKeyCode()==127) delete(0);
if (k.getKeyCode()==37) movePos(-1);
if (k.getKeyCode()==39) movePos(1);
if (k.getKeyCode()==38) movePos(-proZeile);
if (k.getKeyCode()==40) movePos(proZeile);
if (k.getKeyCode()==33) movePos(-proZeile*(iHeight/hoehe));
if (k.getKeyCode()==34) movePos(proZeile*(iHeight/hoehe));
}
public void keyReleased(KeyEvent k){}
public void keyTyped(KeyEvent k){
switch(modus) {
case 1: {
if (k.getKeyChar()>='0' && k.getKeyChar()<='1') modifyByte(k.getKeyChar());
break;
}
case 2: {
if (k.getKeyChar()>='0' && k.getKeyChar()<='9') modifyByte(k.getKeyChar());
if (k.getKeyChar()>='a' && k.getKeyChar()<='f') modifyByte(k.getKeyChar());
if (k.getKeyChar()>='A' && k.getKeyChar()<='F') modifyByte(k.getKeyChar());
break;
}
default: {
if (k.getKeyCode()!= 127) modifyByte(k.getKeyChar());
}
}
}
}
class myMouseListener implements MouseListener
{
public void mouseClicked( MouseEvent m )
{
moveToMousePos(m.getX(),m.getY() );
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}
public Edit(HexEditor p){
super();
parent = p;
file = null;
pos = 0;
subpos = 0;
addKeyListener(new myKeyListener());
addMouseListener(new myMouseListener());
modus = 1;
}
public void adjustTextMetrics()
{
int iWidth = getSize().width;
int iHeight = getSize().height;
Graphics g = getGraphics();
g.setFont(new Font("Monospaced",Font.PLAIN,12));
FontMetrics fm = g.getFontMetrics( g.getFont() );
hoehe = fm.getHeight();
switch (modus) {
case 1: breite = fm.stringWidth("01010101")+4; luecke = 4; anzahl = 8;
break;
case 2: breite = fm.stringWidth("FF")+4; luecke = 4; anzahl = 2;
break;
default : breite = fm.stringWidth("F"); luecke = 0; anzahl = 1;
}
proZeile = iWidth / breite;
}
public void paint(Graphics g){
String s;
int iWidth = getSize().width;
int iHeight = getSize().height;
Rectangle r = getVisibleRect();
adjustTextMetrics();
g.setFont(new Font("Monospaced",Font.PLAIN,12));
g.setColor( Color.black );
int zeile, spalte;
if (file != null) {
int laenge = file.getLength();
int start = (int)(r.getY() / hoehe) * proZeile;
int ende = ((int) ((r.getY()+r.getHeight()) / hoehe)+1)*proZeile;
zeile = (int) (r.getY() / hoehe);
spalte = 0;
for (int i=start; i<ende && i<laenge; i++){
if (file.getSearchByte(i) == 1) {
g.setColor( Color.red);
g.fillRect((spalte)*breite+luecke/2-1,4+(zeile)*hoehe-1,breite-luecke/2+1,hoehe+2);
g.setColor( Color.black);
}
if (i==pos) {
g.setColor( Color.lightGray);
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
if (subpos != 0) {
g.setColor( Color.GRAY);
g.fillRect((spalte)*breite+subpos*(breite-luecke)/anzahl+luecke/2,4+(zeile)*hoehe,(breite-luecke/2)/anzahl-1,hoehe);
}
g.setColor( Color.black);
}
switch (modus) {
case 1: s = file.getByteBinary(i);
break;
case 2: s = file.getByteHex(i);
break;
default : s = file.getByteChar(i);
}
g.drawString(s,(spalte)*breite+luecke/2,hoehe+(zeile)*hoehe);
spalte++;
if (spalte >= proZeile) {
zeile++;
spalte = 0;
}
}
if (pos<ende && pos==laenge) { // Cursor steht hinter dem letzten Zeichen => leeres Rechteck zeichnen
g.setColor( Color.lightGray);
g.fillRect((spalte)*breite+luecke/2,4+(zeile)*hoehe,breite-luecke/2-1,hoehe);
g.setColor( Color.black);
}
parent.showLabels(file.getByteBinary(pos), file.getByteHex(pos), file.getByteChar(pos), pos+1);
}
}
public void setDatei(Datei file) {
this.file = file;
pos = 0;
subpos = 0;
}
public Datei getDatei(){
return file;
}
public Dimension getPreferredSize()
{
adjustTextMetrics();
if (file == null)
{
return new Dimension( 300, 200 );
}
else
{
int laenge = file.getLength();
int komponentenhoehe = hoehe+(laenge/proZeile)*hoehe+5;
if (komponentenhoehe < 200) {
komponentenhoehe = 200;
}
return new Dimension( 300, komponentenhoehe);
}
}
public Dimension getMinimumSize()
{
return getPreferredSize();
}
public void setMode( int i) {
modus = i;
subpos = 0;
repaint();
}
public void setUeberschreiben(int i) {
ueberschreiben = i;
}
public int getUeberschreiben() {
return ueberschreiben;
}
public void movePos ( int i ){
if (file!=null) {
subpos = 0;
pos += i;
if (pos > file.getLength()) pos = file.getLength();
if (pos < 0) pos = 0;
repaint();
}
}
public void moveToMousePos(int x, int y) {
if(file!=null) {
pos = (y / hoehe)*proZeile + (x / breite);
subpos = 0;
if (pos > file.getLength()) pos = file.getLength();
if (pos < 0) pos = 0;
repaint();
}
}
public int compare(File vergleichDatei) {
int gefunden = -1;
if (file!=null)
{
gefunden = file.compare(vergleichDatei);
}
repaint();
return gefunden;
}
public int search(String s) {
int gefunden = -1;
if (file!=null)
{
String s2="";
char b;
for (int i = 0; i < s.length(); i++)
{
b = s.charAt(i);
if (modus==1 && (b == '0' || b == '1')) s2 = s2 + b;
if (modus==2 && ((b >= '0' && b <= '9')|| (b>='A' && b <='F') || (b>='a' && b<='f'))) s2 = s2+b;
if (modus==3) s2 = s2+b;
}
if (modus==2) s2 = s2.toUpperCase();
if (s2.length()>0) gefunden = file.search(s2,modus);
}
repaint();
return gefunden;
}
public void delete( int i) {
if (file != null && pos+i>0 && pos+i<file.getLength()) {
file.deleteByte(pos+i);
subpos = 0;
pos += i;
if (pos > file.getLength()) pos--;
}
repaint();
}
public void modifyByte( char c ) {
String s;
if (file!= null) {
if (pos == file.getLength() || (subpos == 0 && !(ueberschreiben==1))) file.insertByte(pos);
switch (modus) {
case 1: s = file.getByteBinary(pos);
break;
case 2: s = file.getByteHex(pos);
break;
default : s = file.getByteChar(pos);
}
s = s.substring(0,subpos)+c+s.substring(subpos+1);
subpos++;
int maxSubpos;
switch (modus) {
case 1: maxSubpos = 7;
file.setByteBinary(pos,s);
break;
case 2: maxSubpos = 1;
file.setByteHex(pos,s);
break;
default : maxSubpos = 0;
file.setByteChar(pos,c);
}
if (subpos > maxSubpos)
{
subpos = 0;
movePos(1);
}
repaint();
}
}
public void keyPressed ( KeyEvent e){
}
public void keyReleased ( KeyEvent e ){
}
public boolean isFocusable() {
return true;
}
}

Binary file not shown.

View file

@ -0,0 +1,287 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import java.io.*;
/**
*
* Beschreibung
*
* @version 1.0 vom 6.12.2009
* @author
*/
public class HexEditor extends JFrame {
// Anfang Attribute
private JMenuBar mb = new JMenuBar();
private JMenu fileMenu = new JMenu("Datei");
private JMenu editMenu = new JMenu("Bearbeiten");
private JMenu viewMenu = new JMenu("Ansicht");
private JMenu infoMenu = new JMenu("Info");
private static JFileChooser dateiauswahldialog = new JFileChooser(System.getProperty("user.dir"));
private Edit eingabe = new Edit(this);
private JScrollPane scrollPane = new JScrollPane(eingabe);
private JPanel infoPane = new JPanel();
private JLabel binLabel = new JLabel(" ");
private JLabel hexLabel = new JLabel(" ");
private JLabel ascLabel = new JLabel(" ");
private JLabel posLabel = new JLabel(" ");
private JLabel posTitle = new JLabel("Byte Nr.:");
private JLabel binTitle = new JLabel("Binär:");
private JLabel hexTitle = new JLabel("Hexadezimal:");
private JLabel ascTitle = new JLabel("ASCII-Code:");
private JPanel titelPane = new JPanel();
private JLabel dateiname = new JLabel("");
private JLabel modus = new JLabel("Überschreibmodus");
private JMenuItem modeAction = new JMenuItem("Einfügemodus wählen");
// Ende Attribute
public HexEditor(String title) {
// Frame-Initialisierung
super(title);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) { System.exit(0); }
});
int frameWidth = 800;
int frameHeight = 500;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
Container cp = getContentPane();
// Anfang Komponenten
setLayout(new BorderLayout());
setJMenuBar(mb);
mb.add(fileMenu);
mb.add(editMenu);
mb.add(viewMenu);
mb.add(infoMenu);
// Create and add simple menu item to one of the drop down menu
JMenuItem newAction = new JMenuItem("Neu");
JMenuItem openAction = new JMenuItem("Öffnen");
JMenuItem saveAction = new JMenuItem("Speichern");
JMenuItem saveasAction = new JMenuItem("Speichern unter");
JMenuItem exitAction = new JMenuItem("Beenden");
JMenuItem searchAction = new JMenuItem("Suchen");
JMenuItem compareAction = new JMenuItem("Dateivergleich");
JMenuItem binAction = new JMenuItem("Binärdarstellung");
JMenuItem hexAction = new JMenuItem("Hexadezimaldarstellung");
JMenuItem ascAction = new JMenuItem("ASCII-Darstellung");
JMenuItem infoAction = new JMenuItem("Info");
fileMenu.add(newAction);
fileMenu.add(openAction);
fileMenu.add(saveAction);
fileMenu.addSeparator();
fileMenu.add(exitAction);
editMenu.add(searchAction);
editMenu.add(compareAction);
editMenu.addSeparator();
editMenu.add(modeAction);
viewMenu.add(binAction);
viewMenu.add(hexAction);
viewMenu.add(ascAction);
infoMenu.add(infoAction);
newAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
eingabe.setDatei(new Datei());
dateiname.setText("unbenannt.txt");
pack();
repaint();
}
});
openAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
openFile();
}
});
saveAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
saveFile();
}
});
exitAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { System.exit(0); }
});
searchAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { suchen();}
});
compareAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { vergleiche();}
});
modeAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { changeUeberschreiben();}
});
binAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { eingabe.setMode(1);
scrollPane.getViewport().setView(eingabe);
}
});
hexAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { eingabe.setMode(2);
scrollPane.getViewport().setView(eingabe);
}
});
ascAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) { eingabe.setMode(3);
scrollPane.getViewport().setView(eingabe);
}
});
infoAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
JOptionPane.showMessageDialog(null, "Autor: T. Schaller Version: April 2013", "Information", JOptionPane.INFORMATION_MESSAGE);
}
});
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(800,450));
scrollPane.setBorder(BorderFactory.createEtchedBorder());
cp.add(scrollPane,BorderLayout.CENTER);
infoPane.setLayout(new BoxLayout(infoPane, BoxLayout.LINE_AXIS));
infoPane.setBorder(BorderFactory.createEmptyBorder(0,5,3,5));
infoPane.add(posTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(posLabel);
infoPane.add(Box.createRigidArea(new Dimension(30, 0)));
infoPane.add(binTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(binLabel);
infoPane.add(Box.createRigidArea(new Dimension(30, 0)));
infoPane.add(hexTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(hexLabel);
infoPane.add(Box.createRigidArea(new Dimension(30, 0)));
infoPane.add(ascTitle);
infoPane.add(Box.createRigidArea(new Dimension(3, 0)));
infoPane.add(ascLabel);
cp.add(infoPane, BorderLayout.PAGE_END);
titelPane.setLayout(new BoxLayout(titelPane, BoxLayout.LINE_AXIS));
titelPane.setBorder(BorderFactory.createEmptyBorder(3,5,0,5));
titelPane.add(dateiname);
titelPane.add(Box.createHorizontalGlue());
titelPane.add(modus);
cp.add(titelPane, BorderLayout.PAGE_START);
// Ende Komponenten
setResizable(true);
setVisible(true);
pack();
eingabe.requestFocus();
}
// Anfang Methoden
public void showLabels(String bin, String hex, String asc, int pos)
{
binLabel.setText(bin);
hexLabel.setText(hex);
ascLabel.setText(asc);
posLabel.setText(""+pos);
}
public void openFile() {
int ergebnis = dateiauswahldialog.showOpenDialog(this);
if(ergebnis != JFileChooser.APPROVE_OPTION) { // abgebrochen
return;
}
Datei file = new Datei(dateiauswahldialog.getSelectedFile());
eingabe.setDatei(file);
dateiname.setText(file.getFileName());
scrollPane.getViewport().setView(eingabe);
repaint();
}
public void saveFile() {
Datei file = eingabe.getDatei();
if (file != null) {
file = eingabe.getDatei();
dateiauswahldialog.setSelectedFile(new File(file.getPathName()));
int ergebnis = dateiauswahldialog.showSaveDialog(this);
if(ergebnis != JFileChooser.APPROVE_OPTION) { // abgebrochen
return;
}
file.saveFile(dateiauswahldialog.getSelectedFile());
dateiname.setText(file.getFileName());
repaint();
}
}
public void changeUeberschreiben() {
if (eingabe.getUeberschreiben()==1) {
eingabe.setUeberschreiben(0);
modeAction.setText("Überschreibemodus wählen");
modus.setText("Einfügemodus");
}
else {
eingabe.setUeberschreiben(1);
modeAction.setText("Einfügemodus wählen");
modus.setText("Überschreibemodus");
}
}
public void suchen() {
String s = JOptionPane.showInputDialog("Geben Sie bitte die gesuchten Bytes ein.");
if (s!=null) {
int erg = eingabe.search(s);
if (erg==-1)
JOptionPane.showMessageDialog(this,"Fehler bei der Suche. Es muss eine Datei geöffnet sein und es können immer nur ganze Bytes gesucht werden.");
if (erg==0)
JOptionPane.showMessageDialog(this,"Gesuchte Bytes wurden nicht gefunden.");
if (erg>0)
JOptionPane.showMessageDialog(this,"Gesuchte Bytes wurden "+erg+" mal gefunden.");
}
}
public void vergleiche() {
int ergebnis = dateiauswahldialog.showOpenDialog(this);
if(ergebnis != JFileChooser.APPROVE_OPTION) { // abgebrochen
return;
}
int erg = eingabe.compare(dateiauswahldialog.getSelectedFile());
repaint();
if (erg==-1)
JOptionPane.showMessageDialog(this,"Fehler beim Vergleich. Es muss eine Datei geöffnet sein.");
if (erg==0)
JOptionPane.showMessageDialog(this,"Keine Unterschiede gefunden.");
if (erg>0)
JOptionPane.showMessageDialog(this,""+erg+" Bytes unterscheiden sich.");
}
// Ende Methoden
public static void main(String[] args) {
new HexEditor("HexEditor");
}
}

View file

@ -0,0 +1,43 @@
object HexEditor: TFGUIFormular
Left = 4
Top = 6
BorderIcons = [biSystemMenu, biMinimize]
Caption = 'd:\tom\Informatik\Java\HexEditor\HexEditor.jfm'
ClientHeight = 205
ClientWidth = 392
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'MS Sans Serif'
Font.Style = []
FormStyle = fsMDIChild
OldCreateOrder = True
Position = poDesigned
Visible = True
WindowState = wsMaximized
OnClose = FormClose
OnCloseQuery = FormCloseQuery
OnResize = FormResize
PixelsPerInch = 96
TextHeight = 16
object button1: TButton
Tag = 4
Left = 224
Top = 128
Width = 75
Height = 25
Caption = 'button1'
TabOrder = 0
end
object textArea1: TMemo
Tag = 3
Left = 0
Top = 24
Width = 569
Height = 81
Lines.Strings = (
'textArea1')
TabOrder = 1
end
end

View file

@ -0,0 +1,12 @@
= Material : Hexeditor
|===
|Zuordnung| Daten und Codierung
|Klassenstufe| ab Klasse 7
|Bildungsplanbezug | Codierung von Texten und Bildern
|Werkzeug| Hexeditor-Quellcodes
|Autoren| Thomas Schaller
|===
== Inhalt
Dieses Programm stellt jegliche Datei in Form von Bits dar. Es kann genutzt werden, um deutlich zu machen, dass auch Textdatei oder Bilder aus Bits bestehen. Im Gegensatz zu üblichen Hexeditoren werden die Daten binär dargestellt (Hexadezimal oder als Text ist aber auch verfügbar.)