TextField Document model

Mark Claassen markclaassenx at gmail.com
Thu Oct 18 12:03:15 PDT 2012


My initial proof of concept worked perfectly... limited to 10 characters,
forced upper case

Altering the source I did the following:
Made TextInputControl.Content public
Made a setContent(Content content) method in TextInputControl
Made the member variable "content" in TextInputControl to be non-final
Made TextFieldContent in TextField public
Made TextFieldContent in TextField non-static

In my source code, I then did:
        TextInputControl.Content content = new TextField.TextFieldContent()
{
            @Override
            public void insert(int i, String string, boolean bln) {
                if (10 - length() => string.length())
                    super.insert(i, string.toUpperCase(), bln);
            }
        };

I don't know why the designers made these things final and
private/protected.  I would imagine they had a reason, so my JFX source
changes would probably need to be more carefully considered.  I just wanted
tom show it was possible.

Mark


On Thu, Oct 18, 2012 at 2:37 PM, Mark Claassen <markclaassenx at gmail.com>wrote:

> I got the source and figured it out...or at least found a problem.
>
> The TextInputControl.Content seems to be exactly what I need.  However, it
> is not public.  Further, the instance variable is a final member in
> TextInputControl.
>
> First, Content, and the default implementations, need to be public so they
> can be easily extended.  I have feeling these were intended to be public
> when the time was right.
>
> Second, there needs to be some way to plug this behavior.  If it is going
> to remain final, then there needs to be a way to specify the Content class
> in the FXML.  The SceneBuilder is clearly the way most UIs are supposed to
> be designed, so, therefore, it needs to be pretty all-encompassing.
>
> Mark
>
>
> On Wed, Oct 17, 2012 at 5:05 PM, Scott Palmer <swpalmer at gmail.com> wrote:
>
>> Using the override mechanism that Will suggested is probably easier for
>> converting to uppercase.
>>
>> final TextField allCapsTextField = new TextField() {
>>         @Override
>>         public void replaceText(int start, int end, String text) {
>>                 super.replaceText(start, end, text.toUppercase());
>>         }
>>         @Override
>>         public void replaceSelection(String text) {
>>                 super.replaceSelection(text.toUppercase());
>>         }
>> };
>>
>> or you could still use the Event Filter and handle the insertion of the
>> characters manually if they are lowercase
>> and then consume the event.  I think that will be more work and be more
>> error-prone though.  As you mention you would have to handle pasting and
>> drag and drop and all ugly details.  Overriding seems cleaner.
>>
>> Perhaps you should take a look at the source code to TextInputControl.
>>  Instead of the Document they have a Content interface.  Maybe you can do
>> some of what you want by overriding getContent().
>>
>> Scott
>>
>> On 2012-10-17, at 4:41 PM, Mark Claassen <markclaassenx at gmail.com> wrote:
>>
>> > Thanks for the tips.  The overriding method does not seem very
>> pluggable,
>> > so I started with the event filter.
>> >
>> > I like the idea of an event filter, and I really like the how JavaFX
>> > defined the process and the order in which items will receive events.
>> >
>> > So, I quickly implemented my event filter like this:
>> >        input.addEventFilter(KeyEvent.
>> > KEY_TYPED, new EventHandler<KeyEvent>() {
>> >            @Override
>> >            public void handle(KeyEvent t) {
>> >                if (input.getText().length() >=10)
>> >                    t.consume();
>> >            }
>> >        });
>> >
>> > This works for typing, but, of course, I can paste whatever I wanted.
>> > (Perhaps I need to find a second filter for that?  How about DnD?)
>> >
>> > All input events go through the Swing Document, so with that, there was
>> > just one method to mess with.
>> >
>> > Further, I currently have a Document implementation that takes user
>> input
>> > and converts it to upper case.  (It doesn't force the user to type in an
>> > upper case character, it just converts it if it is not.)  Since, in the
>> > case of a Document, I can control exactly what the data is, this is
>> pretty
>> > straightforward.  How is that accomplished here?  Consume the event, and
>> > then first a new modified copy of the original.  Or do I need to start
>> > overriding various methods?
>> >
>> >
>> > On Wed, Oct 17, 2012 at 4:40 PM, Mark Claassen <markclaassenx at gmail.com
>> >wrote:
>> >
>> >> Thanks for the tips.  The overriding method does not seem very
>> pluggable,
>> >> so I started with the event filter.
>> >>
>> >> I like the idea of an event filter, and I really like the how JavaFX
>> >> defined the process and the order in which items will receive events.
>> >>
>> >> So, I quickly implemented my event filter like this:
>> >>        input.addEventFilter(KeyEvent.KEY_TYPED, new
>> >> EventHandler<KeyEvent>() {
>> >>            @Override
>> >>            public void handle(KeyEvent t) {
>> >>                if (input.getText().length() >=10)
>> >>                    t.consume();
>> >>            }
>> >>        });
>> >>
>> >> This works for typing, but, of course, I can paste whatever I wanted.
>> >> (Perhaps I need to find a second filter for that?  How about DnD?)
>> >>
>> >> All input events go through the Swing Document, so with that, there was
>> >> just one method to mess with.
>> >>
>> >> Further, I currently have a Document implementation that takes user
>> input
>> >> and converts it to upper case.  (It doesn't force the user to type in
>> an
>> >> upper case character, it just converts it if it is not.)  Since, in the
>> >> case of a Document, I can control exactly what the data is, this is
>> pretty
>> >> straightforward.  How is that accomplished here?  Consume the event,
>> and
>> >> then first a new modified copy of the original.  Or do I need to start
>> >> overriding various methods?
>> >>
>> >> Mark
>> >>
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> On Wed, Oct 17, 2012 at 2:13 PM, Will Hoover <java.whoover at gmail.com
>> >wrote:
>> >>
>> >>> Have you tried:
>> >>>
>> >>> final TextField tf = new TextField() {
>> >>>        final String restictTo = "[A-Z\\s]*";
>> >>>        @Override
>> >>>        public void replaceText(int start, int end, String text) {
>> >>>                if (matchTest(text)) {
>> >>>                        super.replaceText(start, end, text);
>> >>>                }
>> >>>        }
>> >>>        @Override
>> >>>        public void replaceSelection(String text) {
>> >>>                if (matchTest(text)) {
>> >>>                        super.replaceSelection(text);
>> >>>                }
>> >>>        }
>> >>>        private boolean matchTest(String text) {
>> >>>                return text.isEmpty() || text.matches(restictTo);
>> >>>        }
>> >>> };
>> >>>
>> >>> -----Original Message-----
>> >>> From: openjfx-dev-bounces at openjdk.java.net
>> >>> [mailto:openjfx-dev-bounces at openjdk.java.net] On Behalf Of Mark
>> Claassen
>> >>> Sent: Wednesday, October 17, 2012 1:08 PM
>> >>> To: openjfx-dev at openjdk.java.net
>> >>> Subject: TextField Document model
>> >>>
>> >>> JTextComponents (like JTextField) has a javax.swing.text.Document
>> model
>> >>> that
>> >>> made it pretty easy to create a text field that only allowed a certain
>> >>> number of characters in it.  Similarly, it was also easy to make a
>> >>> Document
>> >>> model that took all input, but forced characters to upper case.
>> >>>
>> >>> @Override
>> >>> public void insertString(int offs, String str, AttributeSet a) throws
>> >>> BadLocationException {
>> >>>     <Do stuff>
>> >>> }
>> >>>
>> >>> What is there going to be in JavaFX to accomplish the same goals?
>> >>>
>> >>> Mark
>> >>>
>> >>>
>> >>
>>
>>
>


More information about the openjfx-dev mailing list