2

First of all, I couldn't find any of my question on google.
This is the following code that I used.

ipAddress = new MaskFormatter("###.###.###.###");
JTextField txtAddress = new JFormattedTextField(ipAddress);

But the code above gives user to (must) input exactly 12 characters.
How to make the JTextField can be written as "12.10.25.25" ?

ifly6
  • 5,003
  • 2
  • 24
  • 47
Raiika
  • 109
  • 1
  • 11
  • One way: create your own class that extends [DefaultFormatter](http://docs.oracle.com/javase/8/docs/api/javax/swing/text/DefaultFormatter.html). Another way, use a standard JTextField and an InputVerifier. – Hovercraft Full Of Eels Dec 17 '16 at 05:49
  • Is not `12.10.25.25` really `012.010.025.025`? – ifly6 Dec 17 '16 at 05:52
  • you only concern with length and this format (two digits and a dot) or you want to verify ip address , clarify the requirements – Pavneet_Singh Dec 17 '16 at 05:57
  • this is to make the users input more simple, instead of inputting 012, they can input 12. I want to verify ip address, but I don't know how to do it besides using maskformatter. – Raiika Dec 17 '16 at 06:54

2 Answers2

2

I would do it differently:

Simply wait for the user to somehow confirm that he has finished entering the address (for example by observing when the field looses focus) and retrieve the value of the field and use one of the many regular expressions that check all properties of valid ip addresses.

Looking at the Oracle tutorial here it seems to me that using a JTextFormattedTextField simply is the wrong answer. That class and the corresponding formats are for either locale-based formatting of dates or numbers.

I think you should be rather looking into input validation; see here for details; and as said; your validation could be based on the things you find here.

Finally: the point is to come up with a consistent user experience. Dont put yourself into a corner by saying: I saw this approach; so I absolutely must use that type of component. Instead, check out the possible options, and go for that one that (given your "budget" of development resources) gives the user the best experience.

Example: instead of using 1 JFormattedTextField, you could go for 4 textfields, and even write code that would move the focus automatically forth and back. Many things are possible; it only depends on how much time you are willing to spend.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • That is hard using the mobile phone. But I would just google those terms do some copy paste. Such things are documented all over the place. – GhostCat Dec 17 '16 at 07:11
  • ahh, okay then, thank you for your information GhostCat. – Raiika Dec 17 '16 at 07:14
  • Let me know if that is really "enough" for you to get going. If no I would put in some updates latest on Monday. – GhostCat Dec 17 '16 at 07:39
  • I could solve it without maskformatter, but I'm not satisfied because the user should type "dot" manually (without the system provides it on the JTextField). I also couldn't use maskformatter with setText() in focusLost event because maskformatter is done after focusLost. – Raiika Dec 17 '16 at 11:22
  • Thank you for your answer GhostCat. – Raiika Dec 17 '16 at 13:44
1

My homegrown IP address control based on a single JTextField

import javax.swing.*;
import javax.swing.text.DefaultEditorKit;
import java.awt.*;
import java.awt.event.*;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class JIp4AddressInput extends JTextField
{
    private final char[] buff = "  0.  0.  0.  0".toCharArray();

    private int bpos;

    private void putnum (int num, int offset)
    {
        int a = num/100;
        num -= a*100;
        int b = num/10;
        num -= b*10;
        buff[offset] = (char)('0'+a);
        buff[offset+1] = (char)('0'+b);
        buff[offset+2] = (char)('0'+num);
    }

    private void align (int base)
    {
        int end = base+3;
        StringBuffer sb = new StringBuffer();
        for (int s=base; s<end; s++)
        {
            if (buff[s] != ' ')
                sb.append(buff[s]);
        }
        while (sb.length() > 1 && sb.charAt(0) == '0')
            sb.delete(0,1);
        while (sb.length() < 3)
            sb.insert(0, ' ');
        try
        {
            int num = Integer.parseInt(sb.toString().trim());
            if (num > 255)
                sb = new StringBuffer("255");
            if (num < 0)
                sb = new StringBuffer("  0");
        }
        catch (NumberFormatException e)
        {
            sb = new StringBuffer("  0");
        }
        for (int s=base; s<end; s++)
        {
            buff[s] = sb.charAt(s-base);
        }
    }

    private void alignAll()
    {
        align(0);
        align (4);
        align(8);
        align (12);
    }

    private void fwd ()
    {
        bpos = bpos == 15 ? bpos : bpos +1;
    }

    private void back ()
    {
        bpos = bpos == 0 ? bpos : bpos -1;
    }

    private void backspace()
    {
        back();
        if (bpos == 3 || bpos == 7 || bpos == 11)
        {
            return;
        }
        if (bpos < 15)
            buff[bpos] = ' ';
    }

    private void setChar (char c)
    {
        if (bpos == 3 || bpos == 7 || bpos == 11)
        {
            fwd();
        }
        if (bpos < 15)
            buff[bpos] = c;
        fwd();
    }

    public JIp4AddressInput()
    {
        super();
        setPreferredSize(new Dimension(110, 30));
        setEditable(false);

        Action beep = getActionMap().get(DefaultEditorKit.deletePrevCharAction);
        beep.setEnabled (false);

        setText (new String (buff));

        addFocusListener(new FocusListener()
        {
            @Override
            public void focusGained(FocusEvent e)
            {
                setText (new String (buff));
                setCaretPosition(0);
                getCaret().setVisible(true);
            }

            @Override
            public void focusLost(FocusEvent e)
            {
                alignAll();
                setText(new String(buff));
            }
        });

        addKeyListener(new KeyAdapter()
        {
            @Override
            public void keyTyped (KeyEvent e)
            {
                bpos = getCaretPosition();
                char c = e.getKeyChar();
                if ((c>= '0' && c<= '9') || c == ' ')
                {
                    setChar (c);
                }
                else if (c == KeyEvent.VK_BACK_SPACE)
                {
                    backspace();
                }
                else if (c == KeyEvent.VK_ENTER)
                {
                    alignAll();
                }
                setText(new String(buff));
                setCaretPosition(bpos);
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////////////////

    public InetAddress getAddress()
    {
        String[] parts = new String(buff).split("\\.");
        byte[] adr = new byte[4];
        for (int s=0; s<4; s++)
            adr[s] = (byte)Integer.parseInt(parts[s].trim());
        try {
            return InetAddress.getByAddress(adr);
        } catch (UnknownHostException e) {
            return null;
        }
    }

    public void putAddress (InetAddress in)
    {
        byte[] adr = in.getAddress();
        putnum(adr[0]&0xff, 0);
        putnum(adr[1]&0xff, 4);
        putnum(adr[2]&0xff, 8);
        putnum(adr[3]&0xff, 12);
        alignAll();
        setText (new String(buff));
    }
}