Swing/IndeterminateRegionPainter のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/IndeterminateRegionPainter へ行く。
- 1 (2014-06-30 (月) 15:57:20)
- 2 (2014-07-14 (月) 00:16:34)
- 3 (2014-10-11 (土) 16:55:44)
- 4 (2015-11-11 (水) 20:04:21)
- 5 (2017-05-09 (火) 17:57:00)
- 6 (2017-07-24 (月) 20:08:17)
- 7 (2018-07-24 (火) 17:52:42)
- 8 (2020-07-25 (土) 03:47:29)
- 9 (2021-12-21 (火) 16:28:59)
- 10 (2025-01-03 (金) 08:57:02)
- 11 (2025-01-03 (金) 09:01:23)
- 12 (2025-01-03 (金) 09:02:38)
- 13 (2025-01-03 (金) 09:03:21)
- 14 (2025-01-03 (金) 09:04:02)
- 15 (2025-06-19 (木) 12:41:37)
- 16 (2025-06-19 (木) 12:43:47)
TITLE:JProgressBarのNimbusLookAndFeelにおける不確定状態アニメーションを変更する
Posted by aterai at 2014-06-30
JProgressBarのNimbusLookAndFeelにおける不確定状態アニメーションを変更する
JProgressBarをNimbusLookAndFeelで使用している場合、その不確定状態アニメーションを変更します。
Screenshot

Advertisement
サンプルコード
UIDefaults d = new UIDefaults();
d.put("ProgressBar[Enabled+Indeterminate].foregroundPainter", new AbstractRegionPainter() {
//...
private final PaintContext ctx = new PaintContext(
new Insets(5, 5, 5, 5), new Dimension(29, 19), false);
@Override public void doPaint(
Graphics2D g, JComponent c, int width, int height, Object[] extendedCacheKeys) {
path = decodePath1();
g.setPaint(color17);
g.fill(path);
rect = decodeRect3();
g.setPaint(decodeGradient5(rect));
g.fill(rect);
rect = decodeRect4();
g.setPaint(decodeGradient6(rect));
g.fill(rect);
}
@Override public PaintContext getPaintContext() {
return ctx;
}
//...
});
progressBar1 = new JProgressBar(model);
progressBar1.putClientProperty("Nimbus.Overrides", d);
View in GitHub: Java, Kotlin解説
上記のサンプルでは、NimbusLookAndFeelでJProgressBarの不確定状態アニメーションを変更するために、セルの描画を行うAbstractRegionPainter#doPaint(...)をオーバーライドし、これをUIDefaultsに設定しています。
- テスト:
BasicLookAndFeelの場合のサンプル
//package example;
//-*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
//@homepage@
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.nimbus.*;
public final class StripedProgressBar extends JPanel implements HierarchyListener {
private final BoundedRangeModel model = new DefaultBoundedRangeModel();
private final JProgressBar progressBar0 = new JProgressBar(model);
private final JProgressBar progressBar1;
private SwingWorker<String, Void> worker;
public StripedProgressBar() {
super(new BorderLayout());
UIManager.put("ProgressBar.cycleTime", 1000);
UIManager.put("ProgressBar.repaintInterval", 10);
progressBar0.setUI(new BasicProgressBarUI() {
@Override protected int getBoxLength(int availableLength, int otherDimension) {
return availableLength; //(int)Math.round(availableLength/6.0);
}
@Override public void paintIndeterminate(Graphics g, JComponent c) {
if (!(g instanceof Graphics2D)) {
return;
}
Insets b = progressBar.getInsets(); // area for border
int barRectWidth = progressBar.getWidth() - b.right - b.left;
int barRectHeight = progressBar.getHeight() - b.top - b.bottom;
if (barRectWidth <= 0 || barRectHeight <= 0) {
return;
}
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Paint the bouncing box.
boxRect = getBox(boxRect);
if (boxRect != null) {
int w = 10;
int x = getAnimationIndex();
GeneralPath p = new GeneralPath();
p.moveTo(boxRect.x, boxRect.y);
p.lineTo(boxRect.x + w * .5f, boxRect.y + boxRect.height);
p.lineTo(boxRect.x + w, boxRect.y + boxRect.height);
p.lineTo(boxRect.x + w * .5f, boxRect.y);
p.closePath();
g2.setColor(progressBar.getForeground());
AffineTransform at = AffineTransform.getTranslateInstance(x, 0);
for (int i = -x; i < boxRect.width; i += w) {
g2.fill(AffineTransform.getTranslateInstance(i, 0).createTransformedShape(p));
}
}
}
});
progressBar1 = new JProgressBar(model);
progressBar1.setUI(new BasicProgressBarUI() {
@Override protected int getBoxLength(int availableLength, int otherDimension) {
return availableLength; //(int)Math.round(availableLength/6.0);
}
@Override public void paintIndeterminate(Graphics g, JComponent c) {
if (!(g instanceof Graphics2D)) {
return;
}
Insets b = progressBar.getInsets(); // area for border
int barRectWidth = progressBar.getWidth() - b.right - b.left;
int barRectHeight = progressBar.getHeight() - b.top - b.bottom;
if (barRectWidth <= 0 || barRectHeight <= 0) {
return;
}
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Paint the bouncing box.
boxRect = getBox(boxRect);
if (boxRect != null) {
int w = 10;
int x = getAnimationIndex();
GeneralPath p = new GeneralPath();
p.moveTo(boxRect.x, boxRect.y + boxRect.height);
p.lineTo(boxRect.x + w * .5f, boxRect.y + boxRect.height);
p.lineTo(boxRect.x + w, boxRect.y);
p.lineTo(boxRect.x + w * .5f, boxRect.y);
p.closePath();
g2.setColor(progressBar.getForeground());
AffineTransform at = AffineTransform.getTranslateInstance(x, 0);
for (int i = boxRect.width + x; i > -w; i -= w) {
g2.fill(AffineTransform.getTranslateInstance(i, 0).createTransformedShape(p));
}
}
}
});
JPanel p = new JPanel(new GridLayout(2, 1));
p.add(makeTitlePanel("Default", progressBar0));
p.add(makeTitlePanel("ProgressBar[Indeterminate].foregroundPainter", progressBar1));
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(new JButton(new AbstractAction("Test start") {
@Override public void actionPerformed(ActionEvent e) {
if (worker != null && !worker.isDone()) {
worker.cancel(true);
}
progressBar0.setIndeterminate(true);
progressBar1.setIndeterminate(true);
worker = new Task();
worker.addPropertyChangeListener(new ProgressListener(progressBar0));
worker.addPropertyChangeListener(new ProgressListener(progressBar1));
worker.execute();
}
}));
box.add(Box.createHorizontalStrut(5));
addHierarchyListener(this);
add(p);
add(box, BorderLayout.SOUTH);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setPreferredSize(new Dimension(320, 240));
}
@Override public void hierarchyChanged(HierarchyEvent he) {
JComponent c = (JComponent) he.getComponent();
if ((he.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0 && !c.isDisplayable() && worker != null) {
System.out.println("DISPOSE_ON_CLOSE");
worker.cancel(true);
worker = null;
}
}
private static JComponent makeTitlePanel(String title, JComponent cmp) {
JPanel p = new JPanel(new GridBagLayout());
p.setBorder(BorderFactory.createTitledBorder(title));
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5, 5, 5, 5);
c.weightx = 1.0;
c.gridy = 0;
p.add(cmp, c);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame frame = new JFrame("@title@");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new StripedProgressBar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class Task extends SwingWorker<String, Void> {
@Override public String doInBackground() {
try { // dummy task
Thread.sleep(5000);
} catch (InterruptedException ie) {
return "Interrupted";
}
int current = 0;
int lengthOfTask = 100;
while (current <= lengthOfTask && !isCancelled()) {
try { // dummy task
Thread.sleep(50);
} catch (InterruptedException ie) {
return "Interrupted";
}
setProgress(100 * current / lengthOfTask);
current++;
}
return "Done";
}
}
class ProgressListener implements PropertyChangeListener {
private final JProgressBar progressBar;
public ProgressListener(JProgressBar progressBar) {
this.progressBar = progressBar;
this.progressBar.setValue(0);
}
@Override public void propertyChange(PropertyChangeEvent evt) {
String strPropertyName = evt.getPropertyName();
if ("progress".equals(strPropertyName)) {
progressBar.setIndeterminate(false);
int progress = (Integer) evt.getNewValue();
progressBar.setValue(progress);
}
}
}
