0

我已经搜索了论坛,但一直找不到解决方案。

我正在制作一种带有 GUI 程序的库。我想要的是它通过文本文件保存条目。我可以使用我拥有的方法很好地创建对象,并且可以轻松地将它们保存到文件中。问题来自于再次启动程序并使用文本文件中的值填充 Vector。我添加的对象有一个字符串值,后跟 7 个布尔值。当我尝试从文件加载时,字符串值为空(“”)并且所有布尔值都是错误的。

在启动 GUI 的其余部分并正确填充 Vector 之前,如何让它读取文本?

编辑:很抱歉对这一切都非常含糊。我会发布代码,但它大约有 337 行长..

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Scanner;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

@SuppressWarnings("serial")
public class SteamLibraryGUI extends JFrame implements ActionListener
{
    //For main window
    private JButton exitButton, addEntry, editEntry, removeEntry; 
    private JLabel selectGame, gameCount;
    private JComboBox<String> gameCombo;
    private Vector<Game> gamesList = new Vector<Game>();
    private Vector<String> titleList = new Vector<String>();
    private int numGames = gamesList.size();
    private int selectedGame;

    //For add window
    private JFrame addFrame;
    private JLabel gameTitle = new JLabel("Title:");
    private JTextField titleText = new JTextField(60);
    private JCheckBox singleBox, coopBox, multiBox, cloudBox, controllerBox, achieveBox, pcBox;
    private JButton addGame, addCancel;

    //For edit window
    private JFrame editFrame;
    private JButton editGame, editCancel;

    public SteamLibraryGUI()
    {


        setTitle("Steam Library Organizer");
        addEntry = new JButton("Add a game");
        editEntry = new JButton("Edit a game");
        removeEntry = new JButton("Remove a game");
        exitButton = new JButton("Exit");
        selectGame = new JLabel("Select a game:");
        gameCount = new JLabel("Number of games:"+numGames);
        gameCombo = new JComboBox<String>(titleList);

        JPanel selectPanel = new JPanel();
        selectPanel.setLayout(new GridLayout(1,2));
        selectPanel.add(selectGame);
        selectPanel.add(gameCombo);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1,3));
        buttonPanel.add(addEntry);
        buttonPanel.add(editEntry);
        buttonPanel.add(removeEntry);

        JPanel exitPanel = new JPanel();
        exitPanel.setLayout(new GridLayout(1,2));
        exitPanel.add(gameCount);
        exitPanel.add(exitButton);

        Container pane = getContentPane();
        pane.setLayout(new GridLayout(3,1));
        pane.add(selectPanel);
        pane.add(buttonPanel);
        pane.add(exitPanel);

        addEntry.addActionListener(this);
        editEntry.addActionListener(this);
        removeEntry.addActionListener(this);
        exitButton.addActionListener(this);
        gameCombo.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource()==addEntry)
            addEntry();
        if(e.getSource()==editEntry)
            editEntry(gamesList.get(selectedGame));
        if(e.getSource()==removeEntry)
        {
            removeEntry(selectedGame);
            update();
        }
        if(e.getSource()==exitButton)
            exitProg();
        if(e.getSource()==gameCombo)
            {
                selectedGame = gameCombo.getSelectedIndex();
            }
        if(e.getSource()==singleBox)
            singleBox.isSelected();
        if(e.getSource()==coopBox)
            coopBox.isSelected();
        if(e.getSource()==multiBox)
            multiBox.isSelected();
        if(e.getSource()==cloudBox)
            cloudBox.isSelected();
        if(e.getSource()==controllerBox)
            controllerBox.isSelected();
        if(e.getSource()==achieveBox)
            achieveBox.isSelected();
        if(e.getSource()==pcBox)
            pcBox.isSelected();
        if(e.getSource()==addGame)
        {
            gamesList.add(new Game(titleText.getText(), singleBox.isSelected(), coopBox.isSelected(), 
                    multiBox.isSelected(), cloudBox.isSelected(), controllerBox.isSelected(), 
                    achieveBox.isSelected(), pcBox.isSelected()));
            titleList.add(titleText.getText());
            addFrame.dispose();
            update();
        }
        if(e.getSource()==addCancel)
            addFrame.dispose();
        if(e.getSource()==editCancel)
            editFrame.dispose();
        if(e.getSource()==editGame)
        {
            gamesList.get(selectedGame).name = titleText.getText();
            gamesList.get(selectedGame).single = singleBox.isSelected();
            gamesList.get(selectedGame).coop = coopBox.isSelected();
            gamesList.get(selectedGame).multi = multiBox.isSelected();
            gamesList.get(selectedGame).cloud = cloudBox.isSelected();
            gamesList.get(selectedGame).controller = controllerBox.isSelected();
            gamesList.get(selectedGame).achieve = achieveBox.isSelected();
            gamesList.get(selectedGame).pc = pcBox.isSelected();
            titleList.remove(selectedGame);
            titleList.add(titleText.getText());
            editFrame.dispose();
            update();
        }
    }

    public void update()
    {
        Collections.sort(titleList);
        Collections.sort(gamesList);
        gameCombo.updateUI();
        titleText.setText("");
        gameCombo.setSelectedIndex(-1);
        numGames = gamesList.size();
        gameCount.setText("Number of games:"+numGames);
    }

    public void addEntry()
    {
        addFrame = new JFrame("Add Entry");
        addFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        addFrame.getContentPane();
        addFrame.setLayout(new GridLayout(3,1));

        singleBox = new JCheckBox("Single-Player");
        singleBox.setSelected(false);
        coopBox = new JCheckBox("Coop");
        coopBox.setSelected(false);
        multiBox = new JCheckBox("MultiPlayer");
        multiBox.setSelected(false);
        cloudBox = new JCheckBox("Steam Cloud");
        cloudBox.setSelected(false);
        controllerBox = new JCheckBox("Controller Support");
        controllerBox.setSelected(false);
        achieveBox = new JCheckBox("Achievements");
        achieveBox.setSelected(false);
        pcBox = new JCheckBox("For New PC");
        pcBox.setSelected(false);
        addGame = new JButton("Add game");
        addCancel = new JButton("Cancel");

        JPanel titlePanel = new JPanel();
        titlePanel.setLayout(new FlowLayout());
        titlePanel.add(gameTitle);
        titlePanel.add(titleText);

        JPanel checkPanel = new JPanel();
        checkPanel.setLayout(new FlowLayout());
        checkPanel.add(singleBox);
        checkPanel.add(coopBox);
        checkPanel.add(multiBox);
        checkPanel.add(cloudBox);
        checkPanel.add(controllerBox);
        checkPanel.add(achieveBox);
        checkPanel.add(pcBox);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());
        buttonPanel.add(addGame);
        buttonPanel.add(addCancel);

        addFrame.add(titlePanel);
        addFrame.add(checkPanel);
        addFrame.add(buttonPanel);

        singleBox.addActionListener(this);
        coopBox.addActionListener(this);
        multiBox.addActionListener(this);
        cloudBox.addActionListener(this);
        controllerBox.addActionListener(this);
        achieveBox.addActionListener(this);
        pcBox.addActionListener(this);
        addGame.addActionListener(this);
        addCancel.addActionListener(this);

        addFrame.pack();
        addFrame.setVisible(true);
    }

    public void editEntry(Game g)
    {
        editFrame = new JFrame("Edit Entry");
        editFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        editFrame.getContentPane();
        editFrame.setLayout(new GridLayout(3,1));

        singleBox = new JCheckBox("Single-Player");
        singleBox.setSelected(g.single);
        coopBox = new JCheckBox("Coop");
        coopBox.setSelected(g.coop);
        multiBox = new JCheckBox("MultiPlayer");
        multiBox.setSelected(g.multi);
        cloudBox = new JCheckBox("Steam Cloud");
        cloudBox.setSelected(g.cloud);
        controllerBox = new JCheckBox("Controller Support");
        controllerBox.setSelected(g.controller);
        achieveBox = new JCheckBox("Achievements");
        achieveBox.setSelected(g.achieve);
        pcBox = new JCheckBox("For New PC");
        pcBox.setSelected(g.pc);
        editGame = new JButton("Edit game");
        editCancel = new JButton("Cancel");
        titleText.setText(g.name);

        JPanel titlePanel = new JPanel();
        titlePanel.setLayout(new FlowLayout());
        titlePanel.add(gameTitle);
        titlePanel.add(titleText);

        JPanel checkPanel = new JPanel();
        checkPanel.setLayout(new FlowLayout());
        checkPanel.add(singleBox);
        checkPanel.add(coopBox);
        checkPanel.add(multiBox);
        checkPanel.add(cloudBox);
        checkPanel.add(controllerBox);
        checkPanel.add(achieveBox);
        checkPanel.add(pcBox);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());
        buttonPanel.add(editGame);
        buttonPanel.add(editCancel);

        editFrame.add(titlePanel);
        editFrame.add(checkPanel);
        editFrame.add(buttonPanel);

        singleBox.addActionListener(this);
        coopBox.addActionListener(this);
        multiBox.addActionListener(this);
        cloudBox.addActionListener(this);
        controllerBox.addActionListener(this);
        achieveBox.addActionListener(this);
        pcBox.addActionListener(this);
        editGame.addActionListener(this);
        editCancel.addActionListener(this);

        editFrame.pack();
        editFrame.setVisible(true);
    }

    public void removeEntry(int g)
    {
        Object[] options = {"Yes, remove the game", "No, keep the game"};

        int n = JOptionPane.showOptionDialog(null, "Are you sure you want to remove this game from the list?",
                "Remove game?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
        if (n==0)
        {
            gamesList.remove(g);
            titleList.remove(g);
        }
    }

    public void exitProg()
    {
        try 
        {
            PrintWriter out = new PrintWriter("games.txt");
            out.flush();
            for(int i=0;i<gamesList.size();i++)
            {

                out.print(gamesList.get(i).toString());
            }
            out.close();
        }
        catch (FileNotFoundException e) {}
        System.exit(0);
    }

    public static void main(String[] args)
    {
        SteamLibraryGUI frame = new SteamLibraryGUI();
        frame.pack();
        frame.setSize(600,200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Scanner in = new Scanner("games.txt");
        while(in.hasNextLine())
        {
            String line = in.nextLine();
            String[] options = line.split("|");
            Game g = new Game(options[0],Boolean.getBoolean(options[1]),
                    Boolean.getBoolean(options[2]),Boolean.getBoolean(options[3]),
                    Boolean.getBoolean(options[4]),Boolean.getBoolean(options[5]),
                    Boolean.getBoolean(options[6]),Boolean.getBoolean(options[7]));
            frame.gamesList.add(g);
            frame.titleList.add(options[0]);
            System.out.println(g.toString());
        }
        in.close();
    }
}

还有一个 Game 类,但它只是 1 个字符串,然后是 7 个布尔值。

4

1 回答 1

0

代码中有两个重大错误。首先,Scanner是用字符串参数构造的(这意味着 Scanner 扫描的是字符串,而不是字符串命名的文件)。二、竖线字符“|” 是一个正则表达式元字符。这很重要,因为line.split()拆分正则表达式。因此,“|” 必须逃脱。main()如果编写如下(包含调试输出代码以显示每个步骤都正常工作),则该函数可以正常工作:

public static void main(String[] args)
{
    SteamLibraryGUI frame = new SteamLibraryGUI();
    frame.pack();
    frame.setSize(600,200);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    try
    {
        Scanner in = new Scanner(new File("games.txt"));
        while(in.hasNextLine())
        {
            System.out.println("line = ");
            String line = in.nextLine();
            System.out.println(line);
            String[] options = line.split("\\|");
            System.out.println("Options = ");
            for (String s : options)
            {
                System.out.println(s);
            }
            Game g = new Game(options[0],Boolean.getBoolean(options[1]),
                Boolean.getBoolean(options[2]),Boolean.getBoolean(options[3]),
                Boolean.getBoolean(options[4]),Boolean.getBoolean(options[5]),
                Boolean.getBoolean(options[6]),Boolean.getBoolean(options[7]));
            frame.gamesList.add(g);
            frame.titleList.add(options[0]);
            System.out.println(g.toString());
        }
        in.close();
    } catch (IOException x) 
    {
        System.err.println(x);
    }
}

还有一个重要的陷阱:该方法exitProg()在程序完成之前再次写出“games.txt”文件。如果文件首先被错误地读取,这会产生问题,因为错误的数据将被写回文件。在测试期间,这意味着即使读取代码已被纠正,它仍会读取从先前测试运行中写入的错误数据。

在这种情况下,我的偏好是隔离类中“game.txt”的所有读写代码Game(这样更容易验证读写格式是否相同),只编写写入数据的代码一旦我编写并测试了阅读代码,就退出,这将避免这个问题。

于 2013-03-24T04:37:07.603 回答