bcd5f646109f8bf16ea3ab81f8ad7dd209a99611
[jalview.git] / src / jalview / jbgui / GSplitFrame.java
1 package jalview.jbgui;
2
3 import java.awt.Component;
4 import java.awt.MouseInfo;
5 import java.awt.Point;
6 import java.awt.Rectangle;
7
8 import javax.swing.JInternalFrame;
9 import javax.swing.JSplitPane;
10 import javax.swing.plaf.basic.BasicInternalFrameUI;
11
12 import jalview.util.Platform;
13
14 public class GSplitFrame extends JInternalFrame
15 {
16   private static final long serialVersionUID = 1L;
17
18   private GAlignFrame topFrame;
19
20   private GAlignFrame bottomFrame;
21
22   private JSplitPane splitPane;
23
24   /**
25    * Constructor
26    * 
27    * @param top
28    * @param bottom
29    */
30   public GSplitFrame(GAlignFrame top, GAlignFrame bottom)
31   {
32     this.topFrame = top;
33     this.bottomFrame = bottom;
34
35     hideTitleBars();
36
37     addSplitPane();
38   }
39
40   /**
41    * Create and add the split pane containing the top and bottom components.
42    */
43   protected void addSplitPane()
44   {
45     splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topFrame,
46             bottomFrame);
47     splitPane.setVisible(true);
48     final double ratio = bottomFrame.getHeight() == 0 ? 0.5d : topFrame
49             .getHeight()
50             / (double) (topFrame.getHeight() + bottomFrame.getHeight());
51     splitPane.setDividerLocation(ratio);
52     splitPane.setResizeWeight(ratio);
53     splitPane.setDividerSize(5);
54     add(splitPane);
55   }
56
57   /**
58    * Try to hide the title bars as a waste of precious space.
59    * 
60    * @see http
61    *      ://stackoverflow.com/questions/7218971/java-method-works-on-windows
62    *      -but-not-macintosh -java
63    */
64   protected void hideTitleBars()
65   {
66     if (new Platform().isAMac())
67     {
68       // this saves some space - but doesn't hide the title bar
69       topFrame.putClientProperty("JInternalFrame.isPalette", true);
70       // topFrame.getRootPane().putClientProperty("Window.style", "small");
71       bottomFrame.putClientProperty("JInternalFrame.isPalette", true);
72     }
73     else
74     {
75       ((BasicInternalFrameUI) topFrame.getUI()).setNorthPane(null);
76       ((BasicInternalFrameUI) bottomFrame.getUI()).setNorthPane(null);
77     }
78   }
79
80   public GAlignFrame getTopFrame()
81   {
82     return topFrame;
83   }
84
85   public GAlignFrame getBottomFrame()
86   {
87     return bottomFrame;
88   }
89
90   /**
91    * Returns the split pane component the mouse is in, or null if neither.
92    * 
93    * @return
94    */
95   protected GAlignFrame getFrameAtMouse()
96   {
97     Point loc = MouseInfo.getPointerInfo().getLocation();
98     
99     if (isIn(loc, splitPane.getTopComponent()))
100     {
101       return getTopFrame();
102     }
103     else if (isIn(loc, splitPane.getBottomComponent()))
104     {
105       return getBottomFrame();
106     }
107     return null;
108   }
109
110   private boolean isIn(Point loc, Component comp)
111   {
112     if (!comp.isVisible())
113     {
114       return false;
115     }
116     Point p = comp.getLocationOnScreen();
117     Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight());
118     return r.contains(loc);
119   }
120
121   /**
122    * Make the complement of the specified split component visible or hidden,
123    * adjusting the position of the split divide.
124    */
125   public void setComplementVisible(Object alignFrame, boolean show)
126   {
127     if (alignFrame == this.topFrame)
128     {
129       this.bottomFrame.setVisible(show);
130     }
131     else if (alignFrame == this.bottomFrame)
132     {
133       this.topFrame.setVisible(show);
134     }
135     if (show)
136     {
137       // SplitPane needs nudging to restore 50-50 split
138       // TODO save/restore other ratios
139       splitPane.setDividerLocation(0.5d);
140     }
141     validate();
142   }
143 }