com.jidesoft.swing.JideSplitPaneLayout Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jide-oss Show documentation
Show all versions of jide-oss Show documentation
JIDE Common Layer (Professional Swing Components)
/*
* @(#)JideSplitPaneLayout.java 7/7/2009
*
* Copyright 2002 - 2009 JIDE Software Inc. All rights reserved.
*
*/
package com.jidesoft.swing;
import com.jidesoft.utils.SystemInfo;
import javax.swing.*;
import java.awt.*;
import java.util.*;
/**
* Layout manager used by JideSplitPane.
*/
public class JideSplitPaneLayout extends JideBoxLayout {
private static final long serialVersionUID = -1826651835409198865L;
public JideSplitPaneLayout(Container target) {
super(target);
setResetWhenInvalidate(false);
}
public JideSplitPaneLayout(Container target, int axis) {
super(target, axis);
setResetWhenInvalidate(false);
}
public JideSplitPaneLayout(Container target, int axis, int gap) {
super(target, axis, gap);
setResetWhenInvalidate(false);
}
int getDividerLocation(int index) {
if (_componentSizes == null) {
return -1;
}
if (index < 0 || (index + 1) << 1 >= _componentSizes.length)
return -1;
boolean ltr = _target.getComponentOrientation().isLeftToRight();
boolean reversed = !ltr && ((JideSplitPane) _target).getOrientation() == JideSplitPane.HORIZONTAL_SPLIT;
int location = 0;
if (reversed) {
for (int i = _componentSizes.length - 1; i >= (index * 2) + 1; i--)
location += _componentSizes[i];
}
else {
for (int i = 0; i < (index * 2) + 1; i++)
location += _componentSizes[i];
}
Insets insets = _target.getInsets();
if (insets != null) {
if (((JideSplitPane) _target).getOrientation() == JideSplitPane.HORIZONTAL_SPLIT) {
location += reversed ? insets.right : insets.left;
}
else {
location += insets.top;
}
}
return location;
}
@SuppressWarnings({"RedundantCast"})
int setDividerLocation(int index, int location, boolean isOriginator) {
int oldLocation = getDividerLocation(index);
if (oldLocation == -1 || oldLocation == location)
return -1;
boolean ltr = _target.getComponentOrientation().isLeftToRight();
boolean reversed = !ltr && ((JideSplitPane) _target).getOrientation() == JideSplitPane.HORIZONTAL_SPLIT;
int prevIndex = reversed ? 2 * index + 2 : 2 * index;
int nextIndex = reversed ? 2 * index : 2 * index + 2;
int nextDividerIndex = reversed ? index - 1 : index + 1;
int prevDividerIndex = reversed ? index + 1 : index - 1;
int flexibleNextIndex;
int flexiblePrevIndex;
java.util.List componentIndexChanged = new ArrayList();
if (reversed) {
while (nextIndex >= 0 && !isPaneVisible(nextIndex)) {
nextIndex -= 2;
nextDividerIndex --;
}
while (prevIndex < _componentSizes.length && !isPaneVisible(prevIndex)) {
prevIndex += 2;
prevDividerIndex ++;
}
flexibleNextIndex = nextIndex;
while (flexibleNextIndex >= 0 &&
(getConstraintMap().get(_target.getComponent(flexibleNextIndex)) == JideBoxLayout.FIX || !isPaneVisible(flexibleNextIndex))) {
flexibleNextIndex -= 2;
}
if (flexibleNextIndex < 0) {
return -1;
}
flexiblePrevIndex = prevIndex;
while (flexiblePrevIndex < _componentSizes.length &&
(getConstraintMap().get(_target.getComponent(flexiblePrevIndex)) == JideBoxLayout.FIX || !isPaneVisible(flexiblePrevIndex))) {
flexiblePrevIndex += 2;
}
if (flexiblePrevIndex >= _componentSizes.length) {
return -1;
}
}
else {
while (nextIndex < _componentSizes.length && !isPaneVisible(nextIndex)) {
nextIndex += 2;
nextDividerIndex ++;
}
while (prevIndex >= 0 && !isPaneVisible(prevIndex)) {
prevIndex -= 2;
prevDividerIndex --;
}
flexibleNextIndex = nextIndex;
while (flexibleNextIndex < _componentSizes.length &&
(getConstraintMap().get(_target.getComponent(flexibleNextIndex)) == JideBoxLayout.FIX || !isPaneVisible(flexibleNextIndex))) {
flexibleNextIndex += 2;
}
if (flexibleNextIndex >= _componentSizes.length) {
return -1;
}
flexiblePrevIndex = prevIndex;
while (flexiblePrevIndex >= 0 &&
(getConstraintMap().get(_target.getComponent(flexiblePrevIndex)) == JideBoxLayout.FIX || !isPaneVisible(flexiblePrevIndex))) {
flexiblePrevIndex -= 2;
}
if (flexiblePrevIndex < 0) {
return -1;
}
}
if (isOriginator
&& getConstraintMap().get(_target.getComponent(nextIndex)) == JideBoxLayout.FIX
&& getConstraintMap().get(_target.getComponent(prevIndex)) == JideBoxLayout.FIX) {
return -1;
}
if (location > oldLocation) {
int size = _componentSizes[2 * index + 1];
if (getConstraintMap().get(_target.getComponent(nextIndex)) == JideBoxLayout.FIX) {
size += _componentSizes[nextIndex];
}
else {
if (((JideSplitPane) _target).getOrientation() == JideSplitPane.HORIZONTAL_SPLIT) {
size += _target.getComponent(nextIndex).getMinimumSize().getWidth();
}
else {
size += _target.getComponent(nextIndex).getMinimumSize().getHeight();
}
}
int nextDividerLocation = getDividerLocation(nextDividerIndex);
if (nextDividerLocation < 0) {
if (((JideSplitPane) _target).getOrientation() == JideSplitPane.HORIZONTAL_SPLIT) {
location = Math.min(location, _target.getWidth() - size);
}
else {
location = Math.min(location, _target.getHeight() - size);
}
}
else if (location + size > nextDividerLocation) {
int actualLocation = setDividerLocation(nextDividerIndex, location + size, false);
if (actualLocation == -1) {
return -1;
}
location = actualLocation - size;
}
if (getConstraintMap().get(_target.getComponent(nextIndex)) != JideBoxLayout.FIX) {
_componentSizes[nextIndex] -= location - oldLocation;
componentIndexChanged.add(nextIndex);
}
if (isOriginator) {
_componentSizes[flexiblePrevIndex] += location - oldLocation;
componentIndexChanged.add(flexiblePrevIndex);
}
else if (getConstraintMap().get(_target.getComponent(prevIndex)) != JideBoxLayout.FIX) {
_componentSizes[prevIndex] += location - oldLocation;
componentIndexChanged.add(prevIndex);
}
}
else if (location < oldLocation) {
int size = 0;
if (prevDividerIndex >= 0) {
size = _componentSizes[prevIndex - 1];
}
if (getConstraintMap().get(_target.getComponent(prevIndex)) == JideBoxLayout.FIX) {
size += _componentSizes[prevIndex];
}
else {
if (((JideSplitPane) _target).getOrientation() == JideSplitPane.HORIZONTAL_SPLIT) {
size += _target.getComponent(prevIndex).getMinimumSize().getWidth();
}
else {
size += _target.getComponent(prevIndex).getMinimumSize().getHeight();
}
}
int prevDividerLocation = getDividerLocation(prevDividerIndex);
if (prevDividerLocation < 0) {
location = Math.max(location, size);
}
else if (location - size < prevDividerLocation) {
int actualLocation = setDividerLocation(prevDividerIndex, location - size, false);
if (actualLocation == -1) {
return -1;
}
location = actualLocation + size;
}
if (getConstraintMap().get(_target.getComponent(prevIndex)) != JideBoxLayout.FIX) {
_componentSizes[prevIndex] -= oldLocation - location;
componentIndexChanged.add(prevIndex);
}
if (isOriginator) {
_componentSizes[flexibleNextIndex] += oldLocation - location;
componentIndexChanged.add(flexibleNextIndex);
}
else if (getConstraintMap().get(_target.getComponent(nextIndex)) != JideBoxLayout.FIX) {
_componentSizes[nextIndex] += oldLocation - location;
componentIndexChanged.add(nextIndex);
}
}
if (SystemInfo.isJdk15Above()) {
if (_target instanceof JideSplitPane) {
((JideSplitPane) _target).firePropertyChange(JideSplitPane.PROPERTY_DIVIDER_LOCATION, oldLocation, location);
}
else {
_target.firePropertyChange(JideSplitPane.PROPERTY_DIVIDER_LOCATION, oldLocation, location);
}
}
((JideSplitPane) _target).revalidate();
if (((JideSplitPane) _target).isProportionalLayout()) {
replaceProportions();
return location;
}
if (((JideSplitPane) _target).getOrientation() == JideSplitPane.HORIZONTAL_SPLIT) {
for (int changedIndex = 0; changedIndex < _target.getComponentCount(); changedIndex++) {
Component component = _target.getComponent(changedIndex);
if (component instanceof JComponent && !(component instanceof JideSplitPaneDivider)) {
((JComponent) component).setPreferredSize(new Dimension(_componentSizes[changedIndex], component.getPreferredSize().height));
}
}
}
else {
for (int changedIndex = 0; changedIndex < _target.getComponentCount(); changedIndex++) {
Component component = _target.getComponent(changedIndex);
if (component instanceof JComponent && !(component instanceof JideSplitPaneDivider)) {
((JComponent) component).setPreferredSize(new Dimension(component.getPreferredSize().width, _componentSizes[changedIndex]));
}
}
}
return location;
}
private boolean isPaneVisible(int index) {
// Considering collapse/expand feature, we need consider the visibility of divider as well
return index < _componentSizes.length && (_componentSizes[index] != 0 || index - 1 < 0 || _componentSizes[index - 1] != 0);
}
/**
* Uses the component sizes to generate a new array of proportions, and replaces the existing one.
*/
private void replaceProportions() {
((JideSplitPane) _target).setProportions(deduceProportions());
}
/**
* Uses the component sizes to generate a new array of proportions.
*
* @return a new array of proportions
*/
private double[] deduceProportions() {
double total = 0.0; // Total height or width of contained panes (not including dividers)
for (int i = 0; i < _componentSizes.length; i += 2) // Note we're skipping dividers
total += _componentSizes[i];
double[] newProportions;
if (total == 0.0)
newProportions = null;
else {
newProportions = new double[(_componentSizes.length - 1) / 2];
for (int i = 0; i < newProportions.length; ++i)
newProportions[i] = _componentSizes[i * 2] / total;
}
return newProportions;
}
// For proportional layouts, override the key box layout method:
@Override
protected boolean calculateComponentSizes(int availableSize, int startIndex, int endIndex) {
// Just go to super for non-proportional layout, or if there are no more
// than one component.
if (!((JideSplitPane) _target).isProportionalLayout()
|| _target.getComponentCount() <= 1)
return super.calculateComponentSizes(availableSize, startIndex, endIndex);
// If we have no set proportions, either call super to get initial
// proportions or set them up as even.
if (((JideSplitPane) _target).getProportions() == null) {
if (!((JideSplitPane) _target).isInitiallyEven()) {
if (!super.calculateComponentSizes(availableSize, startIndex, endIndex))
return false;
// Luke's change
// David: We now wait to set proportions until the user sets them directly. Otherwise recreated
// docked frames end up with tiny sizes instead of using preferred size, since they are
// initially added to their ContainerContainers without their contents.
// _proportions = deduceProportions(); // Note no call to setProportions: no event
//
return true;
}
// What remains is the "initially even" logic:
int c = ((JideSplitPane) _target).getPaneCount();
double[] p = new double[c - 1];
for (int i = 0; i < p.length; ++i)
p[i] = 1.0 / c;
((JideSplitPane) _target).internalSetProportions(p); // Note no call to setProportions: no event may be sent here
}
// Spin through the dividers, setting up their sizes and subtracting from available.
for (int i = 1; i < _target.getComponentCount(); i += 2) {
if (_target.getComponent(i).isVisible())
_componentSizes[i] = ((JideSplitPane) _target).getDividerSize();
availableSize -= _componentSizes[i];
}
if (availableSize < 0)
return false;
// Then spin through the panes and set their sizes according to the
// proportions.
double[] proportions = ((JideSplitPane) _target).getProportions();
// double last = 1.0;
// for (double p : proportions) last -= p;
// double total = 0.0;
// for (int i = 0; i < getComponentCount(); i += 2) {
// int j = i / 2;
// if (getComponent(i).isVisible())
// total += (j < proportions.length) ? proportions[j] : last;
// }
int size = availableSize;
for (int i = 0; i < proportions.length; ++i) {
int j = i * 2;
if (_target.getComponent(j).isVisible()) {
double d = proportions[i]/* / total*/;
if (d <= 1.0)
_componentSizes[j] = (int) (0.5 + size * d);
}
availableSize -= _componentSizes[j];
}
// Now set the last one to whatever is left over.
if (availableSize < 0)
return false;
_componentSizes[_componentSizes.length - 1] = availableSize;
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy