Swing/StringPaintedCellProgressBar の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/StringPaintedCellProgressBar へ行く。
- Swing/StringPaintedCellProgressBar の差分を削除
--- category: swing folder: StringPaintedCellProgressBar title: TableCellRendererに進捗文字列を設定したJProgressBarを使用する tags: [JTable, JProgressBar, SwingWorker, TableCellRenderer] author: aterai pubdate: 2014-03-24T00:27:55+09:00 description: JTableのTableCellRendererとして、進捗文字列を表示するJProgressBarを設定します。 image: https://lh4.googleusercontent.com/-XSMYQI-BTU8/Uy67ZR-E4TI/AAAAAAAACCE/2zdsU6o7iA0/s800/StringPaintedCellProgressBar.png hreflang: href: https://java-swing-tips.blogspot.com/2014/05/jprogressbar-in-jtable-cell-render.html lang: en --- * 概要 [#summary] `JTable`の`TableCellRenderer`として、進捗文字列を表示する`JProgressBar`を設定します。 #download(https://lh4.googleusercontent.com/-XSMYQI-BTU8/Uy67ZR-E4TI/AAAAAAAACCE/2zdsU6o7iA0/s800/StringPaintedCellProgressBar.png) * サンプルコード [#sourcecode] #code(link){{ class Task extends SwingWorker<Integer, ProgressValue> { private final int lengthOfTask; private final int sleepDummy = new Random().nextInt(100) + 1; private final int randomSleep = new Random().nextInt(100) + 1; public Task(int lengthOfTask) { super(); this.lengthOfTask = lengthOfTask; } @Override protected Integer doInBackground() { int current = 0; while (current < lengthOfTask && !isCancelled()) { current++; try { Thread.sleep(sleepDummy); Thread.sleep(randomSleep); } catch (InterruptedException ie) { break; } publish(new ProgressValue(lengthOfTask, current)); } return sleepDummy * lengthOfTask; return randomSleep * lengthOfTask; } } class ProgressValue { private final Integer progress; private final Integer lengthOfTask; public ProgressValue(Integer lengthOfTask, Integer progress) { this.progress = progress; this.lengthOfTask = lengthOfTask; } public Integer getProgress() { return progress; } public Integer getLengthOfTask() { return lengthOfTask; } } class ProgressRenderer extends DefaultTableCellRenderer { private final JProgressBar progress = new JProgressBar(); private final JPanel renderer = new JPanel(new BorderLayout()); @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component c; renderer.removeAll(); progress.setValue(0); if (value instanceof ProgressValue) { ProgressValue pv = (ProgressValue) value; Integer current = pv.getProgress(); Integer lengthOfTask = pv.getLengthOfTask(); if (current < 0) { c = super.getTableCellRendererComponent( table, "Canceled", isSelected, hasFocus, row, column); } else if (current < lengthOfTask) { progress.setValue(current * 100 / lengthOfTask); progress.setStringPainted(true); progress.setString(String.format("%d/%d", current, lengthOfTask)); renderer.add(progress); c = renderer; } else { c = super.getTableCellRendererComponent( table, "Done", isSelected, hasFocus, row, column); } } else { c = super.getTableCellRendererComponent( table, "Waiting...", isSelected, hasFocus, row, column); } return c; } @Override public void updateUI() { super.updateUI(); setOpaque(true); if (Objects.nonNull(renderer)) { SwingUtilities.updateComponentTreeUI(renderer); } } } }} * 解説 [#explanation] 上記のサンプルでは、`2`列目の`TableCellRenderer`として`JProgressBar#setStringPainted(true)`で進捗文字列を表示するように設定した`JProgressBar`を使用しています。 - 進捗状況文字列は「現在値/最大値」の形式で表示するため、この`2`つの値を保持する`ProgressValue`オブジェクトを作成して`SwingWorker#publish(...)`メソッドで`JTable`のモデルに設定 - `TableCellRenderer`はモデルから取得した`ProgressValue`オブジェクトから以下の`3`つの値を`JProgressBar`に設定し、セルの描画用コンポーネントとして使用 -- `JProgressBar#setMaximum(int)`(最大値は各行ごとにランダムなので)で最大値を設定 -- `JProgressBar#setValue(int)`で現在値を設定 -- 上記の値から生成した進捗状況文字列を`JProgressBar#setString(String)`で設定 * 参考リンク [#reference] - [[JTableのセルにJProgressBarを表示>Swing/TableCellProgressBar]] * コメント [#comment] #comment #comment