/* ViewerDocumentTabbedPane.java created 2007-09-17 * */ package org.signalml.app.view.workspace; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import javax.swing.border.EmptyBorder; import org.apache.log4j.Logger; import org.signalml.app.action.selector.ActionFocusEvent; import org.signalml.app.action.selector.ActionFocusListener; import org.signalml.app.action.selector.ActionFocusManager; import org.signalml.app.document.BookDocument; import org.signalml.app.document.DocumentFlowIntegrator; import org.signalml.app.document.DocumentManagerEvent; import org.signalml.app.document.DocumentManagerListener; import org.signalml.app.document.ManagedDocumentType; import org.signalml.app.document.MonitorSignalDocument; import org.signalml.app.document.signal.SignalDocument; import org.signalml.app.view.View; import org.signalml.app.view.common.dialogs.errors.Dialogs; import org.signalml.plugin.export.SignalMLException; import org.signalml.plugin.export.signal.Document; import org.signalml.plugin.export.view.DocumentView; import org.springframework.context.MessageSourceResolvable; /** ViewerDocumentTabbedPane * * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public class ViewerDocumentTabbedPane extends JTabbedPane implements DocumentManagerListener, ActionFocusListener { private static final long serialVersionUID = 1L; protected static final Logger logger = Logger.getLogger(ViewerDocumentTabbedPane.class); /** * The maximum length a tab title can have. Document names that are longer * than this will be shortened. */ private static int MAXIMUM_TAB_TITLE_LENGTH = 35; private ActionFocusManager actionFocusManager; private View view; /** * DocumentFlowIntegrator for closing documents using the cross * on the tabs. */ private DocumentFlowIntegrator documentFlowIntegrator; public ViewerDocumentTabbedPane() { super(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT); } public void initialize() { setBorder(new EmptyBorder(3, 3, 3, 3)); KeyStroke ctrlTab = KeyStroke.getKeyStroke("ctrl TAB"); getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ctrlTab, "nextDocument"); getActionMap().put("nextDocument", new NextDocumentAction()); KeyStroke ctrlShiftTab = KeyStroke.getKeyStroke("ctrl shift TAB"); getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ctrlShiftTab, "previousDocument"); getActionMap().put("previousDocument", new PreviousDocumentAction()); } @Override public void documentAdded(DocumentManagerEvent e) { Document document = e.getDocument(); if ((document instanceof SignalDocument) || (document instanceof BookDocument) || (document instanceof MonitorSignalDocument)) { addDocumentTab(document); } } @Override public void documentPathChanged(DocumentManagerEvent e) { Document document = e.getDocument(); int index = indexOfComponent(document.getDocumentView()); if (index >= 0) { String tabTitle = getTabTitle(document); String tabTooltip = getTabTooltip(document); setTitleAt(index, tabTitle); setToolTipTextAt(index, tabTooltip); } } /** * Returns the document name of the given document. * @param document the document * @return the name of the document */ protected String getDocumentName(Document document) { String documentName = null; if (document instanceof MessageSourceResolvable) { documentName = ((MessageSourceResolvable) document).getDefaultMessage(); } else { documentName = document.toString(); } return documentName; } @Override public void documentRemoved(DocumentManagerEvent e) { removeDocumentTab(e.getDocument()); } @Override public void actionFocusChanged(ActionFocusEvent e) { Document document = actionFocusManager.getActiveDocument(); if (document != null) { showDocument(document); } } public void addDocumentTab(Document document) { DocumentView documentViewPanel; try { documentViewPanel = view.createDocumentViewPanel(document); } catch (SignalMLException ex) { logger.error("Failed to create signal view", ex); Dialogs.showExceptionDialog(this, ex); return; } ManagedDocumentType type = ManagedDocumentType.getForClass(document.getClass()); Icon icon = null; if (type != null) { icon = type.getIcon(); } document.setDocumentView(documentViewPanel); String tabTitle = getTabTitle(document); String tabTooltip = getTabTooltip(document); addTab(tabTitle, icon, documentViewPanel, tabTooltip); this.setTabComponentAt(this.getTabCount()-1, new ViewerDocumentTabbedPaneTabComponent(this)); } /** * Returns a tab title for a given document. * @param document a document for which the tab title will be returned * @return a tab title for the document. */ private String getTabTitle(Document document) { String documentName = getDocumentName(document); String tabTitle; if (documentName.length() > MAXIMUM_TAB_TITLE_LENGTH) { String dots = "..."; int substringLengthWithoutDots = MAXIMUM_TAB_TITLE_LENGTH - dots.length(); tabTitle = documentName.substring(0, substringLengthWithoutDots); tabTitle += dots; } else { tabTitle = documentName; } return tabTitle; } /** * Returns a tab tooltip for a given document. * @param document a document for which the tooltip will be returned * @return a tooltip for the document */ private String getTabTooltip(Document document) { String documentName = getDocumentName(document); String tabTooltip = documentName; return tabTooltip; } public void removeDocumentTab(Document document) { DocumentView documentView = (DocumentView) document.getDocumentView(); if (documentView != null) { remove(documentView); document.setDocumentView(null); documentView.destroy(); } } public void showDocument(Document document) { setSelectedComponent(document.getDocumentView()); } public Document getDocumentInTab(int index) { DocumentView dv = (DocumentView) getComponentAt(index); return dv.getDocument(); } public ActionFocusManager getActionFocusManager() { return actionFocusManager; } public void setActionFocusManager(ActionFocusManager actionFocusManager) { this.actionFocusManager = actionFocusManager; } public View getView() { return view; } public void setView(View view) { this.view = view; } /** * Sets the DocumentFlowIntegrator to be used for closing documents * using the cross on the tabs. * @param documentFlowIntegrator */ public void setDocumentFlowIntegrator(DocumentFlowIntegrator documentFlowIntegrator) { this.documentFlowIntegrator = documentFlowIntegrator; } /** * Returns the DocumentFlowIntegrator which is used for closing documents * using the cross on the tabs. * @return */ public DocumentFlowIntegrator getDocumentFlowIntegrator() { return documentFlowIntegrator; } private class NextDocumentAction extends AbstractAction { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { int cnt = getTabCount(); int index = (getSelectedIndex() + 1) % cnt; setSelectedIndex(index); } } private class PreviousDocumentAction extends AbstractAction { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { int cnt = getTabCount(); int index = (cnt + getSelectedIndex() - 1) % cnt; setSelectedIndex(index); } } }