java - 如何自定义一个 JProgressBar?

标签 java swing jprogressbar

我正在制作一个启动器,我想要一个自定义的 ProgressBar。 我已经做了一些研究,JavaFX 是可能的(从来没有用它做过什么)并且可以替换 UI。 我正在寻找具有圆形边缘和圆形填充的条形。 像这样:

package gui;

import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class Gui extends JFrame {

    private static final long serialVersionUID = 1L;
    private final JPanel contentPane;
    final JFrame frame = new JFrame();
    int pX,pY;

    /**
     * Launch the application.
     */
    public static void main(final String[] args) {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    final Gui frame = new Gui();
                    frame.setVisible(true);
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }


    /**
     * Create the frame.
     */
    public Gui() {
        this.setTitle("Exile Launcher");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(0, 0, 1000, 563);
        this.contentPane = new JPanel();
        this.contentPane.setBorder(null);
        this.setContentPane(this.contentPane);
        this.contentPane.setLayout(null);
        this.setUndecorated(true);
        this.setLocation(Toolkit.getDefaultToolkit().getScreenSize().width/2-this.getSize().width/2, Toolkit.getDefaultToolkit().getScreenSize().height/2-this.getSize().height/2);

        int X = 24;
        int Y = 40; 

        final JButton HomeButton = new JButton();
        HomeButton.setFocusPainted(false);
        HomeButton.setBorder(null);
        HomeButton.setContentAreaFilled(false);
        HomeButton.setIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/0.png")));
        HomeButton.setRolloverIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/0_h.png")));
        HomeButton.setBounds(new Rectangle(X, Y, 50, 50));
        this.contentPane.add(HomeButton);
        HomeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                try {
                    Desktop.getDesktop().browse(new URL("http://www.google.nl").toURI());
                } catch (IOException | URISyntaxException e1) {
                    e1.printStackTrace();
                }
            }
        });

        Y += 60;

        final JButton ForumButton = new JButton();
        ForumButton.setFocusPainted(false);
        ForumButton.setBorder(null);
        ForumButton.setContentAreaFilled(false);
        ForumButton.setIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/1.png")));
        ForumButton.setRolloverIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/1_h.png")));
        ForumButton.setBounds(new Rectangle(X, Y, 50, 50));
        this.contentPane.add(ForumButton);

        Y += 60;

        final JButton VoteButton = new JButton();
        VoteButton.setFocusPainted(false);
        VoteButton.setBorder(null);
        VoteButton.setContentAreaFilled(false);
        VoteButton.setIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/4.png")));
        VoteButton.setRolloverIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/4_h.png")));
        VoteButton.setBounds(new Rectangle(X, Y, 50, 50));
        this.contentPane.add(VoteButton);

        final JButton CloseButton = new JButton();
        CloseButton.setFocusPainted(false);
        CloseButton.setBorder(null);
        CloseButton.setContentAreaFilled(false);
        CloseButton.setIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/Close.png")));
        CloseButton.setRolloverIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/Close_h.png")));
        CloseButton.setBounds(new Rectangle(875, 0, 27, 28));
        this.contentPane.add(CloseButton);
        CloseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                System.exit(0);
            }
        });

        final JButton MinimizeButton = new JButton();
        MinimizeButton.setFocusPainted(false);
        MinimizeButton.setBorder(null);
        MinimizeButton.setContentAreaFilled(false);
        MinimizeButton.setIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/Minimize.png")));
        MinimizeButton.setRolloverIcon(new ImageIcon(this.getClass().getClassLoader().getResource("Images/Minimize_h.png")));
        MinimizeButton.setBounds(new Rectangle(850, -1, 27, 28));
        this.contentPane.add(MinimizeButton);
        MinimizeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                setState(Frame.ICONIFIED);
            }
        });

        final JProgressBar ProgressBar = new JProgressBar();
        ProgressBar.setLocation(150, 500);
        ProgressBar.setSize(600, 50);
        ProgressBar.setValue(50);
        getContentPane().add(ProgressBar);

        final JLabel backgroundLabel = new JLabel(new ImageIcon(this.getClass().getClassLoader().getResource("Images/Background.png")));
        backgroundLabel.setBounds(new Rectangle(0, 0, 1000, 563));
        getContentPane().add(backgroundLabel);

        JPanel titleBar = new JPanel();
        titleBar.setBounds(0, 0, 1000, 25);
        contentPane.add(titleBar);


        titleBar.addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent me)
            {
                // Get x,y and store them
                pX=me.getX();
                pY=me.getY();
            }
        });

        titleBar.addMouseMotionListener(new MouseAdapter(){
            public void mouseDragged(MouseEvent me)
            {
                setLocation(getLocation().x+me.getX()-pX,getLocation().y+me.getY()-pY);
            }
        }); 
    }
}

最佳答案

您可以通过多种方式实现这一目标,其中一种更好的方式是创建一个自定义 ProgressBarUI 委托(delegate),它可以按照您想要的方式自行绘制,例如...

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.
    }

}

通常情况下,您可能会倾向于将其注册为所有 JProgressBar 的默认外观委托(delegate),但通常情况下,我只会在您的 JProgressBar 实例上安装真的想要它,这取决于你。

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.
        }

    }

}

如果您想将外观委托(delegate)安装为默认委托(delegate),请查看 this answer有关更多详细信息(向下滚动一点,它就在那里)

关于java - 如何自定义一个 JProgressBar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28908135/

相关文章:

java : when is this method called : getTableCellRendererComponent?

java - 仅在一侧的圆角边框 java

Swing 中的 Java ProgressBar

java - 可选的 <Integer> 不能转换为 Int(用于 GUI 进度条)

java - 更改 Swing 进度条的外观

java - 在 Java 中使用 BulkWriteOperation 的数据更新插入问题

java - Go 的等价于 'throws' 的子句是什么?

java - Wicket 中的不同页面有多个超时期限吗?

java - 如何确定指纹图像前景区域的边界

java - 设置按钮模型使复选框不可操作