package gsingh.learnkirtan; import static gsingh.learnkirtan.Constants.VERSION; import static gsingh.learnkirtan.Constants.WHITE_KEY_HEIGHT; import static gsingh.learnkirtan.Constants.WHITE_KEY_WIDTH; import gsingh.learnkirtan.FileManager.SaveResult; import gsingh.learnkirtan.installer.SoundBankInstaller; import gsingh.learnkirtan.keys.KeyMapper; import gsingh.learnkirtan.keys.LabelManager; import gsingh.learnkirtan.listener.SettingsChangedListener; import gsingh.learnkirtan.note.NoteList; import gsingh.learnkirtan.player.ShabadPlayer; import gsingh.learnkirtan.settings.SettingsManager; import gsingh.learnkirtan.shabad.Shabad; import gsingh.learnkirtan.ui.ControlPanel; import gsingh.learnkirtan.ui.PianoPanel; import gsingh.learnkirtan.ui.WindowTitleManager; import gsingh.learnkirtan.ui.action.ActionFactory; import gsingh.learnkirtan.ui.menu.EditMenu; import gsingh.learnkirtan.ui.menu.FileMenu; import gsingh.learnkirtan.ui.menu.HelpMenu; import gsingh.learnkirtan.ui.menu.OptionsMenu; import gsingh.learnkirtan.ui.menu.controller.HelpMenuController; import gsingh.learnkirtan.ui.menu.controller.OptionsMenuController; import gsingh.learnkirtan.ui.shabadeditor.SwingShabadEditor; import gsingh.learnkirtan.ui.shabadeditor.tableeditor.TableShabadEditor; import gsingh.learnkirtan.utility.DialogUtility; import gsingh.learnkirtan.utility.NetworkUtility; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.SplashScreen; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenuBar; import javax.swing.JPanel; import javax.swing.SwingUtilities; /** * The main entry point for the program. Responsible for initializing the GUI, * installing the soundbank if necessary, and checking for updates * * @author Gulshan * */ public class Main { /** The base title of the software. Includes the name and version number */ public static final String BASETITLE = "Learn Kirtan v" + VERSION + " Beta - "; /** The width of the screen */ private final int WIDTH = 20 * WHITE_KEY_WIDTH; /** * The main shabad editor. When play is pressed, the text in here will be * played. It cannot be edited while playing. */ public SwingShabadEditor shabadEditor; /** The main frame */ private JFrame frame; /** Manages changes in the title of the window */ private WindowTitleManager titleManager; /** Handles the opening and saving of files */ private FileManager fileManager = new FileManager(); /** Manages the setting and getting of settings */ private SettingsManager settingsManager = SettingsManager.getInstance(); /** A list of all of the notes */ private NoteList notes; /** Manages the labelling of the keys */ private LabelManager labelManager; // Only Main can instantiate itself private Main() { } public static void main(String[] args) { new Main().init(); } /** * Constructs the GUI, installs the sound bank, and checks for updates */ public void init() { SplashScreen.getSplashScreen(); // TODO // if (System.getProperty("os.name").startsWith("Windows")) { // try { // // UIManager.setLookAndFeel(UIManager // // .getSystemLookAndFeelClassName()); // } catch (UnsupportedLookAndFeelException e) { // } catch (ClassNotFoundException e) { // } catch (InstantiationException e) { // } catch (IllegalAccessException e) { // } // } // SettingsManager persists settings so it needs access to a FileManager // However it is a singleton, so this must be set through a method settingsManager.setFileManager(fileManager); // The NoteList is initialized with the key representing middle Sa notes = new NoteList(settingsManager.getSaKey()); labelManager = new LabelManager(notes); KeyMapper.getInstance().setNotes(notes); SwingUtilities.invokeLater(new Runnable() { public void run() { // Initialize GUI createAndShowGui(); // Install soundbank if necessary SoundBankInstaller installer = new SoundBankInstaller(); installer.installSoundBank(); // Check for update new Thread(new Runnable() { @Override public void run() { NetworkUtility.checkForUpdate(); } }).start(); } }); } /** * Constructs the menu, control panel, piano panel, and shabad editor */ public void createAndShowGui() { frame = new JFrame(BASETITLE + "Untitled Shabad"); // frame.addComponentListener(new ComponentAdapter() { // @Override // public void componentResized(ComponentEvent e) { // frame.setSize(new Dimension(frame.getPreferredSize().width, // frame.getHeight())); // super.componentResized(e); // } // }); titleManager = new WindowTitleManager(frame); DialogUtility.setFrame(frame); // TODO: Shouldn't need to pass these two managers shabadEditor = new TableShabadEditor(titleManager, fileManager); frame.setJMenuBar(createMenuBar()); JPanel controlPanel = new ControlPanel(new ShabadPlayer(), shabadEditor); JComponent pianoPanel = new PianoPanel(labelManager); settingsManager .addSettingsChangedListener((SettingsChangedListener) pianoPanel); fileManager.addFileEventListener((ControlPanel) controlPanel); fileManager.addFileEventListener(titleManager); JPanel mainPanel = initMainPanel(controlPanel, pianoPanel, shabadEditor); frame.add(mainPanel); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new MyWindowAdapter()); frame.pack(); frame.setLocation(250, 60); frame.setResizable(false); frame.setVisible(true); shabadEditor.reset(); } /** * Constructs the mainPanel by taking the {@code controlPanel}, * {@code pianoPanel}, and {@code editor} and arranging them using a * {@link GridBagLayout}. * */ private JPanel initMainPanel(JPanel controlPanel, JComponent pianoPanel, SwingShabadEditor editor) { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS)); mainPanel.add(controlPanel); pianoPanel.setPreferredSize(new Dimension(WIDTH, WHITE_KEY_HEIGHT)); mainPanel.add(pianoPanel); editor.setPreferredSize(new Dimension(editor.getWidth(), 250)); mainPanel.add(editor); return mainPanel; } private JMenuBar createMenuBar() { JMenuBar menuBar = new JMenuBar(); menuBar.add(new FileMenu(new ActionFactory(shabadEditor, fileManager))); menuBar.add(new EditMenu(shabadEditor.getUndoAction(), shabadEditor .getRedoAction(), shabadEditor.getCutAction(), shabadEditor .getCopyAction(), shabadEditor.getPasteAction())); // TODO Add the keyboard mode menu back in // menuBar.add(new KeyboardMenu(new // KeyboardMenuController(shabadEditor))); menuBar.add(new OptionsMenu(new OptionsMenuController(notes, labelManager))); menuBar.add(new HelpMenu(new HelpMenuController())); return menuBar; } private class MyWindowAdapter extends WindowAdapter { /** * Prompts the user if they would like to save and saves if accepted * * @return a {@code SaveResult} describing the action taken * @throws IOException */ private SaveResult safeSave(Shabad shabad) throws IOException { int result = DialogUtility.showSaveDialog(); if (DialogUtility.isCancelledOrClosed(result)) return SaveResult.NOT_SAVED_CANCELLED; if (DialogUtility.isYes(result)) { if (shabadEditor.isValidShabad()) { return fileManager.saveShabad(shabad); } else { return SaveResult.NOT_SAVED_INVALID_SHABAD; } } return SaveResult.NOT_SAVED; } public void windowClosing(WindowEvent ev) { try { SaveResult result = null; if (shabadEditor.isModified()) { result = safeSave(shabadEditor.getShabad()); } if (result != SaveResult.NOT_SAVED_INVALID_SHABAD) { if (result != SaveResult.NOT_SAVED_CANCELLED) { System.exit(0); } } else { DialogUtility.showInvalidShabadDialog(); } } catch (IOException e) { e.printStackTrace(); } } } }