How to customize a JProgressBar?

后端 未结 1 1425
野的像风
野的像风 2020-11-30 09:23

I am making a launcher and I want to have a customized ProgressBar. I have done some research and it\'s possible with JavaFX(Never did something with it) and it\'s possible

相关标签:
1条回答
  • 2020-11-30 10:12

    There are a number of ways you might achieve this, one of the better ways would be to create a custom ProgressBarUI delegate which paints itself the way you want, for example...

    public class FancyProgressBar extends BasicProgressBarUI {
    
        @Override
        protected Dimension getPreferredInnerVertical() {
            return new Dimension(20, 146);
        }
    
        @Override
        protected Dimension getPreferredInnerHorizontal() {
            return new Dimension(146, 20);
        }
    
    
    
        @Override
        protected void paintDeterminate(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(progressBar.getBackground());
            g2d.setBackground(progressBar.getBackground());
    
            int width = progressBar.getWidth();
            int height = progressBar.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);
    
            double dProgress = progressBar.getPercentComplete();
            if (dProgress < 0) {
                dProgress = 0;
            } else if (dProgress > 1) {
                dProgress = 1;
            }
    
            iInnerWidth = (int) Math.round(iInnerWidth * dProgress);
    
            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 = {progressBar.getBackground(), progressBar.getBackground().brighter(), progressBar.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 paintIndeterminate(Graphics g, JComponent c) {
            super.paintIndeterminate(g, c); //To change body of generated methods, choose Tools | Templates.
        }
    
    }
    

    Normally you might be tempered to register this as the default look and feel delegate of all JProgressBars, but typically, I would install only on those instance of JProgressBar you really wanted it, that comes down to you.

    Progress

    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.GridBagConstraints;
    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.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.plaf.basic.BasicProgressBarUI;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    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 {
    
            public TestPane() {
                setBackground(Color.BLACK);
                JProgressBar fancyPB = new JProgressBar();
                fancyPB.setUI(new FancyProgressBar());
    
                JProgressBar normalPB = new JProgressBar();
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
    
                add(fancyPB, gbc);
                add(normalPB, gbc);
    
                Timer timer = new Timer(250, new ActionListener() {
    
                    private int count = 0;
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        fancyPB.setValue(count);
                        normalPB.setValue(count);
                        count++;
                        if (count >= 100) {
                            ((Timer)e.getSource()).stop();
                        }
                    }
                });
                timer.start();
            }
    
        }
    
        public class FancyProgressBar extends BasicProgressBarUI {
    
            @Override
            protected Dimension getPreferredInnerVertical() {
                return new Dimension(20, 146);
            }
    
            @Override
            protected Dimension getPreferredInnerHorizontal() {
                return new Dimension(146, 20);
            }
    
    
    
            @Override
            protected void paintDeterminate(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(progressBar.getBackground());
                g2d.setBackground(progressBar.getBackground());
    
                int width = progressBar.getWidth();
                int height = progressBar.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);
    
                double dProgress = progressBar.getPercentComplete();
                if (dProgress < 0) {
                    dProgress = 0;
                } else if (dProgress > 1) {
                    dProgress = 1;
                }
    
                iInnerWidth = (int) Math.round(iInnerWidth * dProgress);
    
                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 = {progressBar.getBackground(), progressBar.getBackground().brighter(), progressBar.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 paintIndeterminate(Graphics g, JComponent c) {
                super.paintIndeterminate(g, c); //To change body of generated methods, choose Tools | Templates.
            }
    
        }
    
    }
    

    If you want to install the look and feel delegate as the default delegate, take a look at this answer for more details (scroll down a little, it's there)

    0 讨论(0)
提交回复
热议问题