0

for a little test application I need a TextField which only accepts numbers. In addition the user should only be able to enter numbers from 0-255. So far i found this:

import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;

/**
 * A JTextField that accepts only integers.
 *
 * @author David Buzatto
 */
public class IntegerField extends JTextField {

    public IntegerField() {
        super();
    }

    public IntegerField( int cols ) {
        super( cols );
    }

    @Override
    protected Document createDefaultModel() {
        return new UpperCaseDocument();
    }

    static class UpperCaseDocument extends PlainDocument {

        @Override
        public void insertString( int offs, String str, AttributeSet a )
                throws BadLocationException {

            if ( str == null ) {
                return;
            }

            char[] chars = str.toCharArray();
            boolean ok = true;

            for ( int i = 0; i < chars.length; i++ ) {

                try {
                    Integer.parseInt( String.valueOf( chars[i] ) );
                } catch ( NumberFormatException exc ) {
                    ok = false;
                    break;
                }
            }

            if ( ok ) {
                super.insertString( offs, new String( chars ), a );
            }
        }
    }

I added to the for Loop the following so only Numbers which contain of 3 Digits can be typed

    if(super.getLength() == 3) {
        ok = false;
        System.out.println("tooLong");
        break;

    }

But how can I set a maximum input value? The user should only enter numbers which goes from 0-255.

Thanks in advance

KilledByCheese
  • 852
  • 10
  • 30

3 Answers3

0

you can implement those two checks as follows:

        if(str.length()>3) {
             return;
        } 

        int inputNum = Integer.parseInt(str);
        if(inputNum<0 || inputNum>255) {
             return;
        }   

Add these checks before the last if block and you should be good to go.

Sanjeev
  • 9,876
  • 2
  • 22
  • 33
0

Here is the easiest way to do what you want.

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class ByteField extends JTextField {

    private boolean revert;

    @Override
    public void replaceSelection(String content) {
        if (revert) {
            super.replaceSelection(content);
        } else {
            String current = getText();
            super.replaceSelection(content);
            String now = getText();
            try {
                if (!now.isEmpty()) {
                    int val = Integer.valueOf(now);
                    revert = val < 0 || val > 255;
                }
            } catch (Exception e) {
                revert = true;
            }
            if (revert) {
                setText(current);
            }
            revert = false;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JTextField fld = new ByteField();
                fld.setColumns(5);
                JFrame frm = new JFrame("Test");
                frm.add(fld);
                frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frm.pack();
                frm.setLocationRelativeTo(null);
                frm.setVisible(true);
            }
        });
    }
}

And here is the way using the document:

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class ByteField extends JTextField {

    private static class ByteDocument extends PlainDocument {

        @Override
        public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
            String currText = getText(0, getLength());
            StringBuilder b = new StringBuilder(currText);
            b.insert(offs, str);
            currText = b.toString();
            boolean proceed = true;
            try {
                if (!currText.isEmpty()) {
                    int val = Integer.valueOf(currText);
                    proceed = val >= 0 && val <= 255;
                }
            } catch (Exception e) {
                proceed = false;
            }
            if (proceed) {
                super.insertString(offs, str, a);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JTextField fld = new JTextField(new ByteDocument(), "", 5);
                JFrame frm = new JFrame("Test");
                frm.add(fld);
                frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frm.pack();
                frm.setLocationRelativeTo(null);
                frm.setVisible(true);
            }
        });
    }
}
Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
  • please why not by using DocumentFilter (to alllows numbers), or JSpinner or JFormattedTextField with min & max in Formatter – mKorbel Oct 14 '16 at 08:57
  • @mKorbel You're right. There are many ways to provide the required functionality. JSpinner/JFormattedTextField can allow to do it even easier, but they also have some restriction. – Sergiy Medvynskyy Oct 14 '16 at 09:05
0

This will get the job done, although i would suggest you add a catch if nothing enters the textInput you get a empty warning.

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;`
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class Matches extends JFrame{

    JTextArea textInput = new JTextArea(1, 10);
    JLabel labelInput = new JLabel("Enter a number between 0-255");
    JLabel labelOutput = new JLabel();
    JPanel p1 = new JPanel();
    JButton b1 = new JButton("Test Number");


    public Matches () {
        p1.add(labelInput);
        p1.add(textInput);
        p1.add(b1);
        p1.add(labelOutput);
        b1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int answer = Integer.parseInt(textInput.getText());

                if (answer >= 0 && answer <= 255) {
                    labelOutput.setText("You entered: " + textInput.getText());
                } else {
                    JOptionPane.showMessageDialog(null, "Error!, only numbers between 0-255 are allowed!");
                }

            }
        });

        add(p1);
        setVisible(true);
        setSize(300, 300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

   public static void main(String[] args) {

      new Matches();
   }
}
castlesnake
  • 37
  • 1
  • 11