简体   繁体   English

Java:制作漂亮的JProgressBar

[英]Java: Making a pretty JProgressBar

I have been working with JProgressBars in java for not too long, and every resource I have seen for setting it to be pretty doesn't work. 我在Java中使用JProgressBars的时间不长,而且我所见过的将其设置为漂亮的所有资源均无法使用。 What I want is on applications you will see the whole progress bar filled from top to bottom, and when the value increases an animation plays with the increasing size. 我想要的是在应用程序上,您将看到整个进度条从上到下填充,并且当值增加时,动画将随着大小的增加而播放。 What I currently have is a JProgressBar that when it increases in value, it has no animation, and when it has an offset that goes to the top-right corner, like so: 我目前拥有的是一个JProgressBar ,当它的值增加时,它没有动画,并且当它的偏移量移到右上角时,如下所示:

在此处输入图片说明

As you can see, it is ugly. 如您所见,这很丑。 How can I get to see the full border, and the whole filling, and the animation to the JProgressBar ? 我如何才能看到完整的边框,整个填充以及JProgressBar的动画?

About the only way you could modify a JProgressBar in any meaningful way would be to design your own UI delegate... 关于以任何有意义的方式修改JProgressBar的唯一方法是设计自己的UI委托...

动画进度条

This is basically an example based on some work I did a long time ago. 这基本上是一个基于我很久以前所做的工作的示例。

The example updates the progress bar in increments of 25, but the progress bar "attempts" to fill from it's current position to the target value in small increments. 该示例以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);

            }

        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM