/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.gui.frame; import icy.action.IcyAbstractAction; import icy.common.MenuCallback; import icy.gui.util.LookAndFeelUtil; import icy.resource.ResourceUtil; import icy.resource.icon.IcyIcon; import icy.system.IcyExceptionHandler; import icy.system.SystemUtil; import icy.system.thread.ThreadUtil; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyVetoException; import javax.swing.JInternalFrame; import javax.swing.JMenu; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; import org.pushingpixels.substance.internal.utils.SubstanceInternalFrameTitlePane; /** * @author Stephane */ public class IcyInternalFrame extends JInternalFrame { /** * */ private static final long serialVersionUID = -5445569637723054083L; private class CloseAction extends IcyAbstractAction { /** * */ private static final long serialVersionUID = 4933605299188863452L; public CloseAction() { super("Close", new IcyIcon(ResourceUtil.ICON_CLOSE, 20), "Close window", KeyEvent.VK_F4, SystemUtil .getMenuCtrlMask()); } @Override public boolean doAction(ActionEvent e) { close(false); return true; } } /** * internals */ SubstanceInternalFrameTitlePane titlePane = null; // JMenu systemMenu; MenuCallback systemMenuCallback; private boolean titleBarVisible; private boolean closeItemVisible; private boolean initialized = false; /** * @param title * @param resizable * @param closable * @param maximizable * @param iconifiable */ public IcyInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable) { super(title, resizable, closable, maximizable, iconifiable); addPropertyChangeListener("titlePane", new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // invoke later so the titlePane variable is up to date ThreadUtil.invokeLater(new Runnable() { @Override public void run() { updateTitlePane(); } }); } }); addInternalFrameListener(new InternalFrameAdapter() { @Override public void internalFrameClosed(InternalFrameEvent e) { // release the system menu callback as it can lead to some memory leak // (cycling reference) systemMenuCallback = null; } }); setFrameIcon(ResourceUtil.ICON_ICY_16); setVisible(false); systemMenuCallback = null; closeItemVisible = closable; updateTitlePane(LookAndFeelUtil.getTitlePane(this)); titleBarVisible = true; initialized = true; } /** * update internals informations linked to title pane with specified pane */ protected void updateTitlePane(final SubstanceInternalFrameTitlePane pane) { // update pane save if (pane != null) titlePane = pane; // update menu // if (titlePane != null) // systemMenuBar = titlePane.getMenuBar(); // refresh system menu whatever updateSystemMenu(); } /** * update internals informations linked to title pane and title pane state */ protected void updateTitlePane() { if (initialized) { // title pane can have changed updateTitlePane(LookAndFeelUtil.getTitlePane(this)); if (!titleBarVisible) setTitleBarVisible(false); } } /** * Refresh system menu */ public void updateSystemMenu() { if ((titlePane != null) && !isClosed()) { final JMenu menu; if (systemMenuCallback != null) menu = systemMenuCallback.getMenu(); else menu = getDefaultSystemMenu(); // ensure compatibility with heavyweight component menu.getPopupMenu().setLightWeightPopupEnabled(false); // rebuild menu titlePane.setSystemMenu(menu); // systemMenuBar.removeAll(); // systemMenuBar.add(menu); // systemMenuBar.validate(); } } /** * Close the frame. * * @param force * if <code>true</code> the frame is close even if {@link #isClosable()} return <code>false</code> */ public void close(boolean force) { if (force || isClosable()) doDefaultCloseAction(); } /** * Implement isMinimized method */ public boolean isMinimized() { return isIcon(); } /** * Implement isMaximized method */ public boolean isMaximized() { return isMaximum(); } /** * Implement setMinimized method */ public void setMinimized(final boolean value) { // only relevant if state changed if (isMinimized() ^ value) { try { setIcon(value); } catch (PropertyVetoException e) { IcyExceptionHandler.showErrorMessage(e, true); } } } /** * Implement setMaximized method */ public void setMaximized(final boolean value) { // have to check that else we obtain a null pointer exception if (getParent() == null) return; // only relevant if state changed if (isMaximized() ^ value) { try { // have to check for parent non null setMaximum(value); } catch (PropertyVetoException e) { IcyExceptionHandler.showErrorMessage(e, true); } } } /** * @return the titleBarVisible */ public boolean isTitleBarVisible() { return titleBarVisible; } /** * @return the closeItemVisible */ public boolean isCloseItemVisible() { return closeItemVisible; } /** * @param value * the closeItemVisible to set */ public void setCloseItemVisible(boolean value) { if (closeItemVisible != value) { closeItemVisible = value; ThreadUtil.invokeLater(new Runnable() { @Override public void run() { updateSystemMenu(); } }); } } @Override public void setClosable(boolean b) { super.setClosable(b); if (!b) setCloseItemVisible(false); } /** * @param value * the titleBarVisible to set */ public void setTitleBarVisible(boolean value) { if (value) LookAndFeelUtil.setTitlePane(this, titlePane); else LookAndFeelUtil.setTitlePane(this, null); revalidate(); titleBarVisible = value; } /** * Return the default system menu */ public JMenu getDefaultSystemMenu() { final JMenu result = new JMenu(); if (closeItemVisible) result.add(new CloseAction()); return result; } /** * @return the systemMenuCallback */ public MenuCallback getSystemMenuCallback() { return systemMenuCallback; } /** * @param value * the systemMenuCallback to set */ public void setSystemMenuCallback(MenuCallback value) { if (systemMenuCallback != value) { systemMenuCallback = value; ThreadUtil.invokeLater(new Runnable() { @Override public void run() { updateSystemMenu(); } }); } } }