/* * Copyright 2003-2010 Tufts University Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ package tufts.vue.gui; import tufts.Util; import tufts.vue.DEBUG; import tufts.vue.SearchTextField; import tufts.vue.VUE; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ComponentEvent; import java.awt.event.ComponentAdapter; import javax.swing.Action; import javax.swing.AbstractButton; /** * An action for displaying a Window and tracking it's displayed state, * keeping in synchronized with a somebody's button (such a checkbox in a menu). * * @version $Revision: 1.16 $ / $Date: 2010-02-03 19:15:46 $ / $Author: mike $ * @author Scott Fraize */ public class WindowDisplayAction extends javax.swing.AbstractAction { private static final org.apache.log4j.Logger Log = org.apache.log4j.Logger.getLogger(WindowDisplayAction.class); private AbstractButton mLinkedButton; private Window mWindow; private Object mObject; private String mTitle; private boolean firstDisplay = true; private static final boolean showActionLabel = false; public WindowDisplayAction(Object o) { mObject = o; Window w; if (o instanceof DockWindow) w = ((DockWindow)o).window(); else w = (Window) o; init(extractTitle(o), w); } /* public WindowDisplayAction(Window w) { super("window: " + w.getName()); } public WindowDisplayAction(ToolWindow tw) { super("window: " + tw.getWindow().getName()); init(tw.getTitle(), tw.getWindow()); } */ private void init(String title, Window w) { mTitle = title; putValue(Action.NAME, "windowDisplayAction:" + w.getName()); updateActionTitle(true); mWindow = w; mWindow.addComponentListener(new ComponentAdapter() { public void componentShown(ComponentEvent e) { handleShown(); } public void componentHidden(ComponentEvent e) { handleHidden(); } }); } /* private String getTitle() { return mTitle; //return extractTitle(mWindow); } */ private static String extractTitle(Object w) { if (w instanceof java.awt.Frame) return ((java.awt.Frame)w).getTitle(); else if (w instanceof java.awt.Dialog) return ((java.awt.Dialog)w).getTitle(); else if (w instanceof DockWindow) { return ((DockWindow)w).getMenuName(); } else return ((java.awt.Window)w).getName(); } private void handleShown() { //if (DEBUG.DOCK) out("handleShown"); firstDisplay = false; setButtonState(isConsideredShown()); updateActionTitle(false); } private void handleHidden() { //if (DEBUG.DOCK) out("handleHidden"); setButtonState(false); updateActionTitle(false); } private void updateActionTitle(boolean firstTime) { if (!firstTime && !showActionLabel) return; if (showActionLabel) { String action = "Show "; if (mLinkedButton != null && mLinkedButton.isSelected()) action = "Hide "; putValue(Action.NAME, action + mTitle); } else { putValue(Action.NAME, mTitle); } } public void setLinkedButton(AbstractButton b) { mLinkedButton = b; setButtonState(isConsideredShown()); } private void setButtonState(boolean checked) { if (mLinkedButton != null) { if (DEBUG.DOCK) out("setButtonState " + checked); mLinkedButton.setSelected(checked); } else { if (DEBUG.DOCK) out("setButtonState " + checked + "; NO LINKED ITEM"); } } private boolean isConsideredShown() { if (mObject instanceof DockWindow) { DockWindow dockWindow = (DockWindow) mObject; if (dockWindow.isDocked()) return !dockWindow.isRolledUp(); else return dockWindow.isVisible(); } else return mWindow.isVisible(); } // TODO: if DockWindow, re-attach to last parent if it had one? // Only roll/unroll instead of hide/show? private static int placedWindow = 1; public void actionPerformed(ActionEvent e) { if (DEBUG.DOCK) out("actionPerformed: " + e); if (mLinkedButton == null) mLinkedButton = (AbstractButton) e.getSource(); if (firstDisplay) { java.awt.Insets screen = GUI.getScreenInsets(); if (DEBUG.DOCK) out("firstDisplay, screenInsets=" + screen + " win " + mWindow.getBounds()); // assign a default location to newly displayed windows // todo: cascade them or somethting //if (mWindow.getX() == screen.left && mWindow.getY() == screen.top) if (mWindow.getX() < 0) mWindow.setLocation(screen.left, screen.top + DockWindow.getCollapsedHeight() * placedWindow++); } firstDisplay = false; final boolean doShowWindow = mLinkedButton.isSelected(); final boolean doHideWindow = !doShowWindow; if (mObject instanceof DockWindow) { DockWindow dockWindow = (DockWindow) mObject; if (doHideWindow && dockWindow.isDocked() && !dockWindow.isRolledUp()) { // "Hiding" a docked DockWindow that is unrolled really means roll it back up // instead of hiding it. dockWindow.setRolledUp(true); return; } } if (doShowWindow) { boolean isMac = Util.isMacPlatform(); // if (isMac) tufts.Util.invoke(mWindow.getPeer(), "setAlpha", new Float(0.5)); // Why do we see the window contents flash twice on showing? // Old VUE does this too -- is Swing/AWT just pathetic? // BTW, this doesn't happen the *first* time a window shows. // Not doing the toFront here doesn't help. // Okay, now Map Inspector is doing it, but not Object Inspector. // Pre-validating may help, but may slow it down? I think this // has to do with validation in some way. //mWindow.validate(); if (VUE.usingAnchorDock()) { if (VUE.getAnchorDock().isVisible()) VUE.getAnchorDock().setVisible(false); VUE.getAnchorDock().setVisible(true); VUE.getAnchorDock().toFront(); } mWindow.setVisible(true); mWindow.toFront(); // could always set off screen and not move back until AWT cleared /* if (isMac) VUE.invokeAfterAWT(new Runnable() { public void run() { tufts.Util.invoke(mWindow.getPeer(), "setAlpha", new Float(1.0)); }}); */ //VUE.ensureToolWindowVisibility(mTitle); } else { if (VUE.usingAnchorDock()) { VUE.getAnchorDock().setVisible(true); VUE.getAnchorDock().toFront(); } mWindow.setVisible(false); if (VUE.usingAnchorDock() && VUE.getAnchorDock().isVisible()) VUE.getAnchorDock().setVisible(false); // Below condition makes no sense -- was something else meant here? // if (!Util.isMacLeopard() && Util.isMacLeopard()) // { // VUE.getAnchorDock().setVisible(true); // VUE.getAnchorDock().toFront(); // } //VUE.ensureToolWindowVisibility(null); } } public void setTitle(String title) { mTitle=title; putValue(Action.NAME, mTitle); } private void out(String s) { //System.out.println("WindowDisplayAction[" + GUI.name(mWindow) + "] " + s); Log.debug(String.format("@%x [%s] %s", System.identityHashCode(this), //Util.tags(mWindow), GUI.name(mWindow), s)); } }