JFormattedTextField:Allow Only numeric digits and asteriks

Hello friends,

I'm using JFormattedTextField to cater my needs wherein I should accept only "numbers or asteriks" and that too the maximum number of characters that I should receive is 20.

I've tried to achieve this, without much success though, with the following piece of code:

myFormatter = new MaskFormatter();

myFormatter.setValidCharacters("*1234567890");

myFormatter.setMask("********************");

myFormatter.setAllowsInvalid(false);

myTxtField = new JFormattedTextField(myFormatter);

myTxtField.setFocusLostBehavio(JFormattedTextField.PERSIST);

The above code is working fine in the sense:

-- it's not allowing more than 20 characters

-- it's not allowing user to type in anything other than numbers and stars

Problem:

When the application loads, this text field is having 20 spaces, this is where the problem is actually stemming from!

how to get to the problem?

1. type "123" in the "myTxtField"

2. move the cursor 1 field to the right using the right arrow

3. type the numbers "*4*5*" now

the problem with this is that -- here the text field is allowing numbers, astericks, and also spaces

but I don't want to have these spaces at all...

so, may I ask you to help me out please?

Thanks,

Srinivas

[1355 byte] By [srini_iiita] at [2007-11-26 16:05:53]
# 1
Did you try using COMMIT instead PERSIST at the last line ?
dragzula at 2007-7-8 22:27:59 > top of Java-index,Desktop,Core GUI APIs...
# 2

First of all, thanks for replying.

I don't have a problem with value persistance or value commit.

The problem is....the text box is accepting white spaces also

it's like....

if i enter the numbers 2, 3, 4

then move the cursor to another 2-3 positions to the right

and then enter 5, 6

when i say myTxtField.getText(), it returns me "23456" -- this is what I want to restrict and at the same time I would like to accept a maximum of 20 digits(or asteriks) in my text field.

I hope, I made myself clear in explaining the problem.

Thanks in advance for helping me solve this problem.

srini_iiita at 2007-7-8 22:27:59 > top of Java-index,Desktop,Core GUI APIs...
# 3

> I hope, I made myself clear in explaining the problem

"A picture is always worth a thousand words"

If you need further help then you need to create a [url http://homepage1.nifty.com/algafield/sscce.html]Short, Self Contained, Compilable and Executable, Example Program[/url] (SSCCE) that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

And don't forget to use the [url http://forum.java.sun.com/help.jspa?sec=formatting]Code Formatting Tags[/url] so the code retains its original formatting.

camickra at 2007-7-8 22:27:59 > top of Java-index,Desktop,Core GUI APIs...
# 4

Then you don't want to use a MaskFormatter. Part of the definition of the

definition of the MaskFormatter is that the mask is present in the text.

For instance, if your mask was "***-**-****", the hyphens would be present

in the text. Note that you are not typing the spaces (you can't), you are merely

moving the cursor over the mask.

With a JFormattedTextField, you should be doing a getValue(), rather than

getText(). The value, rather than the text, is what will match the mask (note,

though, that any mask characters (such as the hyphens in the above

example) will still be present in the value).

You also need to use COMMIT rather than PERSIST as otherwise nothing

happens when the field loses focus -- the value is never updated. If you want

to allow up to 20 characters, you can use the [url http://forum.java.sun.com/thread.jspa?forumID=57&threadID=461577&start=3]VariableLengthMaskFormatter.[/url]

You could also use a DocumentFilter on a regular JTextField to accomplish

what you want.

JayDSa at 2007-7-8 22:27:59 > top of Java-index,Desktop,Core GUI APIs...
# 5

Here is a piece of code, that depicts my problem:

import java.awt.*;

import javax.swing.*;

import javax.swing.text.*;

import java.text.*;

import java.beans.PropertyChangeListener;

import java.beans.PropertyChangeEvent;

public class jfttDemo extends JPanel

implements PropertyChangeListener {

//Values for the fields

private String textEntry = "10000";

//Labels to identify the fields

private JLabel textEntryLabel;

private JLabel textDisplayLabel;

//Strings for the labels

private static String textEntryString = "textEntry: ";

private static String textDisplayString = "textDisplay: ";

//Fields for data entry

private JFormattedTextField textEntryField;

private JFormattedTextField textDisplayField;

//Formats to format and parse numbers

private MaskFormatter textEntryFormat;

private MaskFormatter textDisplayFormat;

public jfttDemo() {

super(new BorderLayout());

setUpFormats();

String textDisplay = textEntry;

//Create the labels.

textEntryLabel = new JLabel(textEntryString);

textDisplayLabel = new JLabel(textDisplayString);

//Create the text fields and set them up.

textEntryField = new JFormattedTextField(textEntryFormat);

textEntryField.setValue(textEntry);

textEntryField.setColumns(25);

textEntryField.setFocusLostBehavior(JFormattedTextField.COMMIT);

textEntryField.addPropertyChangeListener("value", this);

textDisplayField = new JFormattedTextField(textDisplayFormat);

textDisplayField.setValue(textDisplay);

textDisplayField.setColumns(25);

textDisplayField.setEditable(false);

textDisplayField.setForeground(Color.red);

//Tell accessibility tools about label/textfield pairs.

textEntryLabel.setLabelFor(textEntryField);

textDisplayLabel.setLabelFor(textDisplayField);

//Lay out the labels in a panel.

JPanel labelPane = new JPanel(new GridLayout(0,1));

labelPane.add(textEntryLabel);

labelPane.add(textDisplayLabel);

//Layout the text fields in a panel.

JPanel fieldPane = new JPanel(new GridLayout(0,1));

fieldPane.add(textEntryField);

fieldPane.add(textDisplayField);

//Put the panels in this panel, labels on left,

//text fields on right.

setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

add(labelPane, BorderLayout.CENTER);

add(fieldPane, BorderLayout.LINE_END);

}

/** Called when a field's "value" property changes. */

public void propertyChange(PropertyChangeEvent e) {

Object source = e.getSource();

textEntry = textEntryField.getText().trim();

String textDisplay = textEntry;

textDisplayField.setValue(textDisplay);

}

/**

* Create the GUI and show it. For thread safety,

* this method should be invoked from the

* event-dispatching thread.

*/

private static void createAndShowGUI() {

//Create and set up the window.

JFrame frame = new JFrame("FormattedTextFieldDemo");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

JComponent newContentPane = new jfttDemo();

newContentPane.setOpaque(true); //content panes must be opaque

frame.setContentPane(newContentPane);

//Display the window.

frame.pack();

frame.setVisible(true);

}

public static void main(String[] args) {

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

}

//Create and set up number formats. These objects also

//parse numbers input by user.

private void setUpFormats() {

try

{

MaskFormatter myFormat = new MaskFormatter();

myFormat.setValidCharacters("*1234567890");

myFormat.setMask("********************");

myFormat.setAllowsInvalid(false);

textEntryFormat = myFormat;

textDisplayFormat = myFormat;

}

catch (ParseException pe)

{

// Do nothing

}

}

}

Please consider the following scenarios when we run the program:

scenario-1: enter the text "1*2*3*4*5*6*7*8*9*0*" in the first text box(text Entry field) and press Tab

This act will update the second text box to the above text.

scenario-2: (run the program afresh)enter the text "1*"

move the cursor towards right(using right arrow key) by 3 positions

and enter the text "3*"

now press Tab

the display Text Field doesn't get updated as the effective text returned by the text Entry box is "1*3* "

Now, what I want is -- <b>I don't want those spaces....</b>

(I'm sorry, I wanted to attach an image, but couldn't find an option to upload an image here)

srini_iiita at 2007-7-8 22:27:59 > top of Java-index,Desktop,Core GUI APIs...
# 6
[url http://java.sun.com/docs/books/tutorial/uiswing/components/generaltext.html#filter]Here[/url] is a tutorial that shows how to limit the number of characters enteredinto a document. You should be able to trivially adapt it to also limit it todigits or asterisks.
JayDSa at 2007-7-8 22:27:59 > top of Java-index,Desktop,Core GUI APIs...
# 7
Well... you can remove it manually, or use replaceAll(" ", "") and/or trim(). But if you type space, you'll get it too. If you wan't to remove the spaces, I think it can work.
dragzula at 2007-7-8 22:27:59 > top of Java-index,Desktop,Core GUI APIs...