【问题标题】:Binding TextArea height to its content将 TextArea 高度绑定到其内容
【发布时间】:2013-03-23 23:27:14
【问题描述】:

JavaFX:是否可以将 TextArea 高度(行数)绑定到其内容的高度?
我想在编写文本时动态更改TextArea 的高度。

【问题讨论】:

    标签: layout binding textarea javafx


    【解决方案1】:

    看看JavaFX utility class。虽然这不是使用绑定的解决方案,但computeTextHeight(Font font, String text, double wrappingWidth) 方法可以帮助您。

    【讨论】:

      【解决方案2】:

      这是一个准确、简单且有效的解决方案:

      SimpleIntegerProperty count = new SimpleIntegerProperty(20);
      int rowHeight = 10;
      
      txtArea.prefHeightProperty().bindBidirectional(count);
      txtArea.minHeightProperty().bindBidirectional(count);
      txtArea.scrollTopProperty().addListener(new ChangeListener<Number>(){
          @Override
          public void changed(ObservableValue<? extends Number> ov, Number oldVal, Number newVal) {
              if(newVal.intValue() > rowHeight){
                  count.setValue(count.get() + newVal.intValue());
              }
          }
      });
      

      或者,您可以使用 lambda 来进一步简化语法:

      SimpleIntegerProperty count=new SimpleIntegerProperty(20);
      int rowHeight = 10;
      
      textArea.prefHeightProperty().bindBidirectional(count);
      textArea.minHeightProperty().bindBidirectional(count);
      textArea.scrollTopProperty().addListener((ov, oldVal, newVal) -> {
          if(newVal.intValue() > rowHeight){
              count.setValue(count.get() + newVal.intValue());
          }
      });
      

      【讨论】:

      • 这还不够。一方面,如果您在 TextArea 的顶部保持滚动(因此 scrollTop 保持为零),它永远不会将大小扩展到所需的大小。
      • Neil Brown 你在投反对票之前有没有试过这个?你似乎没有理解其中的逻辑。 scrollTop 在写入 textArea 的长度 > 宽度的文本时增加。因此计数增加并有效地增加 textArea 高度。这又将 scrollTop 设置为零。如果你在 changelistnener 中打印 newval.intValue() 你就会明白发生了什么。打印的值如下所示:16 0 16 0 16 0...
      • 我的意思是你不能“滚动”,因为没有滚动条,因为在 textArea 高度增加后 scrollTop 被重置为 0
      • 你说得对:我不明白 scrollTop 会做什么。但是我已经尝试过代码 - 当我在空白文本框中按 Enter 以创建空白新行时,滚动条出现并且高度增加但通常不足以摆脱滚动条。我现在看到虽然在空白行上输入文本会导致高度得到纠正。当我按退格键删除这些行时, scrollTop 永远不会被修改,因此该字段永远不会缩小以适应 - 这对我来说是必需的,尽管可能不是原始提问者。试图删除我的反对票,但除非编辑答案,否则它会被锁定。
      【解决方案3】:

      在 javafx8 中运行良好的解决方案(隐藏工具栏的灵感来自 JavaFX TextArea Hiding Scroll Bars):

      class MyTextArea extends TextArea {
      
          @Override
          protected void layoutChildren() {
              super.layoutChildren();
              ScrollBar scrollBarv = (ScrollBar) this.lookup(".scroll-bar:vertical");
              if (scrollBarv != null) {
                  System.out.println("hiding vbar");
                  ((ScrollPane) scrollBarv.getParent()).setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
              }
              ScrollBar scrollBarh = (ScrollBar) this.lookup(".scroll-bar:horizontal");
              if (scrollBarh != null) {
                  System.out.println("hiding hbar");
                  ((ScrollPane) scrollBarh.getParent()).setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
              }
          }
      
          @Override
          protected double computePrefWidth(double width) {
              Bounds bounds = getTextBounds();
              Insets insets = getInsets();
              double w = Math.ceil(bounds.getWidth() + insets.getLeft() + insets.getRight());
              return w;
          }
      
          @Override
          protected double computePrefHeight(double height) {
              Bounds bounds = getTextBounds();
              Insets insets = getInsets();
              double h = Math.ceil(bounds.getHeight() + insets.getLeft() + insets.getRight());
              return h;
          }
      
          //from https://stackoverflow.com/questions/15593287/binding-textarea-height-to-its-content/19717901#19717901
          public Bounds getTextBounds() {
              //String text = (textArea.getText().equals("")) ? textArea.getPromptText() : textArea.getText();
              String text = "";
              text = this.getParagraphs().stream().map((p) -> p + "W\n").reduce(text, String::concat);
              text += "W";
              helper.setText(text);
              helper.setFont(this.getFont());
              // Note that the wrapping width needs to be set to zero before
              // getting the text's real preferred width.
              helper.setWrappingWidth(0);
              return helper.getLayoutBounds();
          }
      }
      

      【讨论】:

      • 我已经尝试过这个解决方案,但我发现我得到了弹跳大小;当图书馆试图显示滚动条时,当我编辑文本时,窗口的高度似乎会上下反弹。太烦人了 JavaFX 在 TextArea 上没有适合大小的属性!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 2018-06-11
      相关资源
      最近更新 更多