JScrollPaneからあふれるJListのアイテムをフェードアウト表示する
Total: 495, Today: 1, Yesterday: 1
Posted by aterai at
Last-modified:
Summary
JScrollPaneの上下からあふれるJListのリストアイテムが存在する場合、それをフェードアウト効果で表示するよう設定します。
Screenshot

Advertisement
Source Code Examples
class FadeScrollLayerUI extends LayerUI<JScrollPane> {
public static final int OVERFLOW = 32;
@Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c instanceof JLayer) {
JScrollPane scroll = (JScrollPane) ((JLayer<?>) c).getView();
Rectangle r = scroll.getViewportBorderBounds();
BoundedRangeModel m = scroll.getVerticalScrollBar().getModel();
// 1. Dynamically get background color of JList
Color bgc = getBgColor(scroll);
Color transparent = new Color(bgc.getRGB() & 0x00_FF_FF_FF, true);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setClip(r);
// 2. Top edge fade (background color → transparent)
if (m.getMinimum() < m.getValue()) {
Paint topGrad = new GradientPaint(
0f, r.y, bgc, 0f, r.y + OVERFLOW, transparent);
g2.setPaint(topGrad);
g2.fillRect(r.x, r.y, r.width, OVERFLOW);
}
// 3. Bottom edge fade (transparent → background color)
if (m.getValue() + m.getExtent() < m.getMaximum()) {
int fadeTop = r.y + r.height - OVERFLOW;
Paint btmGrad = new GradientPaint(
0f, fadeTop, transparent, 0f, r.y + r.height, bgc);
g2.setPaint(btmGrad);
g2.fillRect(r.x, fadeTop, r.width, OVERFLOW);
}
g2.dispose();
}
}
private static Color getBgColor(JScrollPane scroll) {
return Optional.ofNullable(scroll.getViewport().getView())
.map(Component::getBackground)
.orElseGet(() -> {
Color fallback = UIManager.getColor("List.background");
return fallback == null ? Color.WHITE : fallback;
});
}
}
View in GitHub: Java, KotlinDescription
JScrollPaneにJLayerを設定JLayer#paint(...)をオーバーライドし、JListの上下辺付近のあふれを半透明白色で上書きしてフェードアウト効果を描画している背景が白色以外のJListやダークモードなどには未対応JListの背景色が白色固定を想定したフェードアウトだったので、ダークモードでおかしな表示になるバグを修正- In dark mode, instead of a fade-out effect, it appears as a hazy display · Issue #39 · aterai/java-swing-tips
JListではなくJTableなどでもフェードスクロール可能だが、上辺にJTableHeaderが配置されることを考慮していないので、行ではなくヘッダがフェードアウトしてしまう- 上辺のフェードアウト効果を描画する前に
g2.setClip(scroll.getViewportBorderBounds());で描画領域を制限することで回避可能
- 上辺のフェードアウト効果を描画する前に