当前位置: 首页 > 知识库问答 >
问题:

在TableView(JavaFX)中显示ArrayList的值

夏季萌
2023-03-14

我正在尝试从一个数据集创建一个TableView,该数据集由一个具有字符串值的双嵌套ArrayList组成。遗憾的是,我无法在TableView中显示所有值。行没有根据数据集进行编号。

internet的大多数解决方案都表明,我应该使用特定的对象实例。然而,我不是这样工作的。相反,我使用大小不确定的字符串矩阵。数据结构如下:

List<List<String>> values = new ArrayList<List<String>>();

int rows = 10;
int cols = 4;
             
for(int r=0; r<rows; r++) {
    List<String> line = new ArrayList<String>();
                     
        for(int c=0; c<cols; c++)
            line.add("r: "+r+", c: "+c);
                     
    values.add(line);
}

我最好的(但错误的)结果是通过以下代码实现的:

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;

public class TestApplication extends Application {

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

    @Override
    public void start(Stage stage) throws Exception {

        // create values
        List<List<String>> values = new ArrayList<List<String>>();

        int rows = 10;
        int cols = 4;

        for (int r = 0; r < rows; r++) {
            List<String> line = new ArrayList<String>();

            for (int c = 0; c < cols; c++)
                line.add("r: " + r + ", c: " + c);

            values.add(line);
        }

        // show values in table
        TableView<List<StringProperty>> tableView = new TableView<List<StringProperty>>();
        ObservableList<List<StringProperty>> data = FXCollections.observableArrayList();

        for (int c = 0; c < cols; c++++) {
            TableColumn<List<StringProperty>, String> col = new TableColumn<>("Col: " + c);
            tableView.getColumns().add(col);
        }

        for (int r = 0; r < values.size(); r++) {
            List<StringProperty> row = new ArrayList<StringProperty>();

            for (int c = 0; c < values.get(r).size(); c++) {
                TableColumn<List<StringProperty>, String> col = (TableColumn<List<StringProperty>, String>) tableView.getColumns().get(c);
                String val = values.get(r).get(c);

                col.setCellValueFactory(cl -> new SimpleStringProperty(new String(val)));
            }

            data.add(row);
        }

        tableView.setItems(data);

        stage.setScene(new Scene(tableView, 300, 500));
        stage.show();
    }
}

结果如下:

但是,该表不显示编号的行。我已经尝试了很多东西。但我没有得到令人满意的结果。我犯了什么错?

共有2个答案

钮晟
2023-03-14

这就是它的工作原理。。。我一直被这个指引着。

@Override
public void start(Stage stage) throws Exception {

    // create values
    List<List<String>> values = new ArrayList<List<String>>();

    int rows = 10;
    int cols = 4;

    for (int r = 0; r < rows; r++) {
        List<String> line = new ArrayList<String>();

        for (int c = 0; c < cols; c++)
            line.add("r: " + r + ", c: " + c);

        values.add(line);
    }

    
    List<String> colHeads = new ArrayList<String>();
    for (int c = 0; c < cols; c++) {
        String ch = "Col: " + c; 
        colHeads.add(ch);
    }
    
    
    // show values in table 
    List<TableColumn<Map<String, String>, String>> tcs = new ArrayList<TableColumn<Map<String, String>, String>>();
    for (int c = 0; c < cols; c++) {
        String ch =  colHeads.get(c);
        
        TableColumn<Map<String, String>, String> col = new TableColumn<>(ch);
        col.setCellValueFactory(new MapValueFactory(ch)); 
        
        tcs.add(col); 
    }
    
    TableView<Map<String, String>> tableView = new TableView<>(generateDataInMap(colHeads, values));
    tableView.getColumns().setAll(tcs);
     

    stage.setScene(new Scene(tableView, 300, 500));
    stage.show();

}

private ObservableList<Map<String, String>> generateDataInMap(List<String> colHeads, List<List<String>> values ) {

    ObservableList<Map<String, String>> allData = FXCollections.observableArrayList();
    
    for(int r=0; r<values.size(); r++) {
        Map<String, String> dataRow = new HashMap<String, String>();
        
        for(int c=0; c<values.get(r).size(); c++) {
            String val = values.get(r).get(c);
            dataRow.put(colHeads.get(c), val);
        }
        allData.add(dataRow);
    }
    return allData;
}
孟花蜂
2023-03-14

给定列的cellValueFactory是一个函数,它接受一个包含行数据的包装器(即列表

在代码中,每次添加一行时都会更改单元格值工厂(cellValueFactory),因此生成的单元格值工厂(cellValueFactory)就是您添加的最后一行中的一个,您只能看到最后一行中的数据。

每列只需设置一次cellValueFactory,它应该是一个将行数据映射到该列特定值的函数。

例如,以下内容将为您提供所需的内容:

@Override
public void start(Stage stage) throws Exception {

    // create values
    List<List<String>> values = new ArrayList<List<String>>();

    int rows = 10;
    int cols = 4;

    for (int r = 0; r < rows; r++) {
        List<String> line = new ArrayList<String>();

        for (int c = 0; c < cols; c++)
            line.add("r: " + r + ", c: " + c);

        values.add(line);
    }

    // show values in table
    TableView<List<StringProperty>> tableView = new TableView<>();
    ObservableList<List<StringProperty>> data = FXCollections.observableArrayList();

    for (int c = 0; c < cols; c++) {
        TableColumn<List<StringProperty>, String> col = new TableColumn<>("Col: " + c);
        
        final int colIndex = c ;
        col.setCellValueFactory(cd -> cd.getValue().get(colIndex));
        
        tableView.getColumns().add(col);
    }

    for (int r = 0; r < values.size(); r++) {
        List<StringProperty> row = new ArrayList<StringProperty>();

        for (int c = 0; c < values.get(r).size(); c++) {
            row.add(new SimpleStringProperty(values.get(r).get(c)));
        }

        data.add(row);
    }

    tableView.setItems(data);

    stage.setScene(new Scene(tableView, 300, 500));
    stage.show();
}

如果数据不会改变,您可能更喜欢使用比StringProperty更轻的东西,尽管这种小幅度性能节约的好处值得商榷:

@Override
public void start(Stage stage) throws Exception {

    // create values
    List<List<String>> values = new ArrayList<List<String>>();

    int rows = 10;
    int cols = 4;

    for (int r = 0; r < rows; r++) {
        List<String> line = new ArrayList<String>();

        for (int c = 0; c < cols; c++)
            line.add("r: " + r + ", c: " + c);

        values.add(line);
    }

    // show values in table
    TableView<List<String>> tableView = new TableView<>();

    for (int c = 0; c < cols; c++) {
        TableColumn<List<String>, String> col = new TableColumn<>("Col: " + c);
        
        final int colIndex = c ;
        col.setCellValueFactory(cd -> new ObservableValue<String>() {

            // If data are immutable, there's nothing for a listener to do, so we ignore them:
            @Override
            public void addListener(InvalidationListener listener) {}
            @Override
            public void removeListener(InvalidationListener listener) {}
            @Override
            public void addListener(ChangeListener<? super String> listener) {}
            @Override
            public void removeListener(ChangeListener<? super String> listener) {}

            @Override
            public String getValue() {
                return cd.getValue().get(colIndex);
            }
            
        });
        
        tableView.getColumns().add(col);
    }

    

    tableView.setItems(FXCollections.observableList(values));

    stage.setScene(new Scene(tableView, 300, 500));
    stage.show();
}
 类似资料:
  • 控制器代码 我想在表格视图中显示之前对数据做一些操作 像秋千 在摇摆,我喜欢这个,它工作得很好。 但不知道如何在tableview javafx上进行操作。

  • 我试图在TableView中插入一些值,但它不显示列中的文本,尽管这些列不是空的,因为有三行(与我在TableView中插入的条目数量相同)可单击。 我有一个类“ClientIController”,它是fxml文件的控制器,这些是TableView和TableView的列的声明。 我在initialize()方法中调用了一个名为loadTable()的函数,该函数将内容添加到TableView中

  • 我想突出显示JavaFX中显示的部分文本。到目前为止,我正在使用对象中的对象。为了突出显示文本中的特定部分,我使用标记将文本切割成部分(objects),以突出显示或不突出显示以下代码。 不幸的是,背景高亮显示不起作用,我有奇怪的换行符,如图所示。文本不包含任何换行符。 (对图片质量表示抱歉,这是一个真实的截图:)) 感谢任何帮助。 解决方案正如@eckig所建议的,在HBox中使用多个标签是一个

  • 我刚启动JavaFx,有点拘泥于TableView,它显示了每个列的非常长的字符串表示,如: 而我预计细胞中只会出现“大”、“5000”、“3000”。 这是我的模型: fxml: 最后是控制器: 看起来控制器很好,它能够从数据库中获取值并向TableView添加行,但为什么TableView显示属性对象的字符串表示,而不仅仅是显示值? 非常感谢!

  • 我有一个class,它在其他属性中包含一个可观察列表 如何让JavaFX提取class

  • 下面是FXML代码- 我尝试与数据库连接,并尝试将数据从数据库显示到TableView。我尝试将这些东西实现到控制器类中,如下所示- 问题是,它显示行错误。我不知道这个错误的原因。如果我将一行编辑为,则不会显示行的任何错误。然后应用程序运行良好。但是,当我单击Show TableWiew按钮时,它不会将数据显示到TableView中,而是将数据显示到控制台中。 我应该忽略这些错误吗?我如何解决我的