package app; import gui.ContinuousModelTab; import gui.DiscreteModelTab; import gui.RateIndicatorBFTab; import gui.TerminalTab; import gui.TimeSlicerTab; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.net.URL; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.BevelBorder; import utils.ExceptionHandler; public class SpreadApp { /** * Version string: assumed to be in format x.x.x */ private static final String VERSION = "1.0.7"; private static final String DATE_STRING = "2015"; // Dimension private Dimension dimension; // Icons public static ImageIcon quitIcon; public static ImageIcon helpIcon; public static ImageIcon clearIcon; public static ImageIcon nuclearIcon; public static ImageIcon treeIcon; public static ImageIcon processingIcon; public static ImageIcon saveIcon; public static ImageIcon errorIcon; public static ImageIcon locationsIcon; public static ImageIcon loadIcon; public static ImageIcon doneIcon; public static ImageIcon logIcon; public static ImageIcon timeSlicesIcon; public static ImageIcon treesIcon; // Frame private JFrame frame; private JTabbedPane tabbedPane; // Menubar private JToolBar mainMenu; // Buttons with options private JButton help; private JButton quit; private JButton clear; // Tabs private ContinuousModelTab continuousModelTab; private DiscreteModelTab discreteModelTab; private RateIndicatorBFTab rateIndicatorBFTab; private TimeSlicerTab timeSlicerTab; private TerminalTab terminalTab; // Status bar private JLabel statusbar; public SpreadApp() throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { boolean lafLoaded = false; // Setup Look & Feel if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) { // Mac stuff System.setProperty("apple.awt.showGrowBox", "true"); System.setProperty("apple.awt.brushMetalLook", "true"); System.setProperty("apple.laf.useScreenMenuBar", "true"); System.setProperty("apple.awt.graphics.UseQuartz", "true"); System.setProperty("apple.awt.antialiasing", "true"); System.setProperty("apple.awt.rendering", "VALUE_RENDER_QUALITY"); System.setProperty("apple.laf.useScreenMenuBar", "true"); System.setProperty("apple.awt.draggableWindowBackground", "true"); System.setProperty("apple.awt.showGrowBox", "true"); UIManager.put("SystemFont", new Font("Lucida Grande", Font.PLAIN, 13)); UIManager.put("SmallSystemFont", new Font("Lucida Grande", Font.PLAIN, 11)); try { // UIManager.setLookAndFeel(UIManager // .getSystemLookAndFeelClassName()); UIManager .setLookAndFeel("ch.randelshofer.quaqua.QuaquaLookAndFeel"); lafLoaded = true; } catch (Exception e) { // } } else { try { UIManager .setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); lafLoaded = true; } catch (Exception e) { // } } if (!lafLoaded) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); System.out.println("Specified l&f not found. Loading system default l&f"); } catch (Exception e) { e.printStackTrace(); } } dimension = Toolkit.getDefaultToolkit().getScreenSize(); Toolkit.getDefaultToolkit().setDynamicLayout(true); // Setup icons quitIcon = CreateImageIcon("/icons/close.png"); helpIcon = CreateImageIcon("/icons/help.png"); clearIcon = CreateImageIcon("/icons/clear.png"); nuclearIcon = CreateImageIcon("/icons/nuclear.png"); treeIcon = CreateImageIcon("/icons/tree.png"); processingIcon = CreateImageIcon("/icons/processing.png"); saveIcon = CreateImageIcon("/icons/save.png"); errorIcon = CreateImageIcon("/icons/error.png"); locationsIcon = CreateImageIcon("/icons/locations.png"); loadIcon = CreateImageIcon("/icons/locations.png"); doneIcon = CreateImageIcon("/icons/check.png"); logIcon = CreateImageIcon("/icons/log.png"); timeSlicesIcon = CreateImageIcon("/icons/timeSlices.png"); treesIcon = CreateImageIcon("/icons/trees.png"); // Setup Main Frame frame = new JFrame("SPREAD"); frame.getContentPane().setLayout(new BorderLayout()); frame.addWindowListener(new ListenCloseWdw()); frame.setIconImage(CreateImage("/icons/spread.png")); // Setup Main Menu buttons help = new JButton("Help", helpIcon); quit = new JButton("Quit", quitIcon); clear = new JButton("Clear Terminal", clearIcon); // Add Main Menu buttons listeners quit.addActionListener(new ListenMenuQuit()); help.addActionListener(new ListenMenuHelp()); clear.addActionListener(new ListenMenuClearTerminal()); // Setup Main Menu mainMenu = new JToolBar(); mainMenu.setFloatable(false); mainMenu.setLayout(new BorderLayout()); JPanel buttonsHolder = new JPanel(); buttonsHolder.setOpaque(false); buttonsHolder.add(clear); buttonsHolder.add(help); buttonsHolder.add(quit); mainMenu.add(buttonsHolder, BorderLayout.EAST); // Setup Tabbed Pane tabbedPane = new JTabbedPane(); // add Discrete Model Tab discreteModelTab = new DiscreteModelTab(this); tabbedPane.add("Discrete Tree", discreteModelTab); // add rateIndicatorBF Tab rateIndicatorBFTab = new RateIndicatorBFTab(this); tabbedPane.add("Discrete Bayes Factors", rateIndicatorBFTab); // add Continuous Model Tab continuousModelTab = new ContinuousModelTab(this); tabbedPane.add("Continuous Tree", continuousModelTab); // add Time Slicer tab timeSlicerTab = new TimeSlicerTab(this); tabbedPane.add("Time Slicer", timeSlicerTab); // add Terminal Tab terminalTab = new TerminalTab(); tabbedPane.add("Terminal", terminalTab); // Setup status bar JPanel statusPanel = new JPanel(); statusPanel.setBorder(new BevelBorder(BevelBorder.LOWERED)); statusPanel.setPreferredSize(new Dimension(frame.getWidth(), 16)); statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS)); statusbar = new JLabel("Welcome to Spread!"); statusbar.setHorizontalAlignment(SwingConstants.LEFT); statusPanel.add(statusbar); frame.getContentPane().add(mainMenu, BorderLayout.NORTH); frame.getContentPane().add(tabbedPane, BorderLayout.CENTER); frame.getContentPane().add(statusPanel, BorderLayout.SOUTH); // frame.getContentPane().add(Box.createVerticalStrut(15), // BorderLayout.SOUTH); frame.pack(); }// END: Constructor private class ListenMenuHelp implements ActionListener { public void actionPerformed(ActionEvent ev) { String helpText = "\n" + "\t SPREAD \n" + "Spatial Phylogenetic Reconstruction of Evolutionary Dynamics \n" + " \t Version " + VERSION + ", " + DATE_STRING + "\n" + "Filip Bielejec, Andrew Rambaut, Marc A. Suchard & Philippe Lemey \n" + "\n" + "SPREAD: www.phylogeography.org/SPREAD \n" + "BEAST software: http://beast.bio.ed.ac.uk/Main_Page \n" + "PROCESSING libraries: http://processing.org/ \n" + "\n" + "Citing SPREAD: \n" + "Bielejec F., Rambaut A., Suchard M.A & Lemey P. SPREAD: Spatial Phylogenetic Reconstruction of Evolutionary Dynamics. Bioinformatics, 2011. doi:10.1093 \n" // + "\n" + "BibTeX entry: \n" + "@article{Bielejec11092011, \n" + "\t author = {Bielejec, Filip and Rambaut, Andrew and Suchard, Marc A. and Lemey, Philippe}, \n" + "\t title = {SPREAD: Spatial phylogenetic reconstruction of evolutionary dynamics}, \n" + "\t year = {2011}, \n" + "\t volume = {27}, \n" + "\t pages = {2910-2912}, \n" + "\t doi = {10.1093/bioinformatics/btr481}, \n" + "\t URL = {http://bioinformatics.oxfordjournals.org/content/27/20/2910.abstract}, \n" + "\t eprint = {http://bioinformatics.oxfordjournals.org/content/27/20/2910.full.pdf+html}, \n" + "\t journal = {Bioinformatics} \n" + "} \n"; terminalTab.setText(helpText); tabbedPane.setSelectedIndex(4); } } private class ListenMenuClearTerminal implements ActionListener { public void actionPerformed(ActionEvent ev) { terminalTab.clearTerminal(); } } public class ListenMenuQuit implements ActionListener { public void actionPerformed(ActionEvent ev) { System.exit(0); } } public class ListenCloseWdw extends WindowAdapter { public void windowClosing(WindowEvent ev) { System.exit(0); } } public JFrame launchFrame() { // Display Frame frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(new Dimension(dimension.width - 100, dimension.height - 100)); frame.setMinimumSize(new Dimension(260, 100)); frame.setResizable(true); frame.setVisible(true); return frame; } public static SpreadApp gui; public static void main(String args[]) { Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler()); // Start application's GUI from Event Dispatching Thread SwingUtilities.invokeLater(new Runnable() { public void run() { try { gui = new SpreadApp(); gui.launchFrame(); } catch (UnsupportedClassVersionError e) { System.err.println("Your Java Runtime Environment is too old. Please update!"); e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (UnsupportedLookAndFeelException e) { e.printStackTrace(); } } }); }// END: main private ImageIcon CreateImageIcon(String path) { URL imgURL = this.getClass().getResource(path); if (imgURL != null) { return new ImageIcon(imgURL); } else { System.err.println("Couldn't find file: " + path + "\n"); return null; } }// END: CreateImageIcon private Image CreateImage(String path) { URL imgURL = this.getClass().getResource(path); Toolkit kit = Toolkit.getDefaultToolkit(); Image img = kit.createImage(imgURL); if (img != null) { return img; } else { System.err.println("Couldn't find file: " + path + "\n"); return null; } }// END: CreateImage public void setStatus(String status) { statusbar.setText(status); }// END: setStatus }// END: class