Java - 用连接中心的线条的圆圈

时间:2015-02-03 19:30:10

标签: java swing

我有JFrame个子类Paint_PanelPaint_Panel扩展JPanel并实施MouseListener

我需要点击鼠标放置三个圆圈。没问题。我有一个按钮(绘图),应该从每个圆的中心到另一个中心画线(因此 - 三角形)。我可以将坐标保持在ArrayList范围内 - 没问题。但是,当我尝试通过单击按钮引用ArrayList时,列表将返回空。在绘制线条时,数组不在内存中。思考?

注意 - 圈子在40处被硬编码。

代码:

public class Paint_Panel extends JPanel implements MouseListener {

    public static int flag = 0;
    boolean drawCircles = false;
    boolean drawLines = false;
    private final ArrayList<Point> points = new ArrayList<>();

    public Paint_Panel() {
        addMouseListener(this);
    }

    //Method to draw lines from point to point
    public void drawLines() {
        Graphics g = getGraphics();
        drawLines = true;
        paintComponent(g);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (drawCircles) {
            for (int i = 0; i < points.size(); i++) {
                //Circle number 1
                g.setColor(Color.RED);
                g.fillOval(points.get(0).x - 20, points.get(0).y - 20, 40, 40);
                //Circle number 2
                if (points.size() >= 2) {
                    g.setColor(Color.GREEN);
                    g.fillOval(points.get(1).x - 20, points.get(1).y - 20, 40, 40);
                }
                //Circle number 3
                if (points.size() >= 3) {
                    g.setColor(Color.BLUE);
                    g.fillOval(points.get(2).x - 20, points.get(2).y - 20, 40, 40);
                }
            }
        } else if (drawLines) {      
            g.setColor(Color.BLACK);    //Set line color
            g.drawLine(points.get(0).x, points.get(0).y, points.get(1).x, points.get(1).y);
            g.drawLine(points.get(1).x, points.get(1).y, points.get(2).x, points.get(2).y);
            g.drawLine(points.get(2).x, points.get(2).y, points.get(0).x, points.get(0).y);
        }
    }

    public void mouseClicked(MouseEvent evt) {  //Place circles for click event

        Graphics g = getGraphics();
        if (!drawCircles) {
            prevX = evt.getX() - 20;    //Allows placement at center. Size - radius
            prevY = evt.getY() - 20;
            points.add(evt.getPoint()); //Add point to ArrayList
            if (flag < 3) {             //Keep track of how many circles are placed
                flag += 1;
                drawCircles = true;
                paintComponent(g);
            } else if (flag == 3) {     //If additional circles attempted, inform user
                flag = 4;
                System.out.println("Only 3 circles allowed."); //Debug
                drawCircles = false;
            }
        }
        drawCircles = false;
    }
    @Override
    public void mousePressed(MouseEvent evt) { //Unused
    }
    @Override
    public void mouseReleased(MouseEvent evt) { //Unused
    }
    @Override
    public void mouseEntered(MouseEvent evt) { //Unused
    }
    @Override
    public void mouseExited(MouseEvent evt) { //Unused
    }
}

2 个答案:

答案 0 :(得分:4)

这是绘制3个圆圈和3个线条的一种方法。编辑首先绘制圆圈,然后绘制线条。再次编辑以检查按下无效按钮。

Circle Paint Test Circle Paint Test

我分离了视图和控制器逻辑。

这是可运行的代码。

package com.ggl.testing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CirclePaintTest implements Runnable {

    private JFrame frame;

    private PaintPanel paintPanel;

    @Override
    public void run() {
        frame = new JFrame("Circle Paint Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());

        paintPanel = new PaintPanel();
        mainPanel.add(paintPanel, BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel();

        JButton lineButton = new JButton("Draw Lines");
        lineButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                if (paintPanel.isComplete()) {
                    paintPanel.setDrawLines(true);
                    paintPanel.repaint();
                }
            }
        });
        buttonPanel.add(lineButton);

        mainPanel.add(buttonPanel, BorderLayout.SOUTH);

        frame.add(mainPanel);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CirclePaintTest());
    }

    public class PaintPanel extends JPanel {

        private static final long serialVersionUID = 6481890334304291711L;

        private final Color[] colors = { Color.RED, Color.GREEN, Color.BLUE,
                Color.ORANGE, Color.CYAN, Color.YELLOW };

        private boolean drawLines;

        private final int pointLimit;

        private final List<Point> points;

        public PaintPanel() {
            this.points = new ArrayList<Point>();
            this.pointLimit = 3;
            this.drawLines = false;

            this.addMouseListener(new CircleMouseListener());
            this.setPreferredSize(new Dimension(400, 400));
        }

        public void setDrawLines(boolean drawLines) {
            this.drawLines = drawLines;
        }

        public boolean isComplete() {
            return points.size() >= pointLimit;
        }

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

            Point pp = null;
            Point p0 = null;

            for (int i = 0; i < points.size(); i++) {
                g.setColor(colors[i]);

                Point p = points.get(i);
                g.fillOval(p.x - 20, p.y - 20, 40, 40);

                pp = p;
            }

            if (drawLines && (points.size() > 1)) {
                p0 = points.get(0);
                pp = p0;
                g.setColor(Color.BLACK);
                for (int i = 1; i < points.size(); i++) {
                    Point p = points.get(i);
                    g.drawLine(pp.x, pp.y, p.x, p.y);
                    pp = p;
                }
                g.drawLine(pp.x, pp.y, p0.x, p0.y);
            }
        }

        public class CircleMouseListener extends MouseAdapter {

            @Override
            public void mousePressed(MouseEvent event) {
                if (points.size() < pointLimit) {
                    points.add(event.getPoint());
                    PaintPanel.this.repaint();
                }
            }
        }
    }

}

答案 1 :(得分:0)

当标记等于3时,您不会调用repaint,因此没有调用具有正确条件的paintComponent方法drawCircles false和{ {1}} drawLines)。 我建议您在true等于3或repaint结束时致电flag