質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

1回答

2853閲覧

JavaFxにてTableViewからの情報をXMLに出力したい

退会済みユーザー

退会済みユーザー

総合スコア0

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2020/08/29 20:07

CSVやXMLから読み込んだ情報をTableViewに入れて表示させ、新規追加を行ったらその情報を表に反映させ、保存ボタンを押したときにXMLで出力させるというプログラムを作成しています。ファイルの読み込みと表の反映、新規追加などを無事実装させることができ、保存ボタンに関する処理を作成していたのですが、TableView内の情報からXMLのための要素を抜き出す方法が調べてみても考えてみても分からず、何かいい方法があれば教えていただきたいです。

出力のために作った簡易的なものですが、イメージとして一応コードを載せておきます。

Data

1package test_fxmls.testa; 2 3import javafx.beans.property.SimpleStringProperty; 4 5public class Data { 6 7 private SimpleStringProperty name; 8 private SimpleStringProperty age; 9 private SimpleStringProperty til; 10 11 public Data(String name, String age, String til) { 12 this.name = new SimpleStringProperty(name); 13 this.age = new SimpleStringProperty(age); 14 this.til = new SimpleStringProperty(til); 15 } 16 17 public void setName(String name) { 18 this.name.set(name); 19 } 20 public String getName() { 21 return name.get(); 22 } 23 24 public void setAge(String age) { 25 this.age.set(age); 26 } 27 public String getAge() { 28 return age.get(); 29 } 30 31 public void setTil(String til) { 32 this.til.set(til); 33 } 34 public String getTil() { 35 return til.get(); 36 } 37 38 @Override 39 public String toString() { 40 return "name: " + name.get() + " - " + "age: " + age.get()+ "til: "+ til.get(); 41 } 42 43} 44

AppMainController

1package test_fxmls.testa; 2 3import java.io.IOException; 4import java.net.URL; 5import java.util.ResourceBundle; 6 7import javafx.collections.FXCollections; 8import javafx.collections.ObservableList; 9import javafx.event.ActionEvent; 10import javafx.fxml.FXML; 11import javafx.fxml.FXMLLoader; 12import javafx.fxml.Initializable; 13import javafx.scene.Parent; 14import javafx.scene.Scene; 15import javafx.scene.control.TableColumn; 16import javafx.scene.control.TableView; 17import javafx.scene.control.cell.PropertyValueFactory; 18import javafx.stage.Modality; 19import javafx.stage.Stage; 20 21 22public class AppMainController implements Initializable { 23 24 @FXML 25 private TableView<Data> tvData; 26 @FXML 27 private TableColumn<Data, String> colName; 28 @FXML 29 private TableColumn<Data, String> colAge; 30 @FXML 31 private TableColumn<Data, String> colTil; 32 33 private ObservableList<Data> tvObservableList = FXCollections.observableArrayList(); 34 35 @FXML 36 void onOpenDialog(ActionEvent event) throws IOException { 37 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("AddPersonDialog.fxml")); 38 Parent parent = fxmlLoader.load(); 39 AddPersonDialogController dialogController = fxmlLoader.<AddPersonDialogController>getController(); 40 dialogController.setAppMainObservableList(tvObservableList); 41 Scene scene = new Scene(parent); 42 Stage stage = new Stage(); 43 stage.initModality(Modality.APPLICATION_MODAL); 44 stage.setScene(scene); 45 stage.showAndWait(); 46 } 47 48 @Override 49 public void initialize(URL location, ResourceBundle resources) { 50 Data Dt = new Data("太郎", "89", "キッチンペーパー"); 51 colName.setCellValueFactory(new PropertyValueFactory<>("name")); 52 colAge.setCellValueFactory(new PropertyValueFactory<>("age")); 53 colTil.setCellValueFactory(new PropertyValueFactory<>("til")); 54 tvObservableList.add(Dt); 55 tvData.setItems(tvObservableList); 56 } 57 58 59}

AppMain

1package test_fxmls.testa; 2 3import javafx.application.Application; 4import javafx.fxml.FXMLLoader; 5import javafx.scene.Parent; 6import javafx.scene.Scene; 7import javafx.stage.Stage; 8 9public class AppMain extends Application { 10 11 @Override 12 public void start(Stage primaryStage) throws Exception { 13 Parent root = FXMLLoader.load(getClass().getResource("AppMain.fxml")); 14 Scene scene = new Scene(root, 500, 500); 15 primaryStage.setScene(scene); 16 primaryStage.show(); 17 } 18 19 public static void main(String[] args) { 20 launch(args); 21 } 22 23}

AddPersonDialog

