Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement: Make insertion style a convenience generic method #209

Closed
ghost opened this issue Nov 17, 2015 · 12 comments
Closed

Improvement: Make insertion style a convenience generic method #209

ghost opened this issue Nov 17, 2015 · 12 comments

Comments

@ghost
Copy link

ghost commented Nov 17, 2015

Hi Tomas, following on earlier communication. I am logging this request so that it is trackable.
Would be great if there was a way to define insertion style of new text, without having to have it be applied first to caret location.
Best,
maher

@ghost ghost changed the title Improvement: Make insertion style a method Improvement: Make insertion style a convenience generic method Nov 17, 2015
@JordanMartinez
Copy link
Contributor

Correct me if I'm wrong @melkhaldi, but I think this can already be done. If one wanted to do what you suggest, wouldn't they just do the following?

StyledTextArea<?, ?> area = // creation code...
int start = // somewhere in the area
int end = // somewhere else in the area
S desiredStyleInsertion = //
PS desiredParagraphStyleInsertion = //
ReadOnlyStyledDocument doc = ReadOnlyStyledDocument.fromString(
    "some text insertion",
    desiredStyleInsertion,
    desiredParagraphStyleInsertion
);

area.replace(start, end, doc);

@ghost
Copy link
Author

ghost commented Jan 17, 2016

Hi Jordan,
The use case for this feature request came from a previous text-editor prototype. I wanted to define a style in my text-editor to be used for anything that the user will enter next (once I define the style). In that implementation, I did something like a current style string property, to which the text area listens. once changed, it applied that style to the caret position by inserting a one space, then reset the caret back one step. Being a new programmer, things didn't work quite well.

I believe the code example suggested above will work for replacing text. but would it work when the area receives text input (user typing)?
ps.(Sorry was travelling, and been trying to catch up with things).

@JordanMartinez
Copy link
Contributor

Ok, that makes sense. Let me see if I understand you correctly. When you modify the text and style within the StyledTextArea programmatically (i.e. you code it to do stuff at certain points), you want it to do what it normally does. On the other hand, when a user inputs text (modifying text and style via user interaction), then you want that user-inputted text to be styled a certain way. However, the style that should be used to style the user-inputted text can change from time to time. Is that about right?

I believe the code example suggested above will work for replacing text. but would it work when the area receives text input (user typing)?

Yes! All you'd need to do is override the EventHandler. Here's an example

class RichTextArea extends StyledTextArea {
    private static final EventHandlerTemplate<RichTextArea, ? super KeyEvent> KEY_TYPED_TEMPLATE;
    static {
        KEY_TYPED_TEMPLATE = EventHandlerTemplate
             .on(KeyEvent.KEY_TYPED)
             .act(RichTextArea::inserUserText)
             .create();
    }

    RichTextArea(/* constructor params */) {
        // constructor code
        EventHandler<? super KeyEvent> keyTypedHandler = KEY_TYPED_TEMPLATE.bind(this);
        // Note: use `install()`, not `installAfter()` here. The former applies before 
        // implementations of the latter, which in your case prevents it from occurring.
        EventHandlerHelper.install(onKeyTypedProperty(), keyTypedHandler);
    }

    public void insertUserText(String text) {
        IndexRange sel = getSelection();
        S currentUserStyle = // get the current style used for user input
        PS curretParagraphStyle = // get current style used for user input
        replace(sel.getStart(), sel.getEnd(), ReadOnlyStyledDocument.fromString(
            text,
            currentUserStyle,
            currentParagraphStyle
        ));
    }
}

If you look at StyledTextAreaBehavior, you can see how Tomas initially creates the handlers for StyledTextArea and if you look at StyledTextArea's javadoc, you can see his example of overriding the default handlers.
Additionally, if you look at the method-chain from StyledTextAreaBehavior#keyTyped() to the method that actually modifies the underlying EditableStyledDocument, you'll see an implementation similar to this one:

  • StyledTextAreaBehavior::keyTyped
  • StyledTextArea::replaceSelection(String replacement)
  • StyledTextArea::replaceText(IndexRange range, String text)
  • StyledTextArea::replaceText(int start, int end, String text)
  • StyledTextArea::replaceText(int start, int end, StyledDocument<S, PS> replacement) (See the method's body here)

@ghost
Copy link
Author

ghost commented Jan 17, 2016

Yes that is correct. In my mind, if an insertion style is set as a public
property of the text area. Then there are two supported scenarios: 1)
insertion style is bound to style at caret by default(which can be set in
constructor); 2) insertion style can be unbound from caret style, then
bound to an external property, for example something that the user can
interactively define in the GUI, or programmatically based on some logic...
(is this considered presenter pattern by the way?)
On Jan 16, 2016 8:17 PM, "JordanMartinez" notifications@github.com wrote:

Ok, that makes sense. Let me see if I understand you correctly. When you
modify the text and style within the StyledTextArea programmatically
(i.e. you code it to do stuff at certain points), you want it to do what it
normally does. On the other hand, when a user inputs text (modifying text
and style via user interaction), then you want that user-inputted text to
be styled a certain way. However, the style that should be used to style
the user-inputted text can change from time to time. Is that about right?

I believe the code example suggested above will work for replacing text.
but would it work when the area receives text input (user typing)?

Yes! All you'd need to do is override the EventHandler. Here's an example

