Merge remote-tracking branch 'origin/bug/JAL-3049colourCellTooltip' into
[jalview.git] / src / jalview / gui / AquaInternalFrameManager.java
index a97d8ec..8ef204c 100644 (file)
 package jalview.gui;
 
 import java.awt.Container;
-import java.awt.Rectangle;
 import java.beans.PropertyVetoException;
 import java.util.Vector;
 
 import javax.swing.DefaultDesktopManager;
+import javax.swing.DesktopManager;
 import javax.swing.JInternalFrame;
 
-import com.apple.laf.AquaInternalFramePaneUI;
-
 /**
  * Based on AquaInternalFrameManager
  *
@@ -57,7 +55,12 @@ import com.apple.laf.AquaInternalFramePaneUI;
  * Downloaded from
  * https://raw.githubusercontent.com/frohoff/jdk8u-jdk/master/src/macosx/classes/com/apple/laf/AquaInternalFrameManager.java
  * 
- * @see com.sun.java.swing.plaf.windows.WindowsDesktopManager
+ * Patch from Jim Procter - when the most recently opened frame is closed,
+ * correct behaviour is to go to the next most recent frame, rather than wrap
+ * around to the bottom of the window stack (as the original implementation
+ * does)
+ * 
+ * see com.sun.java.swing.plaf.windows.WindowsDesktopManager
  */
 public class AquaInternalFrameManager extends DefaultDesktopManager
 {
@@ -70,8 +73,6 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
 
   JInternalFrame fInitialFrame;
 
-  AquaInternalFramePaneUI fCurrentPaneUI;
-
   /* The list of frames, sorted by order of creation.
    * This list is necessary because by default the order of
    * child frames in the JDesktopPane changes during frame
@@ -81,12 +82,32 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
    */
   Vector<JInternalFrame> fChildFrames = new Vector<>(1);
 
+  /**
+   * keep a reference to the original LAF manager so we can iconise/de-iconise
+   * correctly
+   */
+  private DesktopManager ourManager;
+
+  public AquaInternalFrameManager(DesktopManager desktopManager)
+  {
+    ourManager = desktopManager;
+  }
+
   @Override
   public void closeFrame(final JInternalFrame f)
   {
     if (f == fCurrentFrame)
     {
-      activateNextFrame();
+      boolean mostRecentFrame = fChildFrames
+              .indexOf(f) == fChildFrames.size() - 1;
+      if (!mostRecentFrame)
+      {
+        activateNextFrame();
+      }
+      else
+      {
+        activatePreviousFrame();
+      }
     }
     fChildFrames.removeElement(f);
     super.closeFrame(f);
@@ -102,14 +123,14 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
     // reshape does delta checks for us
     f.reshape(desktopIcon.getX(), desktopIcon.getY(), f.getWidth(),
             f.getHeight());
-    super.deiconifyFrame(f);
+    ourManager.deiconifyFrame(f);
   }
 
   void addIcon(final Container c,
           final JInternalFrame.JDesktopIcon desktopIcon)
   {
     c.add(desktopIcon);
-    }
+  }
 
   /**
    * Removes the frame from its parent and adds its desktopIcon to the parent.
@@ -117,25 +138,7 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
   @Override
   public void iconifyFrame(final JInternalFrame f)
   {
-    // Same as super except doesn't deactivate it
-    JInternalFrame.JDesktopIcon desktopIcon;
-    Container c;
-
-    desktopIcon = f.getDesktopIcon();
-    // Position depends on *current* position of frame, unlike super which
-    // reuses the first position
-    final Rectangle r = getBoundsForIconOf(f);
-    desktopIcon.setBounds(r.x, r.y, r.width, r.height);
-
-    c = f.getParent();
-    if (c == null)
-        {
-          return;
-        }
-
-    c.remove(f);
-    addIcon(c, desktopIcon);
-    c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
+    ourManager.iconifyFrame(f);
   }
 
   // WindowsDesktopManager code
@@ -145,15 +148,16 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
     try
     {
       if (f != null)
-            {
-              super.activateFrame(f);
-            }
+      {
+        super.activateFrame(f);
+      }
 
-      // If this is the first activation, add to child list.
-      if (fChildFrames.indexOf(f) == -1)
+      // add or relocate to top of stack
+      if (fChildFrames.indexOf(f) != -1)
       {
-        fChildFrames.addElement(f);
+        fChildFrames.remove(f);
       }
+      fChildFrames.addElement(f);
 
       if (fCurrentFrame != null && f != fCurrentFrame)
       {
@@ -184,7 +188,7 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
         activateFrame(fInitialFrame);
       }
       return;
-        }
+    }
 
     final int count = fChildFrames.size();
     if (count <= 1)
@@ -221,7 +225,7 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
     final JInternalFrame f = fChildFrames.elementAt(nextIndex);
     activateFrame(f);
     fCurrentFrame = f;
-    }
+  }
 
   /**
    * Activate the next child JInternalFrame, as determined by the frames'
@@ -231,7 +235,7 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
   public void activateNextFrame()
   {
     switchFrame(true);
-    }
+  }
 
   /**
    * same as above but will activate a frame if none have been selected
@@ -240,7 +244,7 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
   {
     fInitialFrame = f;
     switchFrame(true);
-    }
+  }
 
   /**
    * Activate the previous child JInternalFrame, as determined by the frames'
@@ -250,5 +254,5 @@ public class AquaInternalFrameManager extends DefaultDesktopManager
   public void activatePreviousFrame()
   {
     switchFrame(false);
-    }
-}
\ No newline at end of file
+  }
+}