這是我在stackoverflow上的第一篇文章,我希望有人可以幫我解決我在這裏遇到的問題。Java:repaint()不要調用for循環中的paintComponent()
我正在處理的問題是repaint()
問題,有些人會認爲我只是沒有足夠的搜索這些論壇來解決我的問題,但我已經廣泛地查找,沒有任何工作。在下面的代碼中,我嘗試在for循環中調用drawB來獲得數組的大小,該代碼正常工作。 for循環調用drawB 20次左右。在drawB中,我希望設置一個圖像(其取決於數組中的數字),然後調用repaint()
,然後在子類GameCanvas中調用paintComponent()
。
問題是,paintComponant沒有在這個初始化中運行。然而,repaint()
是否在我製作gameLoop()
的循環中運行,但我需要在gameLoop()
之前進行此初始化。
任何人都有任何線索怎麼回事,或如何解決它?
package engine;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class GameMain extends JFrame // main class for the game as a Swing application
{
// Define constants for the game
static final int CANVAS_WIDTH = 800; // width and height of the game screen
static final int CANVAS_HEIGHT = 600;
static final int UPDATE_RATE = 4; // number of game update per second
static final long UPDATE_PERIOD = 1000000000L/UPDATE_RATE; // nanoseconds
String path;
BufferedImage image;
private GameCanvas canvas;
// Constructor to initialize the UI components and game objects
public GameMain()
{
gameInit();
image = null;
canvas = new GameCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
this.setContentPane(canvas);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setTitle("Blockcraft!");
this.setVisible(true);
}
public void gameInit()
{
dispArray();
gameStart();
}
public void dispArray()
{
int tempLevel[][] = new int[][] {{1,1,1,1},{6,2,2,2},{3,3,3,3},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4}};
int widthTemp = tempLevel[0].length;
int heightTemp = tempLevel.length;
for(int i = 0; i < heightTemp; i++)
{
for(int j = 0; j < widthTemp; j++)
{
try
{
image = ImageIO.read(getFile());
}
catch (Exception e)
{
e.printStackTrace();
}
drawB(image);
}
}
}
public File getFile()
{
path = "images//1.jpg";
File file = new File(path);
return file;
}
public void drawB(BufferedImage imgTemp)
{
image = imgTemp;
repaint();
}
private void gameLoop()
{
long beginTime, timeTaken, timeLeft;
while (true)
{
repaint();
beginTime = System.nanoTime();
timeTaken = System.nanoTime() - beginTime;
timeLeft = (UPDATE_PERIOD - timeTaken)/1000000L; // in milliseconds
if (timeLeft < 10) timeLeft = 10; // set a minimum
try
{
Thread.sleep(timeLeft);
}
catch (InterruptedException ex)
{
//
}
}
}
// Refresh the display. Called back via repaint(), which invoke the paintComponent().
private void gameDraw(Graphics2D g2d)
{
g2d.drawImage(image, 0, 0, 15, 15, this);
}
public void gameKeyPressed(int keyCode)
{
//
}
public void gameKeyReleased(int keyCode)
{
//
}
public void gameKeyTyped(char keyChar)
{
//
}
class GameCanvas extends JPanel implements KeyListener
{
boolean paintAll;
int xPos, yPos;
Image img;
public GameCanvas()
{
setFocusable(true);
requestFocus();
addKeyListener(this);
}
// Override paintComponent to do custom drawing.
// Called back by repaint()... sometimes?
@Override
public void paintComponent(Graphics g)
{
System.out.println("repainting");
Graphics2D g2d = (Graphics2D)g;
// Draw the game objects
gameDraw(g2d);
}
// KeyEvent handlers
@Override
public void keyPressed(KeyEvent e)
{
gameKeyPressed(e.getKeyCode());
}
@Override
public void keyReleased(KeyEvent e)
{
gameKeyReleased(e.getKeyCode());
}
@Override
public void keyTyped(KeyEvent e)
{
gameKeyTyped(e.getKeyChar());
}
}
// To start and re-start the game.
public void gameStart()
{
// Create a new thread
Thread gameThread = new Thread()
{
// Override run() to provide the running behavior of this thread.
@Override
public void run()
{
gameLoop();
}
};
// Start the thread. start() calls run(), which in turn calls gameLoop().
gameThread.start();
}
// main
public static void main(String[] args)
{
// Use the event dispatch thread to build the UI for thread-safety.
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new GameMain();
}
});
}
}
希望這個關於[paintComponent不起作用,如果它的遞歸函數調用?](http://stackoverflow.com/q/10338163/1057230),將有一些你感興趣。和往常一樣,答案中給出的建議非常好,堅持不懈。 –
另外不要忘記在重寫的paintComponent方法中調用super.paintConponent(g)。另請參見此處的固定時間步驟遊戲循環的一個很好的示例:http://stackoverflow.com/a/14001011/1133011也不會不必要地擴展JFrame –