Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TableCell中的JavaFx文本换行_Javafx_Javafx 8_Word Wrap - Fatal编程技术网

TableCell中的JavaFx文本换行

TableCell中的JavaFx文本换行,javafx,javafx-8,word-wrap,Javafx,Javafx 8,Word Wrap,我对TableCells中的文本换行有一个问题,其中一个问题是,如果我更改单元格的数据,文本换行不会自动工作,只是如果我做一些修改。我很好奇是否有人和我有同样的问题,也许他们找到了更好的解决办法 以下是一个您可以验证的简单示例: public class Controller implements Initializable { @FXML private TableView<Model> table; @FXML private TableColu

我对TableCells中的文本换行有一个问题,其中一个问题是,如果我更改单元格的数据,文本换行不会自动工作,只是如果我做一些修改。我很好奇是否有人和我有同样的问题,也许他们找到了更好的解决办法

以下是一个您可以验证的简单示例:

public class Controller implements Initializable {

    @FXML
    private TableView<Model> table;
    @FXML
    private TableColumn<Model, String> colA;
    @FXML
    private TableColumn<Model, String> colB;
    @FXML
    private Button changeString;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        colA.setCellValueFactory(data -> data.getValue().stringA);
        colB.setCellValueFactory(data -> data.getValue().stringB);

        setCellFactory();

        ObservableList<Model> items = FXCollections.observableArrayList();

        items.add(new Model("This is a long string that needs to be wrapped", "Short"));
        items.add(new Model("This is a long string that needs to be wrapped", "Short"));

        changeString.setOnAction(event -> {
            table.getItems().get(0).getStringA().setValue("Short");
            table.getColumns().get(0).setVisible(false);
            table.getColumns().get(0).setVisible(true);
        });

        table.setItems(items);
    }

    private void setCellFactory() {
        colA.setCellFactory(f -> {
            TableCell<Model, String> cell = new TableCell<Model, String>() {
                Text text = new Text();

                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    if (empty) {
                        setGraphic(null);
                        return;
                    }
                    text.setWrappingWidth(getTableColumn().getWidth() - 10);
                    text.setText(item);
                    setGraphic(text);
                }
            };
            return cell;
        });
    }

    @Getter
    private static class Model {

        private final StringProperty stringA;
        private final StringProperty stringB;

        private Model(String stringA, String stringB) {
            this.stringA = new SimpleStringProperty(stringA);
            this.stringB = new SimpleStringProperty(stringB);
        }
    }
}
公共类控制器实现可初始化{
@FXML
私有表视图表;
@FXML
私人餐桌可乐;
@FXML
私用colB;
@FXML
私有按钮转换字符串;
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
colA.setCellValueFactory(数据->数据.getValue().stringA);
colB.setCellValueFactory(数据->数据.getValue().stringB);
setCellFactory();
ObservableList items=FXCollections.observableArrayList();
添加(新模型(“这是一个需要包装的长字符串”,“短”);
添加(新模型(“这是一个需要包装的长字符串”,“短”);
changeString.setOnAction(事件->{
table.getItems().get(0.getStringA().setValue(“Short”);
table.getColumns().get(0).setVisible(false);
table.getColumns().get(0).setVisible(true);
});
表2.设置项目(项目);
}
私有void setCellFactory(){
可乐.赛赛尔工厂(f->{
TableCell单元格=新的TableCell(){
Text Text=新文本();
@凌驾
受保护的void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
if(空){
设置图形(空);
回来
}
setWrappingWidth(getTableColumn().getWidth()-10);
text.setText(项目);
设置图形(文本);
}
};
返回单元;
});
}
@吸气剂
私有静态类模型{
私人最终财产stringA;
私人最终财产stringB;
专用模型(字符串stringA、字符串stringB){
this.stringA=新的SimpleStringProperty(stringA);
this.stringB=新的SimpleStringProperty(stringB);
}
}
}
(这只是相关部分,如果需要,我将包括
Main
fxml

如您所见,我必须在模型中设置一个值,该值显示在表格单元格中,但设置后单元格的高度不会更新。我为了更新它,我必须包括隐藏/显示列以刷新高度


对于这个问题,您有什么更好的建议/解决方案吗?

这与您的setCellFactory中的updateItem位于主线程中有关。将单元格工厂更改为在FX线程中运行,如下所示

                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    Platform.runLater(() -> {
                        if (empty) {
                            setGraphic(null);
                        } else {
                            text.wrappingWidthProperty().bind(getTableColumn().widthProperty().subtract(10));
                            text.setText(item);
                            setGraphic(text);
                        }
                    });

                }
            };
        });
    }
