Question

I need a JTextField to insert hexadecimal bytes. Example: "05 DE DD A9 4D 00 0C 5E" I have tried JFormattedTextField + MaskFormatter with Mask "HH HH HH" but this is a fixed mask. I need one, which could be "filled".

I have also tried the DocumentFilter, but this does not allow me to edit the complete text. Only the inserted chunks were "filtered".

Do you know another way to solve the problem?

Was it helpful?

Solution

Problem solved.

import java.awt.EventQueue;
import java.awt.Toolkit;

import javax.xml.bind.DatatypeConverter;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class HexTextField extends JTextField implements DocumentListener
{
    private static final long serialVersionUID= -6694532039668603522L;
    private boolean filtering= false;

    public HexTextField()
    {
        super();
        getDocument().addDocumentListener(this);
    }

    @Override
    public void changedUpdate(DocumentEvent e)
    {
        filterText();
    }

    @Override
    public void insertUpdate(DocumentEvent e)
    {
        filterText();
    }

    @Override
    public void removeUpdate(DocumentEvent e)
    {
        filterText();
    }

    private void filterText()
    {
        if(filtering)
            return;
        filtering= true;

        EventQueue.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                String input= getText().toUpperCase();
                String filtered= "";
                int index= 0;

                // filter
                for(int i= 0; i < input.length(); i++)
                {
                    char c= input.charAt(i);
                    if("0123456789ABCDEF".indexOf(c) >= 0)  // hex only
                    {
                        filtered+= c;
                        if(index++ % 2 == 1 && i != input.length() - 1)
                            filtered+= " "; // whitespace after each byte
                    }
                }

                // limit size
                int maxBytes= 256;
                if(filtered.length() > 3 * maxBytes)
                {
                    filtered= filtered.substring(0, 3 * maxBytes);
                    Toolkit.getDefaultToolkit().beep();
                }

                setText(filtered);
                filtering= false;
            }
        });
    }

    public byte[] getBytes()
    {
        String text= getText().replace(" ", "");
        if(text.length() == 0)
            return null;

        if(text.length() % 2 == 1)
            text= text.substring(0, text.length()-1) + "0" + text.charAt(text.length()-1);

        byte[] bytes= DatatypeConverter.parseHexBinary(text);
        if(bytes.length == 0)
            return null;

        return bytes;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top