开发者

How to scroll a GWT TextArea?

开发者 https://www.devze.com 2022-12-22 14:30 出处:网络
I am calling com.google.gwt.user.client.ui.TextArea.setText(myText) to set the content. After that I call setCursorPosition(myText.length()) to get the cursor to the end. This works well.

I am calling com.google.gwt.user.client.ui.TextArea.setText(myText) to set the content. After that I call setCursorPosition(myText.length()) to get the cursor to the end. This works well.

When myText has more lines then the text area can display at once, it shows a scroll bar. But it does not scroll to the cursor position. Even worse - it scrolls to the top.

How can I scroll the GWT TextArea to the cursor position? I realy need the cursor position, not the bottom of the Tex开发者_开发问答tArea. A JSNI workaround would be ok too.


Try adding this after setting the cursor position:

textAreaToScroll.getElement().setScrollTop(textAreaToScroll.getElement().getScrollHeight());

This will scroll the element to the bottom.

EDIT:

To scroll to the any cursor position there is (as far as I know) no easy way to do so. I don't think there is any way to ask the browser wich line the cursor is on. I just got an idea for something that may work (haven't actually tested it) to guess a rough estimate of how long to scroll.

int cursorPos = textAreaToScroll.getCursorPos();
long offsetRatio = cursorPos / textAreaToScroll.getText().length(); 
//gives 0.0 to 1.0
offsetRatio += someMagicNumber; // -0.1 maybe?
// Depending on the font you may need to adjust the magic number
// to adjust the ratio if it scrolls to far or to short.
offsetRatio = offsetRatio>0.0 ? offsetRatio : 0; //make sure 
//we don't get negative ratios 
//(negative values may crash some browsers while others ignore it) 
textAreaToScroll.getElement().setScrollTop(
     textAreaToScroll.getElement().getScrollHeight() * offsetRatio );

This may scroll the roughly the desired distance. Note, this assumes each line is filled about the same amount since it uses the cursor position divided by the length of the text and not the number of lines (wich is hard to calculate). Manual newlines will skew this estimate, and proportional fonts will allso make it less accurate.

You'll probably need to adjust the ratio so that it scrolls sligtly too short rather than too far since the cursor will still be visible if it's slightly below the top of the text area.

As I said I haven't actually tested this, I may have inverted the logic and other subtle bugs.


I had a scenario where the textarea will already have something and when a new command is submitted it will add the data to it and scroll to the start of the newly added data. this is what I did

    // Hold the previous height to set the scroll.
    final int prevHeight = document.get().getElementById(textareadid).getScrollHeight();
    // Hold the prev position if output area already has some data.
    final int prevPos = this.textArea.getValue() != null ?  
    this.textArea.getValue().length() : 0;

after processing and setting the new data

        int posCount = 0;
        if (previousResponse != null && !previousResponse.isEmpty())
        {
            final String dataStr = "new data from process";
            // add 15 lines for the cursor position
            posCount = getRelativeCount(dataStr);
        }
        this.textArea.getElement().setScrollTop(prevHeight);
        this.textArea.setCursorPos(prevPos + posCount);

 private int getRelativeCount(final String str)
{
    int charCount = 0;

    if (str != null)
    {

        int NUM_ROWS = 15;

        if (getUserAgent().contains("msie"))
        {
            NUM_ROWS = 16;
        }

        final String[] splitArr = str.split("\n"); // split on the new line
                                                   // char

        for (int index = 0; index < splitArr.length && index < NUM_ROWS; index++)
        {
            charCount += splitArr[index].length();
        }
    }
    return charCount;
}


To improve on Stein's answer, you can count the number of lines in the text, and then set the top position based on the desired line over the total lines, rather than using characters.

While you are counting lines, you will also have to determine which line the cursor is in.

String text = textArea.getText();
int lines = 1;
int pos = 0;
int cursorPos = ...;
int cursorLine = -1;
while((pos = 1+text.indexOf("\n", pos)) > 0)
{
    if (cursorLine == -1 && pos > cursorPos)
        cursorLine = lines;
    lines++;
}
if (lines > 0 && cursorLine > 0 && cursorLine < lines)
{
    int scroll = textArea.getElement().getScrollHeight();
    scroll *= cursorLine;
    scroll /= lines;
    scroll -= 30; // Back up a bit so it's not right at the top
    if (scroll < 0)
        scroll = 0;
    textArea.getElement().setScrollTop(scroll);
}


this worked for me: GWT textArea Scroll issue

http://www.gwtplayground.com/2012/08/gwt-textarea-scroll-issue_21.html

0

精彩评论

暂无评论...
验证码 换一张
取 消