1

Just wanted to know why this is occurring, not that it's a huge issue.


Problem

I have a class, JDecimalField, that extends JTextField. I've modified the createDefaultModel() code in this class so it returns a custom Document that writes only numerical inputs (1 through 9 as well as '.').

Created a quick SSCCE of the code I have, excuse the dirtiness:

import java.io.Serializable;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;

public class TestField{
    
    public static void main(String args[]){
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JDecimalField field = new JDecimalField();
        frame.add(field);
        frame.pack();
        frame.setVisible(true);          
    }
    
    public static class JDecimalField extends JTextField{

        public JDecimalField() {
            super();
        }

        @Override
        protected Document createDefaultModel() {
            String[] inputs = {"1", "2", "3", "4","5","6","7","8","9", "0", "."};
            return new RestrictedDocument(inputs); 
        }

        public int getValue() throws NumberFormatException{
            return Integer.parseInt(getText());
        }  
    }
    
    public static class RestrictedDocument extends PlainDocument implements Serializable {
        private final String[] charList;

        public RestrictedDocument(String[] charList){
            this.charList = charList;
        }

        public boolean validate(String exp){
            for (String charList1 : charList) {
                if (exp.equals(charList1)) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
            if (validate(str)){
                super.insertString(offs, str, a);
            }     
        }       
    }
    
}

My Question/TL;DR:

I just was wondering what in my RestrictedDocument is not accepting a ctrl+v action? Being able to do so would be nice but I could live without it.

And before it's mentioned, yes I've considered using a JFormattedTextField. I usually do, just in my case I can't for this current assignment. I don't mind though, expounds upon my knowledge of Java.

Community
  • 1
  • 1
Eric
  • 373
  • 1
  • 3
  • 14

1 Answers1

3

The solution is simple:

  • Either use a JFormattedTextField (as you already know) or
  • use a DocumentFilter.

For example:
DocumentFilter Example 1
DocumentFilter Example 2

For tutorial:
DocumentFilter Tutorial


Edit
Your problem is in your validate method: it will allow "3" since that's in the list, but won't allow "33" since that's not in the list.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • So a custom document does not allow pasting? Just curious – Eric Apr 10 '14 at 19:58
  • @Eric: I've never used it for that, so I don't know, but I do know that a DocumentFilter works great for this. – Hovercraft Full Of Eels Apr 10 '14 at 19:59
  • Thanks, I was just curious to try a different method was all. – Eric Apr 10 '14 at 20:02
  • @Eric: see edit. Your validate method is erroneous. Still I recommend a DocumentFilter or JFormattedTextField for this. – Hovercraft Full Of Eels Apr 10 '14 at 20:07
  • I'm able to enter '33' or any number into my field. But I'm going to use the Document filter anyways. – Eric Apr 10 '14 at 20:11
  • @Eric: I wasn't clear -- you can type in 33 because you type each number digit String one at a time, and each number digit String is validated **one at a time**. If you try to ***paste*** in "3", no problem, it gets validated fine, but if you try to ***paste*** "33" the validation fails due a bug in your validation method. – Hovercraft Full Of Eels Apr 10 '14 at 20:12
  • Ah I see, I wasn't testing single digits when pasting. – Eric Apr 10 '14 at 20:15
  • Quick question on the filter you linked (yours). I'm trying to figure out which method (insert, replace, remove) is not allowing me to delete my field. As in I'll enter 2434, backspace and won't allow me to delete the last remaining number. – Eric Apr 10 '14 at 22:25
  • Right now the only method in the filter being used is the replace method, should that be the case as well? – Eric Apr 10 '14 at 22:30
  • @Eric: I'm not sure. If this were my problem, I'd do some simple debugging operations to identify the offending methods and to fix it. – Hovercraft Full Of Eels Apr 10 '14 at 22:33
  • sorry to bother you then. – Eric Apr 10 '14 at 22:35
  • @Eric: it's no bother, it's just some basic debugging should solve this, and better for you to try it first than for me. I'm still at work and have work responsibilities to attend to. – Hovercraft Full Of Eels Apr 10 '14 at 22:37
  • Figured out the issue, and in case you ever run into it again it was the remove method's if statement. Need to add a clause that checks for an empty string essentially. – Eric Apr 10 '14 at 22:42