---
category: swing
folder: ListOverflowWithFadeScroll
title: JScrollPaneからあふれるJListのアイテムをフェイドアウト表示する
tags: [JScrollPane, JLayer, JList]
author: aterai
pubdate: 2025-10-06T03:23:49+09:00
description: JScrollPaneの上下からあふれるJListのリストアイテムが存在する場合、それをフェイドアウト効果で表示するよう設定します。
image: https://drive.google.com/uc?id=1o6hLUHfaGUlG03CAnuJEDPT0zKpXM54q
---
* Summary [#summary]
`JScrollPane`の上下からあふれる`JList`のリストアイテムが存在する場合、それをフェイドアウト効果で表示するよう設定します。

#download(https://drive.google.com/uc?id=1o6hLUHfaGUlG03CAnuJEDPT0zKpXM54q)

* Source Code Examples [#sourcecode]
#code(link){{
class FadeScrollLayerUI extends LayerUI<JScrollPane> {
  public static final int OVERFLOW = 32;

  @Override public void paint(Graphics g, JComponent c) {
    super.paint(g, c);
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setPaint(new Color(0x12_FF_FF_FF, true));
    if (c instanceof JLayer) {
      JScrollPane scroll = (JScrollPane) ((JLayer<?>) c).getView();
      Rectangle r = scroll.getViewportBorderBounds();
      BoundedRangeModel m = scroll.getVerticalScrollBar().getModel();
      g2.setClip(r);
      if (m.getMinimum() < m.getValue()) {
        for (int i = OVERFLOW; i > 0; i--) {
          g2.fillRect(0, r.y - i, r.width, OVERFLOW - i);
        }
      }
      if (m.getValue() + m.getExtent() < m.getMaximum()) {
        g2.translate(r.x, r.y + r.height - OVERFLOW);
        for (int i = 0; i < OVERFLOW; i++) {
          g2.fillRect(0, i, r.width, OVERFLOW - i);
        }
      }
    }
    g2.dispose();
  }
}
}}

* Description [#description]
- `JScrollPane`に`JLayer`を設定し、`JLayer#paint(...)`をオーバーライドして`JList`の上下辺付近のあふれを半透明の白色で上書きすることでフェードアウト効果で描画している
- `JScrollPane`に`JLayer`を設定
-- `JLayer#paint(...)`をオーバーライドし、`JList`の上下辺付近のあふれを半透明白色で上書きしてフェードアウト効果を描画している
-- 背景が白色以外の`JList`やダークモードなどには未対応
- `JList`ではなく`JTable`などでもフェードスクロール可能だが、上辺に`JTableHeader`が配置されることを考慮していないので、行ではなくヘッダがフェードアウトしてしまう
-- 上辺のフェードアウト効果を描画する前に`g2.setClip(scroll.getViewportBorderBounds());`で描画領域を制限することで回避可能

* Reference [#reference]
- [[JScrollPane内のコンテンツがJViewportの幅より大きい場合その右端に影を描画する>Swing/ViewportBorderBounds]]
- [[JLabelで文字列のあふれをフェードアウト効果に変更する>Swing/TextOverflowFadeLabel]]

* Comment [#comment]
#comment
#comment