我需要在音量旋钮周围画一条弧线,弧长代表音量。
我尝试了 Graphics.drawArc() 和 Arc2D.Double,但结果并不好:对于不同的范围值,弧的路径并不完全相同。
public class ArcComponent extends JComponent
{
private ImageIcon knobImage = new ImageIcon(ArcComponent.class.getResource("Knob-w37.png"));
int arcLength = 220; // Degrees
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Paint knob image
knobImage.paintIcon(this, g2, 20, 20);
// Add arc
var arc = new Arc2D.Double(22, 22, 32, 32, 220 - arcLength, arcLength, Arc2D.OPEN);
g2.setColor(Color.CYAN);
g2.setStroke(new BasicStroke(2));
g2.draw(arc);
g2.dispose();
}
void shorter()
{
arcLength -= 5;
if (arcLength < 0)
{
arcLength = 260;
}
repaint();
}
void longer()
{
arcLength += 5;
if (arcLength > 260)
{
arcLength = 0;
}
repaint();
}
}
如何确保圆弧的路径始终相同?
编辑:添加旋钮图像绘制
答案 0 :(得分:2)
一个肮脏的把戏:画一个完整的圆圈,然后用一个形状,背景颜色相同的颜色覆盖你不需要的部分。
像这样:
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Shape circle=new Ellipse2D.Double(20, 20, 30, 30);
g2.setColor(Color.CYAN);
g2.setStroke(new BasicStroke(2f));
g2.draw(circle);
Shape arc=new Arc2D.Double(10,10,50,50,230,360-arcLength,Arc2D.PIE);
g2.setColor(getBackground());
g2.fill(arc);
g2.dispose();
}
不幸的是,这需要在同一区域中的任何其他事物之前绘制弧线,但您可能可以解决这个问题。
EDIT:对于额外的约束,不一致的渲染实际上是由于笔划,所以尝试创建一个粗的形状并填充它,例如:
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
double thickness=8.0; //This replaces your stroke width
GeneralPath shape=new GeneralPath();
shape.append(new Arc2D.Double(20-thickness/2,20-thickness/2, 30+thickness, 30+thickness, 230, -arcLength, Arc2D.OPEN),false);
shape.append(new Arc2D.Double(20+thickness/2,20+thickness/2, 30-thickness, 30-thickness, 230-arcLength, arcLength, Arc2D.OPEN),true);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.CYAN);
g2.fill(shape);
g2.dispose();
}
答案 1 :(得分:0)
只需绘制一个完整的圆并夹在弧形上(使用一些填充以确保绘制所有内容)。
Graphics2D g2 = (Graphics2D) g.create();
Ellipse2D circle = new Ellipse2D.Double(20, 20, 30, 30);
int d = 2;
Arc2D arc = new Arc2D.Double(20 - d, 20 - d, 30 + 2 * d, 30 + 2 * d, 230, -arcLength, Arc2D.PIE);
g2.setColor(Color.CYAN);
g2.setClip(arc);
g2.setStroke(new BasicStroke(2f));
g2.draw(circle);
knobImage.paintIcon(this, g, 20, 20);