2013-07-22 11 views
12

私は、イベントハンドラを介して入力される新しいテキストで下部に自動スクロールするTextAreaを取得しようとしています。それぞれの新しいエントリは、各エントリが改行で区切られた1つの長いテキスト文字列です。 setscrolltopをDouble.MIN_VALUEに設定する変更ハンドラを試しましたが、役に立たないです。どのようにこれを行うことができるの任意のアイデア?JavaFX TextAreaとautoscroll

@FXML private TextArea txa; 

... 

txa.textProperty().addListener(new ChangeListener<Object>() { 
    @Override 
    public void changed(ObservableValue<?> observable, Object oldValue, 
      Object newValue) { 
     txa.setScrollTop(Double.MAX_VALUE); //this will scroll to the bottom 
     //use Double.MIN_VALUE to scroll to the top 
    } 
}); 

しかし、あなたがしたいのであればあなたは、setText(text)方法を使用する場合、このリスナーがトリガされていません。

+1

あなたのコメントはあなたが回答として投稿したため、(私ではなく)削除されました。私はそこにあなたに答えました。答えを受け入れることができるかもしれないということは、あなたが満足する解決策を見つけたことを他人に知らせるのが正しいと判断したことです。これを行うには、あなたが好む回答のほかに 'V 'をクリックして緑色にします。これはあなたの[自分の答え](http://stackoverflow.com/questions/19122056/camel-jpa-component-forcing-a-commit)でも有効です。 – Math

答えて

20

は、あなたはそれが値が変更されていたときに一番下までスクロールするTextArea要素にリスナーを追加する必要があります

txa.setText("Text into the textArea"); //does not trigger the listener 
txa.appendText(""); //this will trigger the listener and will scroll the 
        //TextArea to the bottom 

これは、より多くのバグのような音がsetText()たらchangedリスナーをトリガする必要がありますが、それは、D、:setText(text)は右のそれの後appendText(text)を使用した後、それをトリガーそうではありません。これは私自身を使用し、それがあなたを助けることを願っている回避策です。

+2

'setScrollTop(Double.MIN_VALUE);'は上にスクロールし、 'MAX_VALUE'は下にスクロールします。 –

+0

@AdamJensen私はこれまでにこれに答えたので、私はここでテストを行います。私はそれを見て覚えていません。レポートをありがとう。 – Math

+1

@AdamJensenあなたは絶対に正しいです。私はただそれを修正した。ありがとう! – Math

7

txa.appendText( "")は、リスナーなしで下にスクロールします。スクロールしてテキストを常に更新したい場合、これは問題になります。 txa.setText( "")はスクロールバーを先頭に戻し、同じ問題が適用されます。

私の解決策は、TextAreaクラスを拡張し、FXMLタグをtextAreaからLogTextAreaに変更することでした。この作品、それがこのコンポーネントはのappendText

textArea.selectPositionCaret(textArea.getLength()); 
textArea.deselect(); //removes the highlighting 
3

代替が何であるかを知らないと、それは明らかシーンビルダーで問題が発生する場合にはFXML内からアクセスできるように、代わりにブール値のプロパティを使用することになります。 このようなものです。

import javafx.beans.property.BooleanProperty; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.scene.control.TextArea; 

public class LogTextArea extends TextArea { 
    private final BooleanProperty pausedScrollProperty = new SimpleBooleanProperty(false); 
    private double scrollPosition = 0; 

    public LogTextArea() { 
     super(); 
    } 

    public void setMessage(String data) { 
     if (isPausedScroll()) { 
      scrollPosition = this.getScrollTop(); 
      this.setText(data); 
      this.setScrollTop(scrollPosition); 
     } else { 
      this.setText(data); 
      this.setScrollTop(Double.MAX_VALUE); 
     } 
    } 

    public final BooleanProperty pausedScrollProperty() { return pausedScrollProperty; } 
    public final boolean isPausedScroll() { return pausedScrollProperty.getValue(); } 
    public final void setPausedScroll(boolean value) { pausedScrollProperty.setValue(value); } 
} 

しかし、この答えの問題点は、(IOストリームからログを取得する際に発生することがありますよう)JavaFXのスレッドがロックアップします入力の不当大量にあふれ出た場合のTextAreaを取得するためということですあまりにも多くのデータ。

1

私はjamesarbrown年代に追加するひとつの補遺を使用せずにその奇妙なのsetTextのバグに

import javafx.scene.control.TextArea; 
import javafx.scene.text.Font; 

public class LogTextArea extends TextArea { 

private boolean pausedScroll = false; 
private double scrollPosition = 0; 

public LogTextArea() { 
    super(); 
} 

public void setMessage(String data) { 
    if (pausedScroll) { 
     scrollPosition = this.getScrollTop(); 
     this.setText(data); 
     this.setScrollTop(scrollPosition); 
    } else { 
     this.setText(data); 
     this.setScrollTop(Double.MAX_VALUE); 
    } 
} 

public void pauseScroll(Boolean pause) { 
    pausedScroll = pause; 
} 

} 
関連する問題