减去圆弧的内半径/部分以获得环形进度条

时间:2019-01-04 21:52:21

标签: java swing graphics shapes

我正在尝试使用圆弧绘制圆环/局部圆环。

但是我需要局部环的中间是透明的并显示其背后的内容。由于我使用的是圆弧并将其旋转,是否有办法减去每个圆弧的内部,只留下所需厚度的一端,然后将其旋转以形成环?

到目前为止,这是我的代码:我的圆弧有效,但是我只是通过在每个圆弧上加上几个圆来模拟圆环,我实际上需要从每个圆弧中减去每个圆弧的面积。

不确定如何执行此操作以使中心透明。如果有更好的方法可以做到这一点,请告诉我,这将是一个自定义进度栏。

public class JCustomProgressBar extends JComponent{

private final Dimension SIZE = new Dimension( 50, 50 );

public JCustomProgressBar() {
    super();
    this.setVisible(true);
    System.out.println("CAlled");

}

int progress = 1;

public void updateProgress (int progress){
    this.progress = progress;
}


 @Override
 public void paintComponent (Graphics g){
   super.paintComponent(g);
   System.out.println("called");
   Graphics2D g2D = (Graphics2D) g.create();
   g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

   g2D.translate(this.getWidth()/2, this.getHeight()/2);
   g2D.rotate(Math.toRadians(270));
   Arc2D.Float arc = new Arc2D.Float (Arc2D.PIE);
   Ellipse2D circle = new Ellipse2D.Float(0, 0, 80, 80);
   arc.setFrameFromCenter (new Point(0,0), new Point (90, 90));
   circle.setFrameFromCenter(new Point(0,0), new Point (80, 80));
   arc.setAngleExtent(-progress*360/100);
   g2D.setColor(new Color(120,192,0));
   g2D.draw(arc);
   g2D.fill(arc);

   g2D.setColor(this.getParent().getBackground());
   g2D.draw(circle);
   g2D.fill(circle);

   arc.setFrameFromCenter (new Point(0,0), new Point (75, 75));
   arc.setAngleExtent(-90*360/100);
   g2D.setColor(new Color(197,228,146));
   g2D.draw(arc);
   g2D.fill(arc);

   circle.setFrameFromCenter(new Point(0,0), new Point (70, 70));
   g2D.setColor(this.getParent().getBackground());
   g2D.draw(circle);
   g2D.fill(circle);

   circle.setFrameFromCenter(new Point(0,0), new Point (60, 60));
   g2D.setColor(new Color(245, 245, 245));
   g2D.draw(circle);
   g2D.fill(circle);



   g2D.setColor(Color.black);
   g2D.rotate(Math.toRadians(90));
   g2D.setFont(new Font("Verdana", Font.PLAIN, 30));
   FontMetrics fm = g2D.getFontMetrics();
   Rectangle2D r2D = fm.getStringBounds(progress + "%", g);
   int x = (0 - (int) r2D.getWidth())/2;
   int y = (0 - (int) r2D.getHeight())/2 +fm.getAscent();
   g2D.drawString(progress + "%", x, y-10);

  //Rectangle2D r2d = fm.getStringBounds(progress + "", g);
  // g2D.setFont(new Font("Verdana", Font.PLAIN, 22));
  // g2D.drawString("%", x + 40, y-10);

   g2D.setFont(new Font("Verdana", Font.PLAIN, 15));
   g2D.drawString("Progress", -35, y+5);
   g2D.dispose();

}

}

1 个答案:

答案 0 :(得分:1)

您可以通过多种方式“这样做”,但是最简单的方法可能是只使用BasicStroke并简单地绘制圆弧(根本不填任何东西)

此示例故意设置背景颜色,以便您可以看到它是透明的。

Stroked

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

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();
                }

                JCustomProgressBar pb = new JCustomProgressBar();
                pb.setProgress(25);

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

    public class JCustomProgressBar extends JPanel {

        private final Dimension SIZE = new Dimension(200, 200);

        public JCustomProgressBar() {
            super();
            setBackground(Color.RED);
            // Uncomment this to make it transparent
            //setOpaque(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return SIZE;
        }

        int progress = 1;

        public void setProgress(int progress) {
            this.progress = progress;
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2D = (Graphics2D) g.create();
            g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            g2D.translate(this.getWidth() / 2, this.getHeight() / 2);

            BasicStroke bs = new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
            Arc2D.Float arc = new Arc2D.Float(Arc2D.OPEN);
            arc.setAngleStart(90);
            arc.setFrameFromCenter(new Point(0, 0), new Point(90, 90));
            arc.setAngleExtent(-((progress / 100d) * 360));
            g2D.setStroke(bs);
            g2D.setColor(new Color(120, 192, 0));
            g2D.draw(arc);

            bs = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
            arc.setFrameFromCenter(new Point(0, 0), new Point(75, 75));
            arc.setAngleExtent(-(((100 - progress) / 100d) * 360));
            g2D.setStroke(bs);
            g2D.setColor(new Color(197, 228, 146));
            g2D.draw(arc);

            g2D.setColor(Color.black);
            g2D.setFont(new Font("Verdana", Font.PLAIN, 30));
            FontMetrics fm = g2D.getFontMetrics();
            Rectangle2D r2D = fm.getStringBounds(progress + "%", g);
            int x = (0 - (int) r2D.getWidth()) / 2;
            int y = (0 - (int) r2D.getHeight()) / 2 + fm.getAscent();
            g2D.drawString(progress + "%", x, y - 10);

            g2D.setFont(new Font("Verdana", Font.PLAIN, 15));
            g2D.drawString("Progress", -35, y + 5);
            g2D.dispose();
        }

    }

}

您可以查看Stroking and Filling Graphics Primitives了解更多详细信息。

在您告诉我如何“不希望两端变圆”(因为我喜欢这样)之前,请确保您花时间阅读BasicStroke JavaDocs