Java:如何保存文件和覆盖并显示Combobox字符串



我正在使用bluejay在学校项目上工作,我创建了两个包装逻辑中的类,即游戏类,vectorgames类。

在我的包GUI中,我创建了一个名为AddGame和ViewGame类的类。

我遇到的问题是,当我在AddGame上单击"保存"按钮时,它仅保存一次文件。当我尝试保存时,它不会做或说什么,它只是在那里归还什么都没有。遇到的另一个问题是,在ViewGame上,GameType列保持空(这是来自组合类型框(

addgame代码:

    package GUI;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import Logic.*;
public class AddGame extends JFrame implements ActionListener{
    private JPanel north, south, east, west, center;
    private JLabel titleLabel, westLabel, eastLabel;
    private JTextField gameNameFld, gameKeyFld;
    private JComboBox gameTypeCombo;
    private JButton saveButton, clearButton;
    private VectorGames vg;
    public AddGame(){
        super("Adding a Game");
        this.setLayout(new BorderLayout());
        vg = new VectorGames();
        vg.readFromFile();
        //north panel
        north = new JPanel();
        this.add(north,BorderLayout.NORTH);
        titleLabel = new JLabel("Add a game below");
        titleLabel.setFont(new Font("Verdana",Font.BOLD,20));
        titleLabel.setForeground(Color.black);
        north.add(titleLabel);
        //west and east panels
        west = new JPanel();
        east = new JPanel();
        this.add(west, BorderLayout.WEST);
        this.add(east, BorderLayout.EAST);
        westLabel = new JLabel("    ");
        eastLabel = new JLabel("    ");
        west.add(westLabel);
        east.add(eastLabel);
        //center panel
        center = new JPanel();
        this.add(center, BorderLayout.CENTER);
        center.setLayout(new GridLayout(4,2,0,20));
        gameNameFld = new JTextField();
        gameKeyFld = new JTextField();
        gameTypeCombo = new JComboBox();
        gameTypeCombo.setModel(new DefaultComboBoxModel(new String[]
        {"<--Select-->", "Arcade", "Puzzle", "Adventure", "Shooter", "Roleplay"}));
        center.add(createLabel("Game Name"));
        center.add(gameNameFld);
        center.add(createLabel("Game Key"));
        center.add(gameKeyFld);
        center.add(createLabel("Game Type"));
        center.add(gameTypeCombo);
        //south panel
        south = new JPanel();
        south.setLayout(new FlowLayout());
        this.add(south, BorderLayout.SOUTH);
        clearButton = new JButton("Clear");
        south.add(clearButton);
        clearButton.addActionListener(this);
        saveButton = new JButton("Save");
        south.add(saveButton);
        saveButton.addActionListener(this);
        this.setSize(300,400);
        this.setLocation(50,50);
        this.setVisible(true);
    }
    private JLabel createLabel(String title){
        return new JLabel(title);
    }
    private void clearFields(){
        gameNameFld.setText("");
        gameKeyFld.setText("");
        gameTypeCombo.setSelectedIndex(0);
    }
    private boolean validateForm(){
        boolean flag = false;
        if(gameNameFld.getText().equals("")||gameKeyFld.getText().equals("")||
        gameTypeCombo.getSelectedIndex()==0){
            flag = true;
        }
        return flag;
    }

    public void actionPerformed(ActionEvent event){
        if (event.getSource() == clearButton){
            clearFields();
        }
        if(event.getSource() == saveButton){
            if(validateForm() == true){
                JOptionPane.showMessageDialog(null,"You have empty fields",
                "Empty Fields", JOptionPane.ERROR_MESSAGE);
            } else if(vg.checkGamebyGameKey(gameKeyFld.getText()) == true){
            JOptionPane.showMessageDialog(null,"Game Key already exists!",
            "Game Key Check", JOptionPane.ERROR_MESSAGE);
        } else {
            Game tempGame = new Game(gameNameFld.getText(),gameKeyFld.getText(),
            (String)gameTypeCombo.getSelectedItem());
            vg.addGame(tempGame);
            vg.saveToFile();
            JOptionPane.showMessageDialog(null, "Game added successfully!", "Adding a Game",
            JOptionPane.INFORMATION_MESSAGE);
            clearFields();
        }
    }
   }
}    

查看游戏代码:

package GUI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import Logic.*;
public class ViewGame extends JFrame {
    private JTable table;
    private VectorGames vg;
    public ViewGame(){
        super("Viewing Games by Name");
        this.setLayout(new BorderLayout());
        vg = new VectorGames();
        vg.readFromFile();
        vg.sortGamesByName();
        int numOfGames = vg.getVectorSize();
        int count = 0;
        Game tempGame = new Game();
        String[] tableHeader = {"Game Name", "Game Type", "Game Key"};
        Object [][] tableContent = new Object[numOfGames][3];
        for(int i = 0; i < numOfGames; i++){
            tempGame = vg.getGamesByIndex(count);
            tableContent[i][0] = tempGame.getGameName();
            tableContent[i][2] = tempGame.getGameType();
            tableContent[i][1] = tempGame.getGameKey();
        }
        table = new JTable (tableContent, tableHeader);
        JScrollPane scrollPane = new JScrollPane(table);
        table.setPreferredScrollableViewportSize(new Dimension(500, 400));
        this.add(table.getTableHeader(), BorderLayout.NORTH);
        this.add(table, BorderLayout.CENTER);
        this.setSize(500,600);
        this.setLocation(100,50);
        this.setVisible(true);
    }
}

游戏代码:

package Logic;
import java.io.*;
public class Game implements Serializable{ // Using serializable to allow easy save and read access
    //Initializing variables related to Game
    private String gameName, gameKey, gameType;
    //Creating a constructor with the parameters for class Games
    public Game(String gameName, String gamekey, String gameType){
        setGameName(gameName);
        setGameKey(gameKey);
        setGameType(gameType);
    }
    //Setting up a parameterless constructor for class Games
    public Game(){
    }
    public String getGameName(){//Get Method for gameName
        return gameName;
    }
    public String getGameKey(){//Get Method for gameKey
        return gameKey;
    }
    public String getGameType(){//Get Method for gameType
        return gameType;
    }
    public void setGameName(String gameName){//Set Method for gameName
        this.gameName = gameName;
    }
    public void setGameKey(String gameKey){//Set Method for gameKey
        this.gameKey = gameKey;
    }
    public void setGameType(String gameType){//Set Method for gameType
        this.gameType = gameType;
    }
    public String toString(){
        return "Game Name : " + gameName + "nGame Key : "
        + gameKey + "nGame Type ; " + gameType;
    }
}

vectorgames代码:

package Logic;
import java.util.*;
import java.io.*;
import java.lang.*;
public class VectorGames extends IOException{
    /* Add a Game, Remove a Game, getVectorGame Size, print allGamesAvailable, 
     * saveToFile , searchGame and return boolean literal, searchGame and return
     * client object, sort games, readFromFile.
     * 
     */
    private Vector<Game> games;
    public VectorGames(){
        games = new Vector<Game>();
    }
    //Adding a Game
    public void addGame(Game game){
        games.add(game);
    }
    public void deleteGame(Game game){
        games.remove(game);
    }
    public int getVectorSize(){
        return games.size();
    }
    public void clearVector(){
        games.clear();
    }
    public void printGames(){
        for(Game tempGame : games){
            System.out.println(tempGame.toString());
            System.out.println("");
        }
    }
    public Game getGamesByIndex(int i){
        Game tempGame = new Game();
        if (i < getVectorSize()){
            tempGame = games.get(i);
        }
        return tempGame;
    }
    public void sortGamesByName(){
        Game currentGame = new Game();
        Game nextGame = new Game();
        Game tempGame = new Game();
        for(int i = 0; i < getVectorSize(); i++){
            for(int j = 0; j < getVectorSize()-i-1; j++){
                currentGame = games.elementAt(j);
                nextGame = games.elementAt(j+1);
                if(currentGame.getGameName().compareTo(nextGame.getGameName())>0){
                    tempGame = currentGame;
                    games.setElementAt(nextGame, j);
                    games.setElementAt(tempGame, j+1);
                }
            }
        }
    }
    public boolean checkGamebyGameKey(String gameKey){
        boolean flag = false;
        for(Game tempGames : games){
            if(tempGames .getGameKey().equals(gameKey)){
                flag = true;
            }
        }
        return flag;
    }
    public Game accessGameByGameName(String gameName){
        Game foundGameName = new Game();
        for(Game tempGames: games){
            if(tempGames.getGameName().equals(gameName)){
                foundGameName = tempGames;
            }
        }
        return foundGameName;
    }
    public void saveToFile(){
        try{
            File f = new File("C:/Users/Denis/Desktop/GameStore/Databases","gameList.obj");
            FileOutputStream fos = new FileOutputStream(f);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(games);
            oos.flush();
            oos.close();
        }catch (IOException ioe){
            System.err.println("Cannot write to file!");
        }
    }
    public void readFromFile(){
        try{
            File f = new File("C:/Users/Denis/Desktop/GameStore/Databases","gameList.obj");
            FileInputStream fis = new FileInputStream(f);
            ObjectInputStream ois = new ObjectInputStream(fis);
            games = (Vector<Game>) ois.readObject();
            ois.close();
        } catch (FileNotFoundException fnfe){
            System.err.println("Cannot find file!");
        }catch (IOException ioe){
            System.err.println("Cannot read from file!");
        }catch(ClassNotFoundException cnfe){
            System.err.println("Client class cannot be found!");
        }
    }
}

主类:gamecenter

public class GameCenter extends JFrame {
    public static void main(String... args) {
        SwingUtilities.invokeLater(() -> new GameCenter().setVisible(true));
    }
    public GameCenter() {
        super("Game Center");
        init();
    }
    private void init() {
        setLayout(new BorderLayout(5, 5));
        Model model = new Model();
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.add("Add", new AddTabPanel(model));
        tabbedPane.add("View", new ViewTabPanel(model));
        add(tabbedPane, BorderLayout.CENTER);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400, 500);
        setMinimumSize(new Dimension(400, 500));
        setResizable(false);
    }
}

游戏实体:

final class Game {
    private static final Pattern RECORD = Pattern.compile("(?<key>.+)\|(?<name>.+)\|(?<type>.+)");
    private final String name;
    private final String key;
    private final String type;
    public static Game createFromRecord(String str) {
        Matcher matcher = RECORD.matcher(str);
        return matcher.matches() ? new Game(matcher.group("name"), matcher.group("key"), matcher.group("type")) : null;
    }
    public Game(String name, String key, String type) {
        this.name = name;
        this.key = key;
        this.type = type;
    }
    public String getName() {
        return name;
    }
    public String getKey() {
        return key;
    }
    public String getType() {
        return type;
    }
    public String serialize() {
        return String.format("%s|%s|%s", key, name, type);
    }
}

表模型:

final class Model extends AbstractTableModel {
    private static final long serialVersionUID = 1858846855164475327L;
    private final Map<String, Game> keyGame = new TreeMap<>();
    private final List<Game> data = new ArrayList<>();
    private File file;
    public File getFile() {
        return file;
    }
    public void setFile(File file) {
        this.file = file;
    }
    public void add(String name, String key, String type) {
        keyGame.put(key, new Game(name, key, type));
        fireTableDataChanged();
    }
    public void remove(int rowIndex) {
        keyGame.remove(data.get(rowIndex).getKey());
        fireTableDataChanged();
    }
    public void save() throws IOException {
        if (file == null)
            return;
        try (FileWriter out = new FileWriter(file, false)) {
            for (Game game : keyGame.values())
                out.write(game.serialize() + 'n');
        }
    }
    public void read() throws IOException {
        if (file == null)
            return;
        keyGame.clear();
        for (String record : Files.readAllLines(file.toPath())) {
            Game game = Game.createFromRecord(record);
            if (game != null)
                keyGame.put(game.getKey(), game);
        }
        fireTableDataChanged();
    }
    private enum Column {
        NAME("Game Name", Game::getName),
        KEY("Game Key", Game::getKey),
        TYPE("Game Type", Game::getType);
        private final String title;
        private final Function<Game, Object> get;
        Column(String title, Function<Game, Object> get) {
            this.title = title;
            this.get = get;
        }
        public Object getValue(Game game) {
            return get.apply(game);
        }
    }
    // ========== AbstractTableModel ==========
    @Override
    public void fireTableDataChanged() {
        data.clear();
        data.addAll(keyGame.values());
        super.fireTableDataChanged();
    }
    // ========== TableModel ==========
    @Override
    public int getRowCount() {
        return data.size();
    }
    @Override
    public int getColumnCount() {
        return Column.values().length;
    }
    @Override
    public String getColumnName(int columnIndex) {
        return Column.values()[columnIndex].title;
    }
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return Column.values()[columnIndex].getValue(data.get(rowIndex));
    }
}

