Swing/ProgressCircle のバックアップ(No.18)
- バックアップ一覧
 - 差分 を表示
 - 現在との差分 を表示
 - 現在との差分 - Visual を表示
 - ソース を表示
 - Swing/ProgressCircle へ行く。
  
- 1 (2014-06-25 (水) 16:55:22)
 - 2 (2014-11-04 (火) 04:26:22)
 - 3 (2014-11-19 (水) 20:15:14)
 - 4 (2014-11-21 (金) 18:11:05)
 - 5 (2015-12-16 (水) 16:48:06)
 - 6 (2017-06-01 (木) 11:13:12)
 - 7 (2018-02-24 (土) 19:51:30)
 - 8 (2018-05-23 (水) 21:15:28)
 - 9 (2019-12-30 (月) 01:47:09)
 - 10 (2021-05-25 (火) 13:07:01)
 - 11 (2025-01-03 (金) 08:57:02)
 - 12 (2025-01-03 (金) 09:01:23)
 - 13 (2025-01-03 (金) 09:02:38)
 - 14 (2025-01-03 (金) 09:03:21)
 - 15 (2025-01-03 (金) 09:04:02)
 - 16 (2025-05-14 (水) 16:08:38)
 - 17 (2025-06-19 (木) 12:41:37)
 - 18 (2025-06-19 (木) 12:43:47)
 
 
- category: swing
folder: ProgressCircle
title: JProgressBarの進捗状況を円形で表示する
tags: [JProgressBar, SwingWorker]
author: aterai
pubdate: 2014-06-02T00:02:59+09:00
description: JProgressBarの進捗状況を円形表示するように設定します。
image: 
hreflang:
href: https://java-swing-tips.blogspot.com/2014/06/how-to-create-circular-progress.html lang: en
 
Summary
JProgressBarの進捗状況を円形表示するように設定します。
Screenshot

Advertisement
Source Code Examples
class ProgressCircleUI extends BasicProgressBarUI {
  @Override public Dimension getPreferredSize(JComponent c) {
    Dimension d = super.getPreferredSize(c);
    int v = Math.max(d.width, d.height);
    d.setSize(v, v);
    return d;
  }
  @Override public void paint(Graphics g, JComponent c) {
    Rectangle rect = SwingUtilities.calculateInnerArea(progressBar, null);
    if (rect.isEmpty()) {
      return;
    }
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    Object o = progressBar.getClientProperty("Slider.clockwise");
    int dir = Objects.equals(o, Boolean.TRUE) ? -1 : 1;
    double start = 90d;
    double degree = dir * 360d * progressBar.getPercentComplete();
    double sz = Math.min(rect.width, rect.height);
    double cx = rect.getCenterX();
    double cy = rect.getCenterY();
    double or = sz * .5;
    double ir = or * .5; // .8;
    Shape inner = new Ellipse2D.Double(cx - ir, cy - ir, ir * 2d, ir * 2d);
    Shape outer = new Ellipse2D.Double(cx - or, cy - or, sz, sz);
    Shape sector = new Arc2D.Double(cx - or, cy - or, sz, sz, start, degree, Arc2D.PIE);
    Area foreground = new Area(sector);
    Area background = new Area(outer);
    Area hole = new Area(inner);
    foreground.subtract(hole);
    background.subtract(hole);
    // Draw the track
    g2.setPaint(new Color(0xDD_DD_DD));
    g2.fill(background);
    // Draw the circular sector
    g2.setPaint(progressBar.getForeground());
    g2.fill(foreground);
    g2.dispose();
    // Deal with possible text painting
    if (progressBar.isStringPainted()) {
      Insets ins = progressBar.getInsets();
      paintString(g, rect.x, rect.y, rect.width, rect.height, 0, ins);
    }
  }
}
View in GitHub: Java, KotlinDescription
上記のサンプルでは、BasicProgressBarUI#paint(Graphics g, JComponent c)メソッドをオーバーライドして進捗状況を円形で表現するProgressBarUIを作成し、これをJProgressBarに設定しています。
- 表示上、中心から表示枠矩形の上辺中央を結ぶ線が弧の始角で時計回り方向が増加を表すように
Arc2Dを作成- 反時計回りの増加に切り替える
JCheckBoxを追加 
 - 反時計回りの増加に切り替える
 - 推奨サイズが常に正方形になるように、
BasicProgressBarUI#getPreferredSize(JComponent c)メソッドをオーバーライドしているので、JProgressBarの方向設定(SwingConstants.VERTICAL,SwingConstants.HORIZONTAL)は無視している - 不確定状態の描画は未対応
BasicProgressBarUI#paintDeterminate(...),BasicProgressBarUI#paintIndeterminate(...)メソッドはオーバーライドしていない
 
Reference
- OverlayLayoutで複数のJButtonを重ねて複合ボタンを作成
 - JProgressBarにUIを設定してインジケータの色を変更
 - JProgressBarの形状をドーナツ状の半円に変更してスピードメーターを作成する