Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何保存程序的状态?_Java_Swing_Button_Serialization - Fatal编程技术网

Java 如何保存程序的状态?

Java 如何保存程序的状态?,java,swing,button,serialization,Java,Swing,Button,Serialization,对于我的程序,我有两个按钮,“添加”和“保存”。当我单击“添加”时,一个按钮被添加到JPanel我的问题是,如何使用用户添加的所有按钮保存程序的当前状态?是否使用序列化? 以下是我的代码片段: public class saveButton { //JFrame and JPanels have been declared earlier class ClickListener implements ActionListener { public void ac

对于我的程序,我有两个按钮,“添加”和“保存”。当我单击“添加”时,一个按钮被添加到JPanel我的问题是,如何使用用户添加的所有按钮保存程序的当前状态?是否使用序列化? 以下是我的代码片段:

public class saveButton
{
   //JFrame and JPanels have been declared earlier

   class ClickListener implements ActionListener
   {
       public void actionPerformed(ActionEvent e)
       {
           String str = JOptionPane.showInputDialog("Name of button");
           JButton b = new JButton(str);
           frame.add(b);
       }
   }
   ActionListener addButtonClicked = new ClickListener();
   b.addActionListener(addButtonClicked);

   class ClickListenerTwo implements ActionListener
   {
       public void actionPerformed(ActionEvent f)
       {
           //save all of the program 
       }

   } 
}

如果对象和类中的每个非临时成员都支持序列化,则只能序列化(即直接的Java序列化)。这并不总是可能的


但是,您可以定义自己的配置对象,该对象包含必要的状态信息,并在任何时候保存(可以在关闭应用程序之前保存,也可以在每次状态更改时保存,这取决于您的保存方式),序列化可能是一种方法。您可以将状态写入一个文件,然后通过读取该文件将其恢复。按钮的数量和顺序等。您还必须决定如何保存它的格式。例如,您可能希望存储在一行中

保存、JButton、imageSrc、xpos、ypos

所以当你读到那一行并在“,”上拆分时,你知道Save是文本,JButton是类,等等


希望这有帮助

我将编写自己的文件格式,而不是处理Java序列化的开销。这样做的好处是在其他语言中更容易阅读,并且性能稍好。此外,正如@MadProgrammer所指出的,Swing对象的序列化目前不受支持,并且与将来的版本不兼容:

警告:此类的序列化对象将与不兼容 未来的Swing版本。当前的序列化支持是 适用于运行的应用程序之间的短期存储或RMI 同样版本的Swing。从1.4开始,支持长期储存 所有JavaBeans™ 已添加到java.beans包中。请看

()

以下是一个例子:

public void saveState(){
    File stateFile = new File("./stateFile");
    FileOutputStream fos = new FileOutputStream(stateFile);
    DataOutputStream dos = new DataOutputStream(fis);

    for(JButton button : jButtons){ //store the buttons in an arraylist when they are created (you could also iterate over the added components and use instanceof)
        dos.writeUTF(button.getText());
    }

    dos.writeUTF("end"); //have some sort of end marker

    dos.flush();
    dos.close();
    fos.flush();
    fos.close()
}

public void loadState(){
    File stateFile = new File("./stateFile");
    FileInputStream fis = new FileInputStream(stateFile);
    DataInputStream dis = new DataInputStream(fis);
    String name;

    while(!(name = dis.readUTF()).equals("end")){
        add(new JButton(name));
    }

    fis.close();
}

是的,我可以work@Scary袋熊我将如何为这个部分使用序列化?我肯定我不应该序列化这些按钮,因为它们可能有一百万个。我应该序列化JFrame还是JPanel?1)“下面是我的代码片段:“这是<代码>字符串str=JOptionPane.showMessageDialog(null,“按钮名称”)。甚至编译?2) 看看有没有一个问题我再也懒得去解决了。@Andrew Thompson我解决了it@MadProgrammer“一般来说,序列化并不是为了对象的长期存储……”我认为澄清这个建议适用于使用Java默认对象序列化的“对象序列化”。序列化数据/程序状态还有许多其他方法。我通常会为任何需要存储的内容制作一个Javabean,并使用
XMLEncoder
XMLDecoder
来编写/读取它。至于序列化的“其他方法”,有很多选择。有关某些的详细信息,请参阅。我将如何执行序列化部分?因为我很确定我不应该序列化我的按钮,因为可能有很多按钮。我可以序列化我的JPanel或JFrame吗?JPanel是可序列化的,尽管我必须承认我从未尝试过序列化。序列化基本JDK类的另一个问题是,您可能无法将其重新扩展到其他版本。就我个人而言,我会让不同的对象跟踪需要序列化的内容,然后在此基础上使用ObjectOutputStream/ObjectInputStream,将应用程序的状态与实际实现分离。但那只是我。然后我会将它添加到我的actionListener中,用于我的“保存”按钮吗?你可以在任何需要的地方调用这些方法——它们很可能在你的“保存”按钮中,尽管这是我们无法为你决定的,因为它是你的程序。直接从“警告:此类的序列化对象将与将来的Swing版本不兼容。当前的序列化支持适用于运行同一版本Swing的应用程序之间的短期存储或RMI。从1.4开始,支持所有JavaBean的长期存储™ 已添加到java.beans包中。请参阅xmlcoder.@D.Maximov作为“对象序列化”的一般规则(使用
ObjectOutputStream
)通常不推荐使用,有许多其他方法可以做到这一点,可能使用JAXB或JavaBean的XML编码器/解码器或
属性
首选项
,这些方法的使用将取决于您想要实现的目标,没有“一刀切”的方法answer@MadProgrammer那么我将尝试使用属性。