您可以删除changeString.setOnAction事件中的visible hack列

或者,因为人们认为
runLater
是一种黑客行为,所以请使用tableview刷新。。。仅使用原始代码段,而不是

       changeString.setOnAction(event -> {
            table.getItems().get(0).getStringA().setValue("Short");
            table.getColumns().get(0).setVisible(false);
            table.getColumns().get(0).setVisible(true);
        });
换成这个

       changeString.setOnAction(event -> {
            table.getItems().get(0).getStringA().setValue("Short");
            table.refresh();
        });

这与setCellFactory中的updateItem位于主线程中有关。将单元格工厂更改为在FX线程中运行,如下所示

                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    Platform.runLater(() -> {
                        if (empty) {
                            setGraphic(null);
                        } else {
                            text.wrappingWidthProperty().bind(getTableColumn().widthProperty().subtract(10));
                            text.setText(item);
                            setGraphic(text);
                        }
                    });

                }
            };
        });
    }
您可以删除changeString.setOnAction事件中的visible hack列

或者,因为人们认为
runLater
是一种黑客行为,所以请使用tableview刷新。。。仅使用原始代码段,而不是

       changeString.setOnAction(event -> {
            table.getItems().get(0).getStringA().setValue("Short");
            table.getColumns().get(0).setVisible(false);
            table.getColumns().get(0).setVisible(true);
        });
换成这个

       changeString.setOnAction(event -> {
            table.getItems().get(0).getStringA().setValue("Short");
            table.refresh();
        });

请参阅,将wrappingWidthProperty与列宽Property绑定,这没有帮助…每次将文本设置为图形之前,我都会设置wrappingWidth。是否需要
文本
?形状在默认情况下不受管理,因此单元格高度不会自动更改也就不足为奇了。单元格高度通常是有问题的,但是如果您直接在单元格上调用方法(
setWrapText(…)
setxt(…)
,等等),它是否有效。或者,在最坏的情况下,对图形使用
标签
。@James\u我两个都试过了。setWrapText不做任何操作,它会剪切。。。但它不会显示整个文本,因此它根本不会更新单元格的高度。使用标签是一样的,它没有绑定标签的
wrappingWIdth
属性。在每一个与wraptext相关的问题上,我都只找到了这个
文本
为基础的问题。这在某种程度上是有效的,但是刷新部分不是很好。。。行中prefHeight的计算似乎发生在单元格内容更新之前。试图在那之后强迫,但没有成功,sry。旁白(这无助于解决您的问题,只是为了代码的完整性:)-由于wrappingWidth与单元格内容无关,而是与列宽相关,因此它应该绑定到updateItem之外的该属性(当然要防止没有列)。请参阅,将wrappingWidthProperty与列宽Property绑定这没有帮助…每次将文本设置为图形之前,我都会设置wrappingWidth。是否需要
文本
?形状在默认情况下不受管理,因此单元格高度不会自动更改也就不足为奇了。单元格高度通常是有问题的,但是如果您直接在单元格上调用方法(
setWrapText(…)
setxt(…)
,等等),它是否有效。或者,在最坏的情况下,对图形使用
标签
。@James\u我两个都试过了。setWrapText不做任何操作,它会剪切。。。但它不会显示整个文本,因此它根本不会更新单元格的高度。使用标签是一样的,它没有绑定标签的
wrappingWIdth
属性。在每一个与wraptext相关的问题上,我都只找到了这个
文本
为基础的问题。这在某种程度上是有效的,但是刷新部分不是很好。。。行中prefHeight的计算似乎发生在单元格内容更新之前。试图在那之后强迫,但没有成功,sry。一