【问题标题】:How to scale Label within a ListView in JavaFX如何在 JavaFX 中的 ListView 中缩放标签
【发布时间】:2018-01-12 14:34:27
【问题描述】:

我有一个 ListView,里面有一些标签。标签的宽度属性绑定到 ListView 的宽度属性,但它们似乎稍大,这意味着列表视图上显示了水平滚动条。我想要的是在列表视图中放置标签,而底部没有滚动条。我查看了标签和列表视图上的各种填充和插入值,但我发现没有一个是罪魁祸首(大多数为零)。

这是一个演示问题的示例。

import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

public class ListViewScrollExample extends Application {

   private ListView<Node> listView;

   @Override
   public void start(Stage stage) throws Exception {
       listView = new ListView<>();
       addItem("Some quite long string to demonstrate the problem");

       Scene scene = new Scene(listView);
       stage.setScene(scene);
       stage.show();
    }

    public void addItem(String item) {
        Label label = new Label(item);
        label.setWrapText(true);
        label.maxWidthProperty().bind(listView.widthProperty());
        listView.getItems().add(label);
    }

    public static void main(String[] args){
        Application.launch(args);
    }

}

【问题讨论】:

  • 如果您允许文本换行,您希望如何计算宽度?我可以缩小列表视图,直到标签每行显示 1 个单词。
  • @user1803551 问题是滚动条出现在ListView的底部。包装按我的预期工作,但标签区域似乎延伸到一边,即使文本本身没有
  • 所以你想去掉滚动条?喜欢this

标签: java listview javafx layout scroll


【解决方案1】:

default CSS file 将填充添加到 ListCell(当前版本中的第 2316 行):

.list-cell {
    -fx-padding: 0.25em 0.583em 0.25em 0.583em; /* 3 7 3 7 */
}

使用Node 实例作为支持ListView 的数据通常是个坏主意:在此示例中您应该使用String,并使用单元工厂创建一个标签来显示您配置的字符串需要。以下似乎适用于您的示例:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

public class ListViewScrollExample extends Application {

   private ListView<String> listView;

   @Override
   public void start(Stage stage) throws Exception {
       listView = new ListView<>();
       listView.getItems().add("Some quite long string to demonstrate the problem");

       listView.setCellFactory(lv -> {
           ListCell<String> cell = new ListCell<String>() {

               private Label label = new Label();
               {
                   label.setWrapText(true);
                   label.maxWidthProperty().bind(Bindings.createDoubleBinding(
                           () -> getWidth() - getPadding().getLeft() - getPadding().getRight() - 1, 
                           widthProperty(), paddingProperty()));
                   setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
               }

               @Override
               protected void updateItem(String item, boolean empty) {
                   super.updateItem(item, empty);
                   if (empty) {
                       setGraphic(null);
                   } else {
                       label.setText(item);
                       setGraphic(label);
                   }
               }
           };
           return cell ;
       });

       Scene scene = new Scene(listView);
       stage.setScene(scene);
       stage.show();
    }


    public static void main(String[] args){
        Application.launch(args);
    }

}

在这里,我创建了一个列表单元格,它显示一个标签作为其图形,标签的文本设置为要显示的字符串。单元格的构造函数将标签的最大宽度绑定到单元格的宽度,减去填充所需的任何空间。对setContentDisplay(ContentDisplay.GRAPHIC_ONLY) 的调用似乎是必要的,因此单元格不会尝试为文本分配任何空间。

可以通过直接在列表单元格上设置文本并在单元格上调用setWrapText(true)(毕竟也是Labeled的子类)来做到这一点,但我无法得到它以这种方式工作。

【讨论】:

  • 这行得通,谢谢。我不会知道使用那种方法
  • 我确实发现绑定中的减一和对 setContentDisplay(ContentDisplay.GRAPHIC_ONLY) 的调用是不必要的
【解决方案2】:

我无法重现该问题,但您可以尝试以下方法而不是 label.maxWidthProperty().bind(listView.widthProperty());

double i = Double.parseDouble(listView.widthProperty().toString());
label.setMaxWidth((i-2.0));

您可以将 2.0 更改为更改屏幕所需的任何像素数。

【讨论】:

  • 我试图避免使用硬编码常量来缩小标签大小。另外你为什么使用 Double.parseDouble(listView.widthProperty().toString()) 而不是 listView.widthProperty().get()?
  • 没有真正的理由使用 double.parse 来代替它,但这就是我首先想到的地方,很长的路要走。你可以试试label.setMaxWidth(listView.getPrefWidth());。这一切都应该做同样的事情,但值可能会略有不同。
  • 如果您要使用硬编码的数量来缩小它,只需使用相同的绑定方法:label.maxWidthProperty().bind(listView.widthProperty().subtract(2.0));
  • 另外,Double.parseDouble(listView.widthProperty().toString()) 甚至不起作用:该属性的toString() 方法返回类似"ReadOnlyDoubleProperty [bean: ListView@27e7a3d1[styleClass=root list-view], name: width, value: 248.0]" 的东西,显然不能解析为双精度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多