在java中绘制一个圈的切片? [英] Drawing slices of a circle in java?

查看:117
本文介绍了在java中绘制一个圈的切片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望通过在整个定时器的分段上绘制一个实心圆来表示定时器。即如果在4秒的时间内每隔1秒就会填充一个圆圈,则第一个会显示四分之一圆圈,然后是一半的四分之三,最后是一个完整的圆圈。



<有没有办法在java中绘制这些圆的切片?我研究过图形API中的任意形状,但不知道这是否是正确的方式,或者是否有写入语言的东西可以轻松生成这些类型的形状?

非常感谢任何帮助。

解决方案

是的,这是可能的。是的,Graphics2D有能力为你做这件事

看看绘制几何图元(查找Arc2D部分)。



它可能最容易使用 javax.swing.Timer ,但您的需求可能需要您使用 SwingWorker 代替。查看 Swing中的货币如何使用Swing Timers 获取更多信息。



下面的例子比较简单。它假定0-100%的进展并根据需要生成一个弧。改变 Graphics2D 上下文的颜色并使用 draw(Shape)绘制一个out你需要一个圆圈的线。



  import java.awt.Color; 
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ArcProgress {

public static void main(String [] args){
new ArcProgress();
}
私人浮动进度;

public ArcProgress(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
}

final ArcProgressPane p1 = new ArcProgressPane );
p1.setForeground(Color.RED);
final ArcProgressPane p2 = new ArcProgressPane();
p2.setForeground(Color.BLUE);
p2.setFillProgress(true );

JFrame frame = new JFrame(Testing);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(p1);
frame.add (P2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

Timer timer = new Timer(40,new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
progress + = 0.01f;
if(progress> = 1f){
progress = 1f;
((Timer)e.getSource())。stop();
}
p1。 setProgress(progress);
p2.setProgress(progress);
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();

}
});
}

public class ArcProgressPane extends JPanel {

private boolean fillProgress = false;
私人浮动进度;

public ArcProgressPane(){
}
$ b $ public void setFillProgress(boolean value){
if(fillProgress!= value){
this.fillProgress = value;
firePropertyChange(fillProgress,!fillProgress,fillProgress);
}
}

public boolean isFillProgress(){
return fillProgress;
}

@Override
public Dimension getPreferredSize(){
return new Dimension(100,100);

$ b $ public void setProgress(float value){
if(progress!= value){
float old = progress;
this.progress = value;
firePropertyChange(progress,old,progress);
repaint();



public float getProgress(){
return progress;


@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);

Graphics2D g2d =(Graphics2D)g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_PURE);

Insets insets = getInsets();
int width = getWidth() - (insets.left + insets.right);
int height = getHeight() - (insets.bottom + insets.top);
int raidus = Math.min(width,height);
int x = insets.left +((width - raidus)/ 2);
int y = insets.right +((height - raidus)/ 2);

double extent = 360d *进度;

g2d.setColor(getForeground());
Arc2D arc = null;
if(isFillProgress()){
arc = new Arc2D.Double(x,y,raidus,raidus,90,-extent,Arc2D.PIE);
} else {
extent = 360 - 范围;
arc = new Arc2D.Double(x,y,raidus,raidus,90,extent,Arc2D.PIE);
}
g2d.fill(arc);
g2d.dispose();
}
}
}


I want to represent a timer by having a filled circle which is fully drawn over the course of the timer by segment. I.e. If the circle is filled in every 1 second for a timer of 4 seconds the first will show a quarter of a circle then a half then three-quarters and finally a full circle.

Is there a way to draw these slices of a circle in java? I've looked into arbitrary shapes in the graphics API but not sure if this is the right way to go or if there is something written into the language which can easily produce these type of shapes?

Any help much appreciated.

解决方案

Yes, it's possible. Yes, Graphics2D has the ability to do this for you

Take a look at Drawing Geometric Primitives (look for the Arc2D section).

To "animate" the progress, it would probably be easiest to use a javax.swing.Timer, but your requirements might require you to use a SwingWorker instead. Have a look at Currency in Swing and How to use Swing Timers for more information.

The following example is relatively simple. It assumes a progress of 0-100% and generates a arc as required. It would be a simple matter of changing the color of the Graphics2D context and using draw(Shape) to draw an out line of the circle should you want one.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ArcProgress {

    public static void main(String[] args) {
        new ArcProgress();
    }
    private float progress;

    public ArcProgress() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                final ArcProgressPane p1 = new ArcProgressPane();
                p1.setForeground(Color.RED);
                final ArcProgressPane p2 = new ArcProgressPane();
                p2.setForeground(Color.BLUE);
                p2.setFillProgress(true);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new FlowLayout());
                frame.add(p1);
                frame.add(p2);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        progress += 0.01f;
                        if (progress >= 1f) {
                            progress = 1f;
                            ((Timer) e.getSource()).stop();
                        }
                        p1.setProgress(progress);
                        p2.setProgress(progress);
                    }
                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();

            }
        });
    }

    public class ArcProgressPane extends JPanel {

        private boolean fillProgress = false;
        private float progress;

        public ArcProgressPane() {
        }

        public void setFillProgress(boolean value) {
            if (fillProgress != value) {
                this.fillProgress = value;
                firePropertyChange("fillProgress", !fillProgress, fillProgress);
            }
        }

        public boolean isFillProgress() {
            return fillProgress;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

        public void setProgress(float value) {
            if (progress != value) {
                float old = progress;
                this.progress = value;
                firePropertyChange("progress", old, progress);
                repaint();
            }
        }

        public float getProgress() {
            return progress;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            Insets insets = getInsets();
            int width = getWidth() - (insets.left + insets.right);
            int height = getHeight() - (insets.bottom + insets.top);
            int raidus = Math.min(width, height);
            int x = insets.left + ((width - raidus) / 2);
            int y = insets.right + ((height - raidus) / 2);

            double extent = 360d * progress;

            g2d.setColor(getForeground());
            Arc2D arc = null;
            if (isFillProgress()) {
                arc = new Arc2D.Double(x, y, raidus, raidus, 90, -extent, Arc2D.PIE);
            } else {
                extent = 360 - extent;
                arc = new Arc2D.Double(x, y, raidus, raidus, 90, extent, Arc2D.PIE);
            }
            g2d.fill(arc);
            g2d.dispose();
        }
    }
}

这篇关于在java中绘制一个圈的切片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