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]
スポンサーリンク