JAL-1645 Version-Rel Version 2.9 Year-Rel 2015 Licensing glob
[jalview.git] / src / jalview / jbgui / GSplitFrame.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9)
3  * Copyright (C) 2015 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.jbgui;
22
23 import jalview.util.Platform;
24
25 import java.awt.Component;
26 import java.awt.MouseInfo;
27 import java.awt.Point;
28 import java.awt.Rectangle;
29
30 import javax.swing.JInternalFrame;
31 import javax.swing.JSplitPane;
32 import javax.swing.plaf.basic.BasicInternalFrameUI;
33
34 public class GSplitFrame extends JInternalFrame
35 {
36   private static final long serialVersionUID = 1L;
37
38   private GAlignFrame topFrame;
39
40   private GAlignFrame bottomFrame;
41
42   private JSplitPane splitPane;
43
44   /**
45    * Constructor
46    * 
47    * @param top
48    * @param bottom
49    */
50   public GSplitFrame(GAlignFrame top, GAlignFrame bottom)
51   {
52     this.topFrame = top;
53     this.bottomFrame = bottom;
54
55     hideTitleBars();
56
57     addSplitPane();
58   }
59
60   /**
61    * Create and add the split pane containing the top and bottom components.
62    */
63   protected void addSplitPane()
64   {
65     splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topFrame,
66             bottomFrame);
67     splitPane.setVisible(true);
68     final double ratio = bottomFrame.getHeight() == 0 ? 0.5d : topFrame
69             .getHeight()
70             / (double) (topFrame.getHeight() + bottomFrame.getHeight());
71     splitPane.setDividerLocation(ratio);
72     splitPane.setResizeWeight(ratio);
73     splitPane.setDividerSize(5);
74     add(splitPane);
75   }
76
77   /**
78    * Try to hide the title bars as a waste of precious space.
79    * 
80    * @see http
81    *      ://stackoverflow.com/questions/7218971/java-method-works-on-windows
82    *      -but-not-macintosh -java
83    */
84   protected void hideTitleBars()
85   {
86     if (new Platform().isAMac())
87     {
88       // this saves some space - but doesn't hide the title bar
89       topFrame.putClientProperty("JInternalFrame.isPalette", true);
90       // topFrame.getRootPane().putClientProperty("Window.style", "small");
91       bottomFrame.putClientProperty("JInternalFrame.isPalette", true);
92     }
93     else
94     {
95       ((BasicInternalFrameUI) topFrame.getUI()).setNorthPane(null);
96       ((BasicInternalFrameUI) bottomFrame.getUI()).setNorthPane(null);
97     }
98   }
99
100   public GAlignFrame getTopFrame()
101   {
102     return topFrame;
103   }
104
105   public GAlignFrame getBottomFrame()
106   {
107     return bottomFrame;
108   }
109
110   /**
111    * Returns the split pane component the mouse is in, or null if neither.
112    * 
113    * @return
114    */
115   protected GAlignFrame getFrameAtMouse()
116   {
117     Point loc = MouseInfo.getPointerInfo().getLocation();
118
119     if (isIn(loc, splitPane.getTopComponent()))
120     {
121       return getTopFrame();
122     }
123     else if (isIn(loc, splitPane.getBottomComponent()))
124     {
125       return getBottomFrame();
126     }
127     return null;
128   }
129
130   private boolean isIn(Point loc, Component comp)
131   {
132     if (!comp.isVisible())
133     {
134       return false;
135     }
136     Point p = comp.getLocationOnScreen();
137     Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight());
138     return r.contains(loc);
139   }
140
141   /**
142    * Make the complement of the specified split component visible or hidden,
143    * adjusting the position of the split divide.
144    */
145   public void setComplementVisible(Object alignFrame, boolean show)
146   {
147     if (alignFrame == this.topFrame)
148     {
149       this.bottomFrame.setVisible(show);
150     }
151     else if (alignFrame == this.bottomFrame)
152     {
153       this.topFrame.setVisible(show);
154     }
155     if (show)
156     {
157       // SplitPane needs nudging to restore 50-50 split
158       // TODO save/restore other ratios
159       splitPane.setDividerLocation(0.5d);
160     }
161     validate();
162   }
163 }