簡體   English   中英

ImageIO.read阻止paintComponent執行?

[英]ImageIO.read preventing paintComponent from executing?

我正在嘗試使用BufferedImage和ImageIO從精靈網格生成精靈圖像。 有一個單獨的類負責處理子圖像的加載和存儲。 這就是問題所在。 我使用ImageIO將精靈網格物體加載到BuffereImage中,由於某種原因,這間歇性地阻止了paintComponent的執行。 但是,當程序實際加載時,程序將正確顯示,但是按鍵偵聽器將停止工作。 如果有幫助,我正在使用NetBeans 7.3。

package breakout;

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

public class GamePanel extends JPanel implements Runnable {
    private Paddle paddle;
    private Breakout boRef;
    private Circle ball;
    private Graphics2D g2d, bufferedGraphics;
    private BufferedImage buffer;
    private Images images;
    private final int WIDTH = Constants.WINDOW_WIDTH;
    private final int HEIGHT = Constants.WINDOW_HEIGHT;
    private ArrayList<Block> blockList;
    private int numBlocks, blockRows, blockCols, ballXInc, ballYInc, blockPadding;
    private int totalWidth, blockX, blockY;
    private Thread ballThread;
    private boolean started, gameOver;
    private String gameOverText;
    private Random rand;

    public GamePanel( Breakout ref ) {
        boRef = ref;
        images = new Images();  <-- Problem

        numBlocks = 12;
        blockRows = 4;
        blockCols = 3;
        blockList = new ArrayList<>();
        blockY = 100;
        blockPadding = 5;
        totalWidth = ( blockCols * Block.WIDTH ) + ( ( blockCols - 1 ) * blockPadding );
        blockX = ( WIDTH / 2 ) - ( totalWidth / 2 ) - 60;
        setupBlocks();

        rand = new Random();        
        gameOverText = "";
        started = false;
        gameOver = false;

        buffer = new BufferedImage( WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB );
        bufferedGraphics = buffer.createGraphics();
        bufferedGraphics.setBackground( Color.LIGHT_GRAY );

        ball = new Circle( 250, 593, 6 );
        ball.setColor( Color.BLUE );
        ballThread = new Thread( this );
        ballXInc = 1;
        ballYInc = -1;

        paddle = new Paddle( this, 200, 600, 100, 15, Color.WHITE, Color.BLACK );

        addKeyListener( new KeyHandler() );
        setLayout( new BorderLayout() );
        setFocusable( true );
        requestFocus();
        System.out.println(" END" );
    }

private void setupBlocks() {
    int xPos = Block.WIDTH + blockPadding, yPos = Block.HEIGHT + blockPadding;
    int xInc = 1, yInc = 1;

    for( int y = 0; y < blockRows; ++y, yInc++ ) {
        for( int x = 0; x < blockCols; ++x, xInc++ ) {
            blockList.add( new Block( xPos * xInc + blockX, yPos * yInc + blockY ) );
        }

        xInc = 1;
    }
}

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

        bufferedGraphics.clearRect( 0, 0, WIDTH, HEIGHT );
       System.out.println( "HELLO" );

        //bufferedGraphics.drawImage( images.getImage(), 100, 100, images.getImage().getWidth(), images.getImage().getHeight(), null ); <-- DrawSprite

        if( !gameOver ) {
            for( Block b : blockList ) {
                b.draw( bufferedGraphics );
            }

            ball.draw( bufferedGraphics );
            paddle.draw( bufferedGraphics );
        } else { 
            bufferedGraphics.setFont( new Font( "Times New Roman", Font.BOLD, 48 ) );
            bufferedGraphics.drawString( gameOverText, WIDTH / 2 - 130, HEIGHT / 2); 
        }

        g2d.drawImage( buffer, 0, 0, WIDTH, HEIGHT, null );
    }

    private class KeyHandler extends KeyAdapter {
        @Override public void keyPressed( KeyEvent e ) {
            if( paddle.x - 10 > -10 && e.getKeyCode() == KeyEvent.VK_LEFT ) {
                paddle.x -= 10;

                if( !started ) {
                    ball.setX( ball.getX() - 10 );
                }
            } else if( paddle.x + paddle.width + 20 < WIDTH && e.getKeyCode() == KeyEvent.VK_RIGHT ) {
                paddle.x += 10;

                if( !started ) {
                    ball.setX( ball.getX() + 10 );
                }
            }

            if( e.getKeyCode() == KeyEvent.VK_SPACE ) {
                if( !started ) {
                    ballThread.start();
                    started = true;
                } else if( gameOver ) {
                    restart();
                }
            }


            repaint();
        }
    }
}



package breakout;

import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.Rectangle;
import java.io.IOException;

public class Images {
    private BufferedImage texture, tex;
    private BufferedImage [] images;
    private String meshPath = "texture\\textures.png";
    private Raster imgRaster;
    private WritableRaster imgWritableRaster;

    public static final int TEX_WIDTH = 16;
    public static final int TEX_HEIGHT = 8;

    public Images() {
        images = new BufferedImage[1];

        try {
            texture = ImageIO.read( new File( meshPath ) ); <-- Seems to be the problem
        } catch( IOException e ) {
            System.out.println( e.getMessage() );
        }

        imgRaster = texture.getData( new Rectangle( TEX_WIDTH * 2, 0, TEX_WIDTH, TEX_HEIGHT ) );
        imgWritableRaster = imgRaster.createCompatibleWritableRaster();

        tex = new BufferedImage( texture.getColorModel(), imgWritableRaster, false, null );
        images[0] = tex;
    }

    public BufferedImage getImage() {
        return images[0];
    }
}

我使用ImageIO將精靈網格物體加載到BuffereImage中,由於某種原因,這間歇性地阻止了paintComponent的執行。

這種性質的間歇性問題表明可能存在線程沖突。 我建議您在諸如SwingWorker對象可獲得的后台線程中執行ImageIO.read(...)調用。

或者,您可以在主線程中讀取圖像,然后僅在圖像全部讀取后才在Swing線程中排隊等待您的GUI。這可能就是我要做的。

public static void main(String[] args) {
  // read in images here in code that is *not* in a background thread

  SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      // start GUI in here
    }
  });
}

但是,當程序實際加載時,程序將正確顯示,但是按鍵偵聽器將停止工作。 如果有幫助,我正在使用NetBeans 7.3。

不要使用KeyListener,而要使用鍵綁定。 關於此的教程非常好,而且如果您搜索此站點,還將看到一些有關如何將其與動畫一起使用的示例。 實際上,有些例子是我寫的。 例如:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM