@Override
  public void layout() {
    ScrollBar scrollBar = (ScrollBar) getComponent();

    int width = getWidth();
    int height = getHeight();

    int start = scrollBar.getStart();
    int end = scrollBar.getEnd();
    int extent = scrollBar.getExtent();
    int value = scrollBar.getValue();

    int maxLegalRealValue = end - extent;
    int numLegalRealValues = maxLegalRealValue - start + 1;
    float extentPercentage = (float) extent / (float) (end - start);

    if (scrollBar.getOrientation() == Orientation.HORIZONTAL) {
      scrollUpButton.setSize(scrollUpButton.getPreferredWidth(-1), height);
      scrollUpButton.setLocation(0, 0);

      scrollDownButton.setSize(scrollDownButton.getPreferredWidth(-1), height);
      scrollDownButton.setLocation(width - scrollDownButton.getWidth(), 0);

      if (scrollBar.isEnabled()) {
        // Calculate the handle width first, as it dictates how much
        // room is left to represent the range of legal values. Note
        // that the handle may overlap each scroll button by 1px so
        // that its borders merge into the borders of the scroll buttons
        int availableWidth = width - scrollUpButton.getWidth() - scrollDownButton.getWidth() + 2;
        int handleWidth =
            Math.max(minimumHandleLength, Math.round(extentPercentage * availableWidth));

        // Calculate the position of the handle by calculating the
        // scale that maps logical value to pixel value
        int numLegalPixelValues = availableWidth - handleWidth + 1;
        float valueScale = (float) numLegalPixelValues / (float) numLegalRealValues;
        int handleX = (int) (value * valueScale) + scrollUpButton.getWidth() - 1;

        if (handleWidth > availableWidth) {
          // If we can't fit the handle, we hide it
          handle.setVisible(false);
        } else {
          handle.setVisible(true);

          handle.setSize(handleWidth, height);
          handle.setLocation(handleX, 0);
        }
      } else {
        handle.setVisible(false);
      }
    } else {
      scrollUpButton.setSize(width, scrollUpButton.getPreferredHeight(-1));
      scrollUpButton.setLocation(0, 0);

      scrollDownButton.setSize(width, scrollDownButton.getPreferredHeight(-1));
      scrollDownButton.setLocation(0, height - scrollDownButton.getHeight());

      if (scrollBar.isEnabled()) {
        // Calculate the handle height first, as it dictates how much
        // room is left to represent the range of legal values. Note
        // that the handle may overlap each scroll button by 1px so
        // that its borders merge into the borders of the scroll buttons
        int availableHeight =
            height - scrollUpButton.getHeight() - scrollDownButton.getHeight() + 2;
        int handleHeight =
            Math.max(minimumHandleLength, Math.round(extentPercentage * availableHeight));

        // Calculate the position of the handle by calculating the
        // scale maps logical value to pixel value
        int numLegalPixelValues = availableHeight - handleHeight + 1;
        float valueScale = (float) numLegalPixelValues / (float) numLegalRealValues;
        int handleY = (int) (value * valueScale) + scrollUpButton.getHeight() - 1;

        if (handleHeight > availableHeight) {
          // If we can't fit the handle, we hide it
          handle.setVisible(false);
        } else {
          handle.setVisible(true);

          handle.setSize(width, handleHeight);
          handle.setLocation(0, handleY);
        }
      } else {
        handle.setVisible(false);
      }
    }
  }