JavaFX 8: Adapting ListView Cell's height to its ScrollBar

186 Views Asked by At

I have a ListView (horizontal orientation) that uses a ListCell to show its items. These cells are Canvas. When enough items are placed into the list, a vertical and horizontal ScrollBar are activated. When this happens, part of the cell's contents are clipped (at the bottom) by the horizontal scrollbar.

How can we set (or adapt) the list view's height so that when the scrollbar appears no clipping will occur? Is their a way to detect when a scrollbar becomes visible? Can we determine the scrollbar's height and simply make the lists's height tall enough?

I have tried several approaches via change listeners in the list view and the list view cell. But these don't seem to work.

TIA

1

There are 1 best solutions below

0
On

I have come up with the following solution: add an event listener - every-time an element is added, removed or replaced resize the ListView's height. When resizing check wether you have only a vertical and/or horizontal scroll-bar. If only a vertical scroll-bar exists use its height and insets to get the cell height. If a horizontal scroll-bar also exists add its height too (height of the thumb). Here are the relevant code snippet (in Scala):

  def extendHeight(thumbnails: ListView[String], vertical: Option[ScrollBar], horizontal: Option[ScrollBar]): Unit = {
    (vertical, horizontal) match {
      case (None, None) => ()
      case (None, Some(_)) => ()
      case (Some(v), None) =>
        resizeHeight(thumbnails, v, 0)
      case (Some(v), Some(h)) =>
        val extra = if (h.isVisible) h.getHeight else 0
        resizeHeight(thumbnails, v, extra)
    }
  }

  def resizeToFrame(thumbnails: ListView[String]): Unit = {
    val (vertical, horizontal) = PStoryBoardUX.getScrollBars(thumbnails)
    PStoryBoardUX.extendHeight(thumbnails, vertical, horizontal)
  }

thumbnails.getItems.addListener( new ListChangeListener[String] {
      override def onChanged(c: Change[_ <: String]): Unit = {
        javafx.application.Platform.runLater( () => {

          // At thus point in time the scrollbars have not been updated
          // So we don't know if they will be active or not. Force this
          thumbnails.layout()
          // Now resize to remove the visible scrollbars
          resizeToFrame(thumbnails)
        })
      }
    })