/*
* EuroCarbDB, a framework for carbohydrate bioinformatics
*
* Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
* A copy of this license accompanies this distribution in the file LICENSE.txt.
*
* This program 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 Lesser General Public License
* for more details.
*
* Last commit: $Rev: 1930 $ by $Author: david@nixbioinf.org $ on $Date:: 2010-07-29 #$
*/
package org.eurocarbdb.application.glycanbuilder;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.print.*;
import java.util.*;
import java.text.*;
import java.net.*;
/**
Main application class. Implement a frame in which a {@link
GlycanCanvas} is inserted. Provides menus and toolbars for creating
and editing a set of glycan structures, and export the results to
files in various formats.
@author Alessio Ceroni (a.ceroni@imperial.ac.uk)
*/
public class GlycanBuilder extends JFrame implements ActionListener, BaseDocument.DocumentChangeListener, FileHistory.Listener, MouseListener {
private static final long serialVersionUID = 0L;
// singletons
protected BuilderWorkspace theWorkspace;
protected GlycanDocument theDoc;
protected ActionManager theActionManager;
// graphical objects
protected JMenuBar theMenuBar;
protected JToolBar theToolBarFile;
protected JPanel theToolBarPanel;
protected GlycanCanvas theCanvas;
// menus
protected JMenu recent_files_menu;
protected String last_exported_file = null;
private Monitor halt_interactions = null;
protected Set<ContextAwareContainer> contextAwareListeners;
// -------------------
/**
Initialize the application, the documents and the graphic
components.
* @throws MalformedURLException
*/
public GlycanBuilder() throws MalformedURLException {
LogUtils.setReportOwner(this);
LogUtils.setGraphicalReport(true);
// create the default workspace
theWorkspace = new BuilderWorkspace(FileUtils.getRootDir() + "/config.xml",true);
theWorkspace.setAutoSave(true);
// create singletons
theDoc = theWorkspace.getStructures();
theActionManager = new ActionManager();
halt_interactions = new Monitor(this);
// initialize the action set
createActions();
// set the layout
getContentPane().setLayout(new BorderLayout());
// create canvas
theCanvas = new GlycanCanvas(this,theWorkspace,new ThemeManager("", this.getClass()));
// set the toolbars
UIManager.getDefaults().put("ToolTip.hideAccelerator",Boolean.TRUE);
theToolBarPanel = new JPanel(new BorderLayout());
theToolBarFile = createToolBarFile();
JPanel northTbPanel = new JPanel();
northTbPanel.setLayout(new BoxLayout(northTbPanel,BoxLayout.X_AXIS));
northTbPanel.add(theToolBarFile);
northTbPanel.add(theCanvas.getToolBarDocument());
theToolBarPanel.add(northTbPanel, BorderLayout.NORTH);
theToolBarPanel.add(theCanvas.getToolBarStructure(), BorderLayout.CENTER);
theToolBarPanel.add(theCanvas.getToolBarProperties(), BorderLayout.SOUTH);
getContentPane().add(theToolBarPanel,BorderLayout.NORTH);
// set the MenuBar
theMenuBar = createMenuBar();
setJMenuBar(theMenuBar);
// set the canvas
JScrollPane sp = new JScrollPane(theCanvas);
theCanvas.setScrollPane(sp);
getContentPane().add(sp,BorderLayout.CENTER);
// add listeners
theDoc.addDocumentChangeListener(this);
theCanvas.addMouseListener( this );
theWorkspace.addDocumentChangeListener(this);
theWorkspace.getFileHistory().addHistoryChangedListener(this);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
onExit();
}
});
// setto la dimensione e la posizione della finestra
setIconImage(FileUtils.themeManager.getImageIcon("logo").getImage());
setSize(800, 600);
setLocationRelativeTo(null);
// initialize document
onNew(theDoc);
theWorkspace.setChanged(false);
updateActions();
}
/**
Exit the application immediately with a specified error
level. Save the configuration to file
*/
public void exit(int err_level) {
// save configurations
theWorkspace.exit(FileUtils.getRootDir() + "/config.xml");
// clear memory
theWorkspace.init();
System.gc();
System.runFinalization();
// exit
System.exit(err_level);
}
/**
Return the workspace object containing all documents and
options
*/
public BuilderWorkspace getWorkspace() {
return theWorkspace;
}
/**
Return the component used to create and edit the structures
*/
public GlycanCanvas getCanvas() {
return theCanvas;
}
/**
Halt the user interaction and display a hourglass cursor
*/
public void haltInteractions() {
// display the wait cursor and block user input
if( halt_interactions.isFree() ) {
Component glassPane = getGlassPane();
glassPane.addMouseListener( new MouseAdapter() { } );
glassPane.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) );
glassPane.setVisible( true );
}
halt_interactions.hold();
}
/**
Restore the user interactions
*/
public void restoreInteractions() {
// restore normal user interaction
halt_interactions.release();
if( halt_interactions.isFree() )
getGlassPane().setVisible(false);
}
private void createActions() {
// file
theActionManager.add("empty",ThemeManager.getResizableEmptyIcon(ICON_SIZE.L3),"Empty",-1,"",this);
for(CoreType t : CoreDictionary.getCores() )
theActionManager.add("new=" + t.getName(),ThemeManager.getResizableEmptyIcon(ICON_SIZE.L3),t.getDescription(),-1,"",this);
theActionManager.add("new",FileUtils.themeManager.getImageIcon("new"),"New",KeyEvent.VK_N, "ctrl N",this);
theActionManager.add("open",FileUtils.themeManager.getImageIcon("open"),"Open document...",KeyEvent.VK_O, "ctrl O",this);
theActionManager.add("openinto",FileUtils.themeManager.getImageIcon("openinto"),"Open additional document...",KeyEvent.VK_I, "ctrl I",this);
theActionManager.add("save",FileUtils.themeManager.getImageIcon("save"),"Save",KeyEvent.VK_S, "ctrl S",this);
theActionManager.add("saveas",FileUtils.themeManager.getImageIcon("saveas"),"Save as...",KeyEvent.VK_A, "shift ctrl S",this);
theActionManager.add("print",FileUtils.themeManager.getImageIcon("print"),"Print...",KeyEvent.VK_P, "ctrl P",this);
theActionManager.add("quit",FileUtils.themeManager.getImageIcon("quit"),"Quit",KeyEvent.VK_Q, "ctrl Q",this);
// import/export
for(java.util.Map.Entry<String,String> e : GlycanDocument.getImportFormats().entrySet() )
theActionManager.add("import=" + e.getKey(),ThemeManager.getEmptyIcon(null),"Import from " + e.getValue() + "...",-1, "",this);
for(java.util.Map.Entry<String,String> e : GlycanDocument.getExportFormats().entrySet() )
theActionManager.add("export=" + e.getKey(),ThemeManager.getEmptyIcon(null),"Export to " + e.getValue() + "...",-1, "",this);
for(java.util.Map.Entry<String,String> e : SVGUtils.getExportFormats().entrySet() )
theActionManager.add("export=" + e.getKey(),ThemeManager.getEmptyIcon(null),"Export to " + e.getValue() + "...",-1, "",this);
// help
theActionManager.add("about",FileUtils.themeManager.getImageIcon("about"),"About",KeyEvent.VK_B,"",this);
}
private void updateActions() {
theActionManager.get("save").setEnabled(theDoc.hasChanged());
}
private void updateRecentFileMenu() {
// update recent files menu
recent_files_menu.removeAll();
FileHistory theFileHistory = theWorkspace.getFileHistory();
for( Iterator<String> i = theFileHistory.iterator(); i.hasNext(); ) {
String file_path = i.next();
String file_type = theFileHistory.getFileType(file_path);
JMenuItem mi = new JMenuItem(theFileHistory.getAbbreviatedName(file_path));
if( file_type.equals("Workspace") )
mi.setActionCommand("openall=" + file_path);
else if( file_type.equals("Structures") )
mi.setActionCommand("openstruct=" + file_path);
mi.addActionListener(this);
mi.setToolTipText(file_path);
recent_files_menu.add(mi);
}
if( recent_files_menu.getItemCount()==0 )
recent_files_menu.add(new JMenuItem("<empty>"));
}
private JMenu createNewDocumentMenu() {
JMenu new_menu = new JMenu("New");
new_menu.setMnemonic(KeyEvent.VK_N);
new_menu.setIcon(FileUtils.themeManager.getImageIcon("new"));
new_menu.add(theActionManager.get("empty"));
for( String superclass : CoreDictionary.getSuperclasses() ) {
JMenu class_menu = new JMenu(superclass);
for( CoreType core_type : CoreDictionary.getCores(superclass) )
class_menu.add(theActionManager.get("new=" + core_type.getName()));
if( class_menu.getItemCount()>0 )
new_menu.add(class_menu);
}
return new_menu;
}
private JMenu createImportSequenceMenu() {
JMenu import_menu = new JMenu("Import from sequence formats");
import_menu.setMnemonic(KeyEvent.VK_M);
import_menu.setIcon(FileUtils.themeManager.getImageIcon("import"));
for(java.util.Map.Entry<String,String> e : GlycanDocument.getImportFormats().entrySet() )
import_menu.add(theActionManager.get("import="+e.getKey()));
return import_menu;
}
private JMenu createExportSequenceMenu() {
JMenu export_menu = new JMenu("Export to sequence formats");
export_menu.setMnemonic(KeyEvent.VK_X);
export_menu.setIcon(FileUtils.themeManager.getImageIcon("export"));
for(java.util.Map.Entry<String,String> e : GlycanDocument.getExportFormats().entrySet() )
export_menu.add(theActionManager.get("export="+e.getKey()));
return export_menu;
}
private JMenu createExportDrawingMenu() {
JMenu export_menu = new JMenu("Export to graphical formats");
export_menu.setMnemonic(KeyEvent.VK_G);
export_menu.setIcon(FileUtils.themeManager.getImageIcon("export"));
for(java.util.Map.Entry<String,String> e : SVGUtils.getExportFormats().entrySet() )
export_menu.add(theActionManager.get("export="+e.getKey()));
return export_menu;
}
private JMenu createFileMenu() {
recent_files_menu = new JMenu("Recent files");
recent_files_menu.setMnemonic(KeyEvent.VK_R);
recent_files_menu.setIcon(ThemeManager.getEmptyIcon(null));
updateRecentFileMenu();
JMenu file_menu = new JMenu("File");
file_menu.setMnemonic(KeyEvent.VK_F);
file_menu.add(createNewDocumentMenu());
file_menu.add(theActionManager.get("open"));
file_menu.add(theActionManager.get("openinto"));
file_menu.add(recent_files_menu);
file_menu.addSeparator();
file_menu.add(theActionManager.get("save"));
file_menu.add(theActionManager.get("saveas"));
file_menu.addSeparator();
file_menu.add(createImportSequenceMenu());
file_menu.add(createExportSequenceMenu());
file_menu.add(createExportDrawingMenu());
file_menu.addSeparator();
file_menu.add(theActionManager.get("print"));
file_menu.addSeparator();
file_menu.add(theActionManager.get("quit"));
return file_menu;
}
private JMenuBar createMenuBar() {
JMenuBar menubar = new JMenuBar();
menubar.add(createFileMenu());
menubar.add(theCanvas.getEditMenu());
menubar.add(theCanvas.getStructureMenu());
menubar.add(theCanvas.getViewMenu());
// help menu
JMenu help_menu = new JMenu("Help");
help_menu.setMnemonic(KeyEvent.VK_H);
help_menu.add(theActionManager.get("about"));
menubar.add(help_menu);
return menubar;
}
private JPopupMenu createPopupMenu() {
return theCanvas.createPopupMenu();
}
private JToolBar createToolBarFile() {
JToolBar toolbar = new JToolBar();
toolbar.setFloatable(false);
toolbar.add(theActionManager.get("new"));
toolbar.add(theActionManager.get("open"));
toolbar.add(theActionManager.get("openinto"));
toolbar.add(theActionManager.get("save"));
toolbar.add(theActionManager.get("saveas"));
toolbar.addSeparator();
toolbar.add(theActionManager.get("print"));
return toolbar;
}
private String askName(String what) {
return JOptionPane.showInputDialog(this,"Insert " + what + " name:", "", JOptionPane.QUESTION_MESSAGE);
}
//----------------------------
// Document handling actions
private void updateTitle() {
String title = FileHistory.getAbbreviatedName(theDoc.getFileName()) + " - GlycanBuilder";
if( theDoc.hasChanged() )
title = "* " + title;
setTitle(title);
}
private File getLastExportedFile() {
if( last_exported_file!=null && last_exported_file.length()>0 ) {
return new File(last_exported_file);
}
return null;
}
private void setLastExportedFile(String name) {
last_exported_file = name;
}
private boolean checkDocumentChanges(BaseDocument doc) {
if( doc.hasChanged() && !doc.isEmpty() ) {
int ret = JOptionPane.showConfirmDialog(this,"Save changes to " + doc.getName().toLowerCase() + "?", null, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if( ret == JOptionPane.CANCEL_OPTION )
return false;
if( ret == JOptionPane.YES_OPTION ) {
if( !onSaveAs(doc) )
return false;
return true;
}
if( ret == JOptionPane.NO_OPTION )
return true;
return false;
}
return true;
}
private boolean checkExisting(String filename) {
if( !(new File(filename)).exists() ) {
JOptionPane.showMessageDialog(this,"The file selected is not existing.", "File not found", JOptionPane.ERROR_MESSAGE);
theWorkspace.getFileHistory().remove(filename);
return false;
}
return true;
}
/**
Initialize the selected document
@return <code>true</code> if the operation was successful
*/
public boolean onNew(BaseDocument doc) {
if( doc==null )
return false;
if( !checkDocumentChanges(doc) )
return false;
// init document
doc.init();
return true;
}
/**
Initialize the structure document with a core motif
@param name the identifier of the core motif
@see CoreDictionary
@return <code>true</code> if the operation was successful
*/
public boolean onNew(String name) {
try {
if( !checkDocumentChanges(theDoc) )
return false;
// add structure from template
if( name!=null && name.length()>0 )
return theDoc.init(CoreDictionary.getCoreType(name).getStructure());
theDoc.init();
return true;
}
catch(Exception e) {
LogUtils.report(e);
return false;
}
}
/*
public boolean tryOpen(String filename, boolean merge) {
try {
if( !checkExisting(filename) )
return false;
// try to open one document
if( theWorkspace.open(filename,merge,false) ) {
theWorkspace.getFileHistory().add(filename,theWorkspace.getName());
return true;
}
if( theWorkspace.getStructures().open(filename,merge,false) ) {
theWorkspace.getFileHistory().add(filename,theWorkspace.getStructures().getName());
return true;
}
throw new Exception("Unrecognized file format");
}
catch(Exception e) {
LogUtils.report(e);
return false;
}
}
*/
private boolean onOpenDocument(Collection<BaseDocument> documents, boolean merge) {
if( documents==null || documents.size()==0 )
return false;
// collect file formats
JFileChooser fileChooser = new JFileChooser();
fileChooser.setAcceptAllFileFilterUsed(false);
HashMap<javax.swing.filechooser.FileFilter,BaseDocument> all_ff = new HashMap<javax.swing.filechooser.FileFilter,BaseDocument>();
for( BaseDocument doc : documents) {
javax.swing.filechooser.FileFilter ff = doc.getAllFileFormats();
fileChooser.addChoosableFileFilter(ff);
all_ff.put(ff,doc);
}
// open file chooser
fileChooser.setCurrentDirectory(theWorkspace.getFileHistory().getRecentFolder());
if( fileChooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION )
return false;
// retrieve file path and document type
String filename = fileChooser.getSelectedFile().getAbsolutePath();
BaseDocument document = all_ff.get(fileChooser.getFileFilter());
// open the file
return onOpen(filename,document,merge);
}
private boolean onOpen(String filename, BaseDocument doc, boolean merge) {
if( doc==null )
return false;
if( filename==null ) {
if( doc.getFileFormats().size()==0 )
return false;
// imposto la dialog per l'apertura del file
JFileChooser fileChooser = new JFileChooser();
for( javax.swing.filechooser.FileFilter ff : doc.getFileFormats() )
fileChooser.addChoosableFileFilter(ff);
fileChooser.setCurrentDirectory(theWorkspace.getFileHistory().getRecentFolder());
// visualizzo la dialog
if( fileChooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION )
return false;
// retrieve file path
filename = fileChooser.getSelectedFile().getAbsolutePath();
}
if( !checkExisting(filename) )
return false;
if( filename.equals(doc.getFileName()) ) {
// ask for reload if document has changed
if( !doc.hasChanged() )
return false;
int retValue = JOptionPane.showOptionDialog(this, "Reload document from the file: " + filename + "?", "Load document", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
if( retValue!=JOptionPane.YES_OPTION )
return false;
}
else if( !checkDocumentChanges(doc) )
return false;
// open document
haltInteractions();
if( !doc.open(filename,merge,true) ) {
restoreInteractions();
return false;
}
restoreInteractions();
// update history
theWorkspace.getFileHistory().add(filename,doc.getName());
return true;
}
/**
Save the selected document to file. Use the same file if the
document was previously saved, otherwise show a file save
dialog
@return <code>true</code> if the operation was successful
*/
public boolean onSave(BaseDocument doc) {
return onSave(doc,true);
}
/**
Save the selected document to file. Use the same file if the
document was previously saved.
@param ask_filename if <code>true</code> a file save dialog is
showed in case the document was not previously saved
@return <code>true</code> if the operation was successful
*/
public boolean onSave(BaseDocument doc, boolean ask_filename) {
if( doc==null )
return false;
// controlla se e' possibile salvare il file nella stessa posizione da cui e' stato aperto
File cur = doc.getFile();
if( cur!=null && cur.canWrite() ) {
// salvo il documento su file
doc.save(cur.getAbsolutePath());
return true;
}
// non e' stato possibile salvare il file nella posizione da cui e' stato aperto. Richiedo il salvataggio con scelta file
if( ask_filename )
return onSaveAs(doc);
return false;
}
/**
Save the selected document to file. Show a file save dialog to
select the destination
@return <code>true</code> if the operation was successful
*/
public boolean onSaveAs(BaseDocument doc) {
if( doc==null )
return false;
// imposto la dialog per il salvataggio del file
JFileChooser fileChooser = new JFileChooser();
for( javax.swing.filechooser.FileFilter ff : doc.getFileFormats() )
fileChooser.addChoosableFileFilter(ff);
fileChooser.setCurrentDirectory(theWorkspace.getFileHistory().getRecentFolder());
// visualizzo la dialog
if( fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION ) {
// aggiunge l'estension
String filename = fileChooser.getSelectedFile().getAbsolutePath();
javax.swing.filechooser.FileFilter ff = fileChooser.getFileFilter();
if( ff!=fileChooser.getAcceptAllFileFilter() && (ff instanceof ExtensionFileFilter) )
filename = FileUtils.enforceExtension(filename,((ExtensionFileFilter)ff).getDefaultExtension());
// chiede conferma prima di sovrascrivere il file
File file = new File(filename);
if( file.exists() ) {
int retValue = JOptionPane.showOptionDialog(this, "File exists. Overwrite file: " + filename + "?",
"Salva documento", JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if( retValue!=JOptionPane.YES_OPTION )
return false;
}
// salvo il documento su file
if( !doc.save(filename) )
return false;
// update history
theWorkspace.getFileHistory().add(filename,doc.getName());
return true;
}
return false;
}
/**
Import structures from a file in a specified format. Show a
file open dialog to select the origin
@param format the encoding format
@return <code>true</code> if the operation was successful
@see GlycanDocument#importFrom
*/
public boolean onImportFrom(String format) {
// imposto la dialog per l'apertura del file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(theWorkspace.getFileHistory().getRecentFolder());
// visualizzo la dialog
if( fileChooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION )
return false;
// retrieve file path
String filename = fileChooser.getSelectedFile().getAbsolutePath();
//if( filename.equals(theDoc.getFileName()) )
//return false;
//if( !checkDocumentChanges(theDoc) )
//return false;
if( !checkExisting(filename) )
return false;
// import structure into the document
return theDoc.importFrom(filename,format);
}
/**
Export the structures to a file in a specified format. Show a
file open dialog to select the origin
@return <code>true</code> if the operation was successful
@see GlycanDocument#importFrom
@see SVGUtils#export
*/
public boolean onExportTo(String format) {
if( theDoc.getStructures().size()>1 && !theDoc.supportMultipleStructures(format) ) {
int retValue = JOptionPane.showOptionDialog(this, "The selected format does not support multiple structures.\n" +
"Only the first structure will be exported. Continue?",
"Cannot export all structures", JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE, null, null, null);
if( retValue!=JOptionPane.YES_OPTION )
return false;
}
// imposto la dialog per il salvataggio del file
JFileChooser fileChooser = new JFileChooser();
fileChooser.addChoosableFileFilter(new ExtensionFileFilter(format));
fileChooser.setCurrentDirectory(theWorkspace.getFileHistory().getRecentFolder());
// visualizzo la dialog
int returnVal = fileChooser.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
// aggiunge l'estension
String filename = fileChooser.getSelectedFile().getAbsolutePath();
filename = FileUtils.enforceExtension(filename,format);
// chiede conferma prima di sovrascrivere il file
File file = new File(filename);
if (file.exists()) {
int retValue = JOptionPane.showOptionDialog(this, "File exists. Overwrite file: " + filename + "?",
"Salva documento", JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if( retValue!=JOptionPane.YES_OPTION )
return false;
}
// esporta il documento su file
if( theDoc.isSequenceFormat(format) ) {
if( theDoc.exportTo(filename,format) )
setLastExportedFile(filename);
return true;
}
else if( SVGUtils.export(theWorkspace.getGlycanRenderer(),filename,theDoc.getStructures(),theWorkspace.getGraphicOptions().SHOW_MASSES,theWorkspace.getGraphicOptions().SHOW_REDEND,format) ) {
setLastExportedFile(filename);
return true;
}
}
return false;
}
/**
Print the content of the {@link GlycanCanvas}
*/
public void onPrint() {
try {
PrinterJob pj = theWorkspace.getPrinterJob();
if( pj!=null ) {
pj.setPrintable(theCanvas);
if( pj.printDialog() )
theCanvas.print(pj);
}
}
catch(Exception e) {
LogUtils.report(e);
}
}
/**
Check for changed document to save and then exit the
application
*/
public void onExit() {
if( checkDocumentChanges(theDoc) )
this.exit(0);
}
//------------------
// Help actions
/**
Show the about menu
*/
public void onAbout() {
try {
JDialog dlg = new JDialog(this, "About GlycanBuilder", true);
JEditorPane html = new JEditorPane(this.getClass().getResource("/html/about_builder.html"));
html.setEditable(false);
html.setBorder(new EmptyBorder(20,20,20,20));
dlg.add(html);
dlg.setSize(320,320);
dlg.setResizable(false);
dlg.setLocationRelativeTo(this);
dlg.setVisible(true);
}
catch(Exception e) {
LogUtils.report(e);
}
}
//--------------------------
// Listeners
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if( MouseUtils.isPopupTrigger(e) ) {
theCanvas.enforceSelection(e.getPoint());
createPopupMenu().show(theCanvas, e.getX(), e.getY());
}
}
public void mouseReleased(MouseEvent e) {
if( MouseUtils.isPopupTrigger(e) ) {
theCanvas.enforceSelection(e.getPoint());
createPopupMenu().show(theCanvas, e.getX(), e.getY());
}
}
public void mouseClicked(MouseEvent e) {
}
public void documentInit(BaseDocument.DocumentChangeEvent e) {
if( e.getSource() == theWorkspace ) {
theDoc = theWorkspace.getStructures();
theDoc.addDocumentChangeListener(this);
theCanvas.setDocument(theDoc);
}
updateTitle();
updateActions();
}
public void documentChanged(BaseDocument.DocumentChangeEvent e) {
updateTitle();
updateActions();
}
public void fileHistoryChanged() {
updateRecentFileMenu();
}
public void actionPerformed(ActionEvent e) {
String action = GlycanAction.getAction(e);
String param = GlycanAction.getParam(e);
// workspace
if( action.equals("empty") )
onNew(theDoc);
// document handling
else if( action.equals("new") )
onNew(param);
else if( action.equals("open") )
onOpenDocument(theWorkspace.getAllDocuments(),false);
//onOpen(param,theDoc,false);
else if( action.equals("openinto") )
onOpenDocument(theWorkspace.getAllDocuments(),true);
else if( action.equals("openstruct") )
onOpen(param,theWorkspace.getStructures(),false);
else if( action.equals("save") )
onSave(theDoc,true);
else if( action.equals("saveas") )
onSaveAs(theDoc);
else if( action.equals("print") )
onPrint();
else if( action.equals("import") )
onImportFrom(param);
else if( action.equals("export") )
onExportTo(param);
else if( action.equals("quit") )
onExit();
// help
else if( action.equals("about") )
onAbout();
updateActions();
}
///-------------------------
/**
Run the application. Open the application frame
* @throws MalformedURLException
*/
public static void main(String[] args) throws MalformedURLException {
new GlycanBuilder().setVisible(true);
}
}