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

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

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

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

Java

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

Q&A

解決済

2回答

1353閲覧

Serializeで複数のオブジェクトを保存したい。

ryu-bamboo

総合スコア9

JavaFX

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

Java

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

0グッド

0クリップ

投稿2021/05/03 07:56

自分は、今、javaFXでスケジュール表を作っていて、一度実行して追加した予定を、実行を終了してからまた実行したときにも、前に追加した予定が表示されるように、Serializeを使ってファイルに保存できるようにしました。

ここで問題があって、保存されるオブジェクトは、直前に実行された、一番最後のオブジェクトだけで、他のオブジェクトが表示されないのです。そこで、オブジェクトを保存するファイルを見てみると、(文字化けしていてはっきりとはわからないのですが)一つのオブジェクトしか保存されていないみたいでした。

どうすれば複数のオブジェクトを保存できるのでしょうか。教えてください!

下のcodeは
1.ScheduleMainがMainクラスで、実行時にファイルを読み込む。
2.ScheduleTableControllerでスケジュール表の本体を表示
3.ScheduleSelectControllerで予定を追加し、追加するごとにSaveDataFile.serにオブジェクトを書き込む

という感じです。fxmlは文字数を超えるため書けませんでした、ご容赦ください。

ScheduleMain

1 2 3public class ScheduleMain extends Application { 4 5 6 public static ScheduleTableController stController; 7 8 @Override 9 public void start(Stage primaryStage) { 10 try { 11 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ScheduleIndividual.fxml")); 12 Scene scene = new Scene((VBox)fxmlLoader.load(),150,600); 13 scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); 14 stController = fxmlLoader.getController(); 15 16 try { 17 if(!isEmpty()) { 18 initScheduleLabel(loading()); 19 } 20 } catch (IOException e) { 21 e.printStackTrace(); 22 } 23 24 primaryStage.setScene(scene); 25 primaryStage.show(); 26 System.out.println(stController.toString()); 27 } catch(Exception e) { 28 e.printStackTrace(); 29 } 30 } 31 32 public static void main(String[] args) { 33 launch(args); 34 } 35 36 boolean isEmpty() throws IOException { 37 File file = new File("SaveDataFile.ser") ; 38 boolean empty = !file.exists() || file.length()==0; 39 return empty; 40 } 41 42 ScheduleData loading() { 43 try (var in = new ObjectInputStream(new FileInputStream("SaveDataFile.ser"))){ 44 var saveData = (ScheduleData)in.readObject(); 45 return saveData; 46 }catch (Exception e) { 47 return null; 48 } 49 } 50 51 @SuppressWarnings("static-access") 52 void initScheduleLabel(ScheduleData data) { 53 var sLabel = new Label(); 54 double stNum = (data.getsTime().getHour()+data.getsTime().getMinute()/60)*30+4; 55 double ftNum = (data.getfTime().getHour()+data.getfTime().getMinute()/60)*30+4; 56 double tNum = ftNum-stNum; 57 String str = data.gettitle()+"\n"+data.gettime()+"\n"+data.getDetail(); 58 sLabel.setText(str); 59 sLabel.setStyle("-fx-background-color:green;"); 60 stController.getaPane().getChildren().add(sLabel); 61 stController.getaPane().setTopAnchor(sLabel, stNum); 62 sLabel.setPrefHeight(tNum); 63 64 } 65} 66

ScheduleTableController

1/** 2 * Sample Skeleton for 'ScheduleIndividual.fxml' Controller Class 3 */ 4 5 6public class ScheduleTableController { 7 8 9 @FXML // ResourceBundle that was given to the FXMLLoader 10 private ResourceBundle resources; 11 12 @FXML // URL location of the FXML file that was given to the FXMLLoader 13 private URL location; 14 15 @FXML // fx:id="pane" 16 private VBox pane; // Value injected by FXMLLoader 17 18 @FXML // fx:id="aPane" 19 private AnchorPane aPane; // Value injected by FXMLLoader 20 21 @FXML // fx:id="aPane" 22 private VBox scheduleIndividual; // Value injected by FXMLLoader 23 24 25 //ここからScheduleSelectのid 26 27 28 29 @FXML 30 void sets(MouseEvent event) { 31 try { 32 showSecondWindow(); 33 } catch (IOException e) { 34 e.printStackTrace(); 35 } 36 } 37 38 39 40 void showSecondWindow() throws IOException { 41 42 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ScheduleSelect.fxml")); 43 AnchorPane root = (AnchorPane) fxmlLoader.load(); 44 Scene scene = new Scene(root); 45 Stage stage = new Stage(); 46 stage.setScene(scene); 47 stage.showAndWait(); 48 49 } 50 51 52 53 54 public AnchorPane getaPane() { 55 return aPane; 56 } 57 58 59 60 @FXML // This method is called by the FXMLLoader when initialization is complete 61 void initialize() { 62 63 64 65 assert pane != null : "fx:id=\"pane\" was not injected: check your FXML file 'ScheduleIndividual.fxml'."; 66 67 } 68 69} 70

ScheduleSelectController

1 2 3public class ScheduleSelectController { 4 5 @FXML // fx:id="scheduleName" 6 private TextField scheduleName; // Value injected by FXMLLoader 7 8 @FXML // fx:id="sHour" 9 private ComboBox<String> sHour; // Value injected by FXMLLoader 10 11 @FXML // fx:id="sakusei" 12 private Button sakusei; // Value injected by FXMLLoader 13 14 @FXML // fx:id="packageSelect" 15 private ComboBox<?> packageSelect; // Value injected by FXMLLoader 16 17 @FXML // fx:id="month" 18 private ComboBox<?> month; // Value injected by FXMLLoader 19 20 @FXML // fx:id="scheduleSelct" 21 private AnchorPane scheduleSelect; // Value injected by FXMLLoader 22 23 @FXML // fx:id="year" 24 private ComboBox<String> year; // Value injected by FXMLLoader 25 26 @FXML // fx:id="fHour" 27 private ComboBox<String> fHour; // Value injected by FXMLLoader 28 29 @FXML // fx:id="fMinute" 30 private ComboBox<String> fMinute; // Value injected by FXMLLoader 31 32 @FXML // fx:id="memo" 33 private TextArea memo; // Value injected by FXMLLoader 34 35 @FXML // fx:id="sMinute" 36 private ComboBox<String> sMinute; // Value injected by FXMLLoader 37 38 @FXML // fx:id="day" 39 private ComboBox<String> day; // Value injected by FXMLLoader 40 41 @FXML 42 void clickMemo(MouseEvent event) { 43 44 } 45 46 @FXML 47 void jikkou(MouseEvent event) { 48 addScheduleLabel(addData()); 49 save(); 50 System.out.println("追加しました。"); 51 } 52 53 ScheduleData addData() { 54 String name = scheduleName.getText(); 55 var sTime = LocalTime.of(Integer.parseInt(sHour.getValue()),Integer.parseInt(sMinute.getValue())); 56 var fTime = LocalTime.of(Integer.parseInt(fHour.getValue()),Integer.parseInt(fMinute.getValue())); 57 String detail = memo.getText(); 58 var sd = new ScheduleData(name, sTime, fTime, detail); 59 return sd; 60 } 61 62 63 @SuppressWarnings("static-access") 64 void addScheduleLabel(ScheduleData data) { 65 var sLabel = new Label(); 66 double stNum = (data.getsTime().getHour()+data.getsTime().getMinute()/60)*30+4; 67 double ftNum = (data.getfTime().getHour()+data.getfTime().getMinute()/60)*30+4; 68 double tNum = ftNum-stNum; 69 String str = data.gettitle()+"\n"+data.gettime()+"\n"+data.getDetail(); 70 sLabel.setText(str); 71 72 ScheduleTableController controller = ScheduleMain.stController; 73 controller.getaPane().getChildren().add(sLabel); 74 controller.getaPane().setTopAnchor(sLabel, stNum); 75 sLabel.setPrefHeight(tNum); 76 } 77 78 @FXML private void initialize() throws IOException { 79 80 } 81 82 83 void save() { 84 85 try (var out = new ObjectOutputStream(new FileOutputStream( "SaveDataFile.ser"))){ 86 out.writeObject(addData()); 87 }catch (IOException e) { 88 e.printStackTrace(); 89 } 90 } 91 92}

SaveDataFile

1ャ・ sr application.ScheduleData 2  L detailt Ljava/lang/String;L 3finishTimet Ljava/time/LocalTime;L 4startTimeq ~ L timeq ~ L titleq ~ xpt vgswgsr 5java.time.Ser評┝"Hイ xpwsq ~ wネxt 601:55・・3:07t wservgwseag

一回目の実行
一回目
二回目の実行
二回目

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

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

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

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

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

guest

回答2

0

FileInputStreamのコンストラクタにはappendという第二引数があって、そこをtrueにすると、writeしたときに前の書き込みを上書きせずに続きから書き込んでくれるみたいでした。

ObjectOutputStreamは、追記されることを想定してはいないとおもうので、追記できたようにみえても、読み出すことはきっと単純ではありませんよ。

https://docs.oracle.com/javase/jp/8/docs/api/java/io/ObjectOutputStream.html をじっくりと読んでみてはいかがかと。

java

1import java.io.*; 2import java.time.LocalTime; 3 4public class HogeSerialize { 5 public static void main(final String[] args) throws Exception { 6 final File file = new File("/tmp/xxx"); 7 file.delete(); 8 for (int i = 0; i < 10; i++) { 9 final ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file, true)); 10 oos.writeObject(LocalTime.now().toString()); 11 oos.close(); 12 } 13 14 final ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); 15 for (int i = 0; i < 10; i++) { 16 System.out.println(ois.readObject()); 17// java.io.StreamCorruptedException: invalid type code: AC 18 } 19 } 20}

投稿2021/05/04 12:50

shiketa

総合スコア3971

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

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

ryu-bamboo

2021/05/04 13:01

そうなんですか!わかりました、じっくり読んでみます。
guest

0

ベストアンサー

一つのオブジェクトしか保存されていないみたいでした。

保存しているのはここ。

java

1 void save() { 2 try (var out = new ObjectOutputStream(new FileOutputStream( "SaveDataFile.ser"))){ 3 out.writeObject(addData()); 4 }catch (IOException e) { 5 e.printStackTrace(); 6 } 7 }

addData()が返すのは、ScheduleDataのインスタンスひとつだけ。

java

1    ScheduleData addData() { 2 String name = scheduleName.getText(); 3 var sTime = LocalTime.of(Integer.parseInt(sHour.getValue()),Integer.parseInt(sMinute.getValue())); 4 var fTime = LocalTime.of(Integer.parseInt(fHour.getValue()),Integer.parseInt(fMinute.getValue())); 5 String detail = memo.getText(); 6 var sd = new ScheduleData(name, sTime, fTime, detail); 7 return sd; 8 }

オブジェクトをひとつだけしか保存していないのですから、「一つのオブジェクトしか保存されていないみたい」なのです。あなたが書いたとおりの動作です。

複数のScheduleDataを保存したいのであれば、配列なりListなりMapなりの形で保存すればよいのではないでしょうか。

投稿2021/05/04 09:57

shiketa

総合スコア3971

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

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

ryu-bamboo

2021/05/04 12:30

回答ありがとうございました!!ですがすみません、質問後に調べてると、FileInputStreamのコンストラクタにはappendという第二引数があって、そこをtrueにすると、writeしたときに前の書き込みを上書きせずに続きから書き込んでくれるみたいでした。もっと調べてから質問するべきでした…考えていただいてありがとうございました! それと、保存することはできたのですが、今度は読み込むときにエラーが起きてしまってどうしようもないので質問させてください…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問