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

Setting the vertical (horizontal as well?) scrollbar positions #130

Closed
fge opened this issue Mar 22, 2015 · 8 comments
Closed

Setting the vertical (horizontal as well?) scrollbar positions #130

fge opened this issue Mar 22, 2015 · 8 comments

Comments

@fge
Copy link

fge commented Mar 22, 2015

For this project, right now I use a TextFlow to insert decorated fragments of text.

When a parsing node is selected, I change the text content into the TextFlow and set the relative vertical scrollbar position so that the beginning of the match, or failure, is visible.

But I can't do that with RichTextFX as far as I can see.

The problem is that in order to better highlight the match, I change the text entirely. I collect the fragments, build the new string and .clear() then .appendText(), this works, I get the new text; and I can style it correctly.

But the scrollbar always jump to the bottom and I can't get it to position where I want; moreover, if I try and insert the widget into a ScrollPane (which is what I do with a TextFlow, and which is how I can position the scrollbar), the widget doesn't size correctly...

So, do I have to use a ScrollPane anyway? Or how do I position the scrollbar to where I want?

@ghost
Copy link

ghost commented Mar 22, 2015

As far as I know you can only position the caret and that should set the
view port and scroll bars. Scrollbar positioning is not supported due to
how java controls work..that's my guess. The expert should have a better
explanation!
On Mar 21, 2015 6:43 PM, "Francis Galiegue" [email protected]
wrote:

For this project https://github.com/fge/grappa-debugger, right now I
use a TextFlow to insert decorated fragments of text.

When a parsing node is selected, I change the text content into the
TextFlow and set the relative vertical scrollbar position so that the
beginning of the match, or failure, is visible.

But I can't do that with RichTextFX as far as I can see.

The problem is that in order to better highlight the match, I change the
text entirely. I collect the fragments, build the new string and .clear()
then .appendText(), this works, I get the new text; and I can style it
correctly.

But the scrollbar always jump to the bottom and I can't get it to position
where I want; moreover, if I try and insert the widget into a ScrollPane
(which is what I do with a TextFlow, and which is how I can position the
scrollbar), the widget doesn't size correctly...

So, do I have to use a ScrollPane anyway? Or how do I position the
scrollbar to where I want?


Reply to this email directly or view it on GitHub
#130.

@fge
Copy link
Author

fge commented Mar 22, 2015

@melkhaldi hmm, I have searched again but cannot find how to set the caret position either :(

And the demo code doesn't seem to show it. Any hints?

@ghost
Copy link

ghost commented Mar 22, 2015

Hi fge, check this issue for background #98.
The method is ' moveto' as in #101 . Hope this helps :)

@TomasMikula
Copy link
Member

@melkhaldi is exactly correct why this is not supported: the visual details (such as scroll position), are handled by a skin, which a user could change for their own custom skin, and the text area does not know how to work with that skin. This has been a problem often enough that I'm leaning towards moving all the functionality from the Skin to the Control itself and not use Skin at all. See also this discussion at openjfx-dev (no response from an Oracle employee yet).

Putting StyledTextArea in a ScrollPane does not work, because StyledTextArea does not return meaningful preferred size. This is because to calculate the total size, it would have to render all the content, but StyledTextArea only renders what is necessary (currently in the viewport). Scrollbar lengths and positions are then just an estimate based on the sizes of already encountered paragraphs. For fixed sized font and no line wrapping, the height estimate happens to be precise, though.

Does the suggested workaround of repositioning the caret work for you?

@fge
Copy link
Author

fge commented Mar 22, 2015

@TomasMikula yes it works; this is in fact better than having to position a scrollbar since I don't have to calculate the offset anymore!

Thanks! Closing.

@fge fge closed this as completed Mar 22, 2015
@isjns
Copy link

isjns commented Oct 8, 2015

I want to be able to set the scroll to the top or the bottom of a InlineStyleTextArea. By the looks of this thread, "moveTo(..)" should do the trick. But it doesn't work for me. I've also tried "selectRange(..)" and "positionCaret(..)". This is my test program, have I misunderstood the "workaround of repositioning the caret"?

import org.fxmisc.richtext.InlineStyleTextArea;

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;

    public class RichTextFXTest extends Application {

    @Override
    public  void start(Stage stage) {

        InlineStyleTextArea<StyleInfo> area = new InlineStyleTextArea<>(
                new StyleInfo(), styleInfo -> styleInfo.toCss());
                area.setPrefSize(300, 300);
        area.setWrapText(false);
                area.setEditable(false);

                StringBuilder largeText = new StringBuilder();

                for (int i = 0; i < 5000; i++) {
                largeText.append("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n");
                }

                area.replaceText(largeText.toString());

                // None of the two rows below works.
                //area.selectRange(1000, 1100);
                //area.moveTo(1100);
                //area.positionCaret

                HBox rootLayout = new HBox();
                rootLayout.setPrefSize(300, 300);
                rootLayout.getChildren().add(area);

                Scene scene = new Scene(rootLayout);
                stage.setScene(scene);
                stage.show();
     }

     // Style class
        class StyleInfo {
            String toCss() {
                return "-fx-fill: #660000;"; // some sort of red
            } 
    }

    public static void main (String[] args) {
            launch();
    }

}

@TomasMikula
Copy link
Member

The problem with your example is that the moveTo/selectRange work-around does not work before the skin is instantiated. If in your example you surround the selectRange in Platform.runLater, that will give you the desired result. Also note that the range is given in character indices, not line numbers.

Platform.runLater(() -> area.selectRange(10000, 10100));

In the code that results from user's interaction after the text area has already been shown, you will not need Platform.runLater anymore.

@isjns
Copy link

isjns commented Oct 12, 2015

Thanks!

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

3 participants