/* * FileEditorDialog.java * * Created on January 27, 2007, 6:16 PM */ package editor; import eug.specific.eu3.EU3DataSource; import java.util.HashMap; import javax.swing.JOptionPane; /** * Dialog to edit province or country history files with syntax highlighting. * <p> * All interaction with this class is handled through the static methods * {@link #showDialog(Frame, ProvinceData.Province)} and * {@link #showDialog(Frame, String, String)}. * @author Michael Myers */ public class FileEditorDialog extends EditorDialog { /** * The province id number or the hashcode of the country tag. Used to * prevent two dialogs from editing the same file, which could cause * problems. */ private int id; /** * The country tag, if a country is being edited; otherwise <code>null</code>. */ private String tag = null; /** * The name of the province or country. */ private String name; /** * Creates new form FileEditorDialog. * * @param parent the <code>Frame</code> that this dialog is a child of. * @param p the <code>Province</code> that this dialog will display * the history file for. */ private FileEditorDialog(final java.awt.Frame parent, final ProvinceData.Province p) { super(parent, p.getName()); this.id = p.getId(); this.name = p.getName(); readFile(p.getId(), p.getName()); register(this); // Register last in case exceptions occur } private FileEditorDialog(final java.awt.Frame parent, String countryTag, String countryName) { super(parent, countryName); this.id = countryTag.hashCode(); this.tag = countryTag; this.name = countryName; readFile(countryTag, countryName); register(this); // Register last in case exceptions occur } /** * Reads in the province history file. * @param pid the province's ID number. * @param pname the province's name. */ private void readFile(int pid, String pname) { final String data = dataSource.getProvinceAsStr(pid); if (data == null) { setOriginalContents("# No previous file for " + pname + "\n"); } else { setOriginalContents(data); } } /** * Reads in the country history file. * @param tag the country's tag. * @param cname the country's name. */ private void readFile(String tag, String cname) { final String data = dataSource.getCountryAsStr(tag); if (data == null) { setOriginalContents("# No previous file for " + cname + "\n"); } else { setOriginalContents(data); } } @Override protected void close() { if (textHasChanged()) { int check = JOptionPane.showConfirmDialog(this, "File has changed. Save changes?", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION); if (check == JOptionPane.YES_OPTION) save(); else if (check == JOptionPane.CANCEL_OPTION) return; // else continue on to disposing } unRegister(this); super.close(); } private static final int MIN_TAG_HASH = "AAA".hashCode(); private void save() { if (id < MIN_TAG_HASH) { // Province dataSource.saveProvince(id, name, getText()); dataSource.reloadProvince(id); } else { dataSource.saveCountry(tag, name, getText()); dataSource.reloadCountry(tag); } } // For some reason, overriding hashCode() consistently generates three // stack traces when closing the dialog. I have yet to figure out why, but // at least I finally figured out what was causing it.... // /** Compares id numbers for equality. */ // @Override // public boolean equals(Object obj) { // return (obj instanceof FileEditorDialog) && // ((FileEditorDialog) obj).id == id; // } // // @Override // public int hashCode() { // return id; // } // ------------------------------------------------------------------- // Static Members // ------------------------------------------------------------------- private static final java.util.Map<Integer, FileEditorDialog> showing = new HashMap<Integer, FileEditorDialog>(); private static void register(FileEditorDialog d) { showing.put(d.id, d); } private static void unRegister(FileEditorDialog d) { showing.remove(d.id); } private static EU3DataSource dataSource = null; public static void setDataSource(EU3DataSource newSource) { dataSource = newSource; } /** * Shows a province history dialog for the given province. * @param parent the <code>Frame</code> that the dialog will be a child of. * @param p the <code>Province</code> that the dialog will show the * history file for. */ public static void showDialog(java.awt.Frame parent, ProvinceData.Province p) { final FileEditorDialog d = showing.get(p.getId()); if (d == null) { // No previous one, so create new. try { new FileEditorDialog(parent, p).setVisible(true); } catch (RuntimeException ex) { JOptionPane.showMessageDialog(null, "Error with province " + p + ": " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); ex.printStackTrace(); } } else { d.setVisible(true); } } /** * Shows a country history dialog for the given country. * @param parent the <code>Frame</code> that the dialog will be a * child of. * @param countryTag the country's tag. * @param countryName the country's name. Used in the dialog's title, and * if no previous country history file existed. */ public static void showDialog(java.awt.Frame parent, String countryTag, String countryName) { final FileEditorDialog d = showing.get(countryTag.hashCode()); if (d == null) { // No previous one, so create new. try { new FileEditorDialog(parent, countryTag, countryName).setVisible(true); } catch (RuntimeException ex) { JOptionPane.showMessageDialog(null, "Error with country " + countryTag + ": " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); ex.printStackTrace(); } } else { d.setVisible(true); } } /** * Closes all showing dialogs naturally (the user gets a chance to save). */ public static void disposeAll() { // Clone the list to avoid ConcurrentModificationException final java.util.Map<Integer, FileEditorDialog> showingClone = (java.util.Map<Integer, FileEditorDialog>) ((HashMap<Integer, FileEditorDialog>)showing).clone(); for (FileEditorDialog d : showingClone.values()) { System.out.println("Still showing: " + d.name); d.close(); if (d.isShowing()) d.dispose(); } } }