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