我可以使用 FileChooser (javafx) 将序列化对象保存在文件中吗?
Posted
技术标签:
【中文标题】我可以使用 FileChooser (javafx) 将序列化对象保存在文件中吗?【英文标题】:Can I save a serialized Object in a File using FileChooser (javafx)? 【发布时间】:2018-01-15 13:56:52 【问题描述】:标题非常不言自明。我想保存序列化的“spiel” 使用文件选择器作为“name.ser”文件。我还想加载文件并将其返回给我的控制器。我不知道如何连接 objectoutputstream 和 filechooser。
public class Speicher
public void spielstandSpeichern(Spiel spiel, String name) // Save File
try
FileChooser fs = new FileChooser();
fs.setInitialDirectory(new File("/Saves"));
fs.setTitle("Spiel speichern");
fs.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("Ser", ".ser")
);
//File file =
FileOutputStream fos = new FileOutputStream("Saves/save1.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(spiel);
oos.close();
fos.close();
catch(IOException e)
e.printStackTrace();
public Spiel spielstandLaden() // Load File
Spiel spiel = null;
try
FileInputStream fis = new FileInputStream("Saves/save1.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
spiel = (Spiel) ois.readObject();
ois.close();
fis.close();
catch(ClassNotFoundException e)
e.printStackTrace();
catch(IOException e)
e.printStackTrace();
return spiel;
提前致谢:)
【问题讨论】:
【参考方案1】:您可以在 FileChooser 实例上分别使用showSaveDialog
和showOpenDialog
来获取文件句柄对象以进行加载和保存。您可以在 FileInputStream 和 FileOutputStream 构造函数中使用此文件句柄对象。
【讨论】:
谢谢你,它似乎正在工作。但我刚刚意识到我无法将对象“Spiel”作为一个整体加载,因为 Spiel 中的某些类包含图像。论文图像未序列化。你知道我该如何解决这个问题吗? 在 Java 中,只有实现了java.io.Serializable
的对象才能完成对象序列化(大多数基本类型,如 String、Integer 等)。请确保必填字段是可序列化的并且没有transient
修饰符。要回答您的问题,您应该提供“Spiel”类定义的 sn-p。
我的 sn-p 在下面的答案中:)【参考方案2】:
感谢您在这方面帮助我 :) 我正在使用 MVC 架构。所以以下是我的课“Spiel”。基本上是我模特的妈妈。模型中的所有其他类都住在这里。 “Spiel”本身由“Fassade”和“Speicher”(保存/加载 Spiel 的类)处理,这是唯一不在“Spiel”内部的模型类。
“Spiel”及其下模型中的每个类都实现了可序列化。但是在某些类中,我在第一次初始化它们时会创建 new Image()。加载保存的“Spiel”时,JavaFX 无法重新创建图像,因为它们没有被序列化。
你知道我该如何解决这个问题,以便我可以保存/加载游戏吗?
public class Spiel implements Serializable
// Attribute
private static final long serialVersionUID = 16L;
private Spielzug spielzug;
private ArrayList<Spieler> spieler;
private Map map;
private Deck deck;
private Ablage ablage;
private OffeneKarten offeneKarten;
private ArrayList<RoutenBP> routenBP;
private ArrayList<StadtBP> stadtBP;
private AlleProvinzenBP alleProvinzenBP;
// Konstruktor
public Spiel(ArrayList<Spieler> spieler)
this.spieler = spieler;
map = new Map();
deck = new Deck();
ablage = new Ablage(map);
ablage.kartenVerteilen(deck.getDeck());
offeneKarten = new OffeneKarten(deck);
spielzug = new Spielzug(spieler.get(0));
bpInitialisieren();
// Methoden
// Initialisierung
private void bpInitialisieren()
//Routen BP initialisieren
routenBP = new ArrayList<RoutenBP>();
ArrayList<Image> routenImg = new ArrayList<Image>();
routenImg.add(new Image("Bilder/bp_S5_2.png"));
routenImg.add(new Image("Bilder/bp_S5_1.png"));
RoutenBP routenbp_1 = new RoutenBP(5, 2, 2, "Du brauchst eine geschlossene Route der Laenge 5, um dieses Bonusplaettchen zu erhalten.", routenImg);
routenBP.add(routenbp_1);
routenImg.clear();
routenImg.add(new Image("Bilder/bp_S6_3.png"));
routenImg.add(new Image("Bilder/bp_S6_2.png"));
routenImg.add(new Image("Bilder/bp_S6_1.png"));
RoutenBP routenbp_2 = new RoutenBP(6, 3, 3, "Du brauchst eine geschlossene Route der Laenge 6, um dieses Bonusplaettchen zu erhalten.", routenImg);
routenBP.add(routenbp_2);
routenImg.clear();
routenImg.add(new Image("Bilder/bp_S7_4.png"));
routenImg.add(new Image("Bilder/bp_S7_3.png"));
routenImg.add(new Image("Bilder/bp_S7_2.png"));
routenImg.add(new Image("Bilder/bp_S7_1.png"));
RoutenBP routenbp_3 = new RoutenBP(6, 4, 4, "Du brauchst eine geschlossene Route der Laenge 7, um dieses Bonusplaettchen zu erhalten.",routenImg);
routenBP.add(routenbp_3);
//Stadt BP initialisieren
stadtBP = new ArrayList<StadtBP>();
ArrayList<Image> stadtbpImg = new ArrayList<Image>();
stadtbpImg.add(new Image("Bilder/bp_lilaP_3.png"));
stadtbpImg.add(new Image("Bilder/bp_lilaP_2.png"));
stadtbpImg.add(new Image("Bilder/bp_lilaP_1.png"));
ArrayList<Karte> benoetigteStaedte = new ArrayList<Karte>();
benoetigteStaedte.add(map.getStadt(3));
benoetigteStaedte.add(map.getStadt(4));
benoetigteStaedte.add(map.getStadt(10));
StadtBP stadtbp_1 = new StadtBP(benoetigteStaedte, 3, 3, "Du brauchst in Freiburg, Mannheim und Carlsruhe ein Haus, um dieses Bonusplaettchen zu erhalten.",stadtbpImg);
stadtBP.add(stadtbp_1);
stadtbpImg.clear();
stadtbpImg.add(new Image("Bilder/bp_blauP_3.png"));
stadtbpImg.add(new Image("Bilder/bp_blauP_1.png"));
stadtbpImg.add(new Image("Bilder/bp_blauP_2.png"));
benoetigteStaedte.clear();
benoetigteStaedte.add(map.getStadt(1));
benoetigteStaedte.add(map.getStadt(21));
benoetigteStaedte.add(map.getStadt(6));
StadtBP stadtbp_2 = new StadtBP(benoetigteStaedte, 3, 3, "Du brauchst in Basel, Zuerich und Innsbruck ein Haus, um dieses Bonusplaettchen zu erhalten.",stadtbpImg);
stadtBP.add(stadtbp_2);
stadtbpImg.clear();
stadtbpImg.add(new Image("Bilder/bp_gruenP_3.png"));
stadtbpImg.add(new Image("Bilder/bp_gruenP_2.png"));
stadtbpImg.add(new Image("Bilder/bp_gruenP_1.png"));
benoetigteStaedte.clear();
benoetigteStaedte.add(map.getStadt(17));
benoetigteStaedte.add(map.getStadt(18));
benoetigteStaedte.add(map.getStadt(19));
StadtBP stadtbp_3 = new StadtBP(benoetigteStaedte, 3, 3, "Du brauchst in Sigmaringen, Stuttgart und Ulm ein Haus, um dieses Bonusplaettchen zu erhalten.",stadtbpImg);
stadtBP.add(stadtbp_3);
stadtbpImg.clear();
stadtbpImg.add(new Image("Bilder/bp_rotP_4.png"));
stadtbpImg.add(new Image("Bilder/bp_rotP_3.png"));
stadtbpImg.add(new Image("Bilder/bp_rotP_2.png"));
benoetigteStaedte.clear();
benoetigteStaedte.add(map.getStadt(2));
benoetigteStaedte.add(map.getStadt(8));
benoetigteStaedte.add(map.getStadt(14));
benoetigteStaedte.add(map.getStadt(16));
StadtBP stadtbp_4 = new StadtBP(benoetigteStaedte, 4, 3, "Du brauchst in Budweis, Pilsen, Linz und Salzburg ein Haus, um dieses Bonusplaettchen zu erhalten.",stadtbpImg);
stadtBP.add(stadtbp_4);
stadtbpImg.clear();
stadtbpImg.add(new Image("Bilder/bp_beigeP_5.png"));
stadtbpImg.add(new Image("Bilder/bp_beigeP_4.png"));
stadtbpImg.add(new Image("Bilder/bp_beigeP_3.png"));
stadtbpImg.add(new Image("Bilder/bp_beigeP_2.png"));
benoetigteStaedte.clear();
benoetigteStaedte.add(map.getStadt(0));
benoetigteStaedte.add(map.getStadt(5));
benoetigteStaedte.add(map.getStadt(7));
benoetigteStaedte.add(map.getStadt(11));
benoetigteStaedte.add(map.getStadt(12));
benoetigteStaedte.add(map.getStadt(13));
benoetigteStaedte.add(map.getStadt(15));
benoetigteStaedte.add(map.getStadt(20));
StadtBP stadtbp_5 = new StadtBP(benoetigteStaedte, 5, 4, "Du brauchst in Augsburg, Ingolstadt, Kempten, Münschen, Nürnberg, Passau, Regensburg und Würzburg ein Haus, um dieses Bonusplaettchen zu erhalten.",stadtbpImg);
stadtBP.add(stadtbp_5);
//Alle Provinzen BP initialisieren
ArrayList<Image> alleProvImg = new ArrayList<Image>();
alleProvImg.add(new Image("Bilder/bp_alleP_6.png"));
alleProvImg.add(new Image("Bilder/bp_alleP_5.png"));
alleProvImg.add(new Image("Bilder/bp_alleP_4.png"));
alleProvImg.add(new Image("Bilder/bp_alleP_3.png"));
alleProvinzenBP = new AlleProvinzenBP(map.getProvinzen(), 6,4, "Du brauchst in min. einer Stadt jeder Provinz ein Haus, um dieses Bonusplaettchen zu erhalten.",alleProvImg);
// Methoden
/**
* Nimmt den jetzigen Spieler entgegegen und uebergibt den naechsten.
*
* @param spieler der jetzt fertig ist
* @return spieler der jetzt dran ist
*/
public void naechsterSpieler()
int idx = spielzug.getAktuellerSpieler().getSpielerNr();
if( idx == spieler.size() )
idx = 0;
System.out.println("SPIEL: Anzahl spieler: "+spieler.size());
spielzug.setAktuellerSpieler(spieler.get(idx));
System.out.println("SPIEL: nächster Spieler ist "+spieler.get(idx).getName()+" mit SpielerNr "+ spieler.get(idx).getSpielerNr());
public void bpVergeben()
for(RoutenBP rbp : routenBP)
if(rbp.bedingungErfuellt(spielzug.getAktuellerSpieler().getRoute().getStaedte(), spielzug))
// gibt BP an Spieler
spielzug.getAktuellerSpieler().getRoutenBP().add(rbp);
// gibt Punkte für BP an Spieler
int p = spielzug.getAktuellerSpieler().getPunkte()
+ rbp.getPunkte(spielzug.getPhase());
spielzug.getAktuellerSpieler().setPunkte(p);
for(StadtBP sbp : stadtBP)
if(sbp.bedingungErfuellt(spielzug.getAktuellerSpieler().getRoute().getStaedte(), spielzug))
// gibt BP an Spieler
spielzug.getAktuellerSpieler().getStadtBP().add(sbp);
// gibt Punkte für BP an Spieler
int p = spielzug.getAktuellerSpieler().getPunkte()
+sbp.getPunkte(spielzug.getPhase());
spielzug.getAktuellerSpieler().setPunkte(p);
if(alleProvinzenBP.bedingungErfuellt(spielzug.getAktuellerSpieler().getRoute().getStaedte(), spielzug))
// gibt BP an Spieler
spielzug.getAktuellerSpieler().setAlleProvinzBP(alleProvinzenBP);
// gibt Punkte für BP an Spieler
int p = spielzug.getAktuellerSpieler().getPunkte()
+alleProvinzenBP.getPunkte(spielzug.getPhase());
spielzug.getAktuellerSpieler().setPunkte(p);
public void kutscheAktualisieren()
if(spielzug.getAktuellerSpieler().getKutsche().bedingungErfuellt(spielzug.getAktuellerSpieler().getRoute().getStaedte(), spielzug))
int p = spielzug.getAktuellerSpieler().getPunkte()
+ spielzug.getAktuellerSpieler().getKutsche().getPunkte(spielzug.getPhase());
spielzug.getAktuellerSpieler().setPunkte(p);
public void hauspunkteVergeben()
if(spielzug.getAktuellerSpieler().getHaeuser()
.bedingungErfuellt(spielzug.getAktuellerSpieler().getRoute().getStaedte(), spielzug))
int p = spielzug.getAktuellerSpieler().getPunkte()
+ spielzug.getAktuellerSpieler().getHaeuser().getPunkte(spielzug.getPhase());
spielzug.getAktuellerSpieler().setPunkte(p);
// Setter und Getter FUnktionen
public Spielzug getSpielzug()
return spielzug;
public void setSpielzug(Spielzug spielzug)
this.spielzug = spielzug;
public ArrayList<Spieler> getSpieler()
return spieler;
public void setSpieler(ArrayList<Spieler> spieler)
this.spieler = spieler;
public Map getMap()
return map;
public void setMap(Map map)
this.map = map;
public Deck getDeck()
return deck;
public void setDeck(Deck deck)
this.deck = deck;
public Ablage getAblage()
return ablage;
public void setAblage(Ablage ablage)
this.ablage = ablage;
public OffeneKarten getOffeneKarten()
return offeneKarten;
public void setOffeneKarten(OffeneKarten offeneKarten)
this.offeneKarten = offeneKarten;
public ArrayList<RoutenBP> getRoutenBP()
return routenBP;
public ArrayList<StadtBP> getStadtBP()
return stadtBP;
public AlleProvinzenBP getAlleProvinzenBP()
return alleProvinzenBP;
【讨论】:
我认为参与序列化的类应该定义一个非参数构造函数。您使用的是什么图像对象。你的问题是基于 javafx,所以我假设它是javafx.scene.image.Image
,它没有实现 Serializable
。如果是这样,请尝试使用不同的类,您可以从中创建 javafx Image 对象。如果需要序列化的全部威力,可以实现:private void writeObject(ObjectOutputStream out) throws IOException; private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
来增强正常进程。
所以我可以实现一个扩展 Image 并实现 Serialziable 的类“图片”?很有帮助,谢谢
我没有对此进行测试,但我有疑问。整个类层次结构需要是可序列化的。您可以尝试使用对象组合创建一个带有 Image 类型的瞬态字段和一个捕获图像路径的 String 字段的 Picture 类(实现 Serializable)。在您的 getImage 方法中,您可以使用字符串路径创建 Image 对象(如果为 null)。以上是关于我可以使用 FileChooser (javafx) 将序列化对象保存在文件中吗?的主要内容,如果未能解决你的问题,请参考以下文章