Java:制作一个漂亮的JProgressBar

Java:制作一个漂亮的JProgressBar,java,swing,animation,java-2d,jprogressbar,Java,Swing,Animation,Java 2d,Jprogressbar,我在java中使用JProgressBars的时间不长,我看到的用于将其设置为美观的所有资源都不起作用。我想要的是在应用程序上,您将看到整个进度条从上到下填充,当值增加时,动画将随着大小的增加而播放。我目前拥有的是一个JProgressBar,当它的值增加时,它没有动画,当它有一个到右上角的偏移量时,就像这样: 正如你所看到的,它是丑陋的。我如何才能看到整个边框、整个填充以及JProgressBar的动画?关于以任何有意义的方式修改JProgressBar的唯一方法是设计自己的UI委托 这基

我在java中使用
JProgressBars
的时间不长,我看到的用于将其设置为美观的所有资源都不起作用。我想要的是在应用程序上,您将看到整个进度条从上到下填充,当值增加时,动画将随着大小的增加而播放。我目前拥有的是一个
JProgressBar
,当它的值增加时,它没有动画,当它有一个到右上角的偏移量时,就像这样:


正如你所看到的,它是丑陋的。我如何才能看到整个边框、整个填充以及
JProgressBar
的动画?

关于以任何有意义的方式修改
JProgressBar
的唯一方法是设计自己的UI委托

这基本上是一个基于我很久以前做的一些工作的例子

该示例以25的增量更新进度条,但进度条“尝试”以较小的增量从其当前位置填充到目标值

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.BoundedRangeModel;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicProgressBarUI;

public class TestMediaProgressBar {

    public static void main(String[] args) {
        new TestMediaProgressBar();
    }

    public TestMediaProgressBar() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private MediaProgressBar pb;
        private int value = 0;
        private int delta = 25;

        public TestPane() {
            setBackground(Color.BLACK);
            setLayout(new GridBagLayout());
            pb = new MediaProgressBar();
            add(pb);

            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (value + delta > 100) {
                        delta *= -1;
                        value = 100;
                    } else if (value + delta < 0) {
                        delta *= -1;
                        value = 0;
                    }
                    value += delta;
                    pb.setValue(value);
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }

    public class MediaProgressBar extends JProgressBar {

        public MediaProgressBar() {
            setUI(new MediaProgressBarUI());
        }

        @Override
        public Dimension getPreferredSize() {

            return new Dimension(128, 24);

        }

    }

    public class MediaProgressBarUI extends BasicProgressBarUI {

        private Handler handler;
        private double renderProgress = 0;
        private double targetProgress = 0;
        private double progressDelta = 0.04;
        private Timer repaintTimer;
        private Timer paintTimer;

        public MediaProgressBarUI() {
            repaintTimer = new Timer(25, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    progressBar.repaint();
                }
            });
            repaintTimer.setRepeats(false);
            repaintTimer.setCoalesce(true);

