@@ -4104,15 +4104,25 @@ public void removeStyleName(String style) {
41044104
41054105 private void setHeightToHeaderCellHeight () {
41064106 RowContainer header = grid .escalator .getHeader ();
4107- if (header .getRowCount () == 0
4107+ if (!WidgetUtil .isDisplayed (header .getElement ())
4108+ || header .getRowCount () == 0
41084109 || !header .getRowElement (0 ).hasChildNodes ()) {
41094110 getLogger ().info (
41104111 "No header cell available when calculating sidebar button height" );
4111- openCloseButton .setHeight (header .getDefaultRowHeight () + "px" );
4112+ // If the Grid is hidden with styles when this is called the
4113+ // border height will be off, but it's usually only a matter of
4114+ // a pixel or so. Removing a style name cannot trigger a full
4115+ // refresh of the layout, it's developer's responsibility to do
4116+ // that where needed.
4117+ double height = header .getDefaultRowHeight ()
4118+ - WidgetUtil .measureVerticalBorder (getElement ()) / 2 ;
4119+ openCloseButton .setHeight (height + "px" );
41124120
41134121 return ;
41144122 }
41154123
4124+ // Use actual height instead of expected height in case the height
4125+ // is modified by styles.
41164126 Element firstHeaderCell = header .getRowElement (0 )
41174127 .getFirstChildElement ();
41184128 double height = WidgetUtil
@@ -4131,8 +4141,6 @@ private void updateVisibility() {
41314141 close ();
41324142 grid .getElement ().appendChild (getElement ());
41334143 Grid .setParent (this , grid );
4134- // border calculation won't work until attached
4135- setHeightToHeaderCellHeight ();
41364144 }
41374145 }
41384146
@@ -4143,10 +4151,9 @@ private boolean isInDOM() {
41434151 @ Override
41444152 protected void onAttach () {
41454153 super .onAttach ();
4146- // make sure the button will get correct height if the button should
4147- // be visible when the grid is rendered the first time.
4148- Scheduler .get ()
4149- .scheduleDeferred (() -> setHeightToHeaderCellHeight ());
4154+ // Make sure the button will get correct height whenever the Sidebar
4155+ // is added to the Grid.
4156+ setHeightToHeaderCellHeight ();
41504157 }
41514158
41524159 @ Override
@@ -4179,6 +4186,12 @@ private final class ColumnHider {
41794186 */
41804187 private boolean hidingColumn ;
41814188
4189+ /**
4190+ * When several columns are set hidable, don't reset the Sidebar for
4191+ * every column separately.
4192+ */
4193+ private boolean toggleUpdateTriggered ;
4194+
41824195 private void updateColumnHidable (final Column <?, T > column ) {
41834196 if (column .isHidable ()) {
41844197 MenuItem toggle = columnToHidingToggleMap .get (column );
@@ -4224,16 +4237,26 @@ private String createHTML(Column<?, T> column) {
42244237 }
42254238
42264239 private void updateTogglesOrder () {
4227- if (!hidingColumn ) {
4228- int lastIndex = 0 ;
4229- for (Column <?, T > column : getColumns ()) {
4230- if (column .isHidable ()) {
4231- final MenuItem menuItem = columnToHidingToggleMap
4232- .get (column );
4233- sidebar .menuBar .removeItem (menuItem );
4234- sidebar .menuBar .insertItem (menuItem , lastIndex ++);
4240+ if (!hidingColumn && !toggleUpdateTriggered ) {
4241+ // This method is called whenever a column is set hidable. If
4242+ // there are multiple hidable columns, it will get called
4243+ // separately for all of them. There is no need to update the
4244+ // order more than once and no other layouting is dependent on
4245+ // the Sidebar layouting getting finished first, so wait until
4246+ // all calls have arrived before proceeding further.
4247+ toggleUpdateTriggered = true ;
4248+ Scheduler .get ().scheduleFinally (() -> {
4249+ int lastIndex = 0 ;
4250+ for (Column <?, T > column : getColumns ()) {
4251+ if (column .isHidable ()) {
4252+ final MenuItem menuItem = columnToHidingToggleMap
4253+ .get (column );
4254+ sidebar .menuBar .removeItem (menuItem );
4255+ sidebar .menuBar .insertItem (menuItem , lastIndex ++);
4256+ }
42354257 }
4236- }
4258+ toggleUpdateTriggered = false ;
4259+ });
42374260 }
42384261 }
42394262
0 commit comments