2017-01-11 1 views
3

Ich versuche, den Text in einem Textfeld in der Mitte des Textfelds vertikal zu zentrieren. Ich konnte den Text horizontal in Java zentrieren, indem ich textArea.setStyle("-fx-text-alignment: center"); verwendete.JavaFX TextArea Vertikale Ausrichtung

Ich dachte über die Möglichkeit, Parameter wie Center Center oder Bottom Center zu verwenden, um diese Ergebnisse durch die -fx-Text-Alignment-Zeichenfolge zu erreichen, aber ich handle die horizontale und vertikale Ausrichtung durch zwei verschiedene Tasten an meinem Fenster, und würde daher keine Logik implementieren wollen, um die beiden Methoden in Beziehung zu setzen.

Ich habe versucht, die -fx-alignment des textArea auch ohne Erfolg umzuschalten.

Hat jemand irgendwelche Ideen, wie ich meinen Text in der vertikalen Mitte des TextArea erscheinen lassen könnte?

EDIT: Unten ist mein aktuelles Fenster, der Textbereich, den ich manipuliere, ist in der Mitte.

enter image description here

+0

Was meinen Sie mit der vertikalen Zentrierung eines Textes in einer 'Textbox'? Eine 'Textbox' ist einzeilig, genauer! –

+0

@James_D Warum ein großes 'TextField' verwenden, wenn ein Steuerelement für diesen Zweck' TextArea' existiert, macht das keinen Sinn! –

+0

Nur um eine Klarstellung hinzuzufügen, verwende ich einen TextArea anstelle eines TextField für meine Anwendung, da es ein "Texteditor" ist und für mehrere Eingabezeilen anstelle einer einzelnen Zeile der Texteingabe verwendet wird. Ich habe dem Originalbeitrag auch ein Bild zur Visualisierung hinzugefügt. – dibiasem

Antwort

4

kann ich nur eine Lösung für dieses von einigen brutal hässlich Hacking des Layout des Textbereichs mit einigen CSS-Lookups und Zuhörer auf die Größen der verschiedenen untergeordneten Knoten des Textbereich finden.

Vielleicht kann jemand etwas robuster, aber ich sehe keinen Weg in die API.

Hier ist ein Beispiel, das funktioniert:

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 hat nur

.text-area .text { 
    -fx-text-alignment: center ; 
} 

Aus Gründen kann ich nicht ganz begreifen, dies überhaupt nicht funktionieren, wenn es keinen Stil Blatt beigefügt.

+0

Das scheint ein bisschen komplex für das, was ich hier erreichen möchte, da ich versuche, die vertikale Position des Textes innerhalb des Textbereichs zwischen drei Zuständen zu ändern - "Top", "Middle" und "Bottom". Korrigiere mich, wenn ich falsch liege - aber es scheint, dass deine Methode prüft, ob eine Zentrierung notwendig ist, und den Text entsprechend übersetzt. Ich konnte die 'setStyle' Methode verwenden, um den Text in der y-Richtung zu übersetzen, jedoch bleibt der Cursor oben im Textbereich, obwohl der Text niedriger als seine ursprüngliche Position erschien. – dibiasem

+0

@dibiasem Es wird zentriert, wenn verfügbarer Platz vorhanden ist. Wenn der Benutzer mehr Text eintippt, als in die visuellen Grenzen des Textbereichs passen würde (so dass eine vertikale Bildlaufleiste angezeigt wird), können Sie überhaupt nicht ausrichten (oder möchten). Um "nach oben" auszurichten, wäre "offset" gleich Null, und um nach unten auszurichten, wäre "offset" "viewportHeight - textHeight" (ohne durch 2 zu teilen). –

+0

@dibiasem Leider scheint der Caret keine Stilklasse zu haben, daher sehe ich keine Möglichkeit, ihn mit CSS zu übersetzen. Wie kontrollierst du, wie weit du es mit 'setStyle (...)' übersetzen kannst? Wenn der Benutzer mehrere Zeilen eingegeben hat (oder wenn der Textbereich die Größe geändert hat), müssen Sie anpassen ... –