addGame选项卡面板:

final class AddTabPanel extends JPanel implements ActionListener, DocumentListener {
    private final Model model;
    private final JTextField nameField = new JTextField();
    private final JTextField keyField = new JTextField();
    private final JLabel nameLabel = new JLabel("Game Name");
    private final JLabel keyLabel = new JLabel("Game Key");
    private final JLabel typeLabel = new JLabel("Game Type");
    private final JComboBox<String> typeCombo = createGameTypeCombo();
    private final JButton openButton = new JButton("Open");
    private final JButton saveButton = new JButton("Save");
    private final JButton clearButton = new JButton("Clear");
    public AddTabPanel(Model model) {
        this.model = model;
        init();
        addListeners();
    }
    private void init() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = createConstraints();
        add(createTitlePanel(), gbc);
        add(createMainPanel(), gbc);
        add(createButtonPanel(), gbc);
        gbc.weighty = 1;
        add(Box.createVerticalGlue(), gbc);
        onNameFieldChanged();
        onKeyFieldChanged();
        onTypeComboChanged();
    }
    private static JPanel createTitlePanel() {
        JLabel label = new JLabel("Add a game below");
        label.setFont(new Font("Verdana", Font.BOLD, 20));
        JPanel panel = new JPanel();
        panel.add(label);
        return panel;
    }
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new GridLayout(3, 2, 5, 5));
        panel.add(nameLabel);
        panel.add(nameField);
        panel.add(keyLabel);
        panel.add(keyField);
        panel.add(typeLabel);
        panel.add(typeCombo);
        return panel;
    }
    private static GridBagConstraints createConstraints() {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        return gbc;
    }
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel();
        panel.add(clearButton);
        panel.add(saveButton);
        panel.add(openButton);
        return panel;
    }
    private static JComboBox<String> createGameTypeCombo() {
        JComboBox<String> combo = new JComboBox<>();
        combo.setModel(new DefaultComboBoxModel<>(new String[] { "<--Select-->", "Arcade", "Puzzle", "Adventure", "Shooter", "Roleplay" }));
        return combo;
    }
    private void addListeners() {
        clearButton.addActionListener(this);
        saveButton.addActionListener(this);
        openButton.addActionListener(this);
        nameField.getDocument().addDocumentListener(this);
        keyField.getDocument().addDocumentListener(this);
        typeCombo.addActionListener(this);
    }
    private void validateFields() {
        String name = nameField.getText().trim();
        String key = keyField.getText().trim();
        int type = typeCombo.getSelectedIndex();
        saveButton.setEnabled(!name.isEmpty() && !key.isEmpty() && type != 0);
    }
    private void onNameFieldChanged() {
        nameLabel.setForeground(nameField.getText().trim().isEmpty() ? Color.RED : Color.BLACK);
        validateFields();
    }
    private void onKeyFieldChanged() {
        keyLabel.setForeground(keyField.getText().trim().isEmpty() ? Color.RED : Color.BLACK);
        validateFields();
    }
    private void onTypeComboChanged() {
        typeLabel.setForeground(typeCombo.getSelectedIndex() == 0 ? Color.RED : Color.BLACK);
        validateFields();
    }
    private void onCleanButton() {
        nameField.setText(null);
        keyField.setText(null);
        typeCombo.setSelectedIndex(0);
        validateFields();
    }
    private void onSaveButton() {
        String name = nameField.getText().trim();
        String key = keyField.getText().trim();
        String type = (String)typeCombo.getSelectedItem();
        model.add(name, key, type);
        if (model.getFile() == null) {
            JFileChooser fileChooser = new JFileChooser();
            int res = fileChooser.showSaveDialog(this);
            model.setFile(res == JFileChooser.APPROVE_OPTION ? fileChooser.getSelectedFile() : null);
        }
        try {
            model.save();
        } catch(Exception e) {
            JOptionPane.showMessageDialog(this, "Cannot save file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
        }
    }
    private void onOpenButton() {
        JFileChooser fileChooser = new JFileChooser();
        int res = fileChooser.showOpenDialog(null);
        model.setFile(res == JFileChooser.APPROVE_OPTION ? fileChooser.getSelectedFile() : null);
        try {
            model.read();
        } catch(Exception e) {
            JOptionPane.showMessageDialog(this, "Cannot read file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
        }
    }
    // ========== ActionListener ==========
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == typeCombo)
            onTypeComboChanged();
        else if (e.getSource() == clearButton)
            onCleanButton();
        else if (e.getSource() == saveButton)
            onSaveButton();
        else if (e.getSource() == openButton)
            onOpenButton();
    }
    // ========== DocumentListener ==========
    @Override
    public void insertUpdate(DocumentEvent e) {
        if (e.getDocument() == nameField.getDocument())
            onNameFieldChanged();
        else if (e.getDocument() == keyField.getDocument())
            onKeyFieldChanged();
    }
    @Override
    public void removeUpdate(DocumentEvent e) {
        if (e.getDocument() == nameField.getDocument())
            onNameFieldChanged();
        else if (e.getDocument() == keyField.getDocument())
            onKeyFieldChanged();
    }
    @Override
    public void changedUpdate(DocumentEvent e) {
    }
}

