Java图形绘制持续闪烁

Java图形绘制持续闪烁,java,graphics,awt,graphics2d,repaint,Java,Graphics,Awt,Graphics2d,Repaint,我试着做一个俄罗斯方块游戏。但是我的jframe GUI持续闪烁。但是当我在代码中注释下面的行时,它不会闪烁。有人能帮忙吗 map.draw((Graphics2D) g); JDK版本-1.8 NetBeans-7.4 代码文件链接如下 package GUI; import Maps.MapGenerator; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Gr

我试着做一个俄罗斯方块游戏。但是我的jframe GUI持续闪烁。但是当我在代码中注释下面的行时,它不会闪烁。有人能帮忙吗

map.draw((Graphics2D) g);
JDK版本-1.8 NetBeans-7.4

代码文件链接如下

package GUI;

import Maps.MapGenerator;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.Timer;

public class BrickBreaker extends javax.swing.JFrame implements KeyListener, ActionListener {

private MapGenerator map;

public BrickBreaker() {
    initComponents();
    this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
    this.setTitle("Test Tetris");
    //Map
    map = new MapGenerator(3, 7);
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    time = new Timer(delay, this);
    time.start();
}

public void paint(Graphics g) {

    //background
    g.setColor(Color.black);
    g.fillRect(1, 1, 692, 592);

    //map
    map.draw((Graphics2D) g);

    //score
    g.setColor(Color.white);
    g.setFont(new Font("serif", Font.BOLD, 25));
    g.drawString("" + score, 560, 30);

    //border
    g.setColor(Color.yellow);
    g.fillRect(0, 0, 3, 592);
    g.fillRect(0, 0, 692, 3);
    g.fillRect(691, 0, 3, 592);

    //paddle
    g.setColor(Color.green);
    g.fillRect(playerPosX, 550, 100, 8);

    //ball
    g.setColor(Color.red);
    g.fillOval(ballPosX, ballPosY, 20, 20);

    g.dispose();
}

private boolean play = false;
private int score = 0;
private int totalBricks = 21;

private Timer time;
private int delay = 8;

private int playerPosX = 310;

private int ballPosX = 210;
private int ballPosY = 350;
private int ballXDir = -1;
private int ballYDir = -2;

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setPreferredSize(new java.awt.Dimension(700, 600));

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 525, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 403, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new BrickBreaker().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
// End of variables declaration                   
@Override
public void keyTyped(KeyEvent e) {
}

@Override
public void keyPressed(KeyEvent e) {
    try {

        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            if (playerPosX >= 600) {
                playerPosX = 600;
            } else {
                moveRight();
            }
        }

        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            if (playerPosX < 10) {
                playerPosX = 10;
            } else {
                moveLeft();
            }
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void moveRight() {
    play = true;
    playerPosX += 20;
}

public void moveLeft() {
    play = true;
    playerPosX -= 20;
}

@Override
public void keyReleased(KeyEvent e) {
}

@Override
public void actionPerformed(ActionEvent e) {
    time.start();

    if (play) {

        if (new Rectangle(ballPosX, ballPosY, 20, 20).intersects(new Rectangle(playerPosX, 550, 100, 8))) {
            ballYDir = -ballYDir;
        }

        A:
        for (int i = 0; i < map.map.length; i++) {
            for (int j = 0; j < map.map[0].length; j++) {
                if (map.map[i][j] > 0) {
                    int brickX = j * map.brickWidth + 60;
                    int brickY = i * map.brickHeight + 50;
                    int brickWidht = map.brickWidth;
                    int brickHeight = map.brickHeight;

                    Rectangle rect = new Rectangle(brickX, brickY, brickWidht, brickHeight);
                    Rectangle ballRect = new Rectangle(ballPosX, ballPosY, 20, 20);
                    Rectangle brickRect = rect;

                    if (ballRect.intersects(brickRect)) {
                        map.setBrickValue(0, i, j);
                        totalBricks--;
                        score += 2;

                        if (ballPosX + 19 <= brickRect.x || ballPosX + 1 >= brickRect.x + brickRect.width) {
                            ballXDir = -ballXDir;
                        } else {
                            ballYDir = -ballYDir;
                        }

                        break A;
                    }
                }
            }
        }

        ballPosX += ballXDir;
        ballPosY += ballYDir;
        if (ballPosX < 0) {
            ballXDir = -ballXDir;
        }
        if (ballPosY < 0) {
            ballYDir = -ballYDir;
        }
        if (ballPosX > 670) {
            ballXDir = -ballXDir;
        }
    }
    repaint();

}
}
packagegui;
导入Maps.MapGenerator;
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Rectangle;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入javax.swing.Timer;
公共类BrickBreaker扩展了javax.swing.JFrame实现了KeyListener、ActionListener{
私有地图生成器地图;
公共砌砖工(){
初始化组件();
此.setDefaultCloseOperation(此.EXIT在关闭时退出);
本书标题为“测试俄罗斯方块”;
//地图
map=新的MapGenerator(3,7);
addKeyListener(此);
设置聚焦(真);
setFocusTraversalKeysEnabled(false);
时间=新计时器(延迟,此);
time.start();
}
公共空间涂料(图g){
//背景
g、 设置颜色(颜色为黑色);
g、 fillRect(1,1692,592);
//地图
绘制地图((图2d)g);
//得分
g、 setColor(Color.white);
g、 setFont(新字体(“衬线”,Font.BOLD,25));
g、 抽绳(“+score,560,30);
//边界
g、 setColor(颜色为黄色);
g、 fillRect(0,0,3592);
g、 fillRect(0,0692,3);
g、 fillRect(691,0,3592);
//划桨
g、 setColor(Color.green);
g、 fillRect(playerPosX,550100,8);
//球
g、 setColor(Color.red);
g、 fillOval(ballPosX,ballPosY,20,20);
g、 处置();
}
私有布尔播放=假;
私人智力得分=0;
私人整数=21;
私人定时器时间;
专用int延迟=8;
私有int playerPosX=310;
私有int-ballPosX=210;
私人整数ballPosY=350;
私有int-ballXDir=-1;
私有int-ballYDir=-2;
@抑制警告(“未选中”)
//                           
私有组件(){
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(新的java.awt.Dimension(700600));
javax.swing.GroupLayout=newjavax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(布局);
layout.setHorizontalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0,525,短。最大值)
);
layout.setVerticalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0,403,短.MAX_值)
);
包装();
}//                         
公共静态void main(字符串参数[]){
/*设置Nimbus的外观和感觉*/
//
/*如果Nimbus(在JavaSE6中引入)不可用,请使用默认的外观。
*详情请参阅http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
*/
试一试{
for(javax.swing.UIManager.LookAndFeelInfo:javax.swing.UIManager.getInstalledLookAndFeels()){
if(“Nimbus”.equals(info.getName())){
setLookAndFeel(info.getClassName());
打破
}
}
}捕获(ClassNotFoundException ex){
getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.severy,null,ex);
}catch(实例化异常){
getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.severy,null,ex);
}捕获(非法访问例外){
getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.severy,null,ex);
}catch(javax.swing.UnsupportedLookAndFeelException ex){
getLogger(BrickBreaker.class.getName()).log(java.util.logging.Level.severy,null,ex);
}
//
/*创建并显示表单*/
invokeLater(new Runnable()){
公开募捐{
新砌砖机().setVisible(true);
}
});
}
//变量声明-不修改
//变量结束声明
@凌驾
public void keyTyped(KeyEvent e){
}
@凌驾
按下公共无效键(按键事件e){
试一试{
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
如果(playerPosX>=600){
playerPosX=600;
}否则{
moveRight();
}
}
如果(例如getKeyCode()==KeyEvent.VK_左){
如果(playerPosX<10){
playerPosX=10;
}否则{
左移();
}
}
}捕获(例外情况除外){
例如printStackTrace();
}
}
公权{
玩=真;
playerPosX+=20;
}
公共空间左移(){
玩=真;
playerPosX-=20;
}
@凌驾
公共无效密钥已释放(密钥事件e){
}
@凌驾
已执行的公共无效操作(操作事件e){
time.start();
如果(玩){
if(新矩形(ballPosX,ballPosY,20,20)。相交(新矩形(playerPosX,550100,8))){
ballYDir=-ballYDir;
}
A:
for(int i=0;i0){
int brickX=j*map.brickWidth+60;
int brickY=i*map.brickHeight+50;
int brickWidth=map.brickWidth;
int brickHeight=map.brickHeight;
矩形矩形=新矩形(砖X、砖、砖宽、砖高);
矩形ballRect=新矩形(ballPosX,ballPosY,20,20);
矩形brickRect=rect;
if(球直相交(砖斜相交)){
映射值(0,i,j);
总砖块--;
分数+=2分;
package Maps;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;


public class MapGenerator {

public int map[][];
public int brickWidth;
public int brickHeight;

public MapGenerator(int row, int col) {
    map = new int[row][col];
    for (int i = 0; i < map.length; i++) {
        for (int j = 0; j < map[0].length; j++) {
            map[i][j] = 1;
        }
    }

    brickWidth = 240 / row;
    brickHeight = 150 / col;
}

public void draw(Graphics2D g) {
    for (int i = 0; i < map.length; i++) {
        for (int j = 0; j < map[0].length; j++) {
            if (map[i][j] > 0) {
                g.setColor(Color.black);
                g.fillRect(j * brickWidth + 60, i * brickHeight + 50, brickWidth, brickHeight);

                g.setStroke(new BasicStroke(3));
                g.setColor(Color.white);
                g.drawRect(j * brickWidth + 60, i * brickHeight + 50, brickWidth, brickHeight);

            }
        }
    }
}

public void setBrickValue(int value, int row, int col) {
    map[row][col] = value;
}

}
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private boolean play = false;
        private int score = 0;
        private int totalBricks = 21;

        private Timer timer;
        private int delay = 8;

        private int playerPosX = 310;

        private int ballPosX = 210;
        private int ballPosY = 350;
        private int ballXDir = -1;
        private int ballYDir = -2;
        private MapGenerator map;

        public TestPane() {
            setBackground(Color.BLACK);
            map = new MapGenerator(3, 7);
            timer = new Timer(delay, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (play) {

                        if (new Rectangle(ballPosX, ballPosY, 20, 20).intersects(new Rectangle(playerPosX, 550, 100, 8))) {
                            ballYDir = -ballYDir;
                        }

                        for (int i = 0; i < map.map.length; i++) {
                            for (int j = 0; j < map.map[0].length; j++) {
                                if (map.map[i][j] > 0) {
                                    int brickX = j * map.brickWidth + 60;
                                    int brickY = i * map.brickHeight + 50;
                                    int brickWidht = map.brickWidth;
                                    int brickHeight = map.brickHeight;

                                    Rectangle rect = new Rectangle(brickX, brickY, brickWidht, brickHeight);
                                    Rectangle ballRect = new Rectangle(ballPosX, ballPosY, 20, 20);
                                    Rectangle brickRect = rect;

                                    if (ballRect.intersects(brickRect)) {
                                        map.setBrickValue(0, i, j);
                                        totalBricks--;
                                        score += 2;

                                        if (ballPosX + 19 <= brickRect.x || ballPosX + 1 >= brickRect.x + brickRect.width) {
                                            ballXDir = -ballXDir;
                                        } else {
                                            ballYDir = -ballYDir;
                                        }
                                    }
                                }
                            }
                        }

                        ballPosX += ballXDir;
                        ballPosY += ballYDir;
                        if (ballPosX < 0) {
                            ballXDir = -ballXDir;
                        }
                        if (ballPosY < 0) {
                            ballYDir = -ballYDir;
                        }
                        if (ballPosX > 670) {
                            ballXDir = -ballXDir;
                        }
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(700, 600);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            //map
            map.draw((Graphics2D) g);

            //score
            g.setColor(Color.white);
            g.setFont(new Font("serif", Font.BOLD, 25));
            g.drawString("" + score, 560, 30);

            //border
            g.setColor(Color.yellow);
            g.fillRect(0, 0, 3, 592);
            g.fillRect(0, 0, 692, 3);
            g.fillRect(691, 0, 3, 592);

            //paddle
            g.setColor(Color.green);
            g.fillRect(playerPosX, 550, 100, 8);

            //ball
            g.setColor(Color.red);
            g.fillOval(ballPosX, ballPosY, 20, 20);

            g2d.dispose();
        }

    }

    public class MapGenerator {

        public int map[][];
        public int brickWidth;
        public int brickHeight;

        public MapGenerator(int row, int col) {
            map = new int[row][col];
            for (int i = 0; i < map.length; i++) {
                for (int j = 0; j < map[0].length; j++) {
                    map[i][j] = 1;
                }
            }

            brickWidth = 240 / row;
            brickHeight = 150 / col;
        }

        public void draw(Graphics2D g) {
            for (int i = 0; i < map.length; i++) {
                for (int j = 0; j < map[0].length; j++) {
                    if (map[i][j] > 0) {
                        g.setColor(Color.black);
                        g.fillRect(j * brickWidth + 60, i * brickHeight + 50, brickWidth, brickHeight);

                        g.setStroke(new BasicStroke(3));
                        g.setColor(Color.white);
                        g.drawRect(j * brickWidth + 60, i * brickHeight + 50, brickWidth, brickHeight);

                    }
                }
            }
        }

        public void setBrickValue(int value, int row, int col) {
            map[row][col] = value;
        }

    }

}
A:
for (int i = 0; i < map.map.length; i++) {
    //...
            //...
                break A;