我正在尝试从一个数据集创建一个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();
}
}
结果如下:
但是,该表不显示编号的行。我已经尝试了很多东西。但我没有得到令人满意的结果。我犯了什么错?
这就是它的工作原理。。。我一直被这个指引着。
@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;
}
给定列的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中,而是将数据显示到控制台中。 我应该忽略这些错误吗?我如何解决我的