在javaFX中自动滚动

时间:2016-11-24 03:22:44

标签: java css user-interface javafx scrollbar

我正在尝试使用javaFX构建一个聊天框。我在当前页面填满时尝试自动向下滚动页面。但它没有正常工作。

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;

public class ChatBox extends Application{
final ScrollPane sp = new ScrollPane();
public static void main(String[] args){
launch(args);
}
public void start(Stage stage){
TextFlow textFlow = new TextFlow();
textFlow.setPadding(new Insets(10));
textFlow.setLineSpacing(10);
textFlow.setPrefSize(300,300);
TextField textField = new TextField();
textField.setPrefSize(50,30);
Button button = new Button("Send");
button.setPrefSize(80,30);
VBox container = new VBox();
VBox box = new VBox();
box.getChildren().addAll(sp,textFlow);
container.setPadding(new Insets(10));
container.getChildren().addAll(box, new HBox(textField, button));
VBox.setVgrow(sp, Priority.ALWAYS);
VBox.setVgrow(textFlow, Priority.ALWAYS);
textField.prefWidthProperty().bind(container.widthProperty().subtract(button.prefWidthProperty()));

// On Enter press
textField.setOnKeyPressed(e -> {
    if(e.getCode() == KeyCode.ENTER) {
        button.fire();
    }
});

button.setOnAction(e -> {
    Text text;
    if(textFlow.getChildren().size()==0){
        text = new Text(textField.getText());
    } else {
        // Add new line if not the first child
        text = new Text("\n" + textField.getText());
    }
    textFlow.getChildren().add(text);
    textField.clear();
    textField.requestFocus();
});
VBox vb = new VBox();
vb.getChildren().addAll(textFlow);
sp.setVmax(440);
sp.setPrefSize(400, 300);
sp.setContent(vb);
sp.vvalueProperty().bind((ObservableValue<? extends Number>) vb.heightProperty());
//sp.setPannable(true);
Scene scene = new Scene(container, 400, 300);
stage.setScene(scene);
stage.setTitle("ChatBox");
stage.show();
}
}

当我运行它时,页面会关闭

enter image description here

这里虽然它是第一条消息但滚动条指向下方虽然它的位置应该在顶部,但是它会上升。我该怎么办?

2 个答案:

答案 0 :(得分:1)

只需注释文本流的Pref大小,因为它会导致滚动发生,因为它需要在滚动窗格内部调整其大小。 请查看以下内容:

struct Edge;

struct Vertex {
    int key;
    int val;
    vector<Edge*> connections;
    Vertex(int k) {
        key = k;
    }
};

答案 1 :(得分:0)

我建议您使用ListView代替TextFlow。这使得代码变得更加简单,因为ListView已经处理换行符并且还提供了scrollTo方法,允许您指定要滚动到视图的消息索引:

public void start(Stage stage) {
    TextField textField = new TextField();
    textField.setPrefSize(50, 30);

    Button button = new Button("Send");
    button.setPrefSize(80, 30);

    VBox container = new VBox();

    ListView<String> listView = new ListView();
    listView.setFocusTraversable(false);
    listView.setCellFactory(lv -> new ListCell<String>() {

        private final Text text;

        {
            text = new Text();
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            setGraphic(text);

            // bind wrapping width to available size
            text.wrappingWidthProperty().bind(Bindings.createDoubleBinding(() -> {
                Insets padding = getPadding();
                return getWidth() - padding.getLeft() - padding.getRight();
            }, widthProperty(), paddingProperty()));

        }

        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                text.setText(null);
            } else {
                text.setText(item);
            }
        }

    });

    container.setPadding(new Insets(10));
    container.getChildren().addAll(listView, new HBox(textField, button));
    VBox.setVgrow(listView, Priority.ALWAYS);

    HBox.setHgrow(textField, Priority.ALWAYS);
    HBox.setHgrow(button, Priority.NEVER);

    EventHandler<ActionEvent> handler = e -> {
        // add new message
        listView.getItems().add(textField.getText());

        textField.clear();
        textField.requestFocus();

        // scroll to newly added item
        listView.scrollTo(listView.getItems().size()-1);
    };

    textField.setOnAction(handler);
    button.setOnAction(handler);

    Scene scene = new Scene(container, 400, 300);
    stage.setScene(scene);
    stage.setTitle("ChatBox");
    stage.show();
}