使用 java 中的图形绘制多个圆

Draw multiple circles using graphics in java

我正在开发一款四人连线游戏,我正试图在我点击屏幕时显示多个圆圈。现在,每次我重新点击时,我刚刚画的圆圈都会消失。

感谢任何帮助。

protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;    // create 2d object
        g2d.setStroke(new BasicStroke(2));  // set thickness of line

        // each box is 100 x 100
        // draws the vertical lines
        for (int i = 0; i < 8; i++) {
            g2d.drawLine(140 + i * DISC_RADIUS, 30, 140 + i * DISC_RADIUS, 690);
        }
        // draws the horizontal lines
        for (int i = 0; i < 7; i++) {
            g2d.drawLine(140, 90 + i * DISC_RADIUS, 840, 90 + i * DISC_RADIUS);
        }
        // draws the circles
        for (int i = 0; i < 6; i++) {       // new vertical row of circles
            for (int j = 0; j < 7; j++) {   // new horizontal row of circles
                g2d.drawOval(140 + j * DISC_RADIUS, 90 + i * DISC_RADIUS, DISC_RADIUS, DISC_RADIUS);
            }
        }

        // if at the start of the game, will not draw the counters
        if (start == true) {
            // draws blue counter
            g2d.drawOval(20, 90, DISC_RADIUS, DISC_RADIUS);
            g2d.setColor(Color.BLUE);       // sets colour to blue
            g2d.fillOval(20, 90, DISC_RADIUS, DISC_RADIUS); // draws the circle

            // draws red counter
            g2d.setColor(Color.BLACK);
            g2d.drawOval(875, 90, DISC_RADIUS, DISC_RADIUS);
            g2d.setColor(Color.RED);            // sets the colour to red
            g2d.fillOval(875, 90, DISC_RADIUS, DISC_RADIUS);    // draws the circle


        }
        //print on the screen who's turn it is


        // draws blue counter stand;
        g2d.setStroke(new BasicStroke(4));  // sets the line width
        g2d.setColor(Color.BLACK);          // changes the outline colour to black
        g2d.drawPolygon(poly1);             // draw the outline
        g2d.setColor(Color.GRAY);           // changes the fill colour to grey
        g2d.fillPolygon(poly1);             // draws the filling

        // draws bred counter stand;
        g2d.setColor(Color.BLACK);  // changes the outline colour to black
        g2d.drawPolygon(poly2);     // draws the outline
        g2d.setColor(Color.GRAY);   // changes the fill colour to grey
        g2d.fillPolygon(poly2);     // draws the filling

        repaint();

        if(Player.getPlayer() == "Blue"){
            g2d.setColor(Color.BLACK);  
            if(draw == true){
                g2d.drawString("Blue's Turn", 40, 300); 
                g2d.drawOval(xPos, yPos, DISC_RADIUS, DISC_RADIUS);
                g2d.setColor(Color.BLUE);       // sets colour to blue
                g2d.fillOval(xPos, yPos, DISC_RADIUS, DISC_RADIUS); // draws the circle
            }
        }

        if(Player.getPlayer() == "Red"){
            g2d.drawString("Red's Turn", 900, 300);
            if(draw == true){
                g2d.drawOval(xPos, yPos, DISC_RADIUS, DISC_RADIUS);
                g2d.setColor(Color.RED);        // sets colour to blue
                g2d.fillOval(xPos, yPos, DISC_RADIUS, DISC_RADIUS); // draws the circle
            }
        }
    }
}

绘制是破坏性的,也就是说,每次调用paintComponent,你都希望从头开始重新绘制组件的整个状态。

你应该做的是创建某种模型来维护关于哪个玩家选择了哪个单元格的信息。

例如,您可以只使用 String 的二维数组,其中 null 表示无人,Red 表示红色玩家,Blue 表示对于蓝色玩家。然后,您将使用一个简单的复合循环遍历数组并相应地绘制 UI...

现在,if(Player.getPlayer() == "Blue"){ 不是 String 比较在 Java 中的工作方式,您应该使用更像 if("Blue".equals(Player.getPlayer())){ 的东西。

不要在任何绘画方法中直接或间接地更新或修改 UI 的状态,这可能会设置一个无限循环的绘画请求,这将消耗您的 CPU 个周期。 .

不应该从 paintComponent() 方法中调用 repaint(),因为 repaint() 会以某种方式调用 paintComponent(),从而导致递归调用。

此外,当调用 repaint() 时,整个 JComponent 实际上是从初始状态绘制的。为了让您绘制已经在 JPanel/JComponent 上的圆圈,可以简单地使用 Collection/Array 来跟踪绘制的内容。这样代码就可以迭代此 Collection/Array 以重绘之前绘制的所有圆圈和要绘制的新圆圈。

这是一个小示例:

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;

public class CircleExample {

    private static final int GAP = 5;

    private JPanel drawingBoard;    

    private void displayGUI() {
        JFrame frame = new JFrame("Circle Drawing Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new BorderLayout(GAP, GAP));
        contentPane.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));

        drawingBoard = new DrawingBoard();
        contentPane.add(drawingBoard);

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

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new CircleExample().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class DrawingBoard extends JPanel {

    private static final int WIDTH = 300;
    private static final int HEIGHT = 350;

    private List<MyCircle> circles;
    private Random random;

    private MouseAdapter mouseAdapter = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent me) {
            System.out.println("Mouse Clicked");
            int x = me.getX();
            int y = me.getY();
            circles.add(new MyCircle(x, y, getRandomColour()));
            DrawingBoard.this.repaint();
        }
    };

    public DrawingBoard() {
        super();
        circles = new ArrayList<MyCircle> ();
        random = new Random();
        setOpaque(true);
        addMouseListener(mouseAdapter);
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (MyCircle circle : circles) {
            circle.drawCircle(g);
        }
    }

    private Color getRandomColour() {
        return new Color(random.nextFloat(), random.nextFloat(),
                            random.nextFloat(), random.nextFloat());
    }
}

class MyCircle {

    private int x;
    private int y;
    private Color backgroundColour;

    private static final int RADIUS = 20;

    public MyCircle(int x, int y, Color backgroundColour) {
        this.x = x;
        this.y = y;
        this.backgroundColour = backgroundColour;
    }

    public void drawCircle(Graphics g) {
        g.setColor(backgroundColour);
        g.fillOval(x, y, RADIUS, RADIUS);
    }
}