I need yo draw a shape as attached in the image using Java graphics. I am struggling with the curve part. The curve part is a arc of an circle whose radius and center is known. But I have to paint the region out side of that arc. How will I do that? I was looking at Path2D.Float() and there is a guadTo function. It says it needs a control point to draw that quadratic curve. Can anybody help me understanding what this control point means. I know how to draw that arc using drawArc method but how to paint outside the arc is what I what I want to know

Recommended Answers

All 3 Replies

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * @see <a href="http://keithp.com/~keithp/porterduff/p253-porter.pdf">Porter-Duff</a>
 * @see <a href="http://www.ibm.com/developerworks/java/library/j-mer0918/">Zukowski</a>
 * @author John B. Matthews
 */
public class AlphaCompositeDemo extends JPanel {

    private static final Rule defaultRule = Rule.Xor;
    private static final String form = "0.00";
    private static final Border border = BorderFactory.createEmptyBorder(4, 16, 4, 16);
    private static final long serialVersionUID = 1L;
    private AlphaView view;
    private JSpinner srcSpin, dstSpin;
    private JComboBox rules;
    private final JTextArea text;

    public AlphaCompositeDemo() {
        super(true);
        this.setLayout(new BorderLayout());
        System.out.println(this.isOpaque());
        JLabel titleLabel = new JLabel("AlphaComposite");
        titleLabel.setHorizontalAlignment(JLabel.CENTER);
        titleLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
        this.add(titleLabel, BorderLayout.NORTH);
        view = new AlphaView();
        view.setBorder(border);
        this.add(view, BorderLayout.CENTER);
        rules = new JComboBox();
        for (Rule rule : Rule.values()) {
            rules.addItem(rule);
        }
        rules.setSelectedItem(defaultRule);
        view.setRule(defaultRule);
        rules.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Rule rule = (Rule) rules.getSelectedItem();
                view.setRule(rule);
                text.setText(rule.getDescription());
            }
        });
        srcSpin = new JSpinner();
        srcSpin.setModel(new SpinnerNumberModel(1.0, 0, 1.0, 0.1));
        srcSpin.setEditor(new JSpinner.NumberEditor(srcSpin, form));
        srcSpin.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                Number n = (Number) srcSpin.getValue();
                view.setSrcAlpha(n.floatValue());
            }
        });
        dstSpin = new JSpinner();
        dstSpin.setModel(new SpinnerNumberModel(1.0, 0, 1.0, 0.1));
        dstSpin.setEditor(new JSpinner.NumberEditor(dstSpin, form));
        dstSpin.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                Number n = (Number) dstSpin.getValue();
                view.setDstAlpha(n.floatValue());
            }
        });
        JRadioButton hexButton = new JRadioButton("Hex");
        hexButton.setMnemonic(KeyEvent.VK_H);
        hexButton.setSelected(true);
        hexButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                view.setRadix(16);
            }
        });
        JRadioButton decButton = new JRadioButton("Dec");
        decButton.setMnemonic(KeyEvent.VK_D);
        decButton.setSelected(false);
        decButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                view.setRadix(10);
            }
        });
        ButtonGroup group = new ButtonGroup();
        group.add(hexButton);
        group.add(decButton);
        JButton srcColor = new JButton("SrcColor");
        srcColor.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Color newColor = JColorChooser.showDialog(AlphaCompositeDemo.this, "Choose Src Color", view.getSrcColor());
                if (newColor != null) {
                    view.setSrcColor(newColor);
                }
            }
        });
        JButton dstColor = new JButton("DstColor");
        dstColor.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Color newColor = JColorChooser.showDialog(AlphaCompositeDemo.this, "Choose Src Color", view.getDstColor());
                if (newColor != null) {
                    view.setDstColor(newColor);
                }
            }
        });
        text = new JTextArea(3, 36);
        text.setEditable(false);
        text.setLineWrap(true);
        text.setWrapStyleWord(true);
        text.setBorder(border);
        text.setText(defaultRule.getDescription());
        JPanel controlPanel = new JPanel();
        controlPanel.add(new JLabel("Src \u03b1:", JLabel.RIGHT));
        controlPanel.add(srcSpin);
        controlPanel.add(new JLabel("Rule:", JLabel.RIGHT));
        controlPanel.add(rules);
        controlPanel.add(new JLabel("Dst \u03b1:", JLabel.RIGHT));
        controlPanel.add(dstSpin);
        JPanel colorPanel = new JPanel();
        colorPanel.add(srcColor);
        colorPanel.add(hexButton);
        colorPanel.add(decButton);
        colorPanel.add(dstColor);
        JPanel southPanel = new JPanel();
        southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
        southPanel.add(controlPanel);
        southPanel.add(colorPanel);
        southPanel.add(text);
        this.add(southPanel, BorderLayout.SOUTH);
    }

    public static void main(String arg[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new AlphaCompositeDemo());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

enum Rule {

    Clear(AlphaComposite.CLEAR),
    Dst(AlphaComposite.DST),
    DstAtop(AlphaComposite.DST_ATOP),
    DstIn(AlphaComposite.DST_IN),
    DstOut(AlphaComposite.DST_OUT),
    DstOver(AlphaComposite.DST_OVER),
    Src(AlphaComposite.SRC),
    SrcAtop(AlphaComposite.SRC_ATOP),
    SrcIn(AlphaComposite.SRC_IN),
    SrcOut(AlphaComposite.SRC_OUT),
    SrcOver(AlphaComposite.SRC_OVER),
    Xor(AlphaComposite.XOR);
    private static final Properties glossary = new Properties();
    private final int code;

    private Rule(int code) {
        this.code = code;
    }

    public int getCode() {
        return this.code;
    }

    public String getDescription() {
        return glossary.getProperty(this.name(), this.name());
    }

    static {
        String name = "src/rule.properties";
        ClassLoader loader = Rule.class.getClassLoader();
        InputStream in = loader.getResourceAsStream(name);
        if (in != null) {
            try {
                glossary.load(in);
            } catch (IOException e) {
                System.err.println(e.toString());
            }
        }
    }
}

class AlphaView extends JLabel implements Icon {

    private static final long serialVersionUID = 1L;
    private int WIDTH1 = 500;
    private int HEIGHT1 = 250;
    private float srcAlpha = 1f;
    private float dstAlpha = 1f;
    private Rule rule = Rule.Xor;
    private BufferedImage src, dst;
    private Graphics2D srcG, dstG;
    private Color srcColor = Color.blue;
    private Color dstColor = Color.red;
    private Ellipse2D.Double srcE = new Ellipse2D.Double();
    private Ellipse2D.Double dstE = new Ellipse2D.Double();
    private Color hiliteColor = new Color(255, 255, 168);
    private int[] ia = new int[4];
    private int radix = 16;

    AlphaView() {
        this.setIcon(this);
        this.setHorizontalAlignment(AlphaView.CENTER);
        int w = 2 * WIDTH1 / 3;
        int h = 2 * HEIGHT1 / 3;
        srcE.setFrame(0, h / 4, w, h);
        dstE.setFrame(w / 2, h / 4, w, h);
        src = new BufferedImage(WIDTH1, HEIGHT1, BufferedImage.TYPE_INT_ARGB);
        dst = new BufferedImage(WIDTH1, HEIGHT1, BufferedImage.TYPE_INT_ARGB);
    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        if (srcG == null) {
            srcG = src.createGraphics();
            srcG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        }
        if (dstG == null) {
            dstG = dst.createGraphics();
            dstG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        }
        srcG.setComposite(AlphaComposite.Clear);
        srcG.fillRect(0, 0, WIDTH1, HEIGHT1);
        srcG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, srcAlpha));
        srcG.setPaint(srcColor);
        srcG.drawString("Src", 20, 20);
        srcG.fill(srcE);
        dstG.setComposite(AlphaComposite.Clear);
        dstG.fillRect(0, 0, WIDTH1, HEIGHT1);
        dstG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, dstAlpha));
        dstG.setPaint(dstColor);
        dstG.drawString("Dst", WIDTH1 - 40, 20);
        dstG.fill(dstE);
        dstG.setComposite(AlphaComposite.getInstance(rule.getCode()));
        dstG.drawImage(src, 0, 0, null);
        g.drawImage(dst, x, y, this);
        //g.drawLine(x + WIDTH / 2, y, x + WIDTH / 2, y + HEIGHT);
        //g.drawLine(x, y + HEIGHT / 2, x + WIDTH, y + HEIGHT / 2);
        dst.getRaster().getPixel(WIDTH1 / 2, HEIGHT1 / 2, ia);
        String s = format(ia);
        int a = g.getFontMetrics().getAscent();
        int w = g.getFontMetrics().stringWidth(s);
        int h = g.getFontMetrics().getHeight();
        int bx = x + WIDTH1 / 2 - w / 2;
        int by = y + HEIGHT1 / 2 + a / 2;
        g.setColor(hiliteColor);
        g.fillRect(bx - 2, by - a, w + 3, h + 1);
        g.setColor(Color.gray);
        g.drawRect(bx - 2, by - a - 1, w + 3, h + 1);
        g.setColor(Color.black);
        g.drawString(s, bx, by);
    }

    private String format(int[] ia) {
        StringBuilder sb = new StringBuilder();
        int length = ia.length;
        for (int i = 0; i < length; i++) {
            sb.append(Integer.toString(ia[i], radix).toUpperCase());
            if (i < length - 1) {
                sb.append(',');
            }
        }
        return sb.toString();
    }

    public void setSrcAlpha(float alpha) {
        this.srcAlpha = alpha;
        this.repaint();
    }

    public void setDstAlpha(float alpha) {
        this.dstAlpha = alpha;
        this.repaint();
    }

    public void setRule(Rule rule) {
        this.rule = rule;
        this.repaint();
    }

    public void setRadix(int radix) {
        this.radix = radix;
        this.repaint();
    }

    public Color getSrcColor() {
        return srcColor;
    }

    public void setSrcColor(Color srcColor) {
        this.srcColor = srcColor;
        this.repaint();
    }

    public Color getDstColor() {
        return dstColor;
    }

    public void setDstColor(Color dstColor) {
        this.dstColor = dstColor;
        this.repaint();
    }

    @Override
    public int getIconWidth() {
        return WIDTH1;
    }

    @Override
    public int getIconHeight() {
        return HEIGHT1;
    }
}

back to your previous thread (animations)

again check your methods with this good & simple example, then anything is just and about timing

- but I miss there repaint();

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;


public class AnimationBackground {

    public AnimationBackground() {
        Random random = new Random();
        JFrame frame = new JFrame("Animation Background");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        final MyJPanel panel = new MyJPanel();
        panel.setBackground(Color.BLACK);
        for (int i = 0; i < 50; i++) {
            Star star = new Star(new Point(random.nextInt(490), random.nextInt(490)));
            star.setColor(new Color(100 + random.nextInt(155), 100 + random.nextInt(155), 100 + random.nextInt(155)));
            star.setxIncr(-3 + random.nextInt(7));
            star.setyIncr(-3 + random.nextInt(7));
            panel.add(star);
        }
        panel.setLayout(new GridLayout(10, 1));
        JLabel label = new JLabel("This is a Starry background.", JLabel.CENTER);
        label.setForeground(Color.WHITE);
        panel.add(label);
        JPanel stopPanel = new JPanel();
        stopPanel.setOpaque(false);
        stopPanel.add(new JButton(new AbstractAction("Stop this madness!!") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                panel.stopAnimation();
            }
        }));
        panel.add(stopPanel);
        JPanel startPanel = new JPanel();
        startPanel.setOpaque(false);
        startPanel.add(new JButton(new AbstractAction("Start moving...") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                panel.startAnimation();
            }
        }));
        panel.add(startPanel);
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                AnimationBackground animationBackground = new AnimationBackground();
            }
        });
    }

    class Star extends Polygon {

        private static final long serialVersionUID = 1L;
        private Point location = null;
        private Color color = Color.YELLOW;
        private int xIncr, yIncr;
        static final int WIDTH = 500, HEIGHT = 500;

        Star(Point location) {
            int x = location.x;
            int y = location.y;
            this.location = location;
            this.addPoint(x, y + 8);
            this.addPoint(x + 8, y + 8);
            this.addPoint(x + 11, y);
            this.addPoint(x + 14, y + 8);
            this.addPoint(x + 22, y + 8);
            this.addPoint(x + 17, y + 12);
            this.addPoint(x + 21, y + 20);
            this.addPoint(x + 11, y + 14);
            this.addPoint(x + 3, y + 20);
            this.addPoint(x + 6, y + 12);
        }

        public void setColor(Color color) {
            this.color = color;
        }

        public void move() {
            if (location.x < 0 || location.x > WIDTH) {
                xIncr = -xIncr;
            }
            if (location.y < 0 || location.y > WIDTH) {
                yIncr = -yIncr;
            }
            translate(xIncr, yIncr);
            location.setLocation(location.x + xIncr, location.y + yIncr);
        }

        public void setxIncr(int xIncr) {
            this.xIncr = xIncr;
        }

        public void setyIncr(int yIncr) {
            this.yIncr = yIncr;
        }

        public Color getColor() {
            return color;
        }
    }

    class MyJPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        private ArrayList<Star> stars = new ArrayList<Star>();
        private Timer timer = new Timer(20, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (Star star : stars) {
                    star.move();
                }
                repaint();
            }
        });

        public void stopAnimation() {
            if (timer.isRunning()) {
                timer.stop();
            }
        }

        public void startAnimation() {
            if (!timer.isRunning()) {
                timer.start();
            }
        }

        @Override
        public void addNotify() {
            super.addNotify();
            timer.start();
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            timer.stop();
        }

        MyJPanel() {
            this.setPreferredSize(new Dimension(512, 512));
        }

        public void add(Star star) {
            stars.add(star);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            for (Star star : stars) {
                g.setColor(star.getColor());
                g.fillPolygon(star);
            }
        }
    }
}

Solved using Path2D and Arc2D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.