Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / May 2005

Tip: Looking for answers? Try searching our database.

How can I stop text field from consuming irrelevant characters?

Thread view: 
David Vanderschel - 11 May 2005 22:52 GMT
I have a JFormattedTextField formatted with a
NumberFormatter.  I have set up another component
using getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).
I want that component to be able to receive and
consume certain alphabetic characters even if that
text field has the focus.  Unfortunately, when the
text field has focus and I type an alphabetic
character, the text field accepts and consumes the
character.  This does not even make sense, since only
numeric input can be accepted validly in that field.
How can I prevent the text field from consuming these
characters which should not be in there in the first
place so that my application can process these keyboard
events correctly?  Or is there some other type of component I
should be using for typed numeric input?

My application's window also has some radio buttons
and a slider; and, when any of those components has
the focus, my application does get the keyboard input
events as I intended.  So I am not far from the
function I seek.  The text field is a nuisance for
interfering with keyboard input to which it should not
even be paying any attention.

Thanks for any pointers,
 David V.
Vova Reznik - 12 May 2005 15:00 GMT
> I have a JFormattedTextField formatted with a
> NumberFormatter.  I have set up another component
[quoted text clipped - 22 lines]
> Thanks for any pointers,
>   David V.

javax.swing.text.Document is responsible to change text in the
JTexdtComponent.
Override Documents
    void insertString(int, String, AttributeSet);
David Vanderschel - 12 May 2005 17:53 GMT
> > Thanks for any pointers,

> javax.swing.text.Document is responsible to change text in the
> JTexdtComponent.
> Override Documents
>      void insertString(int, String, AttributeSet);

I am but a beginner at java programming.  As a result,
I have difficulty seeing how the above relates to my
problem.  I do not really care so much that the
alphabetic characters are being _displayed_ in the
(supposedly numeric) text field.  The problem is that
I do not want them to be _consumed_ by that process.
I want the characters to be seen by my own application
code, not being stopped by the text field
implementation.

Given my limited experience with java, I could really
benefit from some additional detail.

Regards,
 David V.
Vova Reznik - 12 May 2005 18:05 GMT
>>>Thanks for any pointers,
>
[quoted text clipped - 18 lines]
> Regards,
>   David V.

Simple Example:

class OnlyDigitDoc extends PlainDocument {

    public void insertString(int offs, String str, AttributeSet a)
                throws BadLocationException {
    for (int i = 0; i < str.length(); i++) {
        if (!Character.isDigit(str.charAt(i))) {
            return;
        }
    }
    super.insertString(offs, str, a);
    }
}

yourTextComponent.setDocument(new OnlyDigitDoc());
David Vanderschel - 12 May 2005 21:16 GMT
> > Given my limited experience with java, I could really
> > benefit from some additional detail.

> Simple Example:
>
[quoted text clipped - 12 lines]
>
> yourTextComponent.setDocument(new OnlyDigitDoc());
David Vanderschel - 12 May 2005 21:59 GMT
> > Given my limited experience with java, I could really
> > benefit from some additional detail.

> Simple Example:
>
[quoted text clipped - 12 lines]
>
> yourTextComponent.setDocument(new OnlyDigitDoc());

Though I still fail to understand what this has to do
with receipt of keyboard events by another component,
I went ahead and attempted to do a setDocument on my
JFormattedTextField with an instance of Vova's
OnlyDigitDoc.  It compiles, but I now get a run time
error:
______________________________________________________________________

D:\dv\java\cube>appletviewer 3.html
v: 0.0   i: 0   button[i].min: -360.0   button[i].max: 360.0
java.lang.NullPointerException
at PuzWin$TextFieldChangeListener.propertyChange(Shrink.java:612)
at
javax.swing.event.SwingPropertyChangeSupport.firePropertyChange(SwingPropert
yChangeSupport.java:264)
at
javax.swing.event.SwingPropertyChangeSupport.firePropertyChange(SwingPropert
yChangeSupport.java:232)
at javax.swing.JComponent.firePropertyChange(JComponent.java:3819)
at javax.swing.text.JTextComponent.setDocument(JTextComponent.java:401)
at javax.swing.JTextField.setDocument(JTextField.java:256)
at
javax.swing.JFormattedTextField.setDocument(JFormattedTextField.java:685)
at PuzWin.<init>(Shrink.java:541)
at Shrink.init(Shrink.java:679)
at sun.applet.AppletPanel.run(AppletPanel.java:353)
at java.lang.Thread.run(Thread.java:534)
______________________________________________________________________

Here is my code at Shrink.java:612:
______________________________________________________________________

 /* Listen to the text field. */
 public class TextFieldChangeListener implements PropertyChangeListener {
   public void propertyChange(PropertyChangeEvent e) {
     float v  = ((Number)textField.getValue()).floatValue();
     int   i  = curParam;
     System.out.println("v: "+v+"   i: "+i+"   button[i].min: "
                        +button[i].min+"   button[i].max: "+button[i].max);
==>   slider.setValue(Math.round(720.f*(v-button[i].min)/(button[i].max -
button[i].min)));
     newValue(i, v);
   }
 }
______________________________________________________________________

As may be seen from the result of my
System.out.println, all my variables are OK, so I
don't know what is causing the problem.  Until I added
the OnlyDigitDoc, the above code worked as I had
intended.  It is conceivable that the change event is
being fired before everything has initialized
properly, as I did the setDocument() in the code which
builds my frame (window).  But I don't understand what
is happening well enough to know that.

I don't see that the OnlyDigitDoc object is doing
anything at all related directly to keyboard input
_events_.  I remain totally confused about how
anything like this could prevent the characters from
being consumed on input.  We are not interfering at
the level I would expect.

Regards,
 David V.
Vova Reznik - 12 May 2005 22:07 GMT
>>>Given my limited experience with java, I could really
>>>benefit from some additional detail.
[quoted text clipped - 81 lines]
> Regards,
>   David V.

Do you want me to teach you all Swing?

Try this complete example.
You cannot type or paste any letters (only digits).

Document is the Model (MVC) in text components.

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class CustomDoc extends JFrame {

    private JTextField    field    = new JTextField(new OnlyDigitDoc(), "", 10);
    public CustomDoc() {
        getContentPane().add(field, BorderLayout.SOUTH);
        System.out.println(field.getDocument());
    }
    public static void main(String[] args) {
        JFrame f = new CustomDoc();
        f.setDefaultCloseOperation(EXIT_ON_CLOSE);
        f.pack();
        f.show();
    }
    class OnlyDigitDoc extends PlainDocument {

        public void insertString(int offs, String str, AttributeSet a)
                throws BadLocationException {
           
            for (int i = 0; i < str.length(); i++) {
                if (!Character.isDigit(str.charAt(i))) {
                    return;
                }
            }
            super.insertString(offs, str, a);
        }
    }
}
David Vanderschel - 13 May 2005 00:49 GMT
> Do you want me to teach you all Swing?

Certainly not.  However, I wish you would address the
problem which I described in my opening post.  This is
not about controlling what can _appear_ in a text
field.  This is about providing a mechanism so that
keyboard input events corresponding to alphabetic keys
can be handled by another component in a frame even
when a numerically formatted text field has the focus.
At present, my text field is _consuming_ the events so
that they are not available elsewhere.  Other swing
components do not do that even though they do listen
to the keyboard for certain keys.  In this case, I
really do not mind so much that the garbage characters
echo in the text field.  I do mind that they are
consumed in the process.

It seems to me that the method that I need override is
whatever the text field uses to accept keyboard events
in the first place.  At that point, I could tell it to
ignore alphabetic characters but without consuming
them so that the system can hand them to my other
component which does want to handle them.  However, I
have no idea what that method is or how to get to it.

Please carefully reread my initial post and decide if
you think that your attempts so far really do address
the issue I described.  Note also that I closed that
message with "Thanks for any pointers".  I am not
expecting folks to _teach_ me background information.
There is plenty of documentation on Sun's Web site and
elsewhere.  However, if you can see what it is that I
am missing conceptually, a pointer to the relevant
documentation or even some key words could be a big
help.

Regards,
 David V.
Alan Moore - 13 May 2005 10:05 GMT
You can intercept the the key events before the text component sees
them with the technique shown here:

http://www.javaspecialists.co.za/archive/Issue007.html
David Vanderschel - 13 May 2005 19:59 GMT
> You can intercept the the key events before the text component sees
> them with the technique shown here:

> http://www.javaspecialists.co.za/archive/Issue007.html

Thank you, Alan!  That article actually does address
my issue.

Coincidentally, in my frustration with Vova's
orthogonal responses, I had managed to find a
workaround for my problem last night.  I finally
managed to bumble onto http://tinyurl.com/dvqq8/.
Ahah!:  Text fields use an InputMap.  Then on
http://tinyurl.com/4dn2o/, I found:

   To make a component ignore a key that it normally
   responds to, you can use the special action name
   "none".

So, all it took was:

   InputMap iMap = textField.getInputMap(); // Tell text field to ignore
alphabetic characters.
   char c;
   for(c='a'; c<='z'; c++) iMap.put(KeyStroke.getKeyStroke(c), "none");
   for(c='A'; c<='Z'; c++) iMap.put(KeyStroke.getKeyStroke(c), "none");

(FWIW, I only had to kill alphabetic keys.  Bindings I
had set up in my other component for some control keys
work OK when the text field has focus without my
having to mess with the bindings of those keys in the
text field.  Since alphabetic characters make no sense
in this text field, I went ahead and killed all 52
alphabetic characters, even though my program only
accepts 12. 40 of them remain without bindings - which
is OK.)

My solution strikes me as one which interferes with
the intended function of a Swing component - somehow
compounding the text field's behaviour with that of my
application.  (It is also conceivable that I have not
gotten sufficiently into the spirit of java
programming.)  The article Alan cites undoubtedly
offers a more systematic approach to the problem.  I
recognize that my solution is somewhat 'pathological'
in terms of structure, but it is simpler and easier to
understand.  I still think there ought to be a
solution which is neither 'pathological' nor complex,
which is why I am only willing to call my solution a
"workaround".  But, since we are not talking about any
code that is reusable outside my application, I am
going to stop worrying about it now.  ;-)

Regards,
 David V.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.