TITLE:JScrollBarのButtonの位置を変更

Posted by aterai at 2011-05-16

JScrollBarのButtonの位置を変更

JScrollBarのButtonの位置を変更します。

  • &jnlp;
  • &jar;
  • &zip;
ScrollBarButtonLayout.png

サンプルコード

scrollbar.setUI(new WindowsScrollBarUI() {
  //Copied from javax.swing.plaf.basic.BasicScrollBarUI
  @Override protected void layoutVScrollbar(JScrollBar sb) {
    Dimension sbSize = sb.getSize();
    Insets sbInsets = sb.getInsets();

    /*
     * Width and left edge of the buttons and thumb.
     */
    int itemW = sbSize.width - (sbInsets.left + sbInsets.right);
    int itemX = sbInsets.left;

    /* Nominal locations of the buttons, assuming their preferred
     * size will fit.
     */
    boolean squareButtons = false;
    //DefaultLookup.getBoolean(scrollbar, this, "ScrollBar.squareButtons", false);
    int decrButtonH = squareButtons
      ? itemW : decrButton.getPreferredSize().height;
    int incrButtonH = squareButtons
      ? itemW : incrButton.getPreferredSize().height;

    //int decrButtonY = sbInsets.top;
    int decrButtonY = sbSize.height - (sbInsets.bottom + incrButtonH + decrButtonH);
    int incrButtonY = sbSize.height - (sbInsets.bottom + incrButtonH);

    /* The thumb must fit within the height left over after we
     * subtract the preferredSize of the buttons and the insets
     * and the gaps
     */
    int sbInsetsH = sbInsets.top + sbInsets.bottom;
    int sbButtonsH = decrButtonH + incrButtonH;

    //need before 1.7.0 ---->
    int decrGap = 0; //ins
    int incrGap = 0; //ins
    //incrGap = UIManager.getInt("ScrollBar.incrementButtonGap");
    //decrGap = UIManager.getInt("ScrollBar.decrementButtonGap");
    //<----

    int gaps = decrGap + incrGap;
    float trackH = sbSize.height - (sbInsetsH + sbButtonsH) - gaps;

    /* Compute the height and origin of the thumb.   The case
     * where the thumb is at the bottom edge is handled specially
     * to avoid numerical problems in computing thumbY.  Enforce
     * the thumbs min/max dimensions.  If the thumb doesn't
     * fit in the track (trackH) we'll hide it later.
     */
    float min = sb.getMinimum();
    float extent = sb.getVisibleAmount();
    float range = sb.getMaximum() - min;
    //float value = getValue(sb); //del
    float value = sb.getValue(); //ins

    int thumbH = (range <= 0) ? getMaximumThumbSize().height
                              : (int)(trackH * (extent / range));
    thumbH = Math.max(thumbH, getMinimumThumbSize().height);
    thumbH = Math.min(thumbH, getMaximumThumbSize().height);

    int thumbY = incrButtonY - incrGap - thumbH;
    if(value < (sb.getMaximum() - sb.getVisibleAmount())) {
      float thumbRange = trackH - thumbH;
      thumbY = (int)(0.5f + (thumbRange * ((value - min) / (range - extent))));
      //thumbY +=  decrButtonY + decrButtonH + decrGap; //del
    }

    /* If the buttons don't fit, allocate half of the available
     * space to each and move the lower one (incrButton) down.
     */
    int sbAvailButtonH = (sbSize.height - sbInsetsH);
    if(sbAvailButtonH < sbButtonsH) {
      incrButtonH = decrButtonH = sbAvailButtonH / 2;
      incrButtonY = sbSize.height - (sbInsets.bottom + incrButtonH);
    }
    decrButton.setBounds(itemX, decrButtonY, itemW, decrButtonH);
    incrButton.setBounds(itemX, incrButtonY, itemW, incrButtonH);

    /* Update the trackRect field.
     */
    //int itrackY = decrButtonY + decrButtonH + decrGap; //del
    //int itrackH = incrButtonY - incrGap - itrackY; //del
    int itrackY = 0; //ins
    int itrackH = decrButtonY - itrackY; //ins
    trackRect.setBounds(itemX, itrackY, itemW, itrackH);

    /* If the thumb isn't going to fit, zero it's bounds.  Otherwise
     * make sure it fits between the buttons.  Note that setting the
     * thumbs bounds will cause a repaint.
     */
    if(thumbH >= (int)trackH) {
      setThumbBounds(0, 0, 0, 0);
    }else{
      //if((thumbY + thumbH) > incrButtonY - incrGap) {
      //  thumbY = incrButtonY - incrGap - thumbH;
      //}
      //if(thumbY < (decrButtonY + decrButtonH + decrGap)) {
      //  thumbY = decrButtonY + decrButtonH + decrGap + 1;
      //}
      if((thumbY + thumbH) > decrButtonY - decrGap) {
        thumbY = decrButtonY - decrGap - thumbH;
      }
      if(thumbY < 0) { //(decrButtonY + decrButtonH + decrGap)) {
        thumbY = 1; //decrButtonY + decrButtonH + decrGap + 1;
      }
      setThumbBounds(itemX, thumbY, itemW, thumbH);
    }
  }
});

解説

上記のサンプルでは、WindowsScrollBarUI#layoutVScrollbar(...)をオーバーライドして、垂直スクロールバーの増加、減少ボタンが両方下側に配置されるようにレイアウトを変更しています。

コメント

  • 水平スクロールバーには今のところ対応していない。 -- aterai