二进制序列化加载菜单

问题描述 投票:0回答:2

我正在用java做一个海战游戏,我用JMenubar创建了一个菜单,我希望能够保存和加载一个游戏。

我创建了一个类 chargerActionListener 实现ActionListener将其添加到我的菜单中的一个项目中,但它不工作,这不会给我返回一个错误,但不会加载 高原 对象,我的加载功能是正确的,我测试了它。

 package actionlistener;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.JFileChooser;

import Main.Plateau;
import interfaceGraphique.Fenetre;
import ioforme.IOPlateau;

public class ChargerActionListener implements ActionListener {
    public Fenetre fenetre;
    public Plateau plateau;
    public ChargerActionListener(Fenetre fenetre)
    {
        this.fenetre = fenetre;


    }

    public void actionPerformed(ActionEvent arg0) {

        JFileChooser choix = new JFileChooser();
        int retour=choix.showOpenDialog(fenetre);
        if(retour==JFileChooser.APPROVE_OPTION){

            try {


                Plateau p = IOPlateau.lire(choix.getSelectedFile().getAbsolutePath());
                fenetre.setPlateau(p);
                System.out.println(choix.getSelectedFile().getAbsolutePath());

                fenetre.actualiserGrilleCible();
                fenetre.actualiserMaGrille();


            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

我很快就写了这段代码,它工作得很完美,但问题还是一样的,我有三个按钮,一个是保存,一个是加载,还有一个是在控制台显示人类对象,我可以放心地保存。例如 : 我启动了这个程序 人类("让",10) (在主函数中)我保存.我退出我的程序,然后我改变了人类("让",50) 当我按下加载按钮时,我加载了之前保存的文件,然后我点击按钮,在控制台显示,它会显示我 "人类[Jean,50]",但我想 "人类[Jean,10]"

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import javax.swing.*;



public class Main  {

    public static class Human implements Serializable {
        String name;
        int age;
        public Human(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public String toString() {
            return "Human [name=" + name + ", age=" + age + "]";
        }


    }


    public static class ChargerActionListener implements ActionListener {
        public Fenetre fenetre;

        public ChargerActionListener(Fenetre fenetre)
        {
            this.fenetre = fenetre;


        }

        public void actionPerformed(ActionEvent arg0) {
            JFileChooser choix = new JFileChooser();
            int retour=choix.showOpenDialog(null);
            if(retour==JFileChooser.APPROVE_OPTION){

                try {


                    Human h  = IOPlateau.lire(choix.getSelectedFile().getAbsolutePath());
                    fenetre.setHuman(h);
                    System.out.println(choix.getSelectedFile().getAbsolutePath());


                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }


        }

    }
    public static class SauvegarderActionListener implements ActionListener {
        public Fenetre fenetre;

        public SauvegarderActionListener(Fenetre fenetre)
        {
            this.fenetre = fenetre;


        }

        public void actionPerformed(ActionEvent arg0) {
            JFileChooser choix = new JFileChooser();
            int retour=choix.showSaveDialog(null);
            if(retour==JFileChooser.APPROVE_OPTION){

                try {


                    IOPlateau.sauver(fenetre.getHuman(),choix.getSelectedFile().getAbsolutePath());

                    System.out.println(choix.getSelectedFile().getAbsolutePath());


                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }


        }

    }
    public static class Fenetre extends JFrame {

        private Human human;

        Fenetre (Human human)
        {
            this.human = human;
            this.setTitle("test");
            this.setSize(1200,500);
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     
            JButton save = new JButton ();
            save.addActionListener(new SauvegarderActionListener(this));
            JButton load = new JButton();
            load.addActionListener(new ChargerActionListener(this));
            JButton display = new JButton ();
            JPanel panel = new JPanel (new GridLayout(1,3));
            // Button for load and save !
            panel.add(save);
            panel.add(load);
            panel.add(display);

            this.setContentPane(panel);
            display.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evenement) 
                {
                    System.out.println(human);
                }
            });
            this.setVisible(true);
        }
        public void setHuman (Human human)
        {
            this.human = human;
        }
        public Human getHuman ()
        {
            return this.human;
        }


    }

    public static class IOPlateau {

        public static Human lire(String fileName) throws IOException {

                Human h = null;
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
                try {
                        h = (Human) ois.readObject();
                } catch (ClassNotFoundException cnfe) {
                    // erreur de lecture
                } catch (EOFException eofe) {
                    //fin de fichier
                }
                ois.close();
                return h;
        }

        public static void sauver(Human h, String fileName) throws IOException {
            try {

                // Recevoir le fichier 
                File f = new File(fileName);

                // Créer un nouveau fichier
                // Vérifier s'il n'existe pas
                if (f.createNewFile())
                    System.out.println("File created");
                else
                    System.out.println("File already exists");
            }
            catch (Exception e) {
                System.err.println(e);
            }
            ObjectOutputStream oos;
            oos = new ObjectOutputStream(new FileOutputStream(fileName));
            oos.writeObject(h);
            oos.close();

        }

    }


    public static void main(String[] args) {

        Human human = new Human ("Jean",11);
        Fenetre fenetre = new Fenetre(human);


    }

}
java swing serialization load
2个回答
0
投票

你是否将ChargerActionListener正确地添加到项目中。

.addActionListener(new ChargerActionListener(fenetre));

也可以尝试使用:

JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());

int returnValue = jfc.showOpenDialog(null);

也许'null'作为'showOpenDialog'的参数会有效果(我不知道fenetre或plateau应该是什么)

另外,可能只有对话框打不开,但实际上Listener被调用了。

请通过运行类似(在'actionPerformed'中)的东西来检查。

System.out.println("Ok");

0
投票

你的问题出在 actionListener() 的相关方法。展示 JButton . 因为该类成员 human 与类的构造函数中的参数名称相同。Fenetre在构造函数代码中,凡是要访问成员(而不是参数)的地方,都需要使用 this 关键字。

下面是方法 actionListener() 应该写。

display.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evenement) {
        System.out.println(Fenetre.this.human);
    }
});

你需要 Fenetre.this.human 因为你正在创建一个匿名的、内部的类和 human 是外层类的成员。

如果你使用的是至少Java 8,你可以将匿名的内类替换成一个 兰姆达表达式 由于接口 java.awt.event.ActionListener 是一个功能接口,即一个正好包含一个抽象方法的接口。这里是替换匿名、内类的lambda表达式。

display.addActionListener(e -> System.out.println(this.human));

正如你所看到的,在lambda表达式中,你只需要写上 this.human 为了进入会员 human 级别的 Fenetre.


-1
投票

你的序列化代码工作正常。你的问题在于如何显示得到的结果。你可以这样做。

public static class Fenetre extends JFrame {
    private Human human;

    Fenetre(Human human) {
        this.human = human;

        // ....

        display.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evenement) {
                System.out.println(human);
            }
        });

        // ....
    }

    // ....
}

你的 System.out.println(human); 调用的是传递到构造函数中的参数,而不是类的字段,所以值永远不会改变。

如果你现在把你的代码改成

public static class Fenetre extends JFrame {
    private Human human;

    Fenetre(Human human) {
        this.human = human;

        // ....

        display.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evenement) {
                System.out.println(getHuman());
            }
        });

        // ....
    }

    // ....
}

Since getHuman() 返回实例字段human所持有的值,你会看到结果是正确的,human字段的引用值实际上已经改变了。

© www.soinside.com 2019 - 2024. All rights reserved.