2017-01-11 6 views
3

Я пытаюсь центрировать текст в текстовом поле в середине текстового поля по вертикали. Я смог центрировать текст по горизонтали в java, используя textArea.setStyle("-fx-text-alignment: center");.Вертикальное выравнивание JavaFX TextArea

Я думал о возможности использования таких параметров, как Center Center или Bottom Center для достижения этих результатов с помощью строки -fx-text-alignment, но я обрабатываю горизонтальное и вертикальное выравнивание с помощью двух разных кнопок в моем окне, и поэтому не захочет внедрять логику, чтобы связать эти два метода.

Я попытался переключить -fx-alignment текстаArea, без каких-либо успехов.

Есть ли у кого-нибудь идеи о том, как я могу получить текст, который появится в вертикальном центре textArea?

EDIT: Ниже мое текущее окно, область текста, которую я пытаюсь манипулировать, находится в центре.

enter image description here

+0

Что вы подразумеваете под вертикальным центрированием текста в текстовом поле? «текстовое поле» является однострочным, более конкретным! –

+0

@James_D Зачем использовать высокий 'TextField', если для этого есть элемент управления TextArea, это не имеет смысла! –

+0

Чтобы добавить некоторые пояснения, я использую TextArea, а не TextField для своего приложения, так как это «текстовый редактор» и используется для нескольких строк ввода, а не для отдельной строки ввода текста. Я добавил изображение в исходное сообщение, а также для визуализации. – dibiasem

ответ

4

Я могу только найти решение этой проблемы с помощью какого-то зверски уродливого хакерства макета текстовой области, используя некоторые CSS-запросы и слушатель от размеров различных дочерних узлов текстовой области.

Возможно, кто-то может придумать что-то более надежное, но я не вижу в этом никакого отношения с API.

Вот пример, который работает:

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 только имеет

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

По причинам, я не могу вполне понять, это не работает вообще, если нет стиля лист прилагается.

+0

Это кажется немного сложным для того, что я пытаюсь выполнить здесь, поскольку я ищу, чтобы изменить вертикальное положение текста в текстовой области между тремя состояниями - «Верх», «Ближний» и «Нижний». Исправьте меня, если я ошибаюсь - но, похоже, ваш метод проверяет, требуется ли центрирование и соответственно переводит текст. Я смог использовать метод 'setStyle' для перевода текста в направлении y, однако каретка остается в верхней части текстовой области, даже если текст появился ниже исходного положения. – dibiasem

+0

@dibiasem Он центрируется, если есть свободное место. Если пользователь набрал больше текста, чем будет соответствовать визуальным границам текстовой области (так появилась вертикальная полоса прокрутки), вы не сможете (или хотите) выровнять все равно. Таким образом, чтобы выровнять вершину, 'offset' будет равен нулю, а для выравнивания в нижней части,' offset' будет 'viewportHeight - textHeight' (без деления на 2). –

+0

@dibiasem К сожалению, у каретки нет класса стиля, поэтому я не вижу никакого способа перевести его с помощью CSS. Как вы контролируете, как далеко перевести его с помощью 'setStyle (...)'? Если пользователь набрал несколько строк (или изменил размер текстовой области), вам нужно настроить ... –

Смежные вопросы