diff --git a/src/main/java/plugins/adufour/protocols/gui/MainFrame.java b/src/main/java/plugins/adufour/protocols/gui/MainFrame.java index d49321a5b75581f28c0c4949dfdef0f646147784..ffff065b26992f2769ed7eb3b5754c34340f2b4f 100644 --- a/src/main/java/plugins/adufour/protocols/gui/MainFrame.java +++ b/src/main/java/plugins/adufour/protocols/gui/MainFrame.java @@ -1,26 +1,5 @@ package plugins.adufour.protocols.gui; -import icy.common.listener.AcceptListener; -import icy.file.Loader; -import icy.gui.component.CloseableTabbedPane; -import icy.gui.component.CloseableTabbedPane.CloseableTabbedPaneListener; -import icy.gui.frame.IcyFrame; -import icy.gui.frame.IcyFrameEvent; -import icy.gui.frame.IcyFrameListener; -import icy.gui.frame.progress.AnnounceFrame; -import icy.main.Icy; -import icy.plugin.PluginDescriptor; -import icy.plugin.PluginInstaller; -import icy.plugin.PluginLoader; -import icy.resource.ResourceUtil; -import icy.resource.icon.IcyIcon; -import icy.system.FileDrop; -import icy.system.FileDrop.FileDropListener; -import icy.system.IcyExceptionHandler; -import icy.system.IcyHandledException; -import icy.system.thread.ThreadUtil; -import icy.util.XMLUtil; - import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; @@ -54,6 +33,26 @@ import org.pushingpixels.substance.internal.ui.SubstanceSplitPaneUI; import org.pushingpixels.substance.internal.utils.SubstanceSplitPaneDivider; import org.w3c.dom.Document; +import icy.common.listener.AcceptListener; +import icy.file.Loader; +import icy.gui.component.CloseableTabbedPane; +import icy.gui.component.CloseableTabbedPane.CloseableTabbedPaneListener; +import icy.gui.frame.IcyFrame; +import icy.gui.frame.IcyFrameEvent; +import icy.gui.frame.IcyFrameListener; +import icy.gui.frame.progress.AnnounceFrame; +import icy.main.Icy; +import icy.plugin.PluginDescriptor; +import icy.plugin.PluginInstaller; +import icy.plugin.PluginLoader; +import icy.resource.ResourceUtil; +import icy.resource.icon.IcyIcon; +import icy.system.FileDrop; +import icy.system.FileDrop.FileDropListener; +import icy.system.IcyExceptionHandler; +import icy.system.IcyHandledException; +import icy.system.thread.ThreadUtil; +import icy.util.XMLUtil; import plugins.adufour.blocks.Blocks; import plugins.adufour.blocks.lang.Block; import plugins.adufour.blocks.lang.BlockDescriptor; @@ -70,12 +69,13 @@ import plugins.adufour.protocols.Protocols; import plugins.adufour.protocols.gui.block.WorkFlowContainer; import plugins.adufour.vars.lang.Var; -public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListener, CloseableTabbedPaneListener, AcceptListener, ChangeListener, BlockListener, FileDropListener +public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListener, CloseableTabbedPaneListener, + AcceptListener, ChangeListener, BlockListener, FileDropListener { private static final String UNTITLED = "untitled"; - + private final JToolBar toolBar; - + private final JButton bNew = new JButton("New", new IcyIcon(ResourceUtil.ICON_DOC_NEW)); private final JButton bLoad = new JButton("Load", new IcyIcon(ResourceUtil.ICON_OPEN)); private final JButton bSave = new JButton("Save", new IcyIcon(ResourceUtil.ICON_SAVE)); @@ -83,53 +83,54 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe private final JButton bEmbed = new JButton("Embed", new IcyIcon(ResourceUtil.ICON_WINDOW_COLLAPSE)); private final JButton bRun = new JButton("Run", new IcyIcon(ResourceUtil.ICON_PLAY)); private final JButton bClean = new JButton("Reset", new IcyIcon(ResourceUtil.ICON_TRASH)); - - private final CloseableTabbedPane closeableTabbedPane = new CloseableTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT); - + + private final CloseableTabbedPane closeableTabbedPane = new CloseableTabbedPane(JTabbedPane.TOP, + JTabbedPane.WRAP_TAB_LAYOUT); + private final ArrayList<ProtocolPanel> protocolPanels = new ArrayList<ProtocolPanel>(); - + private BlockSearchPanel blockSearchPanel = new BlockSearchPanel(); - + private JSplitPane splitPane; - + // Copy-paste support private static final HashMap<BlockDescriptor, BlockDescriptor> blocksClipBoard = new HashMap<BlockDescriptor, BlockDescriptor>(); private static final HashMap<BlockDescriptor, BlockDescriptor> blocksClipBoardBackup = new HashMap<BlockDescriptor, BlockDescriptor>(); private static final ArrayList<Link<?>> linksClipBoard = new ArrayList<Link<?>>(); private static final ArrayList<Link<?>> linksClipBoardBackup = new ArrayList<Link<?>>(); - + private static final String LINKS_CUT_MSG = "Some links will not be copied. Continue?"; - + private final Protocols pluginInstance; - + private boolean isFrameClosing = false; - + public MainFrame(Protocols pluginInstance) { super("Protocols editor (" + new Blocks().getFriendlyVersion() + ")", true, true, true, true, true); - + this.pluginInstance = pluginInstance; - + // handle close event locally setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); addFrameListener(this); - + setPreferredSize(new Dimension(800, 640)); - + // Menus - + toolBar = new JToolBar("Blocks toolbar", SwingConstants.HORIZONTAL); - + getContentPane().add(toolBar, BorderLayout.NORTH); - - for (JButton button : new JButton[] { bNew, bLoad, bSave, bSaveAs, bEmbed, bRun, bClean }) + + for (JButton button : new JButton[] {bNew, bLoad, bSave, bSaveAs, bEmbed, bRun, bClean}) { button.setFocusPainted(false); button.setBorderPainted(true); button.addActionListener(this); button.setBorder(null); } - + bNew.setToolTipText("<html><h4>Create a new empty protocol</h4></html>"); bLoad.setToolTipText("<html><h4>Load a protocol from a file</h4></html>"); bSave.setToolTipText("<html><h4>Save the current protocol</h4></html>"); @@ -137,7 +138,7 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe bEmbed.setToolTipText("<html><h4>Embed the current selection into a new work flow or a batch</h4></html>"); bRun.setToolTipText("<html><h4>Run the current protocol</h4></html>"); bClean.setToolTipText("<html><h4>Clear all intermediate results (may help saving memory)</h4></html>"); - + toolBar.add(bNew); toolBar.add(bLoad); toolBar.add(bSave); @@ -147,61 +148,62 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe toolBar.add(new JToolBar.Separator()); toolBar.add(bRun); toolBar.add(bClean); - + closeableTabbedPane.addCloseableTabbedPaneListener(this); - + splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, blockSearchPanel, closeableTabbedPane); splitPane.setOneTouchExpandable(true); splitPane.setContinuousLayout(true); splitPane.setUI(new MySplitPaneUI()); getContentPane().add(splitPane, BorderLayout.CENTER); - + getContentPane().addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent key) { - if ((key.getModifiers() & Protocols.MENU_SHORTCUT_KEY) == Protocols.MENU_SHORTCUT_KEY && key.getComponent() instanceof WorkFlowContainer) + if ((key.getModifiers() & Protocols.MENU_SHORTCUT_KEY) == Protocols.MENU_SHORTCUT_KEY + && key.getComponent() instanceof WorkFlowContainer) { WorkFlow wf = ((WorkFlowContainer) key.getComponent()).getWorkFlow(); - + switch (key.getKeyCode()) { case KeyEvent.VK_C: copySelection(wf, false); - break; + break; case KeyEvent.VK_V: pasteSelection(wf, false); - break; + break; case KeyEvent.VK_X: copySelection(wf, false); deleteSelection(wf); - break; + break; case KeyEvent.VK_BACK_SPACE: case KeyEvent.VK_DELETE: deleteSelection(wf); } - + key.getComponent().requestFocus(); // enable successive operations } } - + @Override public void keyTyped(KeyEvent arg0) { } - + @Override public void keyReleased(KeyEvent arg0) { } }); - + Icy.getMainInterface().addCanExitListener(this); - + pack(); } - + public static void copySelection(WorkFlow wf, boolean embedding) throws LinkCutException { // do not modify clip-board when embedding/dis-embedding @@ -215,10 +217,10 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe linksClipBoardBackup.clear(); linksClipBoardBackup.addAll(linksClipBoard); } - + blocksClipBoard.clear(); linksClipBoard.clear(); - + // copy the whole workflow if (wf.getBlockSelection().isEmpty()) { @@ -235,39 +237,41 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe for (Link<?> l : wf.getLinkSelection()) linksClipBoard.add(l); } - - if (embedding && linkCut(wf.getLinksIterator())) throw new LinkCutException(LINKS_CUT_MSG); + + if (embedding && linkCut(wf.getLinksIterator())) + throw new LinkCutException(LINKS_CUT_MSG); } - - @SuppressWarnings({ "rawtypes", "unchecked" }) + + @SuppressWarnings({"rawtypes", "unchecked"}) public static void pasteSelection(WorkFlow wf, boolean embedding) { for (BlockDescriptor bd : blocksClipBoard.keySet()) { - if (bd.getBlock() instanceof WorkFlow) // avoid getting the selection back in the - // container + // avoid getting the selection back in the container + if (bd.getBlock() instanceof WorkFlow) ((WorkFlow) blocksClipBoard.get(bd).getBlock()).newSelection(); + wf.addBlock(blocksClipBoard.get(bd)); } - + for (Link<?> l : linksClipBoard) { Link clone = linkClone(wf, l); - + if (clone == null) { System.err.println("Warning: cannot copy a link to an exposed variable"); continue; } - + wf.addLink(clone.srcBlock, clone.srcVar, clone.dstBlock, clone.dstVar); } - + // re-copy the first copy // avoid pasting an altered state of the block for (BlockDescriptor bd : blocksClipBoard.keySet()) blocksClipBoard.put(bd, blocksClipBoard.get(bd).clone(embedding)); - + if (embedding) { // restore the backup @@ -280,7 +284,7 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe linksClipBoard.addAll(linksClipBoardBackup); } } - + private static void deleteSelection(WorkFlow wf) { if (wf.getBlockSelection().isEmpty()) @@ -290,7 +294,7 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe tmp.add(l); // avoid concurrent modification exception for (Link<?> l : tmp) wf.removeLink(l.dstVar); - + for (int i = 0; i < wf.size();) wf.removeBlock(wf.getBlock(i), false); } @@ -298,26 +302,27 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe { for (Link<?> l : wf.getLinkSelection()) wf.removeLink(l.dstVar); - + // avoid infinite loop when canceling ArrayList<BlockDescriptor> tmp = new ArrayList<BlockDescriptor>(wf.getBlockSelection()); for (BlockDescriptor bd : tmp) wf.removeBlock(bd, false); } } - + private static boolean linkCut(Iterable<Link<?>> links) { for (Link<?> l : links) - if (blocksClipBoard.keySet().contains(l.dstBlock) ^ blocksClipBoard.keySet().contains(l.srcBlock)) return true; + if (blocksClipBoard.keySet().contains(l.dstBlock) ^ blocksClipBoard.keySet().contains(l.srcBlock)) + return true; return false; } - - @SuppressWarnings({ "rawtypes", "unchecked" }) + + @SuppressWarnings({"rawtypes", "unchecked"}) private static Link<?> linkClone(WorkFlow wf, Link<?> l) { Var<?> newSrc = null, newDst = null; - + try { // get link input from block inputs @@ -330,25 +335,25 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe newSrc = blocksClipBoard.get(l.srcBlock).outputVars.get(l.srcBlock.outputVars.getID(l.srcVar)); newDst = blocksClipBoard.get(l.dstBlock).inputVars.get(l.dstBlock.inputVars.getID(l.dstVar)); } - + // if the link contains an exposed variable of a work flow, newSrc or newDst == null // (because the ID of the cloned variable is different in the cloned work flow) if (newSrc == null || newDst == null) { return null; } - + return new Link(wf, blocksClipBoard.get(l.srcBlock), newSrc, blocksClipBoard.get(l.dstBlock), newDst); } - + public void addProtocolPane(ProtocolPanel protocol) { getProtocolPanels().add(protocol); protocol.addPropertyChangeListener(ProtocolPanel.WORKFLOW_MODIFIED, this); protocol.addBlockListener(this); - + new FileDrop(protocol, false, this); - + if (protocol.getFile() != null) { File f = protocol.getFile(); @@ -361,16 +366,16 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe protocol.setName(UNTITLED); closeableTabbedPane.addTab(UNTITLED, protocol); } - + closeableTabbedPane.setSelectedIndex(getProtocolPanels().size() - 1); } - + public ProtocolPanel getActiveProtocol() { int index = closeableTabbedPane.getSelectedIndex(); return (index == -1) ? null : getProtocolPanels().get(index); } - + @Override public void actionPerformed(ActionEvent e) { @@ -389,15 +394,16 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe else if (e.getSource() == bSaveAs) { ProtocolPanel protocol = getActiveProtocol(); - - if (protocol == null) return; - + + if (protocol == null) + return; + // save the old file to restore it in case a problem occurs File oldFile = protocol.getFile(); - + // erase the file to force an open file dialog protocol.setFile(null); - + if (!saveWorkFlow(protocol, true)) { // work flow was not saved => restore the old file @@ -407,9 +413,10 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe else if (e.getSource() == bRun) { ProtocolPanel protocol = getActiveProtocol(); - - if (protocol == null) return; - + + if (protocol == null) + return; + WorkFlow wf = protocol.getWorkFlow(); if (wf.getBlockDescriptor().getStatus() == BlockStatus.RUNNING) { @@ -423,19 +430,21 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe else if (e.getSource() == bEmbed) { ProtocolPanel panel = getActiveProtocol(); - if (panel != null) panel.showBlocksEmbedMenu(bEmbed); + if (panel != null) + panel.showBlocksEmbedMenu(bEmbed); } else if (e.getSource() == bClean) { ProtocolPanel protocol = getActiveProtocol(); - - if (protocol == null) return; - + + if (protocol == null) + return; + WorkFlow wf = protocol.getWorkFlow(); wf.reset(); } } - + @Override public void propertyChange(PropertyChangeEvent evt) { @@ -443,17 +452,19 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe { ProtocolPanel protocolPanel = (ProtocolPanel) evt.getSource(); int index = getProtocolPanels().indexOf(protocolPanel); - + if (index == -1) { String message = "in method \"icy.adufour.protocols.Protocols.propertyChange(PropertyChangeEvent)\":\n"; message += "A protocol was modified, but its panel is already closed (index = -1)"; - IcyExceptionHandler.handleException(pluginInstance.getDescriptor(), new ArrayIndexOutOfBoundsException(message), true); + IcyExceptionHandler.handleException(pluginInstance.getDescriptor(), + new ArrayIndexOutOfBoundsException(message), true); return; } - - if (closeableTabbedPane.getTabCount() <= index) return; - + + if (closeableTabbedPane.getTabCount() <= index) + return; + if (((Boolean) evt.getNewValue()).booleanValue()) { closeableTabbedPane.setTitleAt(index, "* " + closeableTabbedPane.getTitleAt(index)); @@ -468,12 +479,12 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe super.propertyChange(evt); } } - + @Override public void tabClosed(int index, String title) { } - + @Override public boolean tabClosing(int index, String title) { @@ -481,57 +492,65 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe if (protocol.isDirty() && !protocol.isEmpty() && !pluginInstance.isReloading()) { String name = protocol.getFile() == null ? UNTITLED : protocol.getFile().getName(); - int option = JOptionPane.showConfirmDialog(protocol, name + " has not been saved.\nSave workflow before closing ?", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION); - - if (option == JOptionPane.CANCEL_OPTION) return false; - - if (option == JOptionPane.YES_OPTION && !saveWorkFlow(protocol, false)) return false; + int option = JOptionPane.showConfirmDialog(protocol, + name + " has not been saved.\nSave workflow before closing ?", "Confirmation", + JOptionPane.YES_NO_CANCEL_OPTION); + + if (option == JOptionPane.CANCEL_OPTION) + return false; + + if (option == JOptionPane.YES_OPTION && !saveWorkFlow(protocol, false)) + return false; } protocol.removePropertyChangeListener(this); protocol.removeBlockListener(this); protocol.dispose(); - + // Remove drag'n'drop hooks FileDrop.remove(protocol); getProtocolPanels().remove(protocol); - + return true; } - + /** * @param protocol * @param updateTabName * @return true if the saving operation was successful, false if canceled * @throws BlocksException - * if an error occurred while saving to disk + * if an error occurred while saving to disk */ private boolean saveWorkFlow(ProtocolPanel protocol, boolean updateTabName) throws BlocksException { - if (protocol == null) return false; - + if (protocol == null) + return false; + boolean success = protocol.saveToDisk(); - - if (!success) return false; - + + if (!success) + return false; + File savedFile = protocol.getFile(); - - if (updateTabName) closeableTabbedPane.setTitleAt(closeableTabbedPane.getSelectedIndex(), savedFile.getName()); - + + if (updateTabName) + closeableTabbedPane.setTitleAt(closeableTabbedPane.getSelectedIndex(), savedFile.getName()); + return true; } - + private File getFile() { final JFileChooser jfc = new JFileChooser(Protocols.getDefaultProtocolFolder()); - + jfc.setFileFilter(BlocksML.XML_FILE_FILTER); jfc.setDialogTitle("Load an Icy protocol..."); - - if (jfc.showOpenDialog(getFrame()) != JFileChooser.APPROVE_OPTION) return null; - + + if (jfc.showOpenDialog(getFrame()) != JFileChooser.APPROVE_OPTION) + return null; + return jfc.getSelectedFile(); } - + /** * @return the protocolPanels */ @@ -539,61 +558,67 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe { return protocolPanels; } - + /** * Loads the specified file as a new workflow * * @param file * @throws IllegalArgumentException - * if the file is not a protocol + * if the file is not a protocol */ public void loadWorkFlow(File file) throws IllegalArgumentException { - if (file == null) file = getFile(); - - if (file == null) return; - + if (file == null) + file = getFile(); + + if (file == null) + return; + final File workingFile = file; - + Protocols.setDefaultProtocolFolder(file.getParent()); - + // check that the work flow is not already opened for (ProtocolPanel protocol : getProtocolPanels()) - if (file.equals(protocol.getFile())) return; - + if (file.equals(protocol.getFile())) + return; + // make sure the xml is well-formed final Document xml = XMLUtil.loadDocument(file); - + boolean isFileValid = false; - + if (xml != null) { String rootName = XMLUtil.getRootElement(xml).getNodeName(); isFileValid = rootName.equalsIgnoreCase("protocol") || rootName.equalsIgnoreCase("workspace"); } - - if (!isFileValid) throw new IcyHandledException("Error while loading \"" + file.getPath() + "\":\nThe selected file is not an Icy protocol."); - + + if (!isFileValid) + throw new IcyHandledException( + "Error while loading \"" + file.getPath() + "\":\nThe selected file is not an Icy protocol."); + final ProtocolPanel panel = new ProtocolPanel(this); panel.setFile(file); addProtocolPane(panel); - + ThreadUtil.bgRun(new Runnable() { @Override public void run() { AnnounceFrame announce = new AnnounceFrame("Loading protocol " + workingFile.getName() + "..."); - + try { PluginInstaller.waitInstall(); PluginLoader.waitWhileLoading(); - + ArrayList<PluginDescriptor> plugins = PluginLoader.getPlugins(Block.class, true, false, false); - - if (plugins.size() == 0) throw new BlocksReloadedException(); - + + if (plugins.size() == 0) + throw new BlocksReloadedException(); + panel.loadWorkFlow(xml, false); } catch (BlocksReloadedException e) @@ -611,17 +636,18 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe message += " - Yes: send the report and the protocol (recommended for diagnosis).\n"; message += " - No: send the report but not the protocol (recommended for privacy).\n"; message += " - Cancel: discard this message (nothing will be sent)"; - int answer = JOptionPane.showConfirmDialog(getFrame(), message, "Couldn't load protocol", JOptionPane.YES_NO_CANCEL_OPTION); - + int answer = JOptionPane.showConfirmDialog(getFrame(), message, "Couldn't load protocol", + JOptionPane.YES_NO_CANCEL_OPTION); + StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); - + message += "\n\n" + sw.toString(); - + switch (answer) { case JOptionPane.YES_OPTION: - + try { message += "\n\n" + BlocksML.getInstance().toString(xml); @@ -638,11 +664,11 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe { e1.printStackTrace(); } - + //$FALL-THROUGH$ Send the report anyway case JOptionPane.NO_OPTION: IcyExceptionHandler.report(pluginInstance.getDescriptor(), message); - break; + break; default: return; } @@ -656,59 +682,60 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe } }); } - + @Override public void icyFrameOpened(IcyFrameEvent e) { } - + @Override public void icyFrameClosing(IcyFrameEvent e) { if (e.getFrame() == this) { isFrameClosing = true; - - if (!accept(this)) isFrameClosing = false; + + if (!accept(this)) + isFrameClosing = false; } } - + @Override public void icyFrameClosed(IcyFrameEvent e) { pluginInstance.setReloading(false); } - + @Override public void icyFrameIconified(IcyFrameEvent e) { } - + @Override public void icyFrameDeiconified(IcyFrameEvent e) { } - + @Override public void icyFrameActivated(IcyFrameEvent e) { } - + @Override public void icyFrameDeactivated(IcyFrameEvent e) { } - + @Override public void icyFrameInternalized(IcyFrameEvent e) { } - + @Override public void icyFrameExternalized(IcyFrameEvent e) { } - + @Override public void filesDropped(File[] files) { @@ -720,63 +747,67 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe } catch (IllegalArgumentException e) { - if (Loader.isSupportedImageFile(file.getPath())) Loader.load(file.getPath(), true); + if (Loader.isSupportedImageFile(file.getPath())) + Loader.load(file.getPath(), true); } } } - + @Override public boolean accept(Object source) { while (closeableTabbedPane.getTabCount() > 0) { int tabCount = closeableTabbedPane.getTabCount(); - + for (int i = 0; i < tabCount; i++) { if (closeableTabbedPane.getSelectedIndex() == i) { boolean closeAccepted = tabClosing(i, null); - + // if "cancel" is clicked for either tab, stop the closing process - if (!closeAccepted) return false; - - if (closeableTabbedPane.getTabCount() > i) closeableTabbedPane.removeTabAt(i); - + if (!closeAccepted) + return false; + + if (closeableTabbedPane.getTabCount() > i) + closeableTabbedPane.removeTabAt(i); + break; } } } - + for (Component component : toolBar.getComponents()) { - if (component instanceof JButton) ((JButton) component).removeActionListener(this); - + if (component instanceof JButton) + ((JButton) component).removeActionListener(this); + toolBar.remove(component); } - + getContentPane().removeAll(); - + removeFrameListener(this); - + // close manually - + setVisible(false); - + close(); - + Icy.getMainInterface().removeCanExitListener(this); - + Protocols.close(); - + return true; } - + @Override public void stateChanged(ChangeEvent e) { ProtocolPanel panel = getActiveProtocol(); - + if (e.getSource() == closeableTabbedPane && panel != null) { // tab was selected, added or removed @@ -784,70 +815,70 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe updateRunButton(getActiveProtocol().getWorkFlow().getBlockDescriptor().getStatus()); } } - + private void updateRunButton(BlockStatus status) { switch (status) { case RUNNING: bRun.setIcon(new IcyIcon(ResourceUtil.ICON_STOP)); - break; + break; default: bRun.setIcon(new IcyIcon(ResourceUtil.ICON_PLAY)); } } - + @Override public void blockCollapsed(BlockDescriptor block, boolean collapsed) { - + } - + @Override public void blockDimensionChanged(BlockDescriptor block, int newWidth, int newHeight) { } - + @Override public void blockLocationChanged(BlockDescriptor block, int newX, int newY) { } - + @Override public void blockStatusChanged(BlockDescriptor block, BlockStatus status) { updateRunButton(status); } - + @Override public void blockVariableAdded(BlockDescriptor block, Var<?> variable) { } - + @Override public <T> void blockVariableChanged(BlockDescriptor block, Var<T> variable, T newValue) { } - + private class MySplitPaneUI extends SubstanceSplitPaneUI { - + @SuppressWarnings("serial") private class MySplitPaneDivider extends SubstanceSplitPaneDivider { - + public MySplitPaneDivider(SubstanceSplitPaneUI ui) { super(ui); } - + protected JButton createLeftOneTouchButton() { JButton button = super.createLeftOneTouchButton(); button.setPreferredSize(new Dimension(20, 40)); return button; } - + protected JButton createRightOneTouchButton() { JButton button = super.createRightOneTouchButton(); @@ -855,7 +886,7 @@ public class MainFrame extends IcyFrame implements IcyFrameListener, ActionListe return button; } } - + public BasicSplitPaneDivider createDefaultDivider() { return new MySplitPaneDivider(this);