📄 mosaiclayout.java
字号:
if( slice[i].m_size > slice[i].m_minSize ) {
d = Math.min( restSpace, d1 );
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;
}
}
}
}
//
// e n s u r e C a p a c i t y
//
// Makes the interior node big enough to contain grid
// position (col,row).
protected MosaicInteriorNode ensureCapacity( int col, int row )
{
int h1Col, h2Col, h1Row, h2Row;
h1Col = 3 * ( ( m_cols + 2 ) / 3 );
if( m_cols <= col ) {
int newCols = col + 1;
m_cols = newCols;
h2Col = 3 * ( ( newCols + 2 ) / 3 );
}
else {
h2Col = h1Col;
}
h1Row = 3 * ( ( m_rows + 2 ) / 3 );
if( m_rows <= row ) {
int newRows = row + 1;
m_rows = newRows;
h2Row = 3 * ( ( newRows + 2 ) / 3 );
}
else {
h2Row = h1Row;
}
if( h1Col < h2Col || h1Row < h2Row ) {
MosaicNode[][] newNode = new MosaicNode[h2Col][h2Row];
for( int i = 0; i < h1Col; ++i ) {
for( int j = 0; j < h1Row; ++j )
newNode[i][j] = m_node[i][j];
}
m_node = newNode;
}
return this;
}
//
// h a n d l e E v e n t
//
protected void handleEvent( Event evt )
{
int i, j, inCol, afterCol, inRow, afterRow, cursor;
// Find out whether the mouse is position within
// a column (inCol >= 0) or between columns, on a
// sash (afterCol >= 0).
inCol = afterCol = -1;
for( i = 1; i < m_cols; ++i ) {
if( evt.x < m_col[i].m_org - m_sashSize ) {
inCol = i - 1;
break;
}
if( evt.x < m_col[i].m_org ) {
afterCol = i - 1;
break;
}
}
if( inCol < 0 && afterCol < 0 )
inCol = m_cols - 1;
inRow = afterRow = -1;
for( j = 1; j < m_rows; ++j ) {
if( evt.y < m_row[j].m_org - m_sashSize ) {
inRow = j - 1;
break;
}
if( evt.y < m_row[j].m_org ) {
afterRow = j - 1;
break;
}
}
if( inRow < 0 && afterRow < 0 )
inRow = m_rows - 1;
// Recurse if no sash was hit.
if( inCol >= 0 && inRow >= 0 ) {
if( m_node[inCol][inRow] != null )
m_node[inCol][inRow].handleEvent( evt );
else
m_layout.defaultCursor();
return;
}
// Find out what shape the cursor should take, but
// only if we can indeed change it (frames only).
if( m_layout.m_frame != null ) {
if( afterCol >= 0 ) {
if( afterRow >= 0 )
cursor = m_layout.crossSashCursor;
else
cursor = m_layout.colSashCursor;
}
else {
cursor = m_layout.rowSashCursor;
}
if( m_layout.m_frame.getCursor().getType() != cursor )
m_layout.m_frame.setCursor( Cursor.getPredefinedCursor(cursor) );
}
// If the event was MOUSE_DOWN, initiate the dragging
// operation by making this node the active one. Note
// that the events MOUSE_DRAG and MOUSE_UP are directly
// relayed to the active node, bypassing the recursion
// via handleEvent().
if( evt.id == Event.MOUSE_DOWN ) {
if( afterCol >= 0 ) {
m_activeColSash = afterCol + 1;
m_colSashOfs = m_col[m_activeColSash].m_org - evt.x;
}
if( afterRow >= 0 ) {
m_activeRowSash = afterRow + 1;
m_rowSashOfs = m_row[m_activeRowSash].m_org - evt.y;
}
m_layout.m_activeNode = this;
}
}
//
// d r a g
//
protected void drag( int dragX, int dragY )
{
boolean finalize = false;
if( m_activeColSash > 0 ) {
int dx = dragX + m_colSashOfs - m_col[m_activeColSash].m_org;
if( m_col[m_activeColSash].m_size - dx <
m_col[m_activeColSash].m_minSize ) {
dx = m_col[m_activeColSash].m_size -
m_col[m_activeColSash].m_minSize;
}
else
if( m_col[m_activeColSash - 1].m_size + dx <
m_col[m_activeColSash - 1].m_minSize ) {
dx = m_col[m_activeColSash - 1].m_minSize -
m_col[m_activeColSash - 1].m_size;
}
if( dx != 0 ) {
m_col[m_activeColSash].m_org += dx;
m_col[m_activeColSash].m_size -= dx;
m_col[m_activeColSash - 1].m_size += dx;
finalize = true;
}
}
if( m_activeRowSash > 0 ) {
int dy = dragY + m_rowSashOfs - m_row[m_activeRowSash].m_org;
if( m_row[m_activeRowSash].m_size - dy <
m_row[m_activeRowSash].m_minSize ) {
dy = m_row[m_activeRowSash].m_size -
m_row[m_activeRowSash].m_minSize;
}
else
if( m_row[m_activeRowSash - 1].m_size + dy <
m_row[m_activeRowSash - 1].m_minSize ) {
dy = m_row[m_activeRowSash - 1].m_minSize -
m_row[m_activeRowSash - 1].m_size;
}
if( dy != 0 ) {
m_row[m_activeRowSash].m_org += dy;
m_row[m_activeRowSash].m_size -= dy;
m_row[m_activeRowSash - 1].m_size += dy;
finalize = true;
}
}
if( finalize )
fixDrag( m_layout.m_liveDrag );
}
//
// r e l e a s e S a s h
//
protected void releaseSash()
{
if( ! m_layout.m_liveDrag )
fixDrag( true );
m_activeColSash = 0;
m_activeRowSash = 0;
m_layout.m_activeNode = null;
}
//
// f i x D r a g
//
// The new position of the dragged sash(es) has/have been
// determined. This change has to be propagated down the
// hierarchy, a la finalize(). We have the panel interrupt
// the invalidation chain, since we don't want the whole
// container to be laid out again.
protected void fixDrag( boolean liveDrag )
{
m_layout.m_panel.dontPropagateInvalidate();
for( int i = 0; i < m_cols; ++i ) {
for( int 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 );
}
}
}
m_layout.m_panel.propagateInvalidate();
m_layout.m_panel.repaint( m_orgx, m_orgy,
m_size.width, m_size.height );
}
//
// p a i n t
//
// Paint the sashes of the grid of this interior node.
protected void paint( Graphics g )
{
int i, j;
if( m_sashSize > 0 ) {
for( i = 1; i < m_cols; ++i )
paintColSash( m_col[i].m_org - m_sashSize, g );
for( j = 1; j < m_rows; ++j ) {
int y = m_row[j].m_org - m_sashSize;
paintRowSash( y, g );
if( m_sashSize > 4 ) {
for( i = 1; i < m_cols; ++i )
paintCrossSash( m_col[i].m_org - m_sashSize, y, g );
}
}
}
for( i = 0; i < m_cols; ++i ) {
for( j = 0; j < m_rows; ++j ) {
if( m_node[i][j] != null ) {
m_node[i][j].paint( g );
}
else {
g.clearRect( m_col[i].m_org, m_row[j].m_org,
m_col[i].m_size, m_row[j].m_size );
}
}
}
}
//
// p a i n t C o l S a s h
//
protected void paintColSash( int x, Graphics g )
{
if( m_sashSize <= 4 ) {
g.setColor( Color.gray );
g.fillRect( x, m_orgy, m_sashSize, m_size.height );
return;
}
int x2 = x + m_sashSize - 1;
int y2 = m_orgy + m_size.height - 1;
g.setColor( Color.lightGray );
g.fillRect( x, m_orgy + 1, m_sashSize - 2, m_size.height - 1 );
g.setColor( Color.white );
g.drawLine( x + 1, m_orgy + 1, x + 1, y2 - 1 );
g.drawLine( x, m_orgy, x2 - 2, m_orgy );
g.setColor( Color.gray );
g.drawLine( x2 - 1, m_orgy, x2 - 1, y2 );
g.drawLine( x, y2, x2 - 2, y2 );
g.setColor( Color.black );
g.drawLine( x2, m_orgy, x2, y2 );
}
//
// p a i n t R o w S a s h
//
protected void paintRowSash( int y, Graphics g )
{
if( m_sashSize <= 4 ) {
g.setColor( Color.gray );
g.fillRect( m_orgx, y, m_size.width, m_sashSize );
return;
}
int x2 = m_orgx + m_size.width - 1;
int y2 = y + m_sashSize - 1;
g.setColor( Color.lightGray );
g.fillRect( m_orgx + 1, y, m_size.width - 1, m_sashSize - 2 );
g.setColor( Color.white );
g.drawLine( m_orgx + 1, y + 1, x2 - 1, y + 1 );
g.drawLine( m_orgx, y, m_orgx, y2 - 2 );
g.setColor( Color.gray );
g.drawLine( m_orgx, y2 - 1, x2, y2 - 1 );
g.drawLine( x2, y, x2, y2 - 2 );
g.setColor( Color.black );
g.drawLine( m_orgx, y2, x2, y2 );
}
//
// p a i n t C r o s s S a s h
//
protected void paintCrossSash( int x, int y, Graphics g )
{
int x2 = x + m_sashSize - 1;
int y2 = y + m_sashSize - 1;
g.setColor( Color.white );
g.drawLine( x + 1, y, x + 1, y );
g.drawLine( x + 1, y2 - 1, x + 1, y2 );
g.setColor( Color.lightGray );
g.drawLine( x + 2, y + 1, x2 - 2, y + 1 );
g.fillRect( x + 2, y2 - 1, m_sashSize - 4, 2 );
g.drawLine( x, y2, x, y2 );
g.setColor( Color.gray );
g.drawLine( x2 - 1, y, x2 - 1, y );
g.drawLine( x2 - 1, y2, x2 - 1, y2 );
}
//
// p r i n t
//
protected void print( String indent )
{
System.out.println( indent + "interior node cols=" +
m_cols + " rows=" + m_rows );
super.print( indent + "o ");
for( int i = 0; i < m_cols; ++i ) {
for( int j = 0; j < m_rows; ++j ) {
if( m_node[i][j] != null ) {
System.out.println( indent +
"o child (" + i + "," + j + ")" );
m_node[i][j].print( indent + " " );
}
}
}
}
}
///////////////////////////////////////////////////////////////
//
// M o s a i c S l i c e
//
///////////////////////////////////////////////////////////////
final class MosaicSlice
{
// A slice describes the shape of a column or row of an
// interior node. m_org is the coordinate at which the
// column/row starts; m_minSize and m_prefSize are the
// minimum and preferred size, derived from the minimum
// and preferred sizes of all child nodes that are part
// of the column/row. m_size is the actual size.
// Note that all these values are one-dimensional.
protected int m_org = 0;
protected int m_minSize = 0;
protected int m_prefSize = 0;
protected int m_size = 0;
// m_sizeSum is used temporarily to compute the weight of
// the slice. The preferred size of all children is
// summed up in this variable; it is used to normalize
// the weight such that the sum over all weight parameters
// of the child nodes in the slice is equal to one.
protected int m_sizeSum = 0;
protected double m_weight = 0;
//
// e x p a n d
//
protected void expand( int minSize, int prefSize )
{
if( minSize > m_minSize )
m_minSize = minSize;
if( prefSize > m_prefSize )
m_prefSize = prefSize;
m_sizeSum += prefSize;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -