0

フォーラムを検索しましたが、解決策が見つからないままです。

GUIプログラムで一種のライブラリを作っています。私が欲しいのは、テキストファイルを介してエントリを保存することです。私が持っている方法でオブジェクトをうまく作成でき、それらをファイルに簡単に保存できます。問題は、プログラムを再起動し、テキスト ファイル内の値を Vector に入力することから発生します。追加するオブジェクトには文字列値があり、その後に 7 つのブール値が続きます。ファイルからロードしようとすると、文字列値が空 ("") になり、すべてのブール値が false になります。

GUI の残りの部分を開始してベクターを正しく埋める前に、テキストを読み取らせるにはどうすればよいですか?

編集:すべてについて非常に曖昧で申し訳ありません。コードを掲載しますが、約 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

コードには 2 つの重大なバグがありました。最初に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);
    }
}

もう 1 つ重要な問題があります。このメソッドexitProg()は、プログラムが終了する前に「games.txt」ファイルを再度書き出します。最初にファイルが正しく読み取られなかった場合、間違ったデータがファイルに書き戻されるため、問題が発生します。テスト中、これは、読み取りコードが修正された場合でも、以前のテスト実行で書き込まれたエラー データを引き続き読み取ることを意味します。

この状況での私の好みは、クラス内の「game.txt」のすべての読み取りおよび書き込みコードを分離しGame(読み取りおよび書き込み形式が同一であることを簡単に確認できるようにする)、データを書き込むためのコードのみを記述することです。読み取りコードを作成してテストしたら、この問題を回避できます。

于 2013-03-24T04:37:07.603 に答える