【问题标题】:How do I save the state of my program? [duplicate]如何保存程序的状态? [复制]
【发布时间】:2023-03-24 04:00:02
【问题描述】:

对于我的程序,我有两个按钮,“添加”和“保存”。当我单击“添加”时,JPanel 中会添加一个按钮。 我的问题是,如何使用用户添加的所有按钮保存程序的当前状态?我是否使用序列化? 这是我的代码的 sn-p:

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 
       }

   } 

}

【问题讨论】:

  • 是的,序列化可能有效
  • @Scary Wombat 我将如何对这部分使用序列化?我确定我不应该序列化这些按钮,因为它们可能有一百万个。我应该序列化 JFrame 还是 JPanel?
  • 1) “这是我的代码的 sn-p:” 这..String str = JOptionPane.showMessageDialog(null, "Name of button"); ..甚至可以编译吗? 2) 请参阅Detection/fix for the hanging close bracket of a code block 了解我无法再费心解决的问题。
  • @Andrew Thompson 我修好了
  • @MadProgrammer “作为一般建议,序列化并不意味着对象的长期存储。” 我认为澄清该建议适用于“对象序列化”很有用' 使用 Java 的默认对象序列化。还有许多其他方法可以序列化数据/程序状态。我通常会制作一个需要存储的 Java bean,并使用XMLEncoderXMLDecoder 来写入/读取它。至于'其他方法的序列化去,有很多选择。一些细节见this answer

标签: java swing button serialization


【解决方案1】:

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

但是,您可以定义自己的包含必要状态信息的配置对象并在任何时候保存(可能是在关闭应用程序之前,可能是每次状态更改时,这取决于您)并且序列化可能是一种去做吧

【讨论】:

  • 我将如何进行序列化部分?因为我很确定我不应该序列化我的按钮,因为它们可能很多。我可以序列化我的 JPanel 或 JFrame 吗?
  • JPanels 是可序列化的,但我必须承认我从未尝试过序列化。序列化 JDK 基类的另一个问题是您可能无法重新膨胀到不同的版本。就个人而言,我会有单独的对象跟踪需要序列化的内容,然后在其上使用 ObjectOutputStream/ObjectInputStream,将应用程序的状态与实际实现分离。但这只是我。
【解决方案2】:

这取决于你如何保存它。您可以将状态写入文件,然后通过读取从那里恢复。按钮的数量和顺序等。您还必须决定如何保存它的格式。例如,您可能希望存储在一行中

保存,JButton,imageSrc,xpos,ypos

因此,当您阅读该行并在 '' 处拆分时,您知道 Save 是文本,JButton 是类,等等。

希望对你有帮助

【讨论】:

    【解决方案3】:

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

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

    (link)

    这是一个例子:

    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();
    }
    

    【讨论】:

    • 我是否可以将其添加到我的 actionListener 中以获取“保存”按钮?
    • 您可以在需要它们的任何地方调用这些方法——这很可能在您的保存按钮中,尽管我们无法为您决定,因为它是您的程序。
    • 直接来自JavaDocs "警告:此类的序列化对象将与未来的 Swing 版本不兼容。当前的序列化支持适用于运行Swing 的相同版本。从 1.4 开始,java.beans 包中添加了对所有 JavaBeans™ 长期存储的支持。请参阅 XMLEncoder。"
    • @D.Maximov 一般不推荐“对象序列化”(使用ObjectOutputStream),有许多其他方法可以做到这一点,可能使用 JAXB 或 Java Bean 的 XML编码器/解码器或PropertiesPreferences,您使用的将归结为您想要实现的目标,没有“一刀切”的答案
    • @MadProgrammer 我会尝试使用属性。
    猜你喜欢
    • 2018-03-05
    • 2014-08-05
    • 2020-10-07
    • 2013-02-24
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 2012-01-28
    相关资源
    最近更新 更多