JavaFXでcsvファイルを読み込んでTableViewに表示する方法
2020/09/23
JavaFXでcsvファイルを読み込んでTableView上に表示させる方法です。任意のcsvファイルなので列数があらかじめわかりません。JavaFXのTableViewで列を動的に生成する方法は以前書きました。これをベースに作りました。
[ad#top-1]
まずはプログラムの動きから
起動するとこんな外観です。左上に「Open」ボタンがありますが、これを押すとcsvファイルを選べます。
「Open」ボタンを押すとFileChooerが現れてcsvファイルを指定できます。
開くと以下の通りTableViewにデータがセットされます。csvファイルの先頭行がTableViewのヘッダーになります。
1つ注意点として、1行目の項目がないと、その下のデータは無視されます。例えば下図のように4行目の5列目に「35」というデータが存在しても、項目がない(赤枠)ので、TableViewには表示されません。
以下のように項目をちゃんと記載すれば(以下の例では「E」)、ちゃんとTableViewに現れます。
ソースコード全文
ソースコード全文です。コピペしてコンパイルしてください。
まずはFXMLファイル(CsvTable.fxml)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.VBox?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="CsvTable">
<children>
<ToolBar prefHeight="40.0" prefWidth="200.0">
<items>
<Button mnemonicParsing="false" onAction="#btnAction" text="Open" />
</items>
</ToolBar>
<TableView fx:id="table" prefHeight="403.0" prefWidth="600.0" />
</children>
</VBox>
データクラス(CsvData.java)
import java.util.*;
import javafx.beans.property.*;
public class CsvData {
private ArrayList<String> list;
public CsvData(ArrayList<String> list) {
this.list = list;
}
public void add(String data){ list.add(data); }
public StringProperty get(int index){
return new SimpleStringProperty(list.get(index));
}
}
本体です。(CsvTable.java)
import javafx.application.Application;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.stage.*;
import javafx.scene.layout.*;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.collections.*;
import javafx.scene.control.cell.*;
import javafx.scene.control.TableColumn.*;
import java.util.*;
import javafx.util.*;
import javafx.beans.value.*;
import javafx.beans.property.*;
import java.io.*;
public class CsvTable extends Application {
@FXML private TableView table;
private List<TableColumn> columnList;
private ObservableList<CsvData> data;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception{
VBox root = FXMLLoader.load(getClass().getResource("CsvTable.fxml"));
stage.setTitle("csv file");
stage.setScene(new Scene(root));
stage.show();
}
@FXML
public void btnAction(ActionEvent e) {
FileChooser fc = new FileChooser();
fc.setTitle("ファイル選択");
fc.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("CSVファイル", "*.csv", "*.CSV"),
new FileChooser.ExtensionFilter("すべてのファイル", "*.*")
);
File file = fc.showOpenDialog(null);
if(file == null) return;
//csvファイル読み込み
try {
columnList = new ArrayList<TableColumn>();
File f = new File(file.getPath());
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
int cnt=0;
int len = 0;
while ((line = br.readLine()) != null) {
String[] d = line.split(",", 0); // 行をカンマ区切りで配列に変換
if(cnt==0){
//先頭行(項目行)の処置
ArrayList<TableColumn> dataCols = new ArrayList<TableColumn>();
len = d.length; //項目列数を保持しておく
for (int i=0; i<d.length; i++) {
if(d[i]==null) d[i]="";
dataCols.add(new TableColumn(d[i]));
columnList.add(dataCols.get(i));
final int index = i;
dataCols.get(i).setCellValueFactory(new Callback<CellDataFeatures<CsvData, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<CsvData, String> p) {
return p.getValue().get(index);
}
});
}
table.getColumns().addAll(columnList);
data = FXCollections.observableArrayList();
table.itemsProperty().setValue(data);
table.setItems(data);
}else{
//2行目以降(データ行)
ArrayList<String> col = new ArrayList<String>();
//項目列数分だけループ
for(int i=0; i<len; i++){
if(d.length > i){
if(d[i]==null) d[i]="";
col.add(d[i]);
}else{ //もしデータ数が少なかったら空欄を入れておく
col.add("");
}
}
data.addAll( new CsvData(col) );
}
cnt++;
}
br.close();
}catch (IOException ie){
System.out.println(ie);
}catch (Exception ie){
System.out.println(ie);
}
}
}
[ad#ad-1]
スポンサーリンク




