如何滚动GWT TextArea?

时间:2010-03-09 13:31:06

标签: gwt

我正在呼叫com.google.gwt.user.client.ui.TextArea.setText(myText)来设置内容。之后我调用setCursorPosition(myText.length())将光标移到最后。这很有效。

myText有更多行时,文本区域可以立即显示,它会显示滚动条。但它不会滚动到光标位置。更糟糕的是 - 它滚动到顶部。

如何将GWT TextArea滚动到光标位置?我真的需要光标位置,而不是TextArea的底部。 JSNI解决方法也可以。

4 个答案:

答案 0 :(得分:3)

设置光标位置后尝试添加此项:

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

这会将元素滚动到底部。

修改

要滚动到任何光标位置(据我所知),没有简单的方法可以这样做。我认为没有办法向浏览器询问光标所在的行。 我只是想知道可能有用的东西(实际上没有测试过)来猜测滚动多长时间的粗略估计。

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 );

这可以大致滚动所需的距离。注意,这假设每行填充大约相同的量,因为它使用光标位置除以文本的长度而不是行数(难以计算)。手动换行会扭曲这一估计值,而比例字体也会降低其准确性。

你可能需要调整比例,使其滑动得太短而不是太远,因为如果光标略低于文本区域的顶部,光标仍然可见。

正如我所说,我实际上没有测试过这个,我可能已经颠倒了逻辑和其他微妙的错误。

答案 1 :(得分:3)

我有一个场景,其中textarea已经有了东西,当提交新命令时,它会将数据添加到它并滚动到新添加数据的开头。这就是我做的事情

    // 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;

处理并设置新数据后

        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;
}

答案 2 :(得分:1)

要改进Stein的答案,您可以计算文本中的行数,然后根据所需的行在总行上设置顶部位置,而不是使用字符。

在计算线条时,您还必须确定光标所在的行。

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);
}

答案 3 :(得分:0)