1package test_fxmls.testa; 2 3import javafx.collections.ObservableList; 4import javafx.event.ActionEvent; 5import javafx.fxml.FXML; 6import javafx.scene.Node; 7import javafx.scene.control.Button; 8import javafx.scene.control.TextField; 9import javafx.stage.Stage; 10 11public class AddPersonDialogController { 12 13 @FXML 14 private TextField tfName; 15 16 @FXML 17 private TextField tfAge; 18 19 @FXML 20 private TextField tfTil; 21 22 @FXML 23 private Button btn_add; 24 25 private ObservableList<Data> appMainObservableList; 26 27 @FXML 28 void btnAddPersonClicked(ActionEvent event) { 29 System.out.println("btnAddPersonClicked"); 30 String name = tfName.getText().trim(); 31 String age = tfAge.getText().trim(); 32 String til = tfTil.getText().trim(); 33 34 Data data = new Data(name, age, til); 35 appMainObservableList.add(data); 36 37 closeStage(event); 38 39 } 40 41 @FXML 42 void btnSavePersonClicked(ActionEvent event) { 43 44// DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 45// DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 46// File file = new File("test1.xml"); 47// 48// Document doc = docBuilder.newDocument(); 49// Element rootElement = doc.createElement("roots"); 50// doc.appendChild(rootElement); 51// 52// Element root = doc.createElement("familia"); 53// rootElement.appendChild(root); 54// 55// Element name = doc.createElement("Name"); 56// name.appendChild(doc.createTextNode(); 57// root.appendChild(name); 58// 59// Element age = doc.createElement("Age"); 60// age.appendChild(doc.createTextNode(); 61// root.appendChild(age); 62// 63// Element tile = doc.createElement("Tile"); 64// tile.appendChild(doc.createTextNode(); 65// root.appendChild(tile); 66 } 67 68 public void setAppMainObservableList(ObservableList<Data> tvObservableList) { 69 this.appMainObservableList = tvObservableList; 70 71 } 72 73 private void closeStage(ActionEvent event) { 74 Node source = (Node) event.getSource(); 75 Stage stage = (Stage) source.getScene().getWindow(); 76 stage.close(); 77 } 78 79} 80

以下FXML

AppPersonDialog

1<?xml version="1.0" encoding="UTF-8"?> 2 3<?import javafx.scene.control.Button?> 4<?import javafx.scene.control.Label?> 5<?import javafx.scene.control.TextField?> 6<?import javafx.scene.layout.AnchorPane?> 7<?import javafx.scene.layout.HBox?> 8<?import javafx.scene.layout.VBox?> 9 10 11<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="142.0" prefWidth="387.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test_fxmls.testa.AddPersonDialogController"> 12 <children> 13 <AnchorPane prefHeight="147.0" prefWidth="387.0"> 14 <children> 15 <HBox alignment="CENTER" layoutX="33.0" layoutY="82.0" prefHeight="43.0" prefWidth="321.0"> 16 <children> 17 <TextField fx:id="tfName" prefHeight="25.0" prefWidth="95.0" /> 18 <TextField fx:id="tfAge" prefHeight="25.0" prefWidth="104.0" /> 19 <TextField fx:id="tfTil" prefHeight="25.0" prefWidth="95.0" /> 20 </children> 21 </HBox> 22 <Label layoutX="49.0" layoutY="73.0" text="名前" /> 23 <Label layoutX="246.0" layoutY="73.0" text="トイレットペーパー" /> 24 <Label layoutX="143.0" layoutY="73.0" text="年齢" /> 25 <Button fx:id="btn_add" layoutX="155.0" layoutY="22.0" mnemonicParsing="false" onAction="#btnAddPersonClicked" prefHeight="25.0" prefWidth="77.0" text="追加" /> 26 </children> 27 </AnchorPane> 28 </children> 29</VBox> 30

AppMain

1<?xml version="1.0" encoding="UTF-8"?> 2 3<?import javafx.scene.control.Button?> 4<?import javafx.scene.control.TableColumn?> 5<?import javafx.scene.control.TableView?> 6<?import javafx.scene.layout.AnchorPane?> 7<?import javafx.scene.layout.HBox?> 8<?import javafx.scene.layout.VBox?> 9 10<AnchorPane maxHeight="400.0" minHeight="400.0" minWidth="500.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test_fxmls.testa.AppMainController"> 11 <children> 12 <VBox alignment="CENTER" layoutX="91.0" layoutY="85.0" spacing="10.0" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="30.0"> 13 <children> 14 <HBox alignment="CENTER" prefHeight="66.0" prefWidth="221.0" spacing="50.0"> 15 <children> 16 <Button mnemonicParsing="false" onAction="#onOpenDialog" prefHeight="25.0" prefWidth="83.0" text="保存" /> 17 <Button mnemonicParsing="false" onAction="#onOpenDialog" prefHeight="25.0" prefWidth="83.0" text="追加" /> 18 </children> 19 </HBox> 20 <TableView fx:id="tvData" prefHeight="300.0" prefWidth="400.0"> 21 <columns> 22 <TableColumn fx:id="colName" prefWidth="75.0" text="名前" /> 23 <TableColumn fx:id="colAge" prefWidth="75.0" text="年齢" /> 24 <TableColumn fx:id="colTil" prefWidth="75.0" text="好きなトイレットペーパー" /> 25 </columns> 26 <columnResizePolicy> 27 <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> 28 </columnResizePolicy> 29 </TableView> 30 </children> 31 </VBox> 32 </children> 33</AnchorPane> 34

この「保存」を押したときに今現在表示されているTableView内の名前、年齢、トイレットペーパーを要素ごとに情報取得させる方法を知りたいです。長々と申し訳ありません。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2020/08/30 00:01

読み込みができているなら出力も同じようなことだと思うのですが、何が問題なんでしょう?? tvObservableListに全データが入っているので、ループ等で書き出すだけですが。
TN8001

2020/08/31 15:19

お返事がありませんがサンプルコードを保持しておくのも面倒なので回答しておきます。
guest

回答1

0

肝心の読み込み部分がないのでどういうフォーマットなのかがわかりません。
コードの断片から適当にでっち上げましたが、読み込みは決め打ちで超雑なので注意してください。

ついでに前回の回答で言及した、Dialog<R>のサンプルも付けました。

Java

1import java.io.*; 2import java.net.URL; 3import java.util.*; 4import javax.xml.parsers.*; 5import javax.xml.transform.*; 6import javax.xml.transform.dom.DOMSource; 7import javax.xml.transform.stream.StreamResult; 8 9import javafx.beans.binding.Bindings; 10import javafx.collections.*; 11import javafx.event.*; 12import javafx.fxml.*; 13import javafx.scene.*; 14import javafx.scene.control.*; 15import javafx.scene.control.cell.PropertyValueFactory; 16import javafx.scene.layout.GridPane; 17import javafx.stage.*; 18import javafx.util.Callback; 19import org.w3c.dom.*; 20import org.xml.sax.SAXException; 21 22public class AppMainController implements Initializable { 23 @FXML 24 private TableView<Data> tvData; 25 @FXML 26 private TableColumn<Data, String> colName; 27 @FXML 28 private TableColumn<Data, String> colAge; 29 @FXML 30 private TableColumn<Data, String> colTil; 31 32 private ObservableList<Data> tvObservableList = FXCollections.observableArrayList(); 33 34 @FXML 35 void onOpenDialog(ActionEvent event) throws IOException { 36 // ついでにDialog<R>のサンプル 37 Dialog<Data> dialog = new AddDataDialog(); 38 Optional<Data> result = dialog.showAndWait(); 39 40 // 取り消しでなければDataを追加 41 if (result.isPresent()) { 42 tvObservableList.add(result.get()); 43 } 44 45// FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("AddPersonDialog.fxml")); 46// Parent parent = fxmlLoader.load(); 47// AddPersonDialogController dialogController = fxmlLoader.<AddPersonDialogController>getController(); 48// dialogController.setAppMainObservableList(tvObservableList); 49// Scene scene = new Scene(parent); 50// Stage stage = new Stage(); 51// stage.initModality(Modality.APPLICATION_MODAL); 52// stage.setScene(scene); 53// stage.showAndWait(); 54 } 55 56 @FXML 57 void onSave(ActionEvent event) { 58 try { 59 saveXml("test1.xml"); 60 } catch (ParserConfigurationException | TransformerException e) { 61 e.printStackTrace(); 62 } 63 } 64 65 @Override 66 public void initialize(URL location, ResourceBundle resources) { 67 colName.setCellValueFactory(new PropertyValueFactory<>("name")); 68 colAge.setCellValueFactory(new PropertyValueFactory<>("age")); 69 colTil.setCellValueFactory(new PropertyValueFactory<>("til")); 70 71 tvData.setItems(tvObservableList); 72 73 try { 74 loadXml("test1.xml"); 75 } catch (ParserConfigurationException | IOException | SAXException e) { 76 e.printStackTrace(); 77 } 78 } 79 80 // 注意 メチャ雑 81 private void loadXml(String path) throws ParserConfigurationException, IOException, SAXException { 82 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 83 DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 84 Document doc = docBuilder.parse(new File(path)); 85 86 NodeList dataList = doc.getDocumentElement().getElementsByTagName("data"); 87 for (int i = 0; i < dataList.getLength(); i++) { 88 Element dataElement = (Element) dataList.item(i); 89 90 Element nameElement = (Element) dataElement.getElementsByTagName("name").item(0); 91 Element ageElement = (Element) dataElement.getElementsByTagName("age").item(0); 92 Element tilElement = (Element) dataElement.getElementsByTagName("til").item(0); 93 94 String name = nameElement.getFirstChild().getNodeValue(); 95 String age = ageElement.getFirstChild().getNodeValue(); 96 String til = tilElement.getFirstChild().getNodeValue(); 97 98 tvObservableList.add(new Data(name, age, til)); 99 } 100 } 101 102 private void saveXml(String path) throws ParserConfigurationException, TransformerException { 103 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 104 DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 105 Document doc = docBuilder.newDocument(); 106 107 Element rootElement = doc.createElement("roots"); 108 doc.appendChild(rootElement); 109 110 for (Data data : tvObservableList) { 111 Element dataElement = doc.createElement("data"); 112 rootElement.appendChild(dataElement); 113 114 Element name = doc.createElement("name"); 115 name.appendChild(doc.createTextNode(data.getName())); 116 dataElement.appendChild(name); 117 118 Element age = doc.createElement("age"); 119 age.appendChild(doc.createTextNode(data.getAge())); 120 dataElement.appendChild(age); 121 122 Element tile = doc.createElement("til"); 123 tile.appendChild(doc.createTextNode(data.getTil())); 124 dataElement.appendChild(tile); 125 } 126 127 TransformerFactory transformerFactory = TransformerFactory.newInstance(); 128 Transformer transformer = transformerFactory.newTransformer(); 129 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 130 131 DOMSource source = new DOMSource(doc); 132 StreamResult result = new StreamResult(new File(path)); 133 transformer.transform(source, result); 134 } 135} 136 137// Dialog<R>の参考実装 138class AddDataDialog extends Dialog<Data> { 139 public AddDataDialog() { 140 setTitle("データの追加"); 141 setHeaderText("名前・年齢・好きなトイレットペーパーの種類を入力してください。"); 142 143 TextField tfName = new TextField(); 144 TextField tfAge = new TextField(); 145 TextField tfTil = new TextField(); 146 147 GridPane grid = new GridPane(); 148 grid.add(new Label("名前"), 1, 1); 149 grid.add(tfName, 2, 1); 150 grid.add(new Label("年齢"), 1, 2); 151 grid.add(tfAge, 2, 2); 152 grid.add(new Label("好きなトイレットペーパー"), 1, 3); 153 grid.add(tfTil, 2, 3); 154 getDialogPane().setContent(grid); 155 156 // OKと取り消しボタンを追加 157 getDialogPane().getButtonTypes().add(ButtonType.OK); 158 getDialogPane().getButtonTypes().add(ButtonType.CANCEL); 159 160 // 何か入力されるまでOKボタンを無視する設定 161 // しかし押せなくなるわけではなく無反応になるだけなのでわかりにくい 162// Button okButton = (Button) getDialogPane().lookupButton(ButtonType.OK); 163// okButton.addEventFilter(ActionEvent.ACTION, new EventHandler<ActionEvent>() { 164// @Override public void handle(ActionEvent event) { 165// String name = tfName.getText().trim(); 166// String age = tfAge.getText().trim(); 167// String til = tfTil.getText().trim(); 168// 169// if (name.length() == 0 || age.length() == 0 || til.length() == 0) { 170// event.consume(); 171// } 172// } 173// }); 174 175 // ↑なので入力があるまではOKボタンを押せなくする 176 Button okButton = (Button) getDialogPane().lookupButton(ButtonType.OK); 177 okButton.setDisable(true); 178 // どれかが未入力&空白のみはダメ 179 okButton.disableProperty().bind(Bindings.createBooleanBinding(() -> 180 tfName.getText().trim().isEmpty(), tfName.textProperty()) 181 .or(Bindings.createBooleanBinding(() -> 182 tfAge.getText().trim().isEmpty(), tfAge.textProperty())) 183 .or(Bindings.createBooleanBinding(() -> 184 tfTil.getText().trim().isEmpty(), tfTil.textProperty()))); 185 // 未入力だけでよければ短く書けるが。。 186// okButton.disableProperty().bind( 187// Bindings.isEmpty(tfName.textProperty()) 188// .or(Bindings.isEmpty(tfAge.textProperty())) 189// .or(Bindings.isEmpty(tfTil.textProperty()))); 190 191 // showAndWaitの戻り値作成 192 setResultConverter(new Callback<ButtonType, Data>() { 193 @Override public Data call(ButtonType buttonType) { 194 if (buttonType == ButtonType.OK) { 195 String name = tfName.getText().trim(); 196 String age = tfAge.getText().trim(); 197 String til = tfTil.getText().trim(); 198 199 return new Data(name, age, til); 200 } 201 return null; 202 } 203 }); 204 } 205}

diff

1-<Button mnemonicParsing="false" onAction="#onOpenDialog" prefHeight="25.0" prefWidth="83.0" text="保存" /> 2+<Button mnemonicParsing="false" onAction="#onSave" prefHeight="25.0" prefWidth="83.0" text="保存"/>

投稿2020/08/31 15:19

TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問