Reputation: 73
I'm trying to center the text in a text box in the middle of the text box, vertically. I've been able to center the text horizontally in java by using textArea.setStyle("-fx-text-alignment: center");
.
I thought about the possibility of using parameters like Center Center or Bottom Center to achieve these results through the -fx-text-alignment string, but I'm handling the horizontal and vertical alignment through two different buttons on my window, and would therefore not want to implement logic to relate the two methods.
I have tried to toggle the -fx-alignment
of the textArea as well, without any success.
Does anyone have any ideas on how I could get my text to appear in the vertical center of the textArea?
EDIT: Below is my current window, the text area I am attempting to manipulate is in the center.
Upvotes: 3
Views: 4442
Reputation: 209684
I can only find a solution to this by some brutally ugly hacking of the layout of the text area using some CSS lookups and listeners on the sizes of various child nodes of the text area.
Perhaps someone can come up with something more robust, but I don't see any way into this with the API.
Here's an example that works:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.shape.Path;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class TextAreaAlignment extends Application {
@Override
public void start(Stage primaryStage) {
TextArea textArea = new TextArea();
Scene scene = new Scene(textArea, 400, 400);
hackTextAreaLayout(textArea);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private void hackTextAreaLayout(TextArea textArea) {
textArea.applyCss();
textArea.layout();
ScrollPane textAreaScroller = (ScrollPane) textArea.lookup(".scroll-pane");
Text text = (Text) textArea.lookup(".text");
ChangeListener<? super Bounds> listener =
(obs, oldBounds, newBounds) -> centerTextIfNecessary(textAreaScroller, text);
textAreaScroller.viewportBoundsProperty().addListener(listener);
text.boundsInLocalProperty().addListener(listener);
}
private void centerTextIfNecessary(ScrollPane textAreaScroller, Text text) {
double textHeight = text.getBoundsInLocal().getHeight();
double viewportHeight = textAreaScroller.getViewportBounds().getHeight();
double offset = Math.max(0, (viewportHeight - textHeight) / 2 );
text.setTranslateY(offset);
Parent content = (Parent)textAreaScroller.getContent();
for (Node n : content.getChildrenUnmodifiable()) {
if (n instanceof Path) { // caret
n.setTranslateY(offset);
}
}
}
public static void main(String[] args) {
launch(args);
}
}
style.css just has
.text-area .text {
-fx-text-alignment: center ;
}
For reasons I can't quite grasp, this doesn't work at all if there is no style sheet attached.
Upvotes: 4