我正在尝试使用圆弧绘制圆环/局部圆环。
但是我需要局部环的中间是透明的并显示其背后的内容。由于我使用的是圆弧并将其旋转,是否有办法减去每个圆弧的内部,只留下所需厚度的一端,然后将其旋转以形成环?
到目前为止,这是我的代码:我的圆弧有效,但是我只是通过在每个圆弧上加上几个圆来模拟圆环,我实际上需要从每个圆弧中减去每个圆弧的面积。
不确定如何执行此操作以使中心透明。如果有更好的方法可以做到这一点,请告诉我,这将是一个自定义进度栏。
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();
}
}
答案 0 :(得分:1)
您可以通过多种方式“这样做”,但是最简单的方法可能是只使用BasicStroke
并简单地绘制圆弧(根本不填任何东西)
此示例故意设置背景颜色,以便您可以看到它是透明的。
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