}
/**
- * Explode the views in the given frame into separate AlignFrame windows.
+ * Explode the views in the given SplitFrame into separate SplitFrame windows.
+ * This respects (remembers) any previous 'exploded geometry' i.e. the size
+ * and location last time the view was expanded (if any). However it does not
+ * remember the split pane divider location - this is set to match the
+ * 'exploding' frame.
*
* @param sf
*/
*/
AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
AlignFrame newTopFrame = new AlignFrame(topPanel);
- newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
- AlignFrame.DEFAULT_HEIGHT));
+ newTopFrame.setSize(oldTopFrame.getSize());
newTopFrame.setVisible(true);
AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
- newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
- AlignFrame.DEFAULT_HEIGHT));
+ newBottomFrame.setSize(oldBottomFrame.getSize());
newBottomFrame.setVisible(true);
topPanel.av.setGatherViewsHere(false);
bottomPanel.av.setGatherViewsHere(false);
view.setViewName(av.viewName);
view.setGatheredViews(av.isGatherViewsHere());
- Rectangle position = ap.av.getExplodedGeometry();
- if (position == null)
+ Rectangle size = ap.av.getExplodedGeometry();
+ Rectangle position = size;
+ if (size == null)
{
- position = ap.alignFrame.getBounds();
+ size = ap.alignFrame.getBounds();
+ if (av.getCodingComplement() != null)
+ {
+ position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
+ .getBounds();
+ }
+ else
+ {
+ position = size;
+ }
}
view.setXpos(position.x);
view.setYpos(position.y);
- view.setWidth(position.width);
- view.setHeight(position.height);
+
+ view.setWidth(size.width);
+ view.setHeight(size.height);
view.setStartRes(av.startRes);
view.setStartSeq(av.startSeq);
int width = (int) dnaFrame.getBounds().getWidth();
int height = (int) (dnaFrame.getBounds().getHeight()
+ proteinFrame.getBounds().getHeight() + 50);
+
+ /*
+ * SplitFrame location is saved to both enclosed frames
+ */
+ splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
Desktop.addInternalFrame(splitFrame, title, width, height);
/*
// about 50 pixels for the SplitFrame's title bar etc
int height = ((AlignFrame) getTopFrame()).getHeight()
+ ((AlignFrame) getBottomFrame()).getHeight() + 50;
- // about 65 pixels for Desktop decorators on Windows
- height = Math.min(height, Desktop.instance.getHeight() - 65);
+ height = fitHeightToDesktop(height);
setSize(width, height);
adjustLayout();
}
/**
+ * Reduce the height if too large to fit in the Desktop. Also adjust the
+ * divider location in proportion.
+ *
+ * @param height
+ * in pixels
+ * @return original or reduced height
+ */
+ public int fitHeightToDesktop(int height)
+ {
+ // allow about 65 pixels for Desktop decorators on Windows
+
+ int newHeight = Math.min(height, Desktop.instance.getHeight() - 65);
+ if (newHeight != height)
+ {
+ int oldDividerLocation = getDividerLocation();
+ setDividerLocation(oldDividerLocation * newHeight / height);
+ }
+ return newHeight;
+ }
+
+ /**
* Set the top and bottom frames to listen to each others Commands (e.g. Edit,
* Order).
*/
public class GSplitFrame extends JInternalFrame
{
+ private static final int DIVIDER_SIZE = 5;
+
private static final long serialVersionUID = 1L;
private GAlignFrame topFrame;
private JSplitPane splitPane;
+ /*
+ * proportional position of split divider; saving this allows it to be
+ * restored after hiding one half and resizing
+ */
+ private double dividerRatio;
+
/**
* Constructor
*
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topFrame,
bottomFrame);
splitPane.setVisible(true);
- final double ratio = bottomFrame.getHeight() == 0 ? 0.5d : topFrame
- .getHeight()
- / (double) (topFrame.getHeight() + bottomFrame.getHeight());
- splitPane.setDividerLocation(ratio);
- splitPane.setResizeWeight(ratio);
- splitPane.setDividerSize(5);
+
+ /*
+ * set divider split at 50:50, or restore saved split if loading from
+ * project
+ */
+ int topFrameHeight = topFrame.getHeight();
+ splitPane.setDividerSize(DIVIDER_SIZE);
+ if (topFrameHeight == 0)
+ {
+ setRelativeDividerLocation(0.5d); // as a proportion
+ }
+ else
+ {
+ int dividerPosition = topFrameHeight + DIVIDER_SIZE / 2;
+ splitPane.setDividerLocation(dividerPosition); // absolute position
+ }
+ splitPane.setResizeWeight(0.5d);
add(splitPane);
}
}
/**
- * Make the complement of the specified split component visible or hidden,
- * adjusting the position of the split divide.
+ * Makes the complement of the specified split component visible or hidden,
+ * restoring or saving the position of the split divide.
*/
public void setComplementVisible(Object alignFrame, boolean show)
{
+ /*
+ * save divider ratio on hide, restore on show
+ */
+ if (show)
+ {
+ setRelativeDividerLocation(dividerRatio);
+ }
+ else
+ {
+ this.dividerRatio = splitPane.getDividerLocation()
+ / (double) (splitPane.getHeight() - splitPane
+ .getDividerSize());
+ }
+
if (alignFrame == this.topFrame)
{
this.bottomFrame.setVisible(show);
{
this.topFrame.setVisible(show);
}
- if (show)
- {
- // SplitPane needs nudging to restore 50-50 split
- // TODO save/restore other ratios
- splitPane.setDividerLocation(0.5d);
- }
+
validate();
}
+
+ /**
+ * Set the divider location as a proportion (0 <= r <= 1) of the height <br>
+ * Warning: this overloads setDividerLocation(int), and getDividerLocation()
+ * returns the int (pixel count) value
+ *
+ * @param r
+ */
+ public void setRelativeDividerLocation(double r)
+ {
+ this.dividerRatio = r;
+ splitPane.setDividerLocation(r);
+ }
+
+ /**
+ * Sets the divider location (in pixels from top)
+ *
+ * @return
+ */
+ protected void setDividerLocation(int p)
+ {
+ splitPane.setDividerLocation(p);
+ }
+
+ /**
+ * Returns the divider location (in pixels from top)
+ *
+ * @return
+ */
+ protected int getDividerLocation()
+ {
+ return splitPane.getDividerLocation();
+ }
}