//This file is part of SECONDO. //Copyright (C) 2004, University in Hagen, Department of Computer Science, //Database Systems for New Applications. //SECONDO is free software; you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation; either version 2 of the License, or //(at your option) any later version. //SECONDO is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. //You should have received a copy of the GNU General Public License //along with SECONDO; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package viewer.chess; import java.io.*; import javax.swing.*; import java.util.*; import java.awt.*; /** *This class provides functionality for exporting chess games to pgn files. */ public class ChessFileExporter { /** * constant for the maximum characters per line */ public static final int MAX_LINE_LENGTH = 80; /** * the Game Deliverer to get a vector of the current games from */ private GameDeliverer gameDeliverer; /** * file chooser to choose the file to write the chessgames to */ private JFileChooser chooser; /** * parent component to place the dialogues on */ private JComponent parent; /** * boolean value whether a new file was created. Needed to clean up if a new file was created and the writing process is aborted in any way */ private boolean createdNewFile = false; /** *list to choose the chessgames that will be written to the pgn-file from */ private JList gameChooser; /** * box which contains everything to show the "select the chessgames you want to export"-dialogue */ private Box gameChooserView; /** * the currently shown game. */ private GameData currentGame; /** *constructor which needs a GameDeliverer to get the games which will be exported. Furthermore this needs a JComponent to locate the *Dialogues on. */ public ChessFileExporter(GameDeliverer gameDeliverer, JComponent parent) { this.gameDeliverer = gameDeliverer; this.parent = parent; chooser = new JFileChooser(); chooser.setMultiSelectionEnabled(false); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY ); gameChooser = new JList(); gameChooser.setFixedCellWidth(300); gameChooser.setVisibleRowCount(5); gameChooser.setFixedCellHeight(24); JScrollPane scroll = new JScrollPane(gameChooser); gameChooserView = new Box(BoxLayout.Y_AXIS); JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0)); JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0)); JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0)); JLabel lbl = new JLabel("Please select which chessgames you want to export."); JLabel lbl2=new JLabel("Note: Duplicated chessgames will be saved only once."); p1.add(lbl); p2.add(scroll); p3.add(lbl2); gameChooserView.add(p1); gameChooserView.add(p2); gameChooserView.add(p3); } /** * method to show an error. The String is the displayed error message */ private void showError(String errorMessage) { JOptionPane.showMessageDialog(parent,errorMessage,"error",JOptionPane.WARNING_MESSAGE ); } /** * lets the user choose a file, adds the ending ".pgn" to the filename, if neccessary and creates a new file if neccessary */ private File fileCreation() throws IOException, Exception { File file = chooser.getSelectedFile(); //file choosing if (!file.getName().toLowerCase().endsWith(".pgn")) //test if already has the right file extension { String path = file.getParent(); String name = file.getName(); if(path == null) file = new File(File.separatorChar+name+".pgn"); else file = new File(path+File.separatorChar+name+".pgn"); } createdNewFile = false; createdNewFile = file.createNewFile(); //create new file if neccessary int selection = JOptionPane.YES_OPTION; if(!createdNewFile) // question if existing file should be overwritten { selection = JOptionPane.showConfirmDialog(parent,"A file called "+file.getName()+" already exists in the current Directory, do you want to overwrite?","File already exists",JOptionPane.YES_NO_OPTION); } if(selection != JOptionPane.YES_OPTION) throw new Exception(); return file; } /** * method to show a number of dialogues to export a chessgame. 'current' is the currently shown chessgame in the view */ public void showSaveDialog(GameData current) { this.currentGame = current; if(chooser.showSaveDialog(parent)==JFileChooser.APPROVE_OPTION) // if the user decided which file the games will be written to { File file = null; try { file = fileCreation(); // file is created try { saveChessGames(file); // chessgames are written to the file if possible } catch (Exception e) { if(createdNewFile) { try { file.delete(); } catch (Exception e2) { } } } } catch(IOException ioe) // if an io Exception occurs the file cannot be written. { showError("Error: Cannot write file !"); } catch (Exception ex) { showSaveDialog(currentGame); } } } /** method to show a dialogue in which the user can select the chessgames which should be exported. Returns an array of objects which contains these chessgames */ private Object[] selectChessGames(Vector v) throws Exception { Object[] selectedGames; gameChooser.setListData(v); int selection = JOptionPane.showConfirmDialog(parent,gameChooserView, "Please select chessgames", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if(selection == JOptionPane.CANCEL_OPTION) { throw new Exception(); } selectedGames = gameChooser.getSelectedValues(); if (selectedGames.length == 0) { showError("No selection was made, file saving abborted."); throw new Exception(); } return selectedGames; } /** * writes the chessgames to the file. Gets the games whih should be written and the PrintWriter which writes the files */ private void writeGames(Object[] selectedGames, PrintWriter p) throws Exception { ArrayList alreadyWritten = new ArrayList(); for(int i = 0;i 1) { selectedGames = selectChessGames(v); // gets the games that will be selected } FileWriter fileWriter = null; PrintWriter p = null; try { fileWriter = new FileWriter(f, false); //creation of writers /opening file and writing the file p = new PrintWriter(fileWriter); writeGames(selectedGames,p); } catch (Exception exc) { showError("Error: Could not write file."); // if problems occur while writing throw new Exception(); } finally { try { fileWriter.close(); // closing of the writers if possible p.close(); } catch(Exception e){} } } /** * writes a tag pair to the file with the PrintWriter p. Key is the key of the tag pair and value the value. */ private void writeTag(PrintWriter p, String key, String value) throws Exception { if(!value.equals("")) { StringBuffer out = new StringBuffer(); out.append('['); out.append(key); out.append(' '); out.append('"'); out.append(value); out.append('"'); out.append(']'); p.println(out.toString()); } } /** * writes all the tags of the chessgame g with the PrintWriter p to the file. This method manages writing at least the most common tags of a chessgames to the pgn file */ private void writeAllTags(PrintWriter p, GameData g) throws Exception { writeTag(p, ChessToolKit.EVENT_KEY, g.getEvent()); writeTag(p, ChessToolKit.SITE_KEY, g.getSite()); writeTag(p, ChessToolKit.DATE_KEY, g.getDate()); writeTag(p, ChessToolKit.ROUND_KEY, g.getRound()); writeTag(p, ChessToolKit.WHITE_KEY, g.getWhite()); writeTag(p, ChessToolKit.BLACK_KEY, g.getBlack()); writeTag(p, ChessToolKit.RESULT_KEY, g.getResult()); HashMap tags = g.getTags(); if(tags != null) { Object[] keys = g.getKeys(); for(int i=0;i=ChessFileExporter.MAX_LINE_LENGTH) { p.println(out.toString()); out.delete(0,out.length()); lineLength = 0; } out.append(moveNumber); out.append('.'); out.append(' '); moveNumber++; lineLength = lineLength+2+((""+moveNumber).length()); } if((lineLength + pgn.length()+1) >=ChessFileExporter.MAX_LINE_LENGTH) { p.println(out.toString()); out.delete(0,out.length()); lineLength = 0; } out.append(pgn); out.append(' '); lineLength = lineLength+pgn.length()+1; movePos++; } if(lineLength+g.getResult().length()+1 >=80) // writing game result { p.println(out.toString()); out.delete(0,out.length()); } out.append(g.getResult()); p.println(out.toString()); } /** * method which manages writing the chessgame g with the PrintWriter p to the file. **/ private void writePGNtoFile(PrintWriter p, GameData g) throws Exception { writeAllTags(p, g); p.println(); writeAllMoves(p,g); p.println(); } }