查看游戏选项卡面板:

final class ViewTabPanel extends JPanel implements ActionListener, PopupMenuListener {
    private final Model model;
    private final JTable table = new JTable();
    private final JPopupMenu popupMenu = new JPopupMenu();
    private final JMenuItem deleteItem = new JMenuItem("Delete");
    public ViewTabPanel(Model model) {
        this.model = model;
        init();
        addListeners();
    }
    private void init() {
        setLayout(new GridLayout(1, 1));
        add(new JScrollPane(table));
        popupMenu.add(deleteItem);
        table.setComponentPopupMenu(popupMenu);
        table.setAutoCreateRowSorter(true);
        table.setModel(model);
        table.updateUI();
    }
    private void addListeners() {
        popupMenu.addPopupMenuListener(this);
        deleteItem.addActionListener(this);
    }
    // ========== ActionListener ==========
    @Override
    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == deleteItem) {
            model.remove(table.getSelectedRow());
            try {
                model.save();
            } catch(Exception e) {
                JOptionPane.showMessageDialog(this, "Cannot save file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    // ========== PopupMenuListener ==========
    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent event) {
        if (event.getSource() == popupMenu) {
            SwingUtilities.invokeLater(() -> {
                int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
                if (rowAtPoint > -1)
                    table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
            });
        }
    }
    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent event) {
    }
    @Override
    public void popupMenuCanceled(PopupMenuEvent event) {
    }
}

最新更新