It is my test code of textarea append text,
public class TextAreaScrollHold extends Application {
TextArea area = new TextArea();
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.getChildren().add(area);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
addTextInTextArea();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public void addTextInTextArea() {
for (int i = 0; i < 15; i++) {
area.appendText("Hello World " + i + "\n");
}
Task<Void> task = new Task() {
@Override
protected Void call() throws Exception {
for (int i = 15; i < 100; i++) {
area.appendText("Hello World " + i + "\n");
Thread.sleep(1000);
}
return null;
}
};
new Thread(task).start();
}
}
It my code data will update in thread. i need how to hold in scroll bar when data update in textarea. I have ref JavaFX TextArea and autoscroll and Access to TextArea's Scroll Pane or Scroll Bars but how solve this problems.
I need
When data update in textarea, i will scroll the text area scrollbar the bar will hold.
textArea.scrollTopProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
textArea.setScrollTop(100);
}
});
I have used this code but scroll bar in not moved bar will fixed in pixel 100 positions
You can use getCaretPostion and postionCaret (yes, that setter's method name is awkward for Java).
I quickly drafted up some code for you, use the scroll lock button to enable/disable scrolling:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ConsoleDemo extends Application {
Console console = new Console();
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.getChildren().add(console);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Console Demo");
primaryStage.setScene(scene);
primaryStage.show();
addTextInTextArea();
}
/**
* @param args
* the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public void addTextInTextArea() {
for (int i = 0; i < 15; i++) {
console.log("Hello World " + i);
}
Task<Void> task = new Task() {
@Override
protected Void call() throws Exception {
for (int i = 15; i < 100; i++) {
console.log("Hello World " + i);
Thread.sleep(1000);
}
return null;
}
};
new Thread(task).start();
}
public class Console extends BorderPane {
TextArea textArea = new TextArea();
int scrollLockPos = -1;
public Console() {
HBox toolbar = new HBox();
ToggleButton scrollLockButton = new ToggleButton("Scroll Lock");
scrollLockButton.setOnAction(e -> {
if (scrollLockButton.isSelected()) {
scrollLockPos = textArea.getCaretPosition();
} else {
scrollLockPos = -1;
}
});
HBox.setMargin(scrollLockButton, new Insets(5, 5, 5, 5));
toolbar.getChildren().add(scrollLockButton);
setCenter(textArea);
setTop(toolbar);
}
public void log(String text) {
textArea.appendText(text + "\n");
if (scrollLockPos != -1) {
textArea.positionCaret(scrollLockPos);
}
}
}
}
Not the nicest solution, but unless you want to use selection in the textarea while it's scrolling is locked, this one works. For a proper solution you'd need access to the skin / scrollpane / scrollbars and with the upcoming Java 9 version and its modularization you don't know what you will have access to since access to them is currently flagged as "restricted".
Edit:
Here's an alternate solution which uses the Range, console component only. With this version you can select text and keep the selection while the Scroll Lock button is down:
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.IndexRange;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
/**
* Console which provides a mechanism to lock scrolling. Selecting text and copying it works while scrolling is locked.
*/
public class Console extends BorderPane {
TextArea textArea = new TextArea();
ToggleButton scrollLockButton;
IndexRange range;
public Console() {
initComponents();
}
private void initComponents() {
// toolbar
HBox toolbar = new HBox();
toolbar.setAlignment(Pos.CENTER_RIGHT);
// clear
Button clearButton = new Button("Clear");
clearButton.setOnAction(e -> {
textArea.clear();
});
// scroll lock
scrollLockButton = new ToggleButton("Scroll Lock");
// button positions & layout
Insets insets = new Insets(5, 5, 5, 5);
HBox.setMargin(clearButton, insets);
HBox.setMargin(scrollLockButton, insets);
toolbar.getChildren().addAll(clearButton,scrollLockButton);
// component layout
setCenter(textArea);
setTop(toolbar);
}
public void log(String text) {
if (scrollLockButton.isSelected()) {
range = textArea.getSelection();
}
textArea.appendText(text + "\n");
if (scrollLockButton.isSelected()) {
textArea.selectRange(range.getStart(), range.getEnd());
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With