Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to set numeric filter for JSpinner?

843807Jul 26 2010 — edited Jul 28 2010
Hi there,
I searched the forum but can't find a solution...I'm kind of getting mad!
Problem is: I have a JSpinner, I must prevent the user to insert any non-numeric value. the accepted input should be in the form <n>.<m>
where n could be any integer number, m is OPTIONAL and could be a single digit number. Example: 150.2 or 41 or 7.1 etc.

I set a DocumentFilter on the editor of JSpinner, overriding replace method. Problem is replace method is never called so my filter is not applied and the user is allowed to insert whatever he wants, characters included.



Here's my code (sorry for the horrible gui, but it's just for some testing.):
import java.awt.Dimension;
import java.util.regex.Pattern;

import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.JSpinner.NumberEditor;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class SpinnerTry {
	public final static String REGEX_DOUBLE_NUMBER = "^([0-9]+)(\\.(\\d{1})?)?$";

	private static final Double MIN_PW = 12.0;
	private static final Double MAX_PW = 19.0;
	private static final Double DEFAULT = 15.0;
	private static final Double STEP = 1.00;
	private static final SpinnerNumberModel model = new SpinnerNumberModel(
			DEFAULT, // initial value
			MIN_PW, // min
			MAX_PW, // max
			STEP);


	public static void main(String[] args) {

		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JSpinner spinner = new JSpinner(model);
		spinner.setPreferredSize(new Dimension(50, 15));

		NumberEditor edit = new NumberEditor(spinner, "#######.#");

		spinner.setEditor(edit);

		JTextField textField = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
		((AbstractDocument) textField.getDocument()).setDocumentFilter(new MyDocumentFilter());

		frame.getContentPane().add(spinner);
		frame.setSize(new Dimension(200, 200));
		frame.setVisible(true);

	}

	static class MyDocumentFilter extends DocumentFilter {

		public void replace(FilterBypass fb, int offset, int length, String text,
				AttributeSet attrs) throws BadLocationException {

			System.out.println("Called replace");
			
			String mytext = fb.getDocument().getText(0, offset);
			mytext += text;
			if (fb.getDocument().getLength() - 1 > offset) {
				mytext += fb.getDocument().getText(offset + 1,
						fb.getDocument().getLength() - offset);
			}
			boolean ok = true;

			ok = Pattern.matches(REGEX_DOUBLE_NUMBER, mytext);

			if (ok)
				super.replace(fb, offset, length, text, attrs);

		}

		public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
				throws BadLocationException {
			
			if (Pattern.matches(REGEX_DOUBLE_NUMBER, string)) {
				super.insertString(fb, offset, string, attr);
			}
		}
	}
}
Why replace method is not called when inserting somethig into the spinner text field?

Thanks a lot in advance.
Paul

Edited by: the.paul on Jul 27, 2010 1:11 AM
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 25 2010
Added on Jul 26 2010
4 comments
932 views