📄 mosaiclayout.java
字号:
m_layout.defaultCursor();
}
//
// p a i n t
//
protected void paint( Graphics g )
{
g.clearRect( m_orgx, m_orgy, m_size.width, m_size.height );
}
//
// p r i n t
//
protected void print( String indent )
{
System.out.println( indent + "leaf node " + m_coordStack.toString() );
super.print( indent + "o ");
}
}
///////////////////////////////////////////////////////////////
//
// M o s a i c I n t e r i o r N o d e
//
///////////////////////////////////////////////////////////////
final class MosaicInteriorNode extends MosaicNode
{
// Every interior node forms a rectangular grid with m_cols
// columns and m_rows rows. As children get added to the node,
// the grid grows dynamically; it represents at all times the
// smallest rectangular grid that contains all the children
// as well as the gridpoint (0,0).
protected int m_cols = 0;
protected int m_rows = 0;
// For each column and row (called "slices"), size and weight
// information is stored in MosaicSlice objects.
protected MosaicSlice m_col[] = null;
protected MosaicSlice m_row[] = null;
// The grid itself is stored in the following array.
protected MosaicNode m_node[][] = null;
// The size of the sash handles is looked up in the layout
// manager and stored here. A size of zero means sashes are
// not available.
protected int m_sashSize = 0;
// If the node is active (some of its sashes have been grabbed),
// the position of the relevant sash(es) is/are stored here.
protected int m_activeColSash = 0;
protected int m_activeRowSash = 0;
// The following values are correction factors; their function
// is to avoid the jumping of the sashes. They store the
// relative position of the mouse cursor in the sashes when
// the mouse button is first pressed (event MOUSE_DOWN).
protected int m_colSashOfs = 0;
protected int m_rowSashOfs = 0;
//
// M o s a i c I n t e r i o r N o d e
//
protected MosaicInteriorNode( MosaicLayout layout )
{
super( layout );
}
//
// i n i t i a l i z e G e o m e t r y
//
protected void initializeGeometry()
{
int i, j;
m_minSize = new Dimension( 0, 0 );
m_prefSize = new Dimension( 0, 0 );
m_weightx = 0;
m_weighty = 0;
if( m_cols == 0 || m_rows == 0 ) {
m_size = new Dimension( 0, 0 );
return;
}
m_col = new MosaicSlice[m_cols];
m_row = new MosaicSlice[m_rows];
for( j = 0; j < m_rows; ++j )
m_row[j] = new MosaicSlice();
for( i = 0; i < m_cols; ++i ) {
m_col[i] = new MosaicSlice();
for( j = 0; j < m_rows; ++j ) {
MosaicNode N = m_node[i][j];
if( N != null ) {
N.initializeGeometry();
m_col[i].expand( N.m_minSize.width, N.m_prefSize.width );
m_row[j].expand( N.m_minSize.height, N.m_prefSize.height );
}
}
}
adjustWeight();
createSashes();
m_size = new Dimension( m_prefSize );
}
//
// a d j u s t W e i g h t
//
// At this point, the minimum and preferred sizes of each slice
// is known. The weight of each slice is determined and normalized
// such that the weight sums up to one in both dimensions.
protected void adjustWeight()
{
int i, j;
for( i = 0; i < m_cols; ++i ) {
for( j = 0; j < m_rows; ++j ) {
MosaicNode N = m_node[i][j];
if( N != null ) {
m_col[i].m_weight += N.m_weightx * N.m_prefSize.width;
m_row[j].m_weight += N.m_weighty * N.m_prefSize.height;
}
}
}
for( i = 0; i < m_cols; ++i ) {
m_col[i].m_size = m_col[i].m_prefSize;
m_minSize.width += m_col[i].m_minSize;
m_prefSize.width += m_col[i].m_prefSize;
if( m_col[i].m_sizeSum > 1 )
m_col[i].m_weight /= m_col[i].m_sizeSum;
m_weightx += m_col[i].m_weight;
}
if( m_weightx == 0 ) {
for( i = 0; i < m_cols; ++i )
m_col[i].m_weight = 1.0 / m_cols;
}
else {
for( i = 0; i < m_cols; ++i )
m_col[i].m_weight /= m_weightx;
}
for( j = 0; j < m_rows; ++j ) {
m_row[j].m_size = m_row[j].m_prefSize;
m_minSize.height += m_row[j].m_minSize;
m_prefSize.height += m_row[j].m_prefSize;
if( m_row[j].m_sizeSum > 1 )
m_row[j].m_weight /= m_row[j].m_sizeSum;
m_weighty += m_row[j].m_weight;
}
if( m_weighty == 0 ) {
for( j = 0; j < m_rows; ++j )
m_row[j].m_weight = 1.0 / m_rows;
}
else {
for( j = 0; j < m_rows; ++j )
m_row[j].m_weight /= m_weighty;
}
}
//
// c r e a t e S a s h e s
//
protected void createSashes()
{
int i, j, t;
m_sashSize = m_layout.getSashSize( m_parent == null );
if( m_sashSize == 0 )
return;
t = ( m_cols - 1 ) * m_sashSize;
m_minSize.width += t;
m_prefSize.width += t;
t = ( m_rows - 1 ) * m_sashSize;
m_minSize.height += t;
m_prefSize.height += t;
}
//
// f i n a l i z e G e o m e t r y
//
protected void finalizeGeometry( int orgx, int orgy,
int width, int height, boolean liveDrag )
{
int i, j;
m_orgx = orgx;
m_orgy = orgy;
Dimension newSize = new Dimension( width, height );
if( m_cols > 0 ) {
if( width <= m_minSize.width ) {
for( i = 0; i < m_cols; ++i )
m_col[i].m_size = m_col[i].m_minSize;
newSize.width = m_minSize.width;
}
else {
int dx = width - m_size.width;
if( dx > 0 )
distributeExtraSpace( dx, m_cols, m_col );
else
if( dx < 0 )
collectExtraSpace( -dx, m_cols, m_col );
}
m_col[0].m_org = m_orgx;
for( i = 1; i < m_cols; ++i ) {
m_col[i].m_org =
m_col[i - 1].m_org + m_col[i - 1].m_size + m_sashSize;
}
}
if( m_rows > 0 ) {
if( height <= m_minSize.height ) {
for( j = 0; j < m_rows; ++j )
m_row[j].m_size = m_row[j].m_minSize;
newSize.height = m_minSize.height;
}
else {
int dy = height - m_size.height;
if( dy > 0 )
distributeExtraSpace( dy, m_rows, m_row );
else
if( dy < 0 )
collectExtraSpace( -dy, m_rows, m_row );
}
m_row[0].m_org = m_orgy;
for( j = 1; j < m_rows; ++j ) {
m_row[j].m_org =
m_row[j - 1].m_org + m_row[j - 1].m_size + m_sashSize;
}
}
m_size = newSize;
for( i = 0; i < m_cols; ++i ) {
for( j = 0; j < m_rows; ++j ) {
if( m_node[i][j] != null ) {
m_node[i][j].finalizeGeometry( m_col[i].m_org, m_row[j].m_org,
m_col[i].m_size, m_row[j].m_size, liveDrag );
}
}
}
}
//
// d i s t r i b u t e E x t r a S p a c e
//
// !!!!!! Some useless print statements added. Algorithm here is
// adequate, but could do with an overhaul. Should not "remember"
// so much what previous configuration was, in case of non-zero
// weights. AMB 06/05/98.
protected void distributeExtraSpace( int extraSpace, int numOfSlices,
MosaicSlice[] slice )
{
int i, d, restSpace;
double w;
restSpace = extraSpace;
// System.out.println("dES: "+extraSpace);
// First bring all components whose weight is positive
// to their preferred size.
while( restSpace > 0 ) {
extraSpace = restSpace;
w = 0;
for( i = 0; i < numOfSlices; ++i ) {
if( slice[i].m_size < slice[i].m_prefSize )
w += slice[i].m_weight;
}
if( w == 0 )
break;
for( i = 0; i < numOfSlices; ++i ) {
if( slice[i].m_size < slice[i].m_prefSize &&
slice[i].m_weight > 0 ) {
d = (int) Math.ceil( slice[i].m_weight / w * extraSpace );
// System.out.println("i: "+i+"restSpace = "+restSpace+", delta = "+d);
if( d > restSpace )
d = restSpace;
if( slice[i].m_size + d > slice[i].m_prefSize )
d = slice[i].m_prefSize - slice[i].m_size;
slice[i].m_size += d;
restSpace -= d;
}
}
}
// System.out.println("Finished makepref: "+restSpace);
// Then distribute the rest proportionally among all
// components whose weight is positive.
if( restSpace > 0 ) {
extraSpace = restSpace;
for( i = 0; i < numOfSlices; ++i ) {
d = (int) Math.ceil( slice[i].m_weight * extraSpace );
// System.out.println("i: "+i+"restSpace = "+restSpace+", delta = "+d);
if( d > restSpace )
d = restSpace;
slice[i].m_size += d;
restSpace -= d;
}
}
}
//
// c o l l e c t E x t r a S p a c e
//
protected void collectExtraSpace( int extraSpace, int numOfSlices,
MosaicSlice[] slice )
{
int i, n, d, d1, restSpace;
double w;
restSpace = extraSpace;
// System.out.println("cES: "+extraSpace);
// First steal space from all slices that are larger
// than their preferred size, and whose weight is greater
// than zero.
while( restSpace > 0 ) {
extraSpace = restSpace;
w = 0;
for( i = 0; i < numOfSlices; ++i ) {
if( slice[i].m_size > slice[i].m_prefSize )
w += slice[i].m_weight;
}
if( w == 0 )
break;
for( i = 0; i < numOfSlices; ++i ) {
if( slice[i].m_size > slice[i].m_prefSize &&
slice[i].m_weight > 0 ) {
d = (int) Math.ceil( slice[i].m_weight / w * extraSpace );
// System.out.println("i: "+i+"restSpace = "+restSpace+", delta = "+d);
if( d > restSpace )
d = restSpace;
if( slice[i].m_size - d < slice[i].m_prefSize )
d = slice[i].m_size - slice[i].m_prefSize;
slice[i].m_size -= d;
restSpace -= d;
}
}
}
// System.out.println("Finished makepref: "+restSpace);
// Now collect from all slices that are larger than their
// minimum size, and whose weight is greater than zero.
while( restSpace > 0 ) {
extraSpace = restSpace;
w = 0;
for( i = 0; i < numOfSlices; ++i ) {
if( slice[i].m_size > slice[i].m_minSize )
w += slice[i].m_weight;
}
if( w == 0 )
break;
for( i = 0; i < numOfSlices; ++i ) {
if( slice[i].m_size > slice[i].m_minSize &&
slice[i].m_weight > 0 ) {
d = (int) Math.ceil( slice[i].m_weight / w * extraSpace );
// System.out.println("i: "+i+"restSpace = "+restSpace+", delta = "+d);
if( d > restSpace )
d = restSpace;
if( slice[i].m_size - d < slice[i].m_minSize )
d = slice[i].m_size - slice[i].m_minSize;
slice[i].m_size -= d;
restSpace -= d;
}
}
}
// System.out.println("Finished makemin: "+restSpace);
// Now we need another round for the case where the slices
// that have nonzero weight are already at their minimum
// size, and all other slices have zero weight.
while( restSpace > 0 ) {
n = 0;
for( i = 0; i < numOfSlices; ++i ) {
if( slice[i].m_size > slice[i].m_minSize )
++n;
}
d1 = ( restSpace + n - 1 ) / n;
for( i = 0; i < numOfSlices; ++i ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -