Tony
Tony

Reputation: 3638

Java JTextArea dynamic column and row numbering

I've had a quick Google around, and I can't seem to find a good solution to this, mostly because I'm not sure how to describe it.

Essentially, I need to display an arbitrary amount of hex characters in a JTextArea, and I'd like to have them spaced evenly, and have the positions of the characters shown at the top and left of the characters.

This is an example of what I'd like to achieve, this is the hex viewer WinHex.

enter image description here

I've been playing around with converting a byte array to a String, and then text-wrapping it, but I've had some odd results. Any advice on how to achieve something similar to this would be appreciated.

Another option I've considered is using a JTable, but I'm wondering if that's over complicating the matter slightly. Maybe.

Thanks

Upvotes: 3

Views: 590

Answers (2)

camickr
camickr

Reputation: 324088

I've considered is using a JTable, but I'm wondering if that's over complicating the matter slightly

A decade ago, when I was trying to understand JTable I created myself a simple hex editor to try to understand table models, renderers and editors.

Check out Hex Editor for my result. Just unzip the file and compile all the java files and then execute the Hex class.

I haven't looked at the code in 10 years so I don't know if I followed all best coding practices, but have fun anyway.

Hex Viewer

Upvotes: 5

durron597
durron597

Reputation: 32323

This should get you started, using a very simple implementation of AbstractTableModel. This only took me 15 minutes to write (in response to "overcomplicating the issue").

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class HexText extends JFrame {
  public static void main(String... args) {
    final HexText window = new HexText();

    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        window.setVisible(true);
      }
    });
  }

  private static class HexTableModel extends AbstractTableModel {
    List<Integer> data = new ArrayList<>();

    @Override
    public int getRowCount() {
      return data.size();
    }

    @Override
    public int getColumnCount() {
      return 9;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
      if (columnIndex == 0) {
        return Integer.toHexString(rowIndex << 5);
      } else {
        int row = data.get(rowIndex);
        int theByte = 0xFF & (row >> (columnIndex * 2));
        String output = Integer.toHexString(theByte);
        if (output.length() == 1)
          output = "0" + output;
        return output;
      }
    }

    public void addRow(int rowElement) {
      data.add(rowElement);

      fireTableRowsInserted(data.size() - 1, data.size() - 1);
    }
  }

  public HexText() {
    JPanel contentPane = new JPanel(new BorderLayout());

    HexTableModel theModel = new HexTableModel();

    JTable theTable = new JTable(theModel);

    Random r = new Random();

    for (int i = 0; i < 20; i++) {
      theModel.addRow(r.nextInt());
    }

    contentPane.add(theTable, BorderLayout.CENTER);
    this.add(theTable);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.pack();
  }
}

Screenshot

Upvotes: 4

Related Questions