Вычитание внутреннего радиуса / части дуги для достижения индикатора выполнения стиля кольца - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь нарисовать кольцо / частичное кольцо, используя дуги.

Но мне нужно, чтобы середина частичного кольца / кольца была прозрачной и показывала, что за этим стоит. Поскольку я использую дугу и вращаю ее, есть ли способ вычесть внутреннюю часть каждой дуги и оставить только конец нужной толщины, который будет вращаться для создания кольца?

Пока это мой код: у меня работают дуги, но я имитирую кольцо только наложением на каждую пару кружков, мне нужно вычесть площадь каждого круга из каждой дуги.

Не уверен, как это сделать, чтобы добиться прозрачности в центре. Если есть лучший способ сделать это, пожалуйста, дайте мне знать, это будет пользовательский индикатор выполнения.

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 голосов
/ 05 января 2019

Есть несколько способов, которыми вы могли бы это сделать, но простейшим может быть просто использовать 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();
        }

    }

}

Вы можете взглянуть на Поглаживание и заполнение графических примитивов для получения более подробной информации.

Прежде чем вы скажете мне, как вы "не хотите, чтобы концы были округлены" (потому что мне это нравится так), убедитесь, что вы нашли время, чтобы прочитать BasicStroke JavaDocs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...