/* * Lilith - a log event viewer. * Copyright (C) 2007-2015 Joern Huxhorn * * This program 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. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.huxhorn.lilith.swing; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Frame; import java.awt.Rectangle; import java.beans.PropertyVetoException; import javax.swing.JDesktopPane; import javax.swing.JInternalFrame; import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ViewContainerInternalFrame extends JInternalFrame implements ViewWindow { private static final long serialVersionUID = 4881227991504896068L; private final Logger logger = LoggerFactory.getLogger(ViewContainerInternalFrame.class); private MainFrame mainFrame; private ViewContainer viewContainer; public ViewContainerInternalFrame(MainFrame mainFrame, ViewContainer viewContainer) { super(); this.mainFrame = mainFrame; this.viewContainer = viewContainer; setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE); add(viewContainer, BorderLayout.CENTER); setClosable(true); setResizable(true); setMaximizable(true); setIconifiable(true); addInternalFrameListener(new CleanupWindowChangeListener()); } @Override public void setGlassPane(Component glassPane) { Component prev = getGlassPane(); super.setGlassPane(glassPane); if(logger.isDebugEnabled()) logger.debug("Glasspane\nprev: {}\n new: {}", prev, glassPane); } public void setShowingStatusBar(boolean showingStatusBar) { if(viewContainer != null) { viewContainer.setShowingStatusBar(showingStatusBar); } } public ViewActions getViewActions() { return mainFrame.getViewActions(); } public ViewContainer getViewContainer() { return viewContainer; } public void focusWindow() { // move mainframe to front. if(!mainFrame.isVisible()) { mainFrame.setVisible(true); } if((mainFrame.getState() & Frame.ICONIFIED) != 0) { mainFrame.setState(Frame.NORMAL); } mainFrame.toFront(); adjustBounds(this); try { setIcon(false); toFront(); setSelected(true); } catch(PropertyVetoException ex) { if(logger.isWarnEnabled()) logger.warn("Veto!!", ex); } } private void adjustBounds(JInternalFrame component) { if(component.isMaximum()) { // don't adjust if maximized return; } Rectangle componentBounds = component.getBounds(); Container parent = component.getParent(); if(parent == null) { return; } Rectangle parentBounds = parent.getBounds(); int componentX = (int) componentBounds.getX(); int componentY = (int) componentBounds.getY(); int componentWidth = (int) componentBounds.getWidth(); int componentHeight = (int) componentBounds.getHeight(); boolean adjusted = false; int usableWidth = (int)(parentBounds.getWidth()); if(componentWidth > usableWidth) { componentWidth = usableWidth; adjusted = true; } int usableHeight = (int)(parentBounds.getHeight()); if(componentHeight > usableHeight) { componentHeight = usableHeight; adjusted = true; } int usableX = 0; if(componentX < usableX) { componentX = usableX; adjusted = true; } else if(usableX + usableWidth < componentX + componentWidth) { componentX = usableX + usableWidth - componentWidth; adjusted = true; } int usableY = 0; if(componentY < usableY) { componentY = usableY; adjusted = true; } else if(usableY + usableHeight < componentY + componentHeight) { componentY = usableY + usableHeight - componentHeight; adjusted = true; } if(adjusted) { Rectangle newBounds = new Rectangle(componentX, componentY, componentWidth, componentHeight); component.setBounds(newBounds); if(logger.isDebugEnabled()) logger.debug("Adjusted bounds from {} to {}.", componentBounds, newBounds); } } public void minimizeWindow() { try { setIcon(true); } catch(PropertyVetoException e) { // ignore } } public void closeWindow() { if(logger.isDebugEnabled()) logger.debug("Closing InternalFrame..."); JDesktopPane desktop = mainFrame.getDesktop(); if(logger.isDebugEnabled()) { JInternalFrame[] frames = desktop.getAllFrames(); StringBuilder result = new StringBuilder(); result.append("before closing:\n"); if(frames != null) { for(JInternalFrame current : frames) { result.append(current).append("\n"); } } logger.debug(result.toString()); } setVisible(false); try { setClosed(true); } catch(PropertyVetoException ex) { if(logger.isWarnEnabled()) logger.warn("Couldn't close InternalFrame!", ex); } if(logger.isDebugEnabled()) { JInternalFrame[] frames = desktop.getAllFrames(); StringBuilder result = new StringBuilder(); result.append("after closing:\n"); if(frames != null) { for(JInternalFrame current : frames) { result.append(current).append("\n"); } } logger.debug(result.toString()); } if(logger.isInfoEnabled()) logger.info("Closed InternalFrame..."); } private class CleanupWindowChangeListener implements InternalFrameListener { public void internalFrameClosing(InternalFrameEvent e) { if(logger.isDebugEnabled()) logger.debug("internalFrameClosing: {}", e.getInternalFrame()); } public void internalFrameClosed(InternalFrameEvent e) { if(logger.isDebugEnabled()) logger.debug("internalFrameClosed: {}", e.getInternalFrame()); viewContainer.cancelSearching(); getContentPane().removeAll(); mainFrame.updateWindowMenus(); } public void internalFrameOpened(InternalFrameEvent e) { if(logger.isDebugEnabled()) logger.debug("internalFrameOpened: {}", e.getInternalFrame()); } public void internalFrameIconified(InternalFrameEvent e) { if(logger.isDebugEnabled()) logger.debug("internalFrameIconified: {}", e.getInternalFrame()); } public void internalFrameDeiconified(InternalFrameEvent e) { if(logger.isDebugEnabled()) logger.debug("internalFrameDeiconified: {}", e.getInternalFrame()); } public void internalFrameActivated(InternalFrameEvent e) { if(logger.isDebugEnabled()) logger.debug("internalFrameActivated: {}", e.getInternalFrame()); mainFrame.getViewActions().setViewContainer(viewContainer); } public void internalFrameDeactivated(InternalFrameEvent e) { if(logger.isDebugEnabled()) logger.debug("internalFrameDeactivated: {}", e.getInternalFrame()); } } }