【问题标题】:JavaFX TextArea Vertical AlignmentJavaFX TextArea 垂直对齐
【发布时间】:2017-01-11 18:15:11
【问题描述】:

我试图在文本框中间的文本框中垂直居中文本。我已经能够使用textArea.setStyle("-fx-text-alignment: center"); 在java 中水平居中文本。

我考虑过使用 Center Center 或 Bottom Center 等参数通过 -fx-text-alignment 字符串实现这些结果的可能性,但我正在通过窗口上的两个不同按钮处理水平和垂直对齐,并且因此,不想实现将这两种方法关联起来的逻辑。

我也尝试切换 textArea 的-fx-alignment,但没有成功。

有没有人知道如何让我的文本出现在 textArea 的垂直中心?

编辑:下面是我当前的窗口,我试图操作的文本区域在中心。

【问题讨论】:

  • textbox 中的文本垂直居中是什么意思? textbox 是单行的,更具体!
  • @James_D 为什么要使用高大的TextField,当有一个为此目的的控件TextArea,它没有意义!
  • 只是为了澄清一下,我在我的应用程序中使用的是 TextArea 而不是 TextField,因为它是一个“文本编辑器”,用于多行输入,而不是单行文字输入。我还在原始帖子中添加了一张图片以进行可视化。
  • 我已经理解了这个错误,我很抱歉,我的下一个问题是关于更高的 TextField,但正如你所说,这不是这里的问题!
  • 我能找到完成这项工作的唯一方法是对文本区域布局进行一些非常丑陋的黑客攻击。似乎没有其他方法可以解决这个问题。

标签: css javafx textarea


【解决方案1】:

我只能通过使用一些 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 ;
}

由于我不能完全理解的原因,如果没有附加样式表,这根本不起作用。

【讨论】:

  • 这对于我要在这里完成的工作来说似乎有点复杂,因为我希望在三个状态之间更改文本区域内文本的垂直位置 - 'Top' 'Middle' 和'底部。如果我错了,请纠正我——但您的方法似乎会检查是否需要居中并相应地翻译文本。我可以使用 setStyle 方法在 y 方向上翻译文本,但是插入符号仍保留在文本区域的顶部,即使文本看起来低于其原始位置。
  • @dibiasem 如果有可用空间,它将居中。如果用户输入的文本超出了文本区域的视觉范围(因此出现了垂直滚动条),那么您将根本无法(或想要)对齐。因此,要与顶部对齐,offset 将为零,而要与底部对齐,offset 将是 viewportHeight - textHeight(不除以 2)。
  • @dibiasem 不幸的是,插入符号似乎没有样式类,所以我看不到任何使用 CSS 翻译它的方法。您如何控制使用setStyle(...) 将其翻译多远?如果用户输入了多行(或者如果文本区域改变了大小)你需要调整...
  • 要设置移动文本的样式,我首先设置了一个节点final Node font1 = textArea.lookup(".text");,它检查textArea 的样式类(text-area)并操作.text 节点。一旦确定,我实施了以下内容; font1.setStyle("-fx-translate-y: 0");
  • 对于用户多行输入来说,这个是我一开始考虑的,后来觉得超出了编辑器的范围。我正在创建的窗口是为简单而设计的,因此处理文本的动态对齐可能超出了目的本身。但是,您提供的解决方案绝对值得赞赏,我一定会参考您在更复杂的设置中使用的方法。
猜你喜欢
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2015-09-06
  • 2011-03-16
相关资源
最近更新 更多