class RichTextArea extends StyledTextArea {
private static final EventHandlerTemplate<RichTextArea, ? super KeyEvent> KEY_TYPED_TEMPLATE;
static {
KEY_TYPED_TEMPLATE = EventHandlerTemplate
.on(KeyEvent.KEY_TYPED)
.act(RichTextArea::inserUserText)
.create();
}

RichTextArea(/* constructor params */) {
    // constructor code
    EventHandler<? super KeyEvent> keyTypedHandler = KEY_TYPED_TEMPLATE.bind(this);
    // Note: use `install()`, not `installAfter()` here. The former applies before
    // implementations of the latter, which in your case prevents it from occurring.
    EventHandlerHelper.install(onKeyTypedProperty(), keyTypedHandler);
}

public void insertUserText(String text) {
    IndexRange sel = getSelection();
    S currentUserStyle = // get the current style used for user input
    PS curretParagraphStyle = // get current style used for user input
    replace(sel.getStart(), sel.getEnd(), ReadOnlyStyledDocument.fromString(
        text,
        currentUserStyle,
        currentParagraphStyle
    ));
}

}

If you look at StyledTextAreaBehavior, you can see how Tomas initially
creates the handlers for StyledTextArea and if you look at StyledTextArea's
javadoc, you can see his example of overriding the default handlers.
Additionally, if you look at the method-chain from
StyledTextAreaBehavior#keyTyped() to the method that actually modifies
the underlying EditableStyledDocument, you'll see an implementation
similar to this one:


Reply to this email directly or view it on GitHub
#209 (comment)
.

@JordanMartinez
Copy link
Contributor

Ok. I see what you mean. Yeah, that would just need to be implemented on top of Tomas' work.

MVC vs MVVM vs MVP seem to be defined differently by different people. I can't remember which link I specifically read that explain them in detail, but this link seems helpful. I won't say whether it is or not because the differences between them are otherwise unimportant to me because they all adhere to the Separation of Concerns (the most important point), just in their own way.

Also, do you know how to style your comments using GitHub-flavored Markdown? I've noticed that you tend not to style them.

@JordanMartinez
Copy link
Contributor

Sorry was travelling, and been trying to catch up with things.

I hope you have a good time traveling 😄

@ghost
Copy link
Author

ghost commented Jan 17, 2016

Yes, i didn't really know about markdown in got until you mentioned it..
Will give it a try. Thanks! It was good :)
On Jan 16, 2016 9:34 PM, "JordanMartinez" notifications@github.com wrote:

Sorry was travelling, and been trying to catch up with things.

I hope you have a good time traveling [image: 😄]


Reply to this email directly or view it on GitHub
#209 (comment)
.

@JordanMartinez
Copy link
Contributor

Hey @melkhaldi, did the above solution work for you? I was wondering if this issue could be closed or not.

@ghost
Copy link
Author

ghost commented Jan 26, 2016

I guess yes! Although the implementation I am suggesting can be tagged as a
suggested improvement -- maybe adding convenience methods. :)
On Jan 25, 2016 6:56 PM, "JordanMartinez" notifications@github.com wrote:

Hey @melkhaldi /~https://github.com/melkhaldi, did the above solution
work for you? I was wondering if this issue could be closed or not.


Reply to this email directly or view it on GitHub
#209 (comment)
.

@JordanMartinez
Copy link
Contributor

So, you're suggesting something like...

// Properties
private PS insertionParagraphStyle;
public final void setInsertionParagraphStyle(PS style) { insertionParagraphStyle = style; }
public final PS getInsertionParagraphStyle() {
    return insertionParagraphStyle == null
                ? initialParagraphStyle
                : insertionParagraphStyle;
}
private S insertionTextStyle;
public final void setInsertionTextStyle(S style) { insertionTextStyle = style; }
public final S getInsertionTextStyle() {
    return insertionTextStyle == null
                ? initialStyle
                : insertionTextStyle;
}

public final void replaceTextWithInsertionStyle(int from, int to, String text) {
    ReadOnlyStyledDocument<PS, S> doc = ReadOnlyStyledDocument.fromString(
        text,
        getInsertionParagraphStyle(),
        getInsertionTextStyle()
    );
    replace(from, to, doc);

@ghost
Copy link
Author

ghost commented Jan 26, 2016

Yes :)
On Jan 25, 2016 7:14 PM, "JordanMartinez" notifications@github.com wrote:

So, you're suggesting something like...

// Propertiesprivate PS insertionParagraphStyle;public final void setInsertionParagraphStyle(PS style) { insertionParagraphStyle = style; }public final PS getInsertionParagraphStyle() {
return insertionParagraphStyle == null
? initialParagraphStyle
: insertionParagraphStyle;
}private S insertionTextStyle;public final void setInsertionTextStyle(S style) { insertionTextStyle = style; }public final S getInsertionTextStyle() {
return insertionTextStyle == null
? initialStyle
: insertionTextStyle;
}
public final void replaceTextWithInsertionStyle(int from, int to, String text) {
ReadOnlyStyledDocument<PS, S> doc = ReadOnlyStyledDocument.fromString(
text,
getInsertionParagraphStyle(),
getInsertionTextStyle()
);
replace(from, to, doc);


Reply to this email directly or view it on GitHub
#209 (comment)
.

@JordanMartinez
Copy link
Contributor

I think this issue should be closed as the proposed method could be implemented on top of RTFX. If that's not possible due to casting issues (like if one wanted to use StyledTextArea as opposed to their subclass of it), there are other ways to still accomplish it.
Please reopen if you think otherwise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant