14
14
import java .lang .reflect .InvocationTargetException ;
15
15
import java .lang .reflect .Method ;
16
16
import java .util .ArrayList ;
17
+ import java .util .Arrays ;
18
+ import java .util .Collection ;
17
19
import java .util .Enumeration ;
18
20
import java .util .HashMap ;
19
21
import java .util .List ;
@@ -52,6 +54,7 @@ public class JBroTableHeaderUI extends BasicTableHeaderUI {
52
54
private ComponentUI headerDelegate ;
53
55
private ReverseBorder lastBorder ;
54
56
private CustomTableHeaderRenderer customRenderer ;
57
+ private int heightsCache [];
55
58
56
59
public JBroTableHeaderUI ( JBroTable table ) {
57
60
this .table = table ;
@@ -248,6 +251,7 @@ public void updateModel() {
248
251
Method createUImethod = uiClass .getMethod ( "createUI" , JComponent .class );
249
252
headerDelegate = ( ComponentUI )createUImethod .invoke ( null , header );
250
253
call ( "installUI" , new Class []{ JComponent .class }, headerDelegate , new Object []{ header } );
254
+ Arrays .fill ( heightsCache , -1 );
251
255
for ( int level = delegates .size (); level < levelsCnt ; level ++ ) {
252
256
ComponentUI delegate = ( ComponentUI )createUImethod .invoke ( null , header );
253
257
delegates .add ( delegate );
@@ -277,6 +281,8 @@ public void installUI( JComponent c ) {
277
281
delegates = new ArrayList < ComponentUI >( levelsCnt );
278
282
headers = new ArrayList < JTableHeader >( levelsCnt );
279
283
rendererPanes = new ArrayList < CellRendererPane >( levelsCnt );
284
+ if ( heightsCache == null || heightsCache .length < levelsCnt )
285
+ heightsCache = new int [ levelsCnt ];
280
286
updateModel ();
281
287
super .installUI ( c );
282
288
SwingUtilities .updateComponentTreeUI ( header );
@@ -308,22 +314,44 @@ public void paint( Graphics g, JComponent c ) {
308
314
JBroTableColumnModel groupModel = getTableColumnModel ();
309
315
if ( groupModel == null )
310
316
return ;
317
+ Rectangle clip = g .getClipBounds ();
318
+ Point left = clip .getLocation ();
319
+ Point right = new Point ( clip .x + clip .width - 1 , clip .y );
320
+ int cMin = header .columnAtPoint ( left );
321
+ int cMax = header .columnAtPoint ( right );
322
+ int columnCount = groupModel .getColumnCount ();
323
+ if ( cMax < 0 || cMax >= columnCount ) {
324
+ cMax = columnCount - 1 ;
325
+ if ( cMin > cMax )
326
+ cMin = cMax ;
327
+ }
328
+ if ( cMin < 0 )
329
+ cMin = 0 ;
311
330
JBroTableHeader header = getHeader ();
312
331
int headerHeight = header .getSize ().height ;
313
332
Rectangle cellRect = new Rectangle ();
314
333
JBroTableColumn draggedColumn = header .getDraggedGroup ();
315
- Enumeration < TableColumn > enumeration = groupModel .getColumns ();
316
334
List < JBroTableColumn > currentColumns = new ArrayList < JBroTableColumn >();
317
335
List < Integer > coords = new ArrayList < Integer >();
318
336
currentColumns .add ( null );
319
337
boolean draggedColumnMet = false ;
320
- while ( enumeration .hasMoreElements () ) {
321
- JBroTableColumn column = ( JBroTableColumn )enumeration .nextElement ();
322
- List < JBroTableColumn > columnParents = groupModel .getColumnParents ( column , true );
338
+ int calcStartXFrom = 0 ;
339
+ for ( int cIdx = cMin ; cIdx <= cMax ; cIdx ++ ) {
340
+ JBroTableColumn column = groupModel .getColumn ( cIdx );
341
+ Collection < JBroTableColumn > columnParents = groupModel .getColumnParents ( column , true );
323
342
int level = 0 ;
324
343
boolean addAbsent = false ;
325
344
boolean doNotPaintCells = draggedColumnMet && columnParents .contains ( draggedColumn );
345
+ boolean firstColumnParentsNeedToBeRepainted = cIdx == cMin && cMin > 0 ;
326
346
for ( JBroTableColumn columnParent : columnParents ) {
347
+ if ( firstColumnParentsNeedToBeRepainted ) {
348
+ int calcStartXTo = groupModel .getColumnAbsoluteIndex ( columnParent );
349
+ for ( int i = calcStartXFrom ; i < calcStartXTo ; i ++ ) {
350
+ JBroTableColumn col = groupModel .getColumn ( i );
351
+ cellRect .x += col .getWidth ();
352
+ }
353
+ calcStartXFrom = calcStartXTo ;
354
+ }
327
355
if ( !addAbsent ) {
328
356
JBroTableColumn currentColumn = currentColumns .get ( level );
329
357
if ( columnParent != currentColumn ) {
@@ -338,10 +366,11 @@ public void paint( Graphics g, JComponent c ) {
338
366
if ( addAbsent ) {
339
367
currentColumns .add ( columnParent );
340
368
cellRect .y = coords .isEmpty () ? 0 : coords .get ( coords .size () - 1 );
341
- Dimension cellSize = getGroupSize ( columnParent );
369
+ cellRect . width = getGroupWidth ( columnParent );
342
370
if ( columnParent == column )
343
- cellSize .height = headerHeight - cellRect .y ;
344
- cellRect .setSize ( cellSize );
371
+ cellRect .height = headerHeight - cellRect .y ;
372
+ else
373
+ cellRect .height = getGroupHeight ( columnParent );
345
374
if ( draggedColumn == columnParent ) {
346
375
g .setColor ( header .getParent ().getBackground () );
347
376
g .fillRect ( cellRect .x , cellRect .y , cellRect .width , headerHeight - cellRect .y );
@@ -350,7 +379,7 @@ public void paint( Graphics g, JComponent c ) {
350
379
} else if ( !doNotPaintCells )
351
380
paintCell ( g , cellRect , columnParent );
352
381
if ( columnParent != column ) {
353
- cellRect .y += cellSize .height ;
382
+ cellRect .y += cellRect .height ;
354
383
coords .add ( cellRect .y );
355
384
}
356
385
}
@@ -451,62 +480,45 @@ private void paintCell( Graphics g, Rectangle cellRect, JBroTableColumn group )
451
480
paintCell ( g , comp , cellRect );
452
481
}
453
482
454
- public Dimension getGroupSize ( JBroTableColumn group ) {
455
- Dimension size = new Dimension ();
483
+ public int getGroupHeight ( JBroTableColumn group ) {
484
+ int height = 0 ;
485
+ for ( int level = group .getY (); level < group .getY () + group .getRowspan (); level ++ )
486
+ height += getRowHeight ( level );
487
+ return height ;
488
+ }
489
+
490
+ public int getGroupWidth ( JBroTableColumn group ) {
491
+ int width = 0 ;
456
492
JBroTableColumnModel groupModel = getTableColumnModel ();
457
- for ( int level = group .getY (); level < group .getY () + group .getRowspan (); level ++ ) {
458
- if ( rowHeights != null && rowHeights .size () > level ) {
459
- Integer height = rowHeights .get ( level );
460
- if ( height != null ) {
461
- size .height += height ;
462
- continue ;
463
- }
464
- }
465
- TableCellRenderer renderer = headers .get ( level ).getDefaultRenderer ();
466
- Component comp = renderer .getTableCellRendererComponent ( header .getTable (), group .getHeaderValue (), false , false , -1 , -1 );
467
- size .height += comp .getPreferredSize ().height ;
468
- }
469
493
List < JBroTableColumn > children = groupModel .getColumnChildren ( group );
470
494
if ( children .isEmpty () )
471
- size . width = group .getWidth ();
495
+ width = group .getWidth ();
472
496
else
473
497
for ( JBroTableColumn column : children )
474
- size .width += groupModel .getWidth ( column );
475
- return size ;
498
+ width += groupModel .getWidth ( column );
499
+ return width ;
500
+ }
501
+
502
+ public Dimension getGroupSize ( JBroTableColumn group ) {
503
+ return new Dimension ( getGroupWidth ( group ), getGroupHeight ( group ) );
476
504
}
477
505
478
506
private int calculateHeaderHeight () {
479
- int mHeight = 0 ;
480
- JBroTableColumnModel groupModel = getTableColumnModel ();
481
- for ( int column = 0 ; column < groupModel .getColumnCount (); column ++ ) {
482
- int cHeight = 0 ;
483
- JBroTableColumn parent = groupModel .getColumn ( column );
484
- while ( parent != null ) {
485
- for ( int level = parent .getY (); level < parent .getY () + parent .getRowspan (); level ++ ) {
486
- if ( rowHeights != null && rowHeights .size () > level ) {
487
- Integer height = rowHeights .get ( level );
488
- if ( height != null ) {
489
- cHeight += height ;
490
- continue ;
491
- }
492
- }
493
- TableCellRenderer renderer = headers .get ( level ).getDefaultRenderer ();
494
- Component comp = renderer .getTableCellRendererComponent ( header .getTable (), parent .getHeaderValue (), false , false , -1 , column );
495
- cHeight += comp .getPreferredSize ().height ;
496
- }
497
- parent = groupModel .getColumnParent ( parent );
498
- }
499
- mHeight = Math .max ( mHeight , cHeight );
500
- }
501
- return mHeight ;
507
+ int height = 0 ;
508
+ int levelsCnt = table .getData () == null ? 0 : table .getData ().getFieldGroups ().size ();
509
+ for ( int level = 0 ; level < levelsCnt ; level ++ )
510
+ height += getRowHeight ( level );
511
+ return height ;
502
512
}
503
513
504
514
public int getRowHeight ( int level ) {
505
- int extra = level == headers .size () - 1 ? getHeader ().getPreferredSize ().height - calculateHeaderHeight () : 0 ;
515
+ int ret = heightsCache [ level ];
516
+ if ( ret >= 0 )
517
+ return ret ;
506
518
if ( rowHeights != null && rowHeights .size () > level ) {
507
519
Integer height = rowHeights .get ( level );
508
520
if ( height != null )
509
- return extra + height ;
521
+ return heightsCache [ level ] = height ;
510
522
}
511
523
int mHeight = 0 ;
512
524
JBroTableColumnModel groupModel = getTableColumnModel ();
@@ -521,7 +533,7 @@ public int getRowHeight( int level ) {
521
533
parent = groupModel .getColumnParent ( parent );
522
534
}
523
535
}
524
- return extra + mHeight ;
536
+ return heightsCache [ level ] = mHeight ;
525
537
}
526
538
527
539
@ Override
@@ -673,6 +685,7 @@ public void setRowHeight( int level, Integer height ) {
673
685
while ( rowHeights .size () <= level )
674
686
rowHeights .add ( null );
675
687
rowHeights .set ( level , height );
688
+ heightsCache [ level ] = -1 ;
676
689
}
677
690
678
691
public Rectangle getGroupHeaderBoundsFor ( JBroTableColumn group ) {
@@ -683,7 +696,7 @@ public Rectangle getGroupHeaderBoundsFor( JBroTableColumn group ) {
683
696
Rectangle bounds = new Rectangle ( size );
684
697
bounds .y = 0 ;
685
698
for ( JBroTableColumn parent : columnModel .getColumnParents ( group , false ) )
686
- bounds .y += getGroupSize ( parent ). height ;
699
+ bounds .y += getGroupHeight ( parent );
687
700
int lastColumnIndex = columnModel .getColumnIndex ( group .getIdentifier () );
688
701
for ( int index = 0 ; index < lastColumnIndex ; index ++ ) {
689
702
JBroTableColumn tc = columnModel .getColumn ( index );
@@ -780,9 +793,9 @@ public void mousePressed( MouseEvent e ) {
780
793
if ( canResize ( point , resizingColumn , header ) ) {
781
794
header .setResizingColumn ( resizingColumn );
782
795
if ( header .getComponentOrientation ().isLeftToRight () )
783
- mouseXOffset = point .x - getGroupSize ( resizingColumn ). width ;
796
+ mouseXOffset = point .x - getGroupWidth ( resizingColumn );
784
797
else
785
- mouseXOffset = point .x + getGroupSize ( resizingColumn ). width ;
798
+ mouseXOffset = point .x + getGroupWidth ( resizingColumn );
786
799
} else if ( header .getReorderingAllowed () ) {
787
800
JBroTableColumn column = getColumnAtPoint ( point );
788
801
if ( column != null ) {
@@ -868,7 +881,7 @@ public void mouseDragged( MouseEvent e ) {
868
881
shouldMove = false ;
869
882
}
870
883
if ( shouldMove ) {
871
- int width = getGroupSize ( newGroup ). width ;
884
+ int width = getGroupWidth ( newGroup );
872
885
int groupStartIndex = groupModel .getColumnAbsoluteIndex ( newGroup );
873
886
int groupEndIndex = newGroup .getColspan () + groupStartIndex - 1 ;
874
887
if ( direction < 0 )
@@ -895,7 +908,7 @@ public void mouseDragged( MouseEvent e ) {
895
908
} else if ( resizingColumn != null ) {
896
909
// TODO: child column resizing should affect only columns inside a parent group.
897
910
// TODO: parent column resizing should proportionally affect all child columns.
898
- int oldWidth = getGroupSize ( resizingColumn ). width ;
911
+ int oldWidth = getGroupWidth ( resizingColumn );
899
912
int newWidth ;
900
913
if ( headerLeftToRight )
901
914
newWidth = mouseX - mouseXOffset ;
0 commit comments