Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

implementing 2 document filter at the same time on keypressed  RSS feed

 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm trying to implement 2 document filter to check for the length and input type, the sad thing is that only one is implemented while the other is overwritten. Also the input detector which limit the input to only integer will not immediately trap alphabet input at first and can allow 2 alpha inputs before it is trapped.

I found the code for alpha checking here and the size filter here


here's the code:



 
Stevens Miller
Bartender
Posts: 1443
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I read the javadoc, rodolfo, it appears that you can only have one active DocumentFilter set for your Document at any given time. So, your second call to setDocumentFilter is simply replacing the effect of your first call. You can rewrite your two DocumentFilter subclasses into one subclass and combine your filtration. That seems the most direct way to deal with the two-filter problem.

No idea why you are having the two-character problem you describe, but I'd suggest you combine your filters into one class and try to debug that. Maybe the problem will seem easy then, or maybe it will just go away by itself.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:

No idea why you are having the two-character problem you describe, but I'd suggest you combine your filters into one class and try to debug that. Maybe the problem will seem easy then, or maybe it will just go away by itself.


Unfortunately the problem didn't go away. I was able to combine the two like you suggested but the character trap is still a bit buggy. I hope that you can help enlighten me on this matter, as I am really unaware of what may cause this


 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I gave a possible solution in your other thread. Maybe you missed it.
In case it didn't work for you, can you give some feedback what problem
you encountered?
 
Campbell Ritchie
Sheriff
Posts: 53773
128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:I gave a possible solution in your other thread. . . .
So I though I would merge the two threads to bring your answer to everybody's attention. But I have done something wrong and the answer isn't here

I am seeking help to try and sort out my mistake.
 
Campbell Ritchie
Sheriff
Posts: 53773
128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I merged your stuff with the following thread. I hope that is okay by you.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am trying to learn on how I can limit the length of my textfield in java to 7 digits, and also limit it to only accept numeric characters.

In my search I have discovered Document Filter, but I can't really understand how to implement it, I did manage to try using some codes I found online and it did check the content of the textfield but if I were to input non numeric content then it will return an exception error, which is not my aim since I don't want my program to stop working everytime a non numeric character is found in the content..

This is the exception error:

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string


here is the code:

"amount" is the variable name of the textfield

 
Campbell Ritchie
Sheriff
Posts: 53773
128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That looks incredibly complicated. The following looks rather simplerBeware: "123 Campbell" will pass hasNextInt.

You can use a regular expression instead if you wish.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:That looks incredibly complicated.

You can use a regular expression instead if you wish.


It is rather complicated, and I'm still having a hard time understanding it thus I opted to ignore it for now, but I will try your suggestion using regex, I did not know that you can do regex in java. Thank you.
 
Campbell Ritchie
Sheriff
Posts: 53773
128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Go through the Java™ Tutorials which has a nice section about regexes.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:That looks incredibly complicated.

Actually, the whole darn Text API looks God-awful. Why cant I just say:

  JTextField text = new JTextField();
  text.setMaxInputLength(8);


and have Swing bleedin' well do it for me? Surely to God it can't be the first time somebody's asked for this...

But nooo ... I have to plough through Documents and EditorKits and ActionEvents ... I dunno.
I want a text field that's 8 characters long, that's all - you'd think I was asking for the friggin' moon...

Gawd I'm glad I don't have to write GUI code.

Winston
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Go through the Java™ Tutorials which has a nice section about regexes.


Thanks but I found a simpler example of document filter and was able to limit the input though I encountered some problems and will create a different thread for it.

Winston Gutkowski wrote:
Campbell Ritchie wrote:That looks incredibly complicated.

Actually, the whole darn Text API looks God-awful. Why cant I just say:

  JTextField text = new JTextField();
  text.setMaxInputLength(8);


and have Swing bleedin' well do it for me? Surely to God it can't be the first time somebody's asked for this...

But nooo ... I have to plough through Documents and EditorKits and ActionEvents ... I dunno.
I want a text field that's 8 characters long, that's all - you'd think I was asking for the friggin' moon...

Gawd I'm glad I don't have to write GUI code.

Winston


You said it! Why can't it be simple, why can't we just edit the properties and set a max length and if we want it to be numeric only or not! This makes me miss Web it's much simpler.
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hmm, well it is actually not that difficult.

There is a literal example in the Oracle documentation:

https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/DocumentSizeFilter.java

If I apply thet to a numeric textfield of length 7, I get:

 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:hmm, well it is actually not that difficult...

I suspect you and me have very different ideas of "difficult".

The very fact that it takes 50 lines of code to do something that (to me) ought to be an attribute of a Text field seems absurdly difficult.

But you get a cow anyway.

Winston
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I quoted the wrong web page. The example I was referring to is more or less
literally from the JTextField API.

Winston Gutkowski wrote:
Piet Souris wrote:hmm, well it is actually not that difficult...

I suspect you and me have very different ideas of "difficult".

If you ever programmed a textfield on an Acorn Archimedes computer, under Risc OS 3.1,
I'm sure you would agree...
 
Campbell Ritchie
Sheriff
Posts: 53773
128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I have managed to sort out my mistake with some help from Roel de Nijs. I think I have merged the right threads this time and managed to restore the thread I merged incorrectly. I think this is where you will find the solution PS suggested.
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Errare Humanum Est!
The link is correct.

The example I started from is on the JTextField API at Oracle, the 'UpperCaseField' class.

I made a new version, because I did not like the non-staticness of the 'NumericDocument'.
However, I had to do that to give that Document access to the maxChars-variable.

In the new version, I also made it possible to specify both the number of columns
(i.e. more or less how wide the textfield will be) and the maximum number of characters.

It made the class a bit longer, just as Winston asked

 
Campbell Ritchie
Sheriff
Posts: 53773
128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:Errare Humanum Est! . . .
Thank you
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:



How do I call this function on keypress? or how do I implement it in my part?

This is what my current event looks like for the IntFilter:


Thank you
 
Rob Spoor
Sheriff
Posts: 20895
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You shouldn't set the filter when a key is pressed. Instead, you should set the filter at the start of your code. When you type it tries to insert text in the document. But because the document has a filter specified, the filter is triggered.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:You shouldn't set the filter when a key is pressed. Instead, you should set the filter at the start of your code. When you type it tries to insert text in the document. But because the document has a filter specified, the filter is triggered.


I was worried that if I don't place it inside a keypress event it won't be triggered. So I just have to place the trigger code inside my main method?
 
Rob Spoor
Sheriff
Posts: 20895
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically where you now attach the listener, you instead attach the filter. AbstractDocument will take care that it's called.
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
rodolfo tuble wrote:I am trying to learn on how I can limit the length of my textfield in java to 7 digits, and also limit it to only accept numeric characters. (...)

So I wrote a subclass of JTextField that does exactly that.
In my reply from 2-12 (dd-mm) I gave an example how to use it,
in my reply from 4-12 I gave a slightly enhanced version of this class,
that allowed to set both the number of digits shown and the maximum
number of digits. That max number can be changed later, if so desired.
The use case is simply:

and possibly later,

Since NumericField extends JTextField, you can add all
kinds of Listeners to it, just like you could do to any other
JTextField.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:Basically where you now attach the listener, you instead attach the filter. AbstractDocument will take care that it's called.


I'm sorry, but I still don't understand on which part of the code should I place this line of code:



I tried placing it at the main, but it needed to be static, also tried placing it on where the initComponents is but it still didn't work. Also tried placing it on the event function that appears when you double-click the text box. I'm sorry for my ignorance in this matter as I am not really knowledgeable with DocumentFilter.

Piet Souris wrote:

The use case is simply:

and possibly later,

Since NumericField extends JTextField, you can add all
kinds of Listeners to it, just like you could do to any other
JTextField.


I'm also a bit lost here, I am using card layout and I structured the call like this:



This is the event that will view the panel where my "amount" text field is present, one of the many fields I wish to trap as a 7 digit numeric input, and that didn't work I also tried placing them inside their keypress event or their event function that appears when you double-click the text field, also tried placing them inside one of the methods that will process the inputted values but still to no avail.

I am truly thankful for all your help and would really appreciate it if you can help me understand this matter more clearly so that I will not be as confused as I am now in the near future. I am looking forward to your guidance.
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi rodolfo,

where you define your 'amount' JTextfield, can you do this:

There is no need to add any keylisteners (or Document Listeners)
to this field. Just maybe an ActionListener to catch an 'enter' from
the keyboard.

Can you tell me if that is what you need?
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:hi rodolfo,

where you define your 'amount' JTextfield, can you do this:

There is no need to add any keylisteners (or Document Listeners)
to this field. Just maybe an ActionListener to catch an 'enter' from
the keyboard.

Can you tell me if that is what you need?


I am using Netbeans for my UI would the declaration of the amount JTextfield be found inside the initComponents? Also, I was hoping to implement the limit during user input and not on enter, is this possible? thank you
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
rodolfo tuble wrote:
I am using Netbeans for my UI would the declaration of the amount JTextfield be found inside the initComponents?

You mean you are using NetBeans to do your GUI layout?
Well, while it IS possible to add my 'NumericField' to the component palette
in NetBeans, that is not an easy task and I would advise not to go this route.

What I sometimes do is to put a placeholder at the position and size
of the component that I will add later. For instance, add a JPanel
at the position where 'amount' is to appear, and of about the correct size.
Make its background transparant.
If you look at your NetBeans code, you will see something like:

I put another line below it:

and it that method add 'amount' to that panel.
Also, I was hoping to implement the limit during user input and not on enter, is this possible?

Why would you do a thing like that?

But is is possible. If you look at the code you see that there is a variable
that sets the maximum number of digits. Right after where a string is added,
just set that variable to whatever value you like.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:
Also, I was hoping to implement the limit during user input and not on enter, is this possible?

Why would you do a thing like that?

But is is possible. If you look at the code you see that there is a variable
that sets the maximum number of digits. Right after where a string is added,
just set that variable to whatever value you like.


I should not do that? I'm just unfamiliar with the best practices in java. Also, my aim is to limit the input of the user so that when they type in the textfield it should only reach 7 characters, and I thought that doing this with the keypress event is the best way. and yes I am using netbeans GUI builder. can you provide an example of applying your answer. I'm terribly sorry for taking too much of your time here, it's just that I'm really stuck in this error trapping part and I don't know how to proceed. Thank you
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is up to you to add all kinds of Listeners or not.

The only thing I did was to provide a class ('NumericField') that
is a JTextField, accepts only digits up to a maximum number that
you can set at contruction time. Nothing more, nothing less.

I thought that that was what you were asking.

Go to my reply dd 2 december, where I give a working example.
Now, copy that example into NetBeans, run it and tell me if
that suits your needs.

If not, please explain why you need something different.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:It is up to you to add all kinds of Listeners or not.

The only thing I did was to provide a class ('NumericField') that
is a JTextField, accepts only digits up to a maximum number that
you can set at contruction time. Nothing more, nothing less.

I thought that that was what you were asking.

Go to my reply dd 2 december, where I give a working example.
Now, copy that example into NetBeans, run it and tell me if
that suits your needs.

If not, please explain why you need something different.


Did you mean this:




or this: returns error: "Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException: Not supported yet."



So I was only able to run the first one and it is what I need though I am still having trouble implementing it in my code, I tried this:



Can you help me figure out how do I add this in my code, also if how would I change it to also trap inputs from the password field. Thank You
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
rodolfo tuble wrote:
So I was only able to run the first one and it is what I need though I am still having trouble implementing it in my code, I tried this:



Can you help me figure out how do I add this in my code, also if how would I change it to also trap inputs from the password field. Thank You


hi Rodolfo,

you can add a Component to only one container. As soon as you add 'nf' to
'card1', it is deleted from 'card17'. So you have to make two instances of NumericField:

The extended version of 'NumericField' does not give me any error. Can you show me
how you tested it? A small program like I delivered shoud do.

(...)
how would I change it to also trap inputs from the password field

What exactly do you mean by "trap the input"? If you want to get informed
when a user presses <return>, you must add an ActionListener to your textfield.
Since NumericField is a JTextField, you can add an ActionListener in the normal way.

By the way: if you look at my code, you see that I check the string-to-be-input
againt a length of 1, and also that it is a digit. By changing this, you can set it
to accept any character you like. You can even make it into a JPassWordField by
inserting a '*' for instance, instead of the typed in character.

Well, enough for you to try out.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:
The extended version of 'NumericField' does not give me any error. Can you show me
how you tested it? A small program like I delivered shoud do.

(...)
how would I change it to also trap inputs from the password field

What exactly do you mean by "trap the input"? If you want to get informed
when a user presses <return>, you must add an ActionListener to your textfield.
Since NumericField is a JTextField, you can add an ActionListener in the normal way.

By the way: if you look at my code, you see that I check the string-to-be-input
againt a length of 1, and also that it is a digit. By changing this, you can set it
to accept any character you like. You can even make it into a JPassWordField by
inserting a '*' for instance, instead of the typed in character.

Well, enough for you to try out.



The weird thing is that the error in the extended NumericField only happens on my newly created class file, but if I add it on my existing project it works without error,

Also I tried this:



But I still can't get it to work, my card1 panel has a jtextfield. Is there something I'm missing here? Thank you
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How did you layout this card1 panel?

But adding 'nf2' should at least make it visible!
If you are using NetBeans for the layout of card1,
then it is in all likelihood using a GroupLayoutManager,
and adding a component like a JTextField to such a
manager by hand is not an easy task; it is certainly not as easy
as 'card1.add(nf2)'.

The problem with using NetBeans for your layout is when
you need to add a dedicated component that is NOT in the
component palette! Although you can drag a JTextField into
your panel, you cannot drag a 'NumericField' into that same
panel.

I explained a way out for this, but before going into that
with some more details, can you explain first how you layout
your cardXX panels?

And: do you at least see 'nf1' appearing in 'card17'?
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:How did you layout this card1 panel?

But adding 'nf2' should at least make it visible!
If you are using NetBeans for the layout of card1,
then it is in all likelihood using a GroupLayoutManager,
and adding a component like a JTextField to such a
manager by hand is not an easy task; it is certainly not as easy
as 'card1.add(nf2)'.

The problem with using NetBeans for your layout is when
you need to add a dedicated component that is NOT in the
component palette! Although you can drag a JTextField into
your panel, you cannot drag a 'NumericField' into that same
panel.

I explained a way out for this, but before going into that
with some more details, can you explain first how you layout
your cardXX panels?

And: do you at least see 'nf1' appearing in 'card17'?


That really is the downside of using Netbeans though having to drag n drop stuff for the GUI makes life a bit easier, still it's troublesome when you want to work on some things that Netbeans don't really want you to. I am using Cardlayout and have a total of 19 cards or Jpanels in my class and I have 1 mainpanel that holds those 19 Jpanels, each panel has it's own GUI different from each other they are used to transfer the user from one page to another. Where and How can I see if "nf1" is appearing in card17? Also thank you for replying again and I have to pause my progress in the other thread as I find it hard to work on 2 things at the same time especially when I need to study both of them thoroughly to better understand them. I hope this post of mine helps you improve your knowledge more.

Mainpanel
-cardlayout
-card1
-jtextfield
-jbutton
-card2
-etc
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, your application is very ambitious, that is for sure!

What you do is the following:

1) go to your 'card17' panel in NetBeans, using the GUI builder

2) drag a JPanel onto 'card17', at about the place where our 'nf1' should appear.

3) give this panel a clear name, and give it a distinctive backgroundcolor. Suppose we name
this JPanel 'PanelForNumericFieldnf1'.

4) now, if you press the 'Source' button, in the button bar right above the program-panel,
('Source' is the left most one), you will see the code that NetBeans generated.
It looks horrible, but let that not scare you.

5) locate the line with the code 'initComponents()';

6) type right below this line, this code: initMyOwnVariables();

7) create a method with this name. In this method you can initialize all your own
variables. It is here that we will create 'nf1'

8) So, type in:


And finally, run your program. If you click on your tab 'card17' you should now see
the NumericField.

If all is okay, you can set the background of that panel to transparant.
 
rodolfo tuble
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:Well, your application is very ambitious, that is for sure!

What you do is the following:

1) go to your 'card17' panel in NetBeans, using the GUI builder

2) drag a JPanel onto 'card17', at about the place where our 'nf1' should appear.

3) give this panel a clear name, and give it a distinctive backgroundcolor. Suppose we name
this JPanel 'PanelForNumericFieldnf1'.

4) now, if you press the 'Source' button, in the button bar right above the program-panel,
('Source' is the left most one), you will see the code that NetBeans generated.
It looks horrible, but let that not scare you.

5) locate the line with the code 'initComponents()';

6) type right below this line, this code: initMyOwnVariables();

7) create a method with this name. In this method you can initialize all your own
variables. It is here that we will create 'nf1'

8) So, type in:


And finally, run your program. If you click on your tab 'card17' you should now see
the NumericField.

If all is okay, you can set the background of that panel to transparant.


Regarding step 8, I actually don't know what you mean by that. So sorry.

Also this is what I tried:



since if I follow your code I get an error where nf1 is not declared.

This is the NumericField I used:


I also don't know what to expect in my "PanelForNumericFieldnf1" when I run the code I see the Jpanel but its the same when I placed it there lonely and gray. Thank you once again.
 
Piet Souris
Rancher
Posts: 1783
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I created a new JFrame application i NetBeans, dragged a JPanel into the frame
and called it 'PanelForNumericFieldnf1'.

Therewas one thing I had to do as well: I had to set the Layoutmanager of
this panel to 'FlowLayout'. I missed that in my earlier step-by-step description.
Right click on that panel, and in the pop-up menu choose 'Set Layout' and go
for 'FlowLayout'.

Having done that, I get the following listing:


(for technical reasons I had to change the name to 'NumericField1').

Run this code, and you will see this NumericField appearing in the panel.
If you replace this panel with your 'card17', you should get the same
outcome.

One remark:

in your version of ' initMyOwnVariables()' I see:

'nf1' is now a local variable, not known outside of this method.

If you look at my code, you'll see I made that component a member variable.
Th advantage is is that I have this variable available everywhere in the code,
but whether that is necessary, I don't know. But for now it might be safest to do so.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!