图形对象被绘制两次

时间:2012-07-25 23:40:00

标签: java

这里是每隔5秒生成并绘制一个四氨基酸的代码。 然而,这个数字被淹没了两次,因此扭曲了原始图片。

这里的四氨基图由10x10像素块组成。 构造函数图描述块和颜色的位置。 方法paint(Graphics g)逐块扫描图f。

import java.applet.*;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;


import javax.swing.Timer;
public class Tetris extends Applet  {

    Dimension size;
    int x1,y1;
    private int xs=0,ys=0;


    public int getXs() {
        return xs;
    }
    public void setXs(int xs) {
        this.xs = xs;
    }
    public int getYs() {
        return ys;
    }
    public void setYs(int ys) {
        this.ys = ys;
    }
    public void rotate(){

    }
    public Figure generate(){
        Figure i = new Figure(new int[][]{new int[]{1},new int[]{1},new int[]{1},new int[]{1}},Color.CYAN);
        Figure j = new Figure(new int[][]{new int[]{1,0,0}, new int[]{1,1,1}},Color.BLUE);
        Figure l = new Figure(new int[][]{new int[]{0,0,1}, new int[]{1,1,1}},Color.ORANGE);
        Figure o = new Figure(new int[][]{new int[]{1,1}, new int[]{1,1}},Color.YELLOW);
        Figure s = new Figure(new int[][]{new int[]{0,1,1}, new int[]{1,1,0}},Color.GREEN);
        Figure t = new Figure(new int[][]{new int[]{1,1,1}, new int[]{0,1,0}},Color.PINK);
        Figure z = new Figure(new int[][]{new int[]{1,1,0}, new int[]{0,1,1}},Color.RED);

        Figure[] genSet = {i,j,l,o,s,t,z};
        int index =((int) (Math.random() * 7)) ;
        //System.out.println(index);
        return  genSet[index];
    }
    public void drop(){

    }
    public void shift(){

    }
    public void movecheck(){

    }
    public void actiondelay(){
        ActionListener actionlistener = new ActionListener() {
            public void actionPerformed(ActionEvent actionevent){
                repaint();
            }

        };
        Timer timer = new Timer(5000,actionlistener);
        timer.start();
    }
    public void init(){
        setSize(200,400);
        setBackground(Color.black);
        size = getSize();

    }

    public void paint(Graphics g){

        super.paint(g);
        System.out.println("________________");
        Graphics2D g2d = (Graphics2D) g.create();
        Figure f = generate();
        int length = f.getX()[0].length;
        for(int j =0; j<f.getX().length;j++){
            System.out.println();
            ys = 0;                 
            for(int i=0;i<length;i++){                      

                if (f.getX()[j][i] == 1){
                    Rectangle2D p = new Rectangle2D.Double(xs,xs,xs+10,ys+10);
                    g2d.setColor(f.getY());
                    g2d.draw(p);
                    //g2d.drawRect(p.x, p.y, p.width, p.height);    
                    //g2d.fillRect(p.x, p.y, p.width, p.height);                    
                    //System.out.println("widnth: " +p.width + " | height: " + p.height + " end ");
                    System.out.print("*");
                }
                else System.out.print(" ");
                ys+=10;             
            }
            xs+=10;
        }
        xs=0;
        ys=0;
        actiondelay();                      
       //g.setColor(Color.white);
       //g.drawRect(45, 95, 55, 105);        
    }


}


import java.awt.Color;

public class Figure{
    int[][] x;
    Color y;
    public Figure(int[][] x , Color y){
        this.x=x;
        this.y=y;
    }
    public int[][] getX() {
        return x;
    }
    public void setX(int[][] x) {
        this.x = x;
    }
    public Color getY() {
        return y;
    }
    public void setY(Color y) {
        this.y = y;
    }
}

3 个答案:

答案 0 :(得分:0)

我认为您错过了g2d.dispose()方法中paint()的来电。我不确定这是否能解决这个问题,但尝试它不会有什么坏处。

答案 1 :(得分:0)

你的图片没有被扭曲,因为数字被绘制了两次,但因为new Rectangle2D.Double(xs,xs,xs+10,ys+10);

中的错误很少
  1. xy位置开始,您使用了xs两次而不是xsys
  2. 您的widthhight不是固定值,但与xsys
  3. 相关

    当你转到新行时,你的循环也在增加xs而不是ys

    尝试用此替换paint()方法:

    public void paint(Graphics g){
    
        super.paint(g);
        System.out.println("________________");
        Graphics2D g2d = (Graphics2D) g.create();
        Figure f = generate();
        int length = f.getX()[0].length;
        for(int j =0; j<f.getX().length; j++){
            System.out.println();
    
            for(int i=0; i<f.getX()[0].length; i++){                      
    
                if (f.getX()[j][i] == 1){
                    Rectangle2D p = new Rectangle2D.Double(xs, ys, 10, 10);
                    g2d.setColor(f.getY());
                    g2d.draw(p);
                    //g2d.drawRect(p.x, p.y, p.width, p.height);    
                    //g2d.fillRect(p.x, p.y, p.width, p.height);                    
                    //System.out.println("widnth: " +p.width + " | height: " + p.height + " end ");
                    System.out.print("*");
                }
                else System.out.print(" ");
                xs+=10;
            }
            xs = 0;
            ys+=10;             
        }
        xs=0;
        ys=0;
        actiondelay();                      
       //g.setColor(Color.white);
       //g.drawRect(45, 95, 55, 105);        
    }
    

    此外javax.swing.Timer(int delay, ActionListener listener)是循环线程的类型,因此,如果要在delay中设置每次执行一次操作,则不应创建少量实例。在您的位置,我会将代码从actiondelay移至init

答案 2 :(得分:0)

问题在于您如何使用Timer。我不知道为什么你坚持在每个“油漆”循环中创建一个新的计时器。

你没有控制油漆循环,Java确实如此。所以基本上,发生了什么,是每次你的组件被绘制(可能是你的Timer事件之间的次数),你创建一个新的Timer重复每5秒。这意味着您正在运行 n 计时器,这将为您带来许多有趣的东西......

相反,创建一个计时器:

@Override
public void start() {

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {

            timer = new Timer(5000, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {

                    repaint();

                }
            });

            timer.setInitialDelay(5000);
            timer.setCoalesce(true);
            timer.start(); // Repeats by default...

        }
    });

}

不要改变涂料方法中的任何东西。只是不要你可能会触发更多的绘制请求,最终会使EDT超载并在短时间内将CPU运行高达100%。