            paintTimer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (progressDelta < 0) {

                        if (renderProgress + progressDelta < targetProgress) {
                            ((Timer) e.getSource()).stop();
                            renderProgress = targetProgress + progressDelta;
                        }

                    } else {

                        if (renderProgress + progressDelta > targetProgress) {
                            ((Timer) e.getSource()).stop();
                            renderProgress = targetProgress - progressDelta;
                        }

                    }
                    renderProgress += progressDelta;
                    requestRepaint();
                }
            });
        }

        protected void requestRepaint() {
            repaintTimer.restart();
        }

        @Override
        protected void installDefaults() {
            super.installDefaults();
            progressBar.setOpaque(false);
            progressBar.setBorder(null);
        }

        public void setRenderProgress(double value) {
            if (value != targetProgress) {
                paintTimer.stop();

                targetProgress = value;
                if (targetProgress < renderProgress && progressDelta > 0) {
                    progressDelta *= -1;
                } else if (targetProgress > renderProgress && progressDelta < 0) {
                    progressDelta *= -1;
                }
                System.out.println(progressDelta);

                paintTimer.start();
            }
        }

        public double getRenderProgress() {
            return renderProgress;
        }

        @Override
        public void paint(Graphics g, JComponent c) {
            Graphics2D g2d = (Graphics2D) g.create();

            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int iStrokWidth = 3;
            g2d.setStroke(new BasicStroke(iStrokWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2d.setColor(c.getBackground());
            g2d.setBackground(c.getBackground());

            int width = c.getWidth();
            int height = c.getHeight();

            RoundRectangle2D outline = new RoundRectangle2D.Double((iStrokWidth / 2), (iStrokWidth / 2),
                    width - iStrokWidth, height - iStrokWidth,
                    height, height);

            g2d.draw(outline);

            int iInnerHeight = height - (iStrokWidth * 4);
            int iInnerWidth = width - (iStrokWidth * 4);

            iInnerWidth = (int) Math.round(iInnerWidth * renderProgress);

            int x = iStrokWidth * 2;
            int y = iStrokWidth * 2;

            Point2D start = new Point2D.Double(x, y);
            Point2D end = new Point2D.Double(x, y + iInnerHeight);

            float[] dist = {0.0f, 0.25f, 1.0f};
            Color[] colors = {c.getBackground(), c.getBackground().brighter(), c.getBackground().darker()};
            LinearGradientPaint p = new LinearGradientPaint(start, end, dist, colors);

            g2d.setPaint(p);

            RoundRectangle2D fill = new RoundRectangle2D.Double(iStrokWidth * 2, iStrokWidth * 2,
                    iInnerWidth, iInnerHeight, iInnerHeight, iInnerHeight);

            g2d.fill(fill);

            g2d.dispose();
        }

        @Override
        protected void installListeners() {
            super.installListeners();
            progressBar.addChangeListener(getChangeHandler());
        }

        protected ChangeListener getChangeHandler() {

            return getHandler();

        }

        protected Handler getHandler() {

            if (handler == null) {
                handler = new Handler();
            }

            return handler;

        }

        protected class Handler implements ChangeListener {

            @Override
            public void stateChanged(ChangeEvent e) {

                BoundedRangeModel model = progressBar.getModel();
                int newRange = model.getMaximum() - model.getMinimum();
                double dProgress = (double) (model.getValue() / (double) newRange);

                if (dProgress < 0) {
                    dProgress = 0;
                } else if (dProgress > 1) {
                    dProgress = 1;
                }

                setRenderProgress(dProgress);

            }

        }

    }

}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.GridBagLayout;
导入java.awt.LinearGradientPaint;
导入java.awt.RenderingHints;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.geom.Point2D;
导入java.awt.geom.RoundRectangle2D;
导入javax.swing.BoundedRangeModel;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JProgressBar;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
导入javax.swing.event.ChangeEvent;
导入javax.swing.event.ChangeListener;
导入javax.swing.plaf.basic.BasicProgressBarUI;
公共类TestMediaProgressBar{
公共静态void main(字符串[]args){
新的TestMediaProgressBar();
}
公共TestMediaProgressBar(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私人媒体;
私有int值=0;
私有整数增量=25;
公共测试窗格(){
挫折背景(颜色:黑色);
setLayout(新的GridBagLayout());
pb=新的MediaProgressBar();
添加(pb);
计时器计时器=新计时器(500,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
如果(值+增量>100){
delta*=-1;
数值=100;
}否则如果(值+增量<0){
delta*=-1;
数值=0;
}
值+=增量;
pb.设定值(值);
}
});
timer.start();
}
@凌驾
公共维度getPreferredSize(){
返回新维度(200200);
}
}
公共类MediaProgressBar扩展了JProgressBar{
公共媒体{
setUI(newmediaprogressbarui());
}
@凌驾
公共维度getPreferredSize(){
返回新维度(128,24);
}
}
公共类MediaProgressBarUI扩展了BasicProgressBarUI{
私人经办人;
私有双渲染进程=0;
私有双目标进度=0;
私人双进位增量=0.04;
专用定时器重绘定时器;
私人定时器;
PublicMediaProgressBarUI(){
RepaitTimer=新计时器(25,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
progressBar.repaint();
}
});
repaittimer.setRepeats(false);
repaittimer.setCoalesce(true);
paintTimer=新计时器(40,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
if(progressDelta<0){
if(渲染进度+进度增量<目标进度){
((计时器)e.getSource()).stop();
renderProgress=targetProgress+progressDelta;
}
}否则{
if(渲染进度+进度增量>目标进度){
((计时器)e.getSource()).stop();
renderProgress=targetProgress-progressDelta;
}
}
renderProgress+=progressDelta;
requestRepaint();
}
});
}
受保护的void requestRepaint(){
repaittimer.restart();
}
@凌驾
受保护的void installDefaults(){
super.installDefaults();
progressBar.set不透明(false);
progressBar.setboorder(空);
}
public void setRenderProgress(双值){
如果(值!=targetProgress){
paintTimer.stop();
目标进度=价值;
我