如何自定义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委托,以自己想要的方式绘制自己,例如……

 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的默认外观JProgressBar ,但通常情况下,我只会安装在您真正想要它的JProgressBar实例上,这取决于您。

进展

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

如果要将外观委托作为默认委托安装,请查看此答案以获取更多详细信息(向下滚动一下,它就在那里)