-
Notifications
You must be signed in to change notification settings - Fork 236
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
Button -- Or Obvious Clickable Link (Inside Text Area) #124
Comments
I think this is similar to my request in #87 for adding support to insert arbitrary nodes. |
Adding a button would indeed require #87. Clickable text does not, and you can do that with RichTextFX. You will not be able to use any of the specialized subclasses like Here is a demo package org.fxmisc.richtext.demo;
import javafx.application.Application;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.IndexRange;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import org.fxmisc.richtext.StyledTextArea;
public class InlineLink extends Application {
static class MyStyleDef {
static final MyStyleDef NO_LINK = new MyStyleDef();
private final String url;
private MyStyleDef() {
this(null);
}
MyStyleDef(String url) {
this.url = url;
}
void applyToText(Text text) {
if(url != null) {
text.setCursor(Cursor.HAND);
text.setFill(Color.BLUE);
text.setUnderline(true);
text.setOnMouseClicked(click -> {
System.out.println("Go to " + url);
});
}
}
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
StyledTextArea<MyStyleDef> area = new StyledTextArea<MyStyleDef>(
MyStyleDef.NO_LINK,
(text, style) -> style.applyToText(text));
Button addLink = new Button("Add link");
addLink.setOnAction(ae -> {
IndexRange range = area.getSelection();
area.setStyle(
range.getStart(), range.getEnd(),
new MyStyleDef("https://github.com/TomasMikula/RichTextFX"));
});
VBox.setVgrow(area, Priority.ALWAYS);
area.setWrapText(true);
VBox vbox = new VBox(addLink, area);
Scene scene = new Scene(vbox, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
} and the result: |
Hi Tomas - I've recently started learning RichTextFX and I have been experimenting with this demo. I have noticed that single-clicking on the hyperlink does not consistently trigger the "Go to..." callback. About one in ten times, the click is ignored. I first observed this in my own app, but I can duplicate the issue with your demo code. I'm almost certain it's connected with the behaviour of the flashing caret. If you happen to click the link at the exact location of the caret while the caret is visible, it seems that the MOUSE_CLICKED event is delivered to the ParagraphText node rather than the TextExt node (and TextExt doesn't get a chance to see it). The reason seems to be connected with the way that Java FX locates the target for the mouse event (see Scene:3551 ish) - I am fairly sure that the flashing of the caret is confusing this algorithm. I've been trying to find a workaround but all my ideas have failed. I wondered if you had any insights please ? Btw thank you for creating such a powerful framework, it has saved me a huge amount of time and frustration ! |
btw, with reference to my earlier comment, here's a shot from the debugger during one of these "failed" clicks. Notice that the "pressedTargets" and "releasedTargets" are not identical, which means that FX selects the ParagraphText node as the one that receives the mouse event, rather than the TextExt. Like I say, I think this must be related to the flashing of the caret but I have no idea how to work around the problem. thanks again, |
Ah I think I found a solution ! I went down the rabbit hole of trying to write my own "mouse pick" routine that would ignore certain types of node, but then I realised that every node has a "MouseTransparent" property. If I modify the source of CaretNode to set this to true, my problem goes away. Hooray ! Can anyone thing of a reason why you would ever want the caret to not be transparent ? I can't think of a valid case. |
Hi @chrisf-london thanks for chasing this down. Could you submit a PR please and I'll be happy to merge it. |
If you install a mouse handler on a TextExt area using setOnMouseClicked(), there's a small chance that your mouse click will be ignored (this happens approximately one time in ten in my experience). The problem occurs when you click at the exact same position as the flashing caret while the caret is visible; this confuses the java FX mouse-picking algorithm, which causes the MouseEvent to be sent to the ParagraphText node rather than the TextExt. The fix is simply to make the caret transparent to mouse picking. See this link for more evidence + screenshots : FXMisc#124
Hi Jugen - thanks, just did it. I hope the format is ok (my first time PR'ing to this repo) |
If you install a mouse handler on a TextExt area using setOnMouseClicked(), there's a small chance that your mouse click will be ignored (this happens approximately one time in ten in my experience). The problem occurs when you click at the exact same position as the flashing caret while the caret is visible; this confuses the java FX mouse-picking algorithm, which causes the MouseEvent to be sent to the ParagraphText node rather than the TextExt. The fix is simply to make the caret transparent to mouse picking. See this link for more evidence + screenshots : #124
Can we have a Wrapping Button or clickable Link inside a text area? -- Something like a button that is obvious to click on -- that would show a (VIDEO) or (PICTURE) but have formatted text.
Thanks
The text was updated successfully, but these errors were encountered: