-
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
Using "setStyle" two times in a row causes inexplicable scrolling #525
Comments
Could you provide a reproducible demo? I'm not fully understanding the issue. This may have something to do with #390 |
Also, which milestone release are you using for 0.7? |
Many thx for your replay. I forget to tell you that i use setStyle TWO TIMES in a row (i edited my post). The first setStyle is changing a range at the beginning of the document and the second one ist changing the style of a character in the mid of the document. For example changing the -rtfx-background-color of the opening I will give you an examplecode asap (maybe in a few hours) ;) At first i started with version 6.10 and it worked. Now i am using v7 Milestone 5. |
Hi, i was able to reproduce the issue. setStyle - or setStyleClass seems not to be the problem. I wrote a method which shall reset the styles of every character to default and this caused the jumps. Look at the last method in my following code example (you can test it by clicking after the last // The CodeArea is child of this VBox
@FXML VBox richtext;
// Patterns to identify TAGS like <div> or <table>
private final Pattern PATTERN = Pattern.compile("(?<TAG><[^\\?](.*?)[ >]|/>)", Pattern.DOTALL);
// Lets build a simple CodeArea and insert it into the above mentioned VBox
public void initialize() {
// The CodeArea
CodeArea ca = new CodeArea();
// Some Sampletext (its neccessary cause the used caretPositions are hardcoded)
ca.replaceText(
"<div class=\"alert alert-danger\">\n" +
" <table>\n" +
" <tr>\n" +
" <td><span class=\"fa fa-close ft_size_27 mg_right_20\"></span></td>\n" +
" <td>\n" +
" {*\n" +
" 1: Username (> 255 || < 5)\n" +
" 2: Firstname (>255 || < 5)\n" +
" 3: Lastname (>255 || < 5)\n" +
" 4: EMail not valid\n" +
" 5: EMail already exists\n" +
" 6: Username already exists\n" +
" 7: Password too short or too long\n" +
" 8: Passwords doesnt match\n" +
" *}\n" +
" {$76be98f9171351b8444a6287fb7f31b3a6c28802}: \n" +
" {if $error eq 1}\n" +
" {$7884fc242eaf64d217d37262b0548582047b29b1}\n" +
" {/if}\n" +
" {if $error eq 2}\n" +
" {$bdfb20b48b66009e556c6437dc020a34a8c6fbf7}\n" +
" {/if}\n" +
" {if $error eq 3}\n" +
" {$d49a9d3450b7852da8932886b6e748a49c11621c}\n" +
" {/if}\n" +
" {if $error eq 4}\n" +
" {$1f91fe7c8c2c73855fcd86bc09c3c769f31ad245}\n" +
" {/if}\n" +
" {if $error eq 5}\n" +
" {$5e7ebc57cef21ce27246943fc69b4edd14f77f34}\n" +
" {/if}\n" +
" {if $error eq 6}\n" +
" {$4e13086230c1f4a3e537a6897f75118a25c544ae}\n" +
" {/if}\n" +
" {if $error eq 7}\n" +
" {$d8b61303910a0b8181828955fa57228821c4a94d}\n" +
" {/if}\n" +
" {if $error eq 8}\n" +
" {$d8b61303910a0b8181828955fa57228821c4a94d}\n" +
" {/if}\n" +
" <br/>\n" +
" <a href=\"\" onClick=\"history.go(-1);return true;\">\n" +
" {$5282443314cba22f63d935a02958e64895f0053f}\n" +
" </a>\n" +
" </td>\n" +
" </tr>\n" +
" </table>\n" +
"</div><!-- Hinweisbox: danger -->"
);
// here we insert the CodeArea into the VBox and setting the prefHeight
richtext.getChildren().add(new VirtualizedScrollPane<>(ca));
ca.setPrefHeight(800.0);
// Now its going to be interesting...
// Whenever the user clicks with the mouse it checks, if the caretPosition is after 1648
// If true -> setStyleClass of caret 1647-1648 and 37-38 to "highlight"
ca.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
// in the following line comes the issue
// this line shall reset the whole text to default style
ca.setStyleSpans(0, computeHighlighting(ca.getText())); // <-- ISSUE
// after text is set to default i want to change some specific chars
// this works fine, but if i click again somewhere the line above makes now a jump
// to Position 37
if(ca.getCaretPosition() == 1648)
{
ca.setStyleClass(37, 38, "highlight");
ca.setStyleClass(ca.getCaretPosition()-1, ca.getCaretPosition(), "highlight");
}
}
});
}
// This method is the probleme i guess.
// It shall reset every stylechanges i made before to the defined regular expressions
public StyleSpans<Collection<String>> computeHighlighting(String text) {
Matcher matcher = PATTERN.matcher(text);
int lastKwEnd = 0;
StyleSpansBuilder<Collection<String>> spansBuilder = new StyleSpansBuilder<>();
while (matcher.find()) {
String styleClass = matcher.group("TAG") != null ? "tag" : null;
assert styleClass != null;
spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd);
spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start());
lastKwEnd = matcher.end();
}
spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
return spansBuilder.create();
} |
I think your problem might be caused by using Try changing that and see it if makes any difference. |
Hi Jordan, i tried the following: InputMap<MouseEvent> testEvent = InputMap.consume(
mousePressed()
);
// Now its going to be interesting...
// Whenever the user clicks with the mouse it checks, if the caretPosition is after 1648
// If true -> setStyleClass of caret 1647-1648 and 37-38 to "highlight"
EventHandler<MouseEvent> mouseClick = e -> {
// in the following line comes the issue
// this line shall reset the whole text to default style
ca.setStyleSpans(0, computeHighlighting(ca.getText())); // <-- ISSUE
// after text is set to default i want to change some specific chars
// this works fine, but if i click again somewhere the line above makes now a jump
// to Position 37
if(ca.getCaretPosition() == 1648)
{
ca.setStyleClass(37, 38, "highlight");
ca.setStyleClass(ca.getCaretPosition()-1, ca.getCaretPosition(), "highlight");
}
};
Nodes.addInputMap(ca, testEvent);
ca.setOnMouseClicked(mouseClick); I navigate to the position 1648 by using the Keyboard (cause i consumed the default MousePressed event) and then i clicked with the mouse so my EventHandler is doing its job but its the same result. If i delete one of the (doesnt matter which one) |
I ran the following code and clicked the mouse in the area. The scroll jump was seen without the two import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.model.StyleSpans;
import org.fxmisc.richtext.model.StyleSpansBuilder;
import org.fxmisc.wellbehaved.event.EventPattern;
import org.fxmisc.wellbehaved.event.InputMap;
import org.fxmisc.wellbehaved.event.Nodes;
import java.util.Collection;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TwiceBug extends Application {
// Patterns to identify TAGS like <div> or <table>
private final Pattern PATTERN = Pattern.compile("(?<TAG><[^\\?](.*?)[ >]|/>)", Pattern.DOTALL);
@Override
public void start(Stage primaryStage) throws Exception {
CodeArea ca = new CodeArea();
ca.setPrefHeight(200);
VBox box = new VBox(new VirtualizedScrollPane<>(ca));
primaryStage.setScene(new Scene(box));
primaryStage.show();
ca.replaceText("<div class=\"alert alert-danger\">\n" +
" <table>\n" +
" <tr>\n" +
" <td><span class=\"fa fa-close ft_size_27 mg_right_20\"></span></td>\n" +
" <td>\n" +
" {*\n" +
" 1: Username (> 255 || < 5)\n" +
" 2: Firstname (>255 || < 5)\n" +
" 3: Lastname (>255 || < 5)\n" +
" 4: EMail not valid\n" +
" 5: EMail already exists\n" +
" 6: Username already exists\n" +
" 7: Password too short or too long\n" +
" 8: Passwords doesnt match\n" +
" *}\n" +
" {$76be98f9171351b8444a6287fb7f31b3a6c28802}: \n" +
" {if $error eq 1}\n" +
" {$7884fc242eaf64d217d37262b0548582047b29b1}\n" +
" {/if}\n" +
" {if $error eq 2}\n" +
" {$bdfb20b48b66009e556c6437dc020a34a8c6fbf7}\n" +
" {/if}\n" +
" {if $error eq 3}\n" +
" {$d49a9d3450b7852da8932886b6e748a49c11621c}\n" +
" {/if}\n" +
" {if $error eq 4}\n" +
" {$1f91fe7c8c2c73855fcd86bc09c3c769f31ad245}\n" +
" {/if}\n" +
" {if $error eq 5}\n" +
" {$5e7ebc57cef21ce27246943fc69b4edd14f77f34}\n" +
" {/if}\n" +
" {if $error eq 6}\n" +
" {$4e13086230c1f4a3e537a6897f75118a25c544ae}\n" +
" {/if}\n" +
" {if $error eq 7}\n" +
" {$d8b61303910a0b8181828955fa57228821c4a94d}\n" +
" {/if}\n" +
" {if $error eq 8}\n" +
" {$d8b61303910a0b8181828955fa57228821c4a94d}\n" +
" {/if}\n" +
" <br/>\n" +
" <a href=\"\" onClick=\"history.go(-1);return true;\">\n" +
" {$5282443314cba22f63d935a02958e64895f0053f}\n" +
" </a>\n" +
" </td>\n" +
" </tr>\n" +
" </table>\n" +
"</div><!-- Hinweisbox: danger -->");
// ignore any default behavior
Nodes.addInputMap(ca, InputMap.consume(EventPattern.mousePressed()));
ca.setOnMouseClicked((event) -> {
// simulate correct user click
ca.moveTo(1648);
ca.setStyleSpans(0, computeHighlighting(ca.getText()));
if(ca.getCaretPosition() == 1648) {
// ca.setStyleClass(37, 38, "highlight");
// ca.setStyleClass(ca.getCaretPosition()-1, ca.getCaretPosition(), "highlight");
}
});
// simulate scroll to the bottom
ca.showParagraphAtBottom(ca.getParagraphs().size() - 1);
// now user needs to manually click in the area
}
public StyleSpans<Collection<String>> computeHighlighting(String text) {
Matcher matcher = PATTERN.matcher(text);
int lastKwEnd = 0;
StyleSpansBuilder<Collection<String>> spansBuilder = new StyleSpansBuilder<>();
while (matcher.find()) {
String styleClass = matcher.group("TAG") != null ? "tag" : null;
assert styleClass != null;
spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd);
spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start());
lastKwEnd = matcher.end();
}
spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
return spansBuilder.create();
}
} Also, just to be clearer, the above code is what I mean by a reproducible demo. Yours doesn't quite fit it because I can't copy and paste into my IDE and immediately run it. Please reopen if that wasn't the issue and I somehow misunderstood you. |
Hey ;)
i upgraded from v6 to v7 and i noticed that there is an issue when using area.setStyle(0,1,"...") two times in a row with different ranges.
For example:
setStyle(0, 1, Arrays.asList("highlight")); setStyle(10000, 10001, Arrays.asList("highlight"));
Causes the following behavior:
After calling the method which includes the above code nothing special happen. The styles are changed like i expect. But after i begin typing the scrollingposition changes to position 0 (or 1) like set in the first line.
In v6 the scrollingposition did not change.
Maybe someone knows a workaround or something what could help me.
The text was updated successfully, but these errors were encountered: