001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.gui.inspector; 020 021import java.awt.BorderLayout; 022import java.awt.Color; 023import java.awt.Component; 024import java.awt.Dimension; 025import java.awt.Point; 026import java.awt.event.ActionEvent; 027import java.awt.event.ActionListener; 028 029import javax.swing.JPanel; 030import javax.swing.JScrollPane; 031import javax.swing.JTabbedPane; 032import javax.swing.ScrollPaneConstants; 033import javax.swing.event.ChangeEvent; 034import javax.swing.event.ChangeListener; 035 036import icy.gui.component.ExtTabbedPanel; 037import icy.gui.component.ExternalizablePanel; 038import icy.gui.component.button.IcyToggleButton; 039import icy.gui.main.ActiveSequenceListener; 040import icy.gui.main.ActiveViewerListener; 041import icy.gui.main.MainFrame; 042import icy.gui.system.MemoryMonitorPanel; 043import icy.gui.system.OutputConsolePanel; 044import icy.gui.system.OutputConsolePanel.OutputConsoleChangeListener; 045import icy.gui.viewer.Viewer; 046import icy.gui.viewer.ViewerEvent; 047import icy.main.Icy; 048import icy.preferences.GeneralPreferences; 049import icy.resource.ResourceUtil; 050import icy.resource.icon.IcyIcon; 051import icy.sequence.Sequence; 052import icy.sequence.SequenceEvent; 053import icy.system.thread.ThreadUtil; 054 055/** 056 * This window shows all details about the current sequence. 057 * 058 * @author Fabrice de Chaumont & Stephane 059 */ 060public class InspectorPanel extends ExternalizablePanel implements ActiveViewerListener, ActiveSequenceListener 061{ 062 private static final long serialVersionUID = 5538230736731006318L; 063 064 /** 065 * GUI 066 */ 067 final ExtTabbedPanel mainPane; 068 069 final SequencePanel sequencePanel; 070 final RoisPanel roisPanel; 071 final LayersPanel layersPanel; 072 final UndoManagerPanel historyPanel; 073 final OutputConsolePanel outputConsolePanel; 074 // final ChatPanel chatPanel; 075 076 final IcyToggleButton virtualModeBtn; 077 078 /** 079 * The width of the inner component of the inspector should not exceed 300. 080 */ 081 public InspectorPanel() 082 { 083 super("Inspector", "inspector", new Point(600, 140), new Dimension(300, 600)); 084 085 // tab panel 086 mainPane = new ExtTabbedPanel(); 087 mainPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); 088 089 // main panels 090 sequencePanel = new SequencePanel(); 091 // final JPanel pluginsPanel = new PluginsPanel(); 092 roisPanel = new RoisPanel(); 093 layersPanel = new LayersPanel(); 094 historyPanel = new UndoManagerPanel(); 095 outputConsolePanel = new OutputConsolePanel(); 096 // chatPanel = new ChatPanel(); 097 098 // virtual mode button (set the same size as memory monitor) 099 virtualModeBtn = new IcyToggleButton(new IcyIcon(ResourceUtil.ICON_HDD_STREAM, 48)); 100 virtualModeBtn.setToolTipText("Enable / disable the virtual mode (all images are created in virtual mode)"); 101 virtualModeBtn.setHideActionText(true); 102 virtualModeBtn.setFlat(true); 103 virtualModeBtn.setFocusable(false); 104 virtualModeBtn.setSelected(GeneralPreferences.getVirtualMode()); 105 virtualModeBtn.addActionListener(new ActionListener() 106 { 107 @Override 108 public void actionPerformed(ActionEvent e) 109 { 110 // switch virtual mode state 111 GeneralPreferences.setVirtualMode(!GeneralPreferences.getVirtualMode()); 112 113 // refresh title (display virtual mode or not) 114 final MainFrame mainFrame = Icy.getMainInterface().getMainFrame(); 115 if (mainFrame != null) 116 mainFrame.refreshTitle(); 117 } 118 }); 119 120 // add main tab panels 121 mainPane.addTab("Sequence", null, new JScrollPane(sequencePanel, 122 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER), 123 "Sequence informations"); 124 // mainPane.add("Active Plugin", pluginsPanel); 125 mainPane.addTab("ROI", null, roisPanel, "Manage / edit your ROI"); 126 mainPane.addTab("Layer", null, layersPanel, "Show all layers details"); 127 mainPane.addTab("History", null, historyPanel, "Actions history"); 128 mainPane.addTab("Output", null, outputConsolePanel, "Console output"); 129 // mainPane.addTab("Chat", null, chatPanel, "Chat room"); 130 131 // minimum required size for sequence infos panel 132 final Dimension minDim = new Dimension(300, 480); 133 getFrame().setMinimumSizeInternal(minDim); 134 getFrame().setMinimumSizeExternal(minDim); 135 setMinimumSize(minDim); 136 setLayout(new BorderLayout()); 137 138 add(mainPane, BorderLayout.CENTER); 139 140 // build bottom panel for inspector 141 final JPanel bottomPanel = new JPanel(); 142 bottomPanel.setLayout(new BorderLayout()); 143 144 // add virtual button and memory monitor 145 bottomPanel.add(virtualModeBtn, BorderLayout.EAST); 146 bottomPanel.add(new MemoryMonitorPanel(), BorderLayout.CENTER); 147 148 add(bottomPanel, BorderLayout.SOUTH); 149 150 validate(); 151 setVisible(true); 152 153 // get default color of tab background 154 final Color defaultBgColor = mainPane.getBackgroundAt(0); 155 156 mainPane.addChangeListener(new ChangeListener() 157 { 158 @Override 159 public void stateChanged(ChangeEvent e) 160 { 161 final int index = getIndexOfTab(outputConsolePanel); 162 163 // set back default tab color 164 if ((index != -1) && (mainPane.getSelectedIndex() == index)) 165 mainPane.setBackgroundAt(index, defaultBgColor); 166 } 167 }); 168 169 outputConsolePanel.addOutputConsoleChangeListener(new OutputConsoleChangeListener() 170 { 171 @Override 172 public void outputConsoleChanged(OutputConsolePanel source, boolean isError) 173 { 174 final int index = getIndexOfTab(outputConsolePanel); 175 176 if ((index != -1) && (mainPane.getSelectedIndex() != index)) 177 { 178 final boolean fIsError = isError; 179 180 ThreadUtil.invokeLater(new Runnable() 181 { 182 @Override 183 public void run() 184 { 185 // change output console tab color when new data 186 if (fIsError) 187 mainPane.setBackgroundAt(index, Color.red); 188 else if (!mainPane.getBackgroundAt(index).equals(Color.red)) 189 mainPane.setBackgroundAt(index, Color.blue); 190 } 191 }); 192 } 193 } 194 }); 195 196 // add focused sequence & viewer listener 197 Icy.getMainInterface().addActiveViewerListener(this); 198 Icy.getMainInterface().addActiveSequenceListener(this); 199 } 200 201 /** 202 * @return the mainPane 203 */ 204 public ExtTabbedPanel getMainPane() 205 { 206 return mainPane; 207 } 208 209 /** 210 * @return the sequencePanel 211 */ 212 public SequencePanel getSequencePanel() 213 { 214 return sequencePanel; 215 } 216 217 /** 218 * @return the roisPanel 219 */ 220 public RoisPanel getRoisPanel() 221 { 222 return roisPanel; 223 } 224 225 /** 226 * @return the layersPanel 227 */ 228 public LayersPanel getLayersPanel() 229 { 230 return layersPanel; 231 } 232 233 /** 234 * @return the historyPanel 235 */ 236 public UndoManagerPanel getHistoryPanel() 237 { 238 return historyPanel; 239 } 240 241 /** 242 * @return the outputConsolePanel 243 */ 244 public OutputConsolePanel getOutputConsolePanel() 245 { 246 return outputConsolePanel; 247 } 248 249 /** 250 * @deprecated IRC has been removed since Icy 1.9.8.0 251 */ 252 public ChatPanel getChatPanel() 253 { 254 return null; 255 // return chatPanel; 256 } 257 258 public static boolean getVirtualMode() 259 { 260 return GeneralPreferences.getVirtualMode(); 261 } 262 263 public void setVirtualMode(boolean value) 264 { 265 virtualModeBtn.setSelected(value); 266 GeneralPreferences.setVirtualMode(value); 267 } 268 269 /** 270 * Call this to disable 'virtual mode' button 271 */ 272 public void imageCacheDisabled() 273 { 274 // image cache is disabled so we can't use caching 275 virtualModeBtn.setEnabled(false); 276 virtualModeBtn.setSelected(false); 277 virtualModeBtn.setToolTipText("Image cache is disabled, cannot use the virtual mode"); 278 279 // refresh title (display virtual mode or not) 280 final MainFrame mainFrame = Icy.getMainInterface().getMainFrame(); 281 if (mainFrame != null) 282 mainFrame.refreshTitle(); 283 } 284 285 /** 286 * Return the index of specified tab component 287 */ 288 protected int getIndexOfTab(Component component) 289 { 290 return mainPane.indexOfComponent(component); 291 } 292 293 @Override 294 public void viewerActivated(Viewer viewer) 295 { 296 sequencePanel.viewerActivated(viewer); 297 layersPanel.viewerActivated(viewer); 298 } 299 300 @Override 301 public void viewerDeactivated(Viewer viewer) 302 { 303 // nothing to do here 304 } 305 306 /** 307 * Called when focused viewer has changed 308 */ 309 @Override 310 public void activeViewerChanged(ViewerEvent event) 311 { 312 sequencePanel.activeViewerChanged(event); 313 layersPanel.activeViewerChanged(event); 314 } 315 316 @Override 317 public void sequenceActivated(Sequence sequence) 318 { 319 sequencePanel.sequenceActivated(sequence); 320 roisPanel.sequenceActivated(sequence); 321 historyPanel.sequenceActivated(sequence); 322 } 323 324 @Override 325 public void sequenceDeactivated(Sequence sequence) 326 { 327 // nothing to do here 328 } 329 330 /** 331 * Called by mainInterface when focused sequence has changed 332 */ 333 @Override 334 public void activeSequenceChanged(SequenceEvent event) 335 { 336 sequencePanel.activeSequenceChanged(event); 337 roisPanel.activeSequenceChanged(event); 338 } 339}