java - 无法重新绘制屏幕,​​但无法清除以前的形状

标签 java swing custom-painting

我正在研究谢尔宾斯基三角形的混沌游戏模拟。

我正在尝试绘制一个新点,而不清除最后一个点。随着 GUI 上创建谢尔宾斯基三角形图像的点数增加,绘制点的速度会因 for 循环而降低。我想在没有 for 循环的情况下运行这个程序,但是每次重新绘制时,前一点都会被清除。

到目前为止,我已经制作了该程序的工作版本,但我希望它更加高效。

这是我的整个程序的代码。

import javax.swing.*; //JFrame and JPanel
import java.awt.*; //Color and Container
import javax.swing.JOptionPane;
import java.awt.event.*;
import java.util.Scanner;
import java.io.*;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;

/**
 * Write a description of class ChaosGame here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class ChaosGame
{
    public static void main(String[] args) {
        JFrame theGUI = new JFrame("Chaos Game");
        theGUI.setSize(800, 800);
        theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ColorPanel panel = new ColorPanel(Color.white);
        Container pane = theGUI.getContentPane();
        pane.add(panel);
        theGUI.setVisible(true);
    }
}
class ColorPanel extends JPanel implements MouseMotionListener, MouseListener{
    private Random random = new Random();
    private Seed s;
    private Red r;
    private Blue b;
    private Green gr;
    private boolean followMouse = true;
    javax.swing.Timer timer;
    javax.swing.Timer arraytimer;
    private int x, y;
    private int newx, newy;
    private int redx = 100;
    private int redy = 660;
    private int bluex = 700;
    private int bluey = 660;
    private int greenx = 400;
    private int greeny = 140;
    private int pointx, pointy;
    private int seedx, seedy;
    private int i;
    private int dotcounter;
    private Point[] p = new Point[10000];

    public ColorPanel(Color backcolor){
        setBackground(backcolor);
        s = new Seed(400, 400, Color.YELLOW);
        r = new Red(100, 660, Color.RED);
        b = new Blue(700, 660, Color.BLUE);
        gr = new Green(400, 140, Color.GREEN);
        i = 0;
        dotcounter = 0;
        addMouseListener(this);
        addMouseMotionListener(this);
        this.setFocusable(true);
        timer = new javax.swing.Timer(1, new MoveListener());
        arraytimer = new javax.swing.Timer(1, new ArrayTimer());
    }

    public void paintComponent(Graphics g){
        //tells ball what to do when it hits the sides
        super.paintComponent(g);
        r.fill(g);
        b.fill(g);
        gr.fill(g);
        s.fill(g);
        Font font = new Font("Courier", Font.PLAIN, 30);
        g.setFont(font);

        if (followMouse == true){
            timer.start();
            s.moveto(x, y);
            g.drawString("Seed" ,x + 10, y - 10);
        }
        else if (followMouse == false){
            timer.stop();
            arraytimer.start();
            s.moveto(seedx, seedy);
            int n = random.nextInt(3) + 1;
            newx = pointx;
            newy = pointy;
            //1 = red
            //2 = green
            //3 = blue
            if(dotcounter <= 14){
                if (n == 1){
                    pointx = (newx + redx) / 2;
                    pointy = (newy + redy) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.WHITE);
                }
                else if (n == 2){
                    pointx = (newx + greenx) / 2;
                    pointy = (newy + greeny) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.WHITE);
                }
                else if (n == 3){
                    pointx = (newx + bluex) / 2;
                    pointy = (newy + bluey) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.WHITE);
                }
            }
            else if (dotcounter >= 15 && dotcounter < 10000){
                if (n == 1){
                    pointx = (newx + redx) / 2;
                    pointy = (newy + redy) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.RED);
                }
                else if (n == 2){
                    pointx = (newx + greenx) / 2;
                    pointy = (newy + greeny) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.GREEN);
                }
                else if (n == 3){
                    pointx = (newx + bluex) / 2;
                    pointy = (newy + bluey) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.BLUE);
                }
            }
            else{
                arraytimer.stop();
            }
            for (i = 0; i < dotcounter; i++)
            { 
                p[i].fill(g);
            }
        }
        g.drawString(""+dotcounter, 600, 60);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        x = e.getX();
        y = e.getY();
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mousePressed(MouseEvent e){
        if (followMouse == true){
            seedx = x;
            seedy = y;
            pointx = seedx;
            pointy = seedy;
            followMouse = false;
        }
        else{}
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    private class MoveListener implements ActionListener{
        public void actionPerformed(ActionEvent e){
            repaint();
        }
    }
    private class ArrayTimer implements ActionListener{
        public void actionPerformed(ActionEvent e){
            dotcounter++;
            repaint();
        }
    }
}
class Seed{
    private int centerX, centerY, radius;
    private Color color;
    public Seed(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Red{
    private int centerX, centerY, radius;
    private Color color;
    public Red(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Blue{
    private int centerX, centerY, radius;
    private Color color;
    public Blue(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Green{
    private int centerX, centerY, radius;
    private Color color;
    public Green(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Point{
    private int centerX, centerY, radius;
    private Color color;
    public Point(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 1;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillRect(centerX-radius, centerY-radius, radius, radius);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}

最佳答案

查看Custom Painting Approaches执行此操作的两种常见方法:

  1. 保留一个要绘制的对象列表,并在每次需要重新绘制组件时迭代此列表
  2. 在 BufferedImage 上绘图,然后重新绘制图像。

听起来,如果第一种方法存在性能问题,那么第二种方法就是您所需要的。

关于java - 无法重新绘制屏幕,​​但无法清除以前的形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28415850/

相关文章:

java - 如何使用java将多个XML文件加载到MySQL

java - 在 finally 期间删除临时文件与在 catch 期间删除输出文件

java - 如何在Swing应用程序中嵌入IE?

java - JTable - boolean 单元格类型 - 背景

java - 在Java中添加canvas后无法关闭窗口

java - 在验证码中为视障人士连接声音

java - 如何使用Java代码查询具有相同字段名称ElasticSearch的两种类型

java - JLayeredPane,背景图像+ "icon"图层

java - Graphics2D 线条和形状绘制问题(渲染在错误的位置)

image - 如何从用 CustomPainter 绘制的 Canvas 中